From 44822b0dceeee48e70170940f8495f1d0529cb2a Mon Sep 17 00:00:00 2001 From: Diego Freitas Date: Tue, 27 Jan 2026 16:34:25 -0300 Subject: [PATCH] repositorio criado --- .checkAPI.sh.swp | Bin 0 -> 1024 bytes .env | 2 + .env.example | 2 + .gitignore | 50 + checkAPI.sh | 10 + connections/mysql-server.js | 124 + connections/sql-server.js | 80 + controllers/addressController.js | 29 + controllers/agendaController.js | 60 + controllers/alexaController.js | 1383 +++ controllers/animationsController.js | 307 + controllers/answerController.js | 271 + controllers/appController.js | 1641 +++ controllers/barcodeController.js | 384 + controllers/baseController.js | 17 + controllers/chamadaController.js | 171 + controllers/charactersController.js | 580 + controllers/chatController.js | 250 + controllers/chattimeController.js | 3360 ++++++ controllers/chattimeController_bkp.js | 3162 ++++++ controllers/classController.js | 955 ++ controllers/classescontentController.js | 361 + controllers/conceptsController.js | 64 + controllers/configController.js | 64 + controllers/courseController.js | 615 ++ controllers/coursesStudentController.js | 35 + controllers/curiositiesController.js | 89 + controllers/customizeController.js | 66 + controllers/elloController.js | 67 + controllers/emailController.js | 345 + controllers/exerciseController.js | 138 + controllers/fileController.js | 235 + controllers/franchiseeController.js | 476 + controllers/holidayController.js | 77 + controllers/ig40Controller.js | 84 + controllers/iyrcController.js | 1425 +++ controllers/listenrepeatController.js | 100 + controllers/loginController.js | 40 + controllers/migrationController.js | 1048 ++ controllers/permissoesController.js | 119 + controllers/productsController.js | 180 + controllers/qrController.js | 189 + controllers/questionController.js | 80 + controllers/relatorioController.js | 670 ++ controllers/slidesController.js | 108 + controllers/sqlServerController.js | 22 + controllers/studentController.js | 314 + controllers/teacherController.js | 597 + controllers/textController.js | 169 + controllers/traineeprogramController.js | 196 + .../traineeprogramcoursesController.js | 151 + controllers/typescourseController.js | 57 + controllers/unileverController.js | 176 + controllers/unityController.js | 1262 +++ controllers/usersController.js | 1171 ++ controllers/videoController.js | 427 + controllers/visitasController.js | 427 + forever.json | 10 + helpers/CheckToken.js | 118 + helpers/config.js | 103 + helpers/generateBarCode.js | 28 + helpers/helper.js | 333 + helpers/mycsv.csv | 3 + helpers/serialBook.js | 115 + package-lock.json | 9701 +++++++++++++++++ package.json | 72 + server.js | 160 + wgetOut | 0 68 files changed, 35125 insertions(+) create mode 100644 .checkAPI.sh.swp create mode 100644 .env create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 checkAPI.sh create mode 100644 connections/mysql-server.js create mode 100644 connections/sql-server.js create mode 100644 controllers/addressController.js create mode 100644 controllers/agendaController.js create mode 100644 controllers/alexaController.js create mode 100644 controllers/animationsController.js create mode 100644 controllers/answerController.js create mode 100644 controllers/appController.js create mode 100644 controllers/barcodeController.js create mode 100644 controllers/baseController.js create mode 100644 controllers/chamadaController.js create mode 100644 controllers/charactersController.js create mode 100644 controllers/chatController.js create mode 100644 controllers/chattimeController.js create mode 100644 controllers/chattimeController_bkp.js create mode 100644 controllers/classController.js create mode 100644 controllers/classescontentController.js create mode 100644 controllers/conceptsController.js create mode 100644 controllers/configController.js create mode 100644 controllers/courseController.js create mode 100644 controllers/coursesStudentController.js create mode 100644 controllers/curiositiesController.js create mode 100644 controllers/customizeController.js create mode 100644 controllers/elloController.js create mode 100644 controllers/emailController.js create mode 100644 controllers/exerciseController.js create mode 100644 controllers/fileController.js create mode 100644 controllers/franchiseeController.js create mode 100644 controllers/holidayController.js create mode 100644 controllers/ig40Controller.js create mode 100644 controllers/iyrcController.js create mode 100644 controllers/listenrepeatController.js create mode 100644 controllers/loginController.js create mode 100644 controllers/migrationController.js create mode 100644 controllers/permissoesController.js create mode 100644 controllers/productsController.js create mode 100644 controllers/qrController.js create mode 100644 controllers/questionController.js create mode 100644 controllers/relatorioController.js create mode 100644 controllers/slidesController.js create mode 100644 controllers/sqlServerController.js create mode 100644 controllers/studentController.js create mode 100644 controllers/teacherController.js create mode 100644 controllers/textController.js create mode 100644 controllers/traineeprogramController.js create mode 100644 controllers/traineeprogramcoursesController.js create mode 100644 controllers/typescourseController.js create mode 100644 controllers/unileverController.js create mode 100644 controllers/unityController.js create mode 100644 controllers/usersController.js create mode 100644 controllers/videoController.js create mode 100644 controllers/visitasController.js create mode 100644 forever.json create mode 100644 helpers/CheckToken.js create mode 100644 helpers/config.js create mode 100644 helpers/generateBarCode.js create mode 100644 helpers/helper.js create mode 100644 helpers/mycsv.csv create mode 100644 helpers/serialBook.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 server.js create mode 100644 wgetOut diff --git a/.checkAPI.sh.swp b/.checkAPI.sh.swp new file mode 100644 index 0000000000000000000000000000000000000000..cfbf39ed26e1f763ca7ee8efe343ae3d94155bcd GIT binary patch literal 1024 zcmYc?$V<%2S1{5u)iY*50>?cW7>e@qOOS+cGBXQw4b6>ojSY1TO?3^8OmHbo&PYwp Xb`0>;E6%{BWK?`K1V%%Ejv)X5Fp3S5 literal 0 HcmV?d00001 diff --git a/.env b/.env new file mode 100644 index 0000000..337185b --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +#.env, don't commit to repo +SECRET=FREYNEYMARWEDR \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..239e458 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +# .env.example, commit to repo +SECRET= \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b24d71e --- /dev/null +++ b/.gitignore @@ -0,0 +1,50 @@ +# These are some examples of commonly ignored file patterns. +# You should customize this list as applicable to your project. +# Learn more about .gitignore: +# https://www.atlassian.com/git/tutorials/saving-changes/gitignore + +# Node artifact files +node_modules/ +dist/ + +# Compiled Java class files +*.class + +# Compiled Python bytecode +*.py[cod] + +# Log files +*.log + +# Package files +*.jar + +# Maven +target/ +dist/ + +# JetBrains IDE +.idea/ + +# Unit test reports +TEST*.xml + +# Generated by MacOS +.DS_Store + +# Generated by Windows +Thumbs.db + +# Applications +*.app +*.exe +*.war + +# Large media files +*.mp4 +*.tiff +*.avi +*.flv +*.mov +*.wmv + diff --git a/checkAPI.sh b/checkAPI.sh new file mode 100644 index 0000000..4427cf9 --- /dev/null +++ b/checkAPI.sh @@ -0,0 +1,10 @@ +wget -O wgetOut "http://127.0.0.1:3337/api/units/listlogin"; +if [[ $? -ne 0 ]]; then + echo "API Offline" + sudo /usr/bin/forever; forever stop zoe_api + sudo /usr/bin/forever; forever start /var/www/zoe_api/forever.json + exit 1; +else + echo "API Online" + exit 0; +fi diff --git a/connections/mysql-server.js b/connections/mysql-server.js new file mode 100644 index 0000000..ccd4252 --- /dev/null +++ b/connections/mysql-server.js @@ -0,0 +1,124 @@ +const mysql = require('mysql'); +require('../helpers/config'); +require('../helpers/CheckToken'); +require("dotenv-safe").load(); +var jwt = require('jsonwebtoken'); + +var MySQLConfig = { + connectionLimit: 100, // Reduzido de 1000 para 100 + host: Variables('ip_mysql'), + user: Variables('user_mysql'), + database: Variables('database_mysql'), + password: Variables('password_mysql'), + charset: "utf8mb4" +}; + +// Criação do pool de conexões MySQL +let pool = mysql.createPool(MySQLConfig); +console.log("MySQL Pool criado!"); + +// Atribui a conexão global à primeira conexão disponível do pool +global.mysqlConnection = pool; + +// Função para verificar se o pool está ativo +function isPoolActive() { + return pool && !pool._closed; +} + +// Função para recriar o pool se ele estiver fechado +function recreatePoolIfClosed() { + if (!isPoolActive()) { + console.log('Recriando o pool de conexões MySQL...'); + pool = mysql.createPool(MySQLConfig); + console.log("Novo MySQL Pool criado!"); + } +} + +// Função para executar uma query SQL com verificação do pool +global.execSQLQuery = function execSQLQuery(sqlQry, res, req, Parametros = null, callback = null) { + // Verifica e recria o pool se necessário + recreatePoolIfClosed(); + + pool.query(sqlQry, Parametros, function (error, results, fields) { + if (error) { + console.error('Erro na consulta MySQL:', error); + + if (error.toString().includes("PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR") || error.toString().includes("Connection lost")) { + console.log('Tentando reconectar e executar a consulta novamente...'); + execSQLQuery(sqlQry, res, req, Parametros, callback); // Reexecuta a query + return; + } + if (error.toString().includes("Too many connections")) { + console.log('Muitas conexões abertas. Aguardando antes de tentar novamente...'); + setTimeout(() => { + execSQLQuery(sqlQry, res, req, Parametros, callback); + }, 1000); // Aumente o tempo de espera para reduzir a sobrecarga + return; + } + + // Retorno de erro + let Retorno = { "status": 500, "error": error, "response": [] }; + res.send(JSON.stringify(Retorno)); + console.log(new Date().toUTCString() + ` - ${req}/ error 500`); + if (callback) callback(Retorno); + return; + } + + // Retorno de sucesso + let Retorno = { "status": 200, "error": null, "response": results }; + res.send(JSON.stringify(Retorno)); + console.log(new Date().toUTCString() + ` - ${req}/ success 200`); + if (callback) callback(Retorno); + }); +}; + +// Similarmente, aplique a verificação nas outras funções +global.execMySQLQueryLogin = function execMySQLQueryLogin(sqlQry, res, req) { + recreatePoolIfClosed(); + + pool.query(sqlQry, function (error, results, fields) { + if (error || results.length == 0) { + res.send(JSON.stringify({ + "status": 500, + "error": error, + "response": [], + "token": null + })); + console.log(new Date().toUTCString() + " - " + req + "/ error 500"); + return; + } + + var token = jwt.sign({ id }, process.env.SECRET, { + expiresIn: Variables('time_token') + }); + res.send(JSON.stringify({ + "status": 200, + "error": null, + "response": results, + "token": token + })); + console.log(new Date().toUTCString() + " - " + req + "/ success 200"); + }); +}; + +global.execSQLQueryVideo = function execSQLQueryVideo(sqlQry, res, req) { + recreatePoolIfClosed(); + + pool.query(sqlQry, function (error, results, fields) { + if (!error && results.length != 0) { + let idvideoaccess = results[0]['idvideoaccess']; + res.redirect(results[0]['url']); + + // Atualização após redirecionamento + setTimeout(() => { + pool.query(`UPDATE videoaccess SET expired = 1 where idvideoaccess = ${idvideoaccess}`, function (error, results, fields) { + if (error) { + console.error('Erro ao atualizar videoaccess:', error); + } + }); + }, 1000); + } else { + res.send("not found"); + } + }); +}; diff --git a/connections/sql-server.js b/connections/sql-server.js new file mode 100644 index 0000000..303a2f4 --- /dev/null +++ b/connections/sql-server.js @@ -0,0 +1,80 @@ +const sql = require('mssql'); +require('../helpers/config'); +require('../helpers/CheckToken'); + +const ip = Variables('ip_sqlServer'); +const user = Variables('user_sqlServer'); +const pass = Variables('password_sqlServer'); +require("dotenv-safe").load(); +var jwt = require('jsonwebtoken'); + +const connStr = "Server=" + ip + ";User Id=" + user + ";Password=" + pass; + +global.AtualizaConexaoSQLServer = function AtualizaConexaoSQLServer() { + console.log("Renovando conexão SQLServer..."); + try { + sql.close(); + } + catch (e) {} + sql.connect(connStr).then(sqlServerConnection => { + global.sqlServerConnection = sqlServerConnection; + console.log('SQLServer Conectado!'); + }).catch(err => { + global.sqlServerConnection = null; + console.log("Impossivel conectar ao SQL Server..."); + //console.log(err) + }); +} + +AtualizaConexaoSQLServer(); + +global.execSQLQuery2 = function execSQLQuery2(sqlQry, res, req, callback = null) { + if (Variables("local") == "Local") { + res.send(JSON.stringify({ + "status": 403, + "error": "Modo de emergência, SQL Server desconectado", + "response": [] + })); + console.log(new Date().toUTCString() + " - " + req + "/ error 403"); + return; + } + sqlServerConnection.request().query(sqlQry, function (error, results, fields) { + let Retorno = []; + if (error || results.length == 0) { + Retorno = { "status": 500, "error": error, "response": [] }; + } + else { + Retorno = { "status": 200, "error": error, "response": results.recordsets }; + } + res.send(JSON.stringify(Retorno)); + console.log(new Date().toUTCString() + ` - ${req}/ ${(Retorno.status == 500) ? 'error' : 'success'} ${Retorno.status}`); + if (callback) + callback(Retorno); + }); +}; + +global.execSQLQueryLogin = function execSQLQueryLogin(sqlQry, res, req) { + sqlServerConnection.request().query(sqlQry, function (error, results, fields) { + if (error || results.recordsets[0].length == 0) { + res.send(JSON.stringify({ + "status": 500, + "error": error, + "response": [], + "token": null + })) + console.log(new Date().toUTCString() + " - " + req + "/ error 500"); + } + else { + var token = jwt.sign({ id }, process.env.SECRET, { + expiresIn: Variables('time_token') + }); + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": results.recordsets, + "token": token //encriptPassword(token, token.length) + })); + console.log(new Date().toUTCString() + " - " + req + "/ success 200"); + } + }) +}; \ No newline at end of file diff --git a/controllers/addressController.js b/controllers/addressController.js new file mode 100644 index 0000000..d31ec57 --- /dev/null +++ b/controllers/addressController.js @@ -0,0 +1,29 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/states', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM states;`, res, req.originalUrl); + }); + + router.get('/citiesbyState/:idstates', verifyJWT, (req, res) => { + const idstates = parseInt(req.params.idstates); + execSQLQuery(`SELECT + * + FROM cities + WHERE idstates = ${idstates};`, res, req.originalUrl); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/agendaController.js b/controllers/agendaController.js new file mode 100644 index 0000000..5c02be0 --- /dev/null +++ b/controllers/agendaController.js @@ -0,0 +1,60 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/getAllEventos', (req, res) => { + execSQLQuery(`SELECT + * + FROM agenda;`, res, req.originalUrl); + }); + + router.post('/insertEventos', verifyJWT, (req, res) => { + const title = req.body.title; + const date = req.body.date; + const hour = req.body.hour; + const duration = req.body.duration; + const description = req.body.description; + const access = req.body.access; + execSQLQuery(` INSERT INTO agenda (title, date, hour, duration, description, access) values + ( + ?,?,'2021-01-01T${hour}',?,?,? + )` , res, req.originalUrl, [title, date, duration, description, access]); + }); + + router.post('/editEventos', verifyJWT, (req, res) => { + const id = req.body.id; + const title = req.body.title; + const date = req.body.date; + const hour = req.body.hour; + const duration = req.body.duration; + const description = req.body.description; + const access = req.body.access; + execSQLQuery(` UPDATE agenda SET + title='${title}', + date='${date}', + hour='2021-01-01T${hour}', + duration='${duration}', + description='${description}', + access='${access}' + WHERE (idagenda = '${id}')` + , res, req.originalUrl); + }); + + router.post('/deleteEventos', verifyJWT, (req, res) => { + const id = req.body.id; + execSQLQuery(` DELETE FROM agenda + WHERE (idagenda = '${id}')` + , res, req.originalUrl); + }); + + return router; +}; + +module.exports = routes; \ No newline at end of file diff --git a/controllers/alexaController.js b/controllers/alexaController.js new file mode 100644 index 0000000..8972472 --- /dev/null +++ b/controllers/alexaController.js @@ -0,0 +1,1383 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const formidable = require('formidable'); +const express = require('express'); +const router = express.Router(); + +var { spawn } = require('child_process'); +let bodyParser = require('body-parser'); +router.use(bodyParser.json({ + verify: function getRawBody(req, res, buf) { + req.rawBody = buf.toString(); + } +})); + +var routes = function () { + + // #region Alexa expressions + router.get('/getCurrentExpression/:idusers/:idunits', verifyJWT, (req, res) => { + let idusers = req.params.idusers; + let idunits = req.params.idunits; + execSQLQuery(`SELECT idexpressions AS Epressao, role AS Modo FROM alexaexpression WHERE idusers = ${idusers} AND idunits = ${idunits};`, res, req.originalUrl); + }) + + router.get('/listAlexaintents', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * FROM alexaintents;`, res, req.originalUrl); + }) + + router.patch('/updateCurrentExpression', verifyJWT, (req, res) => { + let idusers = req.body.idusers; + let idunits = req.body.idunits; + let role = req.body.role; + let idexpressions = req.body.idexpressions; + execSQLQuery(`UPDATE alexaexpression SET role = ${role}, idexpressions = ${idexpressions} WHERE idusers = ${idusers} AND idunits = ${idunits};`, res, req.originalUrl); + }) + + // #endregion + + // #region Alexa intents + router.get('/listAlexaintents', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * FROM alexaintents;`, res, req.originalUrl); + }) + + router.get('/getAlexaintent/:idalexaintents', verifyJWT, (req, res) => { + let idalexaintents = req.params.idalexaintents; + execSQLQuery(`SELECT * FROM alexaintents WHERE idalexaintents = ${idalexaintents};`, res, req.originalUrl); + }) + + router.get('/getReqIntent/:idalexaintents', verifyJWT, (req, res) => { + const idalexaintents = req.params.idalexaintents; + execSQLQuery(`SELECT + ait.reqIntent + FROM alexanextintents ani + inner join alexaintents ait on ait.idalexaintents = ani.idalexaintents_next + where ani.idalexaintents = ${idalexaintents};`, res, req.originalUrl); + }); + + router.get('/getFirstIntentofTree/:idconversationtree', verifyJWT, (req, res) => { + let idconversationtree = req.params.idconversationtree; + execSQLQuery(` + SELECT ai.reqIntent + FROM alexanextintents an + INNER JOIN alexaintents ai ON ai.idalexaintents = an.idalexaintents + WHERE an.idconversationtree = ${idconversationtree} LIMIT 1;`, res, req.originalUrl); + }) + + router.get('/deleteAlexaintent/:idalexaintents', verifyJWT, (req, res) => { + let idalexaintents = req.params.idalexaintents; + execSQLQuery(`DELETE FROM alexaintents WHERE idalexaintents = ${idalexaintents};`, res, req.originalUrl); + }) + + router.post('/insertAlexaintent', verifyJWT, (req, res) => { + const reqIntent = req.body.reqIntent; + const resIntent = req.body.resIntent; + const exampleResponse = req.body.exampleResponse; + const endSession = req.body.endSession ? 1 : 0; + const askRobot = req.body.askRobot ? 1 : 0; + execSQLQuery(`INSERT INTO alexaintents(reqIntent, resIntent, endSession, exampleResponse, askRobot) + VALUES ("${reqIntent}","${resIntent}", ${endSession}, "${exampleResponse}", ${askRobot});`, res, req.originalUrl); + }) + + router.patch('/updateAlexaintent', verifyJWT, (req, res) => { + const idalexaintents = req.body.idalexaintents; + const reqIntent = req.body.reqIntent; + const resIntent = req.body.resIntent; + const exampleResponse = req.body.exampleResponse; + const endSession = req.body.endSession ? 1 : 0; + const askRobot = req.body.askRobot ? 1 : 0; + execSQLQuery(`UPDATE alexaintents SET + reqIntent = "${reqIntent}", + resIntent = "${resIntent}", + endSession = ${endSession}, + exampleResponse = "${exampleResponse}", + askRobot = ${askRobot} + WHERE + idalexaintents = ${idalexaintents};`, res, req.originalUrl); + }) + + // #endregion + + // #region Alexa next intents + router.get('/listAlexanextintents', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * FROM alexanextintents;`, res, req.originalUrl); + }) + + router.get('/deleteAlexanextintent/:idconversationtree', verifyJWT, (req, res) => { + let idconversationtree = req.params.idconversationtree; + execSQLQuery(`DELETE FROM alexanextintents WHERE idconversationtree = ${idconversationtree};`, res, req.originalUrl); + }) + + router.post('/insertAlexanextintent', verifyJWT, (req, res) => { + const idalexaintents = req.body.idalexaintents; + const idalexaintents_next = req.body.idalexaintents_next; + const idconversationtree = req.body.idconversationtree; + execSQLQuery(`INSERT INTO alexanextintents (idalexaintents, idalexaintents_next, idconversationtree) + VALUES (${idalexaintents},${idalexaintents_next}, ${idconversationtree});`, res, req.originalUrl); + }) + + router.get('/getconnectionsbyid/:idalexaintents', verifyJWT, (req, res) => { + let idalexaintents = req.params.idalexaintents; + execSQLQuery(`SELECT * FROM alexanextintents WHERE idalexaintents = ${idalexaintents};`, res, req.originalUrl); + }) + + router.get('/getnextintents/:idalexaintents/:campo', verifyJWT, (req, res) => { + let idalexaintents = req.params.idalexaintents; + let campo = req.params.campo; + + execSQLQuery(` + SELECT + ai.idalexaintents, + ai.reqIntent, + ai.resIntent, + an.idalexaintents_next, + ai.endsession, + ai.exampleResponse, + ai.askRobot + FROM + alexanextintents an + RIGHT JOIN + alexaintents ai ON an.idalexaintents = ai.idalexaintents + WHERE ${campo} = ${idalexaintents};`, res, req.originalUrl); + }) + + router.get('/getConnectionsbytree/:idconversationtree', verifyJWT, (req, res) => { + let idconversationtree = req.params.idconversationtree; + + execSQLQuery(` + SELECT + ai.idalexaintents, + ai.reqIntent, + ai.resIntent, + an.idalexaintents_next, + ai.endsession, + ai.exampleResponse, + ai.askRobot + FROM + alexanextintents an + RIGHT JOIN + alexaintents ai ON an.idalexaintents = ai.idalexaintents + WHERE idconversationtree = ${idconversationtree}; + `, res, req.originalUrl); + }) + + // #endregion + + // #region Alexa Sentences + router.post('/insertAlexasentence', verifyJWT, (req, res) => { + const idalexaintents = req.body.idalexaintents; + const sentence = req.body.sentence; + execSQLQuery(`INSERT INTO alexasentences(idalexaintents, sentence) VALUES (${idalexaintents},"${sentence}");`, res, req.originalUrl); + }) + + router.patch('/updateAlexasentence', verifyJWT, (req, res) => { + const idalexasentences = req.body.idalexasentences; + const sentence = req.body.sentence; + execSQLQuery(`UPDATE alexasentences SET sentence = "${sentence}" WHERE idalexasentences = ${idalexasentences};`, res, req.originalUrl); + }) + + router.get('/deleteAlexasentence/:idalexasentences', verifyJWT, (req, res) => { + let idalexasentences = req.params.idalexasentences; + execSQLQuery(`DELETE FROM alexasentences WHERE idalexasentences = ${idalexasentences};`, res, req.originalUrl); + }) + + router.get('/getListAlexasentence', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * FROM alexasentences;`, res, req.originalUrl); + }) + + router.get('/getAlexasentencebyintent/:idalexaintents', verifyJWT, (req, res) => { + let idalexaintents = req.params.idalexaintents; + execSQLQuery(`SELECT * FROM alexasentences WHERE idalexaintents = ${idalexaintents};`, res, req.originalUrl); + }) + + router.get('/deleteAlexasentences/:idalexaintents', verifyJWT, (req, res) => { + let idalexaintents = req.params.idalexaintents; + execSQLQuery(`DELETE FROM alexasentences WHERE idalexaintents = ${idalexaintents};`, res, req.originalUrl); + }) + + router.post('/deleteAlexasentenceBySentence', verifyJWT, (req, res) => { + let sentence = req.body.sentence; + let sqlQry = `DELETE FROM alexasentences WHERE sentence = "${sentence}";`; + execSQLQuery(sqlQry, res, req.originalUrl); + }) + + // #endregion + + // #region Árvore de conversação + router.post('/insertConversationtree', verifyJWT, (req, res) => { + const idconversationtree = req.body.idconversationtree; + const description = req.body.description; + execSQLQuery(`INSERT INTO alexaconversationtree (description) VALUES ("${description}");`, res, req.originalUrl); + }) + + router.patch('/updateConversationtree', verifyJWT, (req, res) => { + const idconversationtree = req.body.idconversationtree; + const description = req.body.description; + execSQLQuery(`UPDATE alexaconversationtree SET description = "${description}" WHERE idconversationtree = ${idconversationtree};`, res, req.originalUrl); + }) + + router.get('/listConversationtree', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * FROM alexaconversationtree;`, res, req.originalUrl); + }) + + router.get('/getConversationtree/:idconversationtree', verifyJWT, (req, res) => { + let idconversationtree = req.params.idconversationtree; + execSQLQuery(`SELECT * FROM alexaconversationtree WHERE idconversationtree = ${idconversationtree};`, res, req.originalUrl); + }) + + router.get('/deleteConversationtree/:idconversationtree', verifyJWT, (req, res) => { + let idconversationtree = req.params.idconversationtree; + execSQLQuery(`DELETE FROM alexaconversationtree WHERE idconversationtree = ${idconversationtree};`, res, req.originalUrl); + }) + + // #endregion + + // #region Variaveis + router.post('/insertVariables', verifyJWT, (req, res) => { + const idalexavariables = req.body.idalexavariables; + const description = req.body.description; + execSQLQuery(`INSERT INTO alexavariables (description) VALUES ('${description}');`, res, req.originalUrl); + }) + + router.patch('/updateVariables', verifyJWT, (req, res) => { + const idalexavariables = req.body.idalexavariables; + const description = req.body.description; + execSQLQuery(`UPDATE alexavariables SET description = '${description}' WHERE idalexavariables = ${idalexavariables};`, res, req.originalUrl); + }) + + router.get('/listVariables', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * FROM alexavariables;`, res, req.originalUrl); + }) + + router.get('/getVariable/:idalexavariables', verifyJWT, (req, res) => { + let idalexavariables = req.params.idalexavariables; + execSQLQuery(`SELECT * FROM alexavariables WHERE idalexavariables = ${idalexavariables};`, res, req.originalUrl); + }) + + // #endregion + + // #region Variaveis de usuário + router.post('/insertUserVariables', verifyJWT, (req, res) => { + const idalexauservariables = req.body.idalexauservariables; + const idalexavariables = req.body.idalexavariables; + const valuecli = req.params.valuecli; + const idusers = req.params.idusers; + const idunits = req.params.idunits; + execSQLQuery(`INSERT INTO alexauservariables (idalexavariables, valuecli, idusers, idunits) + VALUES (${idalexavariables}, '${valuecli}', ${idusers}, ${idunits});`, res, req.originalUrl); + }) + + router.patch('/updateUserVariables', verifyJWT, (req, res) => { + const idalexauservariables = req.body.idalexauservariables; + const idalexavariables = req.body.idalexavariables; + const valuecli = req.params.valuecli; + const idusers = req.params.idusers; + const idunits = req.params.idunits; + execSQLQuery(` + UPDATE alexauservariables SET + idalexavariables = ${idalexavariables}, + valuecli = '${valuecli}', + idusers = ${idusers}, + iduntis = ${idunits} + WHERE idalexauservariables = ${idalexauservariables};`, res, req.originalUrl); + }) + + router.get('/listUserVariables', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * FROM alexauservariables;`, res, req.originalUrl); + }) + + router.get('/getUserVariable/:idalexavariables', verifyJWT, (req, res) => { + let idalexauservariables = req.params.idalexauservariables; + execSQLQuery(`SELECT * FROM alexauservariables WHERE idalexauservariables = ${idalexauservariables};`, res, req.originalUrl); + }) + + // #endregion + + // #region Requisição do robô + + const FraseNaoEntendeu = "Sorry, I didn't understand you. Could you repeat please?"; + const VelocidadePadrao = 0.85; + router.post('/recognizeAudio/:token', (req, res) => { + let token = req.params.token; + if(token != Variables("tk_fixed")) { + res.status(500).send({ status: 'expired' }); + return; + } + console.log("/RecognizeAudio"); + // RECEBE DADOS DA REQUISIÇÃO + let form = new formidable.IncomingForm(); + form.maxFileSize = 1024 * 1024 * 1024; + form.on('file', function(name, file) { }); + form.on('error', function(err) { }); + form.on('aborted', function() { }); + form.parse(req, function(err, fields, files) { + const fs = require('fs'); + var Modo = fields.Modo; + var SessaoID = fields.SessaoID; + var CaminhoArquivo; + var UltimoIntentID = fields.UltimoIntentID; + var Vezes = fields.Vezes; + var ArvoreID = fields.ArvoreID; + var Matricula = fields.Matricula; + var IDUnidade = fields.IDUnidade; + var IDAula = fields.IDAula || 0; + var Intencao = fields.Intencao || ""; + var Velocidade = fields.Velocidade || VelocidadePadrao; + + try { + CaminhoArquivo = files.Arquivo.path; + } + catch (e) { + console.log("Sem audio na entrada"); + } + + // CRIA VARIAVEL COM A DATA ATUAL PARA RENOMEAR O ARQUIVO COM A IDENTIFICACAO DO ALUNO + let date_ob = new Date(); + let DataHoje = date_ob.getDate() + "-" + (date_ob.getMonth() + 1) + "-" + date_ob.getFullYear() + "-" + date_ob.getHours() + "-" + date_ob.getMinutes() + "-" + date_ob.getSeconds(); + var NomeArquivo = Matricula + "_" + IDUnidade + "_" + IDAula + "_" + DataHoje + ".mp3"; + + if (Intencao.length > 2) { // SE A INTECAO ESCOLHIDA JA ESTIVER NO CORPO DA REQUISICAO + + if (Modo == "exercise") { // SE O MODO EXERCICIO + + console.log("Exercício de pronúncia - Robot"); + EnviaResposta(Intencao, NomeArquivo, res, 0, Intencao, 0, 0, 0, 1, Velocidade); + + } + else if (Modo == "conversation") { // SE O MODO FOR CONVERSAOCAO LIVRE + console.log("Conversação livre"); + // ENVIA A PERGUNTA PARA MITSUKU + EnviaPerguntaMitsuku(Intencao, SessaoID, function(Resposta) { + EnviaResposta(Resposta, NomeArquivo, res, 0, Resposta, Vezes, 0, 0, 1, Velocidade); + }); + } + else { // (classroom) SE O MODO FOR SALA DE AULA + + let sqlQry1 = `SELECT * FROM alexaintents WHERE reqIntent = "${Intencao}";`; + mysqlConnection.query(sqlQry1, function (error, results, fields) { + if (results.length > 0) { + EnviaResposta(results[0].resIntent, NomeArquivo, res, results[0].idalexaintents, results[0].exampleResponse, 0, results[0].endSession, results[0].askRobot, 1, Velocidade); + } + }) + + } + + } + else { // SE TIVER QUE PROCESSAR A FRASE DO ALUNO + + // COPIAR O AUDIO DE ENTRADA NO SERVIDOR + fs.rename(CaminhoArquivo, Variables('src_media') + 'alexa/' + NomeArquivo, function (err) { + if (err) throw err; + const shell = require('shelljs'); + + // CONVERTER O .mp3 para .wav + //const ComandoConvert = `ffmpeg -i ${Variables('src_media')}alexa/${NomeArquivo} ${Variables('src_media')}alexa/${NomeArquivo}.wav`; + //shell.exec(ComandoConvert, function (sucesso) { + //NomeArquivo += ".wav"; + + // CONVERTER O .wav PARA TEXTO + var audioTotext = null; + if (Modo == "classroom") { + let Comando = 'export GOOGLE_APPLICATION_CREDENTIALS="/var/www/html/assets/ZoeRobot-1ead32c17478.json";python ' + Variables('src_media') + 'assets/speech_cloud.py ' + NomeArquivo; + //let Comando = 'python ' + Variables('src_media') + 'assets/audio_to_text.py ' + NomeArquivo; + //console.log(Comando); + audioTotext = shell.exec(Comando); + } + else { + let Comando = 'python ' + Variables('src_media') + 'assets/audio_to_text.py ' + NomeArquivo; + //audioTotext = spawn('python', [Variables('src_media') + 'assets/audio_to_text.py', NomeArquivo]); + audioTotext = shell.exec(Comando); + } + + var Pergunta = audioTotext.stdout; + console.log("Aluno: " + Pergunta); + + if (Modo == "conversation") { // MODO CONVERSACAO LIVRE + console.log("Conversação livre"); + // ENVIA A PERGUNTA PARA MITSUKU + EnviaPerguntaMitsuku(Pergunta, SessaoID, function(Resposta) { + if (Pergunta.includes("Google Speech Recognition could not understand audio") || Pergunta.includes("Could not request results from Google Speech Recognition service")) + Resposta = FraseNaoEntendeu; + EnviaResposta(Resposta, NomeArquivo, res, 0, Resposta, Vezes, 0, 0, 1, Velocidade); + }); + } + else if (Modo == "classroom") { // MODO SALA DE AULA + console.log("Conversação em ambiente de aula"); + // VERIFICA A INTENCAO ATRAVES DA SENTENCA PROFERIDA PELO USUARIO + VerificaIntencao(ArvoreID, Pergunta, UltimoIntentID, Vezes, Matricula, IDUnidade, function(Resposta, idalexaintents, ExemploResposta, newVezes, Final, RetornaPergunta, Coerente) { + EnviaResposta(Resposta, NomeArquivo, res, idalexaintents, ExemploResposta, newVezes, Final, RetornaPergunta, Coerente, Velocidade); + }); + } + else if (Modo == "config") { // MODO CONFIGURACAO DE VARIAVEIS + console.log("Configuração de variáveis do usuário"); + ModoConfiguracao(Pergunta, NomeArquivo, res, Matricula, IDUnidade); + } + else if (Modo == "exercise") { // MODO EXERCICIO DE PRONUNCIA - verifica a pronúncia do aluno + console.log("Exercício de pronúncia - Aluno"); + EnviaResposta(Pergunta, NomeArquivo, res, 0, Pergunta, 0, 0, 0, 1, Velocidade); + } + + //}); + + }) + + } + + }); + }) + + function EnviaResposta(Resposta, NomeArquivo, res, idalexaintents, ExemploResposta, Vezes, Final, RetornaPergunta, Coerente, Velocidade) { + console.log("Robot: " + Resposta); + const fs = require('fs'); + const shell = require('shelljs'); + const ModoCoversao = 3; + + if (ModoCoversao == 1) { + // CONVERTE A RESPOSTA EM TEXTO PARA AUDIO + shell.exec(`pico2wave --wave=${Variables("src_media") + "alexa/" + NomeArquivo.split('.')[0]}.wav "${Resposta}"`, function(Resultado) { + // CONVERTE O AUDIO .WAV PARA .MP3 + shell.exec(`ffmpeg -i ${Variables('src_media')}alexa/${NomeArquivo.split('.')[0]}.wav ${Variables('src_media')}alexa/${NomeArquivo.split('.')[0]}_exit.mp3 -loglevel quiet -stats`, function (sucesso) { + // APAGA O AUDIO .WAV DO SERVIDOR + shell.exec(`rm ${Variables('src_media')}alexa/${NomeArquivo.split('.')[0]}.wav`); + // ENVIA O LINK DO AUDIO GERADO COMO RETORNO DA REQUISIÇÃO + res.send(JSON.stringify({ + "status": 200, + "url_audio": "http://18.228.91.135/alexa/" + NomeArquivo.split(".")[0] + "_exit.mp3", + "UltimoIntentID": idalexaintents, + "Vezes": Vezes, + "ExemploResposta": ExemploResposta, + "Final": Final, + "RetornaPergunta": RetornaPergunta, + "Coerente": Coerente + })); + // EXCLUI O ARQUIVO DE AUDIO DE ENTRADA + shell.exec('rm ' + Variables('src_media') + 'alexa/' + NomeArquivo); + }); + + }); + } + else if (ModoCoversao == 2) { + // CONVERTE A RESPOSTA EM TEXTO PARA AUDIO + shell.exec(`python ${Variables('src_media')}assets/text_to_audio2.py "${Resposta}" ${NomeArquivo}`, function(Sucesso) { + // ENVIA O LINK DO AUDIO GERADO COMO RETORNO DA REQUISIÇÃO + res.send(JSON.stringify({ + "status": 200, + "url_audio": "http://18.228.91.135/alexa/" + NomeArquivo.split(".")[0] + "_exit.mp3", + "UltimoIntentID": idalexaintents, + "Vezes": Vezes, + "ExemploResposta": ExemploResposta, + "Final": Final, + "RetornaPergunta": RetornaPergunta, + "Coerente": Coerente + })); + // EXCLUI O ARQUIVO DE AUDIO DE ENTRADA + shell.exec('rm ' + Variables('src_media') + 'alexa/' + NomeArquivo); + }); + } + else if (ModoCoversao == 3) { + const request = require('request'); + var options = { + uri: 'https://texttospeechapi.wideo.co/api/wideo-text-to-speech', + method: 'POST', + json: { "data":{"text":Resposta,"speed":Velocidade,"voice":"en-US-Standard-H"} } + }; + request(options, function (error, response, body) { + if (!error && response.statusCode == 200) { + shell.exec(`wget "${response['body']['result']['url']}" -O ${Variables("src_media")}alexa/${NomeArquivo.split(".")[0]}_exit.mp3 -q;`, function(Sucesso) { + res.send(JSON.stringify({ + "status": 200, + "url_audio": "http://18.228.91.135/alexa/" + NomeArquivo.split(".")[0] + "_exit.mp3", + "UltimoIntentID": idalexaintents, + "Vezes": Vezes, + "ExemploResposta": ExemploResposta, + "Final": Final, + "RetornaPergunta": RetornaPergunta, + "Coerente": Coerente + })); + // EXCLUI O ARQUIVO DE AUDIO DE ENTRADA + shell.exec('rm ' + Variables('src_media') + 'alexa/' + NomeArquivo); + }); + } + }); + } + else { + // CONVERTE A RESPOSTA EM TEXTO PARA AUDIO + const textToaudio = spawn('python', [Variables('src_media') + 'assets/text_to_audio.py', Resposta, NomeArquivo]); + textToaudio.stdout.on('data', function(data) { + // ENVIA O LINK DO AUDIO GERADO COMO RETORNO DA REQUISIÇÃO + res.send(JSON.stringify({ + "status": 200, + "url_audio": "http://18.228.91.135/alexa/" + NomeArquivo.split(".")[0] + "_exit.mp3", + "UltimoIntentID": idalexaintents, + "Vezes": Vezes, + "ExemploResposta": ExemploResposta, + "Final": Final, + "RetornaPergunta": RetornaPergunta, + "Coerente": Coerente + })) + + // EXCLUI O ARQUIVO DE AUDIO DE ENTRADA + try { + fs.unlinkSync(Variables('src_media') + 'alexa/' + NomeArquivo); + } + catch (e) { + console.log("Sem audio na entrada para excluir"); + } + }); + } + + } + + function EnviaPerguntaMitsuku(Pergunta, SessaoID, callback) { + + // TROCA A PALAVRA ZOE POR MITSUKU + Pergunta = ReplaceAll(Pergunta, ["Zoe"], ["Mitsuku"], 10); + + // ENVIA A PERGUNTA EM TEXTO PARA MITSUKU + const querystring = require('querystring'); + const request = require('request'); + var form = { + input: Pergunta, + botid: '9fa364f2fe345a10', // ID do bot (CONSTANTE) + custid: SessaoID // ID do usuário falando com o bot, ex: b3dfe148ae499f98 + }; + var formData = querystring.stringify(form); + request({ + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, + uri: 'https://kakko.pandorabots.com/pandora/talk-xml', + body: formData, + method: 'POST' + }, function (err, res2, body) { + var striptags = require('striptags'); + var Resposta = body; + try { Resposta = body.split('')[1].split('')[0]; } catch (e) { } + Resposta = decodeURI(Resposta); + Resposta = striptags(Resposta); + + RemoverTagsDoTexto(Resposta, ["xgallery.", "xloadswf2.", "xloadswf3.", "xlink.", "xnslink."], function(NewResposta) { + + if (NewResposta.includes("Human Virus deletion program started")) + NewResposta = NewResposta.split("Human Virus deletion program started")[0]; + + if (NewResposta.includes("This is a list of the games I can play with you")) + NewResposta = NewResposta.split(".")[NewResposta.split(".").length - 1]; + + if (NewResposta.includes("<img") && NewResposta.includes("/img>")) + NewResposta = NewResposta.split("<P")[0] + NewResposta.split("/P>")[1]; + + if (NewResposta.includes("<P") && NewResposta.includes("/P>")) + NewResposta = NewResposta.split("<P")[0] + NewResposta.split("/P>")[1]; + + NewResposta = ReplaceAll(NewResposta, ["Mitsuku", "<br>", """], ["Zoe", " ", '"'], 15); + + callback(NewResposta); + }); + + }); + } + + function ReplaceAll(Texto, Palavras, TrocarPor, Vezes) { + for (let i = 0; i < Vezes; i++) { + for (let o = 0; o < Palavras.length; o++) { + Texto = Texto.replace(Palavras[o], TrocarPor[o]); + } + } + return Texto; + } + + function VerificaIntencao(ArvoreID, Pergunta, UltimoIntentID, Vezes, Matricula, IDUnidade, callback) { + // PROCURA POR UMA SENTENCA QUE SEJA IGUAL A QUE O USUARIO PROFERIU + let newPergunta = Pergunta.substring(0, Pergunta.length - 1); + let sqlQry1 = `SELECT * FROM alexasentences WHERE sentence = "${newPergunta}";`; + mysqlConnection.query(sqlQry1, function (error, results, fields) { + if (results.length == 0) { // NAO ENCONTROU UMA INTENCAO A PRIMEIRA INSTANCIA + // SEPARA A FRASE DO USUARIO POR PALAVRAS + let Palavras = newPergunta.split(' '); + //Palavras[Palavras.length - 1] = Palavras[Palavras.length - 1].substring(0, Palavras[Palavras.length - 1].length - 1); + // PROCURA EM TODAS AS SENTENCAS A MAIS PROXIMA DA QUAL O USUARIO PROFERIU + AproximacaoSentencial(Palavras, ArvoreID, function(Intencao) { + // VERIFICA SE A INTENCAO ESTA LIGADA AO CONTEXTO + VerificaConexoes(ArvoreID, Intencao, UltimoIntentID, Vezes, Pergunta, Matricula, IDUnidade, function(Resposta, ExemploResposta, newVezes, newUltimoIntentID, Final, RetornaPergunta, Coerente) { + callback(Resposta, newUltimoIntentID, ExemploResposta, newVezes, Final, RetornaPergunta, Coerente); + }); + }); + } + else { // ENCONTROU UMA INTENCAO A PRIMEIRA INSTANCIA + // VERIFICA SE A INTENCAO ESTA LIGADA AO CONTEXTO + let AlexaSentence = results; + VerificaConexoes(ArvoreID, AlexaSentence[0], UltimoIntentID, Vezes, Pergunta, Matricula, IDUnidade, function(Resposta, ExemploResposta, newVezes, newUltimoIntentID, Final, RetornaPergunta, Coerente) { + callback(Resposta, newUltimoIntentID, ExemploResposta, newVezes, Final, RetornaPergunta, Coerente); + }) + } + + }); + } + + function AproximacaoSentencial(Palavras, idconversationtree, callback) { + /*let sqlQry1 = `SELECT R.idalexaintents, (SELECT sentence FROM alexasentences WHERE idalexaintents = R.idalexaintents LIMIT 1) AS sentence FROM (SELECT idalexaintents, (`; + for (let i = 0; i < Palavras.length; i++) { + if (i > 0) + sqlQry1 += ` + `; + sqlQry1 += `CASE WHEN sentence LIKE "%${Palavras[i]}%" THEN 1 ELSE 0 END`; + } + sqlQry1 += `) AS Qtde FROM alexasentences WHERE `; + for (let o = 0; o < Palavras.length; o++) { + if (o > 0) + sqlQry1 += ` OR `; + sqlQry1 += `sentence LIKE "%${Palavras[o]}%"`; + } + sqlQry1 += ` GROUP BY idalexaintents, Qtde ORDER BY Qtde DESC LIMIT 1) R RIGHT JOIN alexanextintents an ON an.idalexaintents = R.idalexaintents WHERE an.idconversationtree = ${idconversationtree} LIMIT 1;`;*/ + let sqlQry1 = `SELECT * FROM (SELECT idalexasentences, sentence, (`; + for (let i = 0; i < Palavras.length; i++) { + if (i > 0) + sqlQry1 += ` + `; + sqlQry1 += `CASE WHEN sentence LIKE "%${Palavras[i]}%" THEN 1 ELSE 0 END`; + } + sqlQry1 += `) AS Qtde FROM alexasentences WHERE `; + for (let o = 0; o < Palavras.length; o++) { + if (o > 0) + sqlQry1 += ` OR `; + sqlQry1 += `sentence LIKE "%${Palavras[o]}%"`; + } + sqlQry1 += ` GROUP BY idalexaintents, idalexasentences, Qtde ORDER BY Qtde DESC) R + INNER JOIN (select + als.idalexasentences, + als.idalexaintents, + als.sentence, + ali.reqIntent, + ali.resIntent, + ani.idalexaintents_next, + (select als1.sentence from alexasentences als1 where als1.idalexaintents = ani.idalexaintents_next limit 1) as 'nextSentece' + from alexaintents ali + inner join alexasentences als on als.idalexaintents = ali.idalexaintents + inner join alexanextintents ani on ani.idalexaintents = als.idalexaintents + where ani.idconversationtree = ${idconversationtree} + order by ani.idalexanextintents asc) T + on T.idalexasentences = R.idalexasentences + order by R.Qtde desc;`; + //console.log(sqlQry1); + mysqlConnection.query(sqlQry1, function (error, results, fields) { + callback(results); + }); + + } + + function VerificaConexoes(ArvoreID, Intencao, UltimoIntentID, Vezes, Pergunta, Matricula, IDUnidade, callback) { + //console.log(Intencao); + // CONSULTA A RESPOSTA PARA A INTENCAO REQUISITADA + Vezes++; + let FraseIntencaoNaoEncontrada = FraseNaoEntendeu; + if (!Intencao || Intencao.length == 0) { + IntencaoResposta = FraseIntencaoNaoEncontrada; + callback(IntencaoResposta, "", Vezes, UltimoIntentID, false, 0); + return; + } + else { + if (Intencao.length > 1) + Intencao = Intencao[0]; + } + + // SQL PARA CONFERIR SE A FRASE DO ALUNO CONDIZ COM O DIALOGO + let sqlQry0 = `SELECT an.*, ai.resIntent FROM alexanextintents an INNER JOIN alexaintents ai ON ai.idalexaintents = an.idalexaintents WHERE an.idalexaintents = ${UltimoIntentID};`; + + // CONSULTAR A INTENCAO ANTERIOR + mysqlConnection.query(sqlQry0, function (error0, results0, fields0) { + let Coerente = false; + let UltimaPergunta = ""; + if (results0.length > 0) { + // CONSULTAR SE A INTENCAO DITA PELO ALUNO ESTA PRESENTE NA ARVORE DE INTENCOES ATUAL + for (let i = 0; i < results0.length; i++) { + if (results0[i].idalexaintents_next == Intencao['idalexaintents']) { + Coerente = true; + UltimaPergunta = results0[i].resIntent; + } + } + } + // SE FOR A PRIMEIRA CHAMADA DO ALUNO E NAO TIVER UMA INTENT ANTERIOR + if (UltimoIntentID == 0) { + Coerente = true; + UltimaPergunta = Intencao['resIntent']; + } + // SE NAO ESTIVER, ALUNO DISSE ALGO QUE NAO CONDIZ COM O DIALOGO ESPERADO + if (!Coerente) { + IntencaoResposta = FraseIntencaoNaoEncontrada; + callback(IntencaoResposta, "", Vezes, UltimoIntentID, false, 0); + return; + } + else { + // SE A INTENCAO DO ALUNO FOR COERENTE COM O DIALOGO + let sqlQry1 = `SELECT * FROM alexaintents WHERE idalexaintents = ${Intencao['idalexaintents']};`; + mysqlConnection.query(sqlQry1, function (error, results, fields) { + let IntencaoResposta = ""; + let IntencaoExemplo = ""; + let Final = 0; + let RetornaPergunta = 0; + let newUltimoIntentID = Intencao['idalexaintents']; + + // ENCONTROU A INTENCAO DO USUARIO + if (Intencao['idalexaintents'] != 0 && results.length > 0) { + IntencaoResposta = results[0]['resIntent']; + Final = results[0]['endSession']; + RetornaPergunta = results[0]['askRobot']; + if (Intencao['idalexaintents'] == 33) + IntencaoExemplo = UltimaPergunta; + else + IntencaoExemplo = results[0]['exampleResponse']; + } + else // NAO ENCONTROU A INTENCAO + IntencaoResposta = FraseIntencaoNaoEncontrada; + + if (IntencaoResposta == "I said, " && UltimoIntentID != 0) { // SE O USUARIOS ESTIVER PEDINDO PRA REPETIR + // CONSULTA QUAL FOI A ULTIMA INTENCAO DITA PELO ROBO PARA ESTE REPETIR + let sqlQry3 = `SELECT * FROM alexaintents WHERE idalexaintents = ${UltimoIntentID};`; + mysqlConnection.query(sqlQry3, function (error, results3, fields) { + // CONCATENA AS DUAS RESPOSTAS + IntencaoResposta += results3[0]['resIntent']; + IntencaoExemplo = results3[0]['exampleResponse']; + newUltimoIntentID = UltimoIntentID; + + VerificaVariaveis(IntencaoResposta, Pergunta, Matricula, IDUnidade, Intencao, function(NovaResposta) { + callback(NovaResposta, IntencaoExemplo, Vezes, newUltimoIntentID, Final, RetornaPergunta, 1); + }) + }); + } + else { // SE FOR QUALQUER OUTRA INTENCAO QUE NAO 'REPEAT PLEASE' + if (UltimoIntentID == 0) { // SE O ULTIMO INTENTID FOR '0', ENTAO É A PRIMEIRA FRASE DO ROBO E NAO VERIFICA AS CONEXOES + VerificaVariaveis(IntencaoResposta, Pergunta, Matricula, IDUnidade, Intencao, function(NovaResposta) { + callback(NovaResposta, IntencaoExemplo, Vezes, newUltimoIntentID, Final, RetornaPergunta, 1); + }) + } + else { // SE JA ESTIVER EM CONVERSACAO, VERIFICAR AS CONEXOES DE CONTEXTO DO DIALOGO + let sqlQry2 = `SELECT * FROM alexanextintents WHERE idalexaintents = ${UltimoIntentID} AND idconversationtree = ${ArvoreID};`; + mysqlConnection.query(sqlQry2, function (error, results2, fields) { + // CRIA LISTA COM PROXIMAS INTENCOES POSSIVEIS + if (results2.length > 0) { + let ProximasIntencoes = results2; + let IntencaoValida = false; + for (let i = 0; i < ProximasIntencoes.length; i++) { + // VERIFICA SE A INTENCAO REQUISITADA ESTA CONTIDA NA LISTA DE POSSIVEIS INTENCOES DE RESPOSTA + if (ProximasIntencoes[i]['idalexaintents_next'] == Intencao['idalexaintents']) { + IntencaoValida = true; + break; + } + } + + if (!IntencaoValida) // SE A INTENCAO NAO ESTIVER NA LISTA + IntencaoResposta = FraseIntencaoNaoEncontrada; + } + else // SE NAO HOUVER UMA POSSIVEL CONEXAO PARA ESSA INTENCAO + IntencaoResposta = FraseIntencaoNaoEncontrada; + + VerificaVariaveis(IntencaoResposta, Pergunta, Matricula, IDUnidade, Intencao, function(NovaResposta) { + callback(NovaResposta, IntencaoExemplo, Vezes, newUltimoIntentID, Final, RetornaPergunta, 1); + }) + }); + } + } + + + }); + + } + }); + + } + + function VerificaVariaveis(IntencaoResposta, Pergunta, Matricula, IDUnidade, Intencao, callback) { + let Variaveis = []; + let VariaveisValor = []; + let ArrayFrase; + let VariavelRobo = false; + let VariavelAluno = false; + try { + if (IntencaoResposta.includes('+')) // VERIFICA SE POSSUI VARIAVEIS NA RESPOSTA DO ROBO + VariavelRobo = true; + if (Intencao['sentence'].includes('+')) // VERIFICA SE POSSUI VARIAVEIS NA RESPOSTA DO ALUNO + VariavelAluno = true; + + if (!VariavelRobo && !VariavelAluno) // SE NAO POSSUIR NENHUMA VARIAVEL NA SENTENCA + fs.readdir("/ss") // CAUSA UM ERRO PARA O SISTEMA PULAR PARA O CATCH + + if (VariavelAluno) { // EXISTE VARIAVEIS NA RESPOSTA DO ALUNO - ATUALIZAR/INSERIR OS VALORES + // MONTA UM ARRAY COM A FRASE DE RESPOSTA DO ALUNO + ArrayFrase = Intencao['sentence'].split('+'); + for (let i = 1; i < ArrayFrase.length; i = i + 2) { + Variaveis.push(ArrayFrase[i]); + VariaveisValor.push(""); + } + + for (let x = 0; x < Variaveis.length; x++) { // CONSULTAR O VALOR DE CADA VARIAVEL PARA ATUALIZACAO DE VALORES + let sqlSearchVariable = `SELECT + au.valuecli + FROM alexauservariables au + INNER JOIN alexavariables av ON av.idalexavariables = au.idalexavariables + WHERE au.idusers = ${Matricula} AND au.idunits = ${IDUnidade} AND av.description = '${Variaveis[x]}';`; + AtualizaValoresVariaveis(sqlSearchVariable, IntencaoResposta, Pergunta, Variaveis, Matricula, IDUnidade, function(valuecli) { + //console.log("Variavel " + Variaveis[x] + " atualizada com sucesso!"); + + if (x == Variaveis.length - 1) { // ULTIMA VARIAVEL JA ATUALIZADA + if (!VariavelRobo) // NAO EIXSTE VARIAVEIS NA FRASE DE RESPOSTA DO ROBO + callback(IntencaoResposta); + else { // EXISTE VARIAVEIS NA FRASE DE RESPOSTA DO ROBO - ATUALIZAR A FRASE COM ESSES VALORES + ArrayFrase = []; + Variaveis = []; + VariaveisValor = []; + + // MONTA UM ARRAY COM A FRASE DE RESPOSTA DO ROBO + ArrayFrase = IntencaoResposta.split('+'); + for (let i = 1; i < ArrayFrase.length; i = i + 2) { + Variaveis.push(ArrayFrase[i]); + VariaveisValor.push(""); + } + + for (let i = 0; i < Variaveis.length; i++) { // CONSULTAR O VALOR DE CADA VARIAVEL CONTIDA NA FRASE DE RESPOSTA + ConsultarValorVariavel(Variaveis[i], Matricula, IDUnidade, function(valuecli) { + VariaveisValor[i] = valuecli; + + if (i == Variaveis.length - 1) { + for (let y = 0; y < Variaveis.length; y++) { + let splitResposta = IntencaoResposta.split('+' + Variaveis[y] + '+'); + newResposta = splitResposta[0] + VariaveisValor[y] + splitResposta[1]; // REMONTA A FRASE SUBSTITUINDO OS VALORES DAS VARIAVEIS + IntencaoResposta = newResposta; + + if (y == Variaveis.length - 1) // ULTIMA VARIAVEL JA SUBSTITUIDA + callback(IntencaoResposta); // RETORNA NOVA FRASE + } + } + }) + } + + } + } + }); + } + + } + } + catch (e) { // NAO EXISTE VARIAVEL NA SENTENCA + callback(IntencaoResposta); + } + } + + function AtualizaValoresVariaveis(sqlSearchVariable, IntencaoResposta, Pergunta, Variaveis, Matricula, IDUnidade, callback) { + let ModoInserir; + mysqlConnection.query(sqlSearchVariable, function (error, results0, fields) { + if (results0.length > 0) { // ENCONTROU UM VALOR JA ATRIBUIDO PARA ESSA VARIAVEL + ModoInserir = false + } + else { // NAO ENCONTROU UM VALOR PARA ESSA VARIAVEL + ModoInserir = true; + } + + // VERIFICA TODAS AS SENTENCAS DESSA INTENCAO + let sqlQry1 = `SELECT + * + FROM alexasentences + WHERE idalexaintents = (SELECT idalexaintents FROM alexaintents WHERE resIntent = "${IntencaoResposta}");`; + mysqlConnection.query(sqlQry1, function (error, results, fields) { + let ArrayPergunta = Pergunta.split(' '); + let UltimoIndexArray = ArrayPergunta.length - 1; + for (let i = 0; i < ArrayPergunta[UltimoIndexArray].length; i++) { // REMOVE O \r\n DO FINAL DA ULTIMA PALAVRA + let UltimaLeta = ArrayPergunta[UltimoIndexArray][ArrayPergunta[UltimoIndexArray].length - 1]; + if (UltimaLeta == "\r" || UltimaLeta == "\n") { + ArrayPergunta[UltimoIndexArray] = ArrayPergunta[UltimoIndexArray].substring(0, ArrayPergunta[UltimoIndexArray].length - 1); + } + else + break; + } + // MONTA ARRAY COM TODAS AS SENTENCAS DESSA INTENCAO + let Sentencas = []; + for (let o = 0; o < results.length; o++) { + Sentencas.push(results[o]['sentence'].split(' ')); + } + let NovoValor = ""; + let indexVariavelAtual = 0; + // PARA CADA VARIAVEL CONTIDA NA FRASE + for (let i = 0; i < Variaveis.length; i++) { + // PARA CADA SENTENCA VERIFICA QUAIS AS PALAVRAS NAO ESTAO PRESENTES NESTA PARA VERIFICAR SE CONDIZ COM A VARIAVEL + indexVariavelAtual = i; + for (let o = 0; o < Sentencas.length; o++) { // PARA CADA SENTENCA + for (let p = 0; p < ArrayPergunta.length; p++) { // PARA CADA PALAVRA DA FRASE DO USUARIO + for (let q = 0; q < Sentencas[o].length; q++) { // PARA CADA PALAVRA DE CADA SENTENCA + if (Sentencas[o][q] == ArrayPergunta[p]) // VERIFICA SE AS PALAVRAS SAO IGUAIS + ArrayPergunta[p] = ''; // SE IGUAIS ENTAO REMOVE, MANTENDO SOMENTE AS DIFERENTES NO ARRAY + } + } + } + + // VERIFICAR OS VALORES QUE SAO DIFERENTES DAS PALAVRAS CONTIDAS NAS FRASES, ATRIBUINDO O VALOR DA VARIAVEL COM ESTE + for (let o = 0; o < ArrayPergunta.length; o++) { + if (ArrayPergunta[o] != '') { + if (!Variaveis[i].includes("Spell")) // SE FOR ALGUMA VARIAVEL DE TEXTO + NovoValor = ArrayPergunta[o]; + else { // SE FOR ALGUMA VARIAVEL DE SOLETRAGEM + if (ArrayPergunta[o].length == 1) // SE A PALAVRAS TIVER APENAS UMA LETRA + NovoValor += ArrayPergunta[o] + "-"; + } + } + } + + if (Variaveis[i].includes("Spell")) + NovoValor = NovoValor.substring(0, NovoValor.length - 1); // REMOVE O ULTIMO - DA VARIAVEL + + } + // ALTERA O VALOR DA VARIAVEL PARA O NOVO VALOR DITO PELO ALUNO + InserirValorVariavel(ModoInserir, Variaveis[indexVariavelAtual], NovoValor, Matricula, IDUnidade, function(Sucesso) { + callback(NovoValor); + }); + + }); + }); + } + + function ModoConfiguracao(Pergunta, NomeArquivo, res, Matricula, IDUnidade) { + let Resposta = ""; + try { + if (Pergunta.toLowerCase().includes("change my")) { // ALTERAR VALOR DA VARIAVEL - FRASE EXEMPLO: change my name to Diego + let Variavel = Pergunta.split(' ')[2]; // change my NAME to diego + let NovoValor = Pergunta.split(' ')[4]; // change my name to DIEGO + NovoValor = NovoValor.substring(0, NovoValor.length - 1); + let sqlSearchVariable = `SELECT au.valuecli FROM alexauservariables au INNER JOIN alexavariables av + ON av.idalexavariables = au.idalexavariables WHERE au.idusers = ${Matricula} AND au.idunits = ${IDUnidade} AND av.description = '${Variavel}';`; + mysqlConnection.query(sqlSearchVariable, function (error, results, fields) { + let ModoInserir = false; + if (results.length == 0) + ModoInserir = false; + InserirValorVariavel(ModoInserir, Variavel, NovoValor, Matricula, IDUnidade, function(Sucesso) { + if (Sucesso) // CONSEGUIU DEFINIR A VARIAVEL COM O NOVO VALOR + Resposta = "Your " + Variavel + " was changed to " + NovoValor; + else // ERRO AO DEFINIR NOVO VALOR PARA VARIAVEL + Resposta = "Fail to define your " + Variavel; + EnviaResposta(Resposta, NomeArquivo, res, 0, "", 0, 1, 1, VelocidadePadrao); + }) + }) + } + else if (Pergunta.toLowerCase().includes("say my")) { // FALAR VALOR DA VARIAVEL - FRASE EXEMPLO: say my name + let Variavel = Pergunta.split(' ')[2]; // say my NAME + Variavel = Variavel.substring(0, Variavel.length - 1); + ConsultarValorVariavel(Variavel, Matricula, IDUnidade, function(valuecli) { + if (valuecli != "") // ENCONTROU VALOR PARA ESSA VARIAVEL + Resposta = "Your " + Variavel + " is " + results[0]['valuecli']; + else // NAO ENCONTROU VALOR PARA ESSA VARIAVEL + Resposta = "I yet not know your " + Variavel + ". Say change my " + Variavel + " to your " + Variavel + " to insert it."; + + EnviaResposta(Resposta, NomeArquivo, res, 0, "", 0, 1, 1, VelocidadePadrao); + }) + } + else { // COMANDO DESCONHECIDO + Resposta = FraseNaoEntendeu; + EnviaResposta(Resposta, NomeArquivo, res, 0, "", 0, 1, 1, VelocidadePadrao); + } + } + catch(e) { // HOUVE ALGUM ERRO DURANTE O PROCESSO OU FRASE INCORRETA + Resposta = FraseNaoEntendeu; + EnviaResposta(Resposta, NomeArquivo, res, 0, "", 0, 1, 1, VelocidadePadrao); + } + } + + function InserirValorVariavel(Inserir, Variavel, NovoValor, Matricula, IDUnidade, callback) { + let sqlChangeVariable = ``; + if (Inserir == true) { + sqlChangeVariable = `INSERT INTO alexauservariables (idalexavariables, valuecli, idusers, idunits) + VALUES ((SELECT idalexavariables FROM alexavariables WHERE description = '${Variavel}'), '${NovoValor}', ${Matricula}, ${IDUnidade});`; + } + else { + sqlChangeVariable = `UPDATE alexauservariables SET valuecli = '${NovoValor}' + WHERE idalexavariables = (SELECT idalexavariables FROM alexavariables WHERE description = '${Variavel}') AND idusers = ${Matricula} AND idunits = ${IDUnidade};`; + } + mysqlConnection.query(sqlChangeVariable, function (error, results, fields) { + let Sucesso = true; + if (error) + Sucesso = false; + callback(Sucesso); + }) + } + + function ConsultarValorVariavel(Variavel, Matricula, IDUnidade, callback) { + let sqlShowVariable = `SELECT au.valuecli FROM alexauservariables au INNER JOIN alexavariables av + ON av.idalexavariables = au.idalexavariables WHERE au.idusers = ${Matricula} AND au.idunits = ${IDUnidade} AND av.description = '${Variavel}';`; + mysqlConnection.query(sqlShowVariable, function (error, results, fields) { + let ValorVariavel = ""; + if (results.length > 0) + ValorVariavel = results[0]['valuecli']; + else + ValorVariavel = ""; + callback(ValorVariavel); + }); + } + + function RemoverTagsDoTexto(Texto, Palavras, callback) { + let NovoTexto = ""; + for (let p = 0; p < Palavras.length; p++) { + for (var i = 0; i < Texto.split(Palavras[p]).length; i++) { + if (i % 2 == 0) + NovoTexto += Texto.split(Palavras[p])[i]; + } + if (NovoTexto != "") + Texto = NovoTexto; + NovoTexto = ""; + } + callback(Texto); + } + + router.post('/recognizeFace/:token', (req, res) => { + let token = req.params.token; + if(token != Variables("tk_fixed")) { + res.status(500).send({ status: 'expired' }); + return; + } + console.log("/RecognizeFace"); + let form = new formidable.IncomingForm(); + form.maxFileSize = 1024 * 1024 * 1024; + form.parse(req, function(err,fields,files){ + const fs = require('fs'); + var Foto = files.foto; + var CaminhoFoto = Variables('src_media') + 'faces/temp/' + Foto.name; + fs.rename(Foto.path, CaminhoFoto, function (err) { + if (err) throw err; + const shell = require('shelljs'); + let ResRecognition = shell.exec("python3 " + Variables('src_media') + 'assets/login_face.py ' + CaminhoFoto); + let Matricula = ResRecognition.split('\\')[0]; + if (Matricula.length < 1) + Matricula = "N/A"; + //console.log(Matricula); + res.send(Matricula); + }); + }); + + }) + + router.post('/cadastroFace/:token', (req, res) => { + let token = req.params.token; + if(token != Variables("tk_fixed")) { + res.status(500).send({ status: 'expired' }); + return; + } + console.log("/RecognizeFace"); + let fs = require('fs'); + let form = new formidable.IncomingForm(); + form.maxFileSize = 1024 * 1024 * 1024; + form.parse(req, function(err,fields,files){ + let Matricula = fields.Matricula; + let Amostras = fields.Amostras; + let Fotos = ""; + for (let i = 0; i < Amostras; i++) { + let Path = files['foto_' + (i + 1)].path; + let CaminhoFoto = Variables('src_media') + 'faces/temp/foto_' + (i + 1) + '.jpg'; + fs.renameSync(Path, CaminhoFoto); + Fotos += " " + CaminhoFoto; + } + const Comando = 'python3 ' + Variables('src_media') + 'assets/cadastro_rosto.py ' + Matricula + Fotos; + const shell = require('shelljs'); + let Request = shell.exec(Comando); + if (Request.stderr == '') + res.send(true); + else + res.send(false); + }) + }) + + // #endregion + + + // #region ALEXA SKILL AMAZOM + + router.post('/', function(req, res) { + if (req.body.request.type === 'LaunchRequest') { + console.log("Requisição Alexa"); + NextIntents.push({ + idalexaintents: [4], + sessionId: req.body.session.sessionId + }) + //res.json(SendResponse("Hello! You have opened the MyRobot Dialog assistent! What is your name?", false)); + res.json(SendResponse("Hey, what’s your name?", false)); + } + else if (req.body.request.type === 'IntentRequest') { + var NameIntent = req.body.request.intent.name; + console.log(NameIntent); + + CheckIntent(req, res, NameIntent) + } + else { + console.log("ELSE"); + res.json(SendResponse("Sorry, I did not understand you! Can you repeat please?", false)); + } + }); + + function SendResponse(speechText, shouldEndSession) { + const speechOutput = "" + speechText + "" + var jsonObj = { + "version": "1.0", + "response": { + "shouldEndSession": shouldEndSession, + "outputSpeech": { + "type": "SSML", + "ssml": speechOutput + }, + "card": { + "type": "Simple", + "title": "MyRobot Dialog", + "content": speechText, + "text": speechText + }, + "reprompt": { + "outputSpeech": { + "type": "PlainText", + "text": speechText, + "ssml": speechText + } + } + } + } + return jsonObj + } + + function CheckIntent(req, res, NameIntent, implement = "") { + let isRepeat = false; + let CorrectIntent = false; + try { + let resposta = req.body.request.intent.slots['Query'].value; + console.log("MyRobot Conversation"); + console.log("Usuario: " + req.body.request.intent.slots['Query'].value); + GetMitsukoResponse(resposta, false, res); + return; + } + catch(e) { + if (this.JustConversation) { + if (NameIntent == "AMAZON.HelpIntent") { + res.json(SendResponse("This skill is a conversation with Mitsuko. Say hello to begin a chat, for example: Hello, my name is Tommy!", false)); + return; + } + res.json(SendResponse("Sorry, I did not understand you! Can you repeat please?", false)); + return; + } + console.log("MyRobot Dialog"); + } + if (NameIntent == "RepeatPleaseIntent") { + isRepeat = true; + NameIntent = LastIntent; + } + const SQLQry = ` + SELECT + ai.idalexaintents, + ai.reqIntent, + ai.resIntent, + ai.endSession, + ai.exampleResponse, + an.idalexaintents_next + FROM + alexaintents ai + LEFT JOIN + alexanextintents an + ON + ai.idalexaintents = an.idalexaintents + WHERE + ai.reqIntent = '${NameIntent}';`; + try { + mysqlConnection.query(SQLQry, function (error, results, fields) { + if (results.length == 0) { + try { + let resposta = req.body.request.intent.slots['Query'].value; + GetMitsukoResponse(resposta, false, res, req.body.session.sessionId); + return; + } + catch(e) { + if (NameIntent == "AMAZON.HelpIntent") { + res.json(SendResponse("This skill is a conversation with Mitsuko. Say hello to begin a chat, for example: Hello, my name is Tommy!", false)); + return; + } + res.json(SendResponse("Sorry, I did not understand you! Can you repeat please?", false)); + return; + } + } + + for (let i = NextIntents.length - 1; i >= 0; i--) { + if (NextIntents[i].sessionId == req.body.session.sessionId) { + for (let o = 0; o < results.length; o++) { + if (results[o]['idalexaintents_next'] == null) { + CorrectIntent = true; + break; + } + for (let f = 0; f < NextIntents[i].idalexaintents.length; f++) { + if (results[o]['idalexaintents'] == NextIntents[i].idalexaintents[f] || NextIntents[i].idalexaintents[0] == null) { + CorrectIntent = true; + NextIntents[i].idalexaintents = []; + for (let g = 0; g < results.length; g++) { + NextIntents[i].idalexaintents.push(results[g]['idalexaintents_next']); + } + } + } + } + } + } + + if (isRepeat) { + CorrectIntent = true; + implement = "I said, "; + } + + if (NameIntent == "AMAZON.HelpIntent") { + res.json(SendResponse("This skill is a conversation with Mitsuko, you can to begin a chat saying hello, my name is... for example.", false)); + return; + } + + if (!CorrectIntent && + NameIntent != "IntentExit" && + NameIntent != "IntentStop" && + NameIntent != "AMAZON.StopIntent" && + NameIntent != "AMAZON.CancelIntent" + ) { + res.json(SendResponse("Sorry, I did not understand you! Can you repeat please?", false)); + return; + } + + if ( + NameIntent == "IntentStop" || + NameIntent == "AMAZON.StopIntent" || + NameIntent == "AMAZON.CancelIntent" || + NameIntent == "IntentUsername" + ) { + NextIntents[NextIntents.length - 1].idalexaintents = [ null ]; + } + var resText = implement + results[0]['resIntent']; + var splitRes = resText.split('+'); + var response = ""; + let slotVal = ""; + for (let i = 0; i < splitRes.length; i++) { + if (i % 2 == 0) + response+= splitRes[i]; + else { + let Add = true; + for (let o = 0; o < Slots.length; o++) { + if (Slots[o].name == splitRes[i] && Slots[o].sessionId == req.body.session.sessionId && Slots[o].name != "Subject") { + Add = false; + slotVal = Slots[o].value; + } + } + if (Add) { + try { + Slots.push( { + name: splitRes[i], + value: req.body.request.intent.slots[splitRes[i]].value, + sessionId: req.body.session.sessionId + }); + } + catch (e) { + Slots.push( { + name: splitRes[i], + value: "undefined", + sessionId: req.body.session.sessionId + }); + } + slotVal = Slots[Slots.length - 1].value; + } + response+= slotVal; + } + } + + if (results[0]['endSession'] == true) { + for (let o = 0; o < Slots.length; o++) { + if (Slots[o].sessionId == req.body.session.sessionId) { + Slots.splice(o, 1); + } + } + } + + if (slotVal != "" && FirstAction) { + for (let y = Slots.length - 1; y >= 0; y--) { + if (Slots[y].name == "Action" && Slots[y].value == slotVal) { + if (Slots[y].value == "chat") { + FirstAction = false; + CheckIntent(req, res, "IntentChat", resText); + return; + } + } + else if (Slots[y].name == "Subject" && Slots[y].value == slotVal) { + let Complement = resText; + if (Slots[y].value == "movie" || Slots[y].value == "movies") { + Complement += " I like that! "; + FirstAction = false; + CheckIntent(req, res, "IntentMovie", Complement); + return; + } + else if (Slots[y].value == "family") { + Complement += " I like talk about it! "; + FirstAction = false; + CheckIntent(req, res, "IntentFamily", Complement); + return; + } + } + /*else if (Slots[y].name == "Movie" && Slots[y].value == slotVal) { + FirstAction = false; + CheckIntent(req, res, "IntentFamily", resText); + return; + }*/ + } + } + + if (!FirstAction) + FirstAction = true; + + res.json(SendResponse(response, results[0]['endSession'])); + //GetMitsukoResponse(response, results[0]['endSession'], res); + + }) + } + catch (e) { + if (NameIntent == "AMAZON.HelpIntent") { + res.json(SendResponse("This skill is a conversation with Mitsuko, you can to begin a chat saying hello, my name is... for example.", false)); + return; + } + } + LastIntent = NameIntent; + } + + function GetMitsukoResponse(Question, EndSession, res, Sessao) { + let Resposta = ""; + var querystring = require('querystring'); + var request = require('request'); + + var form = { + input: Question, + botid: '9fa364f2fe345a10', // ID do bot (trocar ? melhor não) + //custid: 'b3dfe148ae499f98' // ID do usuário falando com o bot + custid: Sessao // ID do usuário falando com o bot + }; + + var formData = querystring.stringify(form); + + request({ + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, + uri: 'https://kakko.pandorabots.com/pandora/talk-xml', + body: formData, + method: 'POST' + }, function (err, res2, body) { + var striptags = require('striptags'); + Resposta = body.split('')[1].split('')[0]; + Resposta = decodeURI(Resposta); + Resposta = striptags(Resposta); + let NewResposta = ""; + for (var i = 0; i < Resposta.split('xgallery.').length; i++) { + if (i % 2 == 0) + NewResposta += Resposta.split('xgallery.')[i]; + } + if (NewResposta == "") + Resposta = NewResposta; + + console.log("Mitsuko: " + NewResposta); + + res.json(SendResponse(NewResposta, EndSession)); + }); + + } + + // #endregion + + + return router; +} + +module.exports = routes; diff --git a/controllers/animationsController.js b/controllers/animationsController.js new file mode 100644 index 0000000..0164d3a --- /dev/null +++ b/controllers/animationsController.js @@ -0,0 +1,307 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); +const formidable = require('formidable'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ + parameterLimit: 100000, + limit: '350mb', + extended: true +})); +router.use(bodyParser.json({ + parameterLimit: 100000, + limit: '350mb', + extended: true +})); + +const routes = function () { + + //#region ANIMATIONS + router.get('/getAllAnimations', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM animations;`, res, req.originalUrl); + }); + + router.get('/getAnimation/:idanimations', verifyJWT, (req, res) => { + const idanimations = req.params.idanimations; + execSQLQuery(`SELECT + * + FROM animations + WHERE idanimations = ${idanimations};`, res, req.originalUrl); + }); + + router.post('/insertAnimation', verifyJWT, (req, res) => { + const idanimations = req.body.idanimations; + const description = req.body.description; + execSQLQuery(`INSERT INTO animations(description) + VALUES (?);`, res, req.originalUrl, [description]); + }); + + router.patch('/updateAnimation', verifyJWT, (req, res) => { + const idanimations = req.body.idanimations; + const description = req.body.description; + execSQLQuery(`UPDATE animations SET + description = ? + WHERE idanimations = ?;`, res, req.originalUrl, [description, idanimations]); + }); + + router.delete('/removeAnimation/:idanimations', verifyJWT, (req, res) => { + const idanimations = req.params.idanimations; + execSQLQuery(`DELETE FROM animations + WHERE idanimations = ${idanimations};`, res, req.originalUrl); + }); + + router.post('/CopiarArquivo', verifyJWT, (req, res) => { + let form = new formidable.IncomingForm(); + form.maxFileSize = 1024 * 1024 * 1024; + form.parse(req, function(err,fields,files){ + const fs = require('fs'); + var idanimations = fields.idanimations; + var dir = Variables('src_media') + 'animations/' + idanimations; + + var oldpath = files.file.path; + fs.rename(oldpath, dir + '.mp4', function (err) { + if (err) throw err; + if(fs.existsSync(dir + '.zip')) { + fs.unlink(dir + '.zip', function(err) { + zipArquivo(idanimations, dir, res); + }); + } + else { + zipArquivo(idanimations, dir, res); + } + }); + + }); + }); + + router.get('/backAnimation/:idanimations', (req, res) => { + var idanimations = req.params.idanimations; + var dir = Variables('src_media') + 'animations/tmp/var/www/html/animations/' + idanimations + '.mp4'; + const fs = require('fs'); + + if(fs.existsSync(dir)) { + const fs = require('fs'); + fs.readFile(dir, (err, data) => { + if (err) throw err; + console.log("Requisição de animação: " + idanimations); + res.setHeader('Content-Type', 'video/mp4'); + res.send(data); + }); + } + else { + require('all-unpacker').unpack(Variables('src_media') + 'animations/' + idanimations + '.zip', { + targetDir: Variables('src_media') + 'animations/tmp/', + password: Variables('passdecrypt'), + forceOverwrite: true, + }, function(err, files, text) { + if (err) return console.error(err); + if (files) console.log('files', files); + if (text) { + console.log('text', text) + fs.readFile(dir, (err, data) => { + if (err) throw err; + console.log("Requisição de animação: " + idanimations); + res.setHeader('Content-Type', 'video/mp4'); + res.send(data); + }); + }; + }); + } + }); + + //#endregion + + //#region ANIMATIONEXERCISES + router.get('/getAllAnimationExercises', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM animationexercises;`, res, req.originalUrl); + }); + + router.get('/getAnimationExercises/:idanimations', verifyJWT, (req, res) => { + const idanimations = req.params.idanimations; + execSQLQuery(` + SELECT + ae.*, + CASE + WHEN ae.idexercises IS NOT NULL THEN (SELECT e.description FROM exercises e WHERE e.idexercises = ae.idexercises) + WHEN ae.idconversationtree IS NOT NULL THEN (SELECT ct.description FROM alexaconversationtree ct WHERE ct.idconversationtree = ae.idconversationtree) + WHEN ae.idzoechattime IS NOT NULL THEN (SELECT z.description FROM zoechattime z WHERE z.idzoechattime = ae.idzoechattime) + END AS 'description', + CASE + WHEN ae.idexercises IS NOT NULL THEN 'Exercício' + WHEN ae.idconversationtree IS NOT NULL THEN 'Conversação' + WHEN ae.idzoechattime IS NOT NULL THEN 'ChatTime' + END AS 'type' + FROM + animationexercises ae + WHERE + ae.idanimations = ${idanimations} + ORDER BY ae.seconds;`, res, req.originalUrl); + }); + + router.delete('/removeAnimationExercise/:idanimationexercises', verifyJWT, (req, res) => { + const idanimationexercises = req.params.idanimationexercises; + execSQLQuery(`DELETE FROM animationexercises + WHERE idanimationexercises = ${idanimationexercises};`, res, req.originalUrl); + }); + + //#endregion + + //#region EXERCISE + + router.post('/insertAnimationExercise', verifyJWT, (req, res) => { + const idanimationexercises = req.body.idanimationexercises; + const idanimations = parseInt(req.body.idanimations); + const idexercises = parseInt(req.body.idexercises); + execSQLQuery(`INSERT INTO animationexercises (idexercises, idanimations, seconds) + VALUES (${idexercises}, ${idanimations}, 0);`, res, req.originalUrl); + }) + + router.patch('/updateAnimationExercise', verifyJWT, (req, res) => { + const idanimationexercises = parseInt(req.body.idanimationexercises); + const idanimations = req.body.idanimations; + const idexercises = req.body.idexercises; + const seconds = parseInt(req.body.seconds); + execSQLQuery(`UPDATE animationexercises SET + seconds = ${seconds} + WHERE idanimationexercises = ${idanimationexercises};`, res, req.originalUrl); + }); + + router.delete('/deleteExercise/:idexercises', verifyJWT, (req, res) => { + const idexercises = parseInt(req.params.idexercises); + var sqlQuery = `SELECT eq.idexercisequestions FROM exercisequestions eq WHERE eq.idexercises = ${idexercises};`; + mysqlConnection.query(sqlQuery, function (error, results, fields) { + if (!error && results.length != 0) { + let IDExerciseQuestion = results[0]['idexercisequestions']; + sqlQuery = `DELETE FROM exerciseanswers WHERE idexercisequestions = ${IDExerciseQuestion};`; + mysqlConnection.query(sqlQuery, function (error, results, fields) { + sqlQuery = `DELETE FROM exercisequestions WHERE idexercisequestions = ${IDExerciseQuestion};`; + mysqlConnection.query(sqlQuery, function (error, results, fields) { + sqlQuery = `DELETE FROM exercises WHERE idexercises = ${idexercises};`; + mysqlConnection.query(sqlQuery, function (error, results, fields) { + console.log("/api/animations/deleteExercise success 200"); + res.send(true); + }); + }); + }); + } + else { + sqlQuery = `DELETE FROM exercises WHERE idexercises = ${idexercises};`; + mysqlConnection.query(sqlQuery, function (error, results, fields) { + console.log("/api/animations/deleteExercise success 200"); + res.send(true); + }); + } + }); + }) + + //#endregion + + //#region CONVERSATION + + router.post('/insertAnimationConversation', verifyJWT, (req, res) => { + const idanimationexercises = req.body.idanimationexercises; + const idanimations = parseInt(req.body.idanimations); + const idconversationtree = parseInt(req.body.idconversationtree); + + execSQLQuery(`INSERT INTO animationexercises (idconversationtree, idanimations, seconds) + VALUES (${idconversationtree}, ${idanimations}, 0);`, res, req.originalUrl); + }); + + router.patch('/updateAnimationConversation', verifyJWT, (req, res) => { + const idanimationexercises = parseInt(req.body.idanimationexercises); + const idanimations = req.body.idanimations; + const idconversationtree = req.body.idconversationtree; + const seconds = parseInt(req.body.seconds); + execSQLQuery(`UPDATE animationexercises SET + seconds = ${seconds} + WHERE idanimationexercises = ${idanimationexercises};`, res, req.originalUrl); + }); + + router.delete('/deleteConversation/:idconverstaiontree', verifyJWT, (req, res) => { + const idconverstaiontree = req.params.idconverstaiontree; + sqlQuery = `DELETE FROM alexaconversationtree + WHERE idconverstaiontree = ${idconverstaiontree};`; + mysqlConnection.query(sqlQuery, function (error, results, fields) { + console.log(new Date().toUTCString() + " - " + req.originalUrl + "success 200"); + res.send(true); + }); + + }); + + //#endregion + + //#region CHAT TIME + + router.post('/insertAnimationChatTime', verifyJWT, (req, res) => { + const idanimationexercises = req.body.idanimationexercises; + const idanimations = parseInt(req.body.idanimations); + const idzoechattime = parseInt(req.body.idzoechattime); + + execSQLQuery(`INSERT INTO animationexercises (idzoechattime, idanimations, seconds) + VALUES (${idzoechattime}, ${idanimations}, 0);`, res, req.originalUrl); + }); + + router.patch('/updateAnimationChatTime', verifyJWT, (req, res) => { + const idanimationexercises = parseInt(req.body.idanimationexercises); + const seconds = parseInt(req.body.seconds); + execSQLQuery(`UPDATE animationexercises SET + seconds = ${seconds} + WHERE idanimationexercises = ${idanimationexercises};`, res, req.originalUrl); + }); + + router.delete('/deleteChatTime/:idzoechattime', verifyJWT, (req, res) => { + const idzoechattime = parseInt(req.params.idzoechattime); + let sqlQuery0 = `DELETE FROM zoechattimesentences WHERE idzoechattimedialog in (select idzoechattimedialog from zoechattimedialog where idzoechattime = ${idzoechattime});`; + let sqlQuery1 = `DELETE FROM zoechattimedialog WHERE idzoechattime = ${idzoechattime};`; + let sqlQuery2 = `DELETE FROM zoechattime WHERE idzoechattime = ${idzoechattime};`; + mysqlConnection.query(sqlQuery0, function (error, results, fields) { + mysqlConnection.query(sqlQuery1, function (error, results, fields) { + mysqlConnection.query(sqlQuery2, function (error, results, fields) { + console.log(new Date().toUTCString() + " - " + req.originalUrl + "success 200"); + res.send(true); + }); + }); + }); + + }); + + //#endregion + + return router; +} + +function zipArquivo(idanimations, dir, res) { + const fs = require('fs'); + require('all-unpacker').pack(Variables('src_media') + 'animations/' + idanimations + '.zip', { + targetDir: Variables('src_media') + 'animations/' + idanimations + '.mp4', + password: Variables('passdecrypt'), + }, function(err, files, text) { + if (err) return console.error(err); + if (files) console.log('files', files); + if (text) { + const shell = require('shelljs'); + shell.exec('chmod -R 777 /var/www/html/animations/', function(Sucesso) { + console.log('text', text); + //console.log("compactado"); + if(fs.unlinkSync(dir + '.mp4')) { + console.log("Falha ao excluir"); + res.send(true); + } + else { + console.log("Excluído com sucesso!"); + res.send(true); + } + }) + + }; + }); +} + +module.exports = routes; \ No newline at end of file diff --git a/controllers/answerController.js b/controllers/answerController.js new file mode 100644 index 0000000..850780e --- /dev/null +++ b/controllers/answerController.js @@ -0,0 +1,271 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); +const formidable = require('formidable'); + +router.use(bodyParser.urlencoded({ + limit: '100mb', + extended: true +})); +router.use(bodyParser.json({ + limit: '100mb', + extended: true +})); + +var routes = function () { + + router.get('/getAnswers/:idexercisequestions', verifyJWT, (req, res) => { + const idexercisequestions = parseInt(req.params.idexercisequestions); + execSQLQuery(`SELECT + * + FROM exerciseanswers + WHERE idexercisequestions = ${idexercisequestions};`, res, req.originalUrl); + }) + + router.get('/getAnswersByid/:idexerciseanswers', verifyJWT, (req, res) => { + const idexerciseanswers = parseInt(req.params.idexerciseanswers); + execSQLQuery(`SELECT + * + FROM exerciseanswers + WHERE idexerciseanswers = ${idexerciseanswers};`, res, req.originalUrl); + }); + + router.get('/getUserAnswersFixed/:idusers/:idunits', verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + const idunits = parseInt(req.params.idunits); + execSQLQuery(`SELECT + * + FROM usergivenanswers + WHERE idusers = ${idusers} AND idunits = ${idunits} AND fixed = 1;`, res, req.originalUrl); + }) + + router.get('/getUserAnswers/:idusers/:idunits', verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + const idunits = parseInt(req.params.idunits); + execSQLQuery(`SELECT + idusergivenanswers, + idusers, + idexerciseanswers, + date_answered, + case when fixed = 0 then 'Não' else 'Sim' end as fixed, + idclasses, + idunits + FROM usergivenanswers + WHERE idusers = ${idusers} AND idunits = ${idunits};`, res, req.originalUrl); + }) + + router.get('/getUserAnswersById/:idusergivenanswers', verifyJWT, (req, res) => { + const idusergivenanswers = req.params.idusergivenanswers; + execSQLQuery(`SELECT + * + FROM usergivenanswers + WHERE idusergivenanswers = ${idusergivenanswers};`, res, req.originalUrl); + }) + + router.get('/getUserAnswersByAnsID/:idanswers/:idusers/:idunits', verifyJWT, (req, res) => { + const idanswers = parseInt(req.params.idanswers); + const idusers = parseInt(req.params.idusers); + const idunits = parseInt(req.params.idunits); + execSQLQuery(`SELECT + * + FROM usergivenanswers + WHERE idexerciseanswers = ${idanswers} AND idusers = ${idusers} AND idunits = ${idunits};`, res, req.originalUrl); + }) + + router.get('/getUserAnswersByClass/:idclasses/:idusers/:idunits', verifyJWT, (req, res) => { + const idclasses = parseInt(req.params.idclasses); + const idusers = parseInt(req.params.idusers); + const idunits = parseInt(req.params.idunits); + execSQLQuery(`SELECT + * + FROM usergivenanswers + WHERE idclasses = ${idclasses} AND idusers = ${idusers} AND idunits = ${idunits};`, res, req.originalUrl); + }) + + router.get('/getUserAnswersNotFixed/:idusers/:idunits', verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + const idunits = parseInt(req.params.idunits); + execSQLQuery(`SELECT + ua.idusergivenanswers, + ua.idusers, + ua.idexerciseanswers, + ua.date_answered, + 'Não' as fixed, + ua.idclasses, + c.name as 'classname' + FROM usergivenanswers ua + INNER JOIN classes c ON ua.idclasses = c.idclasses + WHERE ua.idusers = ${idusers} AND ua.idunits = ${idunits} AND fixed = 0;`, res, req.originalUrl); + }) + + router.get('/getHomeworkNotFixed/:idusers', verifyJWT, (req, res) => { + let idusers = req.params.idusers; + execSQLQuery(` + SELECT + 0 as idexerciseanswers, + sc.idusers, + c.name as 'classname', + 'Lição de casa' as 'date_answered', + 'Não' as 'fixed', + sc.idclasses + FROM + stepclass sc + INNER JOIN + classes c + ON + c.idclasses = sc.idclasses + WHERE + sc.homework + AND + sc.completedClass = 1 + AND + sc.note is null + AND + sc.idusers = ${idusers} + AND + false;`, + res, + req.originalUrl + ); + }) + + router.post('/insertuseranswer', verifyJWT, (req, res) => { + const usergivenanswerid = parseInt(req.body.usergivenanswerid); + const idusers = parseInt(req.body.idusers); + const idexerciseanswers = parseInt(req.body.idexerciseanswers); + const date_answered = req.body.date_answered; + const fixed = req.body.fixed ? 1 : 0; + const idclasses = parseInt(req.body.idclasses); + const idunits = parseInt(req.body.idunits); + mysqlConnection.query('select * from usergivenanswers order by idusergivenanswers desc limit 1;', function (error, results, fields) { + let IDuserGivenAnswers = 0; + if (!results || results == "" || results.length == 0) + IDuserGivenAnswers = 1; + else + IDuserGivenAnswers = results[0]['idusergivenanswers'] + 1; + execSQLQuery(`INSERT INTO usergivenanswers(idusergivenanswers, idusers, idexerciseanswers, date_answered, fixed, idclasses, idunits) + VALUES (?, ?, ?, ?, ?, ?, ?);`, res, req.originalUrl, [IDuserGivenAnswers, idusers, idexerciseanswers, date_answered, fixed, idclasses, idunits], function(Retorno) { + if (Retorno.status == 500) { + console.log(Retorno.error); + } + }); + }); + }); + + router.patch('/fixAnswer', verifyJWT, (req, res) => { + const idexerciseanswers = parseInt(req.body.idexerciseanswers); + const iscorrect = req.body.iscorrect ? 1 : 0; + execSQLQuery(`UPDATE exerciseanswers SET + iscorrect = ${iscorrect} + WHERE idexerciseanswers = ${idexerciseanswers}`, res, req.originalUrl); + }); + + router.get('/fixUserAnswer/:idusergivenanswers', verifyJWT, (req, res) => { + const idusergivenanswers = parseInt(req.params.idusergivenanswers); + execSQLQuery(`UPDATE usergivenanswers SET + fixed = 1 + WHERE idusergivenanswers = ${idusergivenanswers};`, res, req.originalUrl); + }); + + router.delete('/delete/:idexerciseanswers', verifyJWT, (req, res) => { + const idexerciseanswers = parseInt(req.params.idexerciseanswers); + execSQLQuery(`DELETE FROM exerciseanswers + WHERE idexerciseanswers = ${idexerciseanswers}`, res, req.originalUrl); + }); + + router.post('/insert', verifyJWT, (req, res) => { + const idexercisequestions = parseInt(req.body.idexercisequestions); + const hasmedia = req.body.hasmedia ? 1 : 0; + const content = req.body.content; + const iscorrect = req.body.iscorrect ? 1 : 0; + const orientation = req.body.orientation ? 1 : 0; + execSQLQuery(`INSERT INTO exerciseanswers(idexercisequestions, hasmedia, content, iscorrect, orientation) + VALUES (?, ?, ?, ?, ?);`, res, req.originalUrl, [idexercisequestions, hasmedia, content, iscorrect, orientation]); + }); + + router.patch('/update', verifyJWT, function (req, res) { + const idexerciseanswers = parseInt(req.body.idexerciseanswers); + const idexercisequestions = parseInt(req.body.idexercisequestions); + const hasmedia = req.body.hasmedia ? 1 : 0; + const content = req.body.content; + const iscorrect = req.body.iscorrect; + const orientation = req.body.orientation; + execSQLQuery(`UPDATE exerciseanswers SET + hasmedia = ?, + content = ?, + iscorrect = ?, + orientation = ?, + idexercisequestions = ? + WHERE idexerciseanswers = ?;`, res, req.originalUrl, [hasmedia, content, iscorrect, orientation, idexercisequestions, idexerciseanswers]); + }); + + router.post('/copy', verifyJWT, (req, res) => { + var base64ToImage = require('base64-to-image'); + var img64 = req.body.src; + var idexerciseanswers = req.body.idexerciseanswers; + var Name = 'ans_' + idexerciseanswers; + var Obj = {'fileName': Name, 'type':'jpg'}; + var path = Variables('src_media') + 'images/'; + if(base64ToImage(img64,path,Obj)) { + res.send(true); + } + else { + res.send(false); + } + //res.send("images uploaded with success!"); + }); + + router.post('/copy2', verifyJWT, (req, res) => { + let form = new formidable.IncomingForm(); + form.maxFileSize = 600 * 1024 * 1024; + form.parse(req, function(err,fields,files){ + const fs = require('fs'); + var name = fields.name; + var dir = Variables('src_media') + 'images/' + name; + + var oldpath = files.file.path; + if(fs.existsSync(dir)) { + fs.unlink(dir, function(err) { + fs.rename(oldpath, dir, function (err) { + res.send(true); + }) + }); + } + else { + fs.rename(oldpath, dir, function (err) { + res.send(true); + }) + } + }); + }); + + router.patch('/removerRespostas', verifyJWT, function (req, res, next) { + let idexerciseanswers = req.body.idexerciseanswers; + let ids = idexerciseanswers.split(','); + index1 = 0; + removeAnswers(ids, res); + }); + + return router; +}; + +index1 = 0; + +function removeAnswers(ids, res) { + if (index1 < ids.length - 1) { + let sqlQuery = `UPDATE exerciseanswers SET idexercisequestions = null WHERE idexerciseanswers = ${ids[index1]};`; + console.log(sqlQuery); + mysqlConnection.query(sqlQuery, function (error, results, fields) { + console.log("QuestionID " + ids[index1] + " removed"); + index1++; + removeAnswers(ids, res); + }); + } + else { + res.send("answers removed"); + } +} + +module.exports = routes; \ No newline at end of file diff --git a/controllers/appController.js b/controllers/appController.js new file mode 100644 index 0000000..e6612a6 --- /dev/null +++ b/controllers/appController.js @@ -0,0 +1,1641 @@ +require('../connections/mysql-server'); +require('../connections/sql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + router.get('/checkFranchiseePortal', (req, res) => { + execSQLQuery( + `SELECT + franchiseeportal + FROM config;`, + res, + req.originalUrl + ); + }); + + router.get('/changeFranchiseePortal/:estado', (req, res) => { + const estado = req.params.estado ? 1 : 0; + execSQLQuery( + `UPDATE config SET + franchiseeportal = ${estado} + WHERE idconfig = 1;`, + res, + req.originalUrl + ); + }); + + router.get('/checkVersionApp', (req, res) => { + execSQLQuery( + `SELECT + versionapp + FROM config;`, + res, + req.originalUrl + ); + }); + + router.get('/checkVersionRobot/:idrobot', (req, res) => { + let idrobot = req.params.idrobot; + let Caminho = Variables('src_media') + 'downloads/'; + let fs = require('fs'); + if (idrobot == 0) Caminho += 'ZoeRobot'; + else if (idrobot == 1) Caminho += 'MiniRobot'; + fs.readFile(Caminho + '/versao.txt', 'utf8', (err, data) => { + if (err) throw err; + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' success 200' + ); + res.send(data); + }); + //execSQLQuery('SELECT versionrobot, messagerobot FROM config;', res, req.originalUrl); + }); + + router.get('/getZoeRobots', (req, res) => { + mysqlConnection.query( + `SELECT * FROM zoerobots;`, + function (error, results, fields) { + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' success 200' + ); + res.send(JSON.stringify(results)); + } + ); + }); + + router.get('/getZoeRobotsApks/:idzoerobots', (req, res) => { + const idzoerobots = req.params.idzoerobots; + mysqlConnection.query( + `SELECT * FROM zoerobotsapks where idzoerobots = ${idzoerobots};`, + function (error, results, fields) { + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' success 200' + ); + res.send(`{"Aplicativos": ` + JSON.stringify(results) + `}`); + } + ); + }); + + router.post('/insertZoeRobotsApks', (req, res) => { + const idzoerobots = req.body.idzoerobots; + const descricao = req.body.descricao; + const versao = req.body.versao; + const mensagem = req.body.mensagem; + const packagename = req.body.packagename; + const enderecoapk = req.body.enderecoapk; + const nomeinstalador = req.body.nomeinstalador; + const pasta = req.body.pasta; + execSQLQuery( + `insert into zoerobotsapks (idzoerobots, descricao, versao, mensagem, packagename, enderecoapk, nomeinstalador, pasta) values (?, ?, ?, ?, ?, ?, ?, ?);`, + res, + req.originalUrl, + [ + idzoerobots, + descricao, + versao, + mensagem, + packagename, + enderecoapk, + nomeinstalador, + pasta, + ] + ); + }); + + router.delete('/deleteZoeRobotsApks/:idzoerobots', (req, res) => { + const idzoerobots = req.params.idzoerobots; + execSQLQuery( + `delete from zoerobotsapks WHERE idzoerobots = ${idzoerobots};`, + res, + req.originalUrl + ); + }); + + router.post('/SetVersaoRobotFile/:idrobot', verifyJWT, (req, res) => { + let Caminho = Variables('src_media') + 'downloads/'; + const fs = require('fs'); + const Json = JSON.stringify(req.body); + const idrobot = parseInt(req.params.idrobot); + if (idrobot == 0) Caminho += 'ZoeRobot'; + else if (idrobot == 1) Caminho += 'MiniRobot'; + fs.writeFile(Caminho + '/versao.txt', Json, (err) => { + if (err) throw err; + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' success 200' + ); + res.send(true); + }); + }); + + router.get('/checkRobotCourses', (req, res) => { + execSQLQuery( + `SELECT + robotcourses + FROM config;`, + res, + req.originalUrl + ); + }); + + router.post('/checkexistnotificationclose/:tk', verifyJWT, (req, res) => { + let idteacher = req.body.idteacher; + let db = req.body.db; + execSQLQuery2( + ` + SELECT + IDNotificacoes, + IDChamadaAPP + FROM + ${db}NotificacoesErroEnvioAPP + WHERE + IDInstrutor = ${idteacher} + AND + EnviarRespostaAPP = 1 + AND + RespostaRecebidaAPP = 0 + AND + IDChamadaAPP != NULL;`, + res, + req.originalUrl + ); + }); + + router.post('/notificationsteacher/:tk', verifyJWT, (req, res) => { + let idteacher = req.body.idteacher; + let idcall = req.body.idcall; + let db = req.body.db; + execSQLQuery2( + ` + SELECT + * + FROM + ${db}NotificacoesErroEnvioAPP + WHERE + IDInstrutor = ${idteacher} + AND + IDChamadaAPP = ${idcall};`, + res, + req.originalUrl + ); + }); + + router.post('/send/:tk', verifyJWT, (req, res) => { + let db = req.body.db; + let idteacher = req.body.idteacher; + let description = req.body.desc; + let date = req.body.date; + let students = req.body.students; + let content = req.body.content; + var StudentsIDs = students.split(','); + let Nomes = ''; + + let sqlQry = ` + SELECT + * + FROM + ${db}FuncionariosAcesso + WHERE + IDFuncionario = ${idteacher} + AND + DescricaoAcesso = '${description}' + AND + permitido = 1;`; + //Check user have permission to this + sqlServerConnection + .request() + .query(sqlQry, function (error, results, fields) { + if (!error && results.length != 0) { + //Check if date exist in TurmasCalendario + CheckDateExists( + db, + date, + idteacher, + StudentsIDs, + 0, + Nomes, + res, + content, + null + ); + } else { + res.send( + 'Funcionário não tem acesso a "Inclusão de Controle de Chamadas"' + ); + } + }); + + /*if(checkAccessEmployee(db, idteacher, description)) { + var ResultTurmasCalendario = SeacrhCall(db, date, idteacher, idstudent); + res.send(ResultTurmasCalendario); + } + else { + res.send('Funcionário não tem acesso a "Inclusão de Controle de Chamadas"'); + }*/ + }); + + router.post('/checkclass/:tk', verifyJWT, (req, res) => { + let date = req.body.date; + let idstudent = req.body.idstudent; + let db = req.body.db; + execSQLQuery2( + ` + SELECT top(1) * + FROM ${db}TurmasCalendario + where IDTurma = ${idstudent} + and Ministrado = 0 + order by Data asc;`, + res, + req.originalUrl + ); + }); + + router.post('/homeworkend', verifyJWT, (req, res) => { + const homework = req.body.homework; + const idstudent = parseInt(req.body.idstudent || req.body.idusers); + const idunits = parseInt(req.body.idunits); + const idclasses = parseInt(req.body.idclasses); + + const SQLQry = `UPDATE stepclass SET + homework = (SELECT CASE WHEN r.qtde = 0 THEN 0 ELSE ${homework} END AS home FROM + (SELECT COUNT(*) AS qtde FROM stepclass WHERE idusers = ${idstudent} AND idunits = ${idunits} AND idclasses = ${idclasses} AND STR_TO_DATE(datefinal, '%d/%m/%Y') > NOW()) r) + WHERE idusers = ${idstudent} AND idunits = ${idunits} AND idclasses = ${idclasses};`; + + mysqlConnection.query(SQLQry, function (error, results, fields) { + if (!error && results.length != 0) { + res.send(200); + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' success 200' + ); + } else { + res.send(500); + console.log( + new Date().toUTCString() + + ' - ' + + req.originalUrl + + ' fail 500 ' + + error + ); + } + }); + InsertUserStage(idstudent, idunits, idclasses, homework); + InsertNotes(); + //InsertNotasDetalhes(idstudent, idunits, idclasses); + }); + + router.get('/InsertNotes', (req, res) => { + if (InsertNotes()) res.send({ error: null, response: false, status: 500 }); + else res.send({ error: null, response: true, status: 200 }); + }); + + router.get('/verifyCorrection/:idunits', verifyJWT, (req, res) => { + let idunits = req.params.idunits; + execSQLQuery( + ` + SELECT + idusers, + idclasses, + homework, + datefinal + FROM + stepclass + WHERE + note IS NULL + AND + completedClass = 1 + AND + idunits = ${idunits};`, + res, + req.originalUrl + ); + }); + + router.post('/listQRcodesByAny/:tk', verifyJWT, (req, res) => { + var value = req.body.value; + var db = req.body.db; + execSQLQuery2( + ` + SELECT + c.Nome, + mt.IDMatricula, + t.IdTurma + FROM + ${db}Turmas t + INNER JOIN + ${db}MatriculasTreinandos mt + ON + t.IdTurma = mt.CodigoTurma + INNER JOIN + ${db}Clientes c + ON + c.IDCliente = mt.IDTreinando + INNER JOIN + ${db}Matriculas m + ON + m.IDMatricula = mt.IDMatricula + WHERE + m.QRCode = '${value}';`, + res, + req.originalUrl + ); + }); + + router.get('/linkStudent/:db/:idusers/:qrcode/:tk', (req, res) => { + let db = req.params.db; + let idusers = req.params.idusers; + let qrcode = req.params.qrcode; + let token = req.params.tk; + + if (token == Variables('tk_fixed')) { + let sqlQry = ` + SELECT + * + FROM + units + WHERE + reference_db = '${db}' + AND + enabled = 1;`; + + mysqlConnection.query(sqlQry, function (error, results, fields) { + if (!error && results.length != 0) { + var idunits = results[0]['idunits']; + let sqlQry2 = ` + UPDATE + qrcodes + SET + idusers = ${idusers}, + idunits = ${idunits} + WHERE + _key = '${qrcode}' + AND + idusers is null;`; + + execSQLQuery(sqlQry2, res, req.originalUrl); + } else { + res.send('not found'); + } + }); + } else { + res.status(500).send({ status: 'expired' }); + } + }); + + router.get('/linkBarCode/:db/:idusers/:_key/:idcourses/:tk', (req, res) => { + let db = req.params.db; + let idusers = req.params.idusers; + let _key = req.params._key; + let idcourses = req.params.idcourses; + let token = req.params.tk; + if (token == Variables('tk_fixed')) { + let sqlQry = ` + SELECT + * + FROM + units + WHERE + reference_db = '${db}' + AND + enabled = 1;`; + + mysqlConnection.query(sqlQry, function (error, results, fields) { + if (!error && results.length != 0) { + var idunits = results[0]['idunits']; + let sqlQry2 = ` + UPDATE + barcodes + SET + idusers = ${idusers}, + idunits = ${idunits}, + idcourses = ${idcourses} + WHERE + _key = '${_key}' + AND + idusers is null;`; + + execSQLQuery(sqlQry2, res, req.originalUrl); + } else { + res.send('not found'); + } + }); + + //execSQLQuery(sqlQry, res, req.originalUrl); + } else { + res.status(500).send({ status: 'expired' }); + } + }); + + router.get('/getCuriosities/:tk', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * FROM curiosities`, res, req.originalUrl); + }); + + router.get('/checkQR/:_key/:_token', (req, res) => { + let _key = req.params._key; + let token = req.params._token; + + if (token != Variables('tk_fixed')) { + res.status(500).send({ status: 'expired' }); + } else { + var sqlQry = ` + SELECT + * + FROM + qrcodes + WHERE + _key = '${_key}';`; + + mysqlConnection.query(sqlQry, function (error, results, fields) { + if (!error && results.length != 0) { + var ordem = results[0]['ordem']; + var idqrlotes = results[0]['idqrlotes']; + var src = + Variables('src_qrcodes') + + idqrlotes + + '/qr_' + + idqrlotes + + '_' + + ordem + + '.jpg'; + var cmd = ''; + if (results[0]['idusers']) cmd = 'N,'; + else cmd = 'S,'; + console.log("/checkQR/ success 200 - '" + cmd + src + "'"); + res.send(cmd + src); + } else { + res.status(500).send('QRCode não encontrado'); + } + }); + } + }); + + router.get( + '/isLastClass/:idusers/:idunits/:idclasses', + verifyJWT, + (req, res) => { + let idusers = req.params.idusers; + let idunits = req.params.idunits; + let idclasses = req.params.idclasses; + + execSQLQuery( + `update stepclass set + homework = 1 + where (SELECT aval FROM classes WHERE idclasses = ${idclasses}) = 1 + and idusers = ${idusers} and idunits = ${idunits} and idclasses = ${idclasses};`, + res, + req.originalUrl + ); + setTimeout(() => { + InsertNotes(); + setTimeout(() => { + InsertCourseNotes(); + }, 200); + }, 500); + } + ); + + router.get( + '/checkHasStudentsToNotificate/:idteacher/:db', + verifyJWT, + (req, res) => { + console.log('/checkHasStudentsToNotificate success 200'); + let idteacher = req.params.idteacher; + let db = req.params.db; + let sqlQuery = ` +SELECT DISTINCT + tc.IdTurma, tc.CodigoCurso, tt.IDMatricula +FROM + ${db}TurmasCalendario tc +INNER JOIN + ${db}TreinandosTurmas tt +ON + tc.IdTurma = tt.CodigoTurma +AND + tc.CodigoCurso = tt.IDCurso + WHERE + tc.Ministrado = 1 + AND + tc.CodigoInstrutor = ${idteacher}; + `; + sqlServerConnection + .request() + .query(sqlQuery, function (error, results, fields) { + if (!error && results.length != 0) { + //res.send(results); + //console.log(results); + indexStudents = 0; + LoopStudentsOfTeacher(results, res, db, idteacher); + } else { + res.send(false); + } + }); + } + ); + + router.post('/insertScoregame/:tk', (req, res) => { + let token = req.params.tk; + if (token != Variables('tk_fixed')) { + res.status(500).send({ status: 'expired' }); + return; + } + let cidade = ''; + let jogador = req.body.jogador; + let pontuacao = req.body.pontuacao; + let idgames = 1; + execSQLQuery( + `INSERT INTO scoregames (cidade, jogador, pontuacao, idgames) VALUES ('${cidade}', '${jogador}', ${pontuacao}, ${idgames});`, + res, + req.originalUrl + ); + }); + + router.post('/updateScoregame/:tk', (req, res) => { + let token = req.params.tk; + if (token != Variables('tk_fixed')) { + res.status(500).send({ status: 'expired' }); + return; + } + let cidade = ''; + let jogador = req.body.jogador; + let pontuacao = req.body.pontuacao; + let idgames = 1; + execSQLQuery( + `UPDATE scoregames SET pontuacao = ${pontuacao} WHERE jogador = '${jogador}' AND idgames = ${idgames};`, + res, + req.originalUrl + ); + }); + + router.get('/listScoregame/:tk/:idgames', (req, res) => { + let token = req.params.tk; + let idgames = req.params.idgames; + if (token != Variables('tk_fixed')) { + res.status(500).send({ status: 'expired' }); + return; + } + execSQLQuery( + `SELECT jogador, pontuacao FROM scoregames WHERE idgames = ${idgames} ORDER BY pontuacao ASC;`, + res, + req.originalUrl + ); + }); + + router.get('/InsertCourseNotes', (req, res) => { + if (InsertCourseNotes()) + res.send({ error: null, response: false, status: 500 }); + else res.send({ error: null, response: true, status: 200 }); + }); + + router.post('/DesativarAluno', (req, res) => { + const idunits = parseInt(req.body.idunits); + const idusers = parseInt(req.body.idusers); + execSQLQuery( + `insert into alunosdesativados (idunits, idusers) values (${idunits}, ${idusers});`, + res, + req.originalUrl + ); + }); + + router.get('/MudarAlunoDesativado/:idunits/:idusers', (req, res) => { + const idunits = parseInt(req.params.idunits); + const idusers = parseInt(req.params.idusers); + execSQLQuery( + `update alunosdesativados set + desativado = !desativado + where idunits = ${idunits} and idusers = ${idusers};`, + res, + req.originalUrl + ); + }); + + router.get('/MudarAlunoDesativadoP/:idunits/:idusers', (req, res) => { + const idunits = parseInt(req.params.idunits); + const idusers = parseInt(req.params.idusers); + execSQLQuery( + `update usershomework set + disabled = !disabled + where idunits = ${idunits} and idusers = ${idusers};`, + res, + req.originalUrl + ); + }); + + router.get('/InserirNotasSQLServer', (req, res) => { + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' - initing...' + ); + let SqlQueryUnidades = `select + idunits, + unityname as 'Unidade', + concat(reference_db, '.dbo.') as 'db' + from units + where enabled = 1 + order by unityname asc;`; + mysqlConnection.query(SqlQueryUnidades, function (error, Unidades, fields) { + PreencherNotasSQLServer(Unidades, 0, function (Unidades) { + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' - finished' + ); + res.send(Unidades); + }); + }); + }); + + router.get('/InserirRespostasAlunos', (req, res) => { + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' - initing...' + ); + let SqlQueryUnidades = `select + idunits, + unityname as 'Unidade', + concat(reference_db, '.dbo.') as 'db' + from units + where enabled = 1 + order by unityname asc;`; + mysqlConnection.query(SqlQueryUnidades, function (error, Unidades, fields) { + let SqlQueryRespostas = `select distinct + cc.idclasses, + ea.idexerciseanswers + from classescontent cc + inner join exercisequestions eq on eq.idexercises = cc.idexercises + inner join exerciseanswers ea on ea.idexercisequestions = eq.idexercisequestions + where ea.iscorrect = 1;`; + mysqlConnection.query( + SqlQueryRespostas, + function (error, Respostas, fields) { + PreencherAulas(Unidades, Respostas, 0, function (Unidades) { + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' - finished' + ); + res.send(Unidades); + }); + } + ); + }); + }); + + function PreencherAulas(Unidades, Respostas, Index, callback) { + if (Index < Unidades.length) { + console.log( + 'Analisando unidade ' + + (Index + 1) + + ' de ' + + Unidades.length + + ' (' + + Unidades[Index]['Unidade'] + + ')' + ); + Unidades[Index]['AulaAluno'] = []; + let SqlQueryMySQL = `select * from ( + select + sc.idusers, + sc.idunits, + sc.idclasses, + sc.note, + ExA.Questoes, + count(ug.idusergivenanswers) as 'Respostas' + from stepclass sc + inner join (select distinct + cl.idclasses, + cl.name as 'Aula', + count(cc.idexercises) as 'Questoes' + from classes cl + inner join courses co on co.idcourses = cl.idcourses + inner join classescontent cc on cc.idclasses = cl.idclasses + left join exercisequestions eq on eq.idexercises = cc.idexercises + where co.idtypescourse in (1,2,3) + group by cl.idclasses, cc.idclasses + order by cl.idclasses asc) ExA on sc.idclasses = ExA.idclasses and ExA.Questoes > 0 + left join usergivenanswers ug on ug.idunits = sc.idunits and ug.idusers = sc.idusers and ug.idclasses = sc.idclasses + where sc.idunits = ${Unidades[Index]['idunits']} and sc.completedClass = 1 and (now() >= date_add(convert(sc.dateinicial, date), interval 7 day) or sc.homework is not null) + group by sc.idusers, sc.idunits, sc.idclasses) R + where R.Respostas = 0;`; + mysqlConnection.query(SqlQueryMySQL, function (error, AulaAluno, fields) { + Unidades[Index]['AulaAluno'] = AulaAluno; + if (AulaAluno && AulaAluno.length > 0) { + Unidades[Index][ + 'SQLRes' + ] = `insert into usergivenanswers (idusergivenanswers, idusers, idexerciseanswers, date_answered, fixed, idclasses, idunits) values `; + Unidades[Index]['SQLNot'] = `update stepclass set note = null where `; + } else { + Unidades[Index]['SQLRes'] = 'select 1;'; + Unidades[Index]['SQLNot'] = 'select 1 ;'; + } + for (let i = 0; i < Unidades[Index]['AulaAluno'].length; i++) { + Unidades[Index][ + 'SQLNot' + ] += `(idusers = ${Unidades[Index]['AulaAluno'][i]['idusers']} and idunits = ${Unidades[Index]['AulaAluno'][i]['idunits']} and idclasses = ${Unidades[Index]['AulaAluno'][i]['idclasses']}) or `; + for (let o = 0; o < Respostas.length; o++) { + if ( + Respostas[o].idclasses == + Unidades[Index]['AulaAluno'][i]['idclasses'] + ) { + Unidades[Index][ + 'SQLRes' + ] += `((select ug1.idusergivenanswers + 1 from usergivenanswers ug1 order by ug1.idusergivenanswers desc limit 1), ${Unidades[Index]['AulaAluno'][i]['idusers']}, ${Respostas[o]['idexerciseanswers']}, '25/01/2021', 1, ${Unidades[Index]['AulaAluno'][i]['idclasses']}, ${Unidades[Index]['AulaAluno'][i]['idunits']}),`; + } + } + } + Unidades[Index]['SQLRes'] = + Unidades[Index]['SQLRes'].substring( + 0, + Unidades[Index]['SQLRes'].length - 1 + ) + ';'; + Unidades[Index]['SQLNot'] = + Unidades[Index]['SQLNot'].substring( + 0, + Unidades[Index]['SQLNot'].length - 4 + ) + ';'; + + mysqlConnection.query( + Unidades[Index]['SQLRes'], + function (error, insRespostas, fields) { + mysqlConnection.query( + Unidades[Index]['SQLNot'], + function (error, updNotas, fields) { + Index++; + PreencherAulas(Unidades, Respostas, Index, callback); + } + ); + } + ); + }); + } else { + callback(Unidades); + } + } + + router.get('/RemoverRespostasAlunos', (req, res) => { + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' - initing...' + ); + let SqlQueryUnidades = `select + idunits, + unityname as 'Unidade', + concat(reference_db, '.dbo.') as 'db' + from units + where enabled = 1 + order by unityname asc;`; + mysqlConnection.query(SqlQueryUnidades, function (error, Unidades, fields) { + RemoverAulas(Unidades, 0, function (Unidades) { + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' - finished' + ); + res.send(Unidades); + }); + }); + }); + + function RemoverAulas(Unidades, Index, callback) { + if (Index < Unidades.length) { + console.log( + 'Analisando unidade ' + + (Index + 1) + + ' de ' + + Unidades.length + + ' (' + + Unidades[Index]['Unidade'] + + ')' + ); + Unidades[Index]['AulaAluno'] = []; + let SqlQueryMySQL = `select * from ( + select + sc.idusers, + sc.idunits, + sc.idclasses, + sc.note, + ExA.Questoes, + count(ug.idusergivenanswers) as 'Respostas' + from stepclass sc + inner join (select distinct + cl.idclasses, + cl.name as 'Aula', + count(cc.idexercises) as 'Questoes' + from classes cl + inner join courses co on co.idcourses = cl.idcourses + inner join classescontent cc on cc.idclasses = cl.idclasses + left join exercisequestions eq on eq.idexercises = cc.idexercises + where co.idtypescourse in (1,2,3) + group by cl.idclasses, cc.idclasses + order by cl.idclasses asc) ExA on sc.idclasses = ExA.idclasses and ExA.Questoes > 0 + left join usergivenanswers ug on ug.idunits = sc.idunits and ug.idusers = sc.idusers and ug.idclasses = sc.idclasses + where sc.idunits = ${Unidades[Index]['idunits']} and sc.completedClass = 1 and (now() >= date_add(convert(sc.dateinicial, date), interval 7 day) or sc.homework is not null) + group by sc.idusers, sc.idunits, sc.idclasses) R + where R.Respostas != R.Questoes;`; + mysqlConnection.query(SqlQueryMySQL, function (error, AulaAluno, fields) { + Unidades[Index]['AulaAluno'] = AulaAluno; + if (AulaAluno && AulaAluno.length > 0) { + Unidades[Index]['SQLRem'] = `delete from usergivenanswers where `; + } else { + Unidades[Index]['SQLRem'] = 'select 1;'; + } + LoopRemoverRespostas(Unidades[Index], 0, '', function (newUnidade) { + Unidades[Index] = newUnidade; + if (Unidades[Index]['IDsRemover'] == '') { + Unidades[Index]['IDsRemover'] = 'select 1;'; + } else { + Unidades[Index]['SQLRem'] += + '(' + Unidades[Index]['IDsRemover'] + ')'; + } + mysqlConnection.query( + Unidades[Index]['SQLRem'], + function (error, delRespostas, fields) { + Index++; + RemoverAulas(Unidades, Index, callback); + } + ); + }); + }); + } else { + callback(Unidades); + } + } + + function LoopRemoverRespostas(Unidade, Index, IDsRemover, callback) { + if (Index < Unidade['AulaAluno'].length) { + let sqlQueryRespostas = `select * from usergivenanswers ug where ug.idunits = ${Unidade['AulaAluno'][Index]['idunits']} and ug.idclasses = ${Unidade['AulaAluno'][Index]['idclasses']} and ug.idusers = ${Unidade['AulaAluno'][Index]['idusers']};`; + mysqlConnection.query( + sqlQueryRespostas, + function (error, ResAluno, fields) { + for (let i = 0; i < ResAluno.length; i++) { + if (IDsRemover != '') IDsRemover += ' or '; + IDsRemover += `(idunits = ${ResAluno[i]['idunits']} and idusers = ${ResAluno[i]['idusers']} and idclasses = ${ResAluno[i]['idclasses']})`; + } + Index++; + LoopRemoverRespostas(Unidade, Index, IDsRemover, callback); + } + ); + } else { + Unidade['IDsRemover'] = IDsRemover; + callback(Unidade); + } + } + + router.get('/RelatorioMatriculasSenhas/:db', (req, res) => { + const db = req.params.db; + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' - initing...' + ); + const SqlQuery = `select distinct + tt.IDMatricula, + cl.Nome, + cl.SenhaIntranet as 'Senha' + from ${db}Clientes cl + inner join ${db}TreinandosTurmas tt on tt.IDTreinando = cl.IDCliente + order by tt.IDMatricula asc;`; + sqlServerConnection + .request() + .query(SqlQuery, function (error, results, fields) { + let Relatorio = []; + for (let i = 0; i < results['recordset'].length; i++) { + Relatorio.push(results['recordset'][i]); + Relatorio[i]['Senha'] = encriptPassword( + Relatorio[i]['Senha'], + Relatorio[i]['Senha'].length + ); + } + res.send(Relatorio); + }); + }); + + return router; +}; + +let indexStudents = 0; +function LoopStudentsOfTeacher(Alunos, res, db, idteacher) { + if (indexStudents < Alunos.length) { + let sqlQuery = ` + SELECT + COUNT(sc.idusers) as qtde_stepclass + FROM + stepclass sc + INNER JOIN + classes c ON sc.idclasses = c.idclasses + INNER JOIN + courses co ON co.idcourses = c.idcourses + WHERE + sc.idusers = ${ + Alunos[indexStudents]['IDMatricula'] + } AND sc.idunits = (SELECT idunits FROM units WHERE reference_db = '${ + db.split('.')[0] + }') AND co.idcourses = ${Alunos[indexStudents]['CodigoCurso']};`; + mysqlConnection.query(sqlQuery, function (error, results, fields) { + if (!error && results.length != 0) { + let sqlQuery2 = `SELECT COUNT(*) AS Ministradas FROM ${db}TurmasCalendario WHERE CodigoCurso = ${Alunos[indexStudents]['CodigoCurso']} AND IdTurma = ${Alunos[indexStudents]['IdTurma']} AND Ministrado = 1;`; + + sqlServerConnection + .request() + .query(sqlQuery2, function (error2, results2, fields) { + if (!error && results2.length > 0) { + if (results2[0]['Ministradas'] > results[0]['qtde_stepclass']) { + res.send(true); + } else { + indexStudents++; + LoopStudentsOfTeacher(Alunos, res, db, idteacher); + } + } else { + indexStudents++; + LoopStudentsOfTeacher(Alunos, res, db, idteacher); + } + }); + } else { + indexStudents++; + LoopStudentsOfTeacher(Alunos, res, db, idteacher); + } + }); + } else { + res.send(false); + } +} + +function CheckDateExists( + db, + date, + idteacher, + StudentsIDs, + i, + Nomes, + res, + content, + finalIDchamada +) { + try { + if (i < StudentsIDs.length) { + if (parseInt(StudentsIDs[i]) > 190000) { + StudentsIDs[ + i + ] = `(SELECT DISTINCT top(1) CodigoTurma FROM ${db}TreinandosTurmas WHERE IDMatricula = ${StudentsIDs[i]})`; + } + let sqlQry1 = `SELECT top(1) *, ${StudentsIDs[i]} AS 'CodTurma' + FROM ${db}TurmasCalendario tc + INNER JOIN ${db}TreinandosTurmas tt + ON tt.CodigoTurma = tc.IdTurma + where tc.IDTurma = ${StudentsIDs[i]} + and Ministrado = 0 + order by Data asc;`; + console.log(sqlQry1); + sqlServerConnection + .request() + .query(sqlQry1, function (error1, results1, fields) { + if (!error1 && results1.length != 0) { + //console.log(results1); + var ResultTurmasCalendario = results1.recordsets[0][0]; + if (ResultTurmasCalendario) { + StudentsIDs[i] = ResultTurmasCalendario['CodTurma']; + //console.log(StudentsIDs[i]); + let sqlQry2 = ` + SELECT + * + FROM + ${db}TreinandosTurmas + WHERE + CodigoTurma = ${ResultTurmasCalendario['IdTurma']} + AND + IDCurso = ${ResultTurmasCalendario['CodigoCurso']} + AND + Desistente = 0 + AND + Faltoso = 0; + `; + + sqlServerConnection + .request() + .query(sqlQry2, function (error2, results2, fields) { + if (!error2 && results2.length != 0) { + //console.log(results2.recordset[0]); + var ResultTreinandosTurmas = results2.recordset[0]; + if ( + ResultTreinandosTurmas['CodigoTurma'] == StudentsIDs[i] + ) { + let sqlQry3 = `SELECT TOP 1 IDChamadas FROM ${db}Chamadas ORDER BY IDChamadas DESC;`; + sqlServerConnection + .request() + .query(sqlQry3, function (error3, results3, fields) { + console.log(results3); + let idchamada = results3.recordsets[0].length + ? results3.recordsets[0][0]['IDChamadas'] + 1 + : 1; + let idturma = ResultTurmasCalendario['IdTurma']; + let idcurso = ResultTurmasCalendario['CodigoCurso']; + let data2 = formatDate( + ResultTurmasCalendario['Data'], + 0 + ); + let hora = formatDate( + ResultTurmasCalendario['HoraInicial'], + 1 + ); + let horainicio = formatDate( + ResultTurmasCalendario['HoraInicial'], + 1 + ); + let horatermino = formatDate( + ResultTurmasCalendario['HoraFinal'], + 1 + ); + let idinstrutor = + ResultTurmasCalendario['CodigoInstrutor']; + let dataenvioapp = formatDate(new Date(), 0); + let dataatualizacaoapp = formatDate(new Date(), 0); + let idfuncionarioapp = + ResultTurmasCalendario['CodigoInstrutor']; + let sqlQry4 = `INSERT INTO ${db}Chamadas + (IDChamadas, IDTurma, IDCurso, Data, Hora, HoraInicio, HoraTermino, IDInstrutor, Flex, APP, DataEnvioAPP, DataAtualizacaoAPP, IDFuncionarioAPP) + VALUES + (${idchamada},${idturma},${idcurso},'${date}','${hora}','${horainicio}','${horatermino}',${idinstrutor},1,1,'${dataenvioapp}','${dataatualizacaoapp}',${idfuncionarioapp});`; + + sqlServerConnection + .request() + .query( + sqlQry4, + function (error6, results6, fields) { + if (!error6) { + let sqlQry6 = `DELETE FROM ${db}ChamadasConteudos WHERE IDChamadas = ${idchamada};`; + + sqlServerConnection + .request() + .query( + sqlQry6, + function (error7, results7, fields) { + if (!error7) { + let sqlQry7 = `INSERT INTO ${db}ChamadasConteudos (IDChamadas, CodigoConteudo, DescricaoConteudo) VALUES (${idchamada}, 0, '${content}');`; + //console.log(sqlQry7); + sqlServerConnection + .request() + .query( + sqlQry7, + function ( + error8, + results8, + fields + ) { + if (!error8) { + let sqlQry8 = `UPDATE ${db}TurmasCalendario SET Ministrado = 1, Data = '${date}' WHERE IdTurmasCalendario = ${ResultTurmasCalendario['IdTurmasCalendario']};`; + //console.log(sqlQry8); + sqlServerConnection + .request() + .query( + sqlQry8, + function ( + error9, + results9, + fields + ) { + if (!error9) { + let sqlQry9 = `DELETE FROM ${db}ChamadasDetalhes WHERE IDChamadas = ${idchamada};`; + //console.log(sqlQry9); + sqlServerConnection + .request() + .query( + sqlQry9, + function ( + error10, + results10, + fields + ) { + if (!error10) { + let sqlQry10 = `INSERT INTO ${db}ChamadasDetalhes + (IDChamadas, IDTreinando, Presente, Avisada, Justificativa, UltimaCarta) VALUES + (${idchamada}, ${ResultTreinandosTurmas['IDTreinando']}, 1, 0, null, null);`; + //console.log(sqlQry10); + sqlServerConnection + .request() + .query( + sqlQry10, + function ( + error11, + results11, + fields + ) { + if ( + !error11 + ) { + i++; + CheckDateExists( + db, + date, + idteacher, + StudentsIDs, + i, + Nomes, + res, + content, + idchamada + ); + } + } + ); + } + } + ); + } + } + ); + } + } + ); + } + } + ); + } else { + console.log('erro sqlQry4: ' + sqlQry4); + console.log(error6); + } + } + ); + }); + } else { + console.log('Não existe'); + + var sqlQry5 = `SELECT * FROM ${db}Clientes WHERE IDCliente = ${StudentsIDs[i]};`; + sqlServerConnection + .request() + .query(sqlQry5, function (error5, results5, fields) { + if (!error5 && results5.length != 0) { + if (Nomes == '') { + console.log(results5.recordsets); + Nomes = results5.recordset[0]['Nome']; + } else { + Nomes += ', ' + results5.recordset[0]['Nome']; + } + } + i++; + CheckDateExists( + db, + date, + idteacher, + StudentsIDs, + i, + Nomes, + res, + content, + null + ); + }); + } + } else { + console.log('erro sqlQry2'); + i++; + CheckDateExists( + db, + date, + idteacher, + StudentsIDs, + i, + Nomes, + res, + content, + null + ); + } + }); + } else { + console.log('erro: turmas calendário retornou null'); + i++; + CheckDateExists( + db, + date, + idteacher, + StudentsIDs, + i, + Nomes, + res, + content, + null + ); + } + } else { + console.log('erro sqlQry1: ' + error1); + i++; + CheckDateExists( + db, + date, + idteacher, + StudentsIDs, + i, + Nomes, + res, + content, + null + ); + } + }); + } else { + //console.log("finalIDchamada: " + finalIDchamada); + res.send( + JSON.stringify({ + idcallresponse: finalIDchamada, + }) + ); + } + } catch (error) { + console.error(error); + res.send( + JSON.stringify({ + error: error, + }) + ); + } +} + +function formatDate(date, ret) { + var novaData = date + .toISOString() + .replace(/T/, ' ') + .replace(/\..+/, '') + .split(' '); + return novaData[ret]; +} + +function InsertNotes() { + console.log(new Date().toUTCString() + ' - /InsertNotes'); + const SQLQryNotasAulas = `update stepclass A + join + (select * from + (select distinct + *, + ((AC2.TotalAcertos / AC2.ItensAula) * 10) as 'Nota' + from ( + select + *, + (AC.Acertos + AC.Erros + AC.Atividades) as 'ItensAula', + (AC.Acertos + AC.NotaAtividades) as 'TotalAcertos' + from + (select + sc.idusers, + sc.idclasses, + sc.idunits, + sc.completedClass, + sc.datefinal, + coalesce((ea.iscorrect), 0) as 'Acertos', + coalesce(sum(case when ea.iscorrect = 1 then 0 else 1 end), 0) as 'Erros', + (SELECT COUNT(*) FROM userstages WHERE idusers = sc.idusers AND idclasses = sc.idclasses AND idunits = sc.idunits) AS 'Atividades', + (SELECT coalesce(SUM(note), 0) FROM userstages WHERE idusers = sc.idusers AND idclasses = sc.idclasses AND idunits = sc.idunits) AS 'NotaAtividades', + sc.note + from (select * from stepclass sc where sc.completedClass = 1 and sc.idusers > 190008 and sc.note is null and (CASE WHEN STR_TO_DATE(sc.datefinal, '%d/%m/%Y') < NOW() OR sc.homework = 1 THEN 1 ELSE 0 END) = 1) sc + left join usergivenanswers ug on ug.idclasses = sc.idclasses and ug.idusers = sc.idusers and ug.idunits = sc.idunits + left join exerciseanswers ea on ea.idexerciseanswers = ug.idexerciseanswers + left join userstages us on us.idclasses = sc.idclasses and us.idusers = sc.idusers and us.idunits = sc.idunits + group by sc.idusers, sc.idclasses, sc.idunits, sc.completedClass, sc.note, sc.datefinal, ea.iscorrect) AC) AC2) AC3) B + on A.idusers = B.idusers and A.idunits = B.idunits and A.idclasses = B.idclasses + set A.note = B.Nota;`; + const SQLNewInsertNotes = `update stepclass A + join (select + R.idusers, + R.idunits, + R.idclasses, + R.Questoes, + R.EAcertos as 'ExerciciosAcertos', + R.TAcertos as 'TarefasAcertos', + case + when (R.Questoes + R.TAcertos + R.TErros) = 0 then 10 + when ((R.EAcertos + R.TAcertos) / (R.Questoes + R.TAcertos + R.TErros) * 10) > 10 then 10 + else ((R.EAcertos + R.TAcertos) / (R.Questoes + R.TAcertos + R.TErros) * 10) + end as 'Nota' + from (select distinct + sc.idstepclass, + sc.idusers, + sc.idunits, + sc.idclasses, + ExA.Questoes, + (select count(*) from usergivenanswers ug inner join exerciseanswers ea on ea.idexerciseanswers = ug.idexerciseanswers and ea.iscorrect = 1 where ug.idclasses = sc.idclasses and ug.idunits = sc.idunits and ug.idusers = sc.idusers) as 'EAcertos', + (select count(*) from usergivenanswers ug inner join exerciseanswers ea on ea.idexerciseanswers = ug.idexerciseanswers and ea.iscorrect = 0 where ug.idclasses = sc.idclasses and ug.idunits = sc.idunits and ug.idusers = sc.idusers) as 'EErros', + (select count(*) from userstages us where us.idclasses = sc.idclasses and us.idunits = sc.idunits and us.idusers = sc.idusers and us.note = 1) as 'TAcertos', + (select count(*) from userstages us where us.idclasses = sc.idclasses and us.idunits = sc.idunits and us.idusers = sc.idusers and us.note = 0) as 'TErros' + from stepclass sc + inner join (select distinct + cl.idclasses, + cl.name as 'Aula', + count(cc.idexercises) as 'Questoes' + from classes cl + inner join classescontent cc on cc.idclasses = cl.idclasses + left join exercisequestions eq on eq.idexercises = cc.idexercises + group by cl.idclasses, cc.idclasses + order by cl.idclasses asc) ExA on ExA.idclasses = sc.idclasses + where sc.note is null and sc.completedClass = 1 and (now() >= date_add(convert(sc.dateinicial, date), interval 7 day) or sc.homework is not null)) R) B + on A.idusers = B.idusers and A.idunits = B.idunits and A.idclasses = B.idclasses + set A.note = B.Nota;`; + + mysqlConnection.query(SQLNewInsertNotes, function (error, results, fields) { + console.log(new Date().toUTCString() + ' - Notas de aulas lançadas'); + InsertCourseNotes(); + return true; + }); +} + +function InsertNotasDetalhes(idusers, idunits, idclasses) { + console.log(new Date().toUTCString() + ' - /InsertNotasDetalhes'); + let sqlQry0 = ` + SELECT + * + FROM + (SELECT note AS Nota from stepclass where idusers = ${idusers} and idunits = ${idunits} and idclasses = ${idclasses}) AS note, + (SELECT reference_db AS Banco from units where idunits = ${idunits}) AS banco, + (SELECT idcourses AS IDCurso from classes where idclasses = ${idclasses}) AS curso, + (SELECT ordem + 1 AS Conceito from classes where idclasses = ${idclasses}) AS conceito;`; + + mysqlConnection.query(sqlQry0, function (error, results, fields) { + if (!error && results.length != 0) { + let nota = results[0]['Nota']; + let db = results[0]['Banco'] + '.dbo.'; + let idcourses = results[0]['IDCurso']; + let concept = results[0]['Conceito']; + + let sqlServerQuery = ` + INSERT INTO + ${db}NotasDetalhes(IDTurma, IDCurso, IDMatricula, IDTreinando, IDConceito, Nota) + SELECT + CodigoTurma, IDCurso, IDMatricula, IDTreinando, ${concept} as IDConceito, ${nota} as Nota FROM ${db}TreinandosTurmas WHERE IDMatricula = ${idusers} AND IDCurso = ${idcourses}; + + INSERT INTO + ${db}NotasDetalhesSequencial(IDTurma, IDCurso, IDMatricula, IDTreinando, IDConceito) + SELECT + CodigoTurma, IDCurso, IDMatricula, IDTreinando, ${concept} as IDConceito FROM ${db}TreinandosTurmas WHERE IDMatricula = ${idusers} AND IDCurso = ${idcourses};`; + //console.log(sqlServerQuery); + sqlServerConnection + .request() + .query(sqlServerQuery, function (error1, results1, fields) { + return true; + }); + } + }); +} + +function InsertCourseNotes() { + console.log(new Date().toUTCString() + ' - /InsertCourseNotes'); + const SQLQry = `select + Tab2.idcourses, + Tab2.idusers, + (sum(Tab2.note) / Tab2.AulasCurso) as 'note', + Tab2.idunits + from ( + select + Tab1.*, + sc.idstepclass, + sc.note + from ( + select + sc.idusers, + co.idcourses, + sc.idunits, + count(sc.idclasses) as 'Aulas', + (select count(*) from classes cl1 where cl1.idcourses = co.idcourses and cl1.disabled = 0) as 'AulasCurso' + from stepclass sc + inner join classes cl on cl.idclasses = sc.idclasses + inner join courses co on co.idcourses = cl.idcourses + where sc.note is not null + group by sc.idusers, co.idcourses, sc.idunits) Tab1 + inner join stepclass sc on sc.idunits = Tab1.idunits and sc.idusers = Tab1.idusers + inner join classes cl on cl.idclasses = sc.idclasses and cl.idcourses = Tab1.idcourses + where Tab1.Aulas = Tab1.AulasCurso + order by idunits, idcourses, idusers) Tab2 + group by Tab2.idcourses, Tab2.idusers, Tab2.idunits;`; + + mysqlConnection.query(SQLQry, function (error, results, fields) { + LoopCursoNotas(0, results, function (Sucesso) { + console.log(new Date().toUTCString() + ' - Notas de cursos lançadas'); + return Sucesso; + }); + }); +} + +function LoopCursoNotas(Index, Registros, callback) { + if (!Registros) { + callback(false); + return; + } + if (Index < Registros.length) { + let SQLInsert = `INSERT INTO coursenotes (idcourses, idusers, note, idunits) VALUES (${Registros[Index]['idcourses']}, ${Registros[Index]['idusers']}, ${Registros[Index]['note']}, ${Registros[Index]['idunits']});`; + //console.log(SQLInsert); + mysqlConnection.query(SQLInsert, function (error, results, fields) { + if (!error) { + console.log( + 'Notas do curso lançadas para o aluno ' + + Registros[Index]['idusers'] + + ' da unidade ' + + Registros[Index]['idcourses'] + ); + } + Index++; + LoopCursoNotas(Index, Registros, callback); + }); + } else { + callback(true); + } +} + +let IndexNotaDetalhe = 0; +function LoopNotasDetalhes(idusers, idunits, idcourses, conceito) { + if (IndexNotaDetalhe <= conceito) { + let sqlQry = `SELECT idclasses FROM classes WHERE ordem = ${IndexNotaDetalhe} AND idcourses = ${idcourses};`; + mysqlConnection.query(sqlQry, function (error, results, fields) { + let idclasses; + try { + idclasses = results[0]['idclasses']; + } catch (e) { + return true; + } + + InsertNotasDetalhes(idusers, idunits, idclasses); + setTimeout(() => { + IndexNotaDetalhe++; + LoopNotasDetalhes(idusers, idunits, idcourses, IndexNotaDetalhe); + }, 200); + }); + } else { + return true; + } +} + +function InsertTraineeProgramNotes(idusers, idunits, idclasses) { + console.log('/InsertTraineeProgramNotes'); + const SQLQry = ` + INSERT INTO + traineeprogramnotes (idtraineeprogram, idusers, note, idunits) + SELECT + (SELECT DISTINCT + idtraineeprogram + FROM + traineeprogramcourses + WHERE + idcourses = (SELECT idcourses FROM classes WHERE idclasses = ${idclasses})) idtraineeprogram, + ${idusers} AS idusers, + (SELECT + SUM(note) / COUNT(*) AS Nota + FROM + coursenotes + WHERE + idusers = ${idusers} AND idunits = ${idunits}) AS note, + ${idunits} AS idunits + FROM + (SELECT 1) r + WHERE + (SELECT COUNT(*) as qtde FROM coursenotes WHERE idusers = ${idusers} AND idunits = ${idusers}) = + (SELECT COUNT(*) as qtde FROM traineeprogramcourses WHERE + idtraineeprogram = (SELECT DISTINCT idtraineeprogram FROM traineeprogramcourses WHERE idcourses = (SELECT idcourses FROM classes WHERE idclasses = ${idclasses})));`; + + mysqlConnection.query(SQLQry, function (error, results, fields) { + if (!error && results.length != 0) { + //console.log(results['affectedRows']); + /*if (results['affectedRows'] == 1) { + + let sqlQry0 = ` + SELECT * FROM + (SELECT SUM(note) / COUNT(*) AS Nota FROM coursenotes WHERE idusers = ${idusers} AND idunits = ${idunits}) AS note, + (SELECT reference_db AS Banco from units where idunits = ${idunits}) AS banco, + (SELECT idcourses AS IDCurso from classes where idclasses = ${idclasses}) AS curso`; + + mysqlConnection.query(sqlQry0, function (error, results, fields) { + if (!error && results.length != 0) { + console.log(results[0]); + let nota = results[0]['Nota']; + let db = results[0]['Banco'] + ".dbo."; + let idcourses = results[0]['IDCurso']; + let sqlQry1 = ` + UPDATE + ${db}TreinandosTurmas tt + SET + Nota = ${nota} + WHERE + IDMatricula = ${idusers} + AND + IDCurso = ${idcourses}`; + //console.log(sqlQry1); + sqlServerConnection.request().query(sqlQry1, function (error1, results1, fields) { + console.log("/Inserted TreinandosTurmas"); + return true; + }) + } + else { + return false; + } + }); + } + else { + return true; + }*/ + return true; + } else { + return true; + } + }); +} + +function InsertUserStage(idusers, idunits, idclasses, note) { + mysqlConnection.query( + 'select * from userstages order by iduserstages desc;', + function (error, results, fields) { + let IDUserStages = ''; + if (!results || results == '' || results.length == 0) IDUserStages = '1'; + else IDUserStages = parseInt(results[0]['iduserstages']) + 1; + console.log(IDUserStages); + const SQLInsert = `INSERT INTO userstages(iduserstages, idstages, idusers, idunits, idclasses, note) values + (${IDUserStages}, 2, ${idusers}, ${idunits}, ${idclasses}, ${note});`; + mysqlConnection.query(SQLInsert, function (error, results, fields) { + if (!error) + console.log( + '/HomeWork success - Matrícula: ' + + idusers + + ' ; Unidade: ' + + idunits + ); + else + console.log( + '/HomeWork error - Matrícula: ' + idusers + ' ; Unidade: ' + idunits + ); + }); + } + ); +} + +function PreencherNotasSQLServer(Unidades, Index, callback) { + if (Index < Unidades.length) { + console.log( + 'Analisando unidade ' + + (Index + 1) + + ' de ' + + Unidades.length + + ' (' + + Unidades[Index]['Unidade'] + + ')' + ); + let SqlQueryMySQL = `select * from ( + select + cl.idcourses as 'IDCurso', + sc.idusers as 'IDMatricula', + (cl.ordem + 1) + ((co.idtypescourse - 1) * 16) as 'IDConceito', + sc.note as 'Nota' + from stepclass sc + inner join classes cl on cl.idclasses = sc.idclasses + inner join courses co on co.idcourses = cl.idcourses + inner join units un on un.idunits = sc.idunits + where co.idtypescourse in (1,2,3) and sc.idunits = ${Unidades[Index]['idunits']}) R + order by R.IDConceito asc;`; + mysqlConnection.query(SqlQueryMySQL, function (error, NotasMySQL, fields) { + let SqlQuerySQLServer = `select * from ${Unidades[Index]['db']}NotasDetalhes;`; + sqlServerConnection + .request() + .query(SqlQuerySQLServer, function (error, results, fields) { + let NotasSQLServer = []; + if (results['recordset']) { + NotasSQLServer = results['recordset']; + } + Unidades[Index].NotasLancar = []; + for (let i = 0; i < NotasMySQL.length; i++) { + let Existe = false; + for (let o = 0; o < NotasSQLServer.length; o++) { + if ( + NotasMySQL[i]['IDCurso'] == NotasSQLServer[o]['IDCurso'] && + NotasMySQL[i]['IDMatricula'] == + NotasSQLServer[o]['IDMatricula'] && + NotasMySQL[i]['IDConceito'] == NotasSQLServer[o]['IDConceito'] + ) { + Existe = true; + break; + } + } + if (!Existe) { + Unidades[Index].NotasLancar.push(NotasMySQL[i]); + } + } + console.log( + 'Registros para inserir: ' + Unidades[Index]['NotasLancar'].length + ); + InserirNotasSqlServer(Unidades, 0, Index, callback); + }); + }); + } else { + callback(Unidades); + } +} + +function InserirNotasSqlServer(Unidades, Index1, Index2, callback) { + if (Index1 < Unidades[Index2]['NotasLancar'].length) { + let SqlQuerySQLInsert = `insert into ${Unidades[Index2]['db']}NotasDetalhes (IDTurma, IDCurso, IDMatricula, IDTreinando, IDConceito, Nota) select top 1 tt.CodigoTurma, ${Unidades[Index2]['NotasLancar'][Index1]['IDCurso']}, ${Unidades[Index2]['NotasLancar'][Index1]['IDMatricula']}, tt.IDTreinando, ${Unidades[Index2]['NotasLancar'][Index1]['IDConceito']}, ${Unidades[Index2]['NotasLancar'][Index1]['Nota']} from ${Unidades[Index2]['db']}TreinandosTurmas tt where tt.IDMatricula = ${Unidades[Index2]['NotasLancar'][Index1]['IDMatricula']}`; + sqlServerConnection + .request() + .query(SqlQuerySQLInsert, function (error, results, fields) { + if (!error) { + let SqlQuerySQLInsert2 = `insert into ${Unidades[Index2]['db']}NotasDetalhesSequencial (IDTurma, IDCurso, IDMatricula, IDTreinando, IDConceito) select top 1 tt.CodigoTurma, ${Unidades[Index2]['NotasLancar'][Index1]['IDCurso']}, ${Unidades[Index2]['NotasLancar'][Index1]['IDMatricula']}, tt.IDTreinando, ${Unidades[Index2]['NotasLancar'][Index1]['IDConceito']} from ${Unidades[Index2]['db']}TreinandosTurmas tt where tt.IDMatricula = ${Unidades[Index2]['NotasLancar'][Index1]['IDMatricula']}`; + sqlServerConnection + .request() + .query(SqlQuerySQLInsert2, function (error, results, fields) { + Index1++; + InserirNotasSqlServer(Unidades, Index1, Index2, callback); + }); + } else { + Index1++; + InserirNotasSqlServer(Unidades, Index1, Index2, callback); + } + }); + } else { + Index2++; + PreencherNotasSQLServer(Unidades, Index2, callback); + } +} + +module.exports = routes; diff --git a/controllers/barcodeController.js b/controllers/barcodeController.js new file mode 100644 index 0000000..e9af441 --- /dev/null +++ b/controllers/barcodeController.js @@ -0,0 +1,384 @@ +require("../connections/mysql-server"); +require("../helpers/CheckToken"); +require("../helpers/config"); + +const express = require("express"); +const router = express.Router(); +const bodyParser = require("body-parser"); +const { genSerialList, generateCSV } = require("../helpers/serialBook"); + +router.use( + bodyParser.urlencoded({ + limit: "10mb", + extended: true, + }) +); +router.use( + bodyParser.json({ + limit: "10mb", + extended: true, + }) +); + +var routes = function () { + router.get("/listLotes", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + * + FROM barlotes;`, + res, + req.originalUrl + ); + }); + + router.get("/listBarCodes", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + * + FROM barcodes;`, + res, + req.originalUrl + ); + }); + + router.get("/listBarcodesByAny/:field/:value", verifyJWT, (req, res) => { + var field = req.params.field; + var value = req.params.value; + execSQLQuery( + `SELECT + bc.*, + un.unityname as 'unity', + co.name as 'course', + un2.unityname as 'unity_env', + co2.name as 'course_apo' + FROM barcodes bc + left join units un on un.idunits = bc.idunits + left join courses co on co.idcourses = bc.idcourses + left join units un2 on un2.idunits = bc.idunits_env + left join courses co2 on co2.idcourses = bc.idcourses_apo + WHERE bc.${field} = '${value}';`, + res, + req.originalUrl + ); + }); + + router.post("/insertLotes", verifyJWT, (req, res) => { + const qtdepack = parseInt(req.body.qtdepack); + const date = req.body.date; + execSQLQuery( + `INSERT INTO barlotes(qtdepack, date) + VALUES (?, ?);`, + res, + req.originalUrl, + [qtdepack, date] + ); + }); + + router.post("/createSerial", verifyJWT, (req, res) => { + let oldserialExists = req.body.oldserial; + let quantity = parseInt(req.body.quantity); + let disAllowFranchise = quantity < 2 && !oldserialExists; + + function deleteList(list) { + let deleteQuery = "DELETE FROM myrobot.serialbook WHERE serial = ?"; + Object.values(list).forEach((element) => { + mysqlConnection.query(deleteQuery, element.serial, function (err) { + if (err) { + console.log( + new Date(), + "Erro ao deletar registros api/barcode/createSerial post", + err + ); + } + }); + }); + } + + if (quantity < 1 || disAllowFranchise) { + console.log( + new Date(), + "Erro ao gerar registros api/barcode/createSerial post error 400" + ); + res + .status(400) + .send( + "Quantidade mínima de etiquetas por lote: 1 ou código antigo não foi enviado" + ); + } else { + let selectQuery = "SELECT serial FROM myrobot.serialbook;"; + mysqlConnection.query(selectQuery, function (error, results, fields) { + if (error) { + console.log( + new Date(), + "Erro ao obter registros api/barcode/createSerial post error 500" + ); + res.status(500).send(error); + } + genSerialList(quantity, results) + .then((serialList) => { + let insertQuery = + "INSERT INTO myrobot.serialbook (serial, createdAt, updatedAt, oldserial) VALUES ?"; + let valuesList = []; + Object.values(serialList).forEach((element) => { + quantity < 2 ? (element.oldserial = req.body.oldserial) : ""; + valuesList.push([ + element.serial, + element.createdAt, + element.updatedAt, + element.oldserial, + ]); + }); + mysqlConnection.query(insertQuery, [valuesList], function (err) { + if (err) { + console.log( + new Date(), + "Erro ao salvar registros api/barcode/createSerial post error 500", + err + ); + res.status(500).json({ + message: "Não foi possível salvar os registros", + erro: err, + }); + deleteList(serialList); + } else { + if (serialList.length < 2) { + console.log( + new Date(), + " - api/barcode/createSerial post success 200" + ); + res.status(200).json({ + serial: serialList[0].serial, + }); + } else { + generateCSV(serialList) + .then((path) => { + console.log( + new Date(), + " - api/barcode/createSerial post success 200" + ); + res.download(path); + }) + .catch((err) => { + console.log( + new Date(), + "Erro ao enviar registros api/barcode/createSerial post error 500", + err + ); + res.status(500).json({ + message: "Não foi possível enviar os registros", + erro: err, + }); + deleteList(serialList); + }); + } + } + }); + }) + .catch((error) => { + console.log( + new Date(), + "Erro ao gerar registros api/barcode/createSerial post error 500", + error + ); + res.status(500).json({ + message: "Impossível gerar seriais", + erro: error, + }); + }); + }); + } + }); + + router.put("/createSerial", verifyJWT, (req, res) => { + let dateUpdate = new Date(); + let values = [ + req.body.user, + req.body.course, + req.body.unity, + true, + dateUpdate, + req.body.serial, + ]; + Object.values(values).forEach((element) => { + let notEmpty = !!element; + if (!notEmpty) { + return res.status(400).json({ error: "Faltam campos na requisição" }); + } + }); + let updateQuery = + "UPDATE myrobot.serialbook SET iduser = ?, idcourse = ?, idunity = ?, used = ?, updatedAt = ? WHERE serial = ? AND used = false"; + mysqlConnection.query( + updateQuery, + values, + function (error, results, fields) { + if (error) { + console.log( + new Date(), + "Erro ao alterar registro api/barcode/createSerial put error 500", + error + ); + res.status(500).json({ + message: "Não foi possível atualizar o serial", + }); + } else { + console.log( + new Date(), + " - api/barcode/createSerial put success 200" + ); + res.status(200).json({ + results: results, + }); + } + } + ); + }); + + router.get("/createSerial", verifyJWT, (req, res) => { + let values = [req.query.user, req.query.course, req.query.unity]; + let validFields = true; + for (let i = 0; i < values.length; i++) { + let notEmpty = !!values[0]; + if (!notEmpty) { + validFields = false; + break; + } + } + + if (validFields) { + let selectQuery = + "SELECT * FROM myrobot.serialbook WHERE iduser = ? AND idcourse = ? AND idunity = ?" + mysqlConnection.query( + selectQuery, + values, + function (error, results, fields) { + if (error) { + console.log( + new Date(), + "Erro ao obter registros api/barcode/createSerial get error 500", + error + ); + res.status(500).json({ + message: "Não foi possível pesquisar pelo serial", + }); + } else { + console.log(new Date(), "api/barcode/createSerial get 200"); + res.status(200).json({ + results: results, + }); + } + } + ); + } else { + console.log( + new Date(), + "Erro ao obter registro api/barcode/createSerial get error 400" + ); + return res.status(400).json({ error: "Faltam campos na requisição" }); + } + }); + + router.get("/listSerial", verifyJWT, (req, res) => { + let selectQuery = + "SELECT sb.idserialbook, sb.serial, sb.createdAt, sb.oldserial FROM myrobot.serialbook as sb limit 100;"; + mysqlConnection.query(selectQuery, function (error, results, fields) { + if (error) { + console.log(error); + res.status(500).json({ + message: "Não foi possivel obter os seriais", + }); + } else { + res.status(200).json({ + results: results, + }); + } + }); + }); + + router.post("/insertBarcodes", verifyJWT, (req, res) => { + const idbarlotes = parseInt(req.body.idbarlotes); + const _key = req.body._key; + const ordem = parseInt(req.body.ordem); + execSQLQuery( + `INSERT INTO barcodes(idbarlotes, _key, ordem) VALUES + (?, ?, ?);`, + res, + req.originalUrl, + [idbarlotes, _key, ordem] + ); + }); + + router.patch("/updateBarcodes", verifyJWT, (req, res) => { + const idbarcodes = parseInt(req.body.idbarcodes); + const idusers = parseInt(req.body.idusers); + const idunits = parseInt(req.body.idunits); + const idcourses = parseInt(req.body.idcourses); + execSQLQuery( + `UPDATE barcodes SET + idusers = ${idusers}, + idunits = ${idunits}, + idcourses = ${idcourses} + WHERE idbarcodes = ${idbarcodes};`, + res, + req.originalUrl + ); + }); + + router.post("/generateTxt", verifyJWT, (req, res) => { + var name = req.body.name; + var content = req.body.content; + var fs = require("fs"); + fs.writeFile( + Variables("src_media") + "barcodes/" + name + ".txt", + content, + function (erro) { + if (erro) { + throw erro; + } else { + res.send(true); + } + } + ); + }); + + router.get("/downloadPack/:idbarlotes", verifyJWT, (req, res) => { + var idbarlotes = req.params.idbarlotes; + var path = Variables("src_media") + "barcodes"; + var fs = require("fs"); + if (!fs.existsSync(path + "/codigo_barras_" + idbarlotes + ".zip")) { + require("all-unpacker").pack( + path + "/barlote_" + idbarlotes + ".zip", + { + targetDir: path + "/codigo_barras_" + idbarlotes + ".txt", + }, + function (err, files, text) { + if (err) return console.error(err); + if (files) console.log("files", files); + if (text) { + console.log("text", text); + console.log("compactado"); + res.send(true); + } + } + ); + } else { + res.send(true); + } + }); + + router.post("/VincularCodigo", verifyJWT, (req, res) => { + const idbarcodes = parseInt(req.body.idbarcodes); + const idunits_env = parseInt(req.body.idunits_env); + const idcourses_apo = parseInt(req.body.idcourses_apo); + execSQLQuery( + `UPDATE barcodes SET + idunits_env = ${idunits_env}, + idcourses_apo = ${idcourses_apo} + WHERE idbarcodes = ${idbarcodes};`, + res, + req.originalUrl + ); + }); + + return router; +}; +module.exports = routes; diff --git a/controllers/baseController.js b/controllers/baseController.js new file mode 100644 index 0000000..da22d1f --- /dev/null +++ b/controllers/baseController.js @@ -0,0 +1,17 @@ +require('../connections/mysql-server'); + +class BaseController { + constructor() { + this.express = require('express'); + this.app = this.express(); + this.router = this.express.Router(); + this.bodyParser = require('body-parser'); + + this.app.use(this.bodyParser.urlencoded({ extended: true })); + this.app.use(this.bodyParser.json()); + + this.declareRoute(); + } +} + +module.exports = BaseController; diff --git a/controllers/chamadaController.js b/controllers/chamadaController.js new file mode 100644 index 0000000..8292575 --- /dev/null +++ b/controllers/chamadaController.js @@ -0,0 +1,171 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/getChamadasProfessor/:IDFuncionario/:db', verifyJWT, (req, res) => { + const IDFuncionario = parseInt(req.params.IDFuncionario); + const db = req.params.db; + execSQLQuery2(`SELECT + ch.IDChamadas, + ch.IDTurma, + ch.IDCurso, + ch.Data, + tt.IDMatricula, + co.NomeVersao + FROM ${db}Chamadas ch + INNER JOIN ${db}Cursos co ON co.Codigo = ch.IDCurso + INNER JOIN ${db}TreinandosTurmas tt ON tt.IDCurso = ch.IDCurso AND tt.CodigoTurma = ch.IDTurma + WHERE ch.IDInstrutor = ${IDFuncionario};`, res, req.originalUrl); + }); + + router.get('/getQRCodeAluno/:_key', verifyJWT, (req, res) => { + const _key = req.params._key; + execSQLQuery(`SELECT + qr.idusers, + qr.idunits + FROM qrcodes qr + where qr._key = ?;`, res, req.originalUrl, [_key]); + }); + + router.get('/getInfoAluno/:IDMatricula/:db', verifyJWT, (req, res) => { + const IDMatricula = parseInt(req.params.IDMatricula); + const db = req.params.db; + execSQLQuery2(`SELECT DISTINCT + cl.Nome, + cu.Codigo AS 'IDCurso', + cu.NomeVersao, + tt.IDTreinando, + tt.CodigoTurma, + (select count(*) from ${db}Chamadas ch2 where ch2.IDTurma = tt.CodigoTurma and ch2.IDCurso = tt.IDCurso) AS qtde_presencas + FROM ${db}TreinandosTurmas tt + INNER JOIN ${db}Clientes cl ON cl.IDCliente = tt.IDTreinando + INNER JOIN ${db}Cursos cu ON cu.Codigo = tt.IDCurso + LEFT JOIN ${db}Chamadas ch ON tt.CodigoTurma = ch.IDTurma AND tt.IDCurso = ch.IDCurso + LEFT JOIN ${db}ChamadasDetalhes cd ON cd.IDChamadas = ch.IDChamadas AND cd.IDTreinando = tt.IDTreinando + WHERE tt.IDMatricula = ${IDMatricula} and tt.CodigoTurma > 0 + GROUP BY cl.Nome, cu.Codigo, cu.NomeVersao, tt.IDTreinando, tt.CodigoTurma, tt.IDCurso + ORDER BY cl.Nome ASC;`, res, req.originalUrl); + }); + + router.get('/checarCursoParaChamada/:IDTurma/:idCourse/:db', verifyJWT, (req, res) => { + const IDTurma = parseInt(req.params.IDTurma); + const idCourse = parseInt(req.params.idCourse); + const db = req.params.db; + execSQLQuery2(`SELECT + tc.IdTurmasCalendario, + tc.Data, + tc.HoraInicial, + tc.HoraFinal, + tc.CodigoInstrutor + FROM ${db}TurmasCalendario tc + WHERE tc.IdTurma = ${IDTurma} AND CodigoCurso = ${idCourse} AND tc.Ministrado = 0 + ORDER BY tc.Data ASC;`, res, req.originalUrl); + }); + + router.post('/EnviarChamada', verifyJWT, (req, res) => { + const db = req.body.db; + const Alunos = JSON.parse(req.body.Alunos); + console.log(Alunos); + RealizaChamada(0, db, Alunos, function(Sucesso) { + res.send(Sucesso); + }); + }); + + + router.post('/insertNewToken', verifyJWT, (req, res) => { + const db = req.body.db; + const description = req.body.description; + const idunits = req.body.idunits; + const token = req.body.token; + execSQLQuery(`insert into appnotifications (description, idunits, token) values (?, ?, ?);`, res, req.originalUrl, [description, idunits, token]); + }); + + router.post('/changeReceive', verifyJWT, (req, res) => { + const token = req.body.token; + execSQLQuery(`update appnotifications set receive = !receive where token = ?;`, res, req.originalUrl, [token]); + }); + + router.get('/getAllUnitTokens/:idunits', verifyJWT, (req, res) => { + const idunits = req.params.idunits; + execSQLQuery(`select * from appnotifications where receive = 1 and ${(idunits > 0) ? 'idunits = ?' : 'true'};`, res, req.originalUrl, [idunits]); + }); + + + return router; +}; + +function RealizaChamada(Index, db, Alunos, callback) { + if (Index < Alunos.length) { + const sqlGetTurmasCalendario = `SELECT + tc.IdTurmasCalendario, + tc.Data, + tc.HoraInicial, + tc.HoraFinal, + tc.CodigoInstrutor, + tt.IDTreinando + FROM ${db}TurmasCalendario tc + inner join ${db}TreinandosTurmas tt on tt.IDCurso = tc.CodigoCurso and tc.IdTurma = tt.CodigoTurma + WHERE tc.IdTurma = ${Alunos[Index]['CodigoTurma']} AND CodigoCurso = ${Alunos[Index]['IDCurso']} AND tc.Ministrado = 0 + ORDER BY tc.Data ASC;`; + sqlServerConnection.request().query(sqlGetTurmasCalendario, function (error0, results0, fields0) { + if (error0 || !results0.recordset || results0.recordset.length == 0) { + console.log("Erro GetTurmasCalendario: " + error0); + Index++; + RealizaChamada(Index, db, Alunos, callback); + return; + } + const TurmasCalendario = results0.recordset; + Alunos[Index]['IDTreinando'] = TurmasCalendario[0]['IDTreinando']; + const sqlGetChamada = `select coalesce((SELECT TOP(1) IDChamadas FROM ${db}Chamadas ORDER BY IDChamadas DESC), 1) as 'IDChamadas';`; + sqlServerConnection.request().query(sqlGetChamada, function (error1, results1, fields1) { + const IDChamadas = results1.recordsets[0][0]['IDChamadas'] + 1; + const IDTurma = Alunos[Index]['CodigoTurma']; + const IDCurso = Alunos[Index]['IDCurso']; + const Data = formatDate(TurmasCalendario[0]['Data'], 0); + const Hora = formatDate(TurmasCalendario[0]['HoraInicial'], 1); + const HoraInicial = formatDate(TurmasCalendario[0]['HoraInicial'], 1); + const HoraFinal = formatDate(TurmasCalendario[0]['HoraFinal'], 1); + const CodigoInstrutor = TurmasCalendario[0]['CodigoInstrutor']; + const DataEnvioApp = formatDate(new Date(), 0); + + const sqlInsertChamada = `INSERT INTO ${db}Chamadas (IDChamadas, IDTurma, IDCurso, Data, Hora, HoraInicio, HoraTermino, IDInstrutor, Flex, APP, DataEnvioAPP, DataAtualizacaoAPP, IDFuncionarioAPP) + VALUES (${IDChamadas}, ${IDTurma}, ${IDCurso}, '${Data}', '${Hora}', '${HoraInicial}', '${HoraFinal}', ${CodigoInstrutor}, 1, 1, '${DataEnvioApp}', '${DataEnvioApp}', ${CodigoInstrutor});`; + sqlServerConnection.request().query(sqlInsertChamada, function (error2, results2, fields2) { + const sqlInsertChamadaConteudo = `INSERT INTO ${db}ChamadasConteudos (IDChamadas, CodigoConteudo, DescricaoConteudo) + VALUES (${IDChamadas}, 0, 'Aula de robótica');`; + sqlServerConnection.request().query(sqlInsertChamadaConteudo, function (error3, results3, fields3) { + const sqlUpdateTurmasCalendario = `UPDATE ${db}TurmasCalendario SET + Ministrado = 1, + Data = '${Data}' + WHERE IdTurmasCalendario = ${TurmasCalendario[0]['IdTurmasCalendario']};`; + sqlServerConnection.request().query(sqlUpdateTurmasCalendario, function (error4, results4, fields4) { + const sqlInsertChamadasDetalhes = `INSERT INTO ${db}ChamadasDetalhes (IDChamadas, IDTreinando, Presente, Avisada, Justificativa, UltimaCarta) + VALUES (${IDChamadas}, ${Alunos[Index]['IDTreinando']}, 1, 0, null, null);`; + sqlServerConnection.request().query(sqlInsertChamadasDetalhes, function (error5, results5, fields5) { + Index++; + RealizaChamada(Index, db, Alunos, callback); + }); + }); + }); + }); + }); + }); + } + else { + callback(true); + } +} + +function formatDate(date, ret) { + var novaData = date.toISOString().replace(/T/, ' ').replace(/\..+/, '').split(" "); + return novaData[ret]; +} + +module.exports = routes; \ No newline at end of file diff --git a/controllers/charactersController.js b/controllers/charactersController.js new file mode 100644 index 0000000..63f52b8 --- /dev/null +++ b/controllers/charactersController.js @@ -0,0 +1,580 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); +const { debug } = require('console'); + +const apikeyWatson = process.env.IBMTTS_APIKEY; +const apiurlServiceWatson = process.env.IBMTTS_SERVICEURL; + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + //#region CHARACTERSCONVERSATION + router.get('/getAllCharConv', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + from charactersConversation;`, res, req.originalUrl); + }); + + router.get('/getCharacterconversation/:idcharactersConversation', verifyJWT, (req, res) => { + const idcharactersConversation = parseInt(req.params.idcharactersConversation); + execSQLQuery(`SELECT + * + from charactersConversation + where idcharactersConversation = ${idcharactersConversation};`, res, req.originalUrl); + }); + + router.post('/insertCharConv', verifyJWT, (req, res) => { + const idcharactersConversation = parseInt(req.body.idcharactersConversation); + const description = req.body.description; + const idcharacters_1 = parseInt(req.body.idcharacters_1); + const idcharacters_2 = parseInt(req.body.idcharacters_2); + const idcharactersBackground = parseInt(req.body.idcharactersBackground); + const idcharactersFonts = parseInt(req.body.idcharactersFonts); + execSQLQuery(`INSERT INTO charactersConversation (description, idcharacters_1, idcharacters_2, idcharactersBackground, idcharactersFonts) + VALUES (?, ?, ?, ?, ?);`, res, req.originalUrl, [description, idcharacters_1, idcharacters_2, idcharactersBackground, idcharactersFonts]); + }); + + router.patch('/updateCharConv', verifyJWT, (req, res) => { + const idcharactersConversation = parseInt(req.body.idcharactersConversation); + const description = req.body.description; + const idcharacters_1 = parseInt(req.body.idcharacters_1); + const idcharacters_2 = parseInt(req.body.idcharacters_2); + const idcharactersBackground = parseInt(req.body.idcharactersBackground); + const idcharactersFonts = parseInt(req.body.idcharactersFonts); + execSQLQuery(`UPDATE charactersConversation SET + description = ?, + idcharacters_1 = ?, + idcharacters_2 = ?, + idcharactersBackground = ?, + idcharactersFonts = ? + WHERE idcharactersConversation = ?;`, res, req.originalUrl, [description, idcharacters_1, idcharacters_2, idcharactersBackground, idcharactersFonts, idcharactersConversation]); + }); + + router.get('/getCharConvDetails/:idcharactersConversation', verifyJWT, (req, res) => { + const idcharactersConversation = parseInt(req.params.idcharactersConversation); + execSQLQuery(`select + cc.idcharactersConversation, + cc.description, + cp.seconds, + cp.speed, + cc.idcharacters_1, + (select ch1.description from characters ch1 where ch1.idcharacters = cc.idcharacters_1) as 'character_1', + cc.idcharacters_2, + (select ch2.description from characters ch2 where ch2.idcharacters = cc.idcharacters_2) as 'character_2', + cc.idcharactersBackground, + cb.description as 'background', + cb.ext as 'backgroundExt', + cc.idcharactersFonts, + cf.description as 'font', + cp.fontSize, + cp.fontColor, + cp.idcharactersPhrases, + cp.charactertalking, + cp.idcharactersBaloons, + ba.description as 'baloon', + ba.ext as 'baloonExt', + cp.baloonColor, + cp.phrase, + cp.idcharactersFeelings_1, + (select cf1.description from charactersFeelings cf1 where cf1.idcharactersFeelings = cp.idcharactersFeelings_1) as 'characterFeeling_1', + cp.idcharactersFeelings_2, + (select cf2.description from charactersFeelings cf2 where cf2.idcharactersFeelings = cp.idcharactersFeelings_2) as 'characterFeeling_2', + cp.sintetizevoice, + cp.idcharactersVoices, + (select cv.description from charactersVoices cv where cv.idcharactersVoices = cp.idcharactersVoices) as 'voicename', + (select cv.voice from charactersVoices cv where cv.idcharactersVoices = cp.idcharactersVoices) as 'voice', + cp.idcharactersTransitions, + ct.description as 'transition', + ct.ext as 'transitionExt', + cp.ordem + from charactersConversation cc + left join charactersBackground cb on cb.idcharactersBackground = cc.idcharactersBackground + left join charactersFonts cf on cf.idcharactersFonts = cc.idcharactersFonts + left join charactersPhrases cp on cp.idcharactersConversation = cc.idcharactersConversation + left join charactersBaloons ba on ba.idcharactersBaloons = cp.idcharactersBaloons + left join charactersTransitions ct on ct.idcharactersTransitions = cp.idcharactersTransitions + where cc.idcharactersConversation = ${idcharactersConversation} + order by cp.ordem asc;`, res, req.originalUrl); + }); + + router.delete('/deleteCharacterconversation/:idcharactersConversation', verifyJWT, (req, res) => { + const idcharactersConversation = parseInt(req.params.idcharactersConversation); + execSQLQuery(`delete from charactersConversation + where idcharactersConversation = ${idcharactersConversation};`, res, req.originalUrl); + }); + + //#endregion + + //#region CHARACTERS + router.get('/getAllCharacters', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + from characters;`, res, req.originalUrl); + }); + + router.get('/getCharacter/:idcharacters', verifyJWT, (req, res) => { + const idcharacters = parseInt(req.params.idcharacters); + execSQLQuery(`SELECT + * + from characters + where idcharacters = ${idcharacters};`, res, req.originalUrl); + }); + + router.post('/insertCharacter', verifyJWT, (req, res) => { + const idcharacters = parseInt(req.body.idcharacters); + const description = req.body.description; + execSQLQuery(`INSERT INTO characters (description) + VALUES (?);`, res, req.originalUrl, [description]); + }); + + router.patch('/updateCharacter', verifyJWT, (req, res) => { + const idcharacters = parseInt(req.body.idcharacters); + const description = req.body.description; + execSQLQuery(`UPDATE characters SET + description = ? + WHERE idcharacters = ?;`, res, req.originalUrl, [description, idcharacters]); + }); + + router.delete('/deleteCharacter/:idcharacters', verifyJWT, (req, res) => { + const idcharacters = parseInt(req.params.idcharacters); + execSQLQuery(`delete from characters + where idcharacters = ${idcharacters};`, res, req.originalUrl); + }); + + //#endregion + + //#region BACKGROUNDS + router.get('/getAllBackgrounds', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + from charactersBackground;`, res, req.originalUrl); + }); + + router.get('/getBackground/:idcharactersBackground', verifyJWT, (req, res) => { + const idcharactersBackground = parseInt(req.params.idcharactersBackground); + execSQLQuery(`SELECT + * + from charactersBackground + where idcharactersBackground = ${idcharactersBackground};`, res, req.originalUrl); + }); + + router.post('/insertBackground', verifyJWT, (req, res) => { + const idcharactersBackground = parseInt(req.body.idcharactersBackground); + const description = req.body.description; + const ext = req.body.ext; + execSQLQuery(`INSERT INTO charactersBackground (description, ext) + VALUES (?, ?);`, res, req.originalUrl, [description, ext]); + }); + + router.patch('/updateBackground', verifyJWT, (req, res) => { + const idcharactersBackground = parseInt(req.body.idcharactersBackground); + const description = req.body.description; + const ext = req.body.ext; + execSQLQuery(`UPDATE charactersBackground SET + description = ?, + ext = ? + WHERE idcharactersBackground = ?;`, res, req.originalUrl, [description, ext, idcharactersBackground]); + }); + + router.delete('/deleteBackground/:idcharactersBackground', verifyJWT, (req, res) => { + const idcharactersBackground = parseInt(req.params.idcharactersBackground); + execSQLQuery(`delete from charactersBackground + where idcharactersBackground = ${idcharactersBackground};`, res, req.originalUrl); + }); + + //#endregion + + //#region FEELINGS + router.get('/getAllFeelings', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + from charactersFeelings;`, res, req.originalUrl); + }); + + router.get('/getFeeling/:idcharactersFeelings', verifyJWT, (req, res) => { + const idcharactersFeelings = parseInt(req.params.idcharactersFeelings); + execSQLQuery(`SELECT + * + from charactersFeelings + where idcharactersFeelings = ${idcharactersFeelings};`, res, req.originalUrl); + }); + + router.post('/insertFeeling', verifyJWT, (req, res) => { + const idcharactersFeelings = parseInt(req.body.idcharactersFeelings); + const description = req.body.description; + execSQLQuery(`INSERT INTO charactersFeelings (description) + VALUES (?);`, res, req.originalUrl, [description]); + }); + + router.patch('/updateFeeling', verifyJWT, (req, res) => { + const idcharactersFeelings = parseInt(req.body.idcharactersFeelings); + const description = req.body.description; + execSQLQuery(`UPDATE charactersFeelings SET + description = ? + WHERE idcharactersFeelings = ?;`, res, req.originalUrl, [description, idcharactersFeelings]); + }); + + router.delete('/deleteFeeling/:idcharactersFeelings', verifyJWT, (req, res) => { + const idcharactersFeelings = parseInt(req.params.idcharactersFeelings); + execSQLQuery(`delete from charactersFeelings + where idcharactersFeelings = ${idcharactersFeelings};`, res, req.originalUrl); + }); + + //#endregion + + //#region FONTS + router.get('/getAllFonts', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + from charactersFonts;`, res, req.originalUrl); + }); + + router.get('/getFont/:idcharactersFonts', verifyJWT, (req, res) => { + const idcharactersFonts = parseInt(req.params.idcharactersFonts); + execSQLQuery(`SELECT + * + from charactersFonts + where idcharactersFonts = ${idcharactersFonts};`, res, req.originalUrl); + }); + + router.post('/insertFont', verifyJWT, (req, res) => { + const idcharactersFonts = parseInt(req.body.idcharactersFonts); + const description = req.body.description; + execSQLQuery(`INSERT INTO charactersFonts (description) + VALUES (?);`, res, req.originalUrl, [description]); + }); + + router.patch('/updateFont', verifyJWT, (req, res) => { + const idcharactersFonts = parseInt(req.body.idcharactersFonts); + const description = req.body.description; + execSQLQuery(`UPDATE charactersFonts SET + description = ? + WHERE idcharactersFonts = ?;`, res, req.originalUrl, [description, idcharactersFonts]); + }); + + router.delete('/deleteFont/:idcharactersFonts', verifyJWT, (req, res) => { + const idcharactersFonts = parseInt(req.params.idcharactersFonts); + execSQLQuery(`delete from charactersFonts + where idcharactersFonts = ${idcharactersFonts};`, res, req.originalUrl); + }); + + //#endregion + + //#region VOICES + router.get('/getAllVoices', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + from charactersVoices;`, res, req.originalUrl); + }); + + router.get('/getVoice/:idcharactersVoices', verifyJWT, (req, res) => { + const idcharactersVoices = parseInt(req.params.idcharactersVoices); + execSQLQuery(`SELECT + * + from charactersVoices + where idcharactersVoices = ${idcharactersVoices};`, res, req.originalUrl); + }); + + router.post('/insertVoice', verifyJWT, (req, res) => { + const idcharactersVoices = parseInt(req.body.idcharactersVoices); + const description = req.body.description; + execSQLQuery(`INSERT INTO charactersVoices (description) + VALUES (?);`, res, req.originalUrl, [description]); + }); + + router.patch('/updateVoice', verifyJWT, (req, res) => { + const idcharactersVoices = parseInt(req.body.idcharactersVoices); + const description = req.body.description; + execSQLQuery(`UPDATE charactersVoices SET + description = ? + WHERE idcharactersVoices = ?;`, res, req.originalUrl, [description, idcharactersVoices]); + }); + + router.delete('/deleteVoice/:idcharactersVoices', verifyJWT, (req, res) => { + const idcharactersVoices = parseInt(req.params.idcharactersVoices); + execSQLQuery(`delete from charactersVoices + where idcharactersVoices = ${idcharactersVoices};`, res, req.originalUrl); + }); + + //#endregion + + //#region BALOONS + router.get('/getAllBaloons', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + from charactersBaloons;`, res, req.originalUrl); + }); + + router.get('/getBaloon/:idcharactersBaloons', verifyJWT, (req, res) => { + const idcharactersBaloons = parseInt(req.params.idcharactersBaloons); + execSQLQuery(`SELECT + * + from charactersBaloons + where idcharactersBaloons = ${idcharactersBaloons};`, res, req.originalUrl); + }); + + router.post('/insertBaloon', verifyJWT, (req, res) => { + const idcharactersBaloons = parseInt(req.body.idcharactersBaloons); + const description = req.body.description; + const ext = req.body.ext; + execSQLQuery(`INSERT INTO charactersBaloons (description, ext) + VALUES (?, ?);`, res, req.originalUrl, [description, ext]); + }); + + router.patch('/updateBaloon', verifyJWT, (req, res) => { + const idcharactersBaloons = parseInt(req.body.idcharactersBaloons); + const description = req.body.description; + const ext = req.body.ext; + execSQLQuery(`UPDATE charactersBaloons SET + description = ?, + ext = ? + WHERE idcharactersBaloons = ?;`, res, req.originalUrl, [description, ext, idcharactersBaloons]); + }); + + router.delete('/deleteBaloon/:idcharactersBaloons', verifyJWT, (req, res) => { + const idcharactersBaloons = parseInt(req.params.idcharactersBaloons); + execSQLQuery(`delete from charactersBaloons + where idcharactersBaloons = ${idcharactersBaloons};`, res, req.originalUrl); + }); + + //#endregion + + //#region PHRASES + router.get('/getAllPhrases', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + from charactersPhrases;`, res, req.originalUrl); + }); + + router.get('/getPhrase/:idcharactersPhrases', verifyJWT, (req, res) => { + const idcharactersPhrases = parseInt(req.params.idcharactersPhrases); + execSQLQuery(`SELECT + * + from charactersPhrases + where idcharactersPhrases = ${idcharactersPhrases};`, res, req.originalUrl); + }); + + router.get('/getPhrasesInConversation/:idcharactersConversation', verifyJWT, (req, res) => { + const idcharactersConversation = parseInt(req.params.idcharactersConversation); + execSQLQuery(`SELECT + * + from charactersPhrases + where idcharactersConversation = ${idcharactersConversation} + order by ordem asc;`, res, req.originalUrl); + }); + + router.post('/insertPhrase', verifyJWT, (req, res) => { + const idcharactersPhrases = parseInt(req.body.idcharactersPhrases); + const idcharactersConversation = parseInt(req.body.idcharactersConversation); + const seconds = parseFloat(req.body.seconds); + const speed = req.body.speed; + const charactertalking = req.body.charactertalking; + const idcharactersBaloons = req.body.idcharactersBaloons; + const baloonColor = req.body.baloonColor; + const phrase = req.body.phrase; + const fontSize = req.body.fontSize; + const fontColor = req.body.fontColor; + const idcharactersFeelings_1 = req.body.idcharactersFeelings_1; + const idcharactersFeelings_2 = req.body.idcharactersFeelings_2; + const sintetizevoice = req.body.sintetizevoice ? 1 : 0; + const idcharactersVoices = req.body.idcharactersVoices; + const idcharactersTransitions = req.body.idcharactersTransitions; + const ordem = parseInt(req.body.ordem); + execSQLQuery(`INSERT INTO charactersPhrases (idcharactersConversation, seconds, speed, charactertalking, idcharactersBaloons, baloonColor, fontSize, fontColor, phrase, idcharactersFeelings_1, idcharactersFeelings_2, sintetizevoice, idcharactersVoices, idcharactersTransitions, ordem) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`, res, req.originalUrl, [idcharactersConversation, seconds, speed, charactertalking, idcharactersBaloons, baloonColor, fontSize, fontColor, phrase, idcharactersFeelings_1, idcharactersFeelings_2, sintetizevoice, idcharactersVoices, idcharactersTransitions, ordem]); + }); + + router.patch('/updatePhrase', verifyJWT, (req, res) => { + const idcharactersPhrases = parseInt(req.body.idcharactersPhrases); + const idcharactersConversation = parseInt(req.body.idcharactersConversation); + const seconds = parseFloat(req.body.seconds); + const speed = parseFloat(req.body.speed); + const charactertalking = parseInt(req.body.charactertalking); + const idcharactersBaloons = parseInt(req.body.idcharactersBaloons); + const baloonColor = req.body.baloonColor; + const phrase = req.body.phrase; + const idcharactersFeelings_1 = parseInt(req.body.idcharactersFeelings_1); + const idcharactersFeelings_2 = parseInt(req.body.idcharactersFeelings_2); + const sintetizevoice = req.body.sintetizevoice ? 1 : 0; + const idcharactersVoices = parseInt(req.body.idcharactersVoices); + const idcharactersTransitions = parseInt(req.body.idcharactersTransitions); + const ordem = parseInt(req.body.ordem); + execSQLQuery(`UPDATE charactersPhrases SET + idcharactersConversation = ?, + seconds = ?, + speed = ?, + charactertalking = ?, + idcharactersBaloons = ?, + baloonColor = ?, + phrase = ?, + idcharactersFeelings_1 = ?, + idcharactersFeelings_2 = ?, + sintetizevoice = ?, + idcharactersVoices = ?, + idcharactersTransitions = ?, + ordem = ? + WHERE idcharactersPhrases = ?;`, res, req.originalUrl, [idcharactersConversation, seconds, speed, charactertalking, idcharactersBaloons, baloonColor, phrase, idcharactersFeelings_1, idcharactersFeelings_2, sintetizevoice, idcharactersVoices, idcharactersTransitions, ordem, idcharactersPhrases]); + }); + + router.delete('/deletePhrase/:idcharactersPhrases', verifyJWT, (req, res) => { + const idcharactersPhrases = parseInt(req.params.idcharactersPhrases); + execSQLQuery(`delete from charactersPhrases + where idcharactersPhrases = ${idcharactersPhrases};`, res, req.originalUrl); + }); + + router.delete('/deletePhrasesInConversation/:idcharactersConversation', verifyJWT, (req, res) => { + const idcharactersConversation = parseInt(req.params.idcharactersConversation); + execSQLQuery(`delete from charactersPhrases + where idcharactersConversation = ${idcharactersConversation};`, res, req.originalUrl); + }); + + //#endregion + + //#region TRANSITIONS + router.get('/getAllTransitions', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + from charactersTransitions;`, res, req.originalUrl); + }); + + router.get('/getTransition/:idcharactersTransitions', verifyJWT, (req, res) => { + const idcharactersTransitions = parseInt(req.params.idcharactersTransitions); + execSQLQuery(`SELECT + * + from charactersTransitions + where idcharactersTransitions = ${idcharactersTransitions};`, res, req.originalUrl); + }); + + router.post('/insertTransition', verifyJWT, (req, res) => { + const idcharactersTransitions = parseInt(req.body.idcharactersTransitions); + const description = req.body.description; + const ext = req.body.ext; + execSQLQuery(`INSERT INTO charactersTransitions (description, ext) + VALUES (?, ?);`, res, req.originalUrl, [description, ext]); + }); + + router.patch('/updateTransition', verifyJWT, (req, res) => { + const idcharactersTransitions = parseInt(req.body.idcharactersTransitions); + const description = req.body.description; + const ext = req.body.ext; + execSQLQuery(`UPDATE charactersTransitions SET + description = ?, + ext = ? + WHERE idcharactersTransitions = ?;`, res, req.originalUrl, [description, ext, idcharactersTransitions]); + }); + + router.delete('/deleteTransition/:idcharactersTransitions', verifyJWT, (req, res) => { + const idcharactersTransitions = parseInt(req.params.idcharactersTransitions); + execSQLQuery(`delete from charactersTransitions + where idcharactersTransitions = ${idcharactersTransitions};`, res, req.originalUrl); + }); + //#endregion + + + router.post('/tts', verifyJWT, (req, res) => { + const Texto = req.body.texto; + const Velocidade = req.body.speed; + const idzoevoices = req.body.idzoevoices; + const PollyVoice = req.body.PollyVoice; + const NomeArquivo = "sintetize.mp3"; + const shell = require('shelljs'); + mysqlConnection.query(`SELECT cf.TTSmode, (SELECT voice FROM zoevoices WHERE idzoevoices = 1) as voice FROM config cf;`, function (error, Config, fields) { + const TTSMode = Config[0]['TTSmode']; + let Voz = Config[0]['voice']; + if (PollyVoice != "") + Voz = PollyVoice; + + if (TTSMode == 3) { // WIDEO + const request = require('request'); + var options = { + uri: 'https://texttospeechapi.wideo.co/api/wideo-text-to-speech', + method: 'POST', + json: { "data":{"text":Texto,"speed":Velocidade,"voice":Voz} } + }; + request(options, function (error, response, body) { + if (!error && response.statusCode == 200) { + shell.exec(`wget "${response['body']['result']['url']}" -O ${Variables("src_media")}/audiosZoe/${NomeArquivo} -q;`, function(Sucesso) { + EnviarAudio(NomeArquivo, true, error, res, req); + }); + } + else { + console.log(error); + EnviarAudio(NomeArquivo, false, error, res, req); + } + }); + } + else if (TTSMode == 4) { // AMAZON POLLY + shell.exec(`python ${Variables('src_media')}assets/polly_service.py "${Texto}" "${Variables('src_media')}/audiosZoe/${NomeArquivo}" "${Voz}"`, function(Sucesso) { + EnviarAudio(NomeArquivo, true, null, res, req); + }); + } + else if (TTSMode == 6) { // WATSON IBM + const fs = require('fs'); + const TextToSpeechV1 = require('ibm-watson/text-to-speech/v1'); + const { IamAuthenticator } = require('ibm-watson/auth'); + + const textToSpeech = new TextToSpeechV1({ + authenticator: new IamAuthenticator({ apikey: apikeyWatson }), + serviceUrl: apiurlServiceWatson + }); + + const params = { + text: Texto, + voice: Voz, + accept: 'audio/wav' + }; + console.log("A" + " " + NomeArquivo); + textToSpeech.synthesize(params).then(response => { + const audio = response.result; + return textToSpeech.repairWavHeaderStream(audio); + }).then(repairedFile => { + fs.writeFileSync(`${Variables("src_media")}audiosZoe/${NomeArquivo}`, repairedFile); + console.log('audio.wav written with a corrected wav header'); + //EnviarAudio(NomeArquivo.replace(".mp3", ".wav"), true, null, res, req); + shell.exec(`ffmpeg -loglevel panic -i ${Variables("src_media")}audiosZoe/${NomeArquivo} ${Variables("src_media")}audiosZoe/${NomeArquivo} -o`, function(Sucesso) { + EnviarAudio(NomeArquivo, true, null, res, req); + }); + }).catch(err => { + console.log(err); + }); + } + }); + + }); + + function EnviarAudio(NomeArquivo, Sucesso, error, res, req) { + if (Sucesso) { + console.log(new Date().toUTCString() + " - " + req.originalUrl + " success 200"); + res.send(JSON.stringify({ + "status": 200, + "error": error, + "url_audio": "audiosZoe/" + NomeArquivo, + })); + } + else { + console.log(new Date().toUTCString() + " - " + req.originalUrl + " error 500"); + res.send(JSON.stringify({ + "status": 500, + "error": error, + "url_audio": null, + })); + } + } + + router.get('/SalvarAudioSintetizado/:nome', verifyJWT, (req, res) => { + const NomeArquivo = req.params.nome; + const shell = require('shelljs'); + shell.exec(`cp ${Variables("src_media")}/audiosZoe/sintetize.mp3 ${Variables("src_media")}/zoeGamesResources/audios/${NomeArquivo}.mp3`, function(Sucesso) { + res.send(true); + }); + }); + + return router; +}; + +module.exports = routes; \ No newline at end of file diff --git a/controllers/chatController.js b/controllers/chatController.js new file mode 100644 index 0000000..c9fe005 --- /dev/null +++ b/controllers/chatController.js @@ -0,0 +1,250 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); +const mysql = require('mysql'); + +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ + limit: '10mb', + extended: true +})); +router.use(bodyParser.json({ + limit: '10mb', + extended: true +})); + +var MySQLConfig = { + connectionLimit: 10, + host: Variables('ip_mysql'), + user: Variables('user_mysql'), + database: Variables('database_mysql'), + password: Variables('password_mysql'), + charset: "utf8mb4" +} + +const connection = mysql.createPool(MySQLConfig); + +var routes = function () { + + router.get('/getChat/:idusers_from/:idusers_to/:db', verifyJWT, (req, res) => { + let idusers_from = req.params.idusers_from; + let idusers_to = req.params.idusers_to; + let banco = req.params.db; + ExecutarQuery(`SELECT idchat, idusers_from, idusers_to, visible, + DATE_FORMAT(time_sent, '%d/%m/%Y %h:%i') AS 'time_sent', + DATE_FORMAT(time_read, '%d/%m/%Y %h:%i') AS 'time_read', + message, quotation FROM chat WHERE + (((idusers_from = ${idusers_from} AND idusers_to = ${idusers_to}) OR + (idusers_to = ${idusers_from} AND idusers_from = ${idusers_to})) AND banco = '${banco}');`, res, req.originalUrl); + }); + + router.post('/sendMessage', verifyJWT, (req, res) => { + const idusers_from = req.body.idusers_from; + const idusers_to = req.body.idusers_to; + const message = req.body.message; + const banco = req.body.banco; + const quotation = req.body.quotation; + ExecutarQuery(`INSERT INTO chat(idusers_from, idusers_to, message, banco, quotation) + VALUES (?, ?, ?, ?, ?);`, res, req.originalUrl, [idusers_from, idusers_to, message, banco, quotation]); + }); + + router.get('/setReaded/:idchat', verifyJWT, (req, res) => { + let idchat = req.params.idchat; + ExecutarQuery(`UPDATE chat SET + time_read = now() + WHERE idchat = ${idchat};`, res, req.originalUrl); + }); + + router.get('/removeMessage/:idchat', verifyJWT, (req, res) => { + let idchat = req.params.idchat; + ExecutarQuery(`UPDATE chat SET + visible = 0 + WHERE idchat = ${idchat};`, res, req.originalUrl); + }); + + router.get('/getAllchats/:tipo/:idusers/:db', verifyJWT, (req, res) => { + let tipo = req.params.tipo; + let idusers = req.params.idusers; + let db = req.params.db; + let sqlQuery = ``; + + if (tipo == 1) { // PROFESSOR + sqlQuery = `select *, + ( + select C.NomeVersao + from ${db}Cursos C + where C.Codigo = ( + select top(1) TT.IDCurso + from ${db}TreinandosTurmas TT + where TT.IDMatricula = R.idusers_para + ) + ) AS 'nomeCurso' + from ( + SELECT DISTINCT TT.IDMatricula AS 'idusers_para', + CLI.Nome AS 'nomePara', + F.IDFuncionario AS 'idusers_de', + F.Nome AS 'nomeDe' + from ${db}TreinandosTurmas TT + inner join ${db}TurmasAgendaCalendario TAC + on TAC.IdTurma = TT.CodigoTurma + inner join ${db}Funcionarios F + on F.IDFuncionario = TAC.IdInstrutor + inner join ${db}Clientes CLI + on CLI.IDCliente = TT.IDTreinando + /*WHERE TAC.IdInstrutor = ${idusers}*/ + ) R`; + } + else if (tipo == 2) { // TODOS OS USUARIOS + sqlQuery = `select F.IDFuncionario AS 'idusers_para', F.Nome AS 'nomePara', 0 as Tipo + from ${db}Funcionarios F + where F.Desativado = 0 + union all + select distinct M.IDMatricula AS 'idusers_para', C.Nome AS 'nomePara', 1 as Tipo + from ${db}Matriculas M + inner join ${db}TreinandosTurmas TT + on TT.IDMatricula = M.IDMatricula + inner join ${db}Clientes C + on C.IDCliente = TT.IDTreinando;`; + } + else if (tipo == 4) { // ALUNO + sqlQuery = `/*SELECT TOP 1 TT.IDMatricula AS 'idusers_de', + CLI.Nome AS 'nomeDe', + F.IDFuncionario AS 'idusers_para', + F.Nome AS 'nomePara', + TT.IDCurso AS 'idcourses', + C.NomeVersao AS 'nomeCurso' + from ${db}TreinandosTurmas TT + inner join ${db}Cursos C + on C.Codigo = TT.IDCurso + inner join ${db}TurmasAgendaCalendario TAC + on TAC.IdTurma = TT.CodigoTurma + inner join ${db}Funcionarios F + on F.IDFuncionario = TAC.IdInstrutor + inner join ${db}Clientes CLI + on CLI.IDCliente = TT.IDTreinando + WHERE TT.IDMatricula = ${idusers} ORDER BY TT.IDCurso DESC;*/ + select F.IDFuncionario AS 'idusers_para', F.Nome AS 'nomePara', 0 as Tipo + from ${db}Funcionarios F + where F.Desativado = 0;`; + } + execSQLQuery2(sqlQuery, res, req.originalUrl); + }) + + router.post('/createGroup', verifyJWT, (req, res) => { + const name = req.body.name; + const created_by = req.body.created_by; + const banco = req.body.banco; + ExecutarQuery(`INSERT INTO chatgroups(name, created_by, banco) + VALUES (?, ?, ?);`, res, req.originalUrl, [name, created_by, banco]); + }); + + router.post('/insertMember', verifyJWT, (req, res) => { + const idchatgroups = parseInt(req.body.idchatgroups); + const idusers = parseInt(req.body.idusers); + const enabled = req.body.enabled ? 1 : 0; + const isadm = req.body.isadm ? 1 : 0; + const inserted_by = parseInt(req.body.inserted_by); + ExecutarQuery(`INSERT INTO chatusergroups(idchatgroups, idusers, enabled, isadm, inserted_by) + VALUES (${idchatgroups}, ${idusers}, ${enabled}, ${isadm}, ${inserted_by});`, res, req.originalUrl); + }); + + router.get('/getAllGroups/:idusers/:db', verifyJWT, (req, res) => { + let idusers = req.params.idusers; + let banco = req.params.db; + let sqlQuery = `SELECT ${idusers} AS idusers_de, '' AS nomeDe, cu.idchatgroups AS idusers_para, + cg.name AS nomePara, 'Grupo' AS nomeCurso, 0 AS idcourses, cu.isadm + FROM chatusergroups cu + INNER JOIN chatgroups cg + ON cg.idchatgroups = cu.idchatgroups + WHERE cu.idusers = ${idusers} AND cg.banco = "${banco}";`; + ExecutarQuery(sqlQuery, res, req.originalUrl); + }); + + router.get('/getChatGroup/:idchatgroups/:db', verifyJWT, (req, res) => { + let idchatgroups = req.params.idchatgroups; + let banco = req.params.db; + ExecutarQuery(`SELECT idchat, idusers_from, idusers_to, visible, + DATE_FORMAT(time_sent, '%d/%m/%Y %h:%i') AS 'time_sent', + DATE_FORMAT(time_read, '%d/%m/%Y %h:%i') AS 'time_read', + message, quotation FROM chat WHERE idusers_to = ${idchatgroups} AND banco = "${banco}";`, res, req.originalUrl); + }); + + router.get('/getGroupMembers/:idchatgroups', verifyJWT, (req, res) => { + const idchatgroups = parseInt(req.params.idchatgroups); + ExecutarQuery(`SELECT + * + FROM chatusergroups + WHERE idchatgroups = ${idchatgroups};`, res, req.originalUrl); + }); + + router.get('/removeMember/:idchatusergroups', verifyJWT, (req, res) => { + const idchatusergroups = parseInt(req.params.idchatusergroups); + ExecutarQuery(`DELETE FROM chatusergroups + WHERE idchatusergroups = ${idchatusergroups};`, res, req.originalUrl); + }); + + router.get('/updateGroupname/:idchatgroups/:name', verifyJWT, (req, res) => { + const idchatgroups = parseInt(req.params.idchatgroups); + const name = req.params.name; + ExecutarQuery(`UPDATE chatgroups SET + name = ? + WHERE idchatgroups = ?;`, res, req.originalUrl, [name, idchatgroups]); + }); + + router.get('/deleteGroup/:idchatgroups', verifyJWT, (req, res) => { + let idchatgroups = req.params.idchatgroups; + mysqlConnection.query(`DELETE FROM chatusergroups WHERE idchatgroups = ${idchatgroups};`, function (error, results, fields) { + console.log(error); + console.log(results); + ExecutarQuery(`DELETE FROM chatgroups WHERE idchatgroups = ${idchatgroups};`, res, req.originalUrl); + }); + }); + + router.get('/getAllchatsViewer/:db', verifyJWT, (req, res) => { + let db = req.params.db; + let sqlQuery = `SELECT DISTINCT + R.idusers_from, R.idusers_to, R.banco, + (SELECT c1.message FROM chat c1 WHERE c1.idusers_from = R.idusers_from AND c1.idusers_to = R.idusers_to ORDER BY c1.time_sent DESC LIMIT 1) AS 'message', + (SELECT date_format(c1.time_sent, '%d/%m/%Y %h:%i') FROM chat c1 WHERE c1.idusers_from = R.idusers_from AND c1.idusers_to = R.idusers_to ORDER BY c1.time_sent ASC LIMIT 1) AS 'time_begin', + (SELECT date_format(c1.time_sent, '%d/%m/%Y %h:%i') FROM chat c1 WHERE c1.idusers_from = R.idusers_from AND c1.idusers_to = R.idusers_to ORDER BY c1.time_sent DESC LIMIT 1) AS 'time_last', + (SELECT COUNT(*) FROM chat c1 WHERE c1.idusers_from = R.idusers_from AND c1.idusers_to = R.idusers_to ORDER BY c1.time_sent DESC LIMIT 1) AS 'amout', + case when R.idusers_to < 1250 then (select cg.name from chatgroups cg where cg.idchatgroups = R.idusers_to) else null end as 'group' + FROM + (select distinct * from ( + select c1.idusers_from, c1.idusers_to, c1.banco from chat c1 + union all + select c1.idusers_from as 'idusers_to', c1.idusers_to as 'idusers_from', c1.banco from chat c1) R + WHERE R.idusers_from >= 1250 and R.idusers_from < 190000 and R.banco = '${db}' + order by R.idusers_to, R.idusers_from ASC) R + ORDER BY time_last DESC;`; + ExecutarQuery(sqlQuery, res, req.originalUrl); + }) + + return router; +}; + +module.exports = routes; + +function ExecutarQuery(sqlQuery, res, url, Parametros = null) { + connection.query(sqlQuery, Parametros, (error, results) => { + if (!error) { + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": results + })); + console.log(url + " success 200"); + } + else { + res.send(JSON.stringify({ + "status": 500, + "error": error, + "response": results + })); + console.log(url + " error 500"); + } + }) +} \ No newline at end of file diff --git a/controllers/chattimeController.js b/controllers/chattimeController.js new file mode 100644 index 0000000..20e94aa --- /dev/null +++ b/controllers/chattimeController.js @@ -0,0 +1,3360 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const formidable = require('formidable'); +const express = require('express'); +const router = express.Router(); +const crypto = require('crypto'); +//const { uploadFileToBucket, getFileStream, deleteFileStream } = require('../s3'); +var { spawn } = require('child_process'); +let bodyParser = require('body-parser'); +router.use( + bodyParser.json({ + verify: function getRawBody(req, res, buf) { + req.rawBody = buf.toString(); + }, + }) +); + +//Payed +const watsonIMBKey = 'ihcWQ89rxCAKDQgyXh7wU4bI_9R2zxjBmcevXA1_x3t1'; +const watsonURLService = + 'https://api.us-south.text-to-speech.watson.cloud.ibm.com/instances/96918c09-fa7d-495f-9413-646e624e46b6'; + +//Free +//const watsonIMBKey = "EJtHH83IMSkHk64oDmrVbwwk_RPnrOu0vgbWJ-O7k5kR"; +//const watsonURLService = "https://api.us-south.text-to-speech.watson.cloud.ibm.com/instances/aa14db78-af38-45ae-9c94-1f226ef325c1"; + +const STTWatsonKey = 'psg1n6enCs0R5MHuEOkCKoCUKOeLFSgBk00eDl0s8T9n'; +const STTWatsonService = + 'https://api.us-south.speech-to-text.watson.cloud.ibm.com/instances/6cdb8798-77e4-4e5d-bcc9-b03ce151ee55'; + +var routes = function () { + //#region CHATTIME + router.get('/getAllChattime', verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + * + from zoechattime;`, + res, + req.originalUrl + ); + }); + + router.get('/getChattime/:idzoechattime', verifyJWT, (req, res) => { + const idzoechattime = parseInt(req.params.idzoechattime); + execSQLQuery( + `SELECT + * + from zoechattime + where idzoechattime = ${idzoechattime};`, + res, + req.originalUrl + ); + }); + + router.post('/insertChattime', verifyJWT, (req, res) => { + const idzoechattime = parseInt(req.body.idzoechattime); + const description = req.body.description; + execSQLQuery( + `INSERT INTO zoechattime (description) + VALUES (?);`, + res, + req.originalUrl, + [description] + ); + }); + + router.patch('/updateChattime', verifyJWT, (req, res) => { + const idzoechattime = parseInt(req.body.idzoechattime); + const description = req.body.description; + execSQLQuery( + `UPDATE zoechattime SET + description = ? + WHERE idzoechattime = ?;`, + res, + req.originalUrl, + [description, idzoechattime] + ); + }); + + router.delete('/deleteChattime/:idzoechattime', verifyJWT, (req, res) => { + const idzoechattime = parseInt(req.params.idzoechattime); + execSQLQuery( + `delete from zoechattime + where idzoechattime = ${idzoechattime};`, + res, + req.originalUrl + ); + }); + + //#endregion + + //#region CHATTIME DIALOG + router.get('/getChattimedialog/:idzoechattime', verifyJWT, (req, res) => { + const idzoechattime = parseInt(req.params.idzoechattime); + execSQLQuery( + `SELECT + * + from zoechattimedialog + where idzoechattime = ${idzoechattime};`, + res, + req.originalUrl + ); + }); + + router.post('/insertChattimedialog', verifyJWT, (req, res) => { + const idzoechattimedialog = parseInt(req.body.idzoechattimedialog); + const idzoechattime = parseInt(req.body.idzoechattime); + const zoetalking = req.body.zoetalking; + const speed = req.body.speed; + const phrase = req.body.phrase; + const ordem = parseInt(req.body.ordem); + const percent = parseInt(req.body.percent); + const english = req.body.english ? 1 : 0; + const sub = parseInt(req.body.sub); + const seq = parseInt(req.body.seq); + const seq_dir = parseInt(req.body.seq_dir); + const explanation = req.body.explanation; + const ex_english = req.body.ex_english ? 1 : 0; + const img = req.body.img; + const idzoevoices = req.body.idzoevoices; + const idzoevoices_ex = req.body.idzoevoices_ex; + execSQLQuery( + `INSERT INTO zoechattimedialog (idzoechattime, zoetalking, speed, phrase, ordem, percent, english, sub, seq, seq_dir, explanation, ex_english, img, idzoevoices, idzoevoices_ex) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`, + res, + req.originalUrl, + [ + idzoechattime, + zoetalking, + speed, + phrase, + ordem, + percent, + english, + sub, + seq, + seq_dir, + explanation, + ex_english, + img, + idzoevoices, + idzoevoices_ex, + ] + ); + }); + router.delete( + '/deleteChattimedialog/:idzoechattime', + verifyJWT, + (req, res) => { + const idzoechattime = parseInt(req.params.idzoechattime); + execSQLQuery( + `delete from zoechattimedialog + where idzoechattime = ${idzoechattime};`, + res, + req.originalUrl + ); + } + ); + + router.get('/getZoeVoices', verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + * + from zoevoices + where disabled = 0;`, + res, + req.originalUrl + ); + }); + + //#endregion + + //#region CHATTIME SENTENCES + router.get( + '/getChattimesentences/:idzoechattimedialog', + verifyJWT, + (req, res) => { + const idzoechattimedialog = parseInt(req.params.idzoechattimedialog); + execSQLQuery( + `SELECT + * + from zoechattimesentences + where idzoechattimedialog = ${idzoechattimedialog};`, + res, + req.originalUrl + ); + } + ); + + router.post('/insertChattimesentences', verifyJWT, (req, res) => { + const idzoechattimesentences = parseInt(req.body.idzoechattimesentences); + const idzoechattimedialog = parseInt(req.body.idzoechattimedialog); + const sentence = req.body.sentence; + const seq_dir = parseInt(req.body.seq_dir); + const ordem_dir = parseInt(req.body.ordem_dir); + const ex_answer = req.body.ex_answer ? 1 : 0; + execSQLQuery( + `INSERT INTO zoechattimesentences (idzoechattimedialog, sentence, seq_dir, ordem_dir, ex_answer) + VALUES (?, ?, ?, ?, ?);`, + res, + req.originalUrl, + [idzoechattimedialog, sentence, seq_dir, ordem_dir, ex_answer] + ); + }); + + router.delete( + '/deleteChattimesentences/:idzoechattime', + verifyJWT, + (req, res) => { + const idzoechattime = parseInt(req.params.idzoechattime); + execSQLQuery( + `delete from zoechattimesentences + where idzoechattimedialog in (select idzoechattimedialog from zoechattimedialog where idzoechattime = ${idzoechattime});`, + res, + req.originalUrl + ); + } + ); + + //#endregion + + //#region TRATAMENTO CHAT BOT + + router.get('/getAllTratamentoChatBot', verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + tf.*, + cb.description as 'NameChatBot' + from zoetratamentofrases tf + inner join ChatBot cb on cb.ChatBot = tf.ChatBot;`, + res, + req.originalUrl + ); + }); + + router.post('/insertTratamentoChatBot', verifyJWT, (req, res) => { + const ChatBot = parseInt(req.body.ChatBot); + const frase = req.body.frase; + const trocada = req.body.trocada; + const habilitado = req.body.habilitado ? 1 : 0; + execSQLQuery( + `INSERT INTO zoetratamentofrases (ChatBot, frase, trocada, habilitado) + VALUES (?, ?, ?, ?);`, + res, + req.originalUrl, + [ChatBot, frase, trocada, habilitado] + ); + }); + + router.patch('/updateTratamentoChatBot', verifyJWT, (req, res) => { + const idzoetratamentofrases = parseInt(req.body.idzoetratamentofrases); + const ChatBot = parseInt(req.body.ChatBot); + const frase = req.body.frase; + const trocada = req.body.trocada; + const habilitado = req.body.habilitado ? 1 : 0; + execSQLQuery( + `UPDATE zoetratamentofrases SET + ChatBot = ?, + frase = ?, + trocada = ?, + habilitado = ? + WHERE idzoetratamentofrases = ?;`, + res, + req.originalUrl, + [ChatBot, frase, trocada, habilitado, idzoetratamentofrases] + ); + }); + + router.delete( + '/deleteTratamentoChatBot/:idzoetratamentofrases', + verifyJWT, + (req, res) => { + const idzoetratamentofrases = parseInt(req.params.idzoetratamentofrases); + execSQLQuery( + `delete from zoetratamentofrases + WHERE idzoetratamentofrases = ?;`, + res, + req.originalUrl, + [idzoetratamentofrases] + ); + } + ); + + //#endregion + + // #region Requisição do robô + + // COMANDOS + const ComandoRepetirFrase = 'repeat'; + const ComandoOpenConfigMode = 'open config mode'; + const ComandoCloseConfigMode = 'close config mode'; + const ComandoOpenRepeatMode = 'open repeat mode'; + const ComandoCloseRepeatMode = 'close repeat mode'; + const ComandoAjuda = 'explain'; + + const FraseFinal = 'Very good'; + const FraseExemploConfig = 'Try saying, change my name to new name'; + const FraseMudarVariavel = 'change my '; + const FraseDizerVariavel = 'say my '; + const FraseEnterSetupMode = 'Config mode has been inited. What can I do?'; + const FraseExitSetupMode = 'Config mode has been closed.'; + const FraseEnterRepeatMode = + "Repeat after me mode has been inited. Say ' " + + ComandoCloseRepeatMode + + "' to exit"; + const FraseServerDown = + 'Ops, server down. Wait a moment and try again please'; + const FraseExitRepeatMode = 'Repeat after me mode has been closed.'; + const FraseComandoIndisponivel = 'Command unavailable while in classes'; + // DAODS PADRAO + const VelocidadePadrao = 0.75; + const CoerenciaPadrao = 60; + const Separador = '<-->'; + const MatriculasTalkFlow = []; + + var IdiomaZoe = ""; + var experienciaUnilever = false; + const VozesUnilever = { + En: "Matthew", + Pt: "Ricardo", + Es: "Enrique" + } + + + function setIdiomaZoe(idclasses, idusers, callback) { + mysqlConnection.query( + `select + case + when co.idlanguage = 0 then 'en-US' + when co.idlanguage = 1 then 'pt-BR' + when co.idlanguage = 2 then 'es-ES' + when co.idlanguage = 3 then 'en-US' + end as courseLanguage, + co.idtypescourse + from courses co + where co.idcourses = (select cl.idcourses from classes cl where cl.idclasses = ${idclasses})`, + function (error, results, fields) { + if (!error && results.length > 0) { + experienciaUnilever = results[0]['idtypescourse'] == 8; + callback(results[0]['courseLanguage']); + } else { + mysqlConnection.query( + `select + case + when co.idlanguage = 0 then 'en-US' + when co.idlanguage = 1 then 'pt-BR' + when co.idlanguage = 2 then 'es-ES' + when co.idlanguage = 3 then 'en-US' + end as courseLanguage, + co.idtypescourse + from users us + inner join studentCourses sc on sc.idusers = us.user + inner join courses co on co.idcourses = sc.idcourses + where us.user = '${idusers}';`, function (err, res, fld) { + if (!err && res.length > 0) { + experienciaUnilever = res[0]['idtypescourse'] == 8; + callback(res[0]['courseLanguage']); + } + else { + experienciaUnilever = false; + callback("en-US"); + } + }); + } + } + ); + } + + function logData(mensagem) { + var data = new Date(); + console.log( + data.getHours() + + ':' + + data.getMinutes() + + ':' + + data.getSeconds() + + '.' + + data.getMilliseconds() + + ' - ' + + mensagem + ); + } + + function MontaSQLChatTime(ChatTimeID, Ordem, Seq) { + return `select R.*, (select ctd.explanation from zoechattimedialog ctd where ctd.idzoechattime = R.idzoechattime and ctd.ordem = R.OrdemAnterior limit 1) as 'Explan' from ( + select + ctd.*, + (select ctd2.phrase end from zoechattimedialog ctd2 where ctd2.idzoechattime = ctd.idzoechattime and ctd2.seq = ctd.seq_dir and ctd2.ordem = ctd.ordem + 1 limit 1) as 'ExemploResposta', + (select ctd2.phrase end from zoechattimedialog ctd2 where ctd2.idzoechattime = ctd.idzoechattime and ctd2.seq = ctd.seq_dir and ctd2.ordem = ctd.ordem + 2 limit 1) as 'ExemploResposta2', + (select ctd2.phrase end from zoechattimedialog ctd2 where ctd2.idzoechattime = ctd.idzoechattime and ctd2.seq = ctd.seq_dir and ctd2.ordem = (select ctd3.ordem from zoechattimedialog ctd3 where ctd3.idzoechattime = ctd.idzoechattime and ctd3.ordem < ctd.ordem and ctd3.zoetalking = 1 order by ctd3.ordem desc limit 1) limit 1) as 'PerguntaAnterior', + (select ctd3.ordem from zoechattimedialog ctd3 where ctd3.idzoechattime = ctd.idzoechattime and ctd3.seq = ctd.seq_dir and ctd3.ordem > ctd.ordem /*and ctd3.zoetalking = 0*/ order by ctd3.ordem asc limit 1) as 'ProximaOrdem', + (select ctd3.ordem from zoechattimedialog ctd3 where ctd3.idzoechattime = ctd.idzoechattime and ctd3.seq = ctd.seq_dir and ctd3.ordem < ctd.ordem /*and ctd3.zoetalking = 1*/ order by ctd3.ordem desc limit 1) as 'OrdemAnterior', + (select case when count(*) = 1 then 0 else 1 end from zoechattimedialog ctd3 where ctd3.idzoechattime = ctd.idzoechattime and ctd3.seq = ctd.seq_dir and ctd3.ordem = ctd.ordem + 1) as 'Final', + (select ctd4.zoetalking from zoechattimedialog ctd4 where ctd4.idzoechattime = ctd.idzoechattime and ctd4.seq = ctd.seq_dir and ctd4.ordem > ctd.ordem order by ctd4.ordem asc limit 1) as 'ProximoZoeTalking' + from zoechattimedialog ctd + where ctd.idzoechattime = ${ChatTimeID} and ctd.ordem = ${Ordem} and ctd.seq = ${Seq}) R;`; + } + + function EscolheFraseNaoEntendeu() { + const FrasesNaoEntendeuEn = [ + 'Sorry, repeat please', + "I didn't get that, repeat please", + "I didn't catch that, repeat please", + 'Sorry, say again', + "I don't understand you", + ]; + const FrasesNaoEntendeuPt = [ + 'Desculpe, repita por favor', + 'Não entendi, repita por favor', + 'Não captei, repita por favor', + 'Desculpe, pode repetir?', + 'Eu não entendo você', + ]; + const FrasesNaoEntendeuEs = [ + 'Lo siento, repite por favor', + 'No entendí eso, repite por favor', + 'No capté eso, repite por favor', + 'Lo siento, ¿puedes repetir?', + 'No te entiendo', + ]; + let FrasesNaoEntendeu = + IdiomaZoe == "pt-BR" ? FrasesNaoEntendeuPt : + IdiomaZoe == "en-US" ? FrasesNaoEntendeuEn : + IdiomaZoe == "es-ES" ? FrasesNaoEntendeuEs : + FrasesNaoEntendeuEn; + + const i = Math.floor(Math.random() * FrasesNaoEntendeu.length - 1) + 1; + return FrasesNaoEntendeu[i]; + } + + // Função para gerar um token alfanumérico de 10 caracteres + function generateToken() { + const randomBuffer = crypto.randomBytes(5); + let token = ''; + for (let i = 0; i < randomBuffer.length; i++) { + token += ('0' + randomBuffer[i]).slice(-2); // Garantir que tenha dois dígitos por byte + } + return token.slice(0, 10); // Garantir que o token tenha exatamente 10 dígitos + } + + // Estrutura para armazenar dados dos usuários + const userSessions = {}; + const MAX_USAGE_COUNT = 100; + const TOKEN_LIFETIME = 3600 * 1000; // 1 hora em milissegundos + + // Função para obter o token de um usuário ou gerar um novo se necessário + function getUserToken(matricula, idUnidade) { + const userKey = `${matricula}-${idUnidade}`; + + if (!userSessions[userKey]) { + const token = generateToken(); + userSessions[token] = { + userKey, + matricula, + idUnidade, + usageCount: 0, + createdAt: Date.now() + }; + return token; + } else { + // Encontrar a sessão pelo userKey + const token = Object.keys(userSessions).find(key => userSessions[key].userKey === userKey); + const session = userSessions[token]; + const currentTime = Date.now(); + + // Verifica se o token deve ser renovado por uso ou tempo + if (session.usageCount >= MAX_USAGE_COUNT || (currentTime - session.createdAt) > TOKEN_LIFETIME) { + const newToken = generateToken(); + delete userSessions[token]; + userSessions[newToken] = { + userKey, + matricula, + idUnidade, + usageCount: 0, + createdAt: Date.now() + }; + return newToken; + } + return token; + } + } + + // Função para registrar o uso do token + function useToken(token) { + console.log('Token Usado: ' + token); + if (userSessions[token]) { + userSessions[token].usageCount++; + console.log(`Uso do token registrado. Contagem atual: ${userSessions[token].usageCount}`); + } else { + console.log('Token inválido.'); + } + } + + router.post('/recognizeAudio/:token', (req, res) => { + logData('RecognizeAudio, iniciando'); + let token = req.params.token; + if (token != Variables('tk_fixed')) { + res.status(500).send({ status: 'expired' }); + return; + } + // RECEBE DADOS DA REQUISIÇÃO + let form = new formidable.IncomingForm(); + form.maxFileSize = 1024 * 1024 * 1024; + form.on('file', function (name, file) {}); + form.on('error', function (err) {}); + form.on('aborted', function () {}); + form.parse(req, function (err, fields, files) { + var Modo = parseInt(fields.Modo); + var Mensagem = fields.Mensagem || ''; + var Vezes = parseInt(fields.Vezes); + var ChatTimeID = parseInt(fields.ChatTimeID); + var Ordem = parseInt(fields.Ordem); + var Seq = parseInt(fields.Seq); + var Matricula = parseInt(fields.Matricula); + var IDUnidade = parseInt(fields.IDUnidade); + var IDAula = parseInt(fields.IDAula) || 0; + var IDExercicio = parseInt(fields.IDExercicio); + + //IdiomaZoe = MatriculasPtBr.includes(Matricula) ? "pt-BR" : "en-US"; + setIdiomaZoe(IDAula, Matricula, function(idioma) { + IdiomaZoe = idioma; + logData("Idioma do curso: " + IdiomaZoe + " - Unilever: " + experienciaUnilever); + + var CaminhoArquivo = ''; + + try { + CaminhoArquivo = files.Arquivo.path; + } catch (e) { + console.log('Sem audio na entrada'); + } + + // CRIA VARIAVEL COM A DATA ATUAL PARA RENOMEAR O ARQUIVO COM A IDENTIFICACAO DO ALUNO + let date_ob = new Date(); + let DataHoje = + date_ob.getDate() + + '-' + + (date_ob.getMonth() + 1) + + '-' + + date_ob.getFullYear() + + '-' + + date_ob.getHours() + + '-' + + date_ob.getMinutes() + + '-' + + date_ob.getSeconds(); + var NomeArquivo = + Matricula + '_' + IDUnidade + '_' + IDAula + '_' + DataHoje + '.mp3'; + + // CONVERSACAO LIVRE + if (Modo == 0) { + console.log('Conversação Livre'); + + //let SessaoID = Matricula + '' + IDUnidade; + let SessaoID = getUserToken(Matricula, IDUnidade); + + if (Mensagem == '') { + ProcessarAudioEntrada( + CaminhoArquivo, + NomeArquivo, + Modo, + function (Pergunta, Entendeu) { + if (Entendeu) { + let ComandoAluno = VerificaComandoAluno(Pergunta); + if (ComandoAluno == ComandoOpenConfigMode) { + // ENTRANDO NO MODO CONFIGURACAO + EnviaResposta( + true, + FraseEnterSetupMode, + NomeArquivo, + res, + FraseEnterSetupMode, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + 2, + 0, + '' + ); + } else if (ComandoAluno == ComandoOpenRepeatMode) { + // ENTRANDO NO MODO REPETICAO + EnviaResposta( + true, + FraseEnterRepeatMode, + NomeArquivo, + res, + FraseEnterRepeatMode, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + 4, + 0, + '' + ); + } else { + // SEM COMANDOS + EnviaPerguntaChatBot(Pergunta, SessaoID, Matricula, function (Resposta) { + TrataRespostaChatBot(Resposta, function (ResTratada) { + AtualizarEtapa( + false, + Matricula, + IDUnidade, + IDAula, + Ordem, + Pergunta, + Resposta, + '', + 'Sim', + '' + ); + + EnviaResposta( + true, + ResTratada, + NomeArquivo, + res, + ResTratada, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + }); + }); + } + } else { + // NAO ENTENDEU A PERGUNTA + const Frase = EscolheFraseNaoEntendeu(); + EnviaResposta( + true, + Frase, + NomeArquivo, + res, + Frase, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + } + ); + } else { + EnviaPerguntaChatBot(Mensagem, SessaoID, Matricula, function (Resposta) { + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + Resposta, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Mensagem, + 0, + 1, + 0, + 1, + 1, + Modo, + '' + ); + }); + } + } + // CONVERSACAO DIRIGIDA + else if (Modo == 1) { + logData('Conversação Dirigida'); + const SQL = MontaSQLChatTime(ChatTimeID, Ordem, Seq); + mysqlConnection.query(SQL, function (error, ChatTimeDialog, fields) { + if (!error && ChatTimeDialog && ChatTimeDialog.length > 0) { + logData('Consulta realizada'); + // FRASE QUE QUEM FALA E A ZOE, LOGO, NAO PROCESSA AUDIO DE ENTRADA + if (ChatTimeDialog[0]['zoetalking'] == 1) { + Ordem = ChatTimeDialog[0]['ProximaOrdem']; + VerificaVariaveisFrase( + ChatTimeDialog[0]['idzoechattimedialog'], + ChatTimeDialog[0]['phrase'], + ChatTimeDialog[0]['phrase'], + Matricula, + IDUnidade, + false, + function (FraseSubstituida) { + logData('Variáveis trocadas'); + //console.log(ChatTimeDialog[0]['img']); + EnviaResposta( + true, + FraseSubstituida, + NomeArquivo, + res, + RemoveVariaveisFrase(ChatTimeDialog[0]['ExemploResposta']), + 0, + ChatTimeDialog[0]['Final'], + 100, + 1, + ChatTimeDialog[0]['speed'], + ChatTimeDialog[0]['phrase'], + Ordem, + ChatTimeDialog[0]['zoetalking'], + ChatTimeDialog[0]['ProximoZoeTalking'], + ChatTimeDialog[0]['idzoevoices'], + ChatTimeDialog[0]['sub'], + Modo, + ChatTimeDialog[0]['seq_dir'], + ChatTimeDialog[0]['img'] + ); + } + ); + } else { + // FRASE QUE QUEM FALA E O ALUNO, LOGO, PROCESSA AUDIO DE ENTRADA + logData('Processar audio de entrada'); + ProcessarAudioEntrada( + CaminhoArquivo, + NomeArquivo, + Modo, + function (TextoAluno, Entendeu) { + logData('Audio processado'); + //console.log(TextoAluno); + + // VERIFICA SE O ALUNO ESTA DANDO ALGUM COMANDO DE SISTEMA + let ComandoAluno = VerificaComandoAluno(TextoAluno); + logData('Comando verificado: ' + ComandoAluno); + if (Entendeu && ComandoAluno != '') { + if (ComandoAluno == ComandoRepetirFrase) { + // SE O ALUNO ESTIVER PEDINDO PRA ZOE REPETIR A PERGUNTA ANTERIOR + logData('REPETINDO'); + VerificaVariaveisFrase( + ChatTimeDialog[0]['idzoechattimedialog'], + ChatTimeDialog[0]['PerguntaAnterior'], + ChatTimeDialog[0]['PerguntaAnterior'], + Matricula, + IDUnidade, + false, + function (FraseSubstituida) { + logData('Variáveis da frase verificadas'); + EnviaResposta( + true, + 'I said, ' + FraseSubstituida, + NomeArquivo, + res, + ChatTimeDialog[0]['phrase'], + Vezes, + ChatTimeDialog[0]['Final'], + 100, + 1, + ChatTimeDialog[0]['speed'], + ChatTimeDialog[0]['phrase'], + Ordem, + ChatTimeDialog[0]['zoetalking'], + 0, + ChatTimeDialog[0]['idzoevoices'], + ChatTimeDialog[0]['sub'], + Modo, + ChatTimeDialog[0]['seq'], + ChatTimeDialog[0]['img'] + ); + } + ); + } else if (ComandoAluno == ComandoAjuda) { + // SE O ALUNO ESTIVER PEDINDO PRA ZOE AJUDAR COM A FRASE + logData('EXPLICACAO'); + const FraseExplicacao = + ChatTimeDialog[0]['Explan'] == '' || + !ChatTimeDialog[0]['Explan'] + ? 'Try saying ' + ChatTimeDialog[0]['phrase'] + : ChatTimeDialog[0]['Explan']; + const En = + ChatTimeDialog[0]['Explan'] == '' || + !ChatTimeDialog[0]['Explan'] + ? 1 + : ChatTimeDialog[0]['idzoevoices_ex']; + EnviaResposta( + true, + FraseExplicacao, + NomeArquivo, + res, + FraseExplicacao, + Vezes, + 0, + 100, + 1, + ChatTimeDialog[0]['speed'], + TextoAluno, + Ordem, + 1, + 0, + En, + 1, + Modo, + ChatTimeDialog[0]['seq'], + ChatTimeDialog[0]['img'] + ); + } else { + // OUTRO COMANDO QUALQUER + EnviaResposta( + true, + FraseComandoIndisponivel, + NomeArquivo, + res, + FraseComandoIndisponivel, + Vezes, + 0, + 100, + 1, + Velocidade, + TextoAluno, + Ordem, + 1, + 0, + 1, + 1, + Modo, + Seq, + '' + ); + } + } else if (!Entendeu) { + logData('NAO ENTENDEU'); + Vezes++; + + let Resposta = EscolheFraseNaoEntendeu(); + + AtualizarEtapa( + false, + Matricula, + IDUnidade, + IDAula, + Ordem, + TextoAluno, + Resposta, + ChatTimeDialog[0]['phrase'], + 'Não', + 'actualItem' + ); + + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + RemoveVariaveisFrase(ChatTimeDialog[0]['phrase']), + Vezes, + ChatTimeDialog[0]['Final'], + 0, + 0, + ChatTimeDialog[0]['speed'], + TextoAluno, + Ordem, + ChatTimeDialog[0]['zoetalking'], + 0, + ChatTimeDialog[0]['idzoevoices'], + ChatTimeDialog[0]['sub'], + Modo, + ChatTimeDialog[0]['seq'], + ChatTimeDialog[0]['img'] + ); + } + // SE O ALUNO ESTIVER RESPONDENDO A PERGUNTA ANTERIOR + else { + logData('PROCESSANDO'); + mysqlConnection.query( + `select sentence, seq_dir from zoechattimesentences where idzoechattimedialog in (select distinct idzoechattimedialog from zoechattimedialog where idzoechattime = ${ChatTimeID} and ordem = ${Ordem});`, + function (error, Sentencas, fields) { + logData('Consulta de sentenças realizada'); + VerificaPronunciaUsuario( + Sentencas, + TextoAluno, + ChatTimeDialog[0]['percent'], + function (Porcentagem, Seq_Dir) { + logData('Pronúncia verificada'); + let Resposta = ''; + let ExResposta = ''; + let Validou = 0; + let Final = 0; + if (Porcentagem >= ChatTimeDialog[0]['percent']) { + // REQUISITAR A PROXIMA FRASE + const SQL = MontaSQLChatTime( + ChatTimeID, + ChatTimeDialog[0]['ProximaOrdem'], + Seq_Dir + ); + mysqlConnection.query( + SQL, + function (error, ChatTimeDialogRes, fields) { + logData( + 'Consulta da próxima frase realizada' + ); + Ordem = ChatTimeDialogRes[0]['ProximaOrdem']; + Final = ChatTimeDialogRes[0]['Final']; + Resposta = ChatTimeDialogRes[0]['phrase']; + ExResposta = RemoveVariaveisFrase( + ChatTimeDialogRes[0]['ExemploResposta'] + ); + Seq_Dir = ChatTimeDialogRes[0]['seq_dir']; + Vezes = 0; + Validou = 1; + + AtualizarEtapa( + true, + Matricula, + IDUnidade, + IDAula, + Ordem, + TextoAluno, + Resposta, + ExResposta, + 'Sim', + 'actualItem' + ); + + VerificaVariaveisFrase( + ChatTimeDialog[0]['idzoechattimedialog'], + TextoAluno, + ChatTimeDialog[0]['phrase'], + Matricula, + IDUnidade, + true, + function (FraseSubstituidaAluno) { + VerificaVariaveisFrase( + ChatTimeDialog[0][ + 'idzoechattimedialog' + ], + TextoAluno, + Resposta, + Matricula, + IDUnidade, + false, + function (FraseSubstituidaZoe) { + EnviaResposta( + Resposta == null ? false : true, + FraseSubstituidaZoe, + NomeArquivo, + res, + ExResposta, + Vezes, + Final, + Porcentagem, + Validou, + VelocidadePadrao, + TextoAluno, + Ordem, + ChatTimeDialogRes[0]['zoetalking'], + ChatTimeDialogRes[0][ + 'ProximoZoeTalking' + ], + ChatTimeDialogRes[0]['idzoevoices'], + ChatTimeDialogRes[0]['sub'], + Modo, + Seq_Dir, + ChatTimeDialogRes[0]['img'] + ); + } + ); + } + ); + } + ); + } else { + logData( + 'Não atingiu a porcentagem mínima: ' + + Porcentagem + + ' de ' + + ChatTimeDialog[0]['percent'] + ); + Resposta = EscolheFraseNaoEntendeu(); + ExResposta = RemoveVariaveisFrase( + ChatTimeDialog[0]['phrase'] + ); + Vezes++; + Validou = 0; + Final = 0; + + AtualizarEtapa( + false, + Matricula, + IDUnidade, + IDAula, + Ordem, + TextoAluno, + Resposta, + ExResposta, + 'Não', + 'actualItem' + ); + + EnviaResposta( + Resposta == null ? false : true, + Resposta, + NomeArquivo, + res, + ExResposta, + Vezes, + Final, + Porcentagem, + Validou, + VelocidadePadrao, + TextoAluno, + Ordem, + ChatTimeDialog[0]['zoetalking'], + 0, + ChatTimeDialog[0]['idzoevoices'], + ChatTimeDialog[0]['sub'], + Modo, + ChatTimeDialog[0]['seq'], + ChatTimeDialog[0]['img'] + ); + } + } + ); + } + ); + } + } + ); + } + } else { + console.log('Erro ao requisitar ChatTime'); + console.log(error); + console.log('Consulta:'); + console.log(SQL); + EnviaResposta( + true, + FraseServerDown, + NomeArquivo, + res, + '', + Vezes, + 0, + 0, + 0, + VelocidadePadrao, + '', + Ordem, + 1, + 1, + 1, + 1, + Modo, + Seq, + '' + ); + } + }); + } + // MODO CONFIGURACAO + else if (Modo == 2) { + console.log('Modo Configuração'); + ProcessarAudioEntrada( + CaminhoArquivo, + NomeArquivo, + Modo, + function (Pergunta, Entendeu) { + if (Entendeu) { + let ComandoAluno = VerificaComandoAluno(Pergunta); + if (ComandoAluno == ComandoCloseConfigMode) { + // SAINDO DO MODO CONFIGURACAO + EnviaResposta( + true, + FraseExitSetupMode, + NomeArquivo, + res, + FraseExitSetupMode, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + '' + ); + } else { + // SEM COMANDOS DO ALUNO + ModoConfiguracao( + Pergunta, + NomeArquivo, + res, + Matricula, + IDUnidade + ); + } + } else { + EnviaResposta( + true, + EscolheFraseNaoEntendeu(), + NomeArquivo, + res, + FraseExemploConfig, + 0, + 0, + 0, + 0, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 0, + Modo, + 0, + '' + ); + } + } + ); + } + // MODO EXERCICIO DE PRONUNCIA + else if (Modo == 3) { + console.log('Exercício de Pronúncia'); + // SEM ARQUIVO DE AUDIO, LOGO, A ZOE IRA PRONUNCIAR A PERGUNTA + const SQL = `select + ex.description, + eq.* + from exercisequestions eq + inner join exercises ex on ex.idexercises = eq.idexercises + where ex.idexercises = ${IDExercicio};`; + mysqlConnection.query(SQL, function (error, Questoes, fields) { + if (!error && Questoes && Questoes.length > 0) { + if (Ordem > Questoes.length - 1 || Ordem < 0) { + console.log(SQL); + console.log('Ordem: ' + Ordem); + console.log('Questoes: ' + Questoes.length); + EnviaResposta( + true, + 'Trying again', + NomeArquivo, + res, + '', + 0, + 0, + 0, + 0, + VelocidadePadrao, + '', + 0, + 1, + 1, + 1, + 1, + Modo, + 0, + '' + ); + return; + } + let Enunciado = Questoes[Ordem]['description']; + let Velocidade = + Questoes[Ordem]['content'].split(Separador)[1] || + VelocidadePadrao; + let Coerencia = + Questoes[Ordem]['content'].split(Separador)[2] || CoerenciaPadrao; + let ExResposta = Questoes[Ordem]['content'].split(Separador)[0]; + let Pergunta = + (Ordem == 0 && Vezes == 0 ? Enunciado + '. ' : '') + ExResposta; + if (CaminhoArquivo == '' || Mensagem != '') { + // SEM ARQUIVO DE AUDIO, LOGO, A ZOE IRA PRONUNCIAR O EXERCICIO + EnviaResposta( + true, + Pergunta, + NomeArquivo, + res, + ExResposta, + 0, + 0, + Coerencia, + 1, + Velocidade, + '', + Ordem, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } else { + // COM ARQUIVO DE AUDIO, LOGO, A ZOE IRA PROCESSAR O AUDIO DO ALUNO + ProcessarAudioEntrada( + CaminhoArquivo, + NomeArquivo, + Modo, + function (TextoAluno, Entendeu) { + // VERIFICA SE O ALUNO ESTA DANDO ALGUM COMANDO DE SISTEMA + let ComandoAluno = VerificaComandoAluno(TextoAluno); + if (Entendeu && ComandoAluno != '') { + if (ComandoAluno == ComandoRepetirFrase) { + // SE O ALUNO ESTIVER PEDINDO PRA ZOE REPETIR A PERGUNTA ANTERIOR + console.log('REPETINDO'); + EnviaResposta( + true, + 'I said, ' + Pergunta, + NomeArquivo, + res, + Pergunta, + Vezes, + 0, + 100, + 1, + Velocidade, + TextoAluno, + Ordem, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } else { + // OUTRO COMANDO QUALQUER + EnviaResposta( + true, + FraseComandoIndisponivel, + NomeArquivo, + res, + FraseComandoIndisponivel, + Vezes, + 0, + 100, + 1, + Velocidade, + TextoAluno, + Ordem, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + } else { + let Frase = { sentence: ExResposta, seq_dir: 0 }; + VerificaPronunciaUsuario( + [Frase], + TextoAluno, + Coerencia, + function (Porcentagem) { + let Resposta = ''; + let Validou = 0; + let Final = 0; + let IndexQuestao = Ordem; + if (Entendeu && Porcentagem >= Coerencia) { + Final = Ordem == Questoes.length - 1 ? 1 : 0; + if (Final == 1) Resposta = FraseFinal; + else { + Ordem++; + Resposta = + Questoes[Ordem]['content'].split(Separador)[0]; + ExResposta = + Questoes[Ordem]['content'].split(Separador)[0]; + } + Validou = 1; + Vezes = 0; + } else { + Resposta = "Try again saying: '" + ExResposta + "'"; + Validou = 0; + Final = 0; + Vezes++; + } + if (Entendeu) { + AtualizarEtapa( + true, + Matricula, + IDUnidade, + IDAula, + Ordem, + Pergunta, + Resposta, + ExResposta, + 'Sim', + 'actualAnswer' + ); + mysqlConnection.query( + `insert into exerciseanswers (idexercisequestions, hasmedia, content, iscorrect, orientation) values (?, 0, ?, ?, 0);`, + [ + Questoes[IndexQuestao]['idexercisequestions'], + TextoAluno, + Validou, + ], + function (errAnswer, resAnswer, fieAnswer) { + if (errAnswer) console.log(errAnswer); + let date_answered = + date_ob.getDate() + + '/' + + (date_ob.getMonth() + 1) + + '/' + + date_ob.getFullYear(); + mysqlConnection.query( + `select idusergivenanswers from usergivenanswers order by idusergivenanswers desc limit 1;`, + function (errUG, resUG, fieUG) { + mysqlConnection.query( + `insert into usergivenanswers (idusergivenanswers, idusers, idexerciseanswers, date_answered, fixed, idclasses, idunits) values (?, ?, ?, ?, 1, ?, ?);`, + [ + resUG[0]['idusergivenanswers'], + Matricula, + resAnswer['insertId'], + date_answered, + IDAula, + IDUnidade, + ], + function ( + errUserAnswer, + resUserAnswer, + fieUserAnswer + ) { + if (errUserAnswer) + console.log(errUserAnswer); + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + ExResposta, + Vezes, + Final, + Porcentagem, + Validou, + Velocidade, + TextoAluno, + Ordem, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + ); + } + ); + } + ); + } else { + AtualizarEtapa( + false, + Matricula, + IDUnidade, + IDAula, + Ordem, + Pergunta, + Resposta, + ExResposta, + 'Não', + 'actualAnswer' + ); + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + ExResposta, + Vezes, + Final, + Porcentagem, + Validou, + Velocidade, + TextoAluno, + Ordem, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + } + ); + } + } + ); + } + } else { + console.log('Erro ao requisitar Exercicio de Pronuncia'); + console.log(error); + console.log('Consulta:'); + console.log(SQL); + EnviaResposta( + true, + FraseServerDown, + NomeArquivo, + res, + '', + Vezes, + 0, + 0, + 0, + VelocidadePadrao, + '', + Ordem, + 1, + 1, + 1, + 1, + Modo, + 0, + '' + ); + } + }); + } + // MODO DE REPETICAO + else if (Modo == 4) { + console.log('MODO DE REPETICAO'); + ProcessarAudioEntrada( + CaminhoArquivo, + NomeArquivo, + Modo, + function (Pergunta, Entendeu) { + if (Entendeu) { + let ComandoAluno = VerificaComandoAluno(Pergunta); + if (ComandoAluno == ComandoCloseRepeatMode) { + // SAINDO DO MODO REPETICAO + EnviaResposta( + true, + FraseExitRepeatMode, + NomeArquivo, + res, + FraseExitRepeatMode, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + '' + ); + } else { + // SEM COMANDOS + EnviaResposta( + true, + Pergunta, + NomeArquivo, + res, + Pergunta, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + } else { + // NAO ENTENDEU A PERGUNTA + const Frase = EscolheFraseNaoEntendeu(); + EnviaResposta( + true, + Frase, + NomeArquivo, + res, + Frase, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + } + ); + } + }); + }); + + + }); + + function AtualizarEtapa( + AtualizaBanco, + idusers, + idunits, + idclasses, + ordem, + Entendeu, + Resposta, + ExResposta, + Validou, + Campo + ) { + if (AtualizaBanco) { + logData('Atualizando etapa'); + mysqlConnection.query( + `update stepclass set ${Campo} = ${ordem} where idusers = ${idusers} and idunits = ${idunits} and idclasses = ${idclasses};`, + function (error, results, fields) { + if (!error) { + logData( + `Etapa atualizada com sucesso - Matrícula: ${idusers}, Unidade: ${idunits}, Aula: ${idclasses}` + ); + } else { + logData( + `Erro ao atualizar etapa - Matrícula: ${idusers}, Unidade: ${idunits}, Aula: ${idclasses}` + ); + } + logData( + `Validou: "${Validou}", Zoe Entendeu: "${Entendeu}", Resposta Zoe: "${Resposta}", Exemplo Resposta: "${ExResposta}"` + ); + } + ); + } else { + logData( + `Validou: "${Validou}", Zoe Entendeu: "${Entendeu}", Resposta Zoe: "${Resposta}", Exemplo Resposta: "${ExResposta}"` + ); + } + } + + function VerificaComandoAluno(TextoAluno) { + let Comando = ''; + + if (TextoAluno.includes(ComandoRepetirFrase)) Comando = ComandoRepetirFrase; + else if (TextoAluno.includes(ComandoOpenConfigMode)) + Comando = ComandoOpenConfigMode; + else if (TextoAluno.includes(ComandoCloseConfigMode)) + Comando = ComandoCloseConfigMode; + else if (TextoAluno.includes(ComandoOpenRepeatMode)) + Comando = ComandoOpenRepeatMode; + else if (TextoAluno.includes(ComandoCloseRepeatMode)) + Comando = ComandoCloseRepeatMode; + else if (TextoAluno.includes(ComandoAjuda)) Comando = ComandoAjuda; + + return Comando; + } + + function ProcessarAudioEntrada(CaminhoArquivo, NomeArquivo, Modo, callback) { + const fs = require('fs'); + const CaminhoArquivoServidor = + Variables('src_media') + 'audioZoe2/' + NomeArquivo; + fs.rename(CaminhoArquivo, CaminhoArquivoServidor, function (err) { + if (err) throw err; + logData('Arquivo renomeado'); + const shell = require('shelljs'); + + mysqlConnection.query( + 'select STTmode, PythonVersion from config;', + function (error, Config, fields) { + logData('Consulta config realizada'); + const STTmode = Config[0]['STTmode']; + const PythonVersion = Config[0]['PythonVersion']; + // CONVERTER O .wav PARA TEXTO + var audioTotext = null; + + if (STTmode == 1) { + // GOOGLE SPEECH RECOGNITION NODE + logData('Google Speech Recognition'); + AudioParaTexto(CaminhoArquivoServidor, function (Texto) { + logData('Response do Google recebido: ' + Texto); + VerificaTextoAudio(Texto, function (Pergunta, Entendeu) { + logData('Texto verificado'); + callback(Pergunta, Entendeu); + //uploadFileToBucket(CaminhoArquivoServidor); + }); + }); + } else if (STTmode == 2) { + // GOOGLE SPEECH RECOGNITION FREE + console.log('inicio do google speech free --- RecognizeAudio'); + let Comando = `${PythonVersion} ${Variables( + 'src_media' + )}assets/audio_to_text2.py ${NomeArquivo}`; + audioTotext = shell.exec(Comando); + VerificaTextoAudio( + audioTotext.stdout, + function (Pergunta, Entendeu) { + callback(Pergunta, Entendeu); + //uploadFileToBucket(CaminhoArquivoServidor); + console.log('inicio do google speech free --- RecognizeAudio'); + } + ); + } else if (STTmode == 3) { + // GOOGLE SPEECH RECOGNITION PYTHON + let Comando = `export GOOGLE_APPLICATION_CREDENTIALS="/var/www/zoeGoogleCloudSpeech.json"; ${PythonVersion} ${Variables( + 'src_media' + )}assets/speech_cloud.py ${NomeArquivo}`; + audioTotext = shell.exec(Comando); + VerificaTextoAudio( + audioTotext.stdout, + function (Pergunta, Entendeu) { + callback(Pergunta, Entendeu); + //uploadFileToBucket(CaminhoArquivoServidor); + } + ); + } else if (STTmode == 4) { + // WATSON + + shell.exec( + `ffmpeg -loglevel panic -i ${CaminhoArquivoServidor} -acodec pcm_s16le -ar 44100 ${ + CaminhoArquivoServidor.split('.')[0] + }.wav`, + function (Sucesso) { + const fs = require('fs'); + const SpeechToTextV1 = require('ibm-watson/speech-to-text/v1'); + const { IamAuthenticator } = require('ibm-watson/auth'); + + const speechToText = new SpeechToTextV1({ + authenticator: new IamAuthenticator({ apikey: STTWatsonKey }), + serviceUrl: STTWatsonService, + }); + + const params = { + audio: fs.createReadStream( + CaminhoArquivoServidor.split('.')[0] + '.wav' + ), + contentType: 'audio/l16; rate=44100', + }; + + speechToText + .recognize(params) + .then((response) => { + let Transcript = JSON.stringify(response.result, null, 2); + let TextoAudio = ''; + let Confidence = ''; + if (JSON.parse(Transcript).results.length > 0) { + TextoAudio = + JSON.parse(Transcript).results[0].alternatives[0] + .transcript; + Confidence = + JSON.parse(Transcript).results[0].alternatives[0] + .confidence; + } + //console.log("Transcript: " + TextoAudio + " - Confidence: " + Confidence); + VerificaTextoAudio( + TextoAudio, + function (Pergunta, Entendeu) { + callback(Pergunta, Entendeu); + } + ); + }) + .catch((err) => { + console.log(err); + VerificaTextoAudio('', function (Pergunta, Entendeu) { + callback(Pergunta, Entendeu); + //uploadFileToBucket(CaminhoArquivoServidor); + }); + }); + } + ); + } + } + ); + }); + } + + async function AudioParaTexto(CaminhoArquivo, callback) { + // HEADERS DE UM WAV EM: http://soundfile.sapp.org/doc/WaveFormat/ + const speech = require('@google-cloud/speech'); + const fs = require('fs'); + const client = new speech.SpeechClient({ + projectId: 'zoerobot-1581961113901', + keyFilename: '/var/www/zoeGoogleCloudSpeech.json', + }); + + const file = fs.readFileSync(CaminhoArquivo); + const audioBytes = file.toString('base64'); + const channels = file[22]; + const RateHertz = parseInt( + file[24].toString() + + file[25].toString() + + file[26].toString() + + file[27].toString() + ); + + const audio = { + content: audioBytes, + }; + const config = { + encoding: 'LINEAR16', + //sampleRateHertz: RateHertz, + languageCode: IdiomaZoe, + audioChannelCount: channels, + }; + const request = { + audio: audio, + config: config, + }; + + const [response] = await client.recognize(request); + const transcription = response.results + .map((result) => result.alternatives[0].transcript) + .join('\n'); + //console.log(`Transcription: ${transcription}`); + callback(transcription); + } + + function VerificaTextoAudio(Pergunta, callback) { + // Remove o \r\n do final da frase + for (let i = 0; i < 2; i++) { + if ( + Pergunta[Pergunta.length - 1] == '\r' || + Pergunta[Pergunta.length - 1] == '\n' + ) { + Pergunta = Pergunta.substring(0, Pergunta.length - 1); + } + } + + //console.log("Audio para Texto: " + Pergunta); + + let Entendeu = true; + + if ( + Pergunta.includes( + 'Google Speech Recognition could not understand audio' + ) || + Pergunta.includes( + 'Could not request results from Google Speech Recognition service' + ) || + Pergunta == '' + ) { + Entendeu = false; + Pergunta = EscolheFraseNaoEntendeu(); + } + + callback(Pergunta, Entendeu); + } + + function VerificaPronunciaUsuario(ListaSentencas, TextoAluno, Coerencia, callback) { + logData('Verificando pronúncia do usuário'); + + for (let i = 0; i < ListaSentencas.length; i++) { + ListaSentencas[i]['sentence'] = ReplaceAll( + ListaSentencas[i]['sentence'].toLowerCase(), + [',', '-', '_', '!', '?', "'", '.'], + ['', '', '', '', '', '', ''], + 15 + ); + } + + TextoAluno = ReplaceAll( + TextoAluno.toLowerCase(), + [',', '-', '_', '!', '?', "'", '.'], + ['', '', '', '', '', '', ''], + 15 + ); + + let Porcentagem = 0; + let IndexSentenca = 0; + + mysqlConnection.query( + 'select checkSentence, PythonVersion from config;', + function (error, Config, fields) { + logData('Consulta config realizada'); + const CheckSentence = Config[0]['checkSentence']; + const PythonVersion = Config[0]['PythonVersion']; + + loopCheckSentence(0, 0, IndexSentenca, ListaSentencas, TextoAluno, PythonVersion, CheckSentence, Coerencia, function(percent, index) { + Porcentagem = percent; + IndexSentenca = index; + callback(Porcentagem, ListaSentencas[IndexSentenca]['seq_dir']); + }); + + /*runPythonScript(`${PythonVersion} ${Variables('src_media')}assets/${CheckSentence} \"${ + ListaSentencas[IndexSentenca]['sentence'] + }\" \"${TextoAluno}\"`).then(percent => { + logData('Percentual de coerencia: ' + percent); + Porcentagem = percent; + callback(Porcentagem, ListaSentencas[IndexSentenca]['seq_dir']); + });*/ + + } + ); + } + + function loopCheckSentence(Porcentagem, Index, IndexSentenca, ListaSentencas, TextoAluno, PythonVersion, CheckSentence, Coerencia, callback) { + if (IndexSentenca < ListaSentencas.length) { + runPythonScript(`${PythonVersion} ${Variables('src_media')}assets/${CheckSentence} \"${ + ListaSentencas[IndexSentenca]['sentence'] + }\" \"${TextoAluno}\"`).then(percent => { + logData('Teste ' + (IndexSentenca + 1) + ' de ' + ListaSentencas.length + ' - Coerencia ' + percent + ' de ' + Coerencia); + if (percent >= Coerencia) { + Porcentagem = percent; + Index = IndexSentenca; + callback(Porcentagem, Index); + } + else { + if (percent > Porcentagem) { + Porcentagem = percent; + Index = IndexSentenca; + } + IndexSentenca++; + loopCheckSentence(Porcentagem, Index, IndexSentenca, ListaSentencas, TextoAluno, PythonVersion, CheckSentence, Coerencia, callback); + } + }); + } + else { + callback(Porcentagem, Index); + } + } + + async function runPythonScript(script) { + const shell = require('shelljs'); + return new Promise((resolve, reject) => { + shell.exec(script, function (code, stdout, stderr) { + if (code === 0) { + const percent = parseFloat(stdout); + resolve(percent); + } else { + reject(stderr); + } + } + ); + }); + } + + function CompareStrings(str1, str2) { + let pairs1 = WordLetterPairs(str1.toLowerCase()); + let pairs2 = WordLetterPairs(str2.toLowerCase()); + + let intersection = 0; + let union = pairs1.length + pairs2.length; + + for (let i = 0; i < pairs1.length; i++) { + for (let j = 0; j < pairs2.length; j++) { + if (pairs1[i] == pairs2[j]) { + intersection++; + pairs2.splice(j, 1); + break; + } + } + } + return (2.0 * intersection) / union; + } + + function WordLetterPairs(str) { + let AllPairs = []; + let Words = str.split(' '); + for (let w = 0; w < Words.length; w++) { + if (Words[w]) { + let PairsInWord = LetterPairs(Words[w]); + for (let p = 0; p < PairsInWord.length; p++) { + AllPairs.push(PairsInWord[p]); + } + } + } + + return AllPairs; + } + + function LetterPairs(str) { + let numPairs = str.length - 1; + let pairs = []; + for (let i = 0; i < numPairs; i++) { + pairs[i] = str.substring(i, 2); + } + + return pairs; + } + + function RemoveVariaveisFrase(Frase) { + let NovaFrase = ''; + if (Frase && Frase.includes('+')) { + let Trechos = Frase.split('+'); + for (let i = 0; i < Trechos.length; i++) { + if (i % 2 == 0) NovaFrase += Trechos[i]; + else NovaFrase += '_____'; + } + } else { + NovaFrase = Frase; + } + + return NovaFrase; + } + + function VerificaVariaveisFrase( + idzoechattimedialog, + FraseEntrada, + FraseComparada, + Matricula, + IDUnidade, + AlunoFalando, + callback + ) { + logData('Verificando se existem variáveis na frase'); + //FraseEntrada = ReplaceAll(FraseEntrada.toLowerCase(), [",", "-", "_", "!", "?", "'"], ["", "", "", "", "", ""], 15); + //FraseComparada = ReplaceAll(FraseComparada.toLowerCase(), [",", "-", "_", "!", "?", "'"], ["", "", "", "", "", ""], 15); + let FraseSubstituida = ''; + //console.log(FraseEntrada); + //console.log(FraseComparada); + // SE HOUVER VARIAVEL NA FRASE + if (FraseComparada && FraseComparada.includes('+')) { + let PalavrasFrase = FraseComparada.split(' '); + let VariaveisFrase = []; + let WhereVariables = '('; + for (let i = 0; i < PalavrasFrase.length; i++) { + if (PalavrasFrase[i].includes('+')) { + const Variavel = PalavrasFrase[i].split('+')[1]; + VariaveisFrase.push({ + idalexavariables: 0, + description: Variavel, + valuecli: 'UNKNOW', + }); + if (WhereVariables != '(') WhereVariables += ','; + WhereVariables += "'" + Variavel + "'"; + } + } + WhereVariables += ')'; + + //console.log(WhereVariables); + + const sqlVariaveis = `select avr.description, auv.* from alexauservariables auv inner join alexavariables avr on avr.idalexavariables = auv.idalexavariables where auv.idusers = ${Matricula} and auv.idunits = ${IDUnidade} and avr.description in ${WhereVariables};`; + //console.log(sqlVariaveis); + mysqlConnection.query( + sqlVariaveis, + function (error, VariaveisEncontradas, fields) { + logData('Consulta de variáveis realizada'); + //console.log(VariaveisEncontradas); + + let Encontrou = false; + // EXISTEM DADOS GRAVADOS NO BANCO PARA AS VARIAVEIS CONSULTADAS + if (VariaveisEncontradas && VariaveisEncontradas.length > 0) { + Encontrou = true; + for (let i = 0; i < VariaveisEncontradas.length; i++) { + for (let o = 0; o < VariaveisFrase.length; o++) { + if ( + VariaveisFrase[o].description == + VariaveisEncontradas[i].description + ) { + VariaveisFrase[o].idalexavariables = + VariaveisEncontradas[i].idalexavariables; + VariaveisFrase[o].valuecli = VariaveisEncontradas[i].valuecli; + } + } + } + //console.log(VariaveisFrase); + } + + // ALUNO FALANDO SEUS DADOS QUE SERAO SALVOS NO BANCO + if (AlunoFalando) { + AtualizaValoresVariaveis( + !Encontrou, + idzoechattimedialog, + FraseEntrada, + VariaveisFrase, + Matricula, + IDUnidade, + function (NovoValor) { + logData('Variável atualizada: ' + NovoValor); + FraseSubstituida = FraseEntrada; + callback(FraseSubstituida); + } + ); + } + // ZOE BUSCANDO DADOS DO ALUNO PRA FALAR + else { + InsereValoresVariaveisFrase( + FraseComparada, + VariaveisFrase, + function (FraseTrocada) { + logData('Variável inserida na frase'); + FraseSubstituida = FraseTrocada; + callback(FraseSubstituida); + } + ); + } + } + ); + } + // NAO EXISTEM VARIAVEIS NA FRASE + else { + logData('Não existem variáveis na frase'); + FraseSubstituida = + !AlunoFalando && FraseComparada ? FraseComparada : FraseEntrada; + callback(FraseSubstituida); + } + } + + function InsereValoresVariaveisFrase(FraseEntrada, VariaveisFrase, callback) { + let FraseTrocada = FraseEntrada; + + for (let i = 0; i < VariaveisFrase.length; i++) { + FraseTrocada = ReplaceAll( + FraseTrocada, + ['+' + VariaveisFrase[i].description + '+'], + [VariaveisFrase[i].valuecli], + 5 + ); + } + + callback(FraseTrocada); + } + + function EnviaResposta( + CriarAudio, + Resposta, + NomeArquivo, + res, + ExemploResposta, + Vezes, + Final, + Coerencia, + Validou, + Velocidade, + ZoeEntendeu, + Ordem, + ZoeTalking, + ProximoZoeTalking, + VozIngles, + Legenda, + Modo, + Seq, + Img + ) { + logData('Enviar resposta'); + const shell = require('shelljs'); + + mysqlConnection.query( + 'select TTSmode, RMaudio, PythonVersion, extAudio, zoevoiceEn, zoevoicePt, zoevoiceEs from config;', + function (error, Config, fields) { + logData('Consulta config realizada'); + const TTSmode = Config[0]['TTSmode']; + const PythonVersion = Config[0]['PythonVersion']; + const ExtAudio = Config[0]['extAudio']; + + const VozZoeEn = experienciaUnilever ? VozesUnilever.En : Config[0]['zoevoiceEn']; + const VozZoePt = experienciaUnilever ? VozesUnilever.Pt : Config[0]['zoevoicePt']; + const VozZoeEs = experienciaUnilever ? VozesUnilever.Es : Config[0]['zoevoiceEs']; + + if (TTSmode == 1) { + // PICO2WAV + if (CriarAudio) { + // CONVERTE A RESPOSTA EM TEXTO PARA AUDIO + shell.exec( + `pico2wave --wave=${ + Variables('src_media') + + 'audioZoe2/' + + NomeArquivo.split('.')[0] + }.wav \"${Resposta} \"`, + function (Resultado) { + // CONVERTE O AUDIO .WAV PARA .MP3 + shell.exec( + `ffmpeg -i ${Variables('src_media')}audioZoe2/${ + NomeArquivo.split('.')[0] + }.wav ${Variables('src_media')} audioZoe2/${ + NomeArquivo.split('.')[0] + }_exit${ExtAudio} -loglevel quiet -stats`, + function (sucesso) { + // APAGA O AUDIO .WAV DO SERVIDOR + shell.exec( + `rm ${Variables('src_media')}audioZoe2/${ + NomeArquivo.split('.')[0] + }.wav` + ); + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + ); + } + ); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + } else if (TTSmode == 2) { + // PYTHON gTTS OP2 + if (CriarAudio) { + // CONVERTE A RESPOSTA EM TEXTO PARA AUDIO + shell.exec( + `${PythonVersion} ${Variables( + 'src_media' + )}assets/text_to_audio2.py \"${Resposta}\" ${NomeArquivo}`, + function (Sucesso) { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + RemoverEntrada, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + ); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + RemoverEntrada, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + } else if (TTSmode == 3) { + // WIDEO + if (CriarAudio) { + const request = require('request'); + var options = { + uri: 'https://texttospeechapi.wideo.co/api/wideo-text-to-speech', + method: 'POST', + json: { + data: { + text: Resposta, + speed: Velocidade - Vezes * 0.05, + voice: VozIngles == 1 ? VozZoeEn : VozZoePt, + }, + }, + }; + request(options, function (error, response, body) { + if (!error && response.statusCode == 200) { + let ComandoBaixar = `wget "${ + response['body']['result']['url'] + }" -O ${Variables('src_media')}audioZoe2/${ + NomeArquivo.split('.')[0] + }_exit.mp3 -q;`; + shell.exec(ComandoBaixar, function (Sucesso) { + if (ExtAudio == '.wav') { + shell.exec( + `ffmpeg -loglevel panic -i ${Variables( + 'src_media' + )}audioZoe2/${ + NomeArquivo.split('.')[0] + }_exit.mp3 ${Variables('src_media')}audioZoe2/${ + NomeArquivo.split('.')[0] + }_exit.wav`, + function (Sucesso) { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + ); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + }); + } + }); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + RemoverEntrada, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + } else if (TTSmode == 4) { + logData('TTS Amazon Polly'); + // AMAZON POLLY + const fs = require('fs'); + + // CONVERTE A RESPOSTA EM TEXTO PARA AUDIO + shell.exec( + `${PythonVersion} ${Variables( + 'src_media' + )}assets/polly_service.py \"${Resposta}\" "${Variables( + 'src_media' + )}audioZoe2/${NomeArquivo}_exit.mp3" "${ + Modo == 0 || !Validou ? + (IdiomaZoe == "pt-BR" ? VozZoePt : + IdiomaZoe == "en-US" ? VozZoeEn : + IdiomaZoe == "es-ES" ? VozZoeEs : + VozZoeEn) : + VozIngles == 1 ? VozZoeEn : + VozIngles == 2 ? VozZoePt : + VozIngles == 3 ? VozZoeEs : + VozZoeEn + }"`, + function (Sucesso) { + logData('Texto convertido para audio'); + if (ExtAudio == '.wav') { + let fileDirectory = + Variables('src_media') + 'audioZoe2/' + NomeArquivo; + shell.exec( + 'lame --decode ' + + '"' + + fileDirectory + + '"' + + '_exit.mp3 ' + + '"' + + fileDirectory + + '"' + + '_exit.wav', + function (Sucesso) { + logData('Convertido wav para mp3'); + fs.chmodSync(fileDirectory + '_exit.wav', 0o777); + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + ); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + } + ); + } else if (TTSmode == 5) { + // PYTHON gTTS OP1 + if (CriarAudio) { + // CONVERTE A RESPOSTA EM TEXTO PARA AUDIO + const textToaudio = spawn('python', [ + Variables('src_media') + 'assets/text_to_audio.py', + Resposta, + NomeArquivo, + ]); + textToaudio.stdout.on('data', function (data) { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + RemoverEntrada, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + }); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + RemoverEntrada, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + } else if (TTSmode == 6) { + // WATSON IBM + const fs = require('fs'); + let respostaFiltered = Resposta.replace('?', 'INT'); + respostaFiltered = respostaFiltered.replace('/', 'BAR'); + if ( + fs.existsSync( + Variables('src_media') + + 'audioZoe2/' + + respostaFiltered + + '_exit.wav' + ) + ) { + //file exists + EnviarDados( + res, + CriarAudio, + Resposta, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } else { + const TextToSpeechV1 = require('ibm-watson/text-to-speech/v1'); + const { IamAuthenticator } = require('ibm-watson/auth'); + + const textToSpeech = new TextToSpeechV1({ + authenticator: new IamAuthenticator({ apikey: watsonIMBKey }), + serviceUrl: watsonURLService, + }); + + const params = { + text: Resposta, + voice: VozIngles == 1 ? VozZoeEn : VozZoePt, + accept: 'audio/wav', + }; + console.log( + 'request body : ' + params[0] + ',' + params[1] + ',' + params[2] + ); + textToSpeech + .synthesize(params) + .then((response) => { + const audio = response.result; + return textToSpeech.repairWavHeaderStream(audio); + }) + .then((repairedFile) => { + fs.writeFileSync( + Variables('src_media') + + 'audioZoe2/' + + respostaFiltered + + '_exit.wav', + repairedFile + ); + console.log('audio.wav written with a corrected wav header'); + if (ExtAudio == '.mp3') { + shell.exec( + 'ffmpeg -loglevel panic -i ' + + Variables('src_media') + + 'audioZoe2/' + + respostaFiltered + + '_exit.wav ' + + Variables('src_media') + + 'audioZoe2/' + + respostaFiltered + + '_exit.mp3', + function (Sucesso) { + EnviarDados( + res, + CriarAudio, + respostaFiltered, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + ); + } else { + EnviarDados( + res, + CriarAudio, + respostaFiltered, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + }) + .catch((err) => { + console.log(err); + }); + } + } + } + ); + } + + function EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + TextoAudio, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ) { + logData('Finalizado, enviado response'); + res.send( + JSON.stringify({ + status: 200, + url_audio: CriarAudio + ? 'https://myrobotlab.com.br/audioZoe2/' + NomeArquivo + '_exit' + ExtAudio + : '', + TextoAudio: TextoAudio, + Vezes: Vezes, + ExemploResposta: ExemploResposta, + Final: Final, + Coerencia: Coerencia, + Validou: Validou, + ZoeEntendeu: ZoeEntendeu, + Ordem: Ordem, + Seq: Seq, + ZoeTalking: ZoeTalking, + ProximoZoeTalking: ProximoZoeTalking, + Legenda: Legenda, + Modo: Modo, + img: Img, + }) + ); + // EXCLUI O ARQUIVO DE AUDIO DE ENTRADA + //const shell = require('shelljs'); + //shell.exec('rm ' + Variables('src_media') + 'audioZoe2/' + NomeArquivo); + } + + /*function UploadFIleToS3(NomeArquivo){ + fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ + if (!err) { + uploadFileToBucket(data); + } else { + console.log(err); + } + }); + }*/ + + function EnviaPerguntaMitsuku(Pergunta, SessaoID, callback) { + // TROCA A PALAVRA ZOE POR MITSUKU + Pergunta = ReplaceAll(Pergunta, ['Zoe'], ['Mitsuku'], 10); + // ENVIA A PERGUNTA EM TEXTO PARA MITSUKU + const querystring = require('querystring'); + const request = require('request'); + var form = { + input: Pergunta, + botid: '9fa364f2fe345a10', // ID do bot (CONSTANTE) + custid: SessaoID, // ID do usuário falando com o bot, ex: b3dfe148ae499f98 + }; + var formData = querystring.stringify(form); + request( + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + uri: 'https://kakko.pandorabots.com/pandora/talk-xml', + body: formData, + method: 'POST', + }, + function (err, res2, body) { + var striptags = require('striptags'); + var Resposta = body; + try { + Resposta = body.split('')[1].split('')[0]; + } catch (e) {} + Resposta = decodeURI(Resposta); + Resposta = striptags(Resposta); + + RemoverTagsDoTexto( + Resposta, + ['xgallery.', 'xloadswf2.', 'xloadswf3.', 'xlink.', 'xnslink.'], + function (NewResposta) { + if (NewResposta.includes('Human Virus deletion program started')) + NewResposta = NewResposta.split( + 'Human Virus deletion program started' + )[0]; + + if ( + NewResposta.includes( + 'This is a list of the games I can play with you' + ) + ) + NewResposta = + NewResposta.split('.')[NewResposta.split('.').length - 1]; + + if ( + NewResposta.includes('<img') && + NewResposta.includes('/img>') + ) + NewResposta = + NewResposta.split('<P')[0] + NewResposta.split('/P>')[1]; + + if (NewResposta.includes('<P') && NewResposta.includes('/P>')) + NewResposta = + NewResposta.split('<P')[0] + NewResposta.split('/P>')[1]; + + NewResposta = ReplaceAll( + NewResposta, + ['Mitsuku', '<br>', '"'], + ['Zoe', ' ', '"'], + 15 + ); + + callback(NewResposta); + } + ); + } + ); + } + + function EnviaPerguntaGPT(Pergunta, callback) { + + // Verificar se a pergunta foi feita em inglês + //if (!isEnglish(Pergunta)) { + // callback('Sorry, I only understand English'); + // return; + //} + + Pergunta = Pergunta.toLowerCase(); + + Pergunta = ReplaceAll(Pergunta, ['Zoe'], ['ChatGPT'], 10); + const querystring = require('querystring'); + const request = require('request'); + var form = { + model: 'gpt-3.5-turbo', + messages: [ + { + role: 'user', + content: Pergunta, + }, + ], + }; + var formData = JSON.stringify(form); + request( + { + headers: { + 'Content-Type': 'application/json', + Authorization: + 'Bearer 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', + }, + uri: 'https://api.openai.com/v1/chat/completions', + body: formData, + method: 'POST', + }, + function (err, res2, body) { + //console.log(body); + var respostaGPT = JSON.parse(body); + var Resposta = respostaGPT['choices'][0]['message']['content']; + Resposta = ReplaceAll(Resposta, ['ChatGPT'], ['Zoe'], 10); + Resposta = ReplaceAll(Resposta, ['OpenAI'], ['MyRobot'], 10); + Resposta = ReplaceAll(Resposta, ['GPT-3'], ['Zoe'], 10); + Resposta = Resposta.replace(/\n/g, ' '); + console.log('Resposta: ' + Resposta); + + callback(Resposta); + } + ); + } + + function EnviaPerguntaRosie(Pergunta, callback) { + Pergunta = ReplaceAll(Pergunta, ['Zoe'], ['Rosie'], 10); + const querystring = require('querystring'); + const request = require('request'); + var form = { + botcust2: 'e007f413decb76eb', + message: Pergunta, + }; + var formData = querystring.stringify(form); + request( + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + uri: 'https://pandorabots.com/pandora/talk?botid=b16e613a3e341aa4', + body: formData, + method: 'POST', + }, + function (err, res2, body) { + var Resposta = body; + try { + Resposta = body.split('Rosie: ')[1].split('
')[0]; + } catch (e) {} + + Resposta = ReplaceAll(Resposta, ['Rosie'], ['Zoe'], 10); + + //console.log(Resposta); + + callback(Resposta); + } + ); + } + + function EnviaPerguntaCleverbot(Pergunta, callback) { + //Pergunta = ReplaceAll(Pergunta, ["Zoe"], ["Rosie"], 10); + const querystring = require('querystring'); + const request = require('request'); + var form = { + uc: 'UseOfficialCleverbotAPI', + in: encodeURI(Pergunta), + bot: 'c', + cbsid: 'WXI2AHQ82N', + xai: 'WXI,405312017,WXHNGDC4RJ1J', + ns: 99, + al: '', + dl: 'en', + flag: '', + user: '', + mode: 1, + alt: 0, + reac: '', + emo: '', + sou: 'website', + xed: '', + t: 5103, + }; + var formData = querystring.stringify(form); + request( + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + uri: 'https://www.cleverbot.com/webservicemin?uc=UseOfficialCleverbotAPI&out=I%27m%20Grant.&in=What%20is%20your%20name%3F&bot=c&cbsid=WXI2AHQ82N&xai=WXI,405312017,WXHNGDC4RJ1J&ns=99&al=&dl=en&flag=&user=&mode=1&alt=0&reac=&emo=&sou=website&xed=&t=5103&', + body: formData, + method: 'POST', + }, + function (err, res2, body) { + var Resposta = body; + //console.log(body); + //try { Resposta = body.split("Rosie: ")[1].split("
")[0]; } catch (e) { } + + //Resposta = ReplaceAll(Resposta, ["Rosie"], ["Zoe"], 10); + + callback(Resposta); + } + ); + } + + function ExcludeZoeAudios() {} + + function EnviaPerguntaKuki(Pergunta, SessaoID, callback) { + Pergunta = ReplaceAll(Pergunta, ['Zoe'], ['Kuki'], 10); + const querystring = require('querystring'); + const request = require('request'); + var form = { + input: Pergunta, + sessionid: SessaoID, + channel: 7, + botkey: + 'icH-VVd4uNBhjUid30-xM9QhnvAaVS3wVKA3L8w2mmspQ-hoUB3ZK153sEG3MX-Z8bKchASVLAo~', + client_name: 'kp17725cfe611', + }; + var formData = querystring.stringify(form); + request( + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + uri: 'https://icap.iconiq.ai/talk', + body: formData, + method: 'POST', + }, + function (err, res2, body) { + var Resposta = JSON.parse(body)['responses'][0]; + //console.log(Resposta); + + if (Resposta.includes('Image from ')) + Resposta = + Resposta.split('Image from ')[0] + Resposta.split('')[1]; + + if (Resposta.includes('') && Resposta.includes('')) + Resposta = + Resposta.split('')[0] + Resposta.split('')[1]; + + if (Resposta.includes('I can currently play these games:')) { + Resposta = Resposta.split('I can currently play these games:')[0]; + if (Resposta == '') Resposta = 'I would love to'; + } + + if ( + Resposta.includes( + '**What website, app or Discord server are you using to talk to me?' + ) + ) + Resposta = Resposta.replace( + '**What website, app or Discord server are you using to talk to me?', + '' + ); + + if ( + Resposta.includes('("status":"error", "message":"401 unauthorized")') + ) + Resposta = Resposta.replace( + '("status":"error", "message":"401 unauthorized")', + '' + ); + + // I can currently play these games: + + Resposta = ReplaceAll( + Resposta, + ['Kuki', 'Mitsuku', '<br>', '"'], + ['Zoe', 'Zoe', ' ', '"'], + 15 + ); + callback(Resposta); + } + ); + } + + function EnviaPerguntaTalkFlow(Pergunta, SessaoID, callback) { + //Pergunta = ReplaceAll(Pergunta, ['Zoe'], ['Rosie'], 10); + const request = require('request'); + var form = { + email: "CONTATO@MYROBOT.COM.BR", + question: Pergunta, + client_id: 21 + }; + var formData = JSON.stringify(form); + request( + { + headers: { + 'Content-Type': 'application/json', + }, + uri: 'https://panel.walo.us/chat/send_message_api', + body: formData, + method: 'POST', + }, + function (err, res2, body) { + const resJson = JSON.parse(body); + var Resposta = resJson.answer; + + console.log("Respsota TalkFlow: " + Resposta); + + callback(Resposta); + } + ); + } + + function EnviaPerguntaChatBot(Pergunta, SessaoID, Matricula, callback) { + mysqlConnection.query( + `select ChatBot, (select count(1) from users where user = '${Matricula}' and idusertype = 18) as Talkflow from config;`, + function (error, Config, fields) { + const ChatBot = Config[0]['ChatBot']; + const Talkflow = Config[0]['Talkflow']; + logData("Enviando pergunta para o chatbot"); + if (Talkflow == 1) { + // talk flow + logData("Chatbot Talk Flow"); + EnviaPerguntaTalkFlow(Pergunta, SessaoID, function (Resposta) { + useToken(SessaoID); + callback(Resposta); + }); + } + else { + if (ChatBot == 1) { + // MITSUKU + logData("Chatbot Mitsuko"); + EnviaPerguntaMitsuku(Pergunta, SessaoID, function (Resposta) { + callback(Resposta); + }); + } else if (ChatBot == 2) { + // ROSIE + logData("Chatbot Rosie"); + EnviaPerguntaRosie(Pergunta, function (Resposta) { + callback(Resposta); + }); + } else if (ChatBot == 3) { + // CLEVERBOT + logData("Chatbot Cleverbot"); + EnviaPerguntaCleverbot(Pergunta, function (Resposta) { + callback(Resposta); + }); + } else if (ChatBot == 4) { + // KUKI + logData("Chatbot Kuki"); + EnviaPerguntaKuki(Pergunta, SessaoID, function (Resposta) { + callback(Resposta); + }); + } else if (ChatBot == 5) { + // gpt + logData("Chatbot ChatGPT"); + EnviaPerguntaGPT(Pergunta, function (Resposta) { + callback(Resposta); + }); + } else if (ChatBot == 6) { + // talk flow + logData("Chatbot Talk Flow"); + EnviaPerguntaTalkFlow(Pergunta, SessaoID, function (Resposta) { + callback(Resposta); + }); + } + } + } + ); + } + + function TrataRespostaChatBot(Resposta, callback) { + let Tratada = Resposta; + Tratada = ReplaceAll(Tratada, ['
', '"'], [' ', "'"], 15); + mysqlConnection.query( + `SELECT tf.* FROM zoetratamentofrases tf inner join config cf on cf.ChatBot = tf.ChatBot;`, + function (error, Tratamentos, fields) { + if (Tratamentos && Tratamentos.length > 0) { + for (let i = 0; i < Tratamentos.length; i++) { + if (Tratamentos[i]['frase'] == Resposta) { + Tratada = Tratamentos[i]['trocada']; + break; + } + } + } + callback(Tratada); + } + ); + } + + function RemoverTagsDoTexto(Texto, Palavras, callback) { + let NovoTexto = ''; + for (let p = 0; p < Palavras.length; p++) { + for (var i = 0; i < Texto.split(Palavras[p]).length; i++) { + if (i % 2 == 0) NovoTexto += Texto.split(Palavras[p])[i]; + } + if (NovoTexto != '') Texto = NovoTexto; + NovoTexto = ''; + } + callback(Texto); + } + + function ReplaceAll(Texto, Palavras, TrocarPor, Vezes) { + try { + for (let i = 0; i < Vezes; i++) { + for (let o = 0; o < Palavras.length; o++) { + Texto = Texto.replace(Palavras[o], TrocarPor[o]); + } + } + } + catch (e) { + + } + + return Texto; + } + + function AtualizaValoresVariaveis( + ModoInserir, + idzoechattimedialog, + FraseEntrada, + Variaveis, + Matricula, + IDUnidade, + callback + ) { + // VERIFICA TODAS AS SENTENCAS DESSA INTENCAO + mysqlConnection.query( + `select * from zoechattimesentences where idzoechattimedialog = ${idzoechattimedialog};`, + function (error, ChatTimeSentences, fields) { + let ArrayPergunta = FraseEntrada.split(' '); + let UltimoIndexArray = ArrayPergunta.length - 1; + // REMOVE O \r\n DO FINAL DA ULTIMA PALAVRA + for (let i = 0; i < ArrayPergunta[UltimoIndexArray].length; i++) { + let UltimaLeta = + ArrayPergunta[UltimoIndexArray][ + ArrayPergunta[UltimoIndexArray].length - 1 + ]; + if (UltimaLeta == '\r' || UltimaLeta == '\n') { + ArrayPergunta[UltimoIndexArray] = ArrayPergunta[ + UltimoIndexArray + ].substring(0, ArrayPergunta[UltimoIndexArray].length - 1); + } else break; + } + + // MONTA ARRAY DE PALAVRAS DE TODAS AS SENTENCAS DESSA INTENCAO + let Sentencas = []; + for (let o = 0; o < ChatTimeSentences.length; o++) { + Sentencas.push(ChatTimeSentences[o]['sentence'].split(' ')); + } + + let NovoValor = ''; + let indexVariavelAtual = 0; + + //console.log(Sentencas); + //console.log(ArrayPergunta); + + // PARA CADA VARIAVEL CONTIDA NA FRASE + for (let i = 0; i < Variaveis.length; i++) { + // PARA CADA SENTENCA VERIFICA QUAIS AS PALAVRAS NAO ESTAO PRESENTES NESTA PARA VERIFICAR SE CONDIZ COM A VARIAVEL + indexVariavelAtual = i; + for (let o = 0; o < Sentencas.length; o++) { + // PARA CADA SENTENCA + for (let p = 0; p < ArrayPergunta.length; p++) { + // PARA CADA PALAVRA DA FRASE DO USUARIO + for (let q = 0; q < Sentencas[o].length; q++) { + // PARA CADA PALAVRA DE CADA SENTENCA + if ( + Sentencas[o][q].toLowerCase() == + ArrayPergunta[p].toLowerCase() + ) + // VERIFICA SE AS PALAVRAS SAO IGUAIS + ArrayPergunta[p] = ''; // SE IGUAIS ENTAO REMOVE, MANTENDO SOMENTE AS DIFERENTES NO ARRAY + } + } + } + + //console.log(ArrayPergunta); + + // VERIFICAR OS VALORES QUE SAO DIFERENTES DAS PALAVRAS CONTIDAS NAS FRASES, ATRIBUINDO O VALOR DA VARIAVEL COM ESTE + for (let o = 0; o < ArrayPergunta.length; o++) { + if (ArrayPergunta[o] != '') { + if (!Variaveis[i].description.includes('Spell')) + // SE FOR ALGUMA VARIAVEL DE TEXTO + NovoValor += (NovoValor != '' ? ' ' : '') + ArrayPergunta[o]; + else { + // SE FOR ALGUMA VARIAVEL DE SOLETRAGEM + if (ArrayPergunta[o].length == 1) + // SE A PALAVRAS TIVER APENAS UMA LETRA + NovoValor += (NovoValor != '' ? '-' : '') + ArrayPergunta[o]; + } + } + } + } + // ALTERA O VALOR DA VARIAVEL PARA O NOVO VALOR DITO PELO ALUNO + Variaveis[indexVariavelAtual].valuecli = NovoValor; + + InserirValorVariavel( + ModoInserir, + Variaveis[indexVariavelAtual], + Matricula, + IDUnidade, + function (Sucesso) { + callback(NovoValor); + } + ); + } + ); + } + + function InserirValorVariavel( + Inserir, + Variavel, + Matricula, + IDUnidade, + callback + ) { + //console.log(Variavel); + Variavel.valuecli = ReplaceAll(Variavel.valuecli, "'", '"', 10); + let sqlChangeVariable = ``; + if (Inserir == true) { + sqlChangeVariable = `INSERT INTO alexauservariables (idalexavariables, valuecli, idusers, idunits) + VALUES ((SELECT idalexavariables FROM alexavariables WHERE description = '${Variavel.description}'), '${Variavel.valuecli}', ${Matricula}, ${IDUnidade});`; + } else { + sqlChangeVariable = `UPDATE alexauservariables SET valuecli = '${Variavel.valuecli}' WHERE idalexavariables = ${Variavel.idalexavariables} AND idusers = ${Matricula} AND idunits = ${IDUnidade};`; + } + //console.log(sqlChangeVariable); + mysqlConnection.query(sqlChangeVariable, function (error, results, fields) { + let Sucesso = true; + if (error) { + Sucesso = false; + console.log( + "Erro ao definir valor da variável '" + Variavel.description + "'" + ); + console.log(error); + console.log(sqlChangeVariable); + } + callback(Sucesso); + }); + } + + function ModoConfiguracao(Pergunta, NomeArquivo, res, Matricula, IDUnidade) { + let Resposta = ''; + try { + if (Pergunta.toLowerCase().includes(FraseMudarVariavel)) { + // ALTERAR VALOR DA VARIAVEL - FRASE EXEMPLO: change my name to Diego + let Variavel = Pergunta.split(FraseMudarVariavel)[1].split(' ')[0]; // change my NAME to diego + let NovoValor = Pergunta.split(Variavel + ' to ')[1]; // change my name to DIEGO + //NovoValor = NovoValor.substring(0, NovoValor.length - 1); + let sqlSearchVariable = `SELECT av.idalexavariables, av.description, au.valuecli FROM alexauservariables au INNER JOIN alexavariables av ON av.idalexavariables = au.idalexavariables WHERE au.idusers = ${Matricula} AND au.idunits = ${IDUnidade} AND av.description = '${Variavel}';`; + mysqlConnection.query( + sqlSearchVariable, + function (error, results, fields) { + let FormVariavel = { + idalexavariables: 0, + description: Variavel, + valuecli: NovoValor, + }; + let ModoInserir = false; + if (results.length == 0) { + ModoInserir = false; + } else { + FormVariavel.idalexavariables = results[0].idalexavariables; + FormVariavel.description = results[0].description; + FormVariavel.valuecli = NovoValor; + } + + InserirValorVariavel( + ModoInserir, + FormVariavel, + Matricula, + IDUnidade, + function (Sucesso) { + if (Sucesso) + // CONSEGUIU DEFINIR A VARIAVEL COM O NOVO VALOR + Resposta = + 'Your ' + Variavel + ' was changed to ' + NovoValor; + // ERRO AO DEFINIR NOVO VALOR PARA VARIAVEL + else Resposta = 'Fail to define your ' + Variavel; + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + FraseExemploConfig, + 0, + 1, + Sucesso ? 100 : 0, + Sucesso ? 1 : 0, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 0, + 2, + 0, + '' + ); + } + ); + } + ); + } else if (Pergunta.toLowerCase().includes(FraseDizerVariavel)) { + // FALAR VALOR DA VARIAVEL - FRASE EXEMPLO: say my name + let Variavel = Pergunta.split(FraseDizerVariavel)[1]; // say my NAME + //Variavel = Variavel.substring(0, Variavel.length - 1); + ConsultarValorVariavel( + Variavel, + Matricula, + IDUnidade, + function (valuecli) { + if (valuecli != '') + // ENCONTROU VALOR PARA ESSA VARIAVEL + Resposta = 'Your ' + Variavel + ' is ' + valuecli; + // NAO ENCONTROU VALOR PARA ESSA VARIAVEL + else + Resposta = + 'I yet not know your ' + + Variavel + + '. Say change my ' + + Variavel + + ' to your ' + + Variavel + + ' to insert it.'; + + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + FraseExemploConfig, + 0, + 1, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 0, + 2, + 0, + '' + ); + } + ); + } else { + // COMANDO DESCONHECIDO + Resposta = EscolheFraseNaoEntendeu(); + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + FraseExemploConfig, + 0, + 1, + 0, + 0, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 0, + 2, + 0, + '' + ); + } + } catch (e) { + // HOUVE ALGUM ERRO DURANTE O PROCESSO OU FRASE INCORRETA + Resposta = EscolheFraseNaoEntendeu(); + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + FraseExemploConfig, + 0, + 1, + 0, + 0, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 0, + 2, + 0, + '' + ); + } + } + + function ConsultarValorVariavel(Variavel, Matricula, IDUnidade, callback) { + let sqlShowVariable = `SELECT au.valuecli FROM alexauservariables au INNER JOIN alexavariables av ON av.idalexavariables = au.idalexavariables WHERE au.idusers = ${Matricula} AND au.idunits = ${IDUnidade} AND av.description = '${Variavel}';`; + //console.log(sqlShowVariable); + mysqlConnection.query(sqlShowVariable, function (error, results, fields) { + let ValorVariavel = ''; + if (results.length > 0) ValorVariavel = results[0]['valuecli']; + else ValorVariavel = ''; + callback(ValorVariavel); + }); + } + + function LimparCaracteres(Texto) { + return Texto.replace(/[^a-zA-Z\d]/g, '').toLowerCase(); + } + + // #endregion + + return router; +}; + +module.exports = routes; diff --git a/controllers/chattimeController_bkp.js b/controllers/chattimeController_bkp.js new file mode 100644 index 0000000..19f09dc --- /dev/null +++ b/controllers/chattimeController_bkp.js @@ -0,0 +1,3162 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const formidable = require('formidable'); +const express = require('express'); +const router = express.Router(); +//const { uploadFileToBucket, getFileStream, deleteFileStream } = require('../s3'); +var { spawn } = require('child_process'); +let bodyParser = require('body-parser'); +router.use( + bodyParser.json({ + verify: function getRawBody(req, res, buf) { + req.rawBody = buf.toString(); + }, + }) +); + +//Payed +const watsonIMBKey = 'ihcWQ89rxCAKDQgyXh7wU4bI_9R2zxjBmcevXA1_x3t1'; +const watsonURLService = + 'https://api.us-south.text-to-speech.watson.cloud.ibm.com/instances/96918c09-fa7d-495f-9413-646e624e46b6'; + +//Free +//const watsonIMBKey = "EJtHH83IMSkHk64oDmrVbwwk_RPnrOu0vgbWJ-O7k5kR"; +//const watsonURLService = "https://api.us-south.text-to-speech.watson.cloud.ibm.com/instances/aa14db78-af38-45ae-9c94-1f226ef325c1"; + +const STTWatsonKey = 'psg1n6enCs0R5MHuEOkCKoCUKOeLFSgBk00eDl0s8T9n'; +const STTWatsonService = + 'https://api.us-south.speech-to-text.watson.cloud.ibm.com/instances/6cdb8798-77e4-4e5d-bcc9-b03ce151ee55'; + +var routes = function () { + //#region CHATTIME + router.get('/getAllChattime', verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + * + from zoechattime;`, + res, + req.originalUrl + ); + }); + + router.get('/getChattime/:idzoechattime', verifyJWT, (req, res) => { + const idzoechattime = parseInt(req.params.idzoechattime); + execSQLQuery( + `SELECT + * + from zoechattime + where idzoechattime = ${idzoechattime};`, + res, + req.originalUrl + ); + }); + + router.post('/insertChattime', verifyJWT, (req, res) => { + const idzoechattime = parseInt(req.body.idzoechattime); + const description = req.body.description; + execSQLQuery( + `INSERT INTO zoechattime (description) + VALUES (?);`, + res, + req.originalUrl, + [description] + ); + }); + + router.patch('/updateChattime', verifyJWT, (req, res) => { + const idzoechattime = parseInt(req.body.idzoechattime); + const description = req.body.description; + execSQLQuery( + `UPDATE zoechattime SET + description = ? + WHERE idzoechattime = ?;`, + res, + req.originalUrl, + [description, idzoechattime] + ); + }); + + router.delete('/deleteChattime/:idzoechattime', verifyJWT, (req, res) => { + const idzoechattime = parseInt(req.params.idzoechattime); + execSQLQuery( + `delete from zoechattime + where idzoechattime = ${idzoechattime};`, + res, + req.originalUrl + ); + }); + + //#endregion + + //#region CHATTIME DIALOG + router.get('/getChattimedialog/:idzoechattime', verifyJWT, (req, res) => { + const idzoechattime = parseInt(req.params.idzoechattime); + execSQLQuery( + `SELECT + * + from zoechattimedialog + where idzoechattime = ${idzoechattime};`, + res, + req.originalUrl + ); + }); + + router.post('/insertChattimedialog', verifyJWT, (req, res) => { + const idzoechattimedialog = parseInt(req.body.idzoechattimedialog); + const idzoechattime = parseInt(req.body.idzoechattime); + const zoetalking = req.body.zoetalking; + const speed = req.body.speed; + const phrase = req.body.phrase; + const ordem = parseInt(req.body.ordem); + const percent = parseInt(req.body.percent); + const english = req.body.english ? 1 : 0; + const sub = parseInt(req.body.sub); + const seq = parseInt(req.body.seq); + const seq_dir = parseInt(req.body.seq_dir); + const explanation = req.body.explanation; + const ex_english = req.body.ex_english ? 1 : 0; + const img = req.body.img; + const idzoevoices = req.body.idzoevoices; + const idzoevoices_ex = req.body.idzoevoices_ex; + execSQLQuery( + `INSERT INTO zoechattimedialog (idzoechattime, zoetalking, speed, phrase, ordem, percent, english, sub, seq, seq_dir, explanation, ex_english, img, idzoevoices, idzoevoices_ex) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`, + res, + req.originalUrl, + [ + idzoechattime, + zoetalking, + speed, + phrase, + ordem, + percent, + english, + sub, + seq, + seq_dir, + explanation, + ex_english, + img, + idzoevoices, + idzoevoices_ex, + ] + ); + }); + router.delete( + '/deleteChattimedialog/:idzoechattime', + verifyJWT, + (req, res) => { + const idzoechattime = parseInt(req.params.idzoechattime); + execSQLQuery( + `delete from zoechattimedialog + where idzoechattime = ${idzoechattime};`, + res, + req.originalUrl + ); + } + ); + + router.get('/getZoeVoices', verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + * + from zoevoices + where disabled = 0;`, + res, + req.originalUrl + ); + }); + + //#endregion + + //#region CHATTIME SENTENCES + router.get( + '/getChattimesentences/:idzoechattimedialog', + verifyJWT, + (req, res) => { + const idzoechattimedialog = parseInt(req.params.idzoechattimedialog); + execSQLQuery( + `SELECT + * + from zoechattimesentences + where idzoechattimedialog = ${idzoechattimedialog};`, + res, + req.originalUrl + ); + } + ); + + router.post('/insertChattimesentences', verifyJWT, (req, res) => { + const idzoechattimesentences = parseInt(req.body.idzoechattimesentences); + const idzoechattimedialog = parseInt(req.body.idzoechattimedialog); + const sentence = req.body.sentence; + const seq_dir = parseInt(req.body.seq_dir); + const ordem_dir = parseInt(req.body.ordem_dir); + const ex_answer = req.body.ex_answer ? 1 : 0; + execSQLQuery( + `INSERT INTO zoechattimesentences (idzoechattimedialog, sentence, seq_dir, ordem_dir, ex_answer) + VALUES (?, ?, ?, ?, ?);`, + res, + req.originalUrl, + [idzoechattimedialog, sentence, seq_dir, ordem_dir, ex_answer] + ); + }); + + router.delete( + '/deleteChattimesentences/:idzoechattime', + verifyJWT, + (req, res) => { + const idzoechattime = parseInt(req.params.idzoechattime); + execSQLQuery( + `delete from zoechattimesentences + where idzoechattimedialog in (select idzoechattimedialog from zoechattimedialog where idzoechattime = ${idzoechattime});`, + res, + req.originalUrl + ); + } + ); + + //#endregion + + //#region TRATAMENTO CHAT BOT + + router.get('/getAllTratamentoChatBot', verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + tf.*, + cb.description as 'NameChatBot' + from zoetratamentofrases tf + inner join ChatBot cb on cb.ChatBot = tf.ChatBot;`, + res, + req.originalUrl + ); + }); + + router.post('/insertTratamentoChatBot', verifyJWT, (req, res) => { + const ChatBot = parseInt(req.body.ChatBot); + const frase = req.body.frase; + const trocada = req.body.trocada; + const habilitado = req.body.habilitado ? 1 : 0; + execSQLQuery( + `INSERT INTO zoetratamentofrases (ChatBot, frase, trocada, habilitado) + VALUES (?, ?, ?, ?);`, + res, + req.originalUrl, + [ChatBot, frase, trocada, habilitado] + ); + }); + + router.patch('/updateTratamentoChatBot', verifyJWT, (req, res) => { + const idzoetratamentofrases = parseInt(req.body.idzoetratamentofrases); + const ChatBot = parseInt(req.body.ChatBot); + const frase = req.body.frase; + const trocada = req.body.trocada; + const habilitado = req.body.habilitado ? 1 : 0; + execSQLQuery( + `UPDATE zoetratamentofrases SET + ChatBot = ?, + frase = ?, + trocada = ?, + habilitado = ? + WHERE idzoetratamentofrases = ?;`, + res, + req.originalUrl, + [ChatBot, frase, trocada, habilitado, idzoetratamentofrases] + ); + }); + + router.delete( + '/deleteTratamentoChatBot/:idzoetratamentofrases', + verifyJWT, + (req, res) => { + const idzoetratamentofrases = parseInt(req.params.idzoetratamentofrases); + execSQLQuery( + `delete from zoetratamentofrases + WHERE idzoetratamentofrases = ?;`, + res, + req.originalUrl, + [idzoetratamentofrases] + ); + } + ); + + //#endregion + + // #region Requisição do robô + + // COMANDOS + const ComandoRepetirFrase = 'repeat'; + const ComandoOpenConfigMode = 'open config mode'; + const ComandoCloseConfigMode = 'close config mode'; + const ComandoOpenRepeatMode = 'open repeat mode'; + const ComandoCloseRepeatMode = 'close repeat mode'; + const ComandoAjuda = 'explain'; + // FRASES PADRAO + const FrasesNaoEntendeu = [ + 'Sorry, repeat please', + "I didn't get that, repeat please", + "I didn't catch that, repeat please", + 'Sorry, say again', + "I don't understand you", + ]; + const TextoNaoEntendeu = 'Zoe could not understand input aduio'; + const FraseFinal = 'Very good'; + const FraseExemploConfig = 'Try saying, change my name to new name'; + const FraseMudarVariavel = 'change my '; + const FraseDizerVariavel = 'say my '; + const FraseEnterSetupMode = 'Config mode has been inited. What can I do?'; + const FraseExitSetupMode = 'Config mode has been closed.'; + const FraseEnterRepeatMode = + "Repeat after me mode has been inited. Say ' " + + ComandoCloseRepeatMode + + "' to exit"; + const FraseServerDown = + 'Ops, server down. Wait a moment and try again please'; + const FraseExitRepeatMode = 'Repeat after me mode has been closed.'; + const FraseComandoIndisponivel = 'Command unavailable while in classes'; + // DAODS PADRAO + const VelocidadePadrao = 0.75; + const CoerenciaPadrao = 60; + const Separador = '<-->'; + const MatriculasPtBr = [240001]; + var IdiomaZoe = "en-US"; + + function logData(mensagem) { + var data = new Date(); + console.log( + data.getHours() + + ':' + + data.getMinutes() + + ':' + + data.getSeconds() + + '.' + + data.getMilliseconds() + + ' - ' + + mensagem + ); + } + + function MontaSQLChatTime(ChatTimeID, Ordem, Seq) { + return `select R.*, (select ctd.explanation from zoechattimedialog ctd where ctd.idzoechattime = R.idzoechattime and ctd.ordem = R.OrdemAnterior limit 1) as 'Explan' from ( + select + ctd.*, + (select ctd2.phrase end from zoechattimedialog ctd2 where ctd2.idzoechattime = ctd.idzoechattime and ctd2.seq = ctd.seq_dir and ctd2.ordem = ctd.ordem + 1 limit 1) as 'ExemploResposta', + (select ctd2.phrase end from zoechattimedialog ctd2 where ctd2.idzoechattime = ctd.idzoechattime and ctd2.seq = ctd.seq_dir and ctd2.ordem = ctd.ordem + 2 limit 1) as 'ExemploResposta2', + (select ctd2.phrase end from zoechattimedialog ctd2 where ctd2.idzoechattime = ctd.idzoechattime and ctd2.seq = ctd.seq_dir and ctd2.ordem = (select ctd3.ordem from zoechattimedialog ctd3 where ctd3.idzoechattime = ctd.idzoechattime and ctd3.ordem < ctd.ordem and ctd3.zoetalking = 1 order by ctd3.ordem desc limit 1) limit 1) as 'PerguntaAnterior', + (select ctd3.ordem from zoechattimedialog ctd3 where ctd3.idzoechattime = ctd.idzoechattime and ctd3.seq = ctd.seq_dir and ctd3.ordem > ctd.ordem /*and ctd3.zoetalking = 0*/ order by ctd3.ordem asc limit 1) as 'ProximaOrdem', + (select ctd3.ordem from zoechattimedialog ctd3 where ctd3.idzoechattime = ctd.idzoechattime and ctd3.seq = ctd.seq_dir and ctd3.ordem < ctd.ordem /*and ctd3.zoetalking = 1*/ order by ctd3.ordem desc limit 1) as 'OrdemAnterior', + (select case when count(*) = 1 then 0 else 1 end from zoechattimedialog ctd3 where ctd3.idzoechattime = ctd.idzoechattime and ctd3.seq = ctd.seq_dir and ctd3.ordem = ctd.ordem + 1) as 'Final', + (select ctd4.zoetalking from zoechattimedialog ctd4 where ctd4.idzoechattime = ctd.idzoechattime and ctd4.seq = ctd.seq_dir and ctd4.ordem > ctd.ordem order by ctd4.ordem asc limit 1) as 'ProximoZoeTalking' + from zoechattimedialog ctd + where ctd.idzoechattime = ${ChatTimeID} and ctd.ordem = ${Ordem} and ctd.seq = ${Seq}) R;`; + } + + function EscolheFraseNaoEntendeu() { + const i = Math.floor(Math.random() * FrasesNaoEntendeu.length - 1) + 1; + return FrasesNaoEntendeu[i]; + } + + router.post('/recognizeAudio/:token', (req, res) => { + logData('RecognizeAudio, iniciando'); + let token = req.params.token; + if (token != Variables('tk_fixed')) { + res.status(500).send({ status: 'expired' }); + return; + } + // RECEBE DADOS DA REQUISIÇÃO + let form = new formidable.IncomingForm(); + form.maxFileSize = 1024 * 1024 * 1024; + form.on('file', function (name, file) {}); + form.on('error', function (err) {}); + form.on('aborted', function () {}); + form.parse(req, function (err, fields, files) { + var Modo = parseInt(fields.Modo); + var Mensagem = fields.Mensagem || ''; + var Vezes = parseInt(fields.Vezes); + var ChatTimeID = parseInt(fields.ChatTimeID); + var Ordem = parseInt(fields.Ordem); + var Seq = parseInt(fields.Seq); + var Matricula = parseInt(fields.Matricula); + var IDUnidade = parseInt(fields.IDUnidade); + var IDAula = parseInt(fields.IDAula) || 0; + var IDExercicio = parseInt(fields.IDExercicio); + + IdiomaZoe = MatriculasPtBr.includes(Matricula) ? "pt-BR" : "en-US"; + + var CaminhoArquivo = ''; + + try { + CaminhoArquivo = files.Arquivo.path; + } catch (e) { + console.log('Sem audio na entrada'); + } + + // CRIA VARIAVEL COM A DATA ATUAL PARA RENOMEAR O ARQUIVO COM A IDENTIFICACAO DO ALUNO + let date_ob = new Date(); + let DataHoje = + date_ob.getDate() + + '-' + + (date_ob.getMonth() + 1) + + '-' + + date_ob.getFullYear() + + '-' + + date_ob.getHours() + + '-' + + date_ob.getMinutes() + + '-' + + date_ob.getSeconds(); + var NomeArquivo = + Matricula + '_' + IDUnidade + '_' + IDAula + '_' + DataHoje + '.mp3'; + + if (Modo == 0) { + // CONVERSACAO LIVRE + console.log('Conversação Livre'); + let SessaoID = Matricula + '' + IDUnidade; + if (Mensagem == '') { + ProcessarAudioEntrada( + CaminhoArquivo, + NomeArquivo, + Modo, + function (Pergunta, Entendeu) { + if (Entendeu) { + let ComandoAluno = VerificaComandoAluno(Pergunta); + if (ComandoAluno == ComandoOpenConfigMode) { + // ENTRANDO NO MODO CONFIGURACAO + EnviaResposta( + true, + FraseEnterSetupMode, + NomeArquivo, + res, + FraseEnterSetupMode, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + 2, + 0, + '' + ); + } else if (ComandoAluno == ComandoOpenRepeatMode) { + // ENTRANDO NO MODO REPETICAO + EnviaResposta( + true, + FraseEnterRepeatMode, + NomeArquivo, + res, + FraseEnterRepeatMode, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + 4, + 0, + '' + ); + } else { + // SEM COMANDOS + EnviaPerguntaChatBot(Pergunta, SessaoID, function (Resposta) { + TrataRespostaChatBot(Resposta, function (ResTratada) { + AtualizarEtapa( + false, + Matricula, + IDUnidade, + IDAula, + Ordem, + Pergunta, + Resposta, + '', + 'Sim', + '' + ); + + EnviaResposta( + true, + ResTratada, + NomeArquivo, + res, + ResTratada, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + }); + }); + console.log('resposta do chatbot --- RecognizeAudio'); + } + } else { + // NAO ENTENDEU A PERGUNTA + const Frase = EscolheFraseNaoEntendeu(); + EnviaResposta( + true, + Frase, + NomeArquivo, + res, + Frase, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + } + ); + } else { + EnviaPerguntaChatBot(Mensagem, SessaoID, function (Resposta) { + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + Resposta, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Mensagem, + 0, + 1, + 0, + 1, + 1, + Modo, + '' + ); + }); + console.log('resposta do chatbot --- RecognizeAudio'); + } + } else if (Modo == 1) { + // CONVERSACAO DIRIGIDA + logData('Conversação Dirigida'); + const SQL = MontaSQLChatTime(ChatTimeID, Ordem, Seq); + mysqlConnection.query(SQL, function (error, ChatTimeDialog, fields) { + if (!error && ChatTimeDialog && ChatTimeDialog.length > 0) { + logData('Consulta realizada'); + // FRASE QUE QUEM FALA E A ZOE, LOGO, NAO PROCESSA AUDIO DE ENTRADA + if (ChatTimeDialog[0]['zoetalking'] == 1) { + Ordem = ChatTimeDialog[0]['ProximaOrdem']; + VerificaVariaveisFrase( + ChatTimeDialog[0]['idzoechattimedialog'], + ChatTimeDialog[0]['phrase'], + ChatTimeDialog[0]['phrase'], + Matricula, + IDUnidade, + false, + function (FraseSubstituida) { + logData('Variáveis trocadas'); + //console.log(ChatTimeDialog[0]['img']); + EnviaResposta( + true, + FraseSubstituida, + NomeArquivo, + res, + RemoveVariaveisFrase(ChatTimeDialog[0]['ExemploResposta']), + 0, + ChatTimeDialog[0]['Final'], + 100, + 1, + ChatTimeDialog[0]['speed'], + ChatTimeDialog[0]['phrase'], + Ordem, + ChatTimeDialog[0]['zoetalking'], + ChatTimeDialog[0]['ProximoZoeTalking'], + ChatTimeDialog[0]['idzoevoices'], + ChatTimeDialog[0]['sub'], + Modo, + ChatTimeDialog[0]['seq_dir'], + ChatTimeDialog[0]['img'] + ); + } + ); + } else { + // FRASE QUE QUEM FALA E O ALUNO, LOGO, PROCESSA AUDIO DE ENTRADA + logData('Processar audio de entrada'); + ProcessarAudioEntrada( + CaminhoArquivo, + NomeArquivo, + Modo, + function (TextoAluno, Entendeu) { + logData('Audio processado'); + //console.log(TextoAluno); + + // VERIFICA SE O ALUNO ESTA DANDO ALGUM COMANDO DE SISTEMA + let ComandoAluno = VerificaComandoAluno(TextoAluno); + logData('Comando verificado: ' + ComandoAluno); + if (Entendeu && ComandoAluno != '') { + if (ComandoAluno == ComandoRepetirFrase) { + // SE O ALUNO ESTIVER PEDINDO PRA ZOE REPETIR A PERGUNTA ANTERIOR + logData('REPETINDO'); + VerificaVariaveisFrase( + ChatTimeDialog[0]['idzoechattimedialog'], + ChatTimeDialog[0]['PerguntaAnterior'], + ChatTimeDialog[0]['PerguntaAnterior'], + Matricula, + IDUnidade, + false, + function (FraseSubstituida) { + logData('Variáveis da frase verificadas'); + EnviaResposta( + true, + 'I said, ' + FraseSubstituida, + NomeArquivo, + res, + ChatTimeDialog[0]['phrase'], + Vezes, + ChatTimeDialog[0]['Final'], + 100, + 1, + ChatTimeDialog[0]['speed'], + ChatTimeDialog[0]['phrase'], + Ordem, + ChatTimeDialog[0]['zoetalking'], + 0, + ChatTimeDialog[0]['idzoevoices'], + ChatTimeDialog[0]['sub'], + Modo, + ChatTimeDialog[0]['seq'], + ChatTimeDialog[0]['img'] + ); + } + ); + } else if (ComandoAluno == ComandoAjuda) { + // SE O ALUNO ESTIVER PEDINDO PRA ZOE AJUDAR COM A FRASE + logData('EXPLICACAO'); + const FraseExplicacao = + ChatTimeDialog[0]['Explan'] == '' || + !ChatTimeDialog[0]['Explan'] + ? 'Try saying ' + ChatTimeDialog[0]['phrase'] + : ChatTimeDialog[0]['Explan']; + const En = + ChatTimeDialog[0]['Explan'] == '' || + !ChatTimeDialog[0]['Explan'] + ? 1 + : ChatTimeDialog[0]['idzoevoices_ex']; + EnviaResposta( + true, + FraseExplicacao, + NomeArquivo, + res, + FraseExplicacao, + Vezes, + 0, + 100, + 1, + ChatTimeDialog[0]['speed'], + TextoAluno, + Ordem, + 1, + 0, + En, + 1, + Modo, + ChatTimeDialog[0]['seq'], + ChatTimeDialog[0]['img'] + ); + } else { + // OUTRO COMANDO QUALQUER + EnviaResposta( + true, + FraseComandoIndisponivel, + NomeArquivo, + res, + FraseComandoIndisponivel, + Vezes, + 0, + 100, + 1, + Velocidade, + TextoAluno, + Ordem, + 1, + 0, + 1, + 1, + Modo, + Seq, + '' + ); + } + } else if (!Entendeu) { + logData('NAO ENTENDEU'); + Vezes++; + + let Resposta = EscolheFraseNaoEntendeu(); + + AtualizarEtapa( + false, + Matricula, + IDUnidade, + IDAula, + Ordem, + TextoAluno, + Resposta, + ChatTimeDialog[0]['phrase'], + 'Não', + 'actualItem' + ); + + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + RemoveVariaveisFrase(ChatTimeDialog[0]['phrase']), + Vezes, + ChatTimeDialog[0]['Final'], + 0, + 0, + ChatTimeDialog[0]['speed'], + TextoAluno, + Ordem, + ChatTimeDialog[0]['zoetalking'], + 0, + ChatTimeDialog[0]['idzoevoices'], + ChatTimeDialog[0]['sub'], + Modo, + ChatTimeDialog[0]['seq'], + ChatTimeDialog[0]['img'] + ); + } + // SE O ALUNO ESTIVER RESPONDENDO A PERGUNTA ANTERIOR + else { + logData('PROCESSANDO'); + mysqlConnection.query( + `select sentence, seq_dir from zoechattimesentences where idzoechattimedialog in (select distinct idzoechattimedialog from zoechattimedialog where idzoechattime = ${ChatTimeID} and ordem = ${Ordem});`, + function (error, Sentencas, fields) { + logData('Consulta de sentenças realizada'); + VerificaPronunciaUsuario( + Sentencas, + TextoAluno, + ChatTimeDialog[0]['percent'], + function (Porcentagem, Seq_Dir) { + logData('Pronúncia verificada'); + let Resposta = ''; + let ExResposta = ''; + let Validou = 0; + let Final = 0; + if (Porcentagem >= ChatTimeDialog[0]['percent']) { + // REQUISITAR A PROXIMA FRASE + const SQL = MontaSQLChatTime( + ChatTimeID, + ChatTimeDialog[0]['ProximaOrdem'], + Seq_Dir + ); + mysqlConnection.query( + SQL, + function (error, ChatTimeDialogRes, fields) { + logData( + 'Consulta da próxima frase realizada' + ); + Ordem = ChatTimeDialogRes[0]['ProximaOrdem']; + Final = ChatTimeDialogRes[0]['Final']; + Resposta = ChatTimeDialogRes[0]['phrase']; + ExResposta = RemoveVariaveisFrase( + ChatTimeDialogRes[0]['ExemploResposta'] + ); + Seq_Dir = ChatTimeDialogRes[0]['seq_dir']; + Vezes = 0; + Validou = 1; + + AtualizarEtapa( + true, + Matricula, + IDUnidade, + IDAula, + Ordem, + TextoAluno, + Resposta, + ExResposta, + 'Sim', + 'actualItem' + ); + + VerificaVariaveisFrase( + ChatTimeDialog[0]['idzoechattimedialog'], + TextoAluno, + ChatTimeDialog[0]['phrase'], + Matricula, + IDUnidade, + true, + function (FraseSubstituidaAluno) { + VerificaVariaveisFrase( + ChatTimeDialog[0][ + 'idzoechattimedialog' + ], + TextoAluno, + Resposta, + Matricula, + IDUnidade, + false, + function (FraseSubstituidaZoe) { + EnviaResposta( + Resposta == null ? false : true, + FraseSubstituidaZoe, + NomeArquivo, + res, + ExResposta, + Vezes, + Final, + Porcentagem, + Validou, + VelocidadePadrao, + TextoAluno, + Ordem, + ChatTimeDialogRes[0]['zoetalking'], + ChatTimeDialogRes[0][ + 'ProximoZoeTalking' + ], + ChatTimeDialogRes[0]['idzoevoices'], + ChatTimeDialogRes[0]['sub'], + Modo, + Seq_Dir, + ChatTimeDialogRes[0]['img'] + ); + } + ); + } + ); + } + ); + } else { + logData( + 'Não atingiu a porcentagem mínima: ' + + Porcentagem + + ' de ' + + ChatTimeDialog[0]['percent'] + ); + Resposta = EscolheFraseNaoEntendeu(); + ExResposta = RemoveVariaveisFrase( + ChatTimeDialog[0]['phrase'] + ); + Vezes++; + Validou = 0; + Final = 0; + + AtualizarEtapa( + false, + Matricula, + IDUnidade, + IDAula, + Ordem, + TextoAluno, + Resposta, + ExResposta, + 'Não', + 'actualItem' + ); + + EnviaResposta( + Resposta == null ? false : true, + Resposta, + NomeArquivo, + res, + ExResposta, + Vezes, + Final, + Porcentagem, + Validou, + VelocidadePadrao, + TextoAluno, + Ordem, + ChatTimeDialog[0]['zoetalking'], + 0, + ChatTimeDialog[0]['idzoevoices'], + ChatTimeDialog[0]['sub'], + Modo, + ChatTimeDialog[0]['seq'], + ChatTimeDialog[0]['img'] + ); + } + } + ); + } + ); + } + } + ); + } + } else { + console.log('Erro ao requisitar ChatTime'); + console.log(error); + console.log('Consulta:'); + console.log(SQL); + EnviaResposta( + true, + FraseServerDown, + NomeArquivo, + res, + '', + Vezes, + 0, + 0, + 0, + VelocidadePadrao, + '', + Ordem, + 1, + 1, + 1, + 1, + Modo, + Seq, + '' + ); + } + }); + } else if (Modo == 2) { + // MODO CONFIGURACAO + console.log('Modo Configuração'); + ProcessarAudioEntrada( + CaminhoArquivo, + NomeArquivo, + Modo, + function (Pergunta, Entendeu) { + if (Entendeu) { + let ComandoAluno = VerificaComandoAluno(Pergunta); + if (ComandoAluno == ComandoCloseConfigMode) { + // SAINDO DO MODO CONFIGURACAO + EnviaResposta( + true, + FraseExitSetupMode, + NomeArquivo, + res, + FraseExitSetupMode, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + '' + ); + } else { + // SEM COMANDOS DO ALUNO + ModoConfiguracao( + Pergunta, + NomeArquivo, + res, + Matricula, + IDUnidade + ); + } + } else { + EnviaResposta( + true, + EscolheFraseNaoEntendeu(), + NomeArquivo, + res, + FraseExemploConfig, + 0, + 0, + 0, + 0, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 0, + Modo, + 0, + '' + ); + } + } + ); + } else if (Modo == 3) { + // MODO EXERCICIO DE PRONUNCIA + console.log('Exercício de Pronúncia'); + // SEM ARQUIVO DE AUDIO, LOGO, A ZOE IRA PRONUNCIAR A PERGUNTA + const SQL = `select + ex.description, + eq.* + from exercisequestions eq + inner join exercises ex on ex.idexercises = eq.idexercises + where ex.idexercises = ${IDExercicio};`; + mysqlConnection.query(SQL, function (error, Questoes, fields) { + if (!error && Questoes && Questoes.length > 0) { + if (Ordem > Questoes.length - 1 || Ordem < 0) { + console.log(SQL); + console.log('Ordem: ' + Ordem); + console.log('Questoes: ' + Questoes.length); + EnviaResposta( + true, + 'Trying again', + NomeArquivo, + res, + '', + 0, + 0, + 0, + 0, + VelocidadePadrao, + '', + 0, + 1, + 1, + 1, + 1, + Modo, + 0, + '' + ); + return; + } + let Enunciado = Questoes[Ordem]['description']; + let Velocidade = + Questoes[Ordem]['content'].split(Separador)[1] || + VelocidadePadrao; + let Coerencia = + Questoes[Ordem]['content'].split(Separador)[2] || CoerenciaPadrao; + let ExResposta = Questoes[Ordem]['content'].split(Separador)[0]; + let Pergunta = + (Ordem == 0 && Vezes == 0 ? Enunciado + '. ' : '') + ExResposta; + if (CaminhoArquivo == '' || Mensagem != '') { + // SEM ARQUIVO DE AUDIO, LOGO, A ZOE IRA PRONUNCIAR O EXERCICIO + EnviaResposta( + true, + Pergunta, + NomeArquivo, + res, + ExResposta, + 0, + 0, + Coerencia, + 1, + Velocidade, + '', + Ordem, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } else { + // COM ARQUIVO DE AUDIO, LOGO, A ZOE IRA PROCESSAR O AUDIO DO ALUNO + ProcessarAudioEntrada( + CaminhoArquivo, + NomeArquivo, + Modo, + function (TextoAluno, Entendeu) { + // VERIFICA SE O ALUNO ESTA DANDO ALGUM COMANDO DE SISTEMA + let ComandoAluno = VerificaComandoAluno(TextoAluno); + if (Entendeu && ComandoAluno != '') { + if (ComandoAluno == ComandoRepetirFrase) { + // SE O ALUNO ESTIVER PEDINDO PRA ZOE REPETIR A PERGUNTA ANTERIOR + console.log('REPETINDO'); + EnviaResposta( + true, + 'I said, ' + Pergunta, + NomeArquivo, + res, + Pergunta, + Vezes, + 0, + 100, + 1, + Velocidade, + TextoAluno, + Ordem, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } else { + // OUTRO COMANDO QUALQUER + EnviaResposta( + true, + FraseComandoIndisponivel, + NomeArquivo, + res, + FraseComandoIndisponivel, + Vezes, + 0, + 100, + 1, + Velocidade, + TextoAluno, + Ordem, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + } else { + let Frase = { sentence: ExResposta, seq_dir: 0 }; + VerificaPronunciaUsuario( + [Frase], + TextoAluno, + Coerencia, + function (Porcentagem) { + let Resposta = ''; + let Validou = 0; + let Final = 0; + let IndexQuestao = Ordem; + if (Entendeu && Porcentagem >= Coerencia) { + Final = Ordem == Questoes.length - 1 ? 1 : 0; + if (Final == 1) Resposta = FraseFinal; + else { + Ordem++; + Resposta = + Questoes[Ordem]['content'].split(Separador)[0]; + ExResposta = + Questoes[Ordem]['content'].split(Separador)[0]; + } + Validou = 1; + Vezes = 0; + } else { + Resposta = "Try again saying: '" + ExResposta + "'"; + Validou = 0; + Final = 0; + Vezes++; + } + if (Entendeu) { + AtualizarEtapa( + true, + Matricula, + IDUnidade, + IDAula, + Ordem, + Pergunta, + Resposta, + ExResposta, + 'Sim', + 'actualAnswer' + ); + mysqlConnection.query( + `insert into exerciseanswers (idexercisequestions, hasmedia, content, iscorrect, orientation) values (?, 0, ?, ?, 0);`, + [ + Questoes[IndexQuestao]['idexercisequestions'], + TextoAluno, + Validou, + ], + function (errAnswer, resAnswer, fieAnswer) { + if (errAnswer) console.log(errAnswer); + let date_answered = + date_ob.getDate() + + '/' + + (date_ob.getMonth() + 1) + + '/' + + date_ob.getFullYear(); + mysqlConnection.query( + `select idusergivenanswers from usergivenanswers order by idusergivenanswers desc limit 1;`, + function (errUG, resUG, fieUG) { + mysqlConnection.query( + `insert into usergivenanswers (idusergivenanswers, idusers, idexerciseanswers, date_answered, fixed, idclasses, idunits) values (?, ?, ?, ?, 1, ?, ?);`, + [ + resUG[0]['idusergivenanswers'], + Matricula, + resAnswer['insertId'], + date_answered, + IDAula, + IDUnidade, + ], + function ( + errUserAnswer, + resUserAnswer, + fieUserAnswer + ) { + if (errUserAnswer) + console.log(errUserAnswer); + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + ExResposta, + Vezes, + Final, + Porcentagem, + Validou, + Velocidade, + TextoAluno, + Ordem, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + ); + } + ); + } + ); + } else { + AtualizarEtapa( + false, + Matricula, + IDUnidade, + IDAula, + Ordem, + Pergunta, + Resposta, + ExResposta, + 'Não', + 'actualAnswer' + ); + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + ExResposta, + Vezes, + Final, + Porcentagem, + Validou, + Velocidade, + TextoAluno, + Ordem, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + } + ); + } + } + ); + } + } else { + console.log('Erro ao requisitar Exercicio de Pronuncia'); + console.log(error); + console.log('Consulta:'); + console.log(SQL); + EnviaResposta( + true, + FraseServerDown, + NomeArquivo, + res, + '', + Vezes, + 0, + 0, + 0, + VelocidadePadrao, + '', + Ordem, + 1, + 1, + 1, + 1, + Modo, + 0, + '' + ); + } + }); + } else if (Modo == 4) { + // MODO DE REPETICAO + console.log('MODO DE REPETICAO'); + ProcessarAudioEntrada( + CaminhoArquivo, + NomeArquivo, + Modo, + function (Pergunta, Entendeu) { + if (Entendeu) { + let ComandoAluno = VerificaComandoAluno(Pergunta); + if (ComandoAluno == ComandoCloseRepeatMode) { + // SAINDO DO MODO REPETICAO + EnviaResposta( + true, + FraseExitRepeatMode, + NomeArquivo, + res, + FraseExitRepeatMode, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + '' + ); + } else { + // SEM COMANDOS + EnviaResposta( + true, + Pergunta, + NomeArquivo, + res, + Pergunta, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + } else { + // NAO ENTENDEU A PERGUNTA + const Frase = EscolheFraseNaoEntendeu(); + EnviaResposta( + true, + Frase, + NomeArquivo, + res, + Frase, + 0, + 0, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 1, + Modo, + 0, + '' + ); + } + } + ); + } + }); + }); + + function AtualizarEtapa( + AtualizaBanco, + idusers, + idunits, + idclasses, + ordem, + Entendeu, + Resposta, + ExResposta, + Validou, + Campo + ) { + if (AtualizaBanco) { + logData('Atualizando etapa'); + mysqlConnection.query( + `update stepclass set ${Campo} = ${ordem} where idusers = ${idusers} and idunits = ${idunits} and idclasses = ${idclasses};`, + function (error, results, fields) { + if (!error) { + logData( + `Etapa atualizada com sucesso - Matrícula: ${idusers}, Unidade: ${idunits}, Aula: ${idclasses}` + ); + } else { + logData( + `Erro ao atualizar etapa - Matrícula: ${idusers}, Unidade: ${idunits}, Aula: ${idclasses}` + ); + } + logData( + `Validou: "${Validou}", Zoe Entendeu: "${Entendeu}", Resposta Zoe: "${Resposta}", Exemplo Resposta: "${ExResposta}"` + ); + } + ); + } else { + logData( + `Validou: "${Validou}", Zoe Entendeu: "${Entendeu}", Resposta Zoe: "${Resposta}", Exemplo Resposta: "${ExResposta}"` + ); + } + } + + function VerificaComandoAluno(TextoAluno) { + let Comando = ''; + + if (TextoAluno.includes(ComandoRepetirFrase)) Comando = ComandoRepetirFrase; + else if (TextoAluno.includes(ComandoOpenConfigMode)) + Comando = ComandoOpenConfigMode; + else if (TextoAluno.includes(ComandoCloseConfigMode)) + Comando = ComandoCloseConfigMode; + else if (TextoAluno.includes(ComandoOpenRepeatMode)) + Comando = ComandoOpenRepeatMode; + else if (TextoAluno.includes(ComandoCloseRepeatMode)) + Comando = ComandoCloseRepeatMode; + else if (TextoAluno.includes(ComandoAjuda)) Comando = ComandoAjuda; + + return Comando; + } + + function ProcessarAudioEntrada(CaminhoArquivo, NomeArquivo, Modo, callback) { + const fs = require('fs'); + const CaminhoArquivoServidor = + Variables('src_media') + 'audioZoe2/' + NomeArquivo; + fs.rename(CaminhoArquivo, CaminhoArquivoServidor, function (err) { + if (err) throw err; + logData('Arquivo renomeado'); + const shell = require('shelljs'); + + mysqlConnection.query( + 'select STTmode, PythonVersion from config;', + function (error, Config, fields) { + logData('Consulta config realizada'); + const STTmode = Config[0]['STTmode']; + const PythonVersion = Config[0]['PythonVersion']; + // CONVERTER O .wav PARA TEXTO + var audioTotext = null; + + if (STTmode == 1) { + // GOOGLE SPEECH RECOGNITION NODE + logData('Google Speech Recognition'); + AudioParaTexto(CaminhoArquivoServidor, function (Texto) { + logData('Response do Google recebido: ' + Texto); + VerificaTextoAudio(Texto, function (Pergunta, Entendeu) { + logData('Texto verificado'); + callback(Pergunta, Entendeu); + //uploadFileToBucket(CaminhoArquivoServidor); + }); + }); + } else if (STTmode == 2) { + // GOOGLE SPEECH RECOGNITION FREE + console.log('inicio do google speech free --- RecognizeAudio'); + let Comando = `${PythonVersion} ${Variables( + 'src_media' + )}assets/audio_to_text2.py ${NomeArquivo}`; + audioTotext = shell.exec(Comando); + VerificaTextoAudio( + audioTotext.stdout, + function (Pergunta, Entendeu) { + callback(Pergunta, Entendeu); + //uploadFileToBucket(CaminhoArquivoServidor); + console.log('inicio do google speech free --- RecognizeAudio'); + } + ); + } else if (STTmode == 3) { + // GOOGLE SPEECH RECOGNITION PYTHON + let Comando = `export GOOGLE_APPLICATION_CREDENTIALS="/var/www/zoeGoogleCloudSpeech.json"; ${PythonVersion} ${Variables( + 'src_media' + )}assets/speech_cloud.py ${NomeArquivo}`; + audioTotext = shell.exec(Comando); + VerificaTextoAudio( + audioTotext.stdout, + function (Pergunta, Entendeu) { + callback(Pergunta, Entendeu); + //uploadFileToBucket(CaminhoArquivoServidor); + } + ); + } else if (STTmode == 4) { + // WATSON + + shell.exec( + `ffmpeg -loglevel panic -i ${CaminhoArquivoServidor} -acodec pcm_s16le -ar 44100 ${ + CaminhoArquivoServidor.split('.')[0] + }.wav`, + function (Sucesso) { + const fs = require('fs'); + const SpeechToTextV1 = require('ibm-watson/speech-to-text/v1'); + const { IamAuthenticator } = require('ibm-watson/auth'); + + const speechToText = new SpeechToTextV1({ + authenticator: new IamAuthenticator({ apikey: STTWatsonKey }), + serviceUrl: STTWatsonService, + }); + + const params = { + audio: fs.createReadStream( + CaminhoArquivoServidor.split('.')[0] + '.wav' + ), + contentType: 'audio/l16; rate=44100', + }; + + speechToText + .recognize(params) + .then((response) => { + let Transcript = JSON.stringify(response.result, null, 2); + let TextoAudio = ''; + let Confidence = ''; + if (JSON.parse(Transcript).results.length > 0) { + TextoAudio = + JSON.parse(Transcript).results[0].alternatives[0] + .transcript; + Confidence = + JSON.parse(Transcript).results[0].alternatives[0] + .confidence; + } + //console.log("Transcript: " + TextoAudio + " - Confidence: " + Confidence); + VerificaTextoAudio( + TextoAudio, + function (Pergunta, Entendeu) { + callback(Pergunta, Entendeu); + } + ); + }) + .catch((err) => { + console.log(err); + VerificaTextoAudio('', function (Pergunta, Entendeu) { + callback(Pergunta, Entendeu); + //uploadFileToBucket(CaminhoArquivoServidor); + }); + }); + } + ); + } + } + ); + }); + } + + async function AudioParaTexto(CaminhoArquivo, callback) { + // HEADERS DE UM WAV EM: http://soundfile.sapp.org/doc/WaveFormat/ + const speech = require('@google-cloud/speech'); + const fs = require('fs'); + const client = new speech.SpeechClient({ + projectId: 'zoerobot-1581961113901', + keyFilename: '/var/www/zoeGoogleCloudSpeech.json', + }); + + const file = fs.readFileSync(CaminhoArquivo); + const audioBytes = file.toString('base64'); + const channels = file[22]; + const RateHertz = parseInt( + file[24].toString() + + file[25].toString() + + file[26].toString() + + file[27].toString() + ); + + const audio = { + content: audioBytes, + }; + const config = { + encoding: 'LINEAR16', + //sampleRateHertz: RateHertz, + languageCode: IdiomaZoe, + audioChannelCount: channels, + }; + const request = { + audio: audio, + config: config, + }; + + const [response] = await client.recognize(request); + const transcription = response.results + .map((result) => result.alternatives[0].transcript) + .join('\n'); + //console.log(`Transcription: ${transcription}`); + callback(transcription); + } + + function VerificaTextoAudio(Pergunta, callback) { + // Remove o \r\n do final da frase + for (let i = 0; i < 2; i++) { + if ( + Pergunta[Pergunta.length - 1] == '\r' || + Pergunta[Pergunta.length - 1] == '\n' + ) { + Pergunta = Pergunta.substring(0, Pergunta.length - 1); + } + } + + //console.log("Audio para Texto: " + Pergunta); + + let Entendeu = true; + + if ( + Pergunta.includes( + 'Google Speech Recognition could not understand audio' + ) || + Pergunta.includes( + 'Could not request results from Google Speech Recognition service' + ) || + Pergunta == '' + ) { + Entendeu = false; + Pergunta = TextoNaoEntendeu; + } + + callback(Pergunta, Entendeu); + } + + function VerificaPronunciaUsuario(ListaSentencas, TextoAluno, Coerencia, callback) { + logData('Verificando pronúncia do usuário'); + + for (let i = 0; i < ListaSentencas.length; i++) { + ListaSentencas[i]['sentence'] = ReplaceAll( + ListaSentencas[i]['sentence'].toLowerCase(), + [',', '-', '_', '!', '?', "'", '.'], + ['', '', '', '', '', '', ''], + 15 + ); + } + + TextoAluno = ReplaceAll( + TextoAluno.toLowerCase(), + [',', '-', '_', '!', '?', "'", '.'], + ['', '', '', '', '', '', ''], + 15 + ); + + let Porcentagem = 0; + let IndexSentenca = 0; + + mysqlConnection.query( + 'select checkSentence, PythonVersion from config;', + function (error, Config, fields) { + logData('Consulta config realizada'); + const CheckSentence = Config[0]['checkSentence']; + const PythonVersion = Config[0]['PythonVersion']; + + loopCheckSentence(0, 0, IndexSentenca, ListaSentencas, TextoAluno, PythonVersion, CheckSentence, Coerencia, function(percent, index) { + Porcentagem = percent; + IndexSentenca = index; + callback(Porcentagem, ListaSentencas[IndexSentenca]['seq_dir']); + }); + + /*runPythonScript(`${PythonVersion} ${Variables('src_media')}assets/${CheckSentence} \"${ + ListaSentencas[IndexSentenca]['sentence'] + }\" \"${TextoAluno}\"`).then(percent => { + logData('Percentual de coerencia: ' + percent); + Porcentagem = percent; + callback(Porcentagem, ListaSentencas[IndexSentenca]['seq_dir']); + });*/ + + } + ); + } + + function loopCheckSentence(Porcentagem, Index, IndexSentenca, ListaSentencas, TextoAluno, PythonVersion, CheckSentence, Coerencia, callback) { + if (IndexSentenca < ListaSentencas.length) { + runPythonScript(`${PythonVersion} ${Variables('src_media')}assets/${CheckSentence} \"${ + ListaSentencas[IndexSentenca]['sentence'] + }\" \"${TextoAluno}\"`).then(percent => { + logData('Teste ' + (IndexSentenca + 1) + ' de ' + ListaSentencas.length + ' - Coerencia ' + percent + ' de ' + Coerencia); + if (percent >= Coerencia) { + Porcentagem = percent; + Index = IndexSentenca; + callback(Porcentagem, Index); + } + else { + if (percent > Porcentagem) { + Porcentagem = percent; + Index = IndexSentenca; + } + IndexSentenca++; + loopCheckSentence(Porcentagem, Index, IndexSentenca, ListaSentencas, TextoAluno, PythonVersion, CheckSentence, Coerencia, callback); + } + }); + } + else { + callback(Porcentagem, Index); + } + } + + async function runPythonScript(script) { + const shell = require('shelljs'); + return new Promise((resolve, reject) => { + shell.exec(script, function (code, stdout, stderr) { + if (code === 0) { + const percent = parseFloat(stdout); + resolve(percent); + } else { + reject(stderr); + } + } + ); + }); + } + + function CompareStrings(str1, str2) { + let pairs1 = WordLetterPairs(str1.toLowerCase()); + let pairs2 = WordLetterPairs(str2.toLowerCase()); + + let intersection = 0; + let union = pairs1.length + pairs2.length; + + for (let i = 0; i < pairs1.length; i++) { + for (let j = 0; j < pairs2.length; j++) { + if (pairs1[i] == pairs2[j]) { + intersection++; + pairs2.splice(j, 1); + break; + } + } + } + return (2.0 * intersection) / union; + } + + function WordLetterPairs(str) { + let AllPairs = []; + let Words = str.split(' '); + for (let w = 0; w < Words.length; w++) { + if (Words[w]) { + let PairsInWord = LetterPairs(Words[w]); + for (let p = 0; p < PairsInWord.length; p++) { + AllPairs.push(PairsInWord[p]); + } + } + } + + return AllPairs; + } + + function LetterPairs(str) { + let numPairs = str.length - 1; + let pairs = []; + for (let i = 0; i < numPairs; i++) { + pairs[i] = str.substring(i, 2); + } + + return pairs; + } + + function RemoveVariaveisFrase(Frase) { + let NovaFrase = ''; + if (Frase && Frase.includes('+')) { + let Trechos = Frase.split('+'); + for (let i = 0; i < Trechos.length; i++) { + if (i % 2 == 0) NovaFrase += Trechos[i]; + else NovaFrase += '_____'; + } + } else { + NovaFrase = Frase; + } + + return NovaFrase; + } + + function VerificaVariaveisFrase( + idzoechattimedialog, + FraseEntrada, + FraseComparada, + Matricula, + IDUnidade, + AlunoFalando, + callback + ) { + logData('Verificando se existem variáveis na frase'); + //FraseEntrada = ReplaceAll(FraseEntrada.toLowerCase(), [",", "-", "_", "!", "?", "'"], ["", "", "", "", "", ""], 15); + //FraseComparada = ReplaceAll(FraseComparada.toLowerCase(), [",", "-", "_", "!", "?", "'"], ["", "", "", "", "", ""], 15); + let FraseSubstituida = ''; + //console.log(FraseEntrada); + //console.log(FraseComparada); + // SE HOUVER VARIAVEL NA FRASE + if (FraseComparada && FraseComparada.includes('+')) { + let PalavrasFrase = FraseComparada.split(' '); + let VariaveisFrase = []; + let WhereVariables = '('; + for (let i = 0; i < PalavrasFrase.length; i++) { + if (PalavrasFrase[i].includes('+')) { + const Variavel = PalavrasFrase[i].split('+')[1]; + VariaveisFrase.push({ + idalexavariables: 0, + description: Variavel, + valuecli: 'UNKNOW', + }); + if (WhereVariables != '(') WhereVariables += ','; + WhereVariables += "'" + Variavel + "'"; + } + } + WhereVariables += ')'; + + //console.log(WhereVariables); + + const sqlVariaveis = `select avr.description, auv.* from alexauservariables auv inner join alexavariables avr on avr.idalexavariables = auv.idalexavariables where auv.idusers = ${Matricula} and auv.idunits = ${IDUnidade} and avr.description in ${WhereVariables};`; + //console.log(sqlVariaveis); + mysqlConnection.query( + sqlVariaveis, + function (error, VariaveisEncontradas, fields) { + logData('Consulta de variáveis realizada'); + //console.log(VariaveisEncontradas); + + let Encontrou = false; + // EXISTEM DADOS GRAVADOS NO BANCO PARA AS VARIAVEIS CONSULTADAS + if (VariaveisEncontradas && VariaveisEncontradas.length > 0) { + Encontrou = true; + for (let i = 0; i < VariaveisEncontradas.length; i++) { + for (let o = 0; o < VariaveisFrase.length; o++) { + if ( + VariaveisFrase[o].description == + VariaveisEncontradas[i].description + ) { + VariaveisFrase[o].idalexavariables = + VariaveisEncontradas[i].idalexavariables; + VariaveisFrase[o].valuecli = VariaveisEncontradas[i].valuecli; + } + } + } + //console.log(VariaveisFrase); + } + + // ALUNO FALANDO SEUS DADOS QUE SERAO SALVOS NO BANCO + if (AlunoFalando) { + AtualizaValoresVariaveis( + !Encontrou, + idzoechattimedialog, + FraseEntrada, + VariaveisFrase, + Matricula, + IDUnidade, + function (NovoValor) { + logData('Variável atualizada: ' + NovoValor); + FraseSubstituida = FraseEntrada; + callback(FraseSubstituida); + } + ); + } + // ZOE BUSCANDO DADOS DO ALUNO PRA FALAR + else { + InsereValoresVariaveisFrase( + FraseComparada, + VariaveisFrase, + function (FraseTrocada) { + logData('Variável inserida na frase'); + FraseSubstituida = FraseTrocada; + callback(FraseSubstituida); + } + ); + } + } + ); + } + // NAO EXISTEM VARIAVEIS NA FRASE + else { + logData('Não existem variáveis na frase'); + FraseSubstituida = + !AlunoFalando && FraseComparada ? FraseComparada : FraseEntrada; + callback(FraseSubstituida); + } + } + + function InsereValoresVariaveisFrase(FraseEntrada, VariaveisFrase, callback) { + let FraseTrocada = FraseEntrada; + + for (let i = 0; i < VariaveisFrase.length; i++) { + FraseTrocada = ReplaceAll( + FraseTrocada, + ['+' + VariaveisFrase[i].description + '+'], + [VariaveisFrase[i].valuecli], + 5 + ); + } + + callback(FraseTrocada); + } + + function EnviaResposta( + CriarAudio, + Resposta, + NomeArquivo, + res, + ExemploResposta, + Vezes, + Final, + Coerencia, + Validou, + Velocidade, + ZoeEntendeu, + Ordem, + ZoeTalking, + ProximoZoeTalking, + VozIngles, + Legenda, + Modo, + Seq, + Img + ) { + logData('Enviar resposta'); + const shell = require('shelljs'); + + mysqlConnection.query( + 'select TTSmode, RMaudio, PythonVersion, extAudio, zoevoiceEn, zoevoicePt, zoevoiceEs from config;', + function (error, Config, fields) { + logData('Consulta config realizada'); + const TTSmode = Config[0]['TTSmode']; + const PythonVersion = Config[0]['PythonVersion']; + const ExtAudio = Config[0]['extAudio']; + const VozZoeEn = Config[0]['zoevoiceEn']; + const VozZoePt = Config[0]['zoevoicePt']; + const VozZoeEs = Config[0]['zoevoiceEs']; + + if (TTSmode == 1) { + // PICO2WAV + if (CriarAudio) { + // CONVERTE A RESPOSTA EM TEXTO PARA AUDIO + shell.exec( + `pico2wave --wave=${ + Variables('src_media') + + 'audioZoe2/' + + NomeArquivo.split('.')[0] + }.wav \"${Resposta} \"`, + function (Resultado) { + // CONVERTE O AUDIO .WAV PARA .MP3 + shell.exec( + `ffmpeg -i ${Variables('src_media')}audioZoe2/${ + NomeArquivo.split('.')[0] + }.wav ${Variables('src_media')} audioZoe2/${ + NomeArquivo.split('.')[0] + }_exit${ExtAudio} -loglevel quiet -stats`, + function (sucesso) { + // APAGA O AUDIO .WAV DO SERVIDOR + shell.exec( + `rm ${Variables('src_media')}audioZoe2/${ + NomeArquivo.split('.')[0] + }.wav` + ); + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + ); + } + ); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + } else if (TTSmode == 2) { + // PYTHON gTTS OP2 + if (CriarAudio) { + // CONVERTE A RESPOSTA EM TEXTO PARA AUDIO + shell.exec( + `${PythonVersion} ${Variables( + 'src_media' + )}assets/text_to_audio2.py \"${Resposta}\" ${NomeArquivo}`, + function (Sucesso) { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + RemoverEntrada, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + ); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + RemoverEntrada, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + } else if (TTSmode == 3) { + // WIDEO + if (CriarAudio) { + const request = require('request'); + var options = { + uri: 'https://texttospeechapi.wideo.co/api/wideo-text-to-speech', + method: 'POST', + json: { + data: { + text: Resposta, + speed: Velocidade - Vezes * 0.05, + voice: VozIngles == 1 ? VozZoeEn : VozZoePt, + }, + }, + }; + request(options, function (error, response, body) { + if (!error && response.statusCode == 200) { + let ComandoBaixar = `wget "${ + response['body']['result']['url'] + }" -O ${Variables('src_media')}audioZoe2/${ + NomeArquivo.split('.')[0] + }_exit.mp3 -q;`; + shell.exec(ComandoBaixar, function (Sucesso) { + if (ExtAudio == '.wav') { + shell.exec( + `ffmpeg -loglevel panic -i ${Variables( + 'src_media' + )}audioZoe2/${ + NomeArquivo.split('.')[0] + }_exit.mp3 ${Variables('src_media')}audioZoe2/${ + NomeArquivo.split('.')[0] + }_exit.wav`, + function (Sucesso) { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + ); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + }); + } + }); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + RemoverEntrada, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + } else if (TTSmode == 4) { + logData('TTS Amazon Polly'); + // AMAZON POLLY + const fs = require('fs'); + + // CONVERTE A RESPOSTA EM TEXTO PARA AUDIO + shell.exec( + `${PythonVersion} ${Variables( + 'src_media' + )}assets/polly_service.py \"${Resposta}\" "${Variables( + 'src_media' + )}audioZoe2/${NomeArquivo}_exit.mp3" "${ + IdiomaZoe == "pt-BR" ? VozZoePt : + VozIngles == 1 ? VozZoeEn : + VozIngles == 2 ? VozZoePt : + VozIngles == 3 ? VozZoeEs : + VozZoeEn + }"`, + function (Sucesso) { + logData('Texto convertido para audio'); + if (ExtAudio == '.wav') { + let fileDirectory = + Variables('src_media') + 'audioZoe2/' + NomeArquivo; + shell.exec( + 'lame --decode ' + + '"' + + fileDirectory + + '"' + + '_exit.mp3 ' + + '"' + + fileDirectory + + '"' + + '_exit.wav', + function (Sucesso) { + logData('Convertido wav para mp3'); + fs.chmodSync(fileDirectory + '_exit.wav', 0o777); + console.log('------|DEBUG|-------: Should have converted'); + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + ); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + } + ); + } else if (TTSmode == 5) { + // PYTHON gTTS OP1 + if (CriarAudio) { + // CONVERTE A RESPOSTA EM TEXTO PARA AUDIO + const textToaudio = spawn('python', [ + Variables('src_media') + 'assets/text_to_audio.py', + Resposta, + NomeArquivo, + ]); + textToaudio.stdout.on('data', function (data) { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + RemoverEntrada, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + }); + } else { + EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + RemoverEntrada, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + } else if (TTSmode == 6) { + // WATSON IBM + const fs = require('fs'); + let respostaFiltered = Resposta.replace('?', 'INT'); + respostaFiltered = respostaFiltered.replace('/', 'BAR'); + if ( + fs.existsSync( + Variables('src_media') + + 'audioZoe2/' + + respostaFiltered + + '_exit.wav' + ) + ) { + //file exists + EnviarDados( + res, + CriarAudio, + Resposta, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } else { + const TextToSpeechV1 = require('ibm-watson/text-to-speech/v1'); + const { IamAuthenticator } = require('ibm-watson/auth'); + + const textToSpeech = new TextToSpeechV1({ + authenticator: new IamAuthenticator({ apikey: watsonIMBKey }), + serviceUrl: watsonURLService, + }); + + const params = { + text: Resposta, + voice: VozIngles == 1 ? VozZoeEn : VozZoePt, + accept: 'audio/wav', + }; + console.log( + 'request body : ' + params[0] + ',' + params[1] + ',' + params[2] + ); + textToSpeech + .synthesize(params) + .then((response) => { + const audio = response.result; + return textToSpeech.repairWavHeaderStream(audio); + }) + .then((repairedFile) => { + fs.writeFileSync( + Variables('src_media') + + 'audioZoe2/' + + respostaFiltered + + '_exit.wav', + repairedFile + ); + console.log('audio.wav written with a corrected wav header'); + if (ExtAudio == '.mp3') { + shell.exec( + 'ffmpeg -loglevel panic -i ' + + Variables('src_media') + + 'audioZoe2/' + + respostaFiltered + + '_exit.wav ' + + Variables('src_media') + + 'audioZoe2/' + + respostaFiltered + + '_exit.mp3', + function (Sucesso) { + EnviarDados( + res, + CriarAudio, + respostaFiltered, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + ); + } else { + EnviarDados( + res, + CriarAudio, + respostaFiltered, + Vezes, + ExemploResposta, + Resposta, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ); + } + }) + .catch((err) => { + console.log(err); + }); + } + } + } + ); + } + + function EnviarDados( + res, + CriarAudio, + NomeArquivo, + Vezes, + ExemploResposta, + TextoAudio, + Final, + Coerencia, + Validou, + ZoeEntendeu, + Ordem, + ExtAudio, + ZoeTalking, + ProximoZoeTalking, + Legenda, + Modo, + Seq, + Img + ) { + logData('Finalizado, enviado response'); + res.send( + JSON.stringify({ + status: 200, + url_audio: CriarAudio + ? 'https://myrobotlab.com.br/audioZoe2/' + NomeArquivo + '_exit' + ExtAudio + : '', + TextoAudio: TextoAudio, + Vezes: Vezes, + ExemploResposta: ExemploResposta, + Final: Final, + Coerencia: Coerencia, + Validou: Validou, + ZoeEntendeu: ZoeEntendeu, + Ordem: Ordem, + Seq: Seq, + ZoeTalking: ZoeTalking, + ProximoZoeTalking: ProximoZoeTalking, + Legenda: Legenda, + Modo: Modo, + img: Img, + }) + ); + // EXCLUI O ARQUIVO DE AUDIO DE ENTRADA + //const shell = require('shelljs'); + //shell.exec('rm ' + Variables('src_media') + 'audioZoe2/' + NomeArquivo); + } + + /*function UploadFIleToS3(NomeArquivo){ + fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ + if (!err) { + uploadFileToBucket(data); + } else { + console.log(err); + } + }); + }*/ + + function EnviaPerguntaMitsuku(Pergunta, SessaoID, callback) { + // TROCA A PALAVRA ZOE POR MITSUKU + Pergunta = ReplaceAll(Pergunta, ['Zoe'], ['Mitsuku'], 10); + // ENVIA A PERGUNTA EM TEXTO PARA MITSUKU + const querystring = require('querystring'); + const request = require('request'); + var form = { + input: Pergunta, + botid: '9fa364f2fe345a10', // ID do bot (CONSTANTE) + custid: SessaoID, // ID do usuário falando com o bot, ex: b3dfe148ae499f98 + }; + var formData = querystring.stringify(form); + request( + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + uri: 'https://kakko.pandorabots.com/pandora/talk-xml', + body: formData, + method: 'POST', + }, + function (err, res2, body) { + var striptags = require('striptags'); + var Resposta = body; + try { + Resposta = body.split('')[1].split('')[0]; + } catch (e) {} + Resposta = decodeURI(Resposta); + Resposta = striptags(Resposta); + + RemoverTagsDoTexto( + Resposta, + ['xgallery.', 'xloadswf2.', 'xloadswf3.', 'xlink.', 'xnslink.'], + function (NewResposta) { + if (NewResposta.includes('Human Virus deletion program started')) + NewResposta = NewResposta.split( + 'Human Virus deletion program started' + )[0]; + + if ( + NewResposta.includes( + 'This is a list of the games I can play with you' + ) + ) + NewResposta = + NewResposta.split('.')[NewResposta.split('.').length - 1]; + + if ( + NewResposta.includes('<img') && + NewResposta.includes('/img>') + ) + NewResposta = + NewResposta.split('<P')[0] + NewResposta.split('/P>')[1]; + + if (NewResposta.includes('<P') && NewResposta.includes('/P>')) + NewResposta = + NewResposta.split('<P')[0] + NewResposta.split('/P>')[1]; + + NewResposta = ReplaceAll( + NewResposta, + ['Mitsuku', '<br>', '"'], + ['Zoe', ' ', '"'], + 15 + ); + + callback(NewResposta); + } + ); + } + ); + } + + router.get('/testGPT/:pergunta', (req, res) => { + var Pergunta = req.params.pergunta; + console.log('acesso 1'); + EnviaPerguntaGPT(Pergunta, function (Resposta) { + res.send(Resposta); + }); + }); + + function EnviaPerguntaGPT(Pergunta, callback) { + console.log('chatgpt'); + + // Verificar se a pergunta foi feita em inglês + //if (!isEnglish(Pergunta)) { + // callback('Sorry, I only understand English'); + // return; + //} + + Pergunta = Pergunta.toLowerCase(); + + Pergunta = ReplaceAll(Pergunta, ['Zoe'], ['ChatGPT'], 10); + const querystring = require('querystring'); + const request = require('request'); + var form = { + model: 'gpt-3.5-turbo', + messages: [ + { + role: 'user', + content: Pergunta, + }, + ], + }; + var formData = JSON.stringify(form); + request( + { + headers: { + 'Content-Type': 'application/json', + Authorization: + 'Bearer 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', + }, + uri: 'https://api.openai.com/v1/chat/completions', + body: formData, + method: 'POST', + }, + function (err, res2, body) { + //console.log(body); + var respostaGPT = JSON.parse(body); + var Resposta = respostaGPT['choices'][0]['message']['content']; + Resposta = ReplaceAll(Resposta, ['ChatGPT'], ['Zoe'], 10); + Resposta = ReplaceAll(Resposta, ['OpenAI'], ['MyRobot'], 10); + Resposta = ReplaceAll(Resposta, ['GPT-3'], ['Zoe'], 10); + Resposta = Resposta.replace(/\n/g, ' '); + console.log('Resposta: ' + Resposta); + + callback(Resposta); + } + ); + } + + function EnviaPerguntaRosie(Pergunta, callback) { + Pergunta = ReplaceAll(Pergunta, ['Zoe'], ['Rosie'], 10); + const querystring = require('querystring'); + const request = require('request'); + var form = { + botcust2: 'e007f413decb76eb', + message: Pergunta, + }; + var formData = querystring.stringify(form); + request( + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + uri: 'https://pandorabots.com/pandora/talk?botid=b16e613a3e341aa4', + body: formData, + method: 'POST', + }, + function (err, res2, body) { + var Resposta = body; + try { + Resposta = body.split('Rosie: ')[1].split('
')[0]; + } catch (e) {} + + Resposta = ReplaceAll(Resposta, ['Rosie'], ['Zoe'], 10); + + //console.log(Resposta); + + callback(Resposta); + } + ); + } + + function EnviaPerguntaCleverbot(Pergunta, callback) { + //Pergunta = ReplaceAll(Pergunta, ["Zoe"], ["Rosie"], 10); + const querystring = require('querystring'); + const request = require('request'); + var form = { + uc: 'UseOfficialCleverbotAPI', + in: encodeURI(Pergunta), + bot: 'c', + cbsid: 'WXI2AHQ82N', + xai: 'WXI,405312017,WXHNGDC4RJ1J', + ns: 99, + al: '', + dl: 'en', + flag: '', + user: '', + mode: 1, + alt: 0, + reac: '', + emo: '', + sou: 'website', + xed: '', + t: 5103, + }; + var formData = querystring.stringify(form); + request( + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + uri: 'https://www.cleverbot.com/webservicemin?uc=UseOfficialCleverbotAPI&out=I%27m%20Grant.&in=What%20is%20your%20name%3F&bot=c&cbsid=WXI2AHQ82N&xai=WXI,405312017,WXHNGDC4RJ1J&ns=99&al=&dl=en&flag=&user=&mode=1&alt=0&reac=&emo=&sou=website&xed=&t=5103&', + body: formData, + method: 'POST', + }, + function (err, res2, body) { + var Resposta = body; + //console.log(body); + //try { Resposta = body.split("Rosie: ")[1].split("
")[0]; } catch (e) { } + + //Resposta = ReplaceAll(Resposta, ["Rosie"], ["Zoe"], 10); + + callback(Resposta); + } + ); + } + + function ExcludeZoeAudios() {} + + function EnviaPerguntaKuki(Pergunta, SessaoID, callback) { + Pergunta = ReplaceAll(Pergunta, ['Zoe'], ['Kuki'], 10); + const querystring = require('querystring'); + const request = require('request'); + var form = { + input: Pergunta, + sessionid: SessaoID, + channel: 7, + botkey: + 'icH-VVd4uNBhjUid30-xM9QhnvAaVS3wVKA3L8w2mmspQ-hoUB3ZK153sEG3MX-Z8bKchASVLAo~', + client_name: 'kp17725cfe611', + }; + var formData = querystring.stringify(form); + request( + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + uri: 'https://icap.iconiq.ai/talk', + body: formData, + method: 'POST', + }, + function (err, res2, body) { + var Resposta = JSON.parse(body)['responses'][0]; + //console.log(Resposta); + + if (Resposta.includes('Image from ')) + Resposta = + Resposta.split('Image from ')[0] + Resposta.split('')[1]; + + if (Resposta.includes('') && Resposta.includes('')) + Resposta = + Resposta.split('')[0] + Resposta.split('')[1]; + + if (Resposta.includes('I can currently play these games:')) { + Resposta = Resposta.split('I can currently play these games:')[0]; + if (Resposta == '') Resposta = 'I would love to'; + } + + if ( + Resposta.includes( + '**What website, app or Discord server are you using to talk to me?' + ) + ) + Resposta = Resposta.replace( + '**What website, app or Discord server are you using to talk to me?', + '' + ); + + if ( + Resposta.includes('("status":"error", "message":"401 unauthorized")') + ) + Resposta = Resposta.replace( + '("status":"error", "message":"401 unauthorized")', + '' + ); + + // I can currently play these games: + + Resposta = ReplaceAll( + Resposta, + ['Kuki', 'Mitsuku', '<br>', '"'], + ['Zoe', 'Zoe', ' ', '"'], + 15 + ); + callback(Resposta); + } + ); + } + + function EnviaPerguntaChatBot(Pergunta, SessaoID, callback) { + mysqlConnection.query( + 'select ChatBot from config;', + function (error, Config, fields) { + const ChatBot = Config[0]['ChatBot']; + console.log('enviando pegundo para chat bot --- RecognizeAudio'); + if (ChatBot == 1) { + // MITSUKU + EnviaPerguntaMitsuku(Pergunta, SessaoID, function (Resposta) { + callback(Resposta); + }); + } else if (ChatBot == 2) { + // ROSIE + EnviaPerguntaRosie(Pergunta, function (Resposta) { + callback(Resposta); + }); + } else if (ChatBot == 3) { + // CLEVERBOT + EnviaPerguntaCleverbot(Pergunta, function (Resposta) { + callback(Resposta); + }); + } else if (ChatBot == 4) { + // KUKI + EnviaPerguntaKuki(Pergunta, SessaoID, function (Resposta) { + callback(Resposta); + }); + } else if (ChatBot == 5) { + // gpt + EnviaPerguntaGPT(Pergunta, function (Resposta) { + callback(Resposta); + }); + } + } + ); + } + + function TrataRespostaChatBot(Resposta, callback) { + let Tratada = Resposta; + Tratada = ReplaceAll(Tratada, ['
', '"'], [' ', "'"], 15); + mysqlConnection.query( + `SELECT tf.* FROM zoetratamentofrases tf inner join config cf on cf.ChatBot = tf.ChatBot;`, + function (error, Tratamentos, fields) { + if (Tratamentos && Tratamentos.length > 0) { + for (let i = 0; i < Tratamentos.length; i++) { + if (Tratamentos[i]['frase'] == Resposta) { + Tratada = Tratamentos[i]['trocada']; + break; + } + } + } + callback(Tratada); + } + ); + } + + function RemoverTagsDoTexto(Texto, Palavras, callback) { + let NovoTexto = ''; + for (let p = 0; p < Palavras.length; p++) { + for (var i = 0; i < Texto.split(Palavras[p]).length; i++) { + if (i % 2 == 0) NovoTexto += Texto.split(Palavras[p])[i]; + } + if (NovoTexto != '') Texto = NovoTexto; + NovoTexto = ''; + } + callback(Texto); + } + + function ReplaceAll(Texto, Palavras, TrocarPor, Vezes) { + for (let i = 0; i < Vezes; i++) { + for (let o = 0; o < Palavras.length; o++) { + Texto = Texto.replace(Palavras[o], TrocarPor[o]); + } + } + return Texto; + } + + function AtualizaValoresVariaveis( + ModoInserir, + idzoechattimedialog, + FraseEntrada, + Variaveis, + Matricula, + IDUnidade, + callback + ) { + // VERIFICA TODAS AS SENTENCAS DESSA INTENCAO + mysqlConnection.query( + `select * from zoechattimesentences where idzoechattimedialog = ${idzoechattimedialog};`, + function (error, ChatTimeSentences, fields) { + let ArrayPergunta = FraseEntrada.split(' '); + let UltimoIndexArray = ArrayPergunta.length - 1; + // REMOVE O \r\n DO FINAL DA ULTIMA PALAVRA + for (let i = 0; i < ArrayPergunta[UltimoIndexArray].length; i++) { + let UltimaLeta = + ArrayPergunta[UltimoIndexArray][ + ArrayPergunta[UltimoIndexArray].length - 1 + ]; + if (UltimaLeta == '\r' || UltimaLeta == '\n') { + ArrayPergunta[UltimoIndexArray] = ArrayPergunta[ + UltimoIndexArray + ].substring(0, ArrayPergunta[UltimoIndexArray].length - 1); + } else break; + } + + // MONTA ARRAY DE PALAVRAS DE TODAS AS SENTENCAS DESSA INTENCAO + let Sentencas = []; + for (let o = 0; o < ChatTimeSentences.length; o++) { + Sentencas.push(ChatTimeSentences[o]['sentence'].split(' ')); + } + + let NovoValor = ''; + let indexVariavelAtual = 0; + + //console.log(Sentencas); + //console.log(ArrayPergunta); + + // PARA CADA VARIAVEL CONTIDA NA FRASE + for (let i = 0; i < Variaveis.length; i++) { + // PARA CADA SENTENCA VERIFICA QUAIS AS PALAVRAS NAO ESTAO PRESENTES NESTA PARA VERIFICAR SE CONDIZ COM A VARIAVEL + indexVariavelAtual = i; + for (let o = 0; o < Sentencas.length; o++) { + // PARA CADA SENTENCA + for (let p = 0; p < ArrayPergunta.length; p++) { + // PARA CADA PALAVRA DA FRASE DO USUARIO + for (let q = 0; q < Sentencas[o].length; q++) { + // PARA CADA PALAVRA DE CADA SENTENCA + if ( + Sentencas[o][q].toLowerCase() == + ArrayPergunta[p].toLowerCase() + ) + // VERIFICA SE AS PALAVRAS SAO IGUAIS + ArrayPergunta[p] = ''; // SE IGUAIS ENTAO REMOVE, MANTENDO SOMENTE AS DIFERENTES NO ARRAY + } + } + } + + //console.log(ArrayPergunta); + + // VERIFICAR OS VALORES QUE SAO DIFERENTES DAS PALAVRAS CONTIDAS NAS FRASES, ATRIBUINDO O VALOR DA VARIAVEL COM ESTE + for (let o = 0; o < ArrayPergunta.length; o++) { + if (ArrayPergunta[o] != '') { + if (!Variaveis[i].description.includes('Spell')) + // SE FOR ALGUMA VARIAVEL DE TEXTO + NovoValor += (NovoValor != '' ? ' ' : '') + ArrayPergunta[o]; + else { + // SE FOR ALGUMA VARIAVEL DE SOLETRAGEM + if (ArrayPergunta[o].length == 1) + // SE A PALAVRAS TIVER APENAS UMA LETRA + NovoValor += (NovoValor != '' ? '-' : '') + ArrayPergunta[o]; + } + } + } + } + // ALTERA O VALOR DA VARIAVEL PARA O NOVO VALOR DITO PELO ALUNO + Variaveis[indexVariavelAtual].valuecli = NovoValor; + + InserirValorVariavel( + ModoInserir, + Variaveis[indexVariavelAtual], + Matricula, + IDUnidade, + function (Sucesso) { + callback(NovoValor); + } + ); + } + ); + } + + function InserirValorVariavel( + Inserir, + Variavel, + Matricula, + IDUnidade, + callback + ) { + //console.log(Variavel); + Variavel.valuecli = ReplaceAll(Variavel.valuecli, "'", '"', 10); + let sqlChangeVariable = ``; + if (Inserir == true) { + sqlChangeVariable = `INSERT INTO alexauservariables (idalexavariables, valuecli, idusers, idunits) + VALUES ((SELECT idalexavariables FROM alexavariables WHERE description = '${Variavel.description}'), '${Variavel.valuecli}', ${Matricula}, ${IDUnidade});`; + } else { + sqlChangeVariable = `UPDATE alexauservariables SET valuecli = '${Variavel.valuecli}' WHERE idalexavariables = ${Variavel.idalexavariables} AND idusers = ${Matricula} AND idunits = ${IDUnidade};`; + } + //console.log(sqlChangeVariable); + mysqlConnection.query(sqlChangeVariable, function (error, results, fields) { + let Sucesso = true; + if (error) { + Sucesso = false; + console.log( + "Erro ao definir valor da variável '" + Variavel.description + "'" + ); + console.log(error); + console.log(sqlChangeVariable); + } + callback(Sucesso); + }); + } + + function ModoConfiguracao(Pergunta, NomeArquivo, res, Matricula, IDUnidade) { + let Resposta = ''; + try { + if (Pergunta.toLowerCase().includes(FraseMudarVariavel)) { + // ALTERAR VALOR DA VARIAVEL - FRASE EXEMPLO: change my name to Diego + let Variavel = Pergunta.split(FraseMudarVariavel)[1].split(' ')[0]; // change my NAME to diego + let NovoValor = Pergunta.split(Variavel + ' to ')[1]; // change my name to DIEGO + //NovoValor = NovoValor.substring(0, NovoValor.length - 1); + let sqlSearchVariable = `SELECT av.idalexavariables, av.description, au.valuecli FROM alexauservariables au INNER JOIN alexavariables av ON av.idalexavariables = au.idalexavariables WHERE au.idusers = ${Matricula} AND au.idunits = ${IDUnidade} AND av.description = '${Variavel}';`; + mysqlConnection.query( + sqlSearchVariable, + function (error, results, fields) { + let FormVariavel = { + idalexavariables: 0, + description: Variavel, + valuecli: NovoValor, + }; + let ModoInserir = false; + if (results.length == 0) { + ModoInserir = false; + } else { + FormVariavel.idalexavariables = results[0].idalexavariables; + FormVariavel.description = results[0].description; + FormVariavel.valuecli = NovoValor; + } + + InserirValorVariavel( + ModoInserir, + FormVariavel, + Matricula, + IDUnidade, + function (Sucesso) { + if (Sucesso) + // CONSEGUIU DEFINIR A VARIAVEL COM O NOVO VALOR + Resposta = + 'Your ' + Variavel + ' was changed to ' + NovoValor; + // ERRO AO DEFINIR NOVO VALOR PARA VARIAVEL + else Resposta = 'Fail to define your ' + Variavel; + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + FraseExemploConfig, + 0, + 1, + Sucesso ? 100 : 0, + Sucesso ? 1 : 0, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 0, + 2, + 0, + '' + ); + } + ); + } + ); + } else if (Pergunta.toLowerCase().includes(FraseDizerVariavel)) { + // FALAR VALOR DA VARIAVEL - FRASE EXEMPLO: say my name + let Variavel = Pergunta.split(FraseDizerVariavel)[1]; // say my NAME + //Variavel = Variavel.substring(0, Variavel.length - 1); + ConsultarValorVariavel( + Variavel, + Matricula, + IDUnidade, + function (valuecli) { + if (valuecli != '') + // ENCONTROU VALOR PARA ESSA VARIAVEL + Resposta = 'Your ' + Variavel + ' is ' + valuecli; + // NAO ENCONTROU VALOR PARA ESSA VARIAVEL + else + Resposta = + 'I yet not know your ' + + Variavel + + '. Say change my ' + + Variavel + + ' to your ' + + Variavel + + ' to insert it.'; + + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + FraseExemploConfig, + 0, + 1, + 100, + 1, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 0, + 2, + 0, + '' + ); + } + ); + } else { + // COMANDO DESCONHECIDO + Resposta = EscolheFraseNaoEntendeu(); + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + FraseExemploConfig, + 0, + 1, + 0, + 0, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 0, + 2, + 0, + '' + ); + } + } catch (e) { + // HOUVE ALGUM ERRO DURANTE O PROCESSO OU FRASE INCORRETA + Resposta = EscolheFraseNaoEntendeu(); + EnviaResposta( + true, + Resposta, + NomeArquivo, + res, + FraseExemploConfig, + 0, + 1, + 0, + 0, + VelocidadePadrao, + Pergunta, + 0, + 1, + 0, + 1, + 0, + 2, + 0, + '' + ); + } + } + + function ConsultarValorVariavel(Variavel, Matricula, IDUnidade, callback) { + let sqlShowVariable = `SELECT au.valuecli FROM alexauservariables au INNER JOIN alexavariables av ON av.idalexavariables = au.idalexavariables WHERE au.idusers = ${Matricula} AND au.idunits = ${IDUnidade} AND av.description = '${Variavel}';`; + //console.log(sqlShowVariable); + mysqlConnection.query(sqlShowVariable, function (error, results, fields) { + let ValorVariavel = ''; + if (results.length > 0) ValorVariavel = results[0]['valuecli']; + else ValorVariavel = ''; + callback(ValorVariavel); + }); + } + + function LimparCaracteres(Texto) { + return Texto.replace(/[^a-zA-Z\d]/g, '').toLowerCase(); + } + + // #endregion + + return router; +}; + +module.exports = routes; diff --git a/controllers/classController.js b/controllers/classController.js new file mode 100644 index 0000000..d2b8f7f --- /dev/null +++ b/controllers/classController.js @@ -0,0 +1,955 @@ +require("../connections/mysql-server"); +require("../connections/sql-server"); +require("../helpers/CheckToken"); +require("../helpers/config"); +const express = require("express"); +const router = express.Router(); +const bodyParser = require("body-parser"); +const formidable = require("formidable"); + +router.use( + bodyParser.urlencoded({ + limit: "10mb", + extended: true, + }) +); +router.use( + bodyParser.json({ + limit: "10mb", + extended: true, + }) +); + +var routes = function () { + + router.get("/getQtdeChamadas/:idusers/:idcourses/:db", verifyJWT,(req, res) => { + const idusers = parseInt(req.params.idusers); + const idcourses = req.params.idcourses; + const db = req.params.db; + let sqlQuery = ` + SELECT + co.idcourses AS IDCurso, + CASE WHEN (SELECT COUNT(1) FROM zoeusers zu INNER JOIN zoeunits zun ON zun.id = zu.idunits WHERE CONCAT(zun.id, '.dbo.') = '${db}' AND zu.user = ${idusers} AND zu.idzoeusertype = 1) > 0 THEN 100 ELSE COUNT(cl.idclasses) END AS qtde_presencas + FROM courses co + LEFT JOIN classes cl ON cl.idcourses = co.idcourses AND cl.disabled = 0 + WHERE co.idcourses IN ${idcourses} + GROUP BY co.idcourses + ORDER BY co.idcourses ASC;`; + //console.log(sqlQuery); + execSQLQuery(sqlQuery, res, req.originalUrl); + }); + + router.get("/getQtdeChamadasOld/:idusers/:idcourses/:db", verifyJWT,(req, res) => { + const idusers = parseInt(req.params.idusers); + const idcourses = req.params.idcourses; + const db = req.params.db; + let sqlQuery = ` + SELECT + c.IDCurso, + COUNT(*) AS qtde_presencas + FROM ${db}Chamadas c + INNER JOIN ${db}TreinandosTurmas tt ON tt.CodigoTurma = c.IDTurma AND tt.IDCurso = c.IDCurso + INNER JOIN ${db}ChamadasDetalhes cd ON cd.IDChamadas = c.IDChamadas + INNER JOIN ${db}Cursos cu ON cu.Codigo = c.IDCurso + WHERE c.Flex = 1 AND c.IDCurso IN ${idcourses} AND tt.IDMatricula = ${idusers} AND cd.Presente = 1 + GROUP BY c.IDCurso, cu.NomeVersao + ORDER BY cu.NomeVersao ASC;`; + //console.log(sqlQuery); + execSQLQuery2(sqlQuery, res, req.originalUrl); + }); + + + + + router.get("/getClass/:idclasses", verifyJWT, (req, res) => { + const idclasses = parseInt(req.params.idclasses); + execSQLQuery( + `SELECT + * + FROM classes + WHERE idclasses = ${idclasses};`, + res, + req.originalUrl + ); + }); + /* router.get('/adjustXp', (req, res) => { + execSQLQuery(`SELECT idusers, completedClass, idunits FROM myrobot.stepclass where completedClass = 1;`, res, req.originalUrl); + }); */ + + router.get("/getClassByAny/:field/:value", verifyJWT, (req, res) => { + const field = req.params.field; + const value = req.params.value; + execSQLQuery( + `SELECT + * + FROM classes + WHERE ? = ?;`, + res, + req.originalUrl, + [field, value] + ); + }); + + router.get("/getQtdeClass/:idusers/:idcourses/:db", verifyJWT, (req, res) => { + const matricula = parseInt(req.params.idusers); + const idcurso = req.params.idcourses; + const db = req.params.db; + let sqlQuery = `select count(*) as qtde_presencas + from ${db}Chamadas c + inner join ${db}TreinandosTurmas tt + on tt.CodigoTurma = c.IDTurma + and tt.IDCurso = c.IDCurso + inner join ${db}ChamadasDetalhes cd + on cd.IDChamadas = c.IDChamadas + and cd.IDTreinando = tt.IDTreinando + where c.Flex = 1 + and c.IDCurso = ${idcurso} + and tt.IDMatricula = ${matricula} + and cd.Presente = 1;`; + execSQLQuery2(sqlQuery, res, req.originalUrl); + }); + + + + router.get("/getClassByCourse/:idcourses", verifyJWT, (req, res) => { + const idcourses = parseInt(req.params.idcourses); + execSQLQuery( + `SELECT + * + FROM classes + WHERE idcourses = ${idcourses} AND disabled = 0 ORDER BY ordem asc;`, + res, + req.originalUrl + ); + }); + + router.get("/getClassbyCourse/count/:idcourses", verifyJWT, (req, res) => { + const idcourses = parseInt(req.params.idcourses); + execSQLQuery( + `SELECT count(*) as numeroDeAulas FROM classes WHERE idcourses = ${idcourses} AND disabled = 0 ORDER BY ordem asc;`, + res, + req.originalUrl + ); + }); + + router.get( + "/getClassEnByCourse/:idcourses/:qtd/:homework", + verifyJWT, + (req, res) => { + const idcourses = parseInt(req.params.idcourses); + const qtd = parseInt(req.params.qtd); + const homework = parseInt(req.params.homework); + execSQLQuery( + `SELECT + idclasses, + idcourses, + name, + case when disabled = 0 and ordem < ${qtd} and (viewed < 2 or ${qtd} != 100) then 0 else 1 end as disabled, + ordem, + description, + viewed, + aval, + download, + demo, + homework, + sprites + FROM classes + WHERE idcourses = ${idcourses} AND disabled = 0 and homework = ${homework} + ORDER BY ordem asc;`, + res, + req.originalUrl + ); + } + ); + + router.get( + "/getClassEnByCourseAll/:idcourses/:qtd/:homework", + verifyJWT, + (req, res) => { + const idcourses = parseInt(req.params.idcourses); + const qtd = parseInt(req.params.qtd); + const homework = parseInt(req.params.homework); + execSQLQuery( + `SELECT + idclasses, + idcourses, + name, + case when (disabled = 0 or disabled = 1) and (viewed < 2 or ${qtd} != 100) then 0 else 1 end as disabled, + ordem, + description, + viewed, + aval, + download, + demo, + homework, + sprites + FROM classes + WHERE idcourses = ${idcourses} AND homework = ${homework} + ORDER BY ordem asc;`, + res, + req.originalUrl + ); + } + ); + + router.post("/insertStepClass", verifyJWT, (req, res) => { + const idusers = parseInt(req.body.idusers); + const idclasses = parseInt(req.body.idclasses); + const idunits = parseInt(req.body.idunits); + mysqlConnection.query( + "select * from stepclass order by idstepclass desc;", + function (error, results, fields) { + let IDStepClass = ""; + if (!results || results == "" || results.length == 0) IDStepClass = "1"; + else IDStepClass = parseInt(results[0]["idstepclass"]) + 1; + let SQLInsert = `INSERT INTO stepclass(idstepclass, idusers, idclasses, actualClass, actualExercise, actualAnswer, actualItem, answersdb, continueClass, completedClass, idunits) VALUES + (?, ?, ?, 0, 0, 0, 0, '', 0, 0, ?);`; + execSQLQuery( + SQLInsert, + res, + req.originalUrl, + [IDStepClass, idusers, idclasses, idunits], + function (Retorno) { + if (Retorno.status == 500) { + console.log(Retorno.error); + } + } + ); + } + ); + }); + + router.get( + "/lockClass/:idusers/:idunits/:idclasses", + verifyJWT, + (req, res) => { + const idusers = parseInt(req.params.idusers); + const idclasses = parseInt(req.params.idclasses); + const idunits = parseInt(req.params.idunits); + + let sqlQuery = `UPDATE stepclass SET + lockedClass = 1 + WHERE idunits = ${idunits} and idclasses = ${idclasses} and idusers = ${idusers};`; + execSQLQuery(sqlQuery, res, req.originalUrl); + } + ); + + router.patch("/updateStepClass", verifyJWT, (req, res) => { + const idusers = parseInt(req.body.idusers); + const idclasses = parseInt(req.body.idclasses); + const idunits = parseInt(req.body.idunits); + const actualClass = parseInt(req.body.actualClass); + const actualExercise = parseInt(req.body.actualExercise); + const actualAnswer = parseInt(req.body.actualAnswer); + const actualItem = parseInt(req.body.actualItem); + const answersdb = req.body.answersdb; + const continueClass = req.body.continueClass; + const completedClass = req.body.completedClass; + const notegame = req.body.notegame; + + let sqlQuery = `UPDATE stepclass SET + actualClass = ${actualClass}, + actualExercise = ${actualExercise}, + actualAnswer = ${actualAnswer}, + actualItem = ${actualItem}, + answersdb = '${answersdb}', + continueClass = ${continueClass}, + completedClass = ${completedClass}, + notegame = ${notegame} + WHERE idunits = ${idunits} and idclasses = ${idclasses} and idusers = ${idusers};`; + execSQLQuery(sqlQuery, res, req.originalUrl); + }); + + router.patch("/addNote/:idunits", verifyJWT, (req, res) => { + const idusers = parseInt(req.body.idusers); + const idclasses = parseInt(req.body.idclasses); + const note = req.body.note; + const idunits = parseInt(req.params.idunits); + execSQLQuery( + `UPDATE stepclass SET + note = ${note}, + notification = 1 + WHERE idusers = ${idusers} AND idclasses = ${idclasses} AND idunits = ${idunits};`, + res, + req.originalUrl + ); + }); + + router.patch("/setFinalDate", verifyJWT, (req, res) => { + const datefinal = req.body.datefinal; + const idusers = req.body.idusers; + const idclasses = req.body.idclasses; + const idunits = req.body.idunits; + execSQLQuery( + `UPDATE stepclass SET + datefinal = (select date_format(date_add(now(), interval 6 day), '%d/%m/%Y')) + WHERE idusers = ${idusers} AND idclasses = ${idclasses} AND idunits = ${idunits};`, + res, + req.originalUrl + ); + }); + + router.get("/PlusView/:idclasses", verifyJWT, (req, res) => { + const idclasses = req.params.idclasses; + execSQLQuery( + `UPDATE classes SET + viewed = viewed + 1 + WHERE idclasses = ${idclasses};`, + res, + req.originalUrl + ); + }); + + router.post("/addCourseNote", verifyJWT, (req, res) => { + const idusers = parseInt(req.body.idusers); + const idcourses = parseInt(req.body.idcourses); + const note = req.body.note; + const idunits = parseInt(req.body.idunits); + execSQLQuery( + `INSERT INTO coursenotes (idusers, idcourses, note, idunits) + VALUES (${idusers}, ${idcourses}, ${note}, ${idunits});`, + res, + req.originalUrl + ); + }); + + router.get("/getActualConcept/:idclasses", verifyJWT, (req, res) => { + const idclasses = parseInt(req.params.idclasses); + execSQLQuery( + `SELECT + (ordem + 1) as concept + FROM classes + WHERE idclasses = ${idclasses};`, + res, + req.originalUrl + ); + }); + + router.patch("/removeNotification", verifyJWT, (req, res) => { + const idusers = parseInt(req.body.idusers); + const idunits = parseInt(req.body.idunits); + execSQLQuery( + `UPDATE stepclass SET + notification = 0 + WHERE idusers = ${idusers} AND idunits = ${idunits}`, + res, + req.originalUrl + ); + }); + + router.get( + "/getTreinandosTurmas/:matricula/:idcurso/:db", + verifyJWT, + (req, res) => { + const matricula = parseInt(req.params.matricula); + const idcurso = parseInt(req.params.idcurso); + const db = req.params.db; + execSQLQuery2( + `SELECT + * + FROM ${db}TreinandosTurmas + WHERE IDMatricula = ${matricula} AND IDCurso = ${idcurso};`, + res, + req.originalUrl + ); + } + ); + + router.post("/insertNotasDetalhes/:banco", verifyJWT, (req, res) => { + const db = req.params.banco; + const IDTurma = parseInt(req.body.IDTurma); + const IDCurso = parseInt(req.body.IDCurso); + const IDMatricula = parseInt(req.body.IDMatricula); + const IDTreinando = parseInt(req.body.IDTreinando); + const IDConceito = parseInt(req.body.IDConceito); + const NumeroProva = parseInt(req.body.NumeroProva); + const Nota = req.body.Nota; + execSQLQuery2( + `INSERT INTO ${db}NotasDetalhes (IDTurma, IDCurso, IDMatricula, IDTreinando, IDConceito, Nota) + VALUES (${IDTurma}, ${IDCurso}, ${IDMatricula}, ${IDTreinando}, ${IDConceito}, ${Nota}); + INSERT INTO ${db}NotasDetalhesSequencial (IDTurma, IDCurso, IDMatricula, IDTreinando, IDConceito) + VALUES (${IDTurma}, ${IDCurso}, ${IDMatricula}, ${IDTreinando}, ${IDConceito});`, + res, + req.originalUrl + ); + }); + + router.get("/getAllStepClass/:englishbot", verifyJWT, (req, res) => { + const englishbot = parseInt(req.params.englishbot); + execSQLQuery( + `select + sc.*, + sc.idusers as 'Matricula', + un.unityname as 'Unidade', + cl.name as 'Aula', + co.name as 'Curso', + sc.completedClass as 'Concluida', + sc.actualExercise as 'Etapa' + from stepclass sc + inner join classes cl on cl.idclasses = sc.idclasses + inner join courses co on co.idcourses = cl.idcourses + inner join units un on un.idunits = sc.idunits + where co.idtypescourse ${englishbot == 1 ? "=" : "!="} 5;`, + res, + req.originalUrl + ); + }); + + router.get( + "/getStepClass/:idusers/:idclasses/:idunits", + (req, res) => { + const idusers = parseInt(req.params.idusers); + const idclasses = parseInt(req.params.idclasses); + const idunits = parseInt(req.params.idunits); + const sql = `SELECT + sc.*, + (SELECT COUNT(*) + FROM ( + SELECT + c.idclassescontent, + COALESCE(e.idexercises, m.idmedia, t.idtexts, s.idslides, c.montagem) AS content_id, + COALESCE(e.description, m.description, t.description, s.title, 'Hora da montagem') AS description, + COALESCE(e.enabled, 1, t.enabled, 1, 1) AS enabled, + CASE + WHEN e.idexercises IS NOT NULL THEN 'Exercício' + WHEN m.idmedia IS NOT NULL THEN 'Mídia' + WHEN t.idtexts IS NOT NULL THEN CASE WHEN t.game = 0 THEN 'Texto' ELSE 'Jogo' END + WHEN s.idslides IS NOT NULL THEN 'Slide' + WHEN c.montagem = 1 THEN 'Montagem' + END AS type, + CASE + WHEN e.idexercises IS NOT NULL THEN 'Editar' + WHEN m.idmedia IS NOT NULL THEN 'Prever' + WHEN t.idtexts IS NOT NULL THEN 'Editar' + WHEN s.idslides IS NOT NULL THEN 'Prever' + WHEN c.montagem = 1 THEN '⠀⠀⠀⠀⠀' + END AS acao + FROM classescontent c + LEFT JOIN exercises e ON c.idexercises = e.idexercises + LEFT JOIN media m ON c.idmedia = m.idmedia + LEFT JOIN texts t ON c.idtexts = t.idtexts + LEFT JOIN slides s ON c.idslides = s.idslides + WHERE c.idclasses = ${idclasses} + ) AS content_table) AS qtdeItens + FROM stepclass sc + WHERE + sc.idusers = ${idusers} + AND sc.idclasses = ${idclasses} + AND sc.idunits = ${idunits};`; + mysqlConnection.query(sql, function (error, results, fields) { + console.log(req.originalUrl + " success 200"); + res.send( + JSON.stringify({ + response: results, + error: error, + status: results.length > 0 ? 200 : 500, + }) + ); + }); + } + ); + + router.get("/getStepClassByUser/:idusers/:idunits", verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + const idunits = parseInt(req.params.idunits); + execSQLQuery( + `SELECT + * + FROM stepclass + WHERE idusers = ${idusers} AND idunits = ${idunits};`, + res, + req.originalUrl + ); + }); + + router.get("/list", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + classes.idclasses, + classes.name, + classes.disabled, + classes.ordem, + courses.name as coursename, + COUNT(classescontent.idclassescontent) as 'classContent' + FROM classes + JOIN courses ON classes.idcourses = courses.idcourses + LEFT JOIN classescontent ON classes.idclasses = classescontent.idclasses + GROUP BY classes.idclasses;`, + res, + req.originalUrl + ); + }); + + router.get("/listEn", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + c.idclasses, + c.name, + c.disabled, + c.ordem, + c.download, + co.name AS coursename, + (select count(*) from courses co2 where co2.idcourses = c.idcourses and co2.idtypescourse = 5) as 'cursoingles', + COUNT(cc.idclassescontent) AS 'classContent' + FROM classes c + JOIN courses co ON c.idcourses = co.idcourses + LEFT JOIN classescontent cc ON c.idclasses = cc.idclasses + GROUP BY c.idcourses, c.idclasses + ORDER BY co.idcourses ASC, c.ordem ASC;`, + res, + req.originalUrl + ); + }); + + router.get("/disable/:idclasses", verifyJWT, (req, res) => { + const idclasses = parseInt(req.params.idclasses); + execSQLQuery( + `UPDATE classes SET + disabled = not disabled + WHERE idclasses = ${idclasses};`, + res, + req.originalUrl + ); + }); + + router.post("/insert", verifyJWT, (req, res) => { + const idcourses = parseInt(req.body.idcourses); + const name = req.body.name; + const disabled = req.body.disabled ? 1 : 0; + const description = req.body.description; + const aval = req.body.aval ? 1 : 0; + const download = req.body.download ? 1 : 0; + const demo = req.body.demo ? 1 : 0; + const homework = req.body.homework ? 1 : 0; + const sprites = parseInt(req.body.sprites); + execSQLQuery( + `INSERT INTO classes(idcourses, name, disabled, ordem, description, aval, download, viewed, demo, homework, sprites) SELECT + ?, ?, ?, (select coalesce((select (ordem + 1) as ordem from classes where idcourses = ${idcourses} order by ordem desc limit 1), 0)), ?, ?, ?, 0, ?, ?, ?;`, + res, + req.originalUrl, + [ + idcourses, + name, + disabled, + description, + aval, + download, + demo, + homework, + sprites, + ] + ); + }); + + router.patch("/update", verifyJWT, (req, res) => { + const idclasses = parseInt(req.body.idclasses); + const idcourses = parseInt(req.body.idcourses); + const name = req.body.name; + const disabled = req.body.disabled ? 1 : 0; + const description = req.body.description; + const viewed = parseInt(req.body.viewed); + const aval = req.body.aval ? 1 : 0; + const download = req.body.download ? 1 : 0; + const demo = req.body.demo ? 1 : 0; + const homework = req.body.homework ? 1 : 0; + const sprites = parseInt(req.body.sprites); + execSQLQuery( + `UPDATE classes SET + idcourses = ?, + name = ?, + disabled = ?, + description = ?, + viewed = ?, + aval = ?, + download = ?, + demo = ?, + homework = ?, + sprites = ? + WHERE idclasses = ?;`, + res, + req.originalUrl, + [ + idcourses, + name, + disabled, + description, + viewed, + aval, + download, + demo, + homework, + sprites, + idclasses, + ] + ); + }); + + router.delete("/delete/:idclasses", verifyJWT, (req, res) => { + const idclasses = parseInt(req.params.idclasses); + execSQLQuery( + `DELETE FROM classes + WHERE idclasses = ${idclasses};`, + res, + req.originalUrl + ); + }); + + router.post("/copy", verifyJWT, (req, res) => { + let form = new formidable.IncomingForm(); + form.maxFileSize = 1024 * 1024 * 1024; + form.parse(req, function (err, fields, files) { + const fs = require("fs"); + var idclasses = fields.idclasses; + var GifFile = ""; + var BackFile = ""; + + try { + GifFile = files.gif.path; + } catch (e) { + console.log("Não copia Gif"); + } + try { + BackFile = files.back.path; + } catch (e) { + console.log("Não copia Back"); + } + + if (GifFile == "" && BackFile != "") { + fs.rename( + BackFile, + Variables("src_media") + "images/back_" + idclasses + ".jpg", + function (err) { + console.log("/classes/copy success 200"); + res.send(true); + } + ); + } else if (GifFile != "" && BackFile == "") { + fs.rename( + GifFile, + Variables("src_media") + "images/gif_" + idclasses + ".gif", + function (err) { + console.log("/classes/copy success 200"); + res.send(true); + } + ); + } else if (GifFile != "" && BackFile != "") { + fs.rename( + GifFile, + Variables("src_media") + "images/gif_" + idclasses + ".gif", + function (err) { + fs.rename( + BackFile, + Variables("src_media") + "images/back_" + idclasses + ".jpg", + function (err) { + console.log("/classes/copy success 200"); + res.send(true); + } + ); + } + ); + } else { + res.send(true); + } + }); + }); + + router.post("/insertUserStage", verifyJWT, (req, res) => { + const iduserstages = req.body.iduserstages; + const idclassescontent = parseInt(req.body.idclassescontent); + const idusers = parseInt(req.body.idusers); + const idunits = parseInt(req.body.idunits); + const idclasses = parseInt(req.body.idclasses); + const note = req.body.note; + mysqlConnection.query( + "select * from userstages order by iduserstages desc;", + function (error, results, fields) { + let IDUserStages = ""; + if (!results || results == "" || results.length == 0) + IDUserStages = "1"; + else IDUserStages = parseInt(results[0]["iduserstages"]) + 1; + const SQLInsert = `INSERT INTO userstages(iduserstages, idstages, idusers, idunits, idclasses, note) + SELECT + ${IDUserStages}, + (SELECT DISTINCT idstages FROM stages WHERE convert(description using utf8) LIKE convert(Stage.description using utf8)) AS idstages, + ${idusers} AS idusers, + ${idunits} AS idunits, + ${idclasses} AS idclasses, + ${note} AS note + FROM (SELECT CASE + WHEN idgames is not null THEN 'Jogo' + WHEN idslides is not null THEN 'Montagem' + ELSE 'Lição de Casa' + END AS description + FROM classescontent + WHERE idclassescontent = ${idclassescontent}) Stage;`; + //console.log(SQLInsert); + execSQLQuery(SQLInsert, res, req.originalUrl); + } + ); + }); + + router.post("/insertZoeUserGames", verifyJWT, (req, res) => { + const idunits = parseInt(req.body.idunits); + const idusers = parseInt(req.body.idusers); + const idclasses = parseInt(req.body.idclasses); + const idgames = parseInt(req.body.idgames); + const note = req.body.note; + execSQLQuery( + `insert into zoeusergames (idunits, idusers, idgames, idclasses, note) values (${idunits}, ${idusers}, ${idgames}, ${idclasses}, ${note});`, + res, + req.originalUrl + ); + }); + + router.get("/CarregarImagem/:Nome", (req, res) => { + let Protocolo = "http://"; + try { + Protocolo = req.headers.referer.split("/")[0] + "//"; + } catch (e) {} + const fs = require("fs"); + const Nome = req.params.Nome; + const DirLocal = `${Variables("src_media")}images/${Nome}`; + console.log(DirLocal); + const DirWeb = `${Protocolo}${ + req.headers.host.split(":")[0] + }/images/${Nome}`; + console.log(DirWeb); + if (DirLocal.includes("C:/")) { + let diretoriodearquivolocal = DirWeb; + diretoriodearquivolocal = diretoriodearquivolocal.replace( + "localhost", + "localhost:4200" + ); + diretoriodearquivolocal = diretoriodearquivolocal.replace( + "images", + "assets/imagesAula" + ); + res.redirect(diretoriodearquivolocal); + } else { + if (fs.existsSync(DirLocal)) { + res.redirect(DirWeb); + } else { + const shell = require("shelljs"); + shell.exec( + "cd " + + Variables("src_media") + + "images/;wget http://18.228.91.135/images/" + + Nome, + function (sucesso) { + //console.log(sucesso); + res.redirect(DirWeb); + } + ); + } + } + }); + + router.patch("/AtualizarOrdem", verifyJWT, (req, res) => { + const idclasses = parseInt(req.body.idclasses); + const ordem = parseInt(req.body.ordem); + execSQLQuery( + `UPDATE classes SET + ordem = ${ordem} + WHERE idclasses = ${idclasses};`, + res, + req.originalUrl + ); + }); + + router.get("/getTeacherPasswords/:db", verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2( + `SELECT + Senha + FROM ${db}Funcionarios + where Desativado = 0;`, + res, + req.originalUrl + ); + }); + + router.get("/getFotoAluno/:idusers/:db", (req, res) => { + const idusers = parseInt(req.params.idusers); + const db = req.params.db; + let sqlQuery = `select distinct + tt.IDTreinando + from ${db}TreinandosTurmas tt + where tt.IDMatricula = ${idusers};`; + if (Variables("local") == "Local") { + console.log(req.originalUrl + " error 403"); + res.send( + JSON.stringify({ + response: "", + error: null, + status: 403, + }) + ); + return; + } + sqlServerConnection + .request() + .query(sqlQuery, function (error, results, fields) { + if (!error && results["recordsets"][0].length != 0) { + const fs = require("fs"); + + /* fs.readdir(Variables("src_fotos"), (err, files) => { + let FotoId = ""; + files.forEach(Foto => { + if (Foto.split('.')[0] == results['recordsets'][0][0]['IDTreinando']) { + FotoId = Foto; + } + }); + if (FotoId != "") { + fs.readFile(Variables("src_fotos") + FotoId, function(err, data) { + if (err) throw err + console.log(req.originalUrl + " success 200"); + res.send(JSON.stringify({ + "response": data, + "error": null, + "status": 200 + })); + }); + } + else { + console.log(req.originalUrl + " error 500"); + res.send(JSON.stringify({ + "response": "", + "error": null, + "status": 500 + })); + } + }); */ + } else { + console.log(req.originalUrl + " error 500"); + res.send( + JSON.stringify({ + response: "", + error: null, + status: 500, + }) + ); + } + }); + }); + + router.post("/AlteraNotaAula", verifyJWT, (req, res) => { + const idclasses = parseInt(req.body.idclasses); + const idunits = parseInt(req.body.idunits); + const idusers = parseInt(req.body.idusers); + const Nota = req.body.Nota; + const SQLUpdate = `UPDATE stepclass SET note = ${Nota} WHERE idunits = ${idunits} AND idclasses = ${idclasses} AND idusers = ${idusers};`; + mysqlConnection.query(SQLUpdate, function (error, results, fields) { + const SQLDelete = `delete from coursenotes where idcourses = (select idcourses from classes where idclasses = ${idclasses}) and idunits = ${idunits} and idusers = ${idusers};`; + mysqlConnection.query(SQLDelete, function (error2, results2, fields2) { + InsertCourseNotes(); + console.log(req.originalUrl + " success 200"); + res.send( + JSON.stringify({ + response: results2, + error: error2, + status: 200, + }) + ); + }); + }); + }); + + router.get( + "/AlteraStatusAulaAssistida/:idunits/:classes/:idusers/:status", + verifyJWT, + (req, res) => { + const idunits = parseInt(req.params.idunits); + const idclasses = parseInt(req.params.idclasses); + const idusers = parseInt(req.params.idusers); + const status = parseInt(req.params.status); + execSQLQuery( + `UPDATE stepclass SET + liberado = ${status} + WHERE idunits = ${idunits} and idclasses = ${idclasses} and idusers = ${idusers};`, + res, + req.originalUrl + ); + } + ); + + router.get("/getTipoCursoPorAula/:idclasses", verifyJWT, (req, res) => { + const idclasses = parseInt(req.params.idclasses); + execSQLQuery( + `SELECT + tc.* + FROM typescourse tc + inner join courses co on co.idtypescourse = tc.idtypescourse + inner join classes cl on cl.idcourses = co.idcourses + where cl.idclasses = ${idclasses};`, + res, + req.originalUrl + ); + }); + + function InsertCourseNotes() { + console.log(new Date().toUTCString() + " - /InsertCourseNotes"); + const SQLQry = `select + Tab2.idcourses, + Tab2.idusers, + (sum(Tab2.note) / Tab2.AulasCurso) as 'note', + Tab2.idunits + from ( + select + Tab1.*, + sc.idstepclass, + sc.note + from ( + select + sc.idusers, + co.idcourses, + sc.idunits, + count(sc.idclasses) as 'Aulas', + (select count(*) from classes cl1 where cl1.idcourses = co.idcourses and cl1.disabled = 0) as 'AulasCurso' + from stepclass sc + inner join classes cl on cl.idclasses = sc.idclasses + inner join courses co on co.idcourses = cl.idcourses + where sc.note is not null + group by sc.idusers, co.idcourses, sc.idunits) Tab1 + inner join stepclass sc on sc.idunits = Tab1.idunits and sc.idusers = Tab1.idusers + inner join classes cl on cl.idclasses = sc.idclasses and cl.idcourses = Tab1.idcourses + where Tab1.Aulas = Tab1.AulasCurso + order by idunits, idcourses, idusers) Tab2 + group by Tab2.idcourses, Tab2.idusers, Tab2.idunits;`; + + mysqlConnection.query(SQLQry, function (error, results, fields) { + LoopCursoNotas(0, results, function (Sucesso) { + console.log(new Date().toUTCString() + " - Notas de cursos lançadas"); + return Sucesso; + }); + }); + } + + function LoopCursoNotas(Index, Registros, callback) { + if (!Registros) { + callback(false); + return; + } + if (Index < Registros.length) { + let SQLInsert = `INSERT INTO coursenotes (idcourses, idusers, note, idunits) VALUES (${Registros[Index]["idcourses"]}, ${Registros[Index]["idusers"]}, ${Registros[Index]["note"]}, ${Registros[Index]["idunits"]});`; + //console.log(SQLInsert); + mysqlConnection.query(SQLInsert, function (error, results, fields) { + if (!error) { + console.log( + "Notas do curso lançadas para o aluno " + + Registros[Index]["idusers"] + + " da unidade " + + Registros[Index]["idcourses"] + ); + } + Index++; + LoopCursoNotas(Index, Registros, callback); + }); + } else { + callback(true); + } + } + + return router; +}; + +module.exports = routes; diff --git a/controllers/classescontentController.js b/controllers/classescontentController.js new file mode 100644 index 0000000..9af2bf1 --- /dev/null +++ b/controllers/classescontentController.js @@ -0,0 +1,361 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * FROM classescontent`, res, req.originalUrl); + }); + + router.get('/getAll', (req, res) => { + execSQLQuery(`SELECT * FROM classescontent`, res, req.originalUrl); + }); + + router.get('/getIdClasses1/:idclasses', verifyJWT, (req, res) => { + const idclasses = parseInt(req.params.idclasses); + execSQLQuery(`SELECT + * + FROM classescontent + WHERE idclasses = ${idclasses} + ORDER BY ordem asc;`, res, req.originalUrl); + }); + + router.get('/getCCbyEx/:idexercises', verifyJWT, (req, res) => { + const idexercises = parseInt(req.params.idexercises); + execSQLQuery(`SELECT + * + FROM classescontent + WHERE idexercises = ${idexercises};`, res, req.originalUrl); + }); + + router.get('/getIdClasses/:idclasses', verifyJWT, (req, res) => { + const idclasses = parseInt(req.params.idclasses); + execSQLQuery(`SELECT + MAX(ordem) as ordem + FROM classescontent + WHERE idclasses = ${idclasses};`, res, req.originalUrl); + }); + + router.get('/getClassescontent/:idclasses', verifyJWT, (req, res) => { + const idclasses = parseInt(req.params.idclasses); + execSQLQuery(`SELECT + * + FROM + (SELECT + c.idclassescontent, + c.idclasses, + c.ordem, + c.idexercises, + e.description, + e.enabled, + 'Exercício' as type, + 'Editar' as acao, + '' as obs + FROM classescontent c + INNER JOIN exercises e ON c.idexercises = e.idexercises + WHERE c.idclasses = ${idclasses} + UNION ALL + SELECT + c.idclassescontent, + c.idclasses, + c.ordem, + c.idmedia, + m.description, + 1 as enabled, + 'Mídia' as type, + 'Prever' as acao, + m.publishid as obs + FROM classescontent c + INNER JOIN media m ON c.idmedia = m.idmedia + WHERE c.idclasses = ${idclasses} + UNION ALL + SELECT + c.idclassescontent, + c.idclasses, + c.ordem, + c.idtexts, + t.description, + t.enabled, + case when t.game = 0 then 'Texto' else 'Jogo' end as type, + 'Editar' as acao, + '' as obs + FROM classescontent c + INNER JOIN texts t ON c.idtexts = t.idtexts + WHERE c.idclasses = ${idclasses} + UNION ALL + SELECT + c.idclassescontent, + c.idclasses, + c.ordem, + c.idgames, + t.description, + t.enabled, + case when t.game = 0 then 'Texto' else 'Jogo' end as type, + 'Editar' as acao, + '' as obs + FROM classescontent c + INNER JOIN texts t ON c.idgames = t.idtexts + WHERE c.idclasses = ${idclasses} + UNION ALL + SELECT + c.idclassescontent, + c.idclasses, + c.ordem, + c.idslides, + s.title, + 1 as enabled, + 'Slide' as type, + 'Editar' as acao, + '' as obs + FROM classescontent c + INNER JOIN slides s ON c.idslides = s.idslides + WHERE c.idclasses = ${idclasses} + UNION ALL + SELECT + c.idclassescontent, + c.idclasses, + c.ordem, + c.montagem, + 'Hora da montagem' as description, + 1 as enabled, + 'Montagem' as type, + '⠀⠀⠀⠀⠀' as acao, + '' as obs + FROM classescontent c + WHERE c.idclasses = ${idclasses} AND c.montagem = 1 + UNION ALL + SELECT + c.idclassescontent, + c.idclasses, + c.ordem, + c.idanimations, + a.description, + 1 as enabled, + 'Animação' as type, + 'Editar' as acao, + '' as obs + FROM classescontent c + INNER JOIN animations a ON c.idanimations = a.idanimations + WHERE c.idclasses = ${idclasses} + UNION ALL + SELECT + c.idclassescontent, + c.idclasses, + c.ordem, + c.idzoechattime, + ct.description, + 1 as enabled, + 'ChatTime' as type, + 'Editar' as acao, + '' as obs + FROM classescontent c + INNER JOIN zoechattime ct ON c.idzoechattime = ct.idzoechattime + WHERE c.idclasses = ${idclasses} + UNION ALL + SELECT + c.idclassescontent, + c.idclasses, + c.ordem, + c.idcharactersConversation, + cc.description, + 1 as enabled, + 'Diálogo' as type, + 'Editar' as acao, + '' as obs + FROM classescontent c + INNER JOIN charactersConversation cc ON c.idcharactersConversation = cc.idcharactersConversation + WHERE c.idclasses = ${idclasses} + UNION ALL + SELECT + c.idclassescontent, + c.idclasses, + c.ordem, + c.idzoelistenrepeat, + lr.description, + 1 as enabled, + 'ListenRepeat' as type, + 'Editar' as acao, + '' as obs + FROM classescontent c + INNER JOIN zoelistenrepeat lr ON c.idzoelistenrepeat = lr.idzoelistenrepeat + WHERE c.idclasses = ${idclasses} + UNION ALL + SELECT + c.idclassescontent, + c.idclasses, + c.ordem, + c.idfiles, + f.description, + 1 as enabled, + 'Download' as type, + 'Baixar' as acao, + '' as obs + FROM classescontent c + INNER JOIN files f ON c.idfiles = f.idfiles + WHERE c.idclasses = ${idclasses} + ) result + ORDER BY result.ordem;`, res, req.originalUrl); + }); + + router.post('/insert', verifyJWT, (req, res) => { + const idexercises = req.body.idexercises || null; + const idmedia = req.body.idmedia || null; + const idtexts = req.body.idtexts || null; + const idclasses = req.body.idclasses || null; + const idslides = req.body.idslides || null; + const idgames = req.body.idgames || null; + const montagem = req.body.montagem || null; + const idanimations = req.body.idanimations || null; + const idzoechattime = req.body.idzoechattime || null; + const idcharactersConversation = req.body.idcharactersConversation || null; + const idzoelistenrepeat = req.body.idzoelistenrepeat || null; + const idfiles = req.body.idfiles || null; + execSQLQuery(`INSERT INTO classescontent(idexercises, idmedia, idtexts, idclasses, ordem, idslides, idgames, montagem, idanimations, idzoechattime, idcharactersConversation, idzoelistenrepeat, idfiles) SELECT + ${idexercises}, ${idmedia}, ${idtexts}, ${idclasses}, (select coalesce((select (ordem + 1) as ordem from classescontent where idclasses = ${idclasses} order by ordem desc limit 1), 0)) ,${idslides}, ${idgames}, ${montagem}, ${idanimations}, ${idzoechattime}, ${idcharactersConversation}, ${idzoelistenrepeat}, ${idfiles};`, res, req.originalUrl); + }) + + router.patch('/update', verifyJWT, (req, res) => { + const idclassescontent = parseInt(req.body.idclassescontent); + const idexercises = req.body.idexercises || null; + const idmedia = req.body.idmedia || null; + const idtexts = req.body.idtexts || null; + const idclasses = req.body.idclasses || null; + const idslides = req.body.idslides || null; + const idgames = req.body.idgames || null; + const montagem = req.body.montagem || null; + const idanimations = req.body.idanimations || null; + const idcharactersConversation = req.body.idcharactersConversation || null; + const idzoelistenrepeat = req.body.idzoelistenrepeat || null; + const idfiles = req.body.idfiles || null; + const ordem = parseInt(req.body.ordem); + execSQLQuery(`UPDATE classescontent SET + idexercises = ${idexercises}, + idmedia = ${idmedia}, + idtexts = ${idtexts}, + idclasses = ${idclasses}, + idslides = ${idslides}, + idgames = ${idgames}, + montagem = ${montagem}, + idanimations = ${idanimations}, + idcharactersConversation = ${idcharactersConversation}, + idzoelistenrepeat, ${idzoelistenrepeat}, + idfiles = ${idfiles}, + ordem = ${ordem} + WHERE idclassescontent = ${idclassescontent};`, res, req.originalUrl); + }) + + router.delete('/delete/:idclassescontent', verifyJWT, (req, res) => { + const idclassescontent = req.params.idclassescontent; + execSQLQuery(`DELETE FROM classescontent + WHERE idclassescontent in (${idclassescontent});`, res, req.originalUrl); + }) + + router.patch('/AtualizarOrdem', verifyJWT, (req, res) => { + const idclassescontent = parseInt(req.body.idclassescontent); + const ordem = parseInt(req.body.ordem); + execSQLQuery(`UPDATE classescontent SET + ordem = ${ordem} + WHERE idclassescontent = ${idclassescontent};`, res, req.originalUrl); + }) + + router.post('/excluirArquivos', verifyJWT, (req, res) => { + const shell = require('shelljs'); + const Tipo = req.body.type; + const IDItem = req.body.idexercises; + switch (Tipo) { + case "Exercício": { + mysqlConnection.query(`SELECT ea.idexerciseanswers FROM exercisequestions eq INNER JOIN exerciseanswers ea ON eq.idexercisequestions = ea.idexercisequestions WHERE eq.idexercises = ${IDItem} AND ea.hasmedia = 1;`, function (error, results, fields) { + for (let i = 0; i < results.length; i++) { + try { + shell.exec("rm " + Variables('src_media') + "images/ans_" + results[i]['idexerciseanswers'] + ".jpg"); + } + catch (e) { + console.log("Não apagou"); + } + } + res.send(JSON.stringify({ + "status": 200, + "error": null, + "response": [] + })) + }) + break; + } + case "Jogo": { + shell.exec("rm -rf " + Variables('src_media') + "games/" + IDItem + "/", function(Sucesso) { + res.send(JSON.stringify({ + "status": 200, + "error": null, + "response": Sucesso + })) + }) + break; + } + case "Mídia": { + mysqlConnection.query(`SELECT publishid FROM media WHERE idmedia = ${IDItem};`, function (error, results, fields) { + shell.exec("rm " + Variables('src_media') + "videos/" + results[0]['publishid'] + ".zip", function(Sucesso) { + res.send(JSON.stringify({ + "status": 200, + "error": null, + "response": Sucesso + })) + }) + }) + break; + } + case "Slide": { + shell.exec("rm " + Variables('src_media') + "images/slide_" + IDItem + "_*", function(Sucesso) { + res.send(JSON.stringify({ + "status": 200, + "error": null, + "response": Sucesso + })) + }) + break; + } + case "Animação": { + shell.exec("rm " + Variables('src_media') + "animations/" + IDItem + ".zip", function(Sucesso) { + res.send(JSON.stringify({ + "status": 200, + "error": null, + "response": Sucesso + })) + }) + break; + } + case "Aula": { + shell.exec("rm " + Variables('src_media') + "images/back_" + IDItem + "_.jpg", function(Sucesso) { + shell.exec("rm " + Variables('src_media') + "images/gif_" + IDItem + "_.gif", function(Sucesso) { + res.send(JSON.stringify({ + "status": 200, + "error": null, + "response": Sucesso + })) + }) + }) + break; + } + } + }); + + router.get('/getClassDownloads/:idclasses', verifyJWT, (req, res) => { + const idclasses = parseInt(req.params.idclasses); + execSQLQuery(`select + cc.idclassescontent, + cc.ordem, + f.* + from classescontent cc + inner join files f on f.idfiles = cc.idfiles + where cc.idclasses = ${idclasses};`, res, req.originalUrl); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/conceptsController.js b/controllers/conceptsController.js new file mode 100644 index 0000000..9d0eba1 --- /dev/null +++ b/controllers/conceptsController.js @@ -0,0 +1,64 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM concepts;`, res, req.originalUrl); + }); + + router.get('/List', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM concepts + WHERE disabled = 0;`, res, req.originalUrl); + }); + + router.get('/getConcept/:idconcepts', verifyJWT, (req, res) => { + const idconcepts = parseInt(req.params.idconcepts); + execSQLQuery(`SELECT + * + FROM concepts + WHERE idconcepts = ${idconcepts};`, res, req.originalUrl); + }); + + router.post('/insert', verifyJWT, (req, res) => { + const idconcepts = parseInt(req.body.idconcepts); + const concept = req.body.concept; + const weight = req.body.weight; + const disabled = req.body.disabled ? 1 : 0; + execSQLQuery(`INSERT INTO concepts(concept, weight, disabled) + VALUES (?, ?, ?);`, res, req.originalUrl, [concept, weight, disabled]); + }); + + router.patch('/update', verifyJWT, (req, res) => { + const idconcepts = parseInt(req.body.idconcepts); + const concept = req.body.concept; + const weight = req.body.weight; + const disabled = req.body.disabled ? 1 : 0; + execSQLQuery(`UPDATE concepts SET + concept = ?, + weight = ?, + disabled = ? + WHERE idconcepts = ?;`, res, req.originalUrl, [concept, weight, disabled, idconcepts]); + }); + + router.get('/disable/:idconcepts', verifyJWT, (req, res) => { + const idconcepts = parseInt(req.params.idconcepts); + execSQLQuery(`UPDATE concepts SET + disabled = not disabled + WHERE idconcepts = ${idconcepts};`, res, req.originalUrl); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/configController.js b/controllers/configController.js new file mode 100644 index 0000000..cc7e114 --- /dev/null +++ b/controllers/configController.js @@ -0,0 +1,64 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/getAllTTSmode', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM TTSmode + order by description asc;`, res, req.originalUrl); + }); + + router.get('/getAllSTTmode', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM STTmode + order by description asc;`, res, req.originalUrl); + }); + + router.get('/getAllChatBot', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM ChatBot + order by description asc;`, res, req.originalUrl); + }); + + router.get('/getZoeConfig', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + TTSmode, + STTmode, + RMaudio, + ChatBot, + zoevoiceEn, + zoevoicePt + FROM config;`, res, req.originalUrl); + }); + + router.post('/saveZoeConfig', verifyJWT, (req, res) => { + const ChatBot = parseInt(req.body.ChatBot); + const RMaudio = req.body.RMaudio ? 1 : 0; + const STTmode = parseInt(req.body.STTmode); + const TTSmode = parseInt(req.body.TTSmode); + const zoevoiceEn = req.body.zoevoiceEn; + const zoevoicePt = req.body.zoevoicePt; + execSQLQuery(`update config set + TTSmode = ${TTSmode}, + STTmode = ${STTmode}, + RMaudio = ${RMaudio}, + ChatBot = ${ChatBot}, + zoevoiceEn = '${zoevoiceEn}', + zoevoicePt = '${zoevoicePt}' + where idconfig = 1;`, res, req.originalUrl); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/courseController.js b/controllers/courseController.js new file mode 100644 index 0000000..c1219bf --- /dev/null +++ b/controllers/courseController.js @@ -0,0 +1,615 @@ +require("../connections/mysql-server"); +require("../connections/sql-server"); +require("../helpers/CheckToken"); +const express = require("express"); +const router = express.Router(); +const bodyParser = require("body-parser"); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get("/getRobotCourses", verifyJWT, (req, res) => { + execSQLQuery(` + SELECT + 0 as 'IDMatricula', + idcourses as 'IDCurso', + name as 'NomeVersao', + aditional as 'Adicional', + extracourse as 'CursoExtra' + FROM courses + WHERE idtypescourse = 5 and disabled = 0;`, + res, + req.originalUrl + ); + }); + + router.get("/getRobotCourseByStudent/:idusers/:banco", verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + const db = req.params.banco; + execSQLQuery(` + SELECT distinct + zus.user AS IDMatricula, + zuc.idcourses AS IDCurso, + co.name AS NomeVersao + FROM zoeusercourses zuc + INNER JOIN courses co ON co.idcourses = zuc.idcourses + INNER JOIN zoeusers zus ON zus.id = zuc.idzoeusers + INNER JOIN zoeunits zun ON zun.id = zuc.idzoeunits + WHERE zuc.enabled = 1 AND (zuc.expiresAt IS NULL OR CURRENT_TIMESTAMP < zuc.expiresAt) AND zus.user = '${idusers}' and CONCAT(zun.id, '.dbo.') = '${db}';`, + res, + req.originalUrl + ); + }); + + router.get("/getRobotCourseByStudentOld/:idusers/:banco", verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + const db = req.params.banco; + execSQLQuery2(` + SELECT distinct + mt.IDMatricula, + tt.IDCurso, + cu.NomeVersao + FROM ${db}MatriculasTreinandos mt + INNER JOIN ${db}TreinandosTurmas tt ON mt.IDMatricula = tt.IDMatricula + INNER JOIN ${db}Cursos cu ON cu.Codigo = tt.IDCurso + WHERE mt.IDMatricula = ${idusers} AND cu.Desativado = 0 AND tt.Desistente = 0 AND cu.IDTipoCurso = 5;`, + res, + req.originalUrl + ); + }); + + + + + router.get("/getAll", verifyJWT, (req, res) => { + const domain = req.hostname.split(".").pop(); + + let language; + + switch (domain) { + case "br": + language = 1; + break; + case "py": + language = 2; + break; + case "us": + language = 3; + break; + default: + language = 1; + break; + } + + execSQLQuery( + `SELECT + * + FROM myrobot.courses where idlanguage = ${language} order by name asc`, + res, + req.originalUrl + ); + }); + + router.get("/getAllCourseOn", verifyJWT, (req, res) => { + const domain = req.hostname.split(".").pop(); + + let language; + + switch (domain) { + case "br": + language = 1; + break; + case "py": + language = 2; + break; + case "us": + language = 3; + break; + default: + language = 1; + break; + } + + execSQLQuery( + `SELECT + * + FROM myrobot.courses where idlanguage = ${language} and disabled = 0 order by name asc`, + res, + req.originalUrl + ); + }); + + router.get("/getAllCourses", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + * + FROM courses + WHERE idtypescourse != 5;`, + res, + req.originalUrl + ); + }); + + router.get("/getSQLServerCourses/:db", verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2( + `SELECT + * + FROM ${db}Cursos;`, + res, + req.originalUrl + ); + }); + + router.get("/getMySQLinSQLServerCourses", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + idcourses AS 'Codigo', + coursecode AS 'CodigoCurso', + idtypescourse AS 'IDTipoCurso', + name AS 'NomeVersao', + description AS 'DescricaoContrato', + durationtraineeprogram AS 'CH_ProgTrein', + durationtraineevip AS 'CH_TurmaVIP', + durationtraineeindividual AS 'CH_Individual', + valueprogram AS 'VR_ProgTrein', + valuevip AS 'VR_TurmaVIP', + valueindividual AS 'VR_Individual', + materialvalue AS 'ValorMaterial', + materialcode AS 'CodigoMaterial', + CASE WHEN extracourse = 1 THEN 'true' else 'false' END AS 'CursoExtra', + CASE WHEN aditional = 1 THEN 'true' else 'false' END AS 'Adicional', + CASE WHEN disabled = 1 THEN 'true' else 'false' END AS 'Desativado', + CASE WHEN autospeak = 1 THEN 'true' else 'false' END AS 'FalaAutomatica' + FROM courses;`, + res, + req.originalUrl + ); + }); + + + + + + router.get("/typescourse", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + * + FROM typescourse;`, + res, + req.originalUrl + ); + }); + + router.get("/getMySQLinSQLServerTypescourse", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + idtypescourse AS 'IDTipoCurso', + description AS 'Descricao', + case when disabled = 1 then true else false end as 'Desativado', + gradecalc AS 'CalculosNotas' + FROM typescourse;`, + res, + req.originalUrl + ); + }); + + router.get("/SQLServertypescourse/:db", verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2( + `SELECT + * + FROM ${db}TiposCurso;`, + res, + req.originalUrl + ); + }); + + router.get("/getExtraCourses", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + 0 as 'IDMatricula', + idcourses as 'IDCurso', + name as 'NomeVersao' + FROM courses + WHERE aditional = 1 and disabled = 0;`, + res, + req.originalUrl + ); + }); + + router.get("/getCourse/:idcourses", verifyJWT, (req, res) => { + const idcourses = parseInt(req.params.idcourses); + execSQLQuery( + `SELECT + * + FROM courses + WHERE idcourses = ${idcourses};`, + res, + req.originalUrl + ); + }); + + router.get("/getCourseNote/:idcourses", verifyJWT, (req, res) => { + const idcourses = parseInt(req.params.idcourses); + execSQLQuery( + `SELECT + * + FROM coursenotes + WHERE idcourses = ${idcourses};`, + res, + req.originalUrl + ); + }); + + router.get("/getAllSQLServerCourses/:idusers", verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + let sqlQuery = `SELECT idcourses AS 'IDCurso', ${idusers} AS 'IDMatricula', name AS 'NomeVersao' FROM courses where idtypescourse != 5 and disabled = 0 order by name asc;`; + execSQLQuery(sqlQuery, res, req.originalUrl); + }); + + router.get("/getCourseByStudent/:idusers/:banco", verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + const db = req.params.banco; + const EAD = req.headers.host && req.headers.host.includes("myrobothome"); + mysqlConnection.query( + "select cursoferias from config;", + function (error, results, fields) { + let sqlQuery = `SELECT distinct + mt.IDMatricula, + cu.Codigo as 'IDCurso', + cu.NomeVersao, + cu.IDTipoCurso + FROM ${db}MatriculasTreinandos mt + INNER JOIN ${db}TreinandosTurmas tt ON mt.IDMatricula = tt.IDMatricula + INNER JOIN ${db}Cursos cu ON cu.Codigo = tt.IDCurso + WHERE mt.IDMatricula = ${idusers} AND cu.Desativado = 0 AND tt.Desistente = 0 AND cu.IDTipoCurso ${ + EAD ? "= 7" : "!= 5" + } + union all select + 0 as IDMatricula, + cu2.Codigo as 'IDCurso', + cu2.NomeVersao, + cu2.IDTipoCurso + from ${db}Cursos cu2 + where 1=0${ + results[0]["cursoferias"] == 1 ? " or cu2.CursoExtra = 1" : "" + }${EAD ? " or cu2.Adicional = 1" : ""};`; + //console.log(sqlQuery); + execSQLQuery2(sqlQuery, res, req.originalUrl); + } + ); + }); + + router.get( + "/getHomeCourseByStudent/:idusers/:banco", + verifyJWT, + (req, res) => { + const idusers = parseInt(req.params.idusers); + const db = req.params.banco; + const EAD = req.headers.host && req.headers.host.includes("myrobothome"); + mysqlConnection.query( + "select cursoferias from config;", + function (error, results, fields) { + let sqlQuery = `SELECT distinct + mt.IDMatricula, + cu.Codigo as 'IDCurso', + cu.NomeVersao, + cu.IDTipoCurso + FROM ${db}MatriculasTreinandos mt + INNER JOIN ${db}TreinandosTurmas tt ON mt.IDMatricula = tt.IDMatricula + INNER JOIN ${db}Cursos cu ON cu.Codigo = tt.IDCurso + WHERE mt.IDMatricula = ${idusers} AND cu.Desativado = 0 AND tt.Desistente = 0 AND + (cu.IDTipoCurso = 4 or cu.IDTipoCurso = 6 or cu.IDTipoCurso = 7) + union all select + 0 as IDMatricula, + cu2.Codigo as 'IDCurso', + cu2.NomeVersao, + cu2.IDTipoCurso + from ${db}Cursos cu2 + where (cu2.IDTipoCurso = 4 or cu2.IDTipoCurso = 6 or cu2.IDTipoCurso = 7) and + (1=0${ + results[0]["cursoferias"] == 1 ? " or cu2.CursoExtra = 1" : "" + }${EAD ? " or cu2.Adicional = 1" : ""});`; + console.log(sqlQuery); + execSQLQuery2(sqlQuery, res, req.originalUrl); + } + ); + } + ); + + router.get("/list", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + idcourses, + name, + description, + concat('R$ ',format(materialvalue,2,'de_DE')) as materialvalue, + disabled, + idtypescourse + FROM courses + WHERE disabled = 0 + order by name asc;`, + res, + req.originalUrl + ); + }); + + router.get("/disable/:idcourses", verifyJWT, (req, res) => { + const idcourses = parseInt(req.params.idcourses); + execSQLQuery( + `UPDATE courses SET + disabled = not disabled + WHERE idcourses = ${idcourses};`, + res, + req.originalUrl + ); + }); + + router.post("/insertSQL", verifyJWT, (req, res) => { + const coursecode = req.body.coursecode + const idtypescourse = parseInt(req.body.idtypescourse) + const name = req.body.name + const description = req.body.description + const durationtraineeprogram = req.body.durationtraineeprogram + const durationtraineevip = req.body.durationtraineevip + const durationtraineeindividual = req.body.durationtraineeindividual + const valueprogram = parseFloat(req.body.valueprogram) + const valuevip = parseFloat(req.body.valuevip) + const valueindividual = parseFloat(req.body.valueindividual) + const disabled = req.body.disabled + const materialvalue = parseFloat(req.body.materialvalue) + const materialcode = req.body.materialcode + const aditional = req.body.aditional + const extracourse = req.body.aditional + const autospeak = req.body.autospeak + console.log(req.body) + }) + + router.post("/insert", verifyJWT, (req, res) => { + const coursecode = req.body.coursecode; + const idtypescourse = parseInt(req.body.idtypescourse); + const name = req.body.name; + const description = req.body.description; + const durationtraineeprogram = req.body.durationtraineeprogram; + const durationtraineevip = req.body.durationtraineevip; + const durationtraineeindividual = req.body.durationtraineeindividual; + const valueprogram = parseFloat(req.body.valueprogram); + const valuevip = parseFloat(req.body.valuevip); + const valueindividual = parseFloat(req.body.valueindividual); + const materialvalue = parseFloat(req.body.materialvalue); + const materialcode = req.body.materialcode; + const extracourse = req.body.extracourse ? 1 : 0; + const aditional = req.body.aditional ? 1 : 0; + const disabled = req.body.disabled ? 1 : 0; + const autospeak = req.body.autospeak ? 1 : 0; + const idlanguage = req.body.idlanguage; + try { + execSQLQuery( + `INSERT INTO courses (coursecode, idtypescourse, name, description, durationtraineeprogram, durationtraineevip, durationtraineeindividual, valueprogram, valuevip, valueindividual, materialvalue, materialcode, extracourse, aditional, disabled, autospeak, idlanguage) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? , ?, ?, ?, ?);`, + res, + req.originalUrl, + [ + coursecode, + idtypescourse, + name, + description, + durationtraineeprogram, + durationtraineevip, + durationtraineeindividual, + valueprogram, + valuevip, + valueindividual, + materialvalue, + materialcode, + extracourse, + aditional, + disabled, + autospeak, + idlanguage, + ] + ); + } catch (error) { + console.log("oi"); + console.log(error); + } + }); + + router.patch("/update", verifyJWT, (req, res) => { + const idcourses = parseInt(req.body.idcourses); + const coursecode = req.body.coursecode; + const idtypescourse = parseInt(req.body.idtypescourse); + const name = req.body.name; + const description = req.body.description; + const durationtraineeprogram = req.body.durationtraineeprogram; + const durationtraineevip = req.body.durationtraineevip; + const durationtraineeindividual = req.body.durationtraineeindividual; + const valueprogram = parseFloat(req.body.valueprogram); + const valuevip = parseFloat(req.body.valuevip); + const valueindividual = parseFloat(req.body.valueindividual); + const materialvalue = parseFloat(req.body.materialvalue); + const materialcode = req.body.materialcode; + const extracourse = req.body.extracourse ? 1 : 0; + const aditional = req.body.aditional ? 1 : 0; + const disabled = req.body.disabled ? 1 : 0; + const autospeak = req.body.autospeak ? 1 : 0; + execSQLQuery( + `UPDATE courses SET + coursecode = ?, + idtypescourse = ?, + name = ?, + description = ?, + durationtraineeprogram = ?, + durationtraineevip = ?, + durationtraineeindividual = ?, + valueprogram = ?, + valuevip = ?, + valueindividual = ?, + materialvalue = ?, + materialcode = ?, + extracourse = ?, + aditional = ?, + disabled = ?, + autospeak = ? + WHERE idcourses = ?;`, + res, + req.originalUrl, + [ + coursecode, + idtypescourse, + name, + description, + durationtraineeprogram, + durationtraineevip, + durationtraineeindividual, + valueprogram, + valuevip, + valueindividual, + materialvalue, + materialcode, + extracourse, + aditional, + disabled, + autospeak, + idcourses, + ] + ); + }); + + router.get( + "/getCourseAndClass/:idusers/:idCursos/:idunits", + verifyJWT, + (req, res) => { + const idusers = parseInt(req.params.idusers); + const idunits = parseInt(req.params.idunits); + const WhereClause = req.params.idCursos; + const domain = req.hostname.split(".").pop(); + + let language; + + switch (domain) { + case "br": + language = 1; + break; + case "py": + language = 2; + break; + case "us": + language = 3; + break; + default: + language = 1; + break; + } + + let sqlQuery = `select distinct + *, + COALESCE(((R.actualItem / R.itensInClass) * 100) , 0) AS 'progressB' + FROM ( + select + co.*, + cl.idclasses, + cl.name AS 'nameC', + cl.description AS 'descriptionC', + cl.aval, + cl.demo, + COALESCE(sc.actualItem, 0) AS 'actualItem', + sc.continueClass, + sc.completedClass, + sc.lockedClass, + sc.liberado, + ROUND(sc.note, 2) AS 'note', + sc.notification, + sc.homework, + (select count(*) from userstages us where us.idunits = sc.idunits and us.idusers = sc.idusers and us.idclasses = sc.idclasses) as 'licao', + 0 AS 'showdet', + 0 AS 'btnVis', + COALESCE(sc.actualItem, 0) AS 'actualItenInClass', + (SELECT COUNT(*) AS 'qtdeItens' + from classescontent cc + LEFT join exercisequestions eq ON eq.idexercises = cc.idexercises + LEFT join media m ON m.idmedia = cc.idmedia + LEFT join texts t ON t.idtexts = cc.idtexts + LEFT join slides s ON s.idslides = cc.idslides + LEFT join texts g ON g.idtexts = cc.idgames AND t.game = 1 + where cc.idclasses = cl.idclasses) + AS 'itensInClass', + cl.download AS 'downloads', + cl.ordem, + (select count(*) from barcodes bc where bc.idunits = ${idunits} and bc.idusers = ${idusers} and bc.idcourses = co.idcourses) as 'Apostila' + from courses co + inner join classes cl on cl.idcourses = co.idcourses and cl.disabled = 0 + left join stepclass sc on sc.idclasses = cl.idclasses and sc.idusers = ${idusers} and sc.idunits = ${idunits} + WHERE ${ + idusers == 190001 ? "cl.demo = 1" : "co.idcourses in " + WhereClause + } AND co.disabled = 0 AND cl.homework = 0 and co.idtypescourse != 5 + AND co.idlanguage = ${language} OR co.idlanguage = 0 + ORDER BY co.name, cl.ordem ASC) R + ORDER BY R.name ASC, ordem ASC;`; + execSQLQuery(sqlQuery, res, req.originalUrl); + } + ); + + router.get( + "/getHomeCourseAndClass/:idusers/:idCursos/:idunits", + verifyJWT, + (req, res) => { + const idusers = parseInt(req.params.idusers); + const idunits = parseInt(req.params.idunits); + const WhereClause = req.params.idCursos; + let sqlQuery = `select distinct + *, + COALESCE(((R.actualItem / R.itensInClass) * 100) , 0) AS 'progressB' + FROM ( + select + co.*, + cl.idclasses, + cl.name AS 'nameC', + cl.description AS 'descriptionC', + cl.aval, + cl.demo, + COALESCE(sc.actualItem, 0) AS 'actualItem', + sc.continueClass, + sc.completedClass, + sc.lockedClass, + sc.liberado, + ROUND(sc.note, 2) AS 'note', + sc.notification, + sc.homework, + (select count(*) from userstages us where us.idunits = sc.idunits and us.idusers = sc.idusers and us.idclasses = sc.idclasses) as 'licao', + 0 AS 'showdet', + 0 AS 'btnVis', + COALESCE(sc.actualItem, 0) AS 'actualItenInClass', + (SELECT COUNT(*) AS 'qtdeItens' + from classescontent cc + LEFT join exercisequestions eq ON eq.idexercises = cc.idexercises + LEFT join media m ON m.idmedia = cc.idmedia + LEFT join texts t ON t.idtexts = cc.idtexts + LEFT join slides s ON s.idslides = cc.idslides + LEFT join texts g ON g.idtexts = cc.idgames AND t.game = 1 + where cc.idclasses = cl.idclasses) + AS 'itensInClass', + cl.download AS 'downloads', + cl.ordem, + (select count(*) from barcodes bc where bc.idunits = ${idunits} and bc.idusers = ${idusers} and bc.idcourses = co.idcourses) as 'Apostila' + from courses co + inner join classes cl on cl.idcourses = co.idcourses and cl.disabled = 0 + left join stepclass sc on sc.idclasses = cl.idclasses and sc.idusers = ${idusers} and sc.idunits = ${idunits} + WHERE ${ + idusers == 190001 ? "cl.demo = 1" : "co.idcourses in " + WhereClause + } AND co.disabled = 0 AND cl.homework = 0 and co.idtypescourse != 5 + and (co.idtypescourse = 4 or co.idtypescourse = 6 or co.idtypescourse = 7) + ORDER BY co.name, cl.ordem ASC) R + ORDER BY R.name ASC, ordem ASC;`; + execSQLQuery(sqlQuery, res, req.originalUrl); + console.log(sqlQuery); + } + ); + + return router; +}; + +module.exports = routes; diff --git a/controllers/coursesStudentController.js b/controllers/coursesStudentController.js new file mode 100644 index 0000000..0726f01 --- /dev/null +++ b/controllers/coursesStudentController.js @@ -0,0 +1,35 @@ +require('../connections/sql-server'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/courses/:idmatricula/:idtreinando', (req, res) => { + const idmatricula = parseInt(req.params.idmatricula); + const idtreinando = parseInt(req.params.idtreinando); + + execSQLQuery(` + select TT.IDCurso, TT.IDMatricula, TT.IDTreinando, + C.NomeVersao + from TreinandosTurmas TT + inner join Cursos C + on C.Codigo = TT.IDCurso + inner join TurmasDetalhe TD + on TD.IDTurma = TT.CodigoTurma + and TD.CodigoCurso = TT.IDCurso + where TT.IDMatricula = ${idmatricula} + and TT.IDTreinando = ${idtreinando} + order by TD.Ordem asc`, + res, + req.originalUrl + ); + }) + + return router; +}; + +module.exports = routes; diff --git a/controllers/curiositiesController.js b/controllers/curiositiesController.js new file mode 100644 index 0000000..153f3ce --- /dev/null +++ b/controllers/curiositiesController.js @@ -0,0 +1,89 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); + +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ + limit: '10mb', + extended: true + } +)); +router.use(bodyParser.json({ + limit: '10mb', + extended: true +})); + +var routes = function () { + + router.get('/getAll', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM curiosities;`, res, req.originalUrl); + }); + + router.get('/getById/:idcuriosities', verifyJWT, (req, res) => { + const idcuriosities = parseInt(req.params.idcuriosities); + execSQLQuery(`SELECT + * + FROM curiosities + WHERE idcuriosities = ${idcuriosities};`, res, req.originalUrl); + }); + + router.post('/insert', verifyJWT, (req, res) => { + const idcuriosities = parseInt(req.body.idcuriosities); + const src = req.body.src; + const description = req.body.description; + const itens = parseInt(req.body.itens); + execSQLQuery(`INSERT INTO curiosities (src, description, itens) + VALUES (?, ?, ?);`, res, req.originalUrl, [src, description, itens]); + }); + + router.patch('/update', verifyJWT, (req, res) => { + const idcuriosities = parseInt(req.body.idcuriosities); + const src = req.body.src; + const description = req.body.description; + const itens = req.body.itens; + execSQLQuery(`UPDATE curiosities SET + src = ?, + description = ?, + itens = ? + WHERE idcuriosities = ?;`, res, req.originalUrl, [src, description, itens, idcuriosities]); + }); + + router.post('/copy', verifyJWT, (req, res) => { + var base64ToImage = require('base64-to-image'); + var img64 = req.body.src; + var Name = req.body.name; + var Obj = {'fileName': Name, 'type':'jpg'}; + var path = Variables('src_media') + 'files/'; + if(base64ToImage(img64,path,Obj)) { + res.send(true) + } + else { + res.send(false); + } + //res.send("images uploaded with success!"); + }); + + router.post('/backimg', verifyJWT, (req, res) => { + var base64Img = require('base64-img'); + var name = req.body.name; + var src = Variables('src_media') + 'files/' + name + '.jpg'; + if(base64Img.base64Sync(src)) { + var srcCuriosity = base64Img.base64Sync(src); + } else { + var srcCuriosity = ""; + } + var imagens = { + srcCuriosity: srcCuriosity + } + res.send(imagens); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/customizeController.js b/controllers/customizeController.js new file mode 100644 index 0000000..175a179 --- /dev/null +++ b/controllers/customizeController.js @@ -0,0 +1,66 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/getInfo/:idUser/:idUnit', verifyJWT, (req, res) => { + console.log(req.body); + const idUser = parseInt(req.params.idUser); + const idUnit = parseInt(req.params.idUnit); + execSQLQuery(`SELECT * + FROM customizeZoeProfile + WHERE idAluno = ${idUser} AND idUnit = ${idUnit};`, res, req.originalUrl); + }); + + router.post('/insertNew', verifyJWT, (req, res) => { + const idUser = parseInt(req.body.idUser); + const idUnit = parseInt(req.body.idUnit); + execSQLQuery(`INSERT INTO + customizeZoeProfile (idAluno, idUnit, boughtItens) + VALUES (${idUser}, ${idUnit}, + "Eyes_Blue;Eyes_Green;Eyes_Red;Eyes_Yellow;Eyes_White;Cheek_Basic;");`, res, req.originalUrl); + }); + + router.post('/updateCoins', verifyJWT, (req, res) => { + const coinsToAdd = parseInt(req.body.coinsToAdd); + const idUser = parseInt(req.body.idUser); + const idUnit = parseInt(req.body.idUnit); + execSQLQuery(`UPDATE customizeZoeProfile + SET coins = coins + ${coinsToAdd} + WHERE idAluno = ${idUser} AND idUnit = ${idUnit};`, res, req.originalUrl); + }); + + router.post('/updateItens', verifyJWT, (req, res) => { + const itemToAdd = req.body.itemToAdd; + const coinsToRemove = parseInt(req.body.coinsToRemove); + const idUser = parseInt(req.body.idUser); + const idUnit = parseInt(req.body.idUnit); + execSQLQuery(`UPDATE customizeZoeProfile + SET coins = coins - ${coinsToRemove}, boughtItens = '${itemToAdd}' + WHERE idAluno = ${idUser} AND idUnit = ${idUnit};`, res, req.originalUrl); + }); + + router.post('/updateActualItens', verifyJWT, (req, res) => { + const newActuals = req.body.newActuals; + const idUser = parseInt(req.body.idUser); + const idUnit = parseInt(req.body.idUnit); + execSQLQuery(`UPDATE customizeZoeProfile + SET actualItens = '${newActuals}' + WHERE idAluno = ${idUser} AND idUnit = ${idUnit};`, res, req.originalUrl); + }); + + router.get('/getItensCustomize', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * + FROM zoeCustomizeItens`, res, req.originalUrl); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/elloController.js b/controllers/elloController.js new file mode 100644 index 0000000..c5a0550 --- /dev/null +++ b/controllers/elloController.js @@ -0,0 +1,67 @@ +require('../connections/mysql-server'); + +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + router.get('/getStudents/:codello/:startdate/:enddate/:tkapi', (req, res) => { + + let codello = req.params.codello; + let tkapi = req.params.tkapi; + let startdate = req.params.startdate; + let enddate = req.params.enddate; + + let sqlQry = `select reference_db, studenthourvalue + from units + cross join config + where codello = ${codello} + and tk_api = '${tkapi}'`; + + mysqlConnection.query(sqlQry, function (error, results, fields) { + if (!error && results.length != 0) { + + var studenthourvalue = results[0]['studenthourvalue']; + var reference_db = results[0]['reference_db']; + + let sqlQry = `select *, + (ceiling(convert(decimal(10,2),HoraAula)/8) * ${studenthourvalue}) as Valor + from ( + select TT.IDMatricula as Matricula, + C.Nome as Nome, + sum(datediff(HOUR,TC.HoraInicial,TC.HoraFinal)) as HoraAula + from ${reference_db}.dbo.TreinandosTurmas TT + inner join ${reference_db}.dbo.TurmasCalendario TC + on TC.IdTurma = TT.CodigoTurma + and TC.CodigoCurso = TT.IDCurso + inner join ${reference_db}.dbo.Clientes C + on C.IDCliente = TT.IDTreinando + where TC.Ministrado = 1 + and TT.IDMatricula > 190008 + and TC.Data between '${startdate}' and '${enddate}' + group by IDMatricula, Nome + ) Res + order by Matricula asc`; + + sqlServerConnection.request().query(sqlQry, function (error2, results2, fields) { + if (!error2 && results2.length != 0) { + //console.log(results2.recordset); + res.status(200).send(results2.recordset); + } else { + res.status(500).send('Não foram encontrados resultados para a pesquisa'); + } + }); + } + else { + res.status(500).send('Código do Cliente ou Token Inválido'); + } + }); + }) + + return router; +} + +module.exports = routes; \ No newline at end of file diff --git a/controllers/emailController.js b/controllers/emailController.js new file mode 100644 index 0000000..ecffff7 --- /dev/null +++ b/controllers/emailController.js @@ -0,0 +1,345 @@ +require('../connections/mysql-server'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var nodemailer = require('nodemailer'); + +var transporter = nodemailer.createTransport({ + //service: 'gmail', + host: "email-ssl.com.br", + port: 465, + secure: true, + auth: { + //user: 'trocasenhamyrobot@gmail.com', + //pass: 'trocasenhamyrobot2021', + //user: 'iyrconline@myrobot.com.br', + //pass: 'iyrcMyrobot@2255', + //user: 'myrobotschool@gmail.com', + //pass: 'myrobot2020**==', + user: 'staff@myrobot.com.br', + pass: 'stAff66**' + } +}); + +var routes = function () { + + router.post('/send', (req, res) => { + EnviarEmail(req.body.to, req.body.subject, req.body.text, function(Sucesso) { + res.send(Sucesso); + }); + }); + + function EnviarEmail(Email, Assunto, Texto, callback) { + var mailOptions = { + from: 'MyRobot School ', + to: Email, + subject: Assunto, + html: Texto, + /*attachments: [{ // Basta incluir esta chave e listar os anexos + filename: 'boleto.pdf', // O nome que aparecerá nos anexos + path: 'servidor/boletos/boleto_gerado1234.pdf' // O arquivo será lido neste local ao ser enviado + }]*/ + }; + transporter.sendMail(mailOptions, function (error, info) { + if (error) { + console.log(error); + callback(false); + } else { + console.log('Email sent to: ' + mailOptions.to + ' - ' + info.response); + callback(true); + } + }); + } + + router.get('/getRequest/:encript', (req, res) => { + encript = req.params.encript; + execSQLQuery(`SELECT * FROM requestpass WHERE encript = '${encript}'`, res, req.originalUrl); + }) + + router.get('/getReqNotExpired/:idusers/:email/:db', (req, res) => { + id = req.params.idusers; + email = req.params.email; + db = req.params.db; + execSQLQuery(` + SELECT * + FROM requestpass + WHERE registration = '${id}' AND email = '${email}' AND db = '${db}'`, + res, + req.originalUrl + ); + }) + + router.post('/insert', (req, res) => { + const idrequestpass = req.body.idrequestpass; + const registration = req.body.registration; + const email = req.body.email; + const encript = req.body.encript; + const db = req.body.db; + const expired = req.body.expired; + execSQLQuery(` + INSERT INTO + requestpass( + registration, email, encript, db, expired + ) VALUES ( + ${registration}, '${email}', '${encript}', '${db}', ${expired} + )`, + res, + req.originalUrl + ); + }) + + router.patch('/update', (req, res) => { + const idrequestpass = req.body.idrequestpass; + const registration = req.body.registration; + const email = req.body.email; + const encript = req.body.encript; + const db = req.body.db; + const expired = req.body.expired; + execSQLQuery(` + UPDATE + requestpass SET + registration = ${registration}, + email = '${email}', + encript = '${encript}', + db = '${db}', + expired = ${expired} + WHERE idrequestpass = ${idrequestpass}`, + res, + req.originalUrl + ); + }) + + router.patch('/expired', (req, res) => { + const idrequestpass = req.body.idrequestpass; + const expired = req.body.expired; + execSQLQuery(` + UPDATE + requestpass SET + expired = ${expired} + WHERE idrequestpass = ${idrequestpass}`, + res, + req.originalUrl + ); + }) + + router.post('/insertLeadsSite', (req, res) => { + const idleadseventos = parseInt(req.body.idleadseventos); + const idunits = parseInt(req.body.idunits); + const nome = req.body.nome; + let telefone = req.body.telefone; + let email = req.body.email; + const horario = req.body.horario; + const formacontato = req.body.forma; + const contato = req.body.contato; + + if(formacontato === "WhatsApp") { + telefone = contato; + req.body.telefone = telefone; + } else if(formacontato === "Email") { + email = contato; + req.body.email = email; + } + + mysqlConnection.query(`insert into leadssite (idleadseventos, idunits, nome, telefone, email, horario) values (?, ?, ?, ?, ?, ?);`, [idleadseventos, idunits, nome, telefone, email, horario], function (error, response, fields) { + mysqlConnection.query(`select + un.unityname, + un.manager, + un.email, + le.descricao, + le.idleadseventos + from units un + inner join leadseventos le on le.idleadseventos = ${idleadseventos} + where un.idunits = ${idunits};`, function (error, InfoUnidade, fields) { + const Assunto = InfoUnidade[0]['descricao']; + const Texto = MontaEmailCaptacaoLeadsSite(InfoUnidade[0], req.body); + EnviarEmail(InfoUnidade[0]['email'], Assunto, Texto, function(Sucesso) { + + const EmailInterno = "joao.pedro@makereducacao.com.br"; + EnviarEmail(EmailInterno, Assunto, Texto, function(Sucesso2) { + res.send(Sucesso); + }); + + }); + }); + }); + }); + + function MontaEmailCaptacaoLeadsSite(DadosEvento, DadosLead) { + let TextoEmail = ""; + + switch (DadosEvento.idleadseventos) { + case 1: + let Contato = DadosLead.contato; + let BotaoContato = ""; + let OldContato = Contato; + + if(DadosLead.forma === "WhatsApp") { + Contato = Contato.replace("(" , "").replace(")","").replace(" ","").replace("-",""); + BotaoContato = `
Entrar em contato
`; + } else if (DadosLead.forma === "Email") { + BotaoContato = `
Entrar em contato
` + } + + TextoEmail = ` +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+ +
+
+
+
+
+
Nova visita agendada!
+
+
Nome: ${DadosLead.nome}
+
Horario: ${DadosLead.horario}
+
Forma de contato: ${DadosLead.forma}
+
Contato: ${OldContato}
+ ${BotaoContato} +
+
+
+
+
+
+
+
+ + + + + + +
+
+
+ `; + break; + + case 2: + TextoEmail = `
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+ +
+
+
+
+
+
Novo lead captado!
+
+
Nome: ${DadosLead.nome}
+
Telefone: ${DadosLead.telefone}
+
Email: ${DadosLead.email}
+ + +
+
+
+
+
+
+
+
+ + + + + + +
+
+
+ `; + break; + } + + return TextoEmail; + } + + + return router; +} + +module.exports = routes; diff --git a/controllers/exerciseController.js b/controllers/exerciseController.js new file mode 100644 index 0000000..005ffcd --- /dev/null +++ b/controllers/exerciseController.js @@ -0,0 +1,138 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM exercises;`, res, req.originalUrl); + }); + + router.get('/types', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM exercisetype + WHERE enabled = 1;`, res, req.originalUrl); + }); + + // router.get('/getExercise/:id', verifyJWT, (req, res) => { + // let id = req.params.id; + // execSQLQuery(` + // SELECT + // e.idexercises as 'exercise_id', + // e.description as 'exercise_desc', + // e.idexercisetype as 'exercise_type', + // eq.idexercisequestions as 'question_id', + // eq.content as question, + // ea.idexerciseanswers as 'answer_id', + // ea.content as answer + // FROM exercises e + // JOIN exercisequestions eq ON e.idexercises = eq.idexercises + // JOIN exerciseanswers ea ON eq.idexercisequestions = ea.idexercisequestions + // WHERE e.idexercises = ${id} + // ORDER BY eq.idexercisequestions, ea.idexerciseanswers ASC;`, + // res, + // req.originalUrl + // ); + // }) + + router.get('/getExercise2/:idexercises', verifyJWT, (req, res) => { + const idexercises = parseInt(req.params.idexercises); + execSQLQuery(`SELECT + * + FROM exercises + WHERE idexercises = ${idexercises};`, res, req.originalUrl); + }); + + router.get('/:idexercises/getQuestions', verifyJWT, function (req, res, next) { + const idexercises = req.params.idexercises; + execSQLQuery(`SELECT + * + FROM exercisequestions + WHERE idexercises = ${idexercises};`, res, req.originalUrl); + }); + + router.get('/:idexercisequestions/getQuestionsById', verifyJWT, function (req, res, next) { + const idexercisequestions = parseInt(req.params.idexercisequestions); + execSQLQuery(`SELECT + * + FROM exercisequestions + WHERE idexercisequestions = ${idexercisequestions};`, res, req.originalUrl); + }); + + router.get('/getExercise/:idexercises', verifyJWT, function (req, res, next) { + const idexercises = parseInt(req.params.idexercises); + execSQLQuery(`SELECT + e.description, + e.enabled, + e.idexercises, + e.idexercisetype, + cc.idclasses + FROM exercises e + JOIN classescontent cc ON e.idexercises = cc.idexercises + WHERE e.idexercises = ${idexercises};`, res, req.originalUrl); + }); + + router.get('/:id/getExercises', verifyJWT, function (req, res, next) { + const idclasses = parseInt(req.params.idclasses); + execSQLQuery(`SELECT + * + FROM exercises + WHERE idclasses = ${idclasses};`, res, req.originalUrl); + }); + + router.post('/insert', verifyJWT, function (req, res) { + const description = req.body.description; + const idexercisetype = parseInt(req.body.idexercisetype); + const enabled = req.body.enabled ? 1 : 0; + execSQLQuery(`INSERT INTO exercises (idexercisetype, description, hasmedia, enabled) + VALUES (?, ?, 0, ?);`, res, req.originalUrl, [idexercisetype, description, enabled]); + }); + + router.patch('/update', verifyJWT, function (req, res) { + const idexercises = parseInt(req.body.idexercises); + const description = req.body.description; + const idexercisetype = parseInt(req.body.idexercisetype); + const enabled = req.body.enabled ? 1 : 0; + execSQLQuery(`UPDATE exercises SET + description = ?, + idexercisetype = ?, + enabled = ? + WHERE idexercises = ?;`, res, req.originalUrl, [description, idexercisetype, enabled, idexercises]); + }); + + router.get('/allExercises', (req, res) => { + execSQLQuery(`SELECT + * + FROM exercises;`, res, req.originalUrl); + }); + + router.get('/allExerciseQuestions', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM exercisequestions;`, res, req.originalUrl); + }); + + router.get('/allExerciseAnswers', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM exerciseanswers;`, res, req.originalUrl); + }); + + router.get('/allExerciseType', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM exercisetype;`, res, req.originalUrl); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/fileController.js b/controllers/fileController.js new file mode 100644 index 0000000..9193953 --- /dev/null +++ b/controllers/fileController.js @@ -0,0 +1,235 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); +const formidable = require('formidable'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ + limit: '50mb', + extended: true +})); +router.use(bodyParser.json({ + limit: '50mb', + extended: true +})); + +var routes = function () { + + router.get('/getAll/', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM files;`, res, req.originalUrl); + }); + + router.get('/getFile/:idfiles', verifyJWT, (req, res) => { + const idfiles = parseInt(req.params.idfiles); + execSQLQuery(`SELECT + * + FROM files + WHERE idfiles = ${idfiles};`, res, req.originalUrl); + }); + + router.post('/insert', verifyJWT, (req, res) => { + const description = req.body.description; + const src = req.body.src; + const extension = req.body.extension; + execSQLQuery(`INSERT INTO files (description, src, extension) + VALUES (?, ?, ?);`, res, req.originalUrl, [description, src, extension]); + }); + + router.patch('/update', verifyJWT, (req, res) => { + const idfiles = req.body.idfiles; + const description = req.body.description; + const src = req.body.src; + const extension = req.body.extension; + execSQLQuery(`UPDATE files SET + description = ?, + src = ?, + extension = ? + WHERE idfiles = ?;`, res, req.originalUrl, [description, src, extension, idfiles]); + }); + + router.get('/delete/:idfiles', verifyJWT, (req, res) => { + const idfiles = req.params.idfiles; + mysqlConnection.query(`SELECT * FROM files where idfiles in (${idfiles});`, function (error, Arquivos, fields) { + mysqlConnection.query(`delete from files where idfiles in (${idfiles});`, function (error, results, fields) { + ExcluirArquivos(Arquivos, 0, function(Sucesso) { + res.send(Sucesso); + }); + }); + }); + }); + + function ExcluirArquivos(Arquivos, Index, callback) { + if (Index < Arquivos.length) { + const fs = require('fs'); + let dir = Variables('src_media') + Arquivos[Index]['src'].split('/')[3] + "/" + Arquivos[Index]['src'].split('/')[4]; + if(fs.existsSync(dir)) { + fs.unlink(dir, function(err) { + Index++; + ExcluirArquivos(Arquivos, Index, callback); + }); + } + else { + Index++; + ExcluirArquivos(Arquivos, Index, callback); + } + } + else { + callback(true); + } + } + + router.post('/copy', verifyJWT, (req, res) => { + let form = new formidable.IncomingForm(); + form.maxFileSize = 600 * 1024 * 1024; + form.parse(req, function(err,fields,files){ + const fs = require('fs'); + var name = fields.name; + var dir = Variables('src_media') + 'files/' + name; + + var oldpath = files.file.path; + if(fs.existsSync(dir)) { + fs.unlink(dir, function(err) { + fs.rename(oldpath, dir, function (err) { + res.send(true); + }) + }); + } + else { + fs.rename(oldpath, dir, function (err) { + res.send(true); + }) + } + }); + }); + + // VIDEOS + + router.get('/getAll1/', verifyJWT, (req, res) => { + execSQLQuery(`SELECT f.idfiles, f.description, f.src, f.extension, 'Arquivo' as type FROM files f;`, res, req.originalUrl); + }) + + router.get('/getAllVideos/', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * FROM videos;`, res, req.originalUrl); + }) + + router.get('/getAllVideos1/', verifyJWT, (req, res) => { + execSQLQuery(`SELECT v.idvideos as idfiles, v.description, concat('https://myrobot.cdn.vooplayer.com/publish/', v.publishid) as src, '.mp4' as extension, 'Vídeo' as type FROM videos v;`, res, req.originalUrl); + }) + + router.get('/getVideo/:idvideos', verifyJWT, (req, res) => { + let idvideos = parseInt(req.params.idvideos); + execSQLQuery(`SELECT * FROM videos WHERE idvideos = ${idvideos};`, res, req.originalUrl); + }) + + router.post('/getVideoFiltrado', verifyJWT, (req, res) => { + const filtro = req.body.filtro; + + execSQLQuery(`SELECT * FROM videos WHERE description LIKE "%${filtro}%";`, res, req.originalUrl); + }) + + router.post('/insertVideo', verifyJWT, (req, res) => { + const idvideos = req.body.idvideos; + const publishId = req.body.publishId; + const description = req.body.description; + + execSQLQuery(`INSERT INTO videos(publishId, description) VALUES ('${publishId}','${description}');`, res, req.originalUrl); + }) + + router.patch('/updateVideo', verifyJWT, (req, res) => { + const idvideos = req.body.idvideos; + const publishId = req.body.publishId; + const description = req.body.description; + execSQLQuery(`UPDATE videos SET publishId = '${publishId}', description = '${description}' WHERE idvideos = ${idvideos};`, + res, req.originalUrl); + }) + + + + router.post('/CopiarBase64', verifyJWT, (req, res) => { + let form = new formidable.IncomingForm(); + form.maxFileSize = 600 * 1024 * 1024; + form.parse(req, function(err, fields, files) { + var base64ToImage = require('base64-to-image'); + const name = fields.name; + const ext = fields.ext.replace('.', ''); + const base64 = fields.base64; + const ArrDir = name.split('/'); + let Diretorio = ""; + for (let i = 0; i < ArrDir.length; i++) { + if (i < ArrDir.length - 1) + Diretorio += ArrDir[i] + "/"; + } + const ArrNome = ArrDir[ArrDir.length - 1].split('.'); + let NomeArquivo = ""; + for (let i = 0; i < ArrNome.length; i++) { + if (i < ArrNome.length - 1) + NomeArquivo += ArrNome[i] + "."; + } + NomeArquivo = NomeArquivo.substring(0, NomeArquivo.length - 1); + var ArquivoCopia = { 'fileName': NomeArquivo, 'type': 'jpg' }; + if (base64ToImage(base64, Variables('src_media') + Diretorio, ArquivoCopia)) { + res.send(true); + } + else { + res.send(false); + } + }); + }); + + router.post('/CopiaArquivos', verifyJWT, (req, res) => { + let form = new formidable.IncomingForm(); + form.maxFileSize = 600 * 1024 * 1024; + form.parse(req, function(err,fields,files){ + const fs = require('fs'); + var name = fields.name; + + var oldpath; + try { + oldpath = files.file.path; + } + catch(e) { + console.log(req.originalUrl + " error 500 - Não foi enviado o arquivo para upload no servidor: " + e); + res.send(false); + return; + } + + const ArrDir = name.split('/'); + let Diretorio = ""; + for (let i = 0; i < ArrDir.length; i++) { + if (i < ArrDir.length - 1) + Diretorio += ArrDir[i] + "/"; + } + + var dirArquivo = Variables('src_media') + name; + var dirPasta = Variables('src_media') + Diretorio; + + if (!fs.existsSync(dirPasta)) + fs.mkdirSync(dirPasta); + + if (fs.existsSync(dirArquivo)) { + fs.unlink(dirArquivo, function(err) { + //console.log(err); + fs.rename(oldpath, dirArquivo, function (err) { + console.log(err); + res.send(true); + console.log(req.originalUrl + " success 200"); + }); + }); + } + else { + fs.rename(oldpath, dirArquivo, function (err) { + res.send(true); + console.log(req.originalUrl + " success 200"); + }); + } + }); + }); + + return router; +}; + +module.exports = routes; \ No newline at end of file diff --git a/controllers/franchiseeController.js b/controllers/franchiseeController.js new file mode 100644 index 0000000..62ab4ac --- /dev/null +++ b/controllers/franchiseeController.js @@ -0,0 +1,476 @@ +require('../connections/mysql-server'); +require('../connections/sql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); +const formidable = require('formidable'); +const fs = require('fs'); +const { userInfo } = require('os'); + +router.use(bodyParser.urlencoded({ + limit: '150mb', + extended: true +})); +router.use(bodyParser.json({ + limit: '150mb', + extended: true +})); + +var routes = function () { + + router.get('/getVideos/:idFolder', verifyJWT, (req, res) => { + const idFolder = parseInt(req.params.idFolder); + execSQLQuery(`SELECT + * + FROM franchisee_media + WHERE franchisee_media.type = 'video' AND franchisee_media.folder_key = ${idFolder};`, res, req.originalUrl); + }); + + router.get('/getFiles/:idFolder/:userFor', verifyJWT, (req, res) => { + const idFolder = parseInt(req.params.idFolder); + const userFor = parseInt(req.params.userFor); + execSQLQuery(`SELECT + * + FROM franchisee_media + WHERE ((franchisee_media.type = 'file' OR franchisee_media.type = 'download' + OR franchisee_media.type = 'img') AND franchisee_media.folder_key = ${idFolder}) AND userFor = ${userFor} + ORDER BY description ASC;`, res, req.originalUrl); + }); + + + router.get('/getAllFoldersV', verifyJWT, (req, res) => { + execSQLQuery(`select * from ( + select + ff.idfranchisee_folder, + ff.folder_type, + ff.folder_description, + ff.folder_into + from franchisee_folders ff + where ff.folder_type = 'videos' and ff.folder_into = 0 + union all + select + ff.idfranchisee_folder, + ff.folder_type, + concat(ff.folder_description, ' - (', ff2.folder_description, '/', ff.folder_description, ')') as 'folder_description', + ff.folder_into + from franchisee_folders ff + inner join franchisee_folders ff2 on ff2.idfranchisee_folder = ff.folder_into + where ff.folder_type = 'videos' and ff.folder_into > 0) R + order by R.folder_description asc`, res, req.originalUrl); + }); + + router.get('/getFoldersV', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM franchisee_folders + WHERE folder_type = 'videos' AND folder_into = 0 + order by folder_description asc;`, res, req.originalUrl); + }); + + router.get('/getFoldersV2/:idFolder', verifyJWT, (req, res) => { + const idFolder = parseInt(req.params.idFolder); + execSQLQuery(`SELECT + * + FROM franchisee_folders + WHERE folder_type = 'videos' AND folder_into = ${idFolder} + order by folder_description asc;`, res, req.originalUrl); + }); + + + router.get('/getAllFoldersF/:userFor', verifyJWT, (req, res) => { + const userFor = parseInt(req.params.userFor); + execSQLQuery(`select * from ( + select + ff.idfranchisee_folder, + ff.folder_type, + ff.folder_description, + ff.folder_into + from franchisee_folders ff + where ff.folder_type = 'files' and ff.folder_into = 0 and ff.userFor = ${userFor} + union all + select + ff.idfranchisee_folder, + ff.folder_type, + concat(ff.folder_description, ' - (', ff2.folder_description, '/', ff.folder_description, ')') as 'folder_description', + ff.folder_into + from franchisee_folders ff + inner join franchisee_folders ff2 on ff2.idfranchisee_folder = ff.folder_into + where ff.folder_type = 'files' and ff.folder_into > 0 and ff.userFor = ${userFor}) R + order by R.folder_description asc`, res, req.originalUrl); + }); + + router.get('/getFoldersF/:userFor', verifyJWT, (req, res) => { + const userFor = parseInt(req.params.userFor); + execSQLQuery(` + SELECT + * + FROM + franchisee_folders + WHERE + franchisee_folders.folder_type = 'files' AND franchisee_folders.folder_into = 0 + AND franchisee_folders.userFor = ${userFor} + ORDER BY folder_description ASC;`, + res, + req.originalUrl + );}) + + router.get('/getFoldersF2/:idFolder/:userFor', verifyJWT, (req, res) => { + const idFolder = parseInt(req.params.idFolder); + const userFor = parseInt(req.params.userFor); + execSQLQuery(`SELECT + * + FROM franchisee_folders + WHERE folder_into = ${idFolder} AND folder_type != 'DESATIVADO' AND userFor = ${userFor} + ORDER BY folder_description ASC;`, res, req.originalUrl); + }); + + + router.get('/Exclude/:idfranchisee_media', verifyJWT, (req, res) => { + const idfranchisee = parseInt(req.params.idfranchisee_media); + execSQLQuery(` + DELETE FROM + franchisee_media + WHERE + franchisee_media.idfranchisee_media = ${idfranchisee}`, + res, + req.originalUrl + );}) + + router.get('/Disable/:idfranchisee_media', verifyJWT, (req, res) => { + const idfranchisee = parseInt(req.params.idfranchisee_media); + execSQLQuery(`UPDATE franchisee_media SET type = 'DESATIVADO' WHERE idfranchisee_media = ${idfranchisee}`, res, req.originalUrl); + }) + + router.get('/ExcludeF/:idfranchisee_folder', verifyJWT, (req, res) => { + const idfranchisee = parseInt(req.params.idfranchisee_folder); + execSQLQuery(` + DELETE FROM + franchisee_folders + WHERE + idfranchisee_folder = ${idfranchisee}`, + res, + req.originalUrl + );}) + + router.get('/getAll', verifyJWT, (req, res) => { + execSQLQuery(` + SELECT + * + FROM + franchisee_media`, + res, + req.originalUrl + ); + }) + + router.get('/getAllWithDescription', verifyJWT, (req, res) => { + execSQLQuery(` + SELECT + fm.idfranchisee_media, + fm.description, + fm.publishid, + fm.type, + fm.folder_key, + ff.folder_description + FROM + franchisee_media fm + INNER JOIN + franchisee_folders ff ON ff.idfranchisee_folder = fm.folder_key;`, + res, + req.originalUrl + ); + }) + + router.get('/getAllF', verifyJWT, (req, res) => { + execSQLQuery(` + SELECT + * + FROM + franchisee_folders`, + res, + req.originalUrl + ); + }) + + router.get('/getOne/:idfranchisee_media/:userFor', verifyJWT, (req, res) => { + const idfranchisee_media = parseInt(req.params.idfranchisee_media); + const userFor = parseInt(req.params.userFor); + execSQLQuery(` + SELECT + * + FROM + franchisee_media + WHERE + idfranchisee_media = ${idfranchisee_media} AND userFor = ${userFor}`, + res, + req.originalUrl + ); + }) + + router.get('/getOneF/:idfranchisee_folder/:userFor', verifyJWT, (req, res) => { + const idfranchisee_folder = parseInt(req.params.idfranchisee_folder); + const userFor = parseInt(req.params.userFor); + execSQLQuery(`SELECT + * + FROM franchisee_folders + WHERE franchisee_folders.idfranchisee_folder = ${idfranchisee_folder} + AND franchisee_folders.userFor = ${userFor};`, res, req.originalUrl); + }); + + router.patch('/update', verifyJWT, (req, res) => { + const idfranchisee_media = req.body.idfranchisee_media; + const description = req.body.description; + const type = req.body.type; + const publishid = req.body.publishid; + const folder_key = req.body.folder_key; + const userFor = req.body.userFor; + execSQLQuery(` + UPDATE + franchisee_media + SET + description = "${description}", + publishid = '${publishid}', + type = '${type}', + folder_key = ${folder_key}, + userFor = ${userFor} + WHERE + idfranchisee_media = ${idfranchisee_media}`, + res, + req.originalUrl + ); + }) + + router.post('/insert', verifyJWT, (req, res) => { + const description = req.body.description; + const type = req.body.type; + const publishid = req.body.publishid; + const folder_key = req.body.folder_key; + const userFor = req.body.userFor; + execSQLQuery(`INSERT INTO franchisee_media (description, type, publishid, folder_key, userFor) + VALUES (?, ?, ?, ?, ?);`, res, req.originalUrl, [description, type, publishid, folder_key, userFor]); + }); + + router.post('/insertF', verifyJWT, (req, res) => { + const folder_type = req.body.folder_type; + const folder_description = req.body.folder_description; + const folder_into = req.body.folder_into; + const userFor = req.body.userFor; + execSQLQuery(`INSERT INTO franchisee_folders (folder_type, folder_description, folder_into, userFor) + VALUES (?, ?, ?, ?);`, res, req.originalUrl, [folder_type, folder_description, folder_into, userFor]); + }); + + router.post('/copy', verifyJWT, (req, res) => { + var base64ToImage = require('base64-to-image'); + var id = req.body.id; + var backStr = req.body.back; + var backThumb = req.body.backThumb; + var backName = 'franch_' + id; + var backNameT = 'franchThumb_' + id; + var Objback = { 'fileName': backName, 'type': 'jpg' }; + var ObjbackT = { 'fileName': backNameT, 'type': 'jpg' }; + var path = Variables('src_media') + 'images/'; + if(base64ToImage(backStr, path, Objback)){ + if (base64ToImage(backThumb, path, ObjbackT)){ + res.send(true); + }else{res.send(false);} + }else {res.send(false);} + }); + + router.post('/copy1', verifyJWT, (req, res) => { + let form = new formidable.IncomingForm(); + form.maxFileSize = 600 * 1024 * 1024; + form.parse(req, function(err,fields,files){ + const fs = require('fs'); + var id = fields.id; + var backThumb = fields.backThumb; + var dir = Variables('src_media') + 'images/'; + var extension = files.back.name.toString(); + var arrExt = extension.split('.'); + extension = "." + arrExt[arrExt.length - 1]; + console.log("name: " + id + " - dir: " + dir + " - extension: " + extension); + try { + fs.unlink(dir + "franch_" + id + extension, function(err) {}); + } + catch(err) { + console.log("arquivo não existe"); + } + var oldpath = files.back.path; + fs.rename(oldpath, dir + "franch_" + id + extension, function (err) { + if (err) { + res.send(false); + throw err; + } + else { + var base64ToImage = require('base64-to-image'); + var ObjbackT = { 'fileName': 'franchThumb_' + id, 'type': 'jpg' }; + if (base64ToImage(backThumb, dir, ObjbackT)) { + res.send(true); + } + else { + res.send(false); + } + } + }); + }); + }); + + router.post('/copyFile', (req, res) => { + + var localPath = req.body.back; + var filetoupload = req.body.filetoupload; + var form = new formidable.IncomingForm(); + console.log(localPath); + form.parse(req, function (_err, _fields, files) { + console.log("Entrou no parse"); + var oldpath = localPath; + console.log(oldpath); + var newpath = Variables('src_media') + 'franchiseeZip/' + filetoupload.name; + console.log("EntrouCopy"); + fs.rename(toString(oldpath), toString(newpath), function (err) { + console.log("EntrouCopy2"); + if (err) throw err; + console.log("EntrouCopy3"); + res.send(true); + }); + }); + /*} else { + res.writeHead(200, {'Content-Type': 'text/html'}); + res.write('
'); + res.write('
'); + res.write(''); + res.write('
'); + return res.end(); + }*/ + }); + + router.post('/copyPdf', verifyJWT, (req, res) => { + var base64 = require('base64topdf'); + var id = req.body.id; + var backStr = req.body.back; + var backName = 'franch_' + id; + var Objback = { 'fileName': backName, 'type': 'pdf' }; + var path = Variables('src_media') + 'images/'; + if(base64.base64Decode(backStr, backName.toString())){ + res.send(true); + }else {res.send(false);} + }); + + router.post('/copyZip', verifyJWT, (req, res) => { + var unzip = require('unzip'); + var fs = require('fs'); + const file = req.body.file; + const name = req.body.name; + var dir = Variables('src_media') + 'franchiseeZip/' + name; + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir); + } + var path = dir + '/'; + var data = file.replace(/^data:application\/\x-zip-compressed;base64,/, ''); + //var data = file.replace(/^data:image\/\w+;base64,/, ''); + fs.writeFile(path + name + '.zip', data, {encoding: 'base64'}, function(err){ + setTimeout(() => { + console.log('Copiado com sucesso!'); + res.send(true); + } , 3000); + }); + }); + + router.post('/copy2', verifyJWT, (req, res) => { + let form = new formidable.IncomingForm(); + form.maxFileSize = 600 * 1024 * 1024; + form.parse(req, function(err,fields,files){ + const fs = require('fs'); + var name = fields.name; + var dir = Variables('src_media') + 'franchiseeZip/' + name + "/"; + var extension = files.file.name.toString(); + var arrExt = extension.split('.'); + extension = "." + arrExt[arrExt.length - 1]; + console.log("name: " + name + " - dir: " + dir + " - extension: " + extension); + if (!fs.existsSync(dir)) { + console.log("criar diretorio"); + fs.mkdirSync(dir); + } + else { + try { + fs.unlink(dir + name + extension, function(err) {}); + } + catch(err) { + console.log("arquivo não existe"); + } + } + var oldpath = files.file.path; + fs.rename(oldpath, dir + name + extension, function (err) { + if (err) { + res.send(false); + throw err; + } + res.send(true); + }); + }); + }); + + router.patch('/updateF', verifyJWT, (req, res) => { + const idfranchisee_folder = req.body.idfranchisee_folder; + const folder_type = req.body.folder_type; + const folder_description = req.body.folder_description; + const folder_into = req.body.folder_into; + const userFor = req.body.userFor; + execSQLQuery(`UPDATE franchisee_folders SET + folder_type = ?, + folder_description = ?, + folder_into = ?, + userFor = ? + WHERE idfranchisee_folder = ?;`, res, req.originalUrl, [folder_type, folder_description, folder_into, userFor, idfranchisee_folder]); + }); + + + router.get('/getNomesAlunos/:banco', (req, res) => { + const db = req.params.banco; + execSQLQuery2(`SELECT distinct + tt.IDMatricula, + cl.Nome + FROM ${db}TreinandosTurmas tt + INNER JOIN ${db}Clientes cl ON cl.IDCliente = tt.IDTreinando;`, res, req.originalUrl); + }); + + + // LEADS + router.get('/getLeadsEventos', verifyJWT, (req, res) => { + execSQLQuery(`select + * + FROM leadseventos + ORDER BY descricao ASC;`, res, req.originalUrl); + }); + + router.get('/getLeadsSite/:idunits/:idleadseventos', verifyJWT, (req, res) => { + const idunits = parseInt(req.params.idunits); + const idleadseventos = parseInt(req.params.idleadseventos); + const SQLQuery = `select + ls.*, + un.unityname as 'unidade', + date_format(ls.insert_date, '%d/%m/%Y %H:%i') as 'data', + case when ls.update_date is not null then 'Sim' else 'Não' end as 'visto', + case when ls.contatado = 1 then 'Sim' else 'Não' end as 'cont' + FROM leadssite ls + inner join units un on un.idunits = ls.idunits + WHERE ${(idunits == 0) ? 'true' : 'ls.idunits = ' + idunits} and ls.idleadseventos = ${idleadseventos} + ORDER BY un.unityname asc, ls.nome ASC;`; + execSQLQuery(SQLQuery, res, req.originalUrl); + }); + + router.get('/updateVistoLead/:idleadssite', verifyJWT, (req, res) => { + const idleadssite = parseInt(req.params.idleadssite); + execSQLQuery(`update leadssite set update_date = now() where idleadssite = ${idleadssite};`, res, req.originalUrl); + }); + + router.get('/updateContatadoLead/:idleadssite', verifyJWT, (req, res) => { + const idleadssite = parseInt(req.params.idleadssite); + execSQLQuery(`update leadssite set contatado = 1 where idleadssite = ${idleadssite};`, res, req.originalUrl); + }); + + return router; +}; + +module.exports = routes; \ No newline at end of file diff --git a/controllers/holidayController.js b/controllers/holidayController.js new file mode 100644 index 0000000..e98c422 --- /dev/null +++ b/controllers/holidayController.js @@ -0,0 +1,77 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/InserirFeriadosPadrao/:ano', verifyJWT, (req, res) => { + const Ano = parseInt(req.params.ano); + execSQLQuery(`insert into holidays (date, reason) values + ('${Ano}-01-01', 'Ano Novo'), + ('${Ano}-02-15', 'Carnaval'), + ('${Ano}-02-16', 'Carnaval'), + ('${Ano}-04-02', 'Paixão de Cristo'), + ('${Ano}-04-21', 'Tiradentes'), + ('${Ano}-05-01', 'Dia do Trabalho'), + ('${Ano}-06-03', 'Corpus Christi'), + ('${Ano}-09-07', 'Independência do Brasil'), + ('${Ano}-10-12', 'Dia das Crianças'), + ('${Ano}-11-02', 'Finados'), + ('${Ano}-11-15', 'Proclamação da República'), + ('${Ano}-12-25', 'Natal');`, res, req.originalUrl); + }); + + router.post('/InserirFeriado', verifyJWT, (req, res) => { + const reason = req.body.reason; + const date = req.body.date; + execSQLQuery(`INSERT INTO holidays (date, reason) + VALUES (?, ?);`, res, req.originalUrl, [date, reason]); + }); + + router.patch('/AtualizarFeriado', verifyJWT, (req, res) => { + const reason = req.body.reason; + const date = req.body.date; + execSQLQuery(`UPDATE holidays SET + date = ?, + reason = ? + WHERE date = ?;`, res, req.originalUrl, [date, reason, date]); + }); + + router.post('/getFeriado', verifyJWT, (req, res) => { + const date = req.body.date; + execSQLQuery(`SELECT + * + FROM holidays + WHERE date = "${date}";`, res, req.originalUrl); + }); + + router.get('/getAllFeriados', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + date_format(date, '%d/%m/%Y') as 'date', + date as 'cdate', + reason + FROM holidays + order by cdate asc;`, res, req.originalUrl); + }); + + router.get('/getMySQLinSQLServerFeriados', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + concat(date_format(date, '%Y-%m-%d'), ' 00:00:00.000') AS 'Data', + reason AS 'Motivo' + FROM holidays;`, res, req.originalUrl); + }) + + router.get('/getSQLServerFeriados/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT * FROM ${db}DiasNaoLetivos;`, res, req.originalUrl); + }) + + return router; +} + +module.exports = routes; \ No newline at end of file diff --git a/controllers/ig40Controller.js b/controllers/ig40Controller.js new file mode 100644 index 0000000..fe450f7 --- /dev/null +++ b/controllers/ig40Controller.js @@ -0,0 +1,84 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/getAllLeads/:idunits', verifyJWT, (req, res) => { + const idunits = parseInt(req.params.idunits); + execSQLQuery(`SELECT igl.*, date_format(igl.insert_date, '%d/%m/%Y %H:%i') as 'inscricao', un.unityname FROM g40_leads igl inner join units un on un.idunits = igl.idunits where ${(idunits > 0) ? 'igl.idunits = ' + idunits : 'true'};`, res, req.originalUrl); + }); + + router.post('/insertLead', (req, res) => { + const idunits = parseInt(req.body.idunits); + const nome = req.body.nome; + const email = req.body.email; + const cidade = req.body.cidade; + const celular = req.body.celular; + const idade = req.body.idade; + const instituicao = req.body.instituicao; + execSQLQuery(`INSERT INTO g40_leads (idunits, nome, email, cidade, celular, idade, instituicao) VALUES + (?, ?, ?, ?, ?, ?, ?);`, res, req.originalUrl, [idunits, nome, email, cidade, celular, idade, instituicao]); + }); + + router.patch('/updateLead', verifyJWT, (req, res) => { + const idg40_leads = parseInt(req.body.idg40_leads); + const idunits = parseInt(req.body.idunits); + const nome = req.body.nome; + const email = req.body.email; + const cidade = req.body.cidade; + const celular = req.body.celular; + const idade = req.body.idade; + const instituicao = req.body.instituicao; + execSQLQuery(`update g40_leads set + idunits = ?, + nome = ?, + email = ?, + cidade = ?, + celular = ?, + idade = ?, + instituicao = ? + where idg40_leads = ?;`, res, req.originalUrl, [idunits, nome, email, cidade, celular, idade, instituicao, idg40_leads]); + }); + + + router.get('/getAllEmpresas/:idunits', verifyJWT, (req, res) => { + const idunits = parseInt(req.params.idunits); + execSQLQuery(`SELECT ige.*, date_format(ige.insert_date, '%d/%m/%Y %H:%i') as 'inscricao', un.unityname FROM g40_empresas ige inner join units un on un.idunits = ige.idunits where ${(idunits > 0) ? 'ige.idunits = ' + idunits : 'true'};`, res, req.originalUrl); + }); + + router.post('/insertEmpresa', (req, res) => { + const idunits = parseInt(req.body.idunits); + const nome = req.body.nome; + const empresa = req.body.empresa; + const email = req.body.email; + const telefone = req.body.telefone; + execSQLQuery(`INSERT INTO g40_empresas (idunits, nome, empresa, email, telefone) VALUES + (?, ?, ?, ?, ?);`, res, req.originalUrl, [idunits, nome, empresa, email, telefone]); + }); + + router.patch('/updateEmpresa', verifyJWT, (req, res) => { + const idg40_empresas = parseInt(req.params.idg40_empresas); + const idunits = parseInt(req.body.idunits); + const nome = req.body.nome; + const empresa = req.body.empresa; + const email = req.body.email; + const telefone = req.body.telefone; + execSQLQuery(`update g40_empresas set + idunits = ?, + nome = ?, + emrpesa = ?, + email = ?, + telefone = ? + where idg40_empresas = ?;`, res, req.originalUrl, [idunits, nome, empresa, email, telefone, idg40_empresas]); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/iyrcController.js b/controllers/iyrcController.js new file mode 100644 index 0000000..2de6353 --- /dev/null +++ b/controllers/iyrcController.js @@ -0,0 +1,1425 @@ +require('../helpers/config'); +require('../connections/mysql-server'); + +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ + limit: '10mb', + extended: true + } +)); +router.use(bodyParser.json({ + limit: '10mb', + extended: true +})); + +// Criar conexão com o banco de dados +var mysqlReference = require('mysql'); +var DadosConnection = { + host: Variables('ip_mysql'), + user: Variables('user_mysql'), + password: Variables('password_mysql'), + database: 'iyrc_2020', + port: 3306 +}; +let ConexaoMySQL = mysqlReference.createConnection(DadosConnection); + +var routes = function () { + + router.get('/getParticipantes', (req, res) => { + const SQLQry = `SELECT * FROM participantes;`; + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + if (!error && results.length != 0) { + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": results + })) + console.log(req.originalUrl + "/ success 200"); + } + else { + res.send(JSON.stringify({ + "status": 500, + "error": error, + "response": results + })) + console.log(req.originalUrl + "/ error 500"); + } + }) + + }) + + router.get('/getParticipantesHTML/:token', (req, res) => { + const SQLQry = `SELECT pa.*, DATE_FORMAT(pa.insert_date, "%d/%m/%Y") as cadastro, case when (select COUNT(*) from pontuacao p where p.idparticipantes = pa.idparticipantes) > 0 then 'Sim' else 'Não' end as jogou FROM participantes pa ORDER BY pa.idparticipantes DESC;`; + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + if (!error && results.length != 0) { + res.writeHeader(200, {"Content-Type": "text/html; charset=utf-8"}); + res.write('Total:' + results.length + '
'); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + results.forEach((result) => { + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + res.write(''); + }); + res.write('
DataNomeResponsávelE-MailTelefoneEstadoCidadeInstagramJogou
' + result.cadastro + '' + result.nome + '' + result.responsavel + '' + result.email + '' + result.telefone + '' + result.estado + '' + result.cidade + '' + result.instagram + '' + result.jogou + '
'); + res.end(); + console.log(req.originalUrl + "/ success 200"); + } + else { + res.send(JSON.stringify({ + "status": 500, + "error": error, + "response": results + })) + console.log(req.originalUrl + "/ error 500"); + } + }) + + }) + + router.get('/getParticipanteByid/:idparticipantes', (req, res) => { + var idparticipantes = req.params.idparticipantes; + + const SQLQry = `SELECT * FROM participantes WHERE idparticipantes = ${idparticipantes};`; + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + if (!error && results.length != 0) { + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": results + })) + console.log(req.originalUrl + "/ success 200"); + } + else { + res.send(JSON.stringify({ + "status": 500, + "error": error, + "response": results + })) + console.log(req.originalUrl + "/ error 500"); + } + }) + }) + + router.get('/getParticipanteScore/:idparticipantes/:idprovas', (req, res) => { + var idparticipantes = req.params.idparticipantes; + var idprovas = req.params.idprovas; + + const SQLQry = `SELECT pa.nome, SUM(po.pontuacao) AS 'pontuacao' FROM participantes pa INNER JOIN pontuacao po ON po.idparticipantes = pa.idparticipantes WHERE pa.idparticipantes = ${idparticipantes} AND po.idprovas = ${idprovas};`; + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + if (!error && results.length != 0) { + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": results + })) + console.log(req.originalUrl + "/ success 200"); + } + else { + res.send(JSON.stringify({ + "status": 500, + "error": error, + "response": results + })) + console.log(req.originalUrl + "/ error 500"); + } + }) + }) + + router.post('/insertParticipante', (req, res) => { + const nome = req.body.nome; + const responsavel = req.body.responsavel; + const email = req.body.email; + const telefone = req.body.telefone; + const instagram = req.body.instagram; + const estado = req.body.estado; + const cidade = req.body.cidade; + + var SQLQry = `SELECT * FROM participantes WHERE email = '${email}';`; + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + if (!error && results.length > 0) { + res.redirect('http://iyrconline.com.br/formulario.html?erro1=email'); + } + else { + + SQLQry = `INSERT INTO participantes (nome, responsavel, email, telefone, instagram, estado, cidade) + VALUES ('${nome}', '${responsavel}', '${email}', '${telefone}', '${instagram}', '${estado}', '${cidade}');`; + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + if (!error && results.length != 0) { + EnviarEmail(results['insertId'], nome, email, 0, 0, function(SucessoEmail) { + EnviarSMS(results['insertId'], telefone, 0, function(SucessoSMS) { + res.redirect('http://iyrconline.com.br/outform.html'); + console.log(req.originalUrl + "/ success 200"); + }); + }); + } + else { + res.send(JSON.stringify({ + "status": 500, + "error": error, + "response": results + })) + console.log(req.originalUrl + "/ error 500"); + } + }) + } + }) + + }) + + router.post('/insertPontuacao', (req, res) => { + console.log(req.body); + const idprovas = req.body.idprovas; + const idparticipantes = req.body.idparticipantes; + const pontuacao = req.body.pontuacao; + + var SQLQry = `SELECT * FROM pontuacao WHERE idprovas = ${idprovas} AND idparticipantes = ${idparticipantes};`; + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + if (!error && results.length > 0) { + if (results[0]['pontuacao'] < pontuacao) { // A PONTUACAO DO USUARIO E MAIOR QUE A ANTERIOR NESSE JOGO + SQLQry = `UPDATE pontuacao SET pontuacao = ${pontuacao} WHERE idparticipantes = ${idparticipantes} AND idprovas = ${idprovas};`; + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": results + })) + console.log(req.originalUrl + " success 200"); + }); + } + else { + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": results + })) + console.log(req.originalUrl + " success 200"); + } + } + else { + SQLQry = `INSERT INTO pontuacao (idprovas, idparticipantes, pontuacao) + VALUES (${idprovas}, ${idparticipantes}, ${pontuacao});`; + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + if (!error && results.length != 0) { + /*SQLQry = `SELECT email FROM participantes WHERE idparticipantes = ${idparticipantes};`; + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + EnviarEmail(results[0]['idparticipantes'], results[0]['nome'], results[0]['email'], pontuacao, 2, function(Sucesso) { + console.log("Sucesso"); + }) + })*/ + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": results + })); + console.log(req.originalUrl + "/ success 200"); + } + else { + res.send(JSON.stringify({ + "status": 500, + "error": error, + "response": results + })) + console.log(req.originalUrl + "/ error 500"); + } + }) + } + + }) + + }) + + router.get('/enviarEMAIL', (req, res) => { + EnviarEmail(265, 'Heloísa Nogueira Moscati', 'zendionmazinni@gmail.com', 0, 0, function(Sucesso) { + console.log("OK"); + res.send(Sucesso); + }) + }) + + router.get('/enviarSMS/:idparticipantes/:telefone', (req, res) => { + let telefone = req.params.telefone; + let idparticipantes = req.params.idparticipantes; + EnviarSMS(idparticipantes, telefone, 0); + res.send(true); + }) + + router.get('/sendMsgToUsers/:op1/:op2', (req, res) => { + let Quem = req.params.op1; + let Opcao = req.params.op2; + var SQLQry = ``; + if (Quem == 0) { // TODOS OS PARTICIPANTES + SQLQry = `SELECT * FROM ( + SELECT DISTINCT + pa.idparticipantes, + pa.nome, + pa.email, + pa.telefone, + CASE WHEN po.idparticipantes = pa.idparticipantes THEN 'Sim' ELSE 'Não' END AS 'Jogou' + FROM participantes pa + LEFT JOIN pontuacao po + ON pa.idparticipantes = po.idparticipantes) R;`; + } + else if (Quem == 1) { // JA PARTICIPARAM DA PRIMEIRA ETAPA + SQLQry = `SELECT * FROM ( + SELECT DISTINCT + pa.idparticipantes, + pa.nome, + pa.email, + pa.telefone, + CASE WHEN po.idparticipantes = pa.idparticipantes THEN 'Sim' ELSE 'Não' END AS 'Jogou' + FROM participantes pa + LEFT JOIN pontuacao po + ON pa.idparticipantes = po.idparticipantes) R + WHERE Jogou = 'Sim';`; + } + else if (Quem == 2) { // NAO PARTICIPARAM DA PRIMEIRA ETAPA + SQLQry = `SELECT * FROM ( + SELECT DISTINCT + pa.idparticipantes, + pa.nome, + pa.email, + pa.telefone, + CASE WHEN po.idparticipantes = pa.idparticipantes THEN 'Sim' ELSE 'Não' END AS 'Jogou' + FROM participantes pa + LEFT JOIN pontuacao po + ON pa.idparticipantes = po.idparticipantes) R + WHERE Jogou = 'Não';`; + } + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + if (!error && results.length != 0) { + EnviaMsg(results, 0, Opcao, function(Sucesso) { + res.send(Sucesso); + console.log(req.originalUrl + "/ success 200"); + }); + } + else { + res.send(false); + console.log(req.originalUrl + "/ error 500"); + } + }) + + }) + + router.post('/getParticipanteScores', (req, res) => { + var email = req.body.email; + + const SQLQry = `SELECT pa.idparticipantes, pa.nome, COUNT(po.idparticipantes) AS 'participacoes' + FROM iyrc_2020.participantes pa + INNER JOIN iyrc_2020.pontuacao po ON po.idparticipantes = pa.idparticipantes + WHERE pa.email = '${email}' group by pa.idparticipantes`; + ConexaoMySQL.query(SQLQry, function (error, results, fields) { + if (!error && results.length != 0) { + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": results + })) + console.log(req.originalUrl + "/ success 200"); + } + else { + res.send(JSON.stringify({ + "status": 500, + "error": error, + "response": results + })) + console.log(req.originalUrl + "/ error 500"); + } + }) + }) + + return router; +}; + +function EnviaMsg(ListaUsuarios, Index, Opcao, callback) { + if (Index < ListaUsuarios.length) { + console.log("Participante: " + ListaUsuarios[Index].nome); + setTimeout(() => { + EnviarEmail(ListaUsuarios[Index].idparticipantes, ListaUsuarios[Index].nome, ListaUsuarios[Index].email, 0, Opcao, function(SucessoEmail) { + EnviarSMS(ListaUsuarios[Index].idparticipantes, ListaUsuarios[Index].telefone, Opcao, function(sucessoSMS) { + Index++; + EnviaMsg(ListaUsuarios, Index, Opcao, callback); + }); + }); + }, 1000); + } + else { + callback(true); + } +} + +function EnviarSMS(idparticipantes, telefone, Opcao, callback) { + + if (telefone == null || telefone == '') { + callback(false); + return; + } + + let NumeroRegistro = Math.pow(idparticipantes, 2); + + var mensagem = ``; + if (Opcao == 0) { // LINK DA PRIMEIRA ETAPA + mensagem = `"PARABÉNS\r\nAbaixo está o link para disputar seu desafio IYRC!\r\nhttp://iyrconline.com.br/provas.html?${NumeroRegistro}"`; + } + else if (Opcao == 1) { // LINK DA SEGUNDA ETAPA + mensagem = `"Segue o link para disputar a segunda etapa IYRC!\r\nhttp://iyrconline.com.br/provas.html?${NumeroRegistro}"`; + } + else if (Opcao == 2) { // PARABENS PRIMEIRA ETAPA + mensagem = `Sua participação na primeira etapa do Campeonato Internacional de Robótica IYRC 2020 foi registrada!`; + } + else if (Opcao == 3) { // FALTA 1 DIA PARA SEGUNDA ETAPA + mensagem = `Falta 1 dia para a segunda etapa do Campeonato Internacional de Robótica IYRC 2020!`; + } + else if (Opcao == 4) { // FALTAM 3 DIAS PARA A ETAPA FINAL + mensagem = `Faltam 3 dias para a etapa final do Campeonato Internacional de Robótica IYRC 2020!`; + } + else if (Opcao == 5) { // FALTAM 2 DIAS PARA A ETAPA FINAL + mensagem = `Faltam 2 dias para a etapa final do Campeonato Internacional de Robótica IYRC 2020!`; + } + else if (Opcao == 6) { // FALTA 1 DIA PARA A ETAPA FINAL + mensagem = `Falta 1 dia para a etapa final do Campeonato Internacional de Robótica IYRC 2020!`; + } + else if (Opcao == 7) { // MUDANCA DATA DA ETAPA FINAL + mensagem = `Fique atento! A data da etapa final do Campeonato Internacional de Robótica IYRC 2020 foi alterada para o dia 13/06/2020!`; + } + + let url = `http://www.facilitamovel.com.br/api/messagesPhonesMultipleSend.ft?user=myrobot&password=3498567&destinatario=${telefone}&msg=${encodeURI(mensagem)};`//Sua URL + + /*var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; + let xhttp = new XMLHttpRequest(); + xhttp.open("GET", url, false); + xhttp.send();*/ + + const http = require('http'); + http.get(url, (resp) => { + let data = ''; + resp.on('data', (chunk) => { + data += chunk; + }); + resp.on('end', () => { + let Sucesso = false; + if (data.includes('Usuario sem Creditos')) { + console.log("ERRO AO ENVIAR SMS PARA: " + telefone + " - " + data); + Sucesso = false; + } + else { + console.log("SMS ENVIADO COM SUCESSO PARA: " + telefone + " - " + data); + Sucesso = true; + } + callback(Sucesso); + }); + }).on("error", (err) => { + console.log("error: " + err); + callback(false); + }); + + //console.log(url); +} + +function EnviarEmail(idparticipantes, nome, email, pontuacao, Opcao, callback) { + + if (email == null || email == '') { + callback(false); + return; + } + + const request = require('request'); + + let NumeroRegistro = Math.pow(idparticipantes, 2); + let Texto = ``; + if (Opcao == 0) { // LINK DA PRIMIERA ETAPA + Texto = CriarTextoEmail_Etapa1(nome, NumeroRegistro); + } + else if (Opcao == 1) { // LINK DA SEGUNDA ETAPA + Texto = CriarTextoEmail_Etapa2(NumeroRegistro); + } + else if (Opcao == 2) { // PARABENS PRIMEIRA ETAPA + Texto = CriarTextoEmail_Parabens(pontuacao); + } + else if (Opcao == 3) { // FALTA 1 DIA PARA SEGUNDA ETAPA + Texto = CriarTextoEmail_Falta1DiaEtapa2(); + } + else if (Opcao == 4) { // FALTA 2 DIAS PARA ETAPA FINAL + Texto = CriarTextoEmail_Falta3DiasEtapaFinal(); + } + else if (Opcao == 5) { // FALTA 2 DIAS PARA ETAPA FINAL + Texto = CriarTextoEmail_Falta2DiasEtapaFinal(); + } + else if (Opcao == 6) { // FALTA 2 DIAS PARA ETAPA FINAL + Texto = CriarTextoEmail_Falta1DiaEtapaFinal(); + } + else if (Opcao == 7) { // MUDANCA DA DATA DA ETAPA FINAL + Texto = CriarTextoEmail_MudancaDataFinal(); + } + + request.post('http://18.228.91.135:3337/api/email/send', { + json: { + from: 'iyrconline@myrobot.com.br', + to: email, + subject: "Etapa Online do Campeonato Internacional de Robótica IYRC", + text: Texto + } + }, function (error, response, body) { + if (!error && response.statusCode == 200) { + console.log("Sucesso ao enviar e-mail!"); + //callback(true); + } + else { + console.log("Falha ao enviar e-mail!"); + //callback(false); + } + } + ); + callback(true); +} + +function CriarTextoEmail_Etapa1(Nome, NumeroRegistro) { + + return `
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+ + + + + + + + + + + + +
+
PARABÉNS, VOCÊ ESTÁ INSCRITO! +
+
+
Olá, ${Nome}! +
+
+
Seu cadastro na Etapa Online do Campeonato Internacional de Robótica IYRC foi realizado com sucesso! +
+
Abaixo está o link para seu ambiente online de competição, onde poderá disputar seu desafio! +
+
+ Clique aqui para ser direcionado ao seu ambiente de competição +
+
Boa sorte e bom game! +
+
+
+
+
+
+
+
+ + + + + + +
+
+
`; +} + +function CriarTextoEmail_Parabens(Pontuacao) { + + return `
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + +
+
VOCÊ FOI CLASSIFICADO PARA A 2ª ETAPA ONLINE DA IYRC! +
+
+
+ Isso mostra que vocé está se preparando para o campeonato presencial, mas ainda faltam 2 etapas. Você consegue! +

+ Sua pontuação:
${Pontuacao}

+ +
+ Confira matéria no site G1 da Globo sobre a etapa nacional de 2019 +

+ Matéria com alunos de escola pública na etapa nacional da competição +
+ +
+
+
+ ATENÇÃO!
+ O PRÓXIMO DESAFIO ACONTECE EM:
+
+ +
+
+
+
+
+
+
+ + + + + + +
+
+
`; +} + +function CriarTextoEmail_Etapa2(NumeroRegistro) { + return `
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + +
+
VOCÊ ESTÁ PREPARADO? +
+
+
+ É hoje, Sábado, das 0h às 24h a segunda etapa do desafio online! São 5 mini games, tire a maior pontuação e garanta sua vaga para a final que será transmitida em uma super live! +

+ + Clique aqui para ser direcionado ao
seu ambiente de competição
+


+ + Confira matéria no site G1 da Globo sobre a etapa nacional de 2019 +

+ Matéria com alunos de escola pública na etapa nacional da competição +
+ +
+
+
+ ATENÇÃO!
+ A FINAL ACONTECE EM:
+
+ +
+
+
+
+
+
+
+ + + + + + +
+
+
`; +} + +function CriarTextoEmail_Falta1DiaEtapa2() { + return `
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + +
+
FALTA APENAS 1 DIA PARA
A PRÓXIMA ETAPA!
+
+
+
+ + + + +
+ É amanhã, Sábado, das 0h às 24h a segunda etapa do desafio online! São 5 mini games, tire a maior pontuação e garanta sua vaga para a final que será transmitida em uma super live! +

+ +
+ + Confira matéria no site G1 da Globo sobre a etapa nacional de 2019 +

+ Matéria com alunos de escola pública na etapa nacional da competição +
+ +
+
+
+ ATENÇÃO!
+ O PRÓXIMO DESAFIO ACONTECE EM:
+
+ +
+
+
+
+
+
+
+ + + + + + +
+
+
`; +} + +function CriarTextoEmail_Falta3DiasEtapaFinal() { + return `
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + +
+
FALTAM APENAS 3 DIAS PARA
A ETAPA FINAL!
+
+
+
+ + + + +
+
Além de uma super oportunidade de estar entre os melhores da Robótica Mundial, no evento presencial ocorrem diversas premiações. +
+
Prepare-se para estar com a gente nessa super competição! +
+
+ Confira matéria no site G1 da Globo sobre a etapa nacional de 2019 +

+ Matéria com alunos de escola pública na etapa nacional da competição +
+ +
+
+
ATENÇÃO! O DESAFIO FINAL ACONTECE EM: +
+ +
+
+
+
+
+
+
+ + + + + + +
+
+
`; +} + +function CriarTextoEmail_Falta2DiasEtapaFinal() { + return `
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + +
+
FALTAM APENAS 2 DIAS PARA
A ETAPA FINAL!
+
+
+
+ + + + +
+
Além de uma super oportunidade de estar entre os melhores da Robótica Mundial, no evento presencial ocorrem diversas premiações. +
+
Prepare-se para estar com a gente nessa super competição! +
+
+ Confira matéria no site G1 da Globo sobre a etapa nacional de 2019 +

+ Matéria com alunos de escola pública na etapa nacional da competição +
+ +
+
+
ATENÇÃO! O DESAFIO FINAL ACONTECE EM: +
+ +
+
+
+
+
+
+
+ + + + + + +
+
+
`; +} + +function CriarTextoEmail_Falta1DiaEtapaFinal() { + return `
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + +
+
FALTA APENAS 1 DIA PARA
A ETAPA FINAL!
+
+
+
+ + + + +
+
Além de uma super oportunidade de estar entre os melhores da Robótica Mundial, no evento presencial ocorrem diversas premiações. +
+
Prepare-se para estar com a gente nessa super competição! +
+
+ Confira matéria no site G1 da Globo sobre a etapa nacional de 2019 +

+ Matéria com alunos de escola pública na etapa nacional da competição +
+ +
+
+
ATENÇÃO! O DESAFIO FINAL ACONTECE EM: +
+ +
+
+
+
+
+
+
+ + + + + + +
+
+
`; +} + +function CriarTextoEmail_MudancaDataFinal() { + return `
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + +
+
Olá competidor!!! +
+
+
+ + Devido à grande demanda de acesso aos jogos online da IYRC, prorrogamos a data da etapa final para dia 13/06/2020, às 14h. +
+
Fique ligado nas notícias da IYRC Onine e convide seus amigos a participarem!!! +
+
+ Boa sorte na final!!!
+
+ Confira matéria no site G1 da Globo sobre a etapa nacional de 2019 +

+ Matéria com alunos de escola pública na etapa nacional da competição +
+ +
+
+
ATENÇÃO! O DESAFIO FINAL ACONTECE EM: +
+ +
+
+
+
+
+
+
+ + + + + + +
+
+
`; +} + +module.exports = routes; diff --git a/controllers/listenrepeatController.js b/controllers/listenrepeatController.js new file mode 100644 index 0000000..46c72b9 --- /dev/null +++ b/controllers/listenrepeatController.js @@ -0,0 +1,100 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); + +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); +const { verify } = require('jsonwebtoken'); + +router.use(bodyParser.urlencoded({ + limit: '10mb', + extended: true + } +)); +router.use(bodyParser.json({ + limit: '10mb', + extended: true +})); + +var routes = function () { + + router.get('/getAllListenRepeat', verifyJWT, (req, res) => { + execSQLQuery(`select * from zoelistenrepeat;`, res, req.originalUrl); + }); + + router.get('/getListenRepeat/:idzoelistenrepeat', verifyJWT, (req, res) => { + const idzoelistenrepeat = parseInt(req.params.idzoelistenrepeat); + execSQLQuery(`select * from zoelistenrepeat where idzoelistenrepeat = ${idzoelistenrepeat};`, res, req.originalUrl); + }); + + router.get('/getLRDetails/:idzoelistenrepeat', (req, res) => { + const idzoelistenrepeat = parseInt(req.params.idzoelistenrepeat); + execSQLQuery(`select + lr.idzoelistenrepeat, + lr.description, + lrp.phrase, + lrp.ordem, + lrp.hasmedia + from zoelistenrepeat lr + inner join zoelistenrepeatprhases lrp on lrp.idzoelistenrepeat = lr.idzoelistenrepeat + where lr.idzoelistenrepeat = ${idzoelistenrepeat} + order by lrp.ordem asc;`, res, req.originalUrl); + }); + + router.post('/InsertListenRepeat', verifyJWT, (req, res) => { + const idzoelistenrepeat = parseInt(req.body.idzoelistenrepeat); + const description = req.body.description; + execSQLQuery(`INSERT INTO zoelistenrepeat (description) + VALUES (?);`, res, req.originalUrl, [description]); + }); + + router.patch('/UpdateListenRepeat', verifyJWT, (req, res) => { + const idzoelistenrepeat = parseInt(req.body.idzoelistenrepeat); + const description = req.body.description; + execSQLQuery(`UPDATE zoelistenrepeat SET + description = ? + WHERE idzoelistenrepeat = ?;`, res, req.originalUrl, [description, idzoelistenrepeat]); + }); + + router.delete('/deleteListenRepeat/:idzoelistenrepeat', verifyJWT, (req, res) => { + const idzoelistenrepeat = parseInt(req.params.idzoelistenrepeat); + execSQLQuery(`delete from zoelistenrepeat + where idzoelistenrepeat = ${idzoelistenrepeat};`, res, req.originalUrl); + }); + + router.get('/getListenRepeatPhrases/:idzoelistenrepeat', verifyJWT, (req, res) => { + const idzoelistenrepeat = parseInt(req.params.idzoelistenrepeat); + execSQLQuery(`select * from zoelistenrepeatprhases where idzoelistenrepeat = ${idzoelistenrepeat};`, res, req.originalUrl); + }); + + router.post('/InsertListenRepeatPrhases', verifyJWT, (req, res) => { + const idzoelistenrepeatprhases = parseInt(req.body.idzoelistenrepeatprhases); + const idzoelistenrepeat = parseInt(req.body.idzoelistenrepeat); + const phrase = req.body.phrase; + const ordem = parseInt(req.body.ordem); + const hasmedia = req.body.hasmedia ? 1 : 0; + const idcharactersVoices = parseInt(req.body.idcharactersVoices); + const speed = req.body.speed; + execSQLQuery(`INSERT INTO zoelistenrepeatprhases (idzoelistenrepeat, phrase, ordem, hasmedia, idcharactersVoices, speed) + VALUES (?, ?, ?, ?, ?, ?);`, res, req.originalUrl, [idzoelistenrepeat, phrase, ordem, hasmedia, idcharactersVoices, speed]); + }); + + router.delete('/deleteListenRepeatPrhases/:idzoelistenrepeat', verifyJWT, (req, res) => { + const idzoelistenrepeat = parseInt(req.params.idzoelistenrepeat); + execSQLQuery(`delete from zoelistenrepeatprhases + where idzoelistenrepeat = ${idzoelistenrepeat};`, res, req.originalUrl); + }); + + router.get('/SalvarAudioSintetizado/:nome', verifyJWT, (req, res) => { + const NomeArquivo = req.params.nome; + const shell = require('shelljs'); + shell.exec(`cp ${Variables("src_media")}/audiosZoe/sintetize.mp3 ${Variables("src_media")}/zoeGamesResources/LR/${NomeArquivo}.mp3`, function(Sucesso) { + res.send(true); + }); + }); + + return router; +}; + +module.exports = routes; \ No newline at end of file diff --git a/controllers/loginController.js b/controllers/loginController.js new file mode 100644 index 0000000..f81e072 --- /dev/null +++ b/controllers/loginController.js @@ -0,0 +1,40 @@ +require('../connections/mysql-server'); +require('../helpers/helper'); +require('../helpers/config'); + +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +//const helper = new Helpers(); + +require("dotenv-safe").load(); +var jwt = require('jsonwebtoken'); + +var routes = function () { + + router.get('/logout', function (req, res) { + res.status(200).send({ auth: false, token: null }); + }); + + router.get('/checktoken', (req, res, next) => { + var token = req.params.tk; + if (!token) return res.status(401).send({ auth: false, message: 'Não foi enviado token' }); + + jwt.verify(token, process.env.SECRET, function (err, decoded) { + if (err) { + res.status(200).send({ response: 'fail' }); + } + else { + req.idusers = decoded.id; + res.status(200).send({ response: 'success' }); + } + }); + }) + return router; +} + +module.exports = routes; diff --git a/controllers/migrationController.js b/controllers/migrationController.js new file mode 100644 index 0000000..55134a7 --- /dev/null +++ b/controllers/migrationController.js @@ -0,0 +1,1048 @@ +require('../connections/mysql-server'); +require('../connections/sql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); +const formidable = require('formidable'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + //=========== usar o mesmo padrão para as rotas ============== + // // + // getMySQL*** // + // getSQLServer*** // + // insertSQLServer*** // + // updateSQLServer*** // + // // + //=========== onde "***" é o nome da tabela do mysql ========= + + router.get('/getAllTables', verifyJWT, (req, res) => { + execSQLQuery(`SHOW TABLES`, res, req.originalUrl); + }); + + router.post('/generateLog/:Pasta', verifyJWT, (req, res) => { + var name = req.body.name; + var content = req.body.content; + const Pasta = req.params.Pasta; + var fs = require('fs'); + fs.writeFile(Variables('src_media') + "migration_log/" + Pasta + "/" + name + ".txt", content, function (erro) { + if (erro) { + throw erro; + } + res.send(true); + }); + }); + + router.get('/listLogFiles/:Pasta', verifyJWT, (req, res) => { + const Pasta = req.params.Pasta; + let fs = require('fs'); + fs.readdir(Variables('src_media') + "migration_log/" + Pasta, (err, files) => { + res.send(files); + }); + + }); + + //#region Migração entre MySQLs + + router.post('/checkStatusUnity', verifyJWT, (req, res) => { + let ip_externo = req.body.ip_externo; + let porta_mysql = req.body.porta_mysql; + + var mysqlReference = require('mysql'); + var DadosConnection = { + host: ip_externo, + user: 'myrobot', + password: 'myrobot2019', + database: 'myrobot', + port: porta_mysql + }; + let mysqlLocal2 = mysqlReference.createConnection(DadosConnection); + + const SQLQry = `SELECT * FROM units;`; + + mysqlLocal2.query(SQLQry, function (error, results, fields) { + try { + if (results.length > 0) { + console.log('/checkStatusUnity success 200'); + res.send(true); + } + else { + console.log('/checkStatusUnity fail 500'); + res.send(false); + } + } + catch (e) { + console.log('/checkStatusUnity fail 500'); + res.send(false); + } + }) + }) + + router.post('/sincronizarTabela', verifyJWT, (req, res) => { + let form = new formidable.IncomingForm(); + form.maxFileSize = 1024 * 1024 * 1024; + form.parse(req, function (err, fields, files) { + let ip_externo = fields.ip_externo; + let porta_mysql = fields.porta_mysql; + let tabela = fields.tabela; + let dados = JSON.parse(fields.dados); + + var mysqlReference = require('mysql'); + var DadosConnection = { + host: ip_externo, + user: 'myrobot', + password: 'myrobot2019', + database: 'myrobot', + port: porta_mysql + }; + let mysqlLocal2 = mysqlReference.createConnection(DadosConnection); + + const SQLQryTruncate = `TRUNCATE TABLE ` + tabela + `;`; + const SQLQryBackup = `SELECT * FROM ${tabela};`; + let DadosBackup; + + mysqlLocal2.query(SQLQryBackup, function (error, results, fields) { + DadosBackup = results; + mysqlLocal2.query('SET FOREIGN_KEY_CHECKS = 0;', function (error0, results0, fields0) { + mysqlLocal2.query(SQLQryTruncate, function (error1, results1, fields1) { + mysqlLocal2.query('SET FOREIGN_KEY_CHECKS = 1;', function (error2, results2, fields2) { + Sincronizar(0, dados, tabela, mysqlLocal2, "true,", function (Sucesso) { + if (Sucesso.split(',')[0] == "true") { + console.log("/sincronizarTabela success 200"); + res.send(Sucesso); + } + else { + console.log("/sincronizarTabela fail 500"); + Sincronizar(0, DadosBackup, tabela, mysqlLocal2, "true,", function (Sucesso2) { + if (Sucesso2.split(',')[0] == "true") + console.log("Backup da tabela com sucesso"); + else + console.log("Backup da tabela com falha"); + + res.send(Sucesso); + }); + } + }); + }) + }) + }) + }) + + }); + + }) + + function Sincronizar(i, dados, tabela, mysqlLocal2, Certo, callback) { + var SQLQryInsert = `INSERT INTO ` + tabela + ` (`; + + let values = []; + let index = 0; + for (var key in dados[i]) { + if (index > 0) + SQLQryInsert += ", "; + SQLQryInsert += key.toString(); + values.push(dados[i][key]); + index++; + } + SQLQryInsert += `) VALUES ?`; + + var records = []; + for (var i = 0; i < dados.length; i++) { + var row = []; + for (var key in dados[i]) { + row.push(dados[i][key]) + } + records.push(row); + } + + mysqlLocal2.query(SQLQryInsert, [records], function (error, results, fields) { + if (error) { + Certo = "false,"; + console.log("Erro: " + error); + } + console.log("Sincronia MySQL finalizada na tabela '" + tabela + "'"); + callback(Certo + error); + }) + } + + router.get('/SalvarDump/:token', (req, res) => { + let token = req.params.token; + if (token != Variables("tk_fixed")) { + res.status(500).send({ status: 'expired' }); + return; + } + const http = require('http'); + mysqlConnection.query('SELECT description, ip_externo FROM units WHERE enabled = 1 AND idunits = 14;', function (error, results, fields) { + let ListaUnidades = results; + for (let i = 0; i < ListaUnidades.length; i++) { + + http.get('http://' + ListaUnidades[i]['ip_externo'] + ':' + ListaUnidades[i]['porta_api'] + '/api/migration/backupDump/' + Variables("tk_fixed"), (resp) => { + let data = ''; + resp.on('data', (chunk) => { + data += chunk; + }); + resp.on('end', () => { + //console.log(JSON.parse(data).response); + const fs = require('fs'); + let Hora = new Date(); + let Nome = "dump_" + ListaUnidades[i]['description'] + "_" + Hora.getDate() + "-" + (Hora.getMonth() + 1) + "-" + Hora.getFullYear() + "_" + Hora.getHours() + "_" + Hora.getMinutes() + "_" + Hora.getSeconds() + ".sql"; + let Unidade = ListaUnidades[i]['description']; + let CaminhoArquivo = Variables('src_media') + 'backup_mysql/' + Unidade + "/"; + let Arquivo = JSON.parse(data)['arquivo']; + if (!fs.existsSync(CaminhoArquivo)) { + fs.mkdirSync(CaminhoArquivo); + } + fs.writeFile(CaminhoArquivo + Nome, Arquivo.toString(), function (err) { + if (err) { + console.log("/salvarBackup fail 500 - " + ListaUnidades[i]['description']); + } + else { + console.log("/salvarBackup success 200 - " + ListaUnidades[i]['description']); + } + }); + + }); + }).on("error", (err) => { + console.log(ListaUnidades[i]['description'] + " - Error: " + err.message); + }); + + } + res.send(true); + }); + }); + + + //#endregion + + //#region Migração entre Arquivos + + router.post('/sincronizarArquivos', verifyJWT, (req, res) => { + let Comando = req.body.comando; + const shell = require('shelljs'); + shell.exec(Comando, function (arquivosbaixados) { + if (Comando.includes('games')) { + var fs = require('fs'); + fs.readdir(Variables('src_media') + "/games/", (err, files) => { + var Pastas = []; + files.forEach(file => { + Pastas.push(file.toString()); + }); + BaixarBuild(Pastas, 0, function (Sucesso) { + shell.exec('chmod -R 777 /var/www/html/', function (Sucesso) { + console.log(new Date().toUTCString() + " - " + req.originalUrl + " success 200"); + res.send(JSON.stringify({ "baixados": Sucesso })) + }) + }); + }); + } + else { + shell.exec('chmod -R 777 /var/www/html/', function (arquivosmovidos) { + console.log(new Date().toUTCString() + " - " + req.originalUrl + " success 200"); + res.send(JSON.stringify({ "baixados": arquivosbaixados })) + }) + } + }); + }); + + function BaixarBuild(Pastas, Index, Callback) { + const shell = require('shelljs'); + if (Index < Pastas.length) { + shell.exec('wget -c -P /var/www/html/ -nH -r -k -np "http://18.228.91.135/games/' + Pastas[Index] + '/Build/" -R index.html?*', function (Sucesso) { + console.log(Sucesso); + Index++; + BaixarBuild(Pastas, Index, Callback); + }) + } + else { + Callback(true); + } + } + + router.get('/backupDump/:token', (req, res) => { + let token = req.params.token; + if (token != Variables("tk_fixed")) { + res.status(500).send({ status: 'expired' }); + return; + } + const fs = require('fs'); + const shell = require('shelljs'); + shell.exec('mysqldump -u' + Variables('user_mysql') + ' -p' + Variables('password_mysql') + ' myrobot > ' + Variables('src_media') + 'backup/dump.sql', function (sucesso) { + const Arquivo = Variables('src_media') + 'backup/dump.sql'; + fs.readFile(Arquivo, (err, data) => { + console.log(new Date().toUTCString() + " - " + req.originalUrl + " success 200"); + res.send(JSON.stringify({ "arquivo": Buffer.from(data).toString() })); + }) + + }) + }) + + router.post('/salvarBackup', verifyJWT, (req, res) => { + let form = new formidable.IncomingForm(); + form.maxFileSize = 1024 * 1024 * 1024; + form.parse(req, function (err, fields, files) { + const fs = require('fs'); + let Nome = fields.name; + let Unidade = fields.unit; + let CaminhoArquivo = Variables('src_media') + 'backup_mysql/' + Unidade + "/"; + let Arquivo = fields.arquivo; + if (!fs.existsSync(CaminhoArquivo)) { + fs.mkdirSync(CaminhoArquivo); + } + fs.writeFile(CaminhoArquivo + Nome, Arquivo.toString(), function (err) { + if (err) { + console.log(new Date().toUTCString() + " - " + req.originalUrl + " fail 500"); + res.send(false); + } + else { + console.log(new Date().toUTCString() + " - " + req.originalUrl + " success 200"); + res.send(true); + } + }); + }); + }); + + router.get('/setLastUpdate/:idunits', verifyJWT, (req, res) => { + const idunits = req.params.idunits; + execSQLQuery(`UPDATE units SET last_update = now() WHERE idunits = ${idunits};`, res, req.originalUrl); + }) + + //#endregion + + //#region EXECUTAR COMANDO TERMINAL + + router.post('/CommandExec', verifyJWT, (req, res) => { + let Comando = req.body.comando; + const shell = require('shelljs'); + let Resposta = shell.exec(Comando); + res.send(JSON.stringify({ "resultado": Resposta })); + }); + + //#endregion + + //#region Migração entre SQLServer + router.post('/MigrarSQLServer/:insert/:db', verifyJWT, (req, res) => { + let Tabela = req.body.Tabela; + let Dados = JSON.parse(req.body.Dados); + let Insert = req.params.insert; + let db = req.params.db; + //console.log(Tabela); + //console.log(Dados); + let SQLMigracao = ``; + let Campos = ''; + let Valores = ''; + if (Insert == "true") { // INSERIR APENAS NOVOS REGISTROS + for (var campo in Dados[0]) { + Campos += campo + ", "; + } + Campos = "(" + Campos.substr(0, Campos.length - 2) + ")"; + //console.log(Campos); + for (let i = 0; i < Dados.length; i++) { + let Ind = 0; + for (let campo in Dados[0]) { + if (Ind == 0) + Valores += "('" + Dados[i][campo] + "', "; + else + Valores += "'" + Dados[i][campo] + "', "; + Ind++; + } + Valores = Valores.substr(0, Valores.length - 2) + "), "; + } + Valores = Valores.substr(0, Valores.length - 2); + //console.log(Valores); + SQLMigracao = `INSERT INTO ${db}${Tabela} ${Campos} VALUES ${Valores};`; + //console.log(SQLMigracao); + execSQLQuery2(SQLMigracao, res, req.originalUrl); + //res.send(SQLMigracao); + } + else { // INSERIR TODOS ATUALIZANDO OS REGISTROS JA EXISTENTES + //console.log(Campos); + let CampoID = ""; + let ValorID = ""; + for (let i = 0; i < Dados.length; i++) { + let Ind = 0; + for (let campo in Dados[0]) { + if (Ind == 0) { + CampoID = campo; + ValorID = Dados[i][campo]; + Valores += `UPDATE ${db}${Tabela} SET `; + } + else { + Valores += campo + " = '" + Dados[i][campo] + "', "; + } + Ind++; + } + Valores = `${Valores.substr(0, Valores.length - 2)} WHERE ${CampoID} = '${ValorID}'; + `; + } + //console.log(Valores); + SQLMigracao = Valores; + //console.log(SQLMigracao); + execSQLQuery2(SQLMigracao, res, req.originalUrl); + //res.send(SQLMigracao); + } + }); + + router.post('/ExecutarSQLServerQuery', verifyJWT, (req, res) => { + const sqlQuery = req.body.comando; + execSQLQuery2(sqlQuery, res, req.originalUrl); + }) + + router.post('/ExecutarMySQLQuery', verifyJWT, (req, res) => { + const sqlQuery = req.body.comando; + execSQLQuery(sqlQuery, res, req.originalUrl); + }) + //#endregion + + //#region MIGRACAO DADOS MYSQL LOCAL PARA ONLINE + router.post('/MigracaoMySQLLocalToWeb', verifyJWT, (req, res) => { + + const ip_externo = req.body.ip_externo; + const porta_mysql = req.body.porta_mysql; + + var mysqlReference = require('mysql'); + var DadosConnection = { + host: ip_externo, + user: 'myrobot', + password: 'myrobot2019', + database: 'myrobot', + port: porta_mysql + }; + let mysqlLocal2 = mysqlReference.createConnection(DadosConnection); + + const CamposStepclass = `idusers,idclasses,actualClass,actualExercise,actualAnswer,actualItem,answersdb,continueClass,completedClass,note,notification,idunits,notegame,homework,datefinal,dateinicial`; + const SQLQryStepclass = `select idusers,idclasses,actualClass,actualExercise,actualAnswer,actualItem,answersdb,continueClass,completedClass,note,notification,idunits,notegame,homework,datefinal,date_format(dateinicial, '%Y-%m-%d %h:%i:%s') AS dateinicial from stepclass;`; + const CamposUsergivenanswers = `idusers,idexerciseanswers,date_answered,fixed,idclasses,idunits`; + const SQLQryUsergivenanswers = `select ${CamposUsergivenanswers} from usergivenanswers;`; + const CamposUserstages = `idstages,idusers,idunits,idclasses,note`; + const SQLQryUserstages = `select ${CamposUserstages} from userstages;`; + + mysqlLocal2.query(SQLQryStepclass, function (errorStepclass, resultsStepclss, fieldsStepclass) { + const TabelaStepclass = resultsStepclss; + mysqlLocal2.query(SQLQryUsergivenanswers, function (errorUsergivenanswers, resultsUsergivenanswers, fieldsUsergivenanswers) { + const TabelaUsergivenanswers = resultsUsergivenanswers + mysqlLocal2.query(SQLQryUserstages, function (errorUserstages, resultsUserstages, fieldsUserstages) { + const TabelaUserstages = resultsUserstages; + + mysqlConnection.query(CriaSQLInsert(TabelaStepclass, CamposStepclass, 'stepclass'), function (errorStepclass1, resultsStepclss1, fieldsStepclass1) { + console.log(req.originalUrl + " success 200 - stepclass"); + mysqlConnection.query(CriaSQLInsert(TabelaUsergivenanswers, CamposUsergivenanswers, 'usergivenanswers'), function (errorUsergivenanswers1, resultsUsergivenanswers1, fieldsUsergivenanswers1) { + console.log(req.originalUrl + " success 200 - usergivenanswers"); + mysqlConnection.query(CriaSQLInsert(TabelaUserstages, CamposUserstages, 'userstages'), function (errorUserstages1, resultsUserstages1, fieldsUserstages1) { + console.log(req.originalUrl + " success 200 - userstages"); + res.send(JSON.stringify({ + Stepclass: { + SQL: CriaSQLInsert(TabelaStepclass, CamposStepclass, 'stepclass'), + results: resultsStepclss1, + error: errorStepclass1, + original: resultsStepclss + }, + Usergivenanswers: { + SQL: CriaSQLInsert(TabelaUsergivenanswers, CamposUsergivenanswers, 'usergivenanswers'), + results: resultsUsergivenanswers1, + error: errorUsergivenanswers1, + original: resultsUsergivenanswers + }, + Userstages: { + SQL: CriaSQLInsert(TabelaUserstages, CamposUserstages, 'userstages'), + results: resultsUserstages1, + error: errorUserstages1, + original: resultsUserstages + }, + })); + }); + }); + }); + }); + }) + }) + }); + + function CriaSQLInsert(Dados, Campos, Tabela) { + let SQLQueryInsert = ``; + if (Dados && Dados.length > 0) { + SQLQueryInsert = `INSERT INTO ${Tabela} (${Campos}) VALUES `; + let Registros = ``; + for (let i = 0; i < Dados.length; i++) { + for (let o = 0; o < Campos.split(',').length; o++) { + if (o == 0) + Registros += '('; + + let Registro = Dados[i][Campos.split(',')[o]]; + if (Registro == null) { + Registros += `null,`; + } + else if (typeof (Registro) == "number" || typeof (Registro) == "boolean") { + Registros += `${Registro},`; + } + else if (typeof (Registro) == "string" || typeof (Registro) == "object") { + Registros += `'${Registro}',`; + } + else { + Registros += `null,`; + } + + if (o == Campos.split(',').length - 1) + Registros = Registros.substr(0, Registros.length - 1) + '),'; + } + } + SQLQueryInsert += Registros.substr(0, Registros.length - 1) + ";"; + } + + return SQLQueryInsert; + } + + router.get('/RemoverDuplicadosMySQL', (req, res) => { + console.log(req.originalUrl + " initializing..."); + const SQLQueryStepclass = `select sc.idstepclass, R.*, sc.note, sc.completedClass, sc.notegame, sc.homework from + (select idusers, idunits, idclasses, count(idusers) as qtde from stepclass group by idusers, idunits, idclasses + HAVING COUNT(*) > 1) R + inner join stepclass sc on sc.idclasses = R.idclasses AND sc.idunits = R.idunits AND sc.idusers = R.idusers + ORDER BY idusers, idunits, idclasses;`; + const SQLQueryUsergivenanswers = `SELECT ug.idusergivenanswers, R.* FROM + (SELECT idusers, idunits, idclasses, idexerciseanswers, COUNT(*) AS qtde FROM usergivenanswers + GROUP BY idusers, idunits, idclasses, idexerciseanswers + HAVING COUNT(*) > 1) R + INNER JOIN usergivenanswers ug ON ug.idusers = R.idusers and ug.idunits = R.idunits and ug.idexerciseanswers = R.idexerciseanswers + ORDER BY ug.idusers, ug.idunits, ug.idclasses, ug.idexerciseanswers;`; + const SQLQueryUserstages = `SELECT us.iduserstages, R.* FROM + (SELECT idusers, idunits, idclasses, idstages, COUNT(*) AS qtde FROM userstages + GROUP BY idusers, idunits, idclasses, idstages + HAVING COUNT(*) > 1) R + INNER JOIN userstages us ON us.idusers = R.idusers and us.idunits = R.idunits and us.idstages = R.idstages + ORDER BY us.idusers, us.idunits, us.idclasses, us.idstages;`; + RemoverDuplicadosTabela(true, SQLQueryStepclass, ['note', 'completedClass', 'notegame', 'homework'], 'stepclass', function(results1, error1) { + console.log("Sucesso: stepclass"); + RemoverDuplicadosTabela(false, SQLQueryUsergivenanswers, ['idusers', 'idunits', 'idclasses', 'idexerciseanswers'], 'usergivenanswers', function(results2, error2) { + console.log("Sucesso: usergivenanswers"); + RemoverDuplicadosTabela(false, SQLQueryUserstages, ['idusers', 'idunits', 'idclasses', 'idstages'], 'userstages', function(results3, error3) { + console.log("Sucesso: userstages"); + res.send(JSON.stringify({ + StepClass: { + response: results1, + error: error1, + }, + UserGivenAnswers: { + response: results2, + error: error2, + }, + UserStages: { + response: results3, + error: error3, + }, + })); + console.log(req.originalUrl + " success 200"); + }); + }); + }); + //execSQLQuery(SQLQuery, res, req); + }); + + function RemoverDuplicadosTabela(Comparacao, SQLQuery, Campos, Tabela, callback) { + mysqlConnection.query(SQLQuery, function (error, results, fields) { + let TabelaDuplicadas = results; + if (TabelaDuplicadas && TabelaDuplicadas.length > 0) { + let IDs = ``; + if (Comparacao) { // METODO DE COMPARACAO DE DADOS + let DadosDuplicados = []; + for (let i = 0; i < TabelaDuplicadas.length; i = i + 2) { + DadosDuplicados.push(ComparaDuplicados(Campos, TabelaDuplicadas, i)); + } + let Resultados = []; + for (let i = 0; i < DadosDuplicados.length; i++) { + let Indice = 0; + let Somatoria = 0; + for (let o = 0; o < DadosDuplicados[i].length; o++) { + Somatoria += DadosDuplicados[i][o]; + } + Resultados.push(Somatoria); + if (Somatoria >= 0) + Resultados.push(-10); + else + Resultados.push(10); + } + for (let i = 0; i < TabelaDuplicadas.length; i = i + 2) { + try { + if (Resultados[i] >= 0) + IDs += TabelaDuplicadas[i + 1]['id' + Tabela] + ','; + else + IDs += TabelaDuplicadas[i]['id' + Tabela] + ','; + } + catch (e) { + + } + } + } + else { // REMOCAO DE DADOS ATRAVES DE QUANTIDADE REPETIDA + let NovaTabela = []; + for (let i = 0; i < TabelaDuplicadas.length; i++) { + let Repetido = false; + for (let o = 0; o < NovaTabela.length; o++) { + let TotalIgual = 0; + for (let u = 0; u < Campos.length; u++) { + if (TabelaDuplicadas[i][Campos[u]] == NovaTabela[o][Campos[u]]) { + TotalIgual++; + } + } + if (TotalIgual == Campos.length) { + IDs += TabelaDuplicadas[i]['id' + Tabela] + ","; + Repetido = true; + break; + } + } + if (!Repetido) + NovaTabela.push(TabelaDuplicadas[i]); + } + //callback(NovaTabela, TabelaDuplicadas); + } + IDs = IDs.substr(0, IDs.length - 1); + RemoverDados(Tabela, IDs, TabelaDuplicadas.length, 0, function (Finalizado) { + callback(results, error); + }); + } + else { + callback(results, error); + } + }); + } + + function ComparaDuplicados(Campos, TabelaDuplicadas, i) { + let Dados = []; + for (let o = 0; o < Campos.length; o++) { + let IIgualdade = 0; + try { + if ((TabelaDuplicadas[i][Campos[o]] > TabelaDuplicadas[i + 1][Campos[o]]) || (TabelaDuplicadas[i][Campos[o]] != null && TabelaDuplicadas[i + 1][Campos[o]] == null)) + IIgualdade++; + else if ((TabelaDuplicadas[i][Campos[o]] < TabelaDuplicadas[i + 1][Campos[o]]) || (TabelaDuplicadas[i][Campos[o]] == null && TabelaDuplicadas[i + 1][Campos[o]] != null)) + IIgualdade--; + } + catch (e) { + + } + Dados.push(IIgualdade); + } + return Dados; + } + + function RemoverDados(Tabela, IDs, Registros, Removidos, callback) { + const SQLRemover = `DELETE FROM ${Tabela} WHERE id${Tabela} IN (${IDs});`; + mysqlConnection.query(SQLRemover, function (error, results, fields) { + Removidos++; + console.log("Dados removidos: " + Tabela); + if (results['affectedRows'] == 0) { + callback(true); + } + else { + RemoverDados(Tabela, IDs, Registros, Removidos, callback); + } + }); + } + //#endregion + + //#region MODO EMERGENCIAL + router.get('/CheckInternetStatus', (req, res) => { + console.log("Verificando conexão com a internet..."); + checkInternet(function(isConnected) { + let StepClass = []; + let SQLSC = "INSERT INTO stepclass (idstepclass, idusers, idclasses, actualClass, actualExercise, actualAnswer, actualItem, answersdb, continueClass, completedClass, note, notification, idunits, notegame, homework, datefinal, dateinicial) VALUES "; + let UserGivenAnswers = []; + let SQLUG = "INSERT INTO usergivenanswers (idusergivenanswers, idusers, idexerciseanswers, date_answered, fixed, idclasses, idunits) VALUES "; + let UserStages = []; + let SQLUS = "INSERT INTO userstages (iduserstages, idstages, idusers, idunits, idclasses, note) VALUES "; + let Comando = ``; + if (isConnected && Variables('local') == "Local") { + //console.log("CASO 1"); + mysqlConnection.query("select idusers, idclasses, actualClass, actualExercise, actualAnswer, actualItem, answersdb, continueClass, completedClass, note, notification, idunits, notegame, homework, datefinal, date_format(dateinicial, '%Y/%m-%d %h:%i:%s') as 'dateinicial' from stepclass;", function (errorSC, resultsSC, fieldsSC) { + StepClass = resultsSC; + mysqlConnection.query('select idusers, idexerciseanswers, date_answered, fixed, idclasses, idunits from usergivenanswers;', function (errorUG, resultsUG, fieldsUG) { + UserGivenAnswers = resultsUG; + mysqlConnection.query('select idstages, idusers, idunits, idclasses, note from userstages;', function (errorUS, resultsUS, fieldsUS) { + UserStages = resultsUS; + + if (resultsSC && resultsSC.length > 0) + SQLSC = MontaSQLInsert(SQLSC, StepClass, "stepclass"); + else + SQLSC = "SELECT 1"; + if (resultsUG && resultsUG.length > 0) + SQLUG = MontaSQLInsert(SQLUG, UserGivenAnswers, "usergivenanswers"); + else + SQLUG = "SELECT 1"; + if (resultsUS && resultsUS.length > 0) + SQLUS = MontaSQLInsert(SQLUS, UserStages, "userstages"); + else + SQLUS = "SELECT 1"; + + Comando = `sed -i 's/var Online = false;/var Online = true;/' /var/www/myrobot_api/helpers/config.js;sed -i 's/Emergencia=1;/Emergencia=0;/' /var/www/html/assets/LW.cnf`; + ExecutaMudanca(Comando, isConnected, res, SQLSC, SQLUG, SQLUS); + }); + }); + }); + } + else if (!isConnected && Variables('local') == "Online") { + //console.log("CASO 2"); + Comando = `sed -i 's/var Online = true;/var Online = false;/' /var/www/myrobot_api/helpers/config.js;sed -i 's/Emergencia=0;/Emergencia=1;/' /var/www/html/assets/LW.cnf`; + ExecutaMudanca(Comando, isConnected, res, "", "", ""); + } + else { + //console.log("CASO 3"); + Comando = `echo "Operação do servidor estável"`; + ExecutaMudanca(Comando, isConnected, res, "", "", ""); + } + }); + }); + + function MontaSQLInsert(SQLIN, Tabela, NomeTabela) { + for (let i = 0; i < Tabela.length; i++) { + SQLIN += `((select (tb1.id${NomeTabela} + 1) from ${NomeTabela} tb1 order by tb1.id${NomeTabela} desc limit 1), `; + for (let key in Tabela[i]) { //.toISOString().replace(/T/, ' ').replace(/\..+/, '') + SQLIN += ((Tabela[i][key] == null) ? "" : "'") + ((Tabela[i][key]) ? Tabela[i][key].toString().replace("/", "-") : Tabela[i][key]) + ((Tabela[i][key] == null) ? "," : "',"); + } + SQLIN = SQLIN.substring(0, SQLIN.length - 1) + "),"; + } + SQLIN = SQLIN.substring(0, SQLIN.length - 1) + ";"; + return SQLIN; + } + + function ExecutaMudanca(Comando, isConnected, res, SQLSC, SQLUG, SQLUS) { + const shell = require('shelljs'); + let LocalAntes = Variables('local'); + shell.exec(Comando, function (sucesso) { + let LocalAgora = ""; + if (isConnected) { + Variables_Set("local", true); + console.log(new Date().toUTCString() + " - Servidor operando em modo normal"); + LocalAgora = "Online"; + } + else { + Variables_Set("local", false); + console.log(new Date().toUTCString() + " - Servidor operando em modo de emergência"); + LocalAgora = "Local"; + } + + //console.log("Antes: " + LocalAntes); + //console.log("Agora: " + LocalAgora); + + if (LocalAntes != LocalAgora) { + if (LocalAgora == "Online") { + var mysqlReference = require('mysql'); + var DadosConnection = { + host: "127.0.0.1", + user: "myrobot", + password: "myrobot2019", + database: Variables('database_mysql'), + port: 3306 + }; + let mysqlLocal2 = mysqlReference.createConnection(DadosConnection); + mysqlLocal2.query("TRUNCATE stepclass;", function (errorSC1, resultsSC1, fieldsSC1) { + mysqlLocal2.query("TRUNCATE usergivenanswers;", function (errorUG1, resultsUG1, fieldsUG1) { + mysqlLocal2.query("TRUNCATE userstages;", function (errorUS1, resultsUS1, fieldsUS1) { + console.log(new Date().toUTCString() + " - Dados removidos do banco Local com sucesso!"); + if (LocalAntes == "Local" && (SQLSC != "SELECT 1" || SQLUG != "SELECT 1" || SQLUS != "SELECT 1")) { + SincronizarDadosParaOnline(SQLSC, SQLUG, SQLUS); + } + else { + AtualizaConexaoMySQL(); + } + }); + }); + }); + } + else { + AtualizaConexaoMySQL(); + } + + } + + res.send(true); + }); + } + + function checkInternet(cb) { + require('dns').lookup('myrobotlab.com.br', function(err) { + if (err) + cb(false); + else + cb(true); + }) + } + + function SincronizarDadosParaOnline(SQLSC, SQLUG, SQLUS) { + var mysqlReference = require('mysql'); + var DadosConnection = { + host: "18.228.91.135", + user: "root", + password: "maker2018**==", + database: Variables('database_mysql'), + port: 3306 + }; + mysqlLocal2 = mysqlReference.createConnection(DadosConnection); + + console.log(new Date().toUTCString() + " - Sincronizando dados para o servidor WEB..."); + setTimeout(() => { + mysqlLocal2.query(SQLSC, function (errorSC, resultsSC, fieldsSC) { + mysqlLocal2.query(SQLUG, function (errorUG, resultsUG, fieldsUG) { + mysqlLocal2.query(SQLUS, function (errorUS, resultsUS, fieldsUS) { + console.log(new Date().toUTCString() + " - Dados sincronizados com sucesso!"); + AtualizaConexaoMySQL(); + }); + }); + }); + }, 1000); + } + + //#endregion + + //#region SINCRONIA AUTOMATICA + router.get('/SincroniaAutomaticaMySQL/:token', (req, res) => { + let token = req.params.token; + if (token != Variables("tk_fixed")) { + res.status(500).send({ status: 'expired' }); + return; + } + if (Variables('local') == "Local") { + console.log("Servidor em modo local - não baixa atualizações"); + res.send(false); + return; + } + const shell = require('shelljs'); + const Comando = `cd /var/www/html/backup/;rm dump1.sql;wget http://18.228.91.135/backup/dump1.sql;mysql --protocol=tcp --host=127.0.0.1 --user=myrobot --password=myrobot2019 --port=3306 --database=${Variables("database_mysql")} < "dump1.sql"`; + shell.exec(Comando, function(Sucesso) { + var mysqlReference = require('mysql'); + var DadosConnection = { + host: "127.0.0.1", + user: "myrobot", + password: "myrobot2019", + database: Variables('database_mysql'), + port: 3306 + }; + let mysqlLocal2 = mysqlReference.createConnection(DadosConnection); + mysqlLocal2.query('SET FOREIGN_KEY_CHECKS = 0;', function (error0, results0, fields0) { + console.log(new Date().toUTCString() + " - " + "Limpando stepclass..."); + mysqlLocal2.query("TRUNCATE stepclass;", function (errorSC1, resultsSC1, fieldsSC1) { + if (errorSC1) console.log(errorSC1); + console.log(new Date().toUTCString() + " - " + "Limpando usergivenanswers..."); + mysqlLocal2.query("TRUNCATE usergivenanswers;", function (errorUG1, resultsUG1, fieldsUG1) { + if (errorUG1) console.log(errorUG1); + console.log(new Date().toUTCString() + " - " + "Limpando userstages..."); + mysqlLocal2.query("TRUNCATE userstages;", function (errorUS1, resultsUS1, fieldsUS1) { + if (errorUS1) console.log(errorUS1); + mysqlLocal2.query('SET FOREIGN_KEY_CHECKS = 1;', function (error1, results1, fields1) { + console.log(new Date().toUTCString() + " - " + "MySQL sincronizado com sucesso!"); + res.send(true); + }); + }); + }); + }); + }); + }); + }); + //#endregion + + //#region CORRECAO DO BANCO SQL SERVER + + router.get('/RemoverMatriculasTeste/:matriculas/:unidades', (req, res) => { + const Matriculas = req.params.matriculas; + const UnidadesIDs = req.params.unidades; + mysqlConnection.query(`select * from units where idunits in ${UnidadesIDs};`, function (error, resUnits, fields) { + let Unidades = resUnits; + LoopUnidades(Unidades, 0, Matriculas, function(Sucesso) { + let TabelasMySQL = []; + TabelasMySQL.push({"Tabela": "stepclass", "IDUsers": Matriculas, "IDUnits": UnidadesIDs}); + TabelasMySQL.push({"Tabela": "usergivenanswers", "IDUsers": Matriculas, "IDUnits": UnidadesIDs}); + TabelasMySQL.push({"Tabela": "userstages", "IDUsers": Matriculas, "IDUnits": UnidadesIDs}); + LoopDeleteMySQL(TabelasMySQL, 0, function(Sucesso2) { + res.send(true); + }); + }); + }); + + + }); + + function LoopUnidades(Unidades, Index, Matriculas, callback) { + if (Index < Unidades.length) { + const db = Unidades[Index]['reference_db'] + ".dbo."; + const SQLConsultaIDs = `select distinct + ma.IDMatricula, + cl.IDCliente, + cl.Nome, + at.IdAtendimento, + pm.IDPreMatricula, + tu.IdTurma, + tc.IdTurmasCalendario, + ch.IDChamadas, + pr.IDPreRequerimento + from ${db}Matriculas ma + left join ${db}Clientes cl on cl.IDCliente = ma.IDClienteResponsavel + left join ${db}TreinandosTurmas tt on tt.IDMatricula = ma.IDMatricula + left join ${db}Atendimentos at on at.IdAtendimento = ma.IDAtendimento + left join ${db}PreMatricula pm on pm.IDPreMatricula = ma.IDPreMatricula + left join ${db}Turmas tu on tu.IdTurma = tt.CodigoTurma + left join ${db}TurmasCalendario tc on tc.IdTurma = tu.IdTurma + left join ${db}Chamadas ch on ch.IDTurma = tu.IdTurma + left join ${db}ChamadasConteudos cc on cc.IDChamadas = ch.IDChamadas + left join ${db}ChamadasDetalhes cd on cd.IDChamadas = ch.IDChamadas + left join ${db}PreRequerimento pr on pr.IDMatricula = ma.IDMatricula + left join ${db}RemanejamentoDetalhes rd on rd.IDMatricula = ma.IDMatricula + where ma.IDMatricula in ${Matriculas};`; + sqlServerConnection.request().query(SQLConsultaIDs, function (error, results, fields) { + const ResultadoIDs = results.recordsets[0]; + let IDsChamadas = "("; + let IDsPreRequerimento = "("; + let IDsTurmas = "("; + let IDsPreMatriculas = "("; + let IDsAtendimentos = "("; + let IDsClientes = "("; + let IDsMatriculas = "("; + let IDsRemanejamentos = "("; + for (let i = 0; i < ResultadoIDs.length; i++) { + if (!IDsChamadas.includes(ResultadoIDs[i]['IDChamadas']) && ResultadoIDs[i]['IDChamadas'] != null) + IDsChamadas += ResultadoIDs[i]['IDChamadas'] + ","; + if (!IDsPreRequerimento.includes(ResultadoIDs[i]['IDPreRequerimento']) && ResultadoIDs[i]['IDPreRequerimento'] != null) + IDsPreRequerimento += ResultadoIDs[i]['IDPreRequerimento'] + ","; + if (!IDsTurmas.includes(ResultadoIDs[i]['IdTurma']) && ResultadoIDs[i]['IdTurma'] != null) + IDsTurmas += ResultadoIDs[i]['IdTurma'] + ","; + if (!IDsPreMatriculas.includes(ResultadoIDs[i]['IDPreMatricula']) && ResultadoIDs[i]['IDPreMatricula'] != null) + IDsPreMatriculas += ResultadoIDs[i]['IDPreMatricula'] + ","; + if (!IDsAtendimentos.includes(ResultadoIDs[i]['IdAtendimento']) && ResultadoIDs[i]['IdAtendimento'] != null) + IDsAtendimentos += ResultadoIDs[i]['IdAtendimento'] + ","; + if (!IDsClientes.includes(ResultadoIDs[i]['IDCliente']) && ResultadoIDs[i]['IDCliente'] != null) + IDsClientes += ResultadoIDs[i]['IDCliente'] + ","; + if (!IDsMatriculas.includes(ResultadoIDs[i]['IDMatricula']) && ResultadoIDs[i]['IDMatricula'] != null) + IDsMatriculas += ResultadoIDs[i]['IDMatricula'] + ","; + if (!IDsRemanejamentos.includes(ResultadoIDs[i]['IDRemanejamento']) && ResultadoIDs[i]['IDRemanejamento'] != null) + IDsRemanejamentos += ResultadoIDs[i]['IDRemanejamento'] + ","; + } + IDsChamadas = IDsChamadas.substring(0, IDsChamadas.length - 1) + ")"; + IDsPreRequerimento = IDsPreRequerimento.substring(0, IDsPreRequerimento.length - 1) + ")"; + IDsTurmas = IDsTurmas.substring(0, IDsTurmas.length - 1) + ")"; + IDsPreMatriculas = IDsPreMatriculas.substring(0, IDsPreMatriculas.length - 1) + ")"; + IDsAtendimentos = IDsAtendimentos.substring(0, IDsAtendimentos.length - 1) + ")"; + IDsClientes = IDsClientes.substring(0, IDsClientes.length - 1) + ")"; + IDsMatriculas = IDsMatriculas.substring(0, IDsMatriculas.length - 1) + ")"; + IDsRemanejamentos = IDsRemanejamentos.substring(0, IDsRemanejamentos.length - 1) + ")"; + + let Tabelas = []; + // chamadas + Tabelas.push({"Tabela": "ChamadasDetalhes", "CampoID": "IDChamadas", "ValorID": IDsChamadas}); + Tabelas.push({"Tabela": "ChamadasConteudos", "CampoID": "IDChamadas", "ValorID": IDsChamadas}); + Tabelas.push({"Tabela": "Chamadas", "CampoID": "IDChamadas", "ValorID": IDsChamadas}); + // pre requerimentos + Tabelas.push({"Tabela": "PreRequerimento", "CampoID": "IDPreRequerimento", "ValorID": IDsPreRequerimento}); + // turmas + Tabelas.push({"Tabela": "TurmasCalendario", "CampoID": "IdTurma", "ValorID": IDsTurmas}); + Tabelas.push({"Tabela": "TurmasDetalhes", "CampoID": "IDTurma", "ValorID": IDsTurmas}); + Tabelas.push({"Tabela": "TurmasAgendaCalendario", "CampoID": "IdTurma", "ValorID": IDsTurmas}); + Tabelas.push({"Tabela": "TransacoesTurmasDetalhe", "CampoID": "IdTurma", "ValorID": IDsTurmas}); + Tabelas.push({"Tabela": "TransacoesTurmasCalendario", "CampoID": "IdTurma", "ValorID": IDsTurmas}); + Tabelas.push({"Tabela": "TransacoesTurmas", "CampoID": "IdTurma", "ValorID": IDsTurmas}); + Tabelas.push({"Tabela": "Notas", "CampoID": "IDTurma", "ValorID": IDsTurmas}); + Tabelas.push({"Tabela": "AtendimentosFuncionarios", "CampoID": "IdTurma", "ValorID": IDsTurmas}); + Tabelas.push({"Tabela": "Turmas", "CampoID": "IdTurma", "ValorID": IDsTurmas}); + // pre matricula + Tabelas.push({"Tabela": "PreMatriculaCursos", "CampoID": "IDPreMatricula", "ValorID": IDsPreMatriculas}); + Tabelas.push({"Tabela": "PreMatriculaFinanceiroMaterial", "CampoID": "IDPreMatricula", "ValorID": IDsPreMatriculas}); + Tabelas.push({"Tabela": "PreMatriculaParcelas", "CampoID": "IDPreMatricula", "ValorID": IDsPreMatriculas}); + Tabelas.push({"Tabela": "PreMatriculaTreinandos", "CampoID": "IDPreMatricula", "ValorID": IDsPreMatriculas}); + Tabelas.push({"Tabela": "PreMatricula", "CampoID": "IDPreMatricula", "ValorID": IDsPreMatriculas}); + // atendimentos + Tabelas.push({"Tabela": "AtendimentosComissoes", "CampoID": "IdAtendimento", "ValorID": IDsAtendimentos}); + Tabelas.push({"Tabela": "AtendimentosCabecalho", "CampoID": "IdAtendimento", "ValorID": IDsAtendimentos}); + Tabelas.push({"Tabela": "ControleAtendimento", "CampoID": "IdAtendimento", "ValorID": IDsAtendimentos}); + Tabelas.push({"Tabela": "Atendimentos", "CampoID": "IdAtendimento", "ValorID": IDsAtendimentos}); + // clientes + Tabelas.push({"Tabela": "Clientes", "CampoID": "IDCliente", "ValorID": IDsClientes}); + // matriculas + Tabelas.push({"Tabela": "Evadidos", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "HistoricoEvadidos", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "HistoricoFaltas", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "HistoricoMatriculas", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "HistoricoTreinandosTurmas", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "MatriculasCursos", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "MatriculasProdutos", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "MatriculasTreinandos", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "NotasDetalhes", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "NotasDetalhesSequencial", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "TreinandosTurmasMateriais", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "TreinandosTurmas", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "Transferencias", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "ContasReceber", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + Tabelas.push({"Tabela": "Matriculas", "CampoID": "IDMatricula", "ValorID": IDsMatriculas}); + LoopDeleteSQLServer(db, Tabelas, 0, function(Sucesso) { + console.log(`Banco SQLServer da unidade de ${Unidades[Index]['unityname']} corrigido com sucesso!`); + Index++; + LoopUnidades(Unidades, Index, Matriculas, callback); + }); + }); + } + else { + callback(true); + } + } + + function LoopDeleteSQLServer(db, Tabelas, Index, callback) { + if (Index < Tabelas.length) { + const SQLDelete = `delete from ${db}${Tabelas[Index]['Tabela']} where ${Tabelas[Index]['CampoID']} in ${Tabelas[Index]['ValorID']};`; + //console.log(SQLDelete); + sqlServerConnection.request().query(SQLDelete, function (error, results, fields) { + Index++; + LoopDeleteSQLServer(db, Tabelas, Index, callback); + }); + } + else { + callback(true); + } + } + + function LoopDeleteMySQL(Tabelas, Index, callback) { + if (Index < Tabelas.length) { + const SQLDelete = `delete from ${Tabelas[Index]['Tabela']} where idunits in ${Tabelas[Index]['IDUnits']} and idusers in ${Tabelas[Index]['IDUsers']};`; + //console.log(SQLDelete); + mysqlConnection.query(SQLDelete, function (error, results, fields) { + Index++; + LoopDeleteMySQL(Tabelas, Index, callback); + }); + } + else { + console.log(`Banco MySQL corrigido com sucesso!`); + callback(true); + } + } + + //#endregion + + //#region ACOMPANHAMENTO STEPCLASS + + router.get('/CheckStepClass', (req, res) => { + mysqlConnection.query(`select count(*) as 'qtde' from stepclass;`, function (error, results, fields) { + let Resultado = false; + if (results && results[0]['qtde'] > 100) { + //console.log("Tabela StepClass OK"); + Resultado = true; + } + else { + console.log(new Date().toUTCString() + " - Erro na tabela StepClass"); + const request = require('request'); + request.post('http://18.228.91.135:3337/api/email/send', { + json: { + from: 'trocasenhamyrobot@gmail.com.br', + to: `zendionmazinni@gmail.com`, + subject: "Problema na Tabela StepClass", + text: `Tabela StepClass está vazia! Verifique imediatamente!!` + } + }, function (error, response, body) {}); + } + res.send(Resultado); + }); + }); + + //#endregion + + return router; +} + +module.exports = routes; \ No newline at end of file diff --git a/controllers/permissoesController.js b/controllers/permissoesController.js new file mode 100644 index 0000000..9c40c45 --- /dev/null +++ b/controllers/permissoesController.js @@ -0,0 +1,119 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/getAllPermissoes', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * from permissoes;`, res, req.originalUrl); + }); + + router.get('/getPermissoesUsuario/:idusers/:idusertype', verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + const idusertype = parseInt(req.params.idusertype); + execSQLQuery(`select distinct * from ( + select + pm.idusers, pm.idjanelas, jn.descricao, jn.title, jn.icon, jn.link, jn.home, jn.children + from permissoes pm + inner join janelas jn on jn.idjanelas = pm.idjanelas + inner join users us on us.idusers = pm.idusers + where pm.idusers = ${idusers} + union all + select + ${idusers} as 'idusers', up.idjanelas, jn2.descricao, jn2.title, jn2.icon, jn2.link, jn2.home, jn2.children + from usertypepermissoes up + inner join janelas jn2 on jn2.idjanelas = up.idjanelas + where up.idusertype = ${idusertype}) R + order by R.children asc, R.title asc;`, res, req.originalUrl); + }); + + router.get('/getAllJanelas', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * from janelas order by descricao asc;`, res, req.originalUrl); + }); + + router.post('/insertPermissoesTipoUsuario', verifyJWT, (req, res) => { + const Permissoes = req.body.ListaPermissoes; + let SQLInsert = `insert into usertypepermissoes (idusertype, idjanelas) values `; + for (let i = 0; i < Permissoes.length; i++) { + if (i > 0) + SQLInsert += `, `; + SQLInsert += `(${Permissoes[i].idusertype}, ${Permissoes[i].idjanelas})`; + } + const SQLDelete = `delete from usertypepermissoes where idusertype = ${Permissoes[0].idusertype};`; + mysqlConnection.query(SQLDelete, null, function (error, results, fields) { + execSQLQuery(SQLInsert, res, req.originalUrl); + }); + }); + + router.post('/insertPermissoesUsuario', verifyJWT, (req, res) => { + const Permissoes = req.body.ListaPermissoes; + let SQLInsert = `insert into permissoes (idusers, idjanelas) values `; + for (let i = 0; i < Permissoes.length; i++) { + if (i > 0) + SQLInsert += `, `; + SQLInsert += `(${Permissoes[i].idusers}, ${Permissoes[i].idjanelas})`; + } + const SQLDelete = `delete from permissoes where idusers = ${Permissoes[0].idusers};`; + mysqlConnection.query(SQLDelete, null, function (error, results, fields) { + execSQLQuery(SQLInsert, res, req.originalUrl); + }); + }); + + router.get('/insertAllPermissoesUsuario/:idusers', (req, res) => { + const idusers = parseInt(req.params.idusers); + mysqlConnection.query(`select * from janelas;`, null, function (error, resJanelas, fields) { + let SQLInsert = "insert into permissoes (idusers, idjanelas) values "; + for (let i = 0; i < resJanelas.length; i++) { + if (i > 0) + SQLInsert += `, `; + SQLInsert += `(${idusers}, ${resJanelas[i]['idjanelas']})`; + } + execSQLQuery(SQLInsert, res, req.originalUrl); + }); + }); + + router.get('/insertAllPermissoesUsertype/:idusertype', (req, res) => { + const idusertype = parseInt(req.params.idusertype); + mysqlConnection.query(`select * from janelas;`, null, function (error, resJanelas, fields) { + let SQLInsert = "insert into usertypepermissoes (idusertype, idjanelas) values "; + for (let i = 0; i < resJanelas.length; i++) { + if (i > 0) + SQLInsert += `, `; + SQLInsert += `(${idusertype}, ${resJanelas[i]['idjanelas']})`; + } + execSQLQuery(SQLInsert, res, req.originalUrl); + }); + }); + + router.post('/insertJanela', verifyJWT, (req, res) => { + const idjanelas = parseInt(req.body.idjanelas); + const descricao = req.body.descricao; + const title = req.body.title; + const icon = req.body.icon; + const link = req.body.link; + const home = req.body.home ? 1 : 0; + const children = req.body.children; + execSQLQuery(`insert into janelas (descricao, title, icon, link, home, children) values + (?, ?, ?, ?, ?, ?);`, res, req.originalUrl, [descricao, title, icon, link, home, children]); + }); + + router.patch('/updateJanela', verifyJWT, (req, res) => { + const idjanelas = parseInt(req.body.idjanelas); + const descricao = req.body.descricao; + const title = req.body.title; + const icon = req.body.icon; + const link = req.body.link; + const home = req.body.home ? 1 : 0; + const children = req.body.children; + execSQLQuery(`update janelas set descricao = ?, title = ?, icon = ?, link = ?, home = ?, children = ? where idjanelas = ?;`, res, req.originalUrl, [descricao, title, icon, link, home, children, idjanelas]); + }); + + return router; +}; + +module.exports = routes; \ No newline at end of file diff --git a/controllers/productsController.js b/controllers/productsController.js new file mode 100644 index 0000000..eb2d91f --- /dev/null +++ b/controllers/productsController.js @@ -0,0 +1,180 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + //#region PRODUTOS - MATERIAIS + router.post('/insert', verifyJWT, (req, res) => { + const barcode = req.body.barcode; + const description = req.body.description; + const value = parseFloat(req.body.value); + const service = req.body.service ? 1 : 0; + const registerdate = req.body.registerdate; + const amountstock = req.body.amountstock; + const minstock = req.body.minstock; + const maxstock = req.body.maxstock; + const idealstock = req.body.idealstock; + const present = req.body.present ? 1 : 0; + const amountplotspresent = req.body.amountplotspresent ? 1 : 0; + const disabled = req.body.disabled ? 1 : 0; + + execSQLQuery(`INSERT INTO products (barcode, description, value, service, registerdate, amountstock, minstock, maxstock, idealstock, present, amountplotspresent, disabled) + VALUES (?, ?, ?, ?, now(), ?, ?, ?, ?, ?, ?, ?);`, res, req.originalUrl, [barcode, description, value, service, amountstock, minstock, maxstock, idealstock, present, amountplotspresent, disabled]); + }); + + router.patch('/update', verifyJWT, (req, res) => { + const idproducts = req.body.idproducts; + const barcode = req.body.barcode; + const description = req.body.description; + const value = parseFloat(req.body.value); + const service = req.body.service ? 1 : 0; + const registerdate = req.body.registerdate; + const amountstock = req.body.amountstock; + const minstock = req.body.minstock; + const maxstock = req.body.maxstock; + const idealstock = req.body.idealstock; + const present = req.body.present ? 1 : 0; + const amountplotspresent = req.body.amountplotspresent ? 1 : 0; + const disabled = req.body.disabled ? 1 : 0; + + execSQLQuery(`UPDATE products SET + barcode = ?, + description = ?, + value = ?, + service = ?, + amountstock = ?, + minstock = ?, + maxstock = ?, + idealstock = ?, + present = ?, + amountplotspresent = ?, + disabled = ? + WHERE idproducts = ?;`, res, req.originalUrl, [barcode, description, value, service, amountstock, minstock, maxstock, idealstock, present, amountplotspresent, disabled, idproducts]); + }); + + router.get('/getProduct/:idproducts', verifyJWT, (req, res) => { + const idproducts = parseInt(req.params.idproducts); + execSQLQuery(`SELECT + * + FROM products + WHERE idproducts = ${idproducts};`, res, req.originalUrl); + }) + + router.get('/list', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + idproducts, + barcode, + description, + concat('R$ ',format(value,2,'de_DE')) as value, + disabled + FROM products;`, res, req.originalUrl); + }) + + router.get('/getAll', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM products;`, res, req.originalUrl); + }) + + router.get('/getMySQLinSQLServerProducts', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + idproducts AS 'IDProduto', + barcode AS 'Codigo', + description AS 'Descricao', + value AS 'Valor', + case when service = 0 then false else true end AS 'Servico', + registerdate AS 'DataCadastro', + amountstock AS 'QtdEstoque', + minstock AS 'QtdMinima', + maxstock AS 'QtdMaxima', + idealstock AS 'QtdIdeal', + present AS 'Brinde', + amountplotspresent AS 'qtdParcelasBrinde', + case when disabled = 1 then true else false end as 'Desativado' + FROM products;`, res, req.originalUrl); + }) + + router.get('/getSQLServerProducts/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT * FROM ${db}Produtos;`, res, req.originalUrl); + }) + + router.patch('/disable', verifyJWT, (req, res) => { + const idproducts = parseInt(req.body.idproducts); + execSQLQuery(` + UPDATE products + SET disabled = not disabled + WHERE idproducts = ${idproducts}`, + res, + req.originalUrl + ); + }) + + //#endregion + + //#region PRODUTOS VENDAS + + router.post('/InserirProdutovenda', verifyJWT, (req, res) => { + const description = req.body.description; + const disabled = req.body.disabled ? 1 : 0; + + execSQLQuery(`INSERT INTO productsale (description, disabled) + VALUES (?, ?);`, res, req.originalUrl, [description, disabled]); + }); + + router.patch('/AtualizarProdutovenda', verifyJWT, (req, res) => { + const idproductsale = req.body.idproductsale; + const description = req.body.description; + const disabled = req.body.disabled ? 1 : 0; + execSQLQuery(`UPDATE productsale SET + description = ?, + disabled = ? + WHERE idproductsale = ?;`, res, req.originalUrl, [description, disabled, idproductsale]); + }); + + router.get('/getProductSale/:idproductsale', verifyJWT, (req, res) => { + const idproductsale = parseInt(req.params.idproductsale); + execSQLQuery(`SELECT + * + FROM productsale + WHERE idproductsale = ${idproductsale};`, res, req.originalUrl); + }) + + router.get('/getAllProductSale', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM productsale;`, res, req.originalUrl); + }) + + router.get('/getMySQLinSQLServerProductSale', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + idproductsale AS 'IDProduto', + description AS 'Descricao', + case when disabled = 1 then true else false end as 'Desativado' + FROM productsale;`, res, req.originalUrl); + }) + + router.get('/getSQLServerProductSale/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT * FROM ${db}ProdutosVendas;`, res, req.originalUrl); + }) + + router.patch('/disableProductSale', verifyJWT, (req, res) => { + const idproductsale = parseInt(req.body.idproductsale); + execSQLQuery(`UPDATE productsale + SET disabled = not disabled + WHERE idproductsale = ${idproductsale};`, res, req.originalUrl); + }); + + //#endregion + + return router; +} + +module.exports = routes; diff --git a/controllers/qrController.js b/controllers/qrController.js new file mode 100644 index 0000000..14e43c2 --- /dev/null +++ b/controllers/qrController.js @@ -0,0 +1,189 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); + +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ + limit: '10mb', + extended: true + } +)); +router.use(bodyParser.json({ + limit: '10mb', + extended: true +})); + +var routes = function () { + + router.get('/listLotes', verifyJWT, (req, res) => { + execSQLQuery(` + SELECT + * + FROM + qrlotes`, + res, + req.originalUrl + ); + }) + + router.get('/listQRcodes', verifyJWT, (req, res) => { + execSQLQuery(` + SELECT + * + FROM + qrcodes`, + res, + req.originalUrl + ); + }) + + router.get('/listLotesByID/:id', verifyJWT, (req, res) => { + var id = req.params.id; + execSQLQuery(` + SELECT + * + FROM + qrlotes + WHERE + idqrlotes = ${id}`, + res, + req.originalUrl + ); + }) + + router.get('/listQRcodesByAny/:field/:value', verifyJWT, (req, res) => { + var field = req.params.field; + var value = req.params.value; + execSQLQuery(` + SELECT + * + FROM + qrcodes + WHERE + ${field} = '${value}'`, + res, + req.originalUrl + ); + }) + + router.post('/insertLotes', verifyJWT, (req, res) => { + const qtdepack = req.body.qtdepack; + const date = req.body.date; + const description = req.body.description; + execSQLQuery(`INSERT INTO qrlotes(qtdepack, date, description) VALUES (${qtdepack},'${date}', "${description}");`, + res, + req.originalUrl + ); + }) + + router.post('/insertQRcodes', verifyJWT, (req, res) => { + const idqrlotes = req.body.idqrlotes; + const idusers = req.body.idusers; + const key = req.body.key; + const ordem = req.body.ordem; + execSQLQuery(` + INSERT INTO qrcodes(idqrlotes, idusers, _key, ordem) + VALUES + (${idqrlotes},${idusers}, '${key}', ${ordem});`, + res, + req.originalUrl + ); + }) + + router.patch('/updateLotes', verifyJWT, (req, res) => { + const idqrlotes = req.body.idqrlotes; + const qtdepack = req.body.qtdepack; + const date = req.body.date; + execSQLQuery(`UPDATE qrlotes SET qtdepack = ${qtdepack}, date = '${date}' WHERE idqrlotes = ${idqrlotes};`, + res, + req.originalUrl + ); + }) + + router.patch('/updateQRcodes', verifyJWT, (req, res) => { + const idqrcodes = req.body.idqrcodes; + const idqrlotes = req.body.idqrlotes; + const idusers = req.body.idusers; + const key = req.body.key; + const ordem = req.body.ordem; + execSQLQuery(` + UPDATE qrcodes SET + idqrlotes = ${idqrlotes}, + idusers = ${idusers}, + _key = ${key}, + ordem = ${ordem} + WHERE + idqrcodes = ${idqrcodes};`, + res, + req.originalUrl + ); + }); + + router.post('/generateTxt', verifyJWT, (req, res) => { + var idqrlotes = req.body.idqrlotes; + var name = req.body.name; + var content = req.body.content; + var fs = require('fs'); + var path = Variables('src_media') + "qrlotes/" + idqrlotes; + fs.mkdirSync(path); + fs.writeFile(path + "/" + name + ".txt", content, function (erro) { + if (erro) { + throw erro; + } + else { + res.send(true); + } + }); + }); + + router.post('/save', verifyJWT, (req, res) => { + var base64ToImage = require('base64-to-image'); + var fs = require('fs'); + var img64 = req.body.src; + var idqrlotes = req.body.idqrlotes; + var numb = req.body.itens; + var Name = 'qr_' + idqrlotes + '_' + numb; + var Obj = {'fileName': Name, 'type':'jpg'}; + var path = Variables('src_media') + "qrlotes/" + idqrlotes; + if(!fs.existsSync(path)) { + fs.mkdirSync(path); + } + path += '/'; + if(base64ToImage(img64,path,Obj)) { + res.send(true) + } + else { + res.send(false); + } + //res.send("images uploaded with success!"); + }); + + router.get('/downloadPack/:idqrlotes', verifyJWT, (req, res) => { + var idqrlotes = req.params.idqrlotes; + var path = Variables('src_media') + "qrlotes/" + idqrlotes; + var fs = require("fs"); + if(!fs.existsSync(path + "/qrlote_" + idqrlotes + '.zip')) { + require('all-unpacker').pack(path + "/qrlote_" + idqrlotes + '.zip', { + targetDir: path + "/*", + }, function(err, files, text) { + if (err) return console.error(err); + if (files) console.log('files', files); + if (text) { + console.log('text', text); + console.log("compactado"); + res.send(true) ; + }; + }); + } + else { + res.send(true); + } + }); + + return router; +}; + +module.exports = routes; \ No newline at end of file diff --git a/controllers/questionController.js b/controllers/questionController.js new file mode 100644 index 0000000..9980af2 --- /dev/null +++ b/controllers/questionController.js @@ -0,0 +1,80 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/:idexercisequestions/getAnswers', verifyJWT, function (req, res, next) { + const idexercisequestions = parseInt(req.params.idexercisequestions); + execSQLQuery(`SELECT + * + FROM exerciseanswers + WHERE idexercisequestions = ${idexercisequestions};`, res, req.originalUrl); + }); + + router.get('/getQuestionByExercise/:idexercises', verifyJWT, function (req, res, next) { + const idexercises = parseInt(req.params.idexercises); + execSQLQuery(`SELECT + * + FROM exercisequestions + WHERE idexercises = ${idexercises};`, res, req.originalUrl); + }); + + router.get('/getQuestion/:idexercises', verifyJWT, function (req, res, next) { + const idexercises = parseInt(req.params.idexercises); + execSQLQuery(`SELECT + * + FROM exercisequestions + WHERE idexercises = ${idexercises};`, res, req.originalUrl); + }); + + router.post('/insert', verifyJWT, (req, res) => { + const content = req.body.content; + const idexercises = parseInt(req.body.idexercises); + execSQLQuery(`INSERT INTO exercisequestions (idexercises, content) + VALUES (?, ?);`, res, req.originalUrl, [idexercises, content]); + }); + + router.patch('/update', verifyJWT, function (req, res) { + const idexercisequestions = parseInt(req.body.idexercisequestions); + const content = req.body.content; + const idexercises = parseInt(req.body.idexercises); + execSQLQuery(`UPDATE exercisequestions SET + content = ?, + idexercises = ? + WHERE idexercisequestions = ?;`, res, req.originalUrl, [content, idexercises, idexercisequestions]); + }); + + router.patch('/removerPerguntas', verifyJWT, function (req, res, next) { + let idexercisequestions = req.body.idexercisequestions; + let ids = idexercisequestions.split(','); + index1 = 0; + removeQuestion(ids, res); + }); + + return router; +}; + +index1 = 0; + +function removeQuestion(ids, res) { + if (index1 < ids.length - 1) { + let sqlQuery = `UPDATE exercisequestions SET idexercises = null WHERE idexercisequestions = ${ids[index1]};`; + console.log(sqlQuery); + mysqlConnection.query(sqlQuery, function (error, results, fields) { + console.log("AnswerID " + ids[index1] + " removed"); + index1++; + removeQuestion(ids, res); + }); + } + else { + res.send("questions removed"); + } +} + +module.exports = routes; \ No newline at end of file diff --git a/controllers/relatorioController.js b/controllers/relatorioController.js new file mode 100644 index 0000000..693af51 --- /dev/null +++ b/controllers/relatorioController.js @@ -0,0 +1,670 @@ +require('../connections/mysql-server'); +require('../connections/sql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + function CheckFiltros(Filtro, reference_db, callback) { + let Condicao1 = ""; + let Condicao2 = ""; + if (Filtro == 0) { + callback(Condicao1, Condicao2); + } + else if (Filtro == 1) { + Condicao1 = `where R.Cancelada = 'Sim'`; + callback(Condicao1, Condicao2); + } + else if (Filtro == 2) { + Condicao1 = `where R.Cancelada = 'Não'`; + callback(Condicao1, Condicao2); + } + else if (Filtro == 3) { + Condicao2 = `where T.Cursos = T.Concluidos`; + callback(Condicao1, Condicao2); + } + else if (Filtro == 4 || Filtro == 5) { + let MySQLQuery = `select distinct group_concat(sc.idusers) as 'Matriculas' from stepclass sc inner join units un on un.idunits = sc.idunits where un.reference_db = '${reference_db.replace('.dbo.', '')}';`; + mysqlConnection.query(MySQLQuery, function (error, Matriculas, fields) { + Condicao2 = `where T.Matricula ${(Filtro == 5) ? 'not' : ''} in (${Matriculas[0]['Matriculas']})` + callback(Condicao1, Condicao2); + }); + } + } + + function LoopSQLMatriculas(Unidades, Index, SQLServerQuery, DataInicial, DataFinal, Filtro, callback) { + if (Index < Unidades.length) { + CheckFiltros(Filtro, Unidades[Index], function(Condicao1, Condicao2) { + if (Index > 0) { + SQLServerQuery += `union all + `; + } + SQLServerQuery += `select * from ( + select + R.Matricula, R.Aluno, R.Data, R.Unidade, R.ValorTotal, R.ValorPrimeira, R.Mensalidade, R.QTDParcela, R.Parcelas, R.ValorParcela, R.TotalMaterial, R.TotalSMaterial, R.TotalCMaterial, R.Cancelada, + count(R.IDCurso) as 'Cursos', + sum(case when R.Concluiu = 1 then 1 else 0 end) as 'Concluidos', + (select top 1 cu.NomeVersao from ${Unidades[Index]}TreinandosTurmas tt inner join ${Unidades[Index]}Cursos cu on cu.Codigo = tt.IDCurso and cu.IDTipoCurso in (3,5) where tt.IDMatricula = R.Matricula) as 'Curso' + from ( + select distinct + tt.IDMatricula as 'Matricula', + cl.Nome as 'Aluno', + convert(varchar, mt.DataMatricula, 103) as 'Data', + '${Unidades[Index].replace('.dbo.', '').replace('SGP', '')}' as 'Unidade', + ROUND(mt.ValorTotal, 2) as 'ValorTotal', + ROUND(pm.ValorMatricula, 2) as 'ValorPrimeira', + ROUND(pm.ValorParcela, 2) as 'Mensalidade', + pm.QTDParcela, + A.Parcelas, + ROUND(A.ValorParcela, 2) as 'ValorParcela', + ROUND(A.Parcelas * A.ValorParcela, 2) as 'TotalMaterial', + ROUND(pm.QTDParcela * pm.ValorParcela, 2) as 'TotalSMaterial', + ROUND((pm.QTDParcela * pm.ValorParcela) + (A.Parcelas * A.ValorParcela), 2) as 'TotalCMaterial', + case when pr.TipoRequerimento = 'C' then 'Sim' else 'Não' end as 'Cancelada', + tt.Concluiu, + tt.IDCurso + from ${Unidades[Index]}TreinandosTurmas tt + inner join ${Unidades[Index]}Matriculas mt on mt.IDMatricula = tt.IDMatricula + inner join ${Unidades[Index]}Clientes cl on cl.IDCliente = tt.IDTreinando + inner join ${Unidades[Index]}PreMatricula pm on pm.IDPreMatricula = mt.IDPreMatricula + left join (select R.*, R.Parcelas * R.ValorParcela as 'TotalMaterial' from (select IDPreMatricula, count(*) as 'Parcelas', ValorParcela from ${Unidades[Index]}PreMatriculaFinanceiroMaterial group by IDPreMatricula, ValorParcela) R) A on A.IDPreMatricula = pm.IDPreMatricula + left join ${Unidades[Index]}PreRequerimento pr on pr.IDTreinando = tt.IDTreinando + where ${(!DataInicial || !DataFinal) ? '1=1' : "mt.DataMatricula between '" + DataInicial + "' and '" + DataFinal + "'"}) R + ${Condicao1} + group by R.Matricula, R.Aluno, R.Data, R.Unidade, R.ValorTotal, R.ValorPrimeira, R.Mensalidade, R.QTDParcela, R.Parcelas, R.ValorParcela, R.TotalMaterial, R.TotalSMaterial, R.TotalCMaterial, R.Cancelada) T + ${Condicao2} + `; + Index++; + LoopSQLMatriculas(Unidades, Index, SQLServerQuery, DataInicial, DataFinal, Filtro, callback); + }); + } + else { + callback(SQLServerQuery); + } + } + + router.post('/getMatriculas', verifyJWT, (req, res) => { + const Unidades = req.body.Unidades; + const DataInicial = req.body.DataInicial; + const DataFinal = req.body.DataFinal; + const Filtro = parseInt(req.body.Filtro); + LoopSQLMatriculas(Unidades, 0, "", DataInicial, DataFinal, Filtro, function(SQLServerQuery) { + SQLServerQuery += `order by T.Matricula asc;`; + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + }); + + router.post('/getTickets', verifyJWT, (req, res) => { + const Unidades = req.body.Unidades; + const DataInicial = req.body.DataInicial; + const DataFinal = req.body.DataFinal; + + let SQLServerQuery = ``; + for (let i = 0; i < Unidades.length; i++) { + if (i > 0) { + SQLServerQuery += `union all + `; + } + SQLServerQuery += `select A.Media, B.Moda, C.*, D.MediaMatricula from ( + select + round(sum(pp.Valor) / count(pp.Valor), 2) as 'Media' + from ${Unidades[i]}PreMatriculaParcelas pp + inner join ${Unidades[i]}PreMatricula pm on pm.IDPreMatricula = pp.IDPreMatricula + inner join ${Unidades[i]}Matriculas mt on mt.IDPreMatricula = pm.IDPreMatricula + where pp.Material = 0 and ${(!DataInicial || !DataFinal) ? '1=1' : "mt.DataMatricula between '" + DataInicial + "' and '" + DataFinal + "'"}) A inner join ( + select top 1 + round(pp.Valor, 2) as 'Moda' + from ${Unidades[i]}PreMatriculaParcelas pp + inner join ${Unidades[i]}PreMatricula pm on pm.IDPreMatricula = pp.IDPreMatricula + inner join ${Unidades[i]}Matriculas mt on mt.IDPreMatricula = pm.IDPreMatricula + where pp.Material = 0 and ${(!DataInicial || !DataFinal) ? '1=1' : "mt.DataMatricula between '" + DataInicial + "' and '" + DataFinal + "'"} + group by pp.Valor + order by count(pp.Valor) desc) B on 1 = 1 + inner join ( + select + round(pp.Valor, 2) as 'Valor', + '${Unidades[i].replace('.dbo.', '').replace('SGP', '')}' as 'Unidade' + from ${Unidades[i]}PreMatriculaParcelas pp + inner join ${Unidades[i]}PreMatricula pm on pm.IDPreMatricula = pp.IDPreMatricula + inner join ${Unidades[i]}Matriculas mt on mt.IDPreMatricula = pm.IDPreMatricula + where pp.Material = 0 and ${(!DataInicial || !DataFinal) ? '1=1' : "mt.DataMatricula between '" + DataInicial + "' and '" + DataFinal + "'"} + ) C on 1 = 1 + inner join ( + select + round(sum(pm.ValorMatricula) / count(pm.ValorMatricula), 2) as 'MediaMatricula' + from ${Unidades[i]}PreMatricula pm + inner join ${Unidades[i]}Matriculas mt on mt.IDPreMatricula = pm.IDPreMatricula + where ${(!DataInicial || !DataFinal) ? '1=1' : "mt.DataMatricula between '" + DataInicial + "' and '" + DataFinal + "'"} + ) D on 1 = 1 + `; + } + SQLServerQuery += `order by C.Unidade asc, C.Valor asc;`; + + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + router.post('/getCancelamentos', verifyJWT, (req, res) => { + const Unidades = req.body.Unidades; + const DataInicial = req.body.DataInicial; + const DataFinal = req.body.DataFinal; + + let SQLServerQuery = ``; + for (let i = 0; i < Unidades.length; i++) { + if (i > 0) { + SQLServerQuery += `union all + `; + } + SQLServerQuery += `select distinct + cl.Nome as 'Aluno', + pr.IDMatricula as 'Matricula', + convert(varchar, pr.Data, 103) as 'Data', + mv.DescricaoMotivo as 'Motivo', + pr.DescricaoMotivo, + '${Unidades[i].replace('.dbo.', '').replace('SGP', '')}' as 'Unidade' + from ${Unidades[i]}PreRequerimento pr + inner join ${Unidades[i]}TreinandosTurmas tt on tt.IDTreinando = pr.IDTreinando + inner join ${Unidades[i]}Clientes cl on cl.IDCliente = pr.IDTreinando + inner join ${Unidades[i]}Motivos mv on mv.IDMotivo = pr.IDMotivo + where pr.TipoRequerimento = 'C' and ${(!DataInicial || !DataFinal) ? '1=1' : "pr.Data between '" + DataInicial + "' and '" + DataFinal + "'"} + `; + } + SQLServerQuery += `order by Unidade asc;`; + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + router.post('/getVisitas', verifyJWT, (req, res) => { + const Unidades = req.body.Unidades; + const DataInicial = req.body.DataInicial; + const DataFinal = req.body.DataFinal; + + let SQLServerQuery = ``; + for (let i = 0; i < Unidades.length; i++) { + if (i > 0) { + SQLServerQuery += `union all + `; + } + SQLServerQuery += `select distinct + ra.Descricao as 'Resultado', + mt.IDMatricula, + fa.Descricao as 'FormaAtendimento', + ve.Descricao as 'Divulgacao', + pv.Descricao as 'Curso', + fu.Nome as 'Funcionario', + ca.Nome as 'Cliente', + convert(varchar, ca.Data, 103) + ' ' + convert(varchar, ca.Hora, 8) as 'Data', + '${Unidades[i].replace('.dbo.', '').replace('SGP', '')}' as 'Unidade' + from ${Unidades[i]}ControleAtendimento ca + inner join ${Unidades[i]}FormasAtendimento fa on fa.IDFormaAtendimento = ca.IDFormaAtendimento + inner join ${Unidades[i]}Veiculos ve on ve.IDVeiculo = ca.IDVeiculo + left join ${Unidades[i]}ProdutosVendas pv on pv.IDProduto = ca.IDProduto + inner join ${Unidades[i]}Funcionarios fu on fu.IDFuncionario = ca.IDFuncionario + left join ${Unidades[i]}Atendimentos at on at.IdAtendimento = ca.IDAtendimento + left join ${Unidades[i]}ResultadosAtendimento ra on ra.IDResultadoAtendimento = at.IDResultadoAtendimento + left join ${Unidades[i]}Matriculas mt on (mt.IDAtendimento + 1) = at.IdAtendimento + where ${(!DataInicial || !DataFinal) ? '1=1' : "ca.Data between '" + DataInicial + "' and '" + DataFinal + "'"} + `; + } + SQLServerQuery += `order by Unidade asc;`; + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + router.post('/getAlunosIrregulares', verifyJWT, (req, res) => { + const Unidades = req.body.Unidades; + let SQLServerQuery = ``; + for (let i = 0; i < Unidades.length; i++) { + if (i > 0) { + SQLServerQuery += `union all + `; + } + SQLServerQuery += ` + select distinct + mt.IDMatricula as 'Matricula', + c.Nome, + case when tt.Faltoso = 0 then 'Não' else 'Sim' end as 'Faltoso', + case when tt.Desistente = 0 then 'Não' else 'Sim' end as 'Desistente', + case when tt.Concluiu = 0 then 'Não' else 'Sim' end as 'Concluiu', + '${Unidades[i].replace('.dbo.', '').replace('SGP', '')}' as 'Unidade' + from ${Unidades[i]}MatriculasTreinandos mt + inner join ${Unidades[i]}Clientes c ON mt.IDTreinando = c.IDCliente + inner join ${Unidades[i]}TreinandosTurmas tt on tt.IDTreinando = mt.IDTreinando + where tt.Faltoso = 1 or tt.Concluiu = 1 or tt.Desistente = 1 + `; + } + SQLServerQuery += `order by Unidade asc;`; + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + router.get('/getAlunosDesativados', verifyJWT, (req, res) => { + execSQLQuery(`select + ad.idusers as 'Matricula', + ad.idunits, + un.unityname as 'Unidade', + ad.desativado, + case when ad.desativado = 1 then 'Sim' else 'Não' end as 'DesativadoT' + from alunosdesativados ad + inner join units un on un.idunits = ad.idunits;`, res, req.originalUrl); + }); + + router.get('/getAlunosDesativadosP', verifyJWT, (req, res) => { + execSQLQuery(`select + uh.idusers as 'Matricula', + uh.idunits, + un.unityname as 'Unidade', + uh.disabled as 'desativado', + case when uh.disabled = 1 then 'Sim' else 'Não' end as 'DesativadoT' + from usershomework uh + inner join units un on un.idunits = uh.idunits;`, res, req.originalUrl); + }); + + router.post('/getAlunosCursos', verifyJWT, (req, res) => { + const Unidades = req.body.Unidades; + const DataInicial = req.body.DataInicial; + const DataFinal = req.body.DataFinal; + + let SQLServerQuery = ``; + for (let i = 0; i < Unidades.length; i++) { + if (i > 0) { + SQLServerQuery += `union all + `; + } + SQLServerQuery += `select + S.Curso, + S.Alunos, + S.Unidade, + round((convert(decimal,S.Alunos, 2) / S.Total) * 100, 2) as 'Porcentagem' + from ( + select distinct + co.Codigo as 'IDCurso', + co.NomeVersao as 'Curso', + count(tt.IDCurso) as 'Alunos', + '${Unidades[i].replace('.dbo.', '').replace('SGP', '')}' as 'Unidade', + (select sum(T.Alunos) as 'Total' from ( + select distinct + co.Codigo as 'IDCurso', + count(tt.IDCurso) as 'Alunos' + from ${Unidades[i]}TreinandosTurmas tt + inner join ${Unidades[i]}Cursos co on co.Codigo = tt.IDCurso and co.IDTipoCurso in (3,5) + inner join ${Unidades[i]}Matriculas ma on ma.IDMatricula = tt.IDMatricula and ma.DataMatricula >= '${DataInicial}' and ma.DataMatricula <= '${DataFinal}' + group by co.NomeVersao, co.Codigo) T) as 'Total' + from ${Unidades[i]}TreinandosTurmas tt + inner join ${Unidades[i]}Cursos co on co.Codigo = tt.IDCurso and co.IDTipoCurso in (3,5) + inner join ${Unidades[i]}Matriculas ma on ma.IDMatricula = tt.IDMatricula and ma.DataMatricula >= '${DataInicial}' and ma.DataMatricula <= '${DataFinal}' + group by co.NomeVersao, co.Codigo) S + `; + } + SQLServerQuery += `order by Unidade asc;`; + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + + router.post('/getAlunosAtivos', (req, res) => { + let Unidades = req.body.Unidades; + const CruzaMySQL = req.body.cruzamysql; + const Cancelada = req.body.cancelada ? 1 : 0; + const Suspensa = req.body.suspensa ? 1 : 0; + const Desistente = req.body.desistente ? 1 : 0; + const Faltoso = req.body.faltoso ? 1 : 0; + const Concluiu = req.body.concluiu ? 1 : 0; + const DataInicial = req.body.DataInicial; + const DataFinal = req.body.DataFinal; + + let NovaUnidades = []; + for (let i = 0; i < Unidades.length; i++) { + NovaUnidades.push({"db": Unidades[i], "TabelaDatas": [], "TabelaSQL": "(select * from ("}); + } + + GetUltimaAulaMatriculas(0, NovaUnidades, function(newUnidades) { + let SQLServerQuery = ``; + for (let i = 0; i < Unidades.length; i++) { + if (i > 0) { + SQLServerQuery += `union all + `; + } + if (!CruzaMySQL) { + SQLServerQuery += `select ROW_NUMBER() OVER(ORDER BY GG.Unidade ASC, GG.Matricula ASC) AS 'N', * from ( + select distinct + T.Unidade, + T.IDMatricula as 'Matricula', + T.Nome, + T.Responsavel, + T.Endereco, + T.Fone, + T.UltimaData + from ( + select + '${NovaUnidades[i]['db'].replace('.dbo.', '').replace('SGP', '')}' as 'Unidade', + *, + case when R.CH_Consumida >= R.CargaHorariaTotal then 1 else 0 end as 'Concluiu' + from ( + select + tt.IDMatricula, + tt.IDTreinando, + tt.IDCurso, + tu.IdTurma, + (select re.Nome from ${NovaUnidades[i]['db']}Clientes re where re.IDCliente = mt.IDClienteResponsavel) as 'Responsavel', + cl.Endereco, + case + when cl.Celular != '' then cl.Celular + when cl.FoneResidencial != '' then cl.FoneResidencial + when cl.FoneRecado != '' then cl.FoneRecado + when cl.FoneComercial != '' then cl.FoneComercial + end as 'Fone', + cl.Nome, + tu.Codigo, + tu.DataInicio, + (select top(1) tc.Data from ${NovaUnidades[i]['db']}TurmasCalendario tc where tc.IdTurma = tt.CodigoTurma and tc.CodigoCurso = tt.IDCurso order by tc.IdTurmasCalendario asc) as 'PrimeiraAula', + tu.DataTermino, + (select top(1) tc.Data from ${NovaUnidades[i]['db']}TurmasCalendario tc where tc.IdTurma = tt.CodigoTurma and tc.CodigoCurso = tt.IDCurso order by tc.IdTurmasCalendario desc) as 'UltimaAula', + cu.CH_Individual, + (select (count(*) * 2) from ${NovaUnidades[i]['db']}Chamadas ch where ch.IDTurma = tt.CodigoTurma and ch. IDCurso = tt.IDCurso) as 'CH_Consumida', + (select top(1) ch.Data from ${NovaUnidades[i]['db']}Chamadas ch where ch.IDTurma = tt.CodigoTurma and ch. IDCurso = tt.IDCurso order by ch.IDChamadas desc) as 'UltimaChamada', + H_${i}.UltimaData, + case when pr.IDPreRequerimento is not null then 1 else 0 end as 'Trancada', + tt.Desistente, + tt.Faltoso, + tu.Cancelada, + tu.Suspensa, + tu.CargaHorariaTotal, + mt.DataMatricula + from ${NovaUnidades[i]['db']}TreinandosTurmas tt + inner join ${NovaUnidades[i]['db']}Turmas tu on tu.IdTurma = tt.CodigoTurma + inner join ${NovaUnidades[i]['db']}Cursos cu on cu.Codigo = tt.IDCurso + inner join ${NovaUnidades[i]['db']}Clientes cl on cl.IDCliente = tt.IDTreinando + inner join ${NovaUnidades[i]['db']}Matriculas mt on mt.IDMatricula = tt.IDMatricula + left join ${NovaUnidades[i]['db']}PreRequerimento pr on pr.IDMatricula = tt.IDMatricula and pr.IDTurma = tt. CodigoTurma and pr.TipoRequerimento = 'T' + left join ${NovaUnidades[i]['TabelaSQL']} on H_${i}.Matricula = tt.IDMatricula) R + ) T + where (T.Cancelada = ${Cancelada} and T.Suspensa = ${Suspensa} and T.Desistente = ${Desistente} and T.Faltoso = ${Faltoso} and T.Concluiu = ${Concluiu} and T.DataMatricula < '${DataFinal}') or + T.UltimaData between '${DataInicial}' and '${DataFinal}' + ) GG + `; + } + else { + SQLServerQuery += `select ROW_NUMBER() OVER(ORDER BY GG.Unidade ASC, GG.Matricula ASC) AS 'N', * from ( + select distinct + T.Unidade, + T.IDMatricula as 'Matricula', + T.Nome, + T.Responsavel, + T.Endereco, + T.Fone + from ( + select + '${NovaUnidades[i]['db'].replace('.dbo.', '').replace('SGP', '')}' as 'Unidade', + *, + case when R.CH_Sistema >= R.CargaHorariaTotal then 1 else 0 end as 'Concluiu' + from ( + select + tt.IDMatricula, + tt.IDTreinando, + tt.IDCurso, + tu.IdTurma, + (select re.Nome from ${NovaUnidades[i]['db']}Clientes re where re.IDCliente = mt.IDClienteResponsavel) as 'Responsavel', + cl.Endereco, + case + when cl.Celular != '' then cl.Celular + when cl.FoneResidencial != '' then cl.FoneResidencial + when cl.FoneRecado != '' then cl.FoneRecado + when cl.FoneComercial != '' then cl.FoneComercial + end as 'Fone', + cl.Nome, + tu.Codigo, + tu.DataInicio, + (select top(1) tc.Data from ${NovaUnidades[i]['db']}TurmasCalendario tc where tc.IdTurma = tt.CodigoTurma and tc.CodigoCurso = tt.IDCurso order by tc.IdTurmasCalendario asc) as 'PrimeiraAula', + tu.DataTermino, + (select top(1) tc.Data from ${NovaUnidades[i]['db']}TurmasCalendario tc where tc.IdTurma = tt.CodigoTurma and tc.CodigoCurso = tt.IDCurso order by tc.IdTurmasCalendario desc) as 'UltimaAula', + cu.CH_Individual, + (select (count(*) * 2) from ${NovaUnidades[i]['db']}Chamadas ch where ch.IDTurma = tt.CodigoTurma and ch. IDCurso = tt.IDCurso) as 'CH_Consumida', + (select top(1) ch.Data from ${NovaUnidades[i]['db']}Chamadas ch where ch.IDTurma = tt.CodigoTurma and ch. IDCurso = tt.IDCurso order by ch.IDChamadas desc) as 'UltimaChamada', + H_${i}.UltimaData, + H_${i}.PrimeiraData, + H_${i}.CH_Sistema, + case when pr.IDPreRequerimento is not null then 1 else 0 end as 'Trancada', + tt.Desistente, + tt.Faltoso, + tu.Cancelada, + tu.Suspensa, + tu.CargaHorariaTotal, + mt.DataMatricula + from ${NovaUnidades[i]['db']}TreinandosTurmas tt + left join ${NovaUnidades[i]['db']}Turmas tu on tu.IdTurma = tt.CodigoTurma + inner join ${NovaUnidades[i]['db']}Cursos cu on cu.Codigo = tt.IDCurso + left join ${NovaUnidades[i]['db']}ProgramaTreinamentoCursos pc on pc.CodigoCurso = cu.Codigo + left join ${NovaUnidades[i]['db']}ProgramaTreinamento pt on pt.Codigo = pc.Codigo and pt.Desativado = 0 + inner join ${NovaUnidades[i]['db']}Clientes cl on cl.IDCliente = tt.IDTreinando + left join ${NovaUnidades[i]['db']}Matriculas mt on mt.IDMatricula = tt.IDMatricula + left join ${NovaUnidades[i]['db']}PreRequerimento pr on pr.IDMatricula = tt.IDMatricula and pr.IDTurma = tt. CodigoTurma and pr.TipoRequerimento = 'T' + left join ${NovaUnidades[i]['TabelaSQL']} on H_${i}.Matricula = tt.IDMatricula) R + ) T + where (T.Cancelada = ${Cancelada} and T.Suspensa = ${Suspensa} and T.Desistente = ${Desistente} and T.Faltoso = ${Faltoso} and T.Concluiu = ${Concluiu} and T.DataMatricula < '${DataFinal}') + ${(Concluiu == 1) ? `` : `or ((T.PrimeiraData <= '${DataInicial}' and T.UltimaData >= '${DataFinal}') or + (T.PrimeiraData between '${DataInicial}' and '${DataFinal}') or + (T.UltimaData between '${DataInicial}' and '${DataFinal}') or + (T.PrimeiraData between '${DataInicial}' and '${DataFinal}' and T.UltimaData >= '${DataFinal}') or + (T.UltimaData between '${DataInicial}' and '${DataFinal}' and T.PrimeiraData <= '${DataInicial}') + )`}) GG + `; + } + } + SQLServerQuery += `order by GG.Unidade asc, GG.Matricula asc;`; + + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + }); + + function GetUltimaAulaMatriculas(Index, Unidades, callback) { + if (Index < Unidades.length) { + let SQLQuery = `select + sc.idusers, + max(date_format(sc.insert_date, '%Y-%m-%d')) as 'UltimaAula' + from stepclass sc + inner join units un on un.idunits = sc.idunits + where un.reference_db = '${Unidades[Index]['db'].replace('.dbo.', '')}' + group by sc.idusers;`; + let newSQLQuery = `select + sc.idusers, + tc.idtraineeprogram, + (count(sc.insert_date) * 2) as 'CH_Consumida', + min(date_format(sc.insert_date, '%Y-%m-%d')) as 'PrimeiraAula', + max(date_format(sc.insert_date, '%Y-%m-%d')) as 'UltimaAula' + from stepclass sc + inner join classes cl on cl.idclasses = sc.idclasses + inner join traineeprogramcourses tc on tc.idcourses = cl.idcourses + inner join traineeprogram tp on tp.idtraineeprogram = tc.idtraineeprogram and tp.disabled = 0 + inner join units un on un.idunits = sc.idunits + where un.reference_db = '${Unidades[Index]['db'].replace('.dbo.', '')}' + group by sc.idusers, tc.idtraineeprogram;`; + mysqlConnection.query(newSQLQuery, function (error, Datas, fields) { + Unidades[Index]['TabelaDatas'] = Datas; + for (let i = 0; i < Datas.length; i++) { + if (i > 0) + Unidades[Index]['TabelaSQL'] += `union all `; + Unidades[Index]['TabelaSQL'] += `select '${Datas[i]['idusers']}' as 'Matricula', '${Datas[i]['PrimeiraAula']}' as 'PrimeiraData', '${Datas[i]['UltimaAula']}' as 'UltimaData', '${Datas[i]['idtraineeprogram']}' as 'ProgramaTreinamento', '${Datas[i]['CH_Consumida']}' as 'CH_Sistema' `; + } + if (Datas.length == 0) { + Unidades[Index]['TabelaSQL'] += `select '' as 'Matricula', '' as 'PrimeiraData', '' as 'UltimaData', '' as 'ProgramaTreinamento', '' as 'CH_Sistema'`; + } + Unidades[Index]['TabelaSQL'] += `) G_${Index}) H_${Index}`; + Index++; + GetUltimaAulaMatriculas(Index, Unidades, callback); + }); + } + else { + callback(Unidades); + } + } + + + router.post('/getContasReceber', verifyJWT, (req, res) => { + const Unidades = req.body.Unidades; + const DataInicial = req.body.DataInicial; + const DataFinal = req.body.DataFinal; + + LoopContasReceber(0, Unidades, DataInicial, DataFinal, [], function(Resultados) { + res.send({ "status": 200, "error": null, "response": Resultados }); + }); + //SQLServerQuery += `order by Unidade asc;`; + //console.log(SQLServerQuery); + //execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + function LoopContasReceber(Index, Unidades, DataInicial, DataFinal, Resultados, callback) { + if (Index < Unidades.length) { + sqlServerConnection.request().query(`exec ${Unidades[Index]}proc_InicializaRelAtrasadas '${DataInicial}','${DataFinal}',0,1,0,0,'G',0,'';`, function (error, results, fields) { + for (let i = 0; i < results['recordsets'][0].length; i++) { + results['recordsets'][0][i]['Unidade'] = Unidades[Index].split('.dbo.')[0].replace('SGP', ''); + + Resultados.push(results['recordsets'][0][i]); + } + Index++; + LoopContasReceber(Index, Unidades, DataInicial, DataFinal, Resultados, callback); + }); + } + else { + callback(Resultados); + } + } + + router.post('/getParcelasAtrasadas', verifyJWT, (req, res) => { + const Unidade = req.body.Unidade; + const IDMatricula = req.body.IDMatricula; + const IDCliente = req.body.IDCliente; + + let SQLServerQuery = `exec ${Unidade}proc_PesquisaParcelasAtrasadas ${IDMatricula},${IDCliente},3, .02, .0003;`; + //SQLServerQuery += `order by Unidade asc;`; + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + router.post('/getHistoricoFinanceiro', verifyJWT, (req, res) => { + const Unidade = req.body.Unidade; + const IDMatricula = req.body.IDMatricula; + + let SQLServerQuery = `exec ${Unidade}proc_ContasReceberHistorico .02, .0003,3,${IDMatricula};`; + //SQLServerQuery += `order by Unidade asc;`; + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + router.post('/InserirCobranca', verifyJWT, (req, res) => { + const Unidade = req.body.Unidade; + const IDMatricula = req.body.IDMatricula; + const IDFuncionario = req.body.IDFuncionario; + const DataStr = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '').split(" ")[0]; + const Data = DataStr.split('-')[0] + "-" + DataStr.split('-')[1] + "-" + DataStr.split('-')[2]; + const Hora = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '').split(" ")[1]; + const Protestado = req.body.Protestado ? 1 : 0; + const Observacao = req.body.Observacao; + const IDTipoRequisicao = req.body.IDTipoRequisicao; + const IDDepartamento = req.body.IDDepartamento; + + let SQLServerQuery = `exec ${Unidade}proc_InserirCobranca ${IDMatricula},${IDFuncionario},'${Data}','${Hora}',${Protestado},'${Observacao}',${IDTipoRequisicao},${IDDepartamento};`; + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + router.get('/getListaFuncionarios/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`select IDFuncionario, Nome from ${db}Funcionarios;`, res, req.originalUrl); + }); + + router.get('/getHistoricoCobrancas/:db/:IDMatricula', verifyJWT, (req, res) => { + const db = req.params.db; + const IDMatricula = req.params.IDMatricula; + execSQLQuery2(`exec ${db}proc_HistoricoGeral ${IDMatricula};`, res, req.originalUrl); + }); + + router.get('/verificaAGendamento/:db/:IDMatricula', verifyJWT, (req, res) => { + const db = req.params.db; + const IDMatricula = req.params.IDMatricula; + execSQLQuery2(`exec ${db}proc_VerificaAgendamentoCobranca ${IDMatricula};`, res, req.originalUrl); + }); + + router.post('/InserirAgendamento', verifyJWT, (req, res) => { + const Unidade = req.body.Unidade; + const IDMatricula = req.body.IDMatricula; + const DataAgendamento = req.body.DataAgendamento; + + let SQLServerQuery = `exec ${Unidade}proc_InserirAgendamentoCobranca ${IDMatricula},'${DataAgendamento}',1;`; + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + router.patch('/AtualizarDadosCliente', verifyJWT, (req, res) => { + const Unidade = req.body.Unidade; + const IDCliente = req.body.Cliente; + const CEP = req.body.CEP; + const Endereco = req.body.Endereco; + const Bairro = req.body.Bairro; + const Cidade = req.body.Cidade; + const UF = req.body.UF; + const Celular = req.body.Celular; + const FoneComercial = req.body.FoneComercial; + const FoneResidencial = req.body.FoneResidencial; + const FoneRecado = req.body.FoneRecado; + + let SQLServerQuery = `update SGP${Unidade}.dbo.Clientes set + CEP = '${CEP}', + Endereco = '${Endereco}', + Bairro = '${Bairro}', + Cidade = '${Cidade}', + UF = '${UF}', + Celular = '${Celular}', + FoneComercial = '${FoneComercial}', + FoneResidencial = '${FoneResidencial}', + FoneRecado = '${FoneRecado}' + where IDCliente = ${IDCliente};`; + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + router.post('/getAgendamentosCobranca', verifyJWT, (req, res) => { + const Unidades = req.body.Unidades; + const DataInicial = req.body.DataInicial; + const DataFinal = req.body.DataFinal; + + let SQLServerQuery = ``; + for (let i = 0; i < Unidades.length; i++) { + if (i > 0) { + SQLServerQuery += `union all + `; + } + SQLServerQuery += `select + '${Unidades[i].replace('.dbo.', '').replace('SGP', '')}' as 'Unidade', + cb.IDCobranca, + ac.IDAgendamentoCobranca, + cb.IDMatricula, + cl.Nome as 'Cliente', + cl.Celular, + convert(varchar, cb.Data, 103) + ' ' + convert(varchar, cb.Hora, 24) as 'Data', + convert(varchar, ac.DataAgendamento, 103) as 'DataAgendamento', + cb.Observacao + from ${Unidades[i]}Cobranca cb + inner join ${Unidades[i]}AgendamentoCobranca ac on ac.IDCobranca = cb.IDCobranca + inner join ${Unidades[i]}Matriculas mt on mt.IDMatricula = cb.IDMatricula + inner join ${Unidades[i]}Clientes cl on cl.IDCliente = mt.IDClienteResponsavel + where ${(!DataInicial || !DataFinal) ? '1=1' : "ac.DataAgendamento between '" + DataInicial + "' and '" + DataFinal + "'"} + `; + } + SQLServerQuery += `order by Unidade asc;`; + //console.log(SQLServerQuery); + execSQLQuery2(SQLServerQuery, res, req.originalUrl); + }); + + + + return router; +}; + +module.exports = routes; \ No newline at end of file diff --git a/controllers/slidesController.js b/controllers/slidesController.js new file mode 100644 index 0000000..09a58f4 --- /dev/null +++ b/controllers/slidesController.js @@ -0,0 +1,108 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); + +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); +const formidable = require('formidable'); + +router.use(bodyParser.urlencoded({ + limit: '10mb', + extended: true + } +)); +router.use(bodyParser.json({ + limit: '10mb', + extended: true +})); + +var routes = function () { + + router.get('/getAll', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM slides;`, res, req.originalUrl); + }); + + router.get('/getSlide/:idslides', verifyJWT, (req, res) => { + const idslides = parseInt(req.params.idslides); + execSQLQuery(`SELECT + * + FROM slides + WHERE idslides = ${idslides};`, res, req.originalUrl); + }); + + router.post('/insert', verifyJWT, (req, res) => { + const idslides = parseInt(req.body.idslides); + const title = req.body.title; + const itens = parseInt(req.body.itens); + execSQLQuery(`INSERT INTO slides(title, itens) VALUES + (?, ?);`, res, req.originalUrl, [title, itens]); + }); + + router.patch('/update', verifyJWT, (req, res) => { + const idslides = parseInt(req.body.idslides); + const title = req.body.title; + const itens = parseInt(req.body.itens); + execSQLQuery(`UPDATE slides SET + title = ?, + itens = ? + WHERE idslides = ?;`, res, req.originalUrl, [title, itens, idslides]); + }); + + router.get('/renomeiaSlide/:idslides/:apartirde', verifyJWT, (req, res) => { + const idslides = parseInt(req.params.idslides); + const apartirde = parseInt(req.params.apartirde); + const fs = require('fs'); + const path = require('path'); + const Diretorio = Variables('src_media') + 'images/'; + fs.readdir(Diretorio, (err, files) => { + let ListaSlides = []; + files.forEach(file => { + if (path.basename(file).includes("slide_" + idslides)) { + ListaSlides.push(file); + } + }); + LoopRenomeiaSlide(0, apartirde, idslides, 0, ListaSlides, Diretorio, function(Sucesso) { + res.send(Sucesso); + }) + }) + }); + + function LoopRenomeiaSlide(Index, apartirde, idslides, newI, ListaSlides, Diretorio, callback) { + const fs = require('fs'); + if (Index < ListaSlides.length) { + if (Index != apartirde) { + if (Index >= apartirde) { + let NovoNome = "slide_" + idslides + "_" + newI + ".jpg"; + console.log("De: " + ListaSlides[Index] + " - Para: " + NovoNome); + fs.rename(Diretorio + ListaSlides[Index], Diretorio + NovoNome, function (err) { + Index++; + newI++; + LoopRenomeiaSlide(Index, apartirde, idslides, newI, ListaSlides, Diretorio, callback); + }); + } + else { + Index++; + newI++; + LoopRenomeiaSlide(Index, apartirde, idslides, newI, ListaSlides, Diretorio, callback); + } + } + else { + fs.unlink(Diretorio + ListaSlides[Index], function (err) { + Index++; + LoopRenomeiaSlide(Index, apartirde, idslides, newI, ListaSlides, Diretorio, callback); + }); + } + } + else { + callback(true); + } + } + + + return router; +}; + +module.exports = routes; diff --git a/controllers/sqlServerController.js b/controllers/sqlServerController.js new file mode 100644 index 0000000..d36df02 --- /dev/null +++ b/controllers/sqlServerController.js @@ -0,0 +1,22 @@ +require('../connections/sql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + router.get('/dbs', verifyJWT, (req, res) => { + execSQLQuery2(`SELECT + name + FROM master.dbo.sysdatabases + WHERE cmptlevel = 80 + ORDER BY name ASC;`, res, req.originalUrl); + }) + + return router; +}; + +module.exports = routes; diff --git a/controllers/studentController.js b/controllers/studentController.js new file mode 100644 index 0000000..7ff22eb --- /dev/null +++ b/controllers/studentController.js @@ -0,0 +1,314 @@ +require("../connections/mysql-server"); +require("../connections/sql-server"); +require("../helpers/CheckToken"); +const express = require("express"); +const router = express.Router(); +const bodyParser = require("body-parser"); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +const sqlServer = function (sqlQry) { + return new Promise((resolve, reject) => { + sqlServerConnection + .request() + .query(sqlQry, function (error, Result, fields) { + let Retorno = []; + if (error) { + Retorno = { status: 500, error: error, response: [] }; + console.log(error); + return reject(error); + } else { + resolve(Result); + } + }); + }); +}; + +var routes = function () { + router.get("/getAllStudent", (req, res) => { + execSQLQuery( + `SELECT + * + FROM agenda;`, + res, + req.originalUrl + ); + }); + + router.post("/insertStudent/:banco", (req, res) => { + const db = req.params.banco; + console.log(db, "banco de dado"); + let { nome, senha, IdUnidade, IdCurso, idFuncionario } = req.body; + senha = encriptPassword(senha); + console.log([nome, senha, IdUnidade, IdCurso]); + let sqlQry = `SELECT MAX([IDCliente]) as 'lastClientId' FROM ${db}[Clientes];`; + console.log(sqlQry); + sqlServerConnection + .request() + .query(sqlQry, function (error, IdClientResult, fields) { + let Retorno = []; + if (error || IdClientResult.length == 0) { + Retorno = { status: 500, error: error, response: [] }; + return res.send(JSON.stringify(Retorno)); + } else { + let { lastClientId } = IdClientResult.recordsets[0][0]; + console.log(lastClientId); + let newClientId = lastClientId + 1; + let sqlInsertClient = `INSERT INTO ${db}[Clientes] (IDCliente, IDUnidade, Nome, PessoaFisica, SenhaIntranet) + VALUES (${newClientId}, ${IdUnidade}, '${nome}', 1, '${senha}');`; + console.log("antes da segunda"); + console.log(sqlInsertClient); + sqlServerConnection + .request() + .query( + sqlInsertClient, + function (error, cadastroClientResult, fields) { + console.log("dentro da segunda"); + if (error) { + Retorno = { status: 500, error: error, response: [] }; + return res.send(JSON.stringify(Retorno)); + } else { + let sqlLastTurmaId = `(SELECT MAX([IdTurma]) as lastTurmaId FROM ${db}[Turmas])`; + sqlServerConnection + .request() + .query( + sqlLastTurmaId, + function (error, IdTurmarResult, fields) { + console.log("dentro da quinta"); + let Retorno = []; + if (error || IdTurmarResult.length == 0) { + Retorno = { + status: 500, + error: error, + response: [], + }; + return res.send(JSON.stringify(Retorno)); + } else { + let { lastTurmaId } = IdTurmarResult.recordsets[0][0]; + console.log(lastTurmaId); + let newTurmaId = lastTurmaId + 1; + let sqlInsertTurma = `INSERT INTO ${db}[Turmas] (IdTurma, Codigo, Nome, DataInicio, DataTermino, HorarioRegular, Domingo, Segunda, Terca, Quarta, Quinta, Sexta, Sabado, Cancelada, Suspensa, IgnoraFerias, ServeCafe, ValorHoraAula, SequenciaRotativa, BloqueadaVenda, CursosParalelos, ForcarDataFinal, IDFuncionario) + Values (${newTurmaId}, '230PYCO000', '${nome}', getDate(), dateadd(yy, 1, getdate()), 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ${idFuncionario});`; + console.log(sqlInsertTurma); + sqlServerConnection + .request() + .query( + sqlInsertTurma, + function (error, CadastroTurmaResult, fields) { + console.log("dentro da sexta"); + let Retorno = []; + if (error) { + Retorno = { + status: 500, + error: error, + response: [], + }; + return res.send(JSON.stringify(Retorno)); + } else { + let sqlLastMatriculaId = `SELECT MAX([IDMatricula]) as 'lastMatriculaId' FROM ${db}[Matriculas];`; + sqlServerConnection + .request() + .query( + sqlLastMatriculaId, + function ( + error, + IdMatriculaResult, + fields + ) { + console.log("dentro da terceira"); + let Retorno = []; + if ( + error || + IdMatriculaResult.length == 0 + ) { + Retorno = { + status: 500, + error: error, + response: [], + }; + return res.send( + JSON.stringify(Retorno) + ); + } else { + let { lastMatriculaId } = + IdMatriculaResult.recordsets[0][0]; + console.log(lastMatriculaId); + let newMatriculaId = + lastMatriculaId + 1; + let sqlIsertMatricula = `INSERT INTO ${db}[Matriculas] (IDMatricula, IDUnidade, CodigoTurma, ContratoImpresso, Certificado, Folha, CartasBoasVindas, DescontoDiferencial, DescontoPontualidade, UsaPerDescPontualidade) + values (${newMatriculaId}, ${IdUnidade}, ${newTurmaId}, 0, 0, 0, 0, 0, 0, 0);`; + console.log(sqlIsertMatricula); + sqlServerConnection + .request() + .query( + sqlIsertMatricula, + function ( + error, + CadMatriculasResult, + fields + ) { + console.log("dentro da quarta"); + + let Retorno = []; + if (error) { + Retorno = { + status: 500, + error: error, + response: [], + }; + return res.send( + JSON.stringify(Retorno) + ); + } else { + let sqlInsertMatriculaCursos = `insert into ${db}[MatriculasCursos] (IDMatricula, IDCurso, CodigoTurma, Gratis, MaterialImbutido) + values (${newMatriculaId}, ${IdCurso}, ${newTurmaId}, 0, 1);`; + sqlServerConnection + .request() + .query( + sqlInsertMatriculaCursos, + function ( + error, + CadastroMatriculaCursoResult, + fields + ) { + let Retorno = []; + if (error) { + Retorno = { + status: 500, + error: error, + response: [], + }; + return res.send( + JSON.stringify( + Retorno + ) + ); + } else { + let sqlInsertTreinandoTurmas = ` Insert Into ${db}[TreinandosTurmas] (IDMatricula, IDTreinando, IDCurso, CodigoTurma, Concluiu, Desistente, Faltoso, EmitiuCertificado, RecebeuMaterial, Aprovado) + Values (${newMatriculaId}, ${newClientId}, ${IdCurso}, ${newTurmaId}, 0, 0, 0, 0, 0, 0);`; + sqlServerConnection + .request() + .query( + sqlInsertTreinandoTurmas, + function ( + error, + CadastroMatriculaCursoResult, + fields + ) { + let Retorno = + []; + if (error) { + Retorno = { + status: 500, + error: + error, + response: + [], + }; + return res.send( + JSON.stringify( + Retorno + ) + ); + } else { + return res.send( + JSON.stringify( + { + mensage: + "Aluno matriculado com sucesso", + matricula: + newMatriculaId, + idturma: + newTurmaId, + } + ) + ); + } + } + ); + } + } + ); + } + } + ); + } + } + ); + } + } + ); + } + } + ); + } + } + ); + } + }); + }); + + router.post("/editStudent", (req, res) => { + const id = req.body.id; + const title = req.body.title; + const date = req.body.date; + const hour = req.body.hour; + const duration = req.body.duration; + const description = req.body.description; + const access = req.body.access; + execSQLQuery( + ` UPDATE agenda SET + title='${title}', + date='${date}', + hour='2021-01-01T${hour}', + duration='${duration}', + description='${description}', + access='${access}' + WHERE (idagenda = '${id}')`, + res, + req.originalUrl + ); + }); + + router.post("/deleteStudent", (req, res) => { + const id = req.body.id; + execSQLQuery( + ` DELETE FROM agenda + WHERE (idagenda = '${id}')`, + res, + req.originalUrl + ); + }); + + router.post("/insertTurmaCalendarioChamada/:banco", async (req, res) => { + const db = req.params.banco; + const { IDCurso, IDTurma, IDFuncionario, numeroDeAulas } = req.body; + console.log(IDCurso, IDTurma, IDFuncionario, numeroDeAulas); + let sqlQry = `insert into ${db}[TurmasCalendario] (IdTurmasCalendario, IdTurma, CodigoCurso, CodigoInstrutor, Data, HoraInicial, HoraFinal, Ministrado, PesquisaOpiniao ) + values((select max(IdTurmasCalendario) from ${db}[TurmasCalendario]) + 1, ${IDTurma}, ${IDCurso}, ${IDFuncionario}, getDate(), getDate(), getDate(), 0, 0 )`; + console.log(sqlQry); + let infos = []; + for (let i = 0; i < numeroDeAulas; i++) { + try { + let result = await sqlServer(sqlQry); + console.log(result); + console.log("cadastrei papai"); + setTimeout(() => {}, 1000); + console.log(`cadastro ${i}`); + } catch (error) { + console.log(error); + } + } + console.log(infos); + // return res.send( + // JSON.stringify({ + // message: "InseridoAulasChamadas", + // }) + // ); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/teacherController.js b/controllers/teacherController.js new file mode 100644 index 0000000..c4a61c7 --- /dev/null +++ b/controllers/teacherController.js @@ -0,0 +1,597 @@ +require('../connections/mysql-server'); +require('../connections/sql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ + limit: '10mb', + extended: true +})); +router.use(bodyParser.json({ + limit: '10mb', + extended: true +})); + +var routes = function () { + + router.get('/getTurmas/:idfuncuionario/:db', verifyJWT, (req, res) => { + var idfuncuionario = parseInt(req.params.idfuncuionario); + var db = req.params.db; + execSQLQuery2(`SELECT DISTINCT + IdTurma + FROM ${db}TurmasCalendario + /*WHERE CodigoInstrutor = ${idfuncuionario}*/;`, res, req.originalUrl); + }) + + router.get('/getMatriculas/:idturma/:db', verifyJWT, (req, res) => { + var idturma = parseInt(req.params.idturma); + var db = req.params.db; + execSQLQuery2(` + SELECT DISTINCT + IDMatricula + FROM + ${db}Matriculas + WHERE + CodigoTurma = ${idturma}`, + res, + req.originalUrl + ); + }) + + router.get('/getNomeAluno/:idmatricula/:db', verifyJWT, (req, res) => { + var idmatricula = parseInt(req.params.idmatricula); + var db = req.params.db; + execSQLQuery2(` + SELECT + ${db}Clientes.Nome + FROM + ${db}MatriculasTreinandos + INNER JOIN + ${db}Clientes + ON + ${db}MatriculasTreinandos.IDTreinando = ${db}Clientes.IDCliente + WHERE + ${db}MatriculasTreinandos.IDMatricula = '${idmatricula}'`, + res, + req.originalUrl + ); + }) + + router.get('/getCallsOfClassesNotMaked/:idmatricula/:qtdeaulas/:idcourses/:idunits/:nome', verifyJWT, (req, res) => { + var idmatricula = parseInt(req.params.idmatricula); + var qtdeaulas = parseInt(req.params.qtdeaulas); + var idcourses = parseInt(req.params.idcourses); + var idunits = parseInt(req.params.idunits); + var nome = req.params.nome; + var sqlQry = `SELECT + t.idclasses, + (select name from classes where idclasses = t.idclasses) as Aula, + ${idcourses} AS CodigoCurso, + (select name from courses where idcourses = ${idcourses}) as NomeVersao, + ${idmatricula} AS IDMatricula, + '${nome}' AS Nome + FROM ( + SELECT DISTINCT + CASE WHEN c.idclasses = r.idclasses THEN 1 ELSE 0 END AS Completed, + c.* + FROM + classes c + LEFT JOIN + (SELECT DISTINCT + c.idclasses + FROM + stepclass sc + INNER JOIN + classes c + ON + sc.idclasses = c.idclasses + WHERE + sc.idusers = ${idmatricula} + AND + c.idcourses = ${idcourses} + AND + sc.idunits = ${idunits}) r + ON + r.idclasses = c.idclasses + WHERE + ordem + 1 <= ${qtdeaulas} + AND + idcourses = ${idcourses} + ORDER BY + c.ordem) t + WHERE + t.Completed = 0 + ORDER BY + t.ordem;`; + execSQLQuery(sqlQry, res, req.originalUrl); + }) + + router.get('/getStudentsByTeacher/:db/:idinstrutor', verifyJWT, (req, res) => { + var db = req.params.db; + var idinstrutor = parseInt(req.params.idinstrutor); + execSQLQuery2(`SELECT + Matriculas2.IDMatricula, + Turmas2.CodigoCurso, + (SELECT COUNT(*) AS Ministradas FROM ${db}TurmasCalendario WHERE CodigoCurso = Turmas2.CodigoCurso AND IdTurma = (SELECT TOP(1) CodigoTurma FROM ${db}TreinandosTurmas WHERE IDMatricula = Matriculas2.IDMatricula) AND Ministrado = 1) AS Ministradas, + (SELECT TOP(1) c.Nome FROM ${db}Clientes c INNER JOIN ${db}TreinandosTurmas tt ON c.IDCliente = tt.IDTreinando WHERE tt.IDMatricula = Matriculas2.IDMatricula) AS Nome + FROM (SELECT DISTINCT + IdTurma, + CodigoCurso + FROM ${db}TurmasCalendario tc + /*WHERE CodigoInstrutor = ${idinstrutor}*/) Turmas2 + INNER JOIN (SELECT DISTINCT + IDMatricula, + CodigoTurma + FROM ${db}Matriculas) Matriculas2 ON Turmas2.IdTurma = Matriculas2.CodigoTurma + WHERE Turmas2.CodigoCurso > 0;`, res, req.originalUrl); + }) + + router.get('/getQtdeStepclass/:idunits/:idusers/:idcourses', verifyJWT, (req, res) => { + var idunits = parseInt(req.params.idunits); + var idusers = parseInt(req.params.idusers); + var idcourses = parseInt(req.params.idcourses); + execSQLQuery(` + SELECT + COUNT(sc.idusers) as qtde_stepclass + FROM + stepclass sc + INNER JOIN + classes c ON sc.idclasses = c.idclasses + INNER JOIN + courses co ON co.idcourses = c.idcourses + WHERE + sc.idusers = ${idusers} AND sc.idunits = ${idunits} + AND co.idcourses = ${idcourses};`, + res, + req.originalUrl + ); + }) + + router.get('/getCalls/:db/:idinstrutor', verifyJWT, (req, res) => { + const db = req.params.db; + var idinstrutor = parseInt(req.params.idinstrutor); + execSQLQuery2(`SELECT DISTINCT + co.NomeVersao, + tt.IDMatricula, + c.Nome, + CONVERT(varchar, tc.Data, 103) AS Data, + CASE + WHEN tc.Ministrado = 0 THEN 'Não' else 'Sim' + END AS Ministrado + FROM ${db}TurmasCalendario tc + INNER JOIN ${db}TreinandosTurmas tt ON tt.CodigoTurma = tc.IdTurma + INNER JOIN ${db}Clientes c ON c.IDCliente = tt.IDTreinando + INNER JOIN ${db}Cursos co ON co.Codigo = tc.CodigoCurso + WHERE /*tc.CodigoInstrutor = ${idinstrutor} and*/ tt.IDMatricula > 190008 and tc.Ministrado = 0;`, res, req.originalUrl); + }); + + router.get('/getClassByOrdem/:idcourses/:ordem', verifyJWT, (req, res) => { + let idcourses = req.params.idcourses; + let ordem = req.params.ordem; + execSQLQuery(` + SELECT + idclasses + FROM + classes + WHERE + idcourses = ${idcourses} + AND + ordem = ${ordem};`, + res, + req.originalUrl + ); + }) + + router.get('/getExerciseContent/:idclasses', verifyJWT, (req, res) => { + let idclasses = req.params.idclasses; + execSQLQuery(` +SELECT + e.idexercises, + e.description AS Enunciado, + eq.idexercisequestions, + eq.content AS Questao, + ea.idexerciseanswers, + ea.content AS Resposta, + ea.iscorrect, + ea.hasmedia, + (select +t.description + from +texts t +inner join +classescontent cc +on +cc.idgames = t.idtexts +where +cc.idclasses = ${idclasses}) as Jogo +FROM + classescontent cc + INNER JOIN + exercisequestions eq ON cc.idexercises = eq.idexercises + INNER JOIN + exercises e ON e.idexercises = eq.idexercises + INNER JOIN + exerciseanswers ea ON ea.idexercisequestions = eq.idexercisequestions +WHERE + cc.idclasses = ${idclasses} +ORDER BY +cc.ordem`, res, req.originalUrl); + }) + + router.post('/getAulasRealizadas', verifyJWT, (req, res) => { + let idusers = req.body.idusers; + let idunits = req.body.idunits; + let ip_externo = req.body.ip_externo; + let porta_mysql = req.body.porta; + + let SQLQry = `SELECT DISTINCT + (SELECT idcourses FROM classes WHERE idclasses = sc.idclasses) AS IDCurso, + (SELECT description FROM courses WHERE idcourses = IDCurso) AS Curso, + idclasses AS IDAula, + (SELECT description FROM classes WHERE idclasses = sc.idclasses) AS Aula, + CASE WHEN datefinal IS NOT NULL THEN datefinal ELSE '--/--/----' END AS Data, + CASE WHEN completedClass = 0 THEN 'Não concluída' ELSE 'Concluída' END AS Status, + CASE WHEN homework = 1 THEN 'Realizada' WHEN homework = 0 THEN 'Falhou' WHEN homework IS NULL THEN 'Não realizada' END AS LicaoCasa, + CASE WHEN notegame = 1 THEN 'Sucesso' WHEN notegame IS NULL THEN 'Não concluído' WHEN notegame = 0 THEN 'Falhou' END AS Jogo, + (SELECT s.title FROM slides s WHERE idslides = (SELECT cc.idslides FROM classescontent cc INNER JOIN slides s1 ON cc. idslides = s1.idslides WHERE cc.idclasses = IDAula AND cc.idslides IS NOT NULL AND s1.title LIKE 'Montagem%')) AS Projeto, + CASE WHEN note IS NOT NULL THEN note ELSE '--' END as Nota, + (SELECT ordem + 1 FROM classes WHERE idclasses = sc.idclasses) AS Ordem + FROM + stepclass sc + WHERE + idunits = ${idunits} AND idusers = ${idusers} + ORDER BY IDCurso, Ordem;`; + mysqlConnection.query(SQLQry, function (error, results, fields) { + let Status = 0; + if (!error && results.length != 0) { + Status = 200; + console.log("/getAulasRealizadas success 200"); + } + else { + Status = 500; + console.log("/getAulasRealizadas fail 500 " + error); + } + res.send(JSON.stringify({ + "status": Status, + "error": [], + "error2": error, + "response": [], + "response2": results + })) + }) + + }) + + router.post('/getExerciciosAluno', verifyJWT, (req, res) => { + let idusers = req.body.idusers; + let idclasses = req.body.idclasses; + let idunits = req.body.idunits; + let ip_externo = req.body.ip_externo; + let porta_mysql = req.body.porta; + + let SQLQry = `SELECT + (SELECT e.description FROM exercises e WHERE eq.idexercises = e.idexercises) AS Enunciado, + eq.content AS Questao, + ea.content AS Resposta, + CASE WHEN ea.iscorrect = 1 THEN 'Correta' ELSE 'Errada' END AS Correcao, + (SELECT e.idexercisetype FROM exercises e WHERE eq.idexercises = e.idexercises) AS Tipo + FROM + exercisequestions eq + INNER JOIN + exerciseanswers ea + ON + eq.idexercisequestions = ea.idexercisequestions + INNER JOIN + usergivenanswers ua + ON + ua.idexerciseanswers = ea.idexerciseanswers + WHERE + ua.idusers = ${idusers} AND ua.idclasses = ${idclasses} and ua.idunits = ${idunits};`; + + mysqlConnection.query(SQLQry, function (error, results, fields) { + let Status = 0; + if (!error && results.length != 0) { + Status = 200; + console.log("/getAulasRealizadas success 200"); + } + else { + Status = 500; + console.log("/getAulasRealizadas fail 500 " + error); + } + + res.send(JSON.stringify({ + "status": Status, + "error2": error, + "response2": results + })) + + }) + + }) + + router.post('/getTurmasDetalhes', verifyJWT, (req, res) => { + const idfuncuionario = parseInt(req.body.IDFuncionario); + const Unidades = req.body.Unidades; + let SQLQuery = ""; + for (let i = 0; i < Unidades.length; i++) { + if (i > 0) { + SQLQuery += `union all + `; + } + /*SQLQuery += `select distinct + ${Unidades[i]['idunits']} as 'IDUnits', + '${Unidades[i]['unityname']}' as 'Unidade', + tt.IDMatricula as 'Matricula', + cl.Nome as 'Aluno', + tu.IdTurma, + cu.Codigo as 'IDCurso', + cu.NomeVersao as 'Curso', + (select top 1 convert(varchar, tc2.HoraInicial, 8) from ${Unidades[i]['reference_db']}.dbo.TurmasCalendario tc2 where tc2.IdTurma = tu.IdTurma) as 'HoraInicial', + (select top 1 convert(varchar, tc2.HoraFinal, 8) from ${Unidades[i]['reference_db']}.dbo.TurmasCalendario tc2 where tc2.IdTurma = tu.IdTurma) as 'HoraFinal', + --convert(varchar, tu.HoraInicial, 8) as 'HoraInicial', + --convert(varchar, tu.HoraFinal, 8) as 'HoraFinal', + convert(VARCHAR, tu.DataInicio, 103) as 'DataInicio', + convert(VARCHAR, tu.DataTermino, 103) as 'DataTermino', + (select count(*) from ${Unidades[i]['reference_db']}.dbo.TurmasCalendario tc1 where tc1.CodigoCurso = cu.Codigo and tc1.IdTurma = tu.IdTurma and tc1.Ministrado = 1) as 'Chamadas' + from ${Unidades[i]['reference_db']}.dbo.Turmas tu + inner join ${Unidades[i]['reference_db']}.dbo.TurmasCalendario tc on tc.IdTurma = tu.IdTurma + inner join ${Unidades[i]['reference_db']}.dbo.Cursos cu on cu.Codigo = tc.CodigoCurso + inner join ${Unidades[i]['reference_db']}.dbo.TreinandosTurmas tt on tt.CodigoTurma = tu.IdTurma and tt.IDCurso = cu.Codigo + inner join ${Unidades[i]['reference_db']}.dbo.Clientes cl on cl.IDCliente = tt.IDTreinando + `;*/ + SQLQuery += `select distinct + ${Unidades[i]['idunits']} as 'IDUnits', + '${Unidades[i]['unityname']}' as 'Unidade', + mt.IDMatricula as 'Matricula', + cl.Nome as 'Aluno', + tu.IdTurma, + tt.IDCurso, + cu.NomeVersao as 'Curso', + (select top 1 convert(varchar, tc2.HoraInicial, 8) from ${Unidades[i]['reference_db']}.dbo.TurmasCalendario tc2 where tc2.IdTurma = tu.IdTurma) as 'HoraInicial', + (select top 1 convert(varchar, tc2.HoraFinal, 8) from ${Unidades[i]['reference_db']}.dbo.TurmasCalendario tc2 where tc2.IdTurma = tu.IdTurma) as 'HoraFinal', + convert(varchar, tu.DataInicio, 103) as 'DataInicio', + convert(varchar, tu.DataTermino, 103) as 'DataTermino', + (select count(*) from ${Unidades[i]['reference_db']}.dbo.TurmasCalendario tc1 where tc1.CodigoCurso = tt.IDCurso and tc1.IdTurma = tu.IdTurma and tc1.Ministrado = 1) as 'Chamadas' + from ${Unidades[i]['reference_db']}.dbo.Matriculas mt + inner join ${Unidades[i]['reference_db']}.dbo.Turmas tu on tu.IdTurma = mt.CodigoTurma + inner join ${Unidades[i]['reference_db']}.dbo.TreinandosTurmas tt on tt.IDMatricula = mt.IDMatricula + inner join ${Unidades[i]['reference_db']}.dbo.Clientes cl on cl.IDCliente = tt.IDTreinando + inner join ${Unidades[i]['reference_db']}.dbo.Cursos cu on cu.Codigo = tt.IDCurso + `; + } + SQLQuery += `/*where tc.CodigoInstrutor = ${idfuncuionario}*/ + group by mt.IDMatricula, cl.Nome, tu.IdTurma, tt.IDCurso, cu.NomeVersao, HoraInicial, HoraFinal, tu.DataInicio, tu.DataTermino + order by mt.IDMatricula asc;`; + + execSQLQuery2(SQLQuery, res, req.originalUrl); + }); + + router.get('/getProgressoAula/:idusers/:idunits/:idcourses', verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + const idunits = parseInt(req.params.idunits); + const idcourses = parseInt(req.params.idcourses); + execSQLQuery(`select distinct + *, + (Tab1.NM / Tab1.VezesAssistida) as 'NotaMedia', + (Tab1.NMGeral / Tab1.VezesAssistidaGeral) as 'NotaMediaGeral' + from (select + cl.idclasses, + sc.idstepclass, + sc.idusers, + sc.idunits, + cl.name as 'Aula', + case when sc.idstepclass then 'Sim' else 'Não' end as 'Iniciada', + case when sc.completedClass = 1 then 'Sim' else 'Não' end as 'Finalizada', + date_format(sc.insert_date, '%d/%m/%Y %h:%i') as 'DataInicio', + date_format(sc.update_date, '%d/%m/%Y %h:%i') as 'DataFinalizada', + sc.datefinal as 'DataFechamento', + case when sc.liberado = 1 then 'Sim' else 'Não' end as 'liberado', + case + when sc.homework = 1 or ((select count(*) from userstages us where us.idclasses = sc.idclasses and us.idunits = sc.idunits and us.idusers = sc.idusers and us.idstages = 2) > 0) then 'Concluída' + when sc.homework is null and sc.completedClass = 1 then 'Não Realizada' + else null + end as 'TarefaCasa', + (select date_format(us.insert_date, '%d/%m/%Y %h:%i') from userstages us where us.idclasses = sc.idclasses and us.idunits = sc.idunits and us.idusers = sc.idusers and us.idstages = 2 limit 1) as 'DataTarefa', + (select round(us.note, 2) from userstages us where us.idclasses = sc.idclasses and us.idunits = sc.idunits and us.idusers = sc.idusers and us.idstages = 3 limit 1) as 'notaProjeto', + round(sc.note, 2) as 'Nota', + case + when (sc.notegame = 1 and sc.completedClass = 1) then (sum(ea.iscorrect) + 1) + when ((sc.notegame = 0 or sc.notegame is null) and sc.completedClass = 1) then coalesce(sum(ea.iscorrect), 0) + else null + end as 'Acertos', + case + when (sc.notegame = 0 and sc.completedClass = 1) then (sum(case when ea.iscorrect = 1 then 0 else 1 end) + 1) + when ((sc.notegame = 1 or sc.notegame is null) and sc.completedClass = 1) then coalesce(sum(case when ea.iscorrect = 1 then 0 else 1 end), 0) + else null + end as 'Erros', + ExA.Questoes, + (select count(*) from stepclass sc1 where sc1.idclasses = cl.idclasses and sc1.idunits = ${idunits}) as 'VezesAssistida', + (select count(*) from stepclass sc1 where sc1.idclasses = cl.idclasses) as 'VezesAssistidaGeral', + (select count(*) from classes cl1 where cl1.idcourses = cl.idcourses and cl1.disabled = 0) as 'AulasCurso', + (select sum(sc1.note) from stepclass sc1 where sc1.idclasses = cl.idclasses and sc1.idunits = ${idunits}) as 'NM', + (select sum(sc1.note) from stepclass sc1 where sc1.idclasses = cl.idclasses) as 'NMGeral', + cn.note as 'NotaCurso' + from classes cl + left join stepclass sc on cl.idclasses = sc.idclasses and sc.idusers = ${idusers} and sc.idunits = ${idunits} + left join usergivenanswers ug on ug.idclasses = sc.idclasses and ug.idusers = sc.idusers and ug.idunits = sc.idunits + left join exerciseanswers ea on ea.idexerciseanswers = ug.idexerciseanswers + left join coursenotes cn on cn.idcourses = ${idcourses} and cn.idunits = ${idunits} and cn.idusers = ${idusers} + inner join (select distinct + cl.idclasses, + cl.name as 'Aula', + count(cc.idexercises) as 'Questoes' + from classes cl + inner join classescontent cc on cc.idclasses = cl.idclasses + left join exercisequestions eq on eq.idexercises = cc.idexercises + group by cl.idclasses, cc.idclasses + order by cl.idclasses asc) ExA on cl.idclasses = ExA.idclasses + where cl.idcourses = ${idcourses} + group by cl.idclasses, sc.idusers, sc.idunits, cl.name, sc.completedClass, sc.insert_date, sc.update_date, sc. note, sc.notegame, cl.ordem, cn.note + order by cl.ordem asc) Tab1;`, res, req.originalUrl); + }); + + router.post('/getAulasDoDiaSQLServer', verifyJWT, (req, res) => { + const Unidades = req.body.Unidades; + const DataInicial = req.body.DataInicial; + const DataFinal = req.body.DataFinal; + let SQLServerQuery = ``; + for (let i = 0; i < Unidades.length; i++) { + if (i > 0) { + SQLServerQuery += `union all + `; + } + SQLServerQuery += `select + * , + case when R.Ministrado = 'Sim' then (select count(*) from ${Unidades[i]}Chamadas ch where ch.IDCurso = R.IDCurso and ch.IdTurma = R.IdTurma) else (select (count(*) + 1) from ${Unidades[i]}Chamadas ch where ch.IDCurso = R.IDCurso and ch.IdTurma = R.IdTurma) end as 'Chamadas' + from (select + fu.Nome as 'Professor', + tc.IdTurma, + tt.IDMatricula, + cl.Nome as 'Aluno', + tt.IDCurso, + cu.NomeVersao as 'Curso', + CONVERT(varchar(10), tc.Data, 103) as 'Data', + CONVERT(varchar(10), tc.HoraInicial, 108) as 'HoraInicial', + CONVERT(varchar(10), tc.HoraFinal, 108) as 'HoraFinal', + case when tc.MInistrado = 1 then 'Sim' else 'Não' end as 'Ministrado', + '${Unidades[i].replace('.dbo.', '')}' as 'Unidade', + 0 as 'Concluida' + from ${Unidades[i]}TurmasCalendario tc + inner join ${Unidades[i]}TreinandosTurmas tt on tt.CodigoTurma = tc.IdTurma and tt.IDCurso = tc.CodigoCurso + inner join ${Unidades[i]}Clientes cl on cl.IDCliente = tt.IDTreinando + inner join ${Unidades[i]}Cursos cu on cu.Codigo = tt.IDCurso + inner join ${Unidades[i]}Funcionarios fu on fu.IDFuncionario = tc.CodigoInstrutor + where tc.Data >= '${DataInicial}' and tc.Data <= '${DataFinal}' and tt.IDMatricula > 190008) R + `; + } + SQLServerQuery += `order by R.Data asc, R.HoraInicial asc;`; + + sqlServerConnection.request().query(SQLServerQuery, function (error, results, fields) { + if (!error && results && results['recordset']) { + let Calendario = results['recordset']; + mysqlConnection.query(`select * from classes;`, function (error, Aulas, fields) { + for (let i = 0; i < Calendario.length; i++) { + for (let o = 0; o < Aulas.length; o++) { + if (Calendario[i]['IDCurso'] == Aulas[o]['idcourses'] && Calendario[i]['Chamadas'] == (Aulas[o]['ordem'] + 1)) { + Calendario[i]['Aula'] = Calendario[i]['Chamadas'] + " - " + Aulas[o]['description']; + break; + } + } + } + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": Calendario, + })); + console.log(new Date().toUTCString() + " - " + req.originalUrl + " success 200"); + }); + } + else { + res.send(JSON.stringify({ + "status": 500, + "error": error, + "response": [], + })); + console.log(req.originalUrl + " error 500"); + } + }); + }); + + router.post('/getAulasDoDiaMySQL', verifyJWT, (req, res) => { + const Unidades = req.body.Unidades; + const DataInicial = req.body.DataInicial; + const DataFinal = req.body.DataFinal; + let SQLQuery = `select distinct * from (`; + for (let i = 0; i < Unidades.length; i++) { + if (i > 0) { + SQLQuery += `union all + `; + } + SQLQuery += `SELECT distinct + date_format(sc.insert_date, '%d/%m/%Y') as 'Data', + '' as 'Professor', + sc.idusers as 'IDMatricula', + '' as 'Aluno', + cl.idcourses as 'IDCurso', + co.name as 'Curso', + concat(cl.ordem + 1, ' - ', cl.description) as 'Aula', + date_format(sc.insert_date, '%H:%i:%s') as 'HoraInicial', + date_format(sc.update_date, '%H:%i:%s') as 'HoraFinal', + un.reference_db as 'Unidade', + sc.completedClass as 'Concluida', + false as 'Assistida', + 2 as 'Horas' + FROM stepclass sc + inner join classes cl on cl.idclasses = sc.idclasses + inner join units un on un.idunits = sc.idunits and un.reference_db = '${Unidades[i].replace('.dbo.', '')}' + inner join courses co on co.idcourses = cl.idcourses + where date_format(sc.insert_date, '%Y-%m-%d') >= '${DataInicial}' and date_format(sc.insert_date, '%Y-%m-%d') <= '${DataFinal}' + `; + } + SQLQuery += `order by Data asc, HoraInicial asc) R;`; + + mysqlConnection.query(SQLQuery, function (error, Aulas, fields) { + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": Aulas, + })); + console.log(new Date().toUTCString() + " - " + req.originalUrl + " success 200"); + }); + }); + + router.post('/getCursosAluno', verifyJWT, (req, res) => { + const idcourses = req.body.idcourses; + const idusers = parseInt(req.body.idusers); + const idunits = parseInt(req.body.idunits); + const SQLQuery1 = `select distinct + co.idcourses, + co.name as 'Curso', + co.durationtraineeindividual as 'CargaHoraria', + co.aditional as 'Adicional', + co.extracourse as 'CursoExtra', + (select un.unityname from units un where un.idunits = ${idunits}) as 'Unidade', + (select count(*) from classes cl where cl.idcourses = co.idcourses) as 'Aulas', + (select count(*) from classes cl inner join stepclass sc on sc.idclasses = cl.idclasses where cl.idcourses = co.idcourses and sc.idusers = ${idusers} and sc.idunits = ${idunits}) as 'AulasAssistidas' + from courses co + left join classes cl on cl.idcourses = co.idcourses + left join stepclass sc on sc.idclasses = cl.idclasses + where co.idcourses in ${idcourses} + group by co.idcourses, co.name, co.durationtraineeindividual, co.aditional, co.extracourse;`; + mysqlConnection.query(SQLQuery1, function (error, Cursos, fields) { + let ExitCursos = []; + for (let i = 0; i < Cursos.length; i++) { + if (Cursos[i]['Curso'].includes('Módulo')) { + let Incluso = false; + for (let o = 0; o < ExitCursos.length; o++) { + if (Cursos[i]['Curso'].includes(ExitCursos[o]['Curso'])) { + ExitCursos[o]['QtdModulos']++; + Incluso = true; + break; + } + } + if (!Incluso) + ExitCursos.push( { 'Curso': Cursos[i]['Curso'].split(' - Módulo')[0], 'QtdModulos': 1, 'Modulos': [] } ); + ExitCursos[ExitCursos.length - 1]['Modulos'].push( Cursos[i] ); + } + else { + ExitCursos.push( { 'Curso': Cursos[i]['Curso'].split(' - Módulo')[0], 'QtdModulos': 1, 'Modulos': [] } ); + ExitCursos[ExitCursos.length - 1]['Modulos'].push( Cursos[i] ); + } + } + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": ExitCursos + })); + console.log(new Date().toUTCString() + " - " + req.originalUrl + " success 200"); + }); + }); + + return router; +}; + +module.exports = routes; \ No newline at end of file diff --git a/controllers/textController.js b/controllers/textController.js new file mode 100644 index 0000000..a84fadb --- /dev/null +++ b/controllers/textController.js @@ -0,0 +1,169 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); +const formidable = require('formidable'); + +router.use(bodyParser.urlencoded({ + limit: '50mb', + extended: true +})); +router.use(bodyParser.json({ + limit: '50mb', + extended: true +})); + +var routes = function () { + + router.get('/getAll', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM texts;`, res, req.originalUrl); + }); + + router.get('/getText/:idtexts', verifyJWT, (req, res) => { + const idtexts = parseInt(req.params.idtexts); + execSQLQuery(`SELECT DISTINCT + * + FROM texts + WHERE idtexts = ${idtexts};`, res, req.originalUrl); + }); + + router.post('/insert', verifyJWT, (req, res) => { + const text = req.body.text; + const enabled = req.body.enabled ? 1 : 0; + const description = req.body.description; + const game = req.body.game ? 1 : 0; + execSQLQuery(`INSERT INTO texts(text, enabled, description, game) + VALUES (?, ?, ?, ?);`, res, req.originalUrl, [text, enabled, description, game]); + }); + + router.patch('/update', verifyJWT, (req, res) => { + const idtexts = parseInt(req.body.idtexts); + const text = req.body.text; + const enabled = req.body.enabled ? 1 : 0; + const description = req.body.description; + const game = req.body.game ? 1 : 0; + execSQLQuery(`UPDATE texts SET + text = ?, + enabled = ?, + description = ?, + game = ? + WHERE idtexts = ?;`, res, req.originalUrl, [text, enabled, description, game, idtexts]); + }); + + router.post('/copy', verifyJWT, (req, res) => { + let form = new formidable.IncomingForm(); + form.maxFileSize = 600 * 1024 * 1024; + form.parse(req, function(err,fields,files){ + const fs = require('fs'); + var name = fields.name; + var dir = Variables('src_media') + 'games/' + name; + var oldpath = files.file.path; + + if (fs.existsSync(dir)) { + const rimraf = require('rimraf'); + rimraf(dir, function(){ + console.log("Apagado"); + copiaJogo(dir, name, res, fs, oldpath); + }); + } + else { + copiaJogo(dir, name, res, fs, oldpath); + } + + }); + }); + + router.get('/CarregarJogo/:idgames', (req, res) => { + const Protocolo = req.headers.referer.split('/')[0] + "//"; + const fs = require('fs'); + const idgames = parseInt(req.params.idgames); + const DirLocal = `${Variables('src_media')}games/${idgames}/`; + const DirWeb = `${Protocolo}${req.headers.host.split(':')[0]}/games/${idgames}/`; + if (fs.existsSync(DirLocal)) { + res.redirect(DirWeb + 'index.html') + } + else { + const shell = require('shelljs'); + shell.exec('wget -c -P /var/www/html/ -N -m -np -nH -l3 "http://18.228.91.135/games/' + idgames + '/"', function (arquivosbaixados) { + shell.exec('wget -c -P /var/www/html/ -nH -r -k -np "http://18.228.91.135/games/' + idgames + '/Build/" -R index.html?*', function (Sucesso) { + shell.exec('chmod -R 777 /var/www/html/games/' + idgames + '/', function (Sucesso) { + console.log(DirWeb + 'index.html'); + res.redirect(DirWeb + 'index.html'); + }) + }) + }) + } + }) + + router.get('/SolucaoProblemas/:idgames', verifyJWT, (req, res) => { + const idgames = req.params.idgames; + const shell = require('shelljs'); + shell.exec('rm -rf ' + Variables('src_media') + 'games/' + idgames + '/', function(Sucesso) { + console.log("Jogo " + idgames + " excluido com sucesso!"); + res.send(true); + }); + }); + + router.post('/InsertGamesExercise', verifyJWT, (req, res) => { + const idgames = parseInt(req.body.idgames); + const idexercises = req.body.idexercises; + const idzoechattime = req.body.idzoechattime; + execSQLQuery(`INSERT INTO gamesexercises(idgames, idexercises, idzoechattime) VALUES + (?, ?, ?);`, res, req.originalUrl, [idgames, idexercises, idzoechattime]); + }); + + router.get('/getInteracoes/:idgames', verifyJWT, (req, res) => { + const idgames = parseInt(req.params.idgames); + execSQLQuery(`select + ge.*, + CASE + WHEN ge.idexercises IS NOT NULL THEN (SELECT e.description FROM exercises e WHERE e.idexercises = ge.idexercises) + WHEN ge.idzoechattime IS NOT NULL THEN (SELECT z.description FROM zoechattime z WHERE z.idzoechattime = ge.idzoechattime) + END AS 'description', + CASE + WHEN ge.idexercises IS NOT NULL THEN 'Exercício' + WHEN ge.idzoechattime IS NOT NULL THEN 'ChatTime' + END AS 'type' + from gamesexercises ge + where ge.idgames = ${idgames};`, res, req.originalUrl); + }); + + router.delete('/deleteInteracao/:idgamesexercises', verifyJWT, (req, res) => { + const idgamesexercises = parseInt(req.params.idgamesexercises); + execSQLQuery(`delete from gamesexercises + where idgamesexercises = ${idgamesexercises};`, res, req.originalUrl); + }); + + return router; +}; + +function copiaJogo(dir, name, res, fs, oldpath) { + fs.mkdirSync(dir); + fs.rename(oldpath, dir + ".zip", function (err) { + console.log('Copiado com sucesso!'); + require('all-unpacker').unpackZip(dir + ".zip", { + targetDir: dir, + forceDirectory: true + }, function(err, files, text) { + if (err) return console.error(err); + if (files) console.log('files', files); + if (text) { + console.log('text', text) + fs.readFile(dir, (err, data) => { + //if (err) throw err; + console.log("Extraído com sucesso!"); + fs.unlink(dir + '.zip', function() { + console.log("Apagado com sucesso!"); + res.send(true); + }) + }); + }; + }) + }) +} + +module.exports = routes; diff --git a/controllers/traineeprogramController.js b/controllers/traineeprogramController.js new file mode 100644 index 0000000..fdb0a2d --- /dev/null +++ b/controllers/traineeprogramController.js @@ -0,0 +1,196 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/', verifyJWT, (req, res) => { + execSQLQuery(` + SELECT + * + FROM traineeprogram`, + res, + req.originalUrl + ); + }) + + router.get('/getTraineeprogram/:id', verifyJWT, (req, res) => { + id = parseInt(req.params.id); + execSQLQuery(` + SELECT + * + FROM traineeprogram + WHERE idtraineeprogram = ${id}`, + res, + req.originalUrl + ); + }) + + router.get('/getTraineeprogramCourses/:id', verifyJWT, (req, res) => { + id = parseInt(req.params.id); + execSQLQuery(` + select + c.name, + tc.ordem, + tc.idtraineeprogramcourses + from + traineeprogramcourses tc + inner join + courses c + on + tc.idcourses = c.idcourses + where + tc.idtraineeprogram = ${id} + order by ordem;`, + res, + req.originalUrl + ); + }) + + router.get('/list', verifyJWT, (req, res) => { + execSQLQuery(` + SELECT + idtraineeprogram, + name, + description, + concat('R$ ',format(totalvalue,2,'de_DE')) as totalvalue, + disabled + FROM traineeprogram`, + res, + req.originalUrl + ); + }) + + router.patch('/disable', verifyJWT, (req, res) => { + const idtraineeprogram = parseInt(req.body.idtraineeprogram); + execSQLQuery(` + UPDATE traineeprogram + SET disabled = not disabled + WHERE idtraineeprogram = ${idtraineeprogram}`, + res, + req.originalUrl + ); + }) + + router.post('/insert', verifyJWT, (req, res) => { + const idaccountplan = req.body.idaccountplan ? 1 : 0; + const name = req.body.name; + const description = req.body.description; + const totalvalue = parseFloat(req.body.totalvalue); + const totalmaterialvalue = parseFloat(req.body.totalmaterialvalue); + const durationtotal = parseFloat(req.body.durationtotal); + const disabled = req.body.disabled ? 1 : 0; + const codetraineeprog = req.body.codetraineeprog ? 1 : 0; + const peopletec = req.body.peopletec ? 1 : 0; + const matvaluefix = req.body.matvaluefix ? 1 : 0; + execSQLQuery(`INSERT INTO + traineeprogram( + idaccountplan, name, description, + totalvalue, totalmaterialvalue, durationtotal, + disabled, codetraineeprog, peopletec, matvaluefix + ) VALUES ( + '${idaccountplan}',"${name}","${description}", + '${totalvalue}',${totalmaterialvalue},${durationtotal}, + '${disabled}','${codetraineeprog}','${peopletec}','${matvaluefix}' + )`, + res, + req.originalUrl + ); + }) + + router.patch('/update', verifyJWT, (req, res) => { + const idtraineeprogram = req.body.idtraineeprogram; + const idaccountplan = req.body.idaccountplan ? 1 : 0; + const name = req.body.name; + const description = req.body.description; + const totalvalue = parseFloat(req.body.totalvalue); + const totalmaterialvalue = parseFloat(req.body.totalmaterialvalue); + const durationtotal = parseFloat(req.body.durationtotal); + const disabled = req.body.disabled ? 1 : 0; + const codetraineeprog = req.body.codetraineeprog ? 1 : 0; + const peopletec = req.body.peopletec ? 1 : 0; + const matvaluefix = req.body.matvaluefix ? 1 : 0; + execSQLQuery(` + UPDATE traineeprogram SET + idaccountplan = '${idaccountplan}', + name = "${name}", + description = "${description}", + totalvalue = ${totalvalue}, + totalmaterialvalue = ${totalmaterialvalue}, + durationtotal = '${durationtotal}', + disabled = '${disabled}', + codetraineeprog = '${codetraineeprog}', + peopletec = '${peopletec}', + matvaluefix = '${matvaluefix}' + WHERE idtraineeprogram = ${idtraineeprogram}`, + res, + req.originalUrl + ); + }) + + router.post('/addTraineeNote', verifyJWT, (req, res) => { + const idtraineeprogram = req.body.idtraineeprogram; + const idusers = req.body.idusers; + const idunits = req.body.idunits; + const note = parseFloat(req.body.note); + execSQLQuery(` + INSERT INTO + traineeprogramnotes(idtraineeprogram, idusers, note, idunits) + VALUES + (${idtraineeprogram}, ${idusers}, ${idunits}, ${note});`, + res, + req.originalUrl + ); + }) + + router.get('/getMySQLinSQLServerTraineeprogram', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + idtraineeprogram AS 'Codigo', + idaccountplan AS 'IDPlanoConta', + name AS 'Nome', + description AS 'DescricaoContrato', + totalvalue AS 'ValorTotal', + totalmaterialvalue AS 'ValorMaterialTotal', + durationtotal AS 'CargaHorariaTotal', + disabled AS 'Desativado', + codetraineeprog AS 'CodigoProgTreinamento', + peopletec AS 'PeopleTec' + FROM traineeprogram;`, res, req.originalUrl); + }); + + router.get('/getSQLServerTraineeprogram/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT + * + FROM ${db}ProgramaTreinamento;`, res, req.originalUrl); + }); + + router.get('/getMySQLinSQLServerTraineeprogramcourses', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + idtraineeprogram AS 'Codigo', + idcourses AS 'CodigoCurso', + value AS 'Valor', + materialvalue AS 'ValorMaterial', + duration AS 'CargaHoraria', + ordem AS 'Ordem', + opinionsearch AS 'PesquisaOpiniao', + materialpercentual AS 'PercentualMaterial' + FROM traineeprogramcourses;`, res, req.originalUrl); + }); + + router.get('/getSQLServerTraineeprogramcourses/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT + * + FROM ${db}ProgramaTreinamentoCursos;`, res, req.originalUrl); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/traineeprogramcoursesController.js b/controllers/traineeprogramcoursesController.js new file mode 100644 index 0000000..2ea287e --- /dev/null +++ b/controllers/traineeprogramcoursesController.js @@ -0,0 +1,151 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/', verifyJWT, (req, res) => { + execSQLQuery(` + SELECT + * + FROM traineeprogramcourses`, + res, + req.originalUrl + ); + }) + + router.get('/getTraineeprogramcourses/:id', verifyJWT, (req, res) => { + id = parseInt(req.params.id); + execSQLQuery(` + SELECT + * + FROM traineeprogramcourses + WHERE idtraineeprogramcourses = ${id}`, + res, + req.originalUrl + ); + }) + + router.get('/getTraineeprogramByCourse/:idcourses', verifyJWT, (req, res) => { + var idcourses = parseInt(req.params.idcourses); + execSQLQuery(` + SELECT + * + FROM + traineeprogramcourses + WHERE + idcourses = ${idcourses}`, + res, + req.originalUrl + ); + }) + + router.delete('/deleteTraineeprogramcourses/:id', verifyJWT, (req, res) => { + id = parseInt(req.params.id); + execSQLQuery(` + DELETE FROM traineeprogramcourses + WHERE idtraineeprogramcourses = ${id}`, + res, + req.originalUrl + ); + }) + + router.get('/list/:id', verifyJWT, (req, res) => { + id = parseInt(req.params.id); + execSQLQuery(`SELECT + c.idcourses, + c.name, + tpc.idtraineeprogramcourses, + concat('R$ ',format(tpc.value,2,'de_DE')) as value, + concat('R$ ',format(tpc.materialvalue,2,'de_DE')) as materialvalue, + tpc.duration, + tpc.ordem, + tpc.opinionsearch, + concat(tpc.materialpercentual,'%') as materialpercentual, + case when tpc.opinionsearch = 0 then 'Não' else 'Sim' end as pesquisa + FROM + courses c + inner join traineeprogramcourses tpc + on tpc.idcourses = c.idcourses + WHERE + tpc.idtraineeprogram = ${id} order by ordem`, + res, + req.originalUrl + ); + }) + + router.post('/insert', verifyJWT, (req, res) => { + const idcourse = req.body.idcourses; + const value = parseFloat(req.body.value); + const materialvalue = parseFloat(req.body.materialvalue); + const duration = parseFloat(req.body.duration); + const order = req.body.ordem; + const opinionsearch = req.body.opinionsearch; + const materialpercentual = parseFloat(req.body.materialpercentual); + const idtraineeprogram = req.body.idtraineeprogram; + execSQLQuery(`INSERT INTO + traineeprogramcourses( + idcourses, value, materialvalue, + duration, ordem, opinionsearch, + materialpercentual, idtraineeprogram + ) VALUES ( + '${idcourse}','${value}','${materialvalue}', + '${duration}','${order}','${opinionsearch}', + '${materialpercentual}','${idtraineeprogram}' + )`, + res, + req.originalUrl + ); + }) + + router.patch('/update/:id', verifyJWT, (req, res) => { + id = parseInt(req.params.id); + const idtraineeprogramcourses = req.body.idtraineeprogramcourses; + const idcourse = req.body.idcourses; + const value = parseFloat(req.body.value); + const materialvalue = parseFloat(req.body.materialvalue); + const duration = parseFloat(req.body.duration); + const order = req.body.ordem; + const opinionsearch = req.body.opinionsearch; + const materialpercentual = parseFloat(req.body.materialpercentual); + const idtraineeprogram = req.body.idtraineeprogram; + execSQLQuery(` + UPDATE traineeprogramcourses SET + idcourses = '${idcourse}', + value = '${value}', + materialvalue = '${materialvalue}', + duration = '${duration}', + ordem = ${order}, + opinionsearch = ${opinionsearch}, + materialpercentual = '${materialpercentual}', + idtraineeprogram = '${idtraineeprogram}' + WHERE idtraineeprogramcourses = ${id}`, + res, + req.originalUrl + ); + }) + + router.patch('/attOrdem0', verifyJWT, (req, res) => { + const idtraineeprogramcourses = req.body.idtraineeprogramcourses; + const ordemagora = req.body.ordemagora; + execSQLQuery(` + UPDATE + traineeprogramcourses + SET + ordem = ${ordemagora} + WHERE + idtraineeprogramcourses = ${idtraineeprogramcourses}`, + res, + req.originalUrl + ); + }) + + return router; +}; + +module.exports = routes; diff --git a/controllers/typescourseController.js b/controllers/typescourseController.js new file mode 100644 index 0000000..b334b5a --- /dev/null +++ b/controllers/typescourseController.js @@ -0,0 +1,57 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/gettypecourse/:idtypescourse', verifyJWT, (req, res) => { + const idtypescourse = parseInt(req.params.idtypescourse); + execSQLQuery(`SELECT + * + FROM typescourse + WHERE idtypescourse = ${idtypescourse};`, res, req.originalUrl); + }); + + router.get('/getList', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM typescourse;`, res, req.originalUrl); + }); + + router.post('/insert', verifyJWT, (req, res) => { + const idtypescourse = parseInt(req.body.idtypescourse); + const description = req.body.description; + const gradecalc = req.body.gradecalc; + const disabled = req.body.disabled ? 1 : 0; + execSQLQuery(`INSERT INTO typescourse(description, gradecalc, disabled) VALUES + (?, ?, ?);`, res, req.originalUrl, [description, gradecalc, disabled]); + }); + + router.patch('/update', verifyJWT, (req, res) => { + const idtypescourse = parseInt(req.body.idtypescourse); + const description = req.body.description; + const gradecalc = req.body.gradecalc; + const disabled = req.body.disabled ? 1 : 0; + execSQLQuery(`UPDATE typescourse SET + description = ?, + gradecalc = ?, + disabled = ? + WHERE idtypescourse = ?;`, res, req.originalUrl, [description, gradecalc, disabled, idtypescourse]); + }); + + router.get('/disable/:idtypescourse', verifyJWT, (req, res) => { + const idtypescourse = parseInt(req.params.idtypescourse); + execSQLQuery(`UPDATE typescourse SET + disabled = not disabled + WHERE idtypescourse = ${idtypescourse};`, res, req.originalUrl); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/unileverController.js b/controllers/unileverController.js new file mode 100644 index 0000000..aea9f39 --- /dev/null +++ b/controllers/unileverController.js @@ -0,0 +1,176 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get("/listLogin", (req, res) => { + execSQLQuery( + `SELECT + un.idunits, + un.description, + un.reference_db, + un.unityname, + un.ip_externo, + un.ip_local, + un.porta_mysql + FROM units un + WHERE un.idunits in (60);`, + res, + req.originalUrl + ); + }); + + router.post('/authUser', (req, res) => { + const type = parseInt(req.body.type); + const password = encriptPassword(req.body.password); + const user = req.body.login; + this.id = type + user + password; + const db = req.body.db; + + if (user == "190000" && password == encriptPassword("zoeteacher")) + { + execMySQLQueryLogin(`SELECT + '190000' as 'IDMatricula', + 'maker2019' as 'SenhaIntranet', + 'Sistema' as 'Nome', + 4 as 'idusertype';`, res, req.originalUrl); + } + else { + const query = `SELECT + CAST(us.user AS UNSIGNED) AS IDMatricula, + 'maker2019' AS SenhaIntranet, + us.Name AS Nome, + 4 AS idusertype + FROM users us + WHERE us.user = '${user}' AND us.password = '${password}' AND us.idusertype = 18;`; + execMySQLQueryLogin(query, res, req.originalUrl); + } + }); + + router.get("/getRobotCourses", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + 0 as 'IDMatricula', + idcourses as 'IDCurso', + name as 'NomeVersao', + aditional as 'Adicional', + extracourse as 'CursoExtra' + FROM courses + WHERE idtypescourse in (5, 8) and disabled = 0;`, + res, + req.originalUrl + ); + }); + + router.get("/getRobotCourseByStudent/:idusers/:banco", verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + const db = req.params.banco; + execSQLQuery( + `SELECT distinct + sc.idusers as IDMatricula, + co.idcourses as IDCurso, + co.name as NomeVersao + FROM studentCourses sc + INNER JOIN courses co on co.idcourses = sc.idcourses + WHERE sc.idusers = ${idusers} and co.disabled = 0;`, + res, + req.originalUrl + ); + } + ); + + router.get("/getQtdeChamadas/:idusers/:idcourses/:db", verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + const idcourses = req.params.idcourses; + const db = req.params.db; + let sqlQuery = `select + co.idcourses, + coalesce((select + sc.callCounter + from studentCall sc + inner join units un on un.idunits = sc.idunit + where sc.idusers = ${idusers} and sc.idcourses = co.idcourses and un.reference_db = '${db}' + ), 0) as qtde_presencas + from courses co + where co.idcourses = ${idcourses};`; + execSQLQuery(sqlQuery, res, req.originalUrl); + } + ); + + router.get("/getClassEnByCourse/:idcourses/:qtd/:homework", verifyJWT, (req, res) => { + const idcourses = parseInt(req.params.idcourses); + const qtd = parseInt(req.params.qtd); + const homework = parseInt(req.params.homework); + execSQLQuery( + `SELECT + idclasses, + idcourses, + name, + case when disabled = 0 and ordem < ${qtd} and (viewed < 2 or ${qtd} != 100) then 0 else 1 end as disabled, + ordem, + description, + viewed, + aval, + download, + demo, + homework, + sprites + FROM classes + WHERE idcourses = ${idcourses} AND disabled = 0 and homework = ${homework} + ORDER BY ordem asc;`, + res, + req.originalUrl + ); + } + ); + + router.get("/getClassEnByCourseAll/:idcourses/:qtd/:homework", verifyJWT, (req, res) => { + const idcourses = parseInt(req.params.idcourses); + const qtd = parseInt(req.params.qtd); + const homework = parseInt(req.params.homework); + execSQLQuery( + `SELECT + idclasses, + idcourses, + name, + case when (disabled = 0 or disabled = 1) and (viewed < 2 or ${qtd} != 100) then 0 else 1 end as disabled, + ordem, + description, + viewed, + aval, + download, + demo, + homework, + sprites + FROM classes + WHERE idcourses = ${idcourses} AND homework = ${homework} + ORDER BY ordem asc;`, + res, + req.originalUrl + ); + } + ); + + router.get('/getZoeRobotsApks/:idzoerobots', (req, res) => { + const idzoerobots = req.params.idzoerobots; + mysqlConnection.query( + `SELECT * FROM zoerobotsapks where idzoerobots = ${idzoerobots};`, + function (error, results, fields) { + console.log( + new Date().toUTCString() + ' - ' + req.originalUrl + ' success 200' + ); + res.send(`{"Aplicativos": ` + JSON.stringify(results) + `}`); + } + ); + }); + + return router; +}; + +module.exports = routes; diff --git a/controllers/unityController.js b/controllers/unityController.js new file mode 100644 index 0000000..9b8bb46 --- /dev/null +++ b/controllers/unityController.js @@ -0,0 +1,1262 @@ +require("../connections/mysql-server"); +require("../helpers/CheckToken"); +const express = require("express"); +const router = express.Router(); +const bodyParser = require("body-parser"); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get("/listLogin", (req, res) => { + execSQLQuery(` + SELECT + CAST(zu.id AS CHAR) AS reference_db, + zu.description AS unityname, + COALESCE(zu.idunits, zu.id + 200) AS idunits, + '' AS ip_externo, + '' AS ip_local, + 0 AS porta_mysql + FROM zoeunits zu + WHERE zu.enabled = 1 + ORDER BY description ASC;`, + res, + req.originalUrl + ); + }); + + router.get("/listLoginOld", (req, res) => { + execSQLQuery(` + SELECT + * + FROM units + WHERE enabled = 1 + ORDER BY description ASC;`, + res, + req.originalUrl + ); + }); + + + router.get("/getEnabledUnits", (req, res) => { + let sqlQry = `select + un.idunits as 'ID', + un.unityname as 'Unidade', + un.address as 'Endereco', + un.neighborhood as 'Bairro', + un.cep as 'CEP', + st.description as 'Estado', + ct.description as 'Cidade' + from units un + inner join cities ct on ct.idcities = un.idcities + inner join states st on st.idstates = un.idstates + where un.enabled = 1 + order by un.unityname asc;`; + execSQLQuery(sqlQry, res, req.originalUrl); + }); + + router.get("/listUnits", (req, res) => { + execSQLQuery( + `SELECT * FROM units WHERE enabled = 1;`, + res, + req.originalUrl + ); + }); + + router.get("/getConfig/:Campo", (req, res) => { + let Campo = req.params.Campo; + execSQLQuery(`SELECT ${Campo} FROM config;`, res, req.originalUrl); + }); + + router.get("/getAll", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + * + FROM units + ORDER BY unityname ASC;`, + res, + req.originalUrl + ); + }); + + router.get("/list", verifyJWT, (req, res) => { + execSQLQuery( + `SELECT + idunits, + unityname, + phone, + manager, + email, + enabled, + reference_db + FROM units + ORDER BY unityname ASC;`, + res, + req.originalUrl + ); + }); + + router.get("/listDis", (req, res) => { + execSQLQuery( + `SELECT distinct + idunits, + unityname, + reference_db, + celphone + FROM units + WHERE enabled = 1 and reference_db not like '%Learning%';`, + res, + req.originalUrl + ); + }); + + router.get("/listLoginFilter", (req, res) => { + const domain = req.hostname.split(".").pop(); + + let language; + + switch (domain) { + case "br": + language = 0; + break; + case "py": + language = 1; + break; + default: + language = 0; + break; + } + + execSQLQuery( + `SELECT + * + FROM units + WHERE enabled = 1 and idcountry = ${language} + ORDER BY description ASC;`, + res, + req.originalUrl + ); + }); + + router.get("/getUnit/:idunits", verifyJWT, (req, res) => { + const idunits = parseInt(req.params.idunits); + execSQLQuery( + `SELECT + * + FROM units + WHERE idunits = ${idunits};`, + res, + req.originalUrl + ); + }); + + router.get("/getUnitByAny/:field/:value", verifyJWT, (req, res) => { + const field = req.params.field; + const value = req.params.value; + execSQLQuery( + `SELECT + * + FROM units + WHERE ? = ? AND enabled = 1;`, + res, + req.originalUrl, + [field, value] + ); + }); + + router.get("/disable/:idunits", verifyJWT, (req, res) => { + const idunits = parseInt(req.params.idunits); + execSQLQuery( + `UPDATE units SET + enabled = not enabled + WHERE idunits = ${idunits};`, + res, + req.originalUrl + ); + }); + + router.post("/insert", verifyJWT, (req, res) => { + const description = req.body.description; + const unityname = req.body.unityname; + const address = req.body.address; + const neighborhood = req.body.neighborhood; + const idcities = parseInt(req.body.idcities); + const idstates = parseInt(req.body.idstates); + const cep = req.body.cep; + const phone = req.body.phone; + const celphone = req.body.celphone; + const cnpj = req.body.cnpj; + const stateregistration = req.body.stateregistration; + const municipalregistration = req.body.municipalregistration; + const manager = req.body.manager; + const email = req.body.email; + const enabled = req.body.enabled ? 1 : 0; + const reference_db = req.body.reference_db; + const ip_local = req.body.ip_local; + const ip_externo = req.body.ip_externo; + const porta_mysql = req.body.porta_mysql; + const codello = req.body.codello; + const idcountry = req.body.idcountry; + execSQLQuery( + `INSERT INTO units (description, unityname, address, neighborhood, idcities, idstates, cep, phone, celphone, cnpj, stateregistration, municipalregistration, manager, email, enabled, reference_db, ip_local, ip_externo, porta_mysql, codello, idcountry) + VALUES (?, ?, ?, ?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`, + res, + req.originalUrl, + [ + description, + unityname, + address, + neighborhood, + idcities, + idstates, + cep, + phone, + celphone, + cnpj, + stateregistration, + municipalregistration, + manager, + email, + enabled, + reference_db, + ip_local, + ip_externo, + porta_mysql, + codello, + idcountry, + ] + ); + }); + + router.patch("/update", verifyJWT, (req, res) => { + const idunits = parseInt(req.body.idunits); + const description = req.body.description; + const unityname = req.body.unityname; + const address = req.body.address; + const neighborhood = req.body.neighborhood; + const idcities = parseInt(req.body.idcities); + const idstates = parseInt(req.body.idstates); + const cep = req.body.cep; + const phone = req.body.phone; + const celphone = req.body.celphone; + const cnpj = req.body.cnpj; + const stateregistration = req.body.stateregistration; + const municipalregistration = req.body.municipalregistration; + const manager = req.body.manager; + const email = req.body.email; + const enabled = req.body.enabled ? 1 : 0; + const reference_db = req.body.reference_db; + const ip_local = req.body.ip_local; + const ip_externo = req.body.ip_externo; + const porta_mysql = req.body.porta_mysql; + const codello = req.body.codello; + execSQLQuery( + `UPDATE units SET + description = ?, + unityname = ?, + address = ?, + neighborhood = ?, + idcities = ?, + idstates = ?, + cep = ?, + phone = ?, + celphone = ?, + cnpj = ?, + stateregistration = ?, + municipalregistration = ?, + manager = ?, + email = ?, + enabled = ?, + reference_db = ?, + ip_local = ?, + ip_externo = ?, + porta_mysql = ?, + codello = ? + WHERE idunits = ?;`, + res, + req.originalUrl, + [ + description, + unityname, + address, + neighborhood, + idcities, + idstates, + cep, + phone, + celphone, + cnpj, + stateregistration, + municipalregistration, + manager, + email, + enabled, + reference_db, + ip_local, + ip_externo, + porta_mysql, + codello, + idunits, + ] + ); + }); + + router.get("/alarmUnits/:tk", (req, res) => { + alarmGetUnits(req, res, 1); + }); + + router.get("/alarmUnitsClassToday/:tk", (req, res) => { + alarmGetUnits(req, res, 2); + }); + + router.get("/getOnlineUsers/:tempo", verifyJWT, (req, res) => { + const Tempo = parseInt(req.params.tempo); + execSQLQuery( + `select + un.unityname as 'Unidade', + co.name as 'Curso', + cl.name as 'Aula', + cl.description as 'Pauta', + sc.idusers as 'Matricula', + sc.actualExercise, + sc.actualItem, + sc.actualAnswer, + case when sc.completedClass = 1 then 'Sim' else 'Não' end as 'Concluida', + date_format(sc.insert_date, '%d/%m/%Y %h:%i') as 'IniciadoEm', + date_format(sc.update_date, '%d/%m/%Y %h:%i') as 'VistoUltimo', + (select count(*) from stepclass sc1 where sc1.idunits = sc.idunits and sc1.insert_date > date_format(now(), '%y-%m-%d')) as 'AulasHoje', + (select count(*) from stepclass sc1 where sc1.insert_date > date_format(now(), '%y-%m-%d')) as 'TotalAulas' + from stepclass sc + inner join units un on un.idunits = sc.idunits + inner join classes cl on cl.idclasses = sc.idclasses + inner join courses co on co.idcourses = cl.idcourses + where sc.update_date > date_sub(now(), interval ${Tempo} minute) + order by sc.update_date desc;`, + res, + req.originalUrl + ); + }); + + router.get("/getAlunosPorUnidade", verifyJWT, (req, res) => { + mysqlConnection.query( + `select * from units where enabled = 1 order by unityname asc;`, + function (error, Unidades, fields) { + if (!Unidades) Unidades = []; + let sqlQry = ``; + for (let i = 0; i < Unidades.length; i++) { + /*sqlQry += `select + ${Unidades[i]['idunits']} as 'idunits', + '${Unidades[i]['unityname']}' as 'Unidade', + count(*) as 'TotalAlunos', + 0 as 'AlunosOnline', + 0 as 'AulasHoje' + from (select distinct + ma.IDMatricula, + cl.Nome, + tu.Nome as 'Turma', + case when pr.TipoRequerimento = 'C' then 'Sim' else 'Não' end as 'Cancelada' + from ${Unidades[i]['reference_db']}.dbo.Matriculas ma + inner join ${Unidades[i]['reference_db']}.dbo.MatriculasTreinandos mt on mt.IDMatricula = ma.IDMatricula + inner join ${Unidades[i]['reference_db']}.dbo.Turmas tu on tu.IdTurma = mt.CodigoTurma + inner join ${Unidades[i]['reference_db']}.dbo.Clientes cl on cl.IDCliente = mt.IDTreinando + inner join ${Unidades[i]['reference_db']}.dbo.TreinandosTurmas tt on tt.IDMatricula = mt.IDMatricula + inner join ${Unidades[i]['reference_db']}.dbo.Cursos cu on cu.Codigo = tt.IDCurso + inner join ${Unidades[i]['reference_db']}.dbo.Chamadas ch on ch.IDTurma = tu.IdTurma + left join ${Unidades[i]['reference_db']}.dbo.PreRequerimento pr on pr.IDTreinando = tt.IDTreinando + where tt.Faltoso = 0 and tt.Concluiu = 0 and tt.Desistente = 0 and tt.IDMatricula > 190008 and ma.QRCode != '' and tu.Cancelada = 0 and tu.Suspensa = 0) T_${i} + where T_${i}.Cancelada = 'Não' + UNION ALL `;*/ + sqlQry += `select + ${Unidades[i]["idunits"]} as 'idunits', + '${Unidades[i]["unityname"]}' as 'Unidade', + count(*) as 'TotalAlunos', + (select COUNT(*) as 'CalendarioEmDia' + from ${Unidades[i]["reference_db"]}.dbo.TreinandosTurmas TT + where TT.Desistente = 0 and TT.Faltoso = 0 and TT.CodigoTurma in ( + select TC.IdTurma + from ${Unidades[i]["reference_db"]}.dbo.TurmasCalendario TC + where GETDATE() between ( + select MIN(TC2.Data) + from ${Unidades[i]["reference_db"]}.dbo.TurmasCalendario TC2 + where TC2.IdTurma = TC.IdTurma and TC2.CodigoCurso = TT.IDCurso) + and + (select MAX(TC3.Data) + from ${Unidades[i]["reference_db"]}.dbo.TurmasCalendario TC3 + where TC3.IdTurma = TC.IdTurma and TC3.CodigoCurso = TT.IDCurso))) as 'CalendarioEmDia', + 0 as 'AlunosOnline', + 0 as 'AulasHoje' + from ( + select + C.Nome + from ${Unidades[i]["reference_db"]}.dbo.Clientes C + inner join ${Unidades[i]["reference_db"]}.dbo.Unidades U on U.IDUnidade = C.IDUnidade + left join ${Unidades[i]["reference_db"]}.dbo.Profissoes P on P.IDProfissao = C.IDProfissao + left join ${Unidades[i]["reference_db"]}.dbo.Funcionarios F on F.IDFuncionario = C.FuncionarioCadastro + where ( + (( + --Cursos Trancados e Cancelados + select COUNT(*) + from ${Unidades[i]["reference_db"]}.dbo.TreinandosTurmas TT + where TT.IDTreinando = C.IDCliente and + (TT.CodigoTurma = 0 or TT.Desistente = 1)) < + (select COUNT(*) + from ${Unidades[i]["reference_db"]}.dbo.TreinandosTurmas TT2 + where TT2.IDTreinando = C.IDCliente))) or + ((select COUNT(*) + from ${Unidades[i]["reference_db"]}.dbo.TreinandosTurmas TT + where TT.IDTreinando = C.IDCliente and TT.Desistente = 0 and TT.Faltoso = 0 and + TT.CodigoTurma in ( + select TC.IdTurma + from ${Unidades[i]["reference_db"]}.dbo.TurmasCalendario TC + where ( + select MIN(TC2.Data) + from ${Unidades[i]["reference_db"]}.dbo.TurmasCalendario TC2 + where TC2.IdTurma = TC.IdTurma and TC2.CodigoCurso = TT.IDCurso) > GETDATE())) > 0) + ) resultado + union all + `; + } + sqlQry = sqlQry.substring(0, sqlQry.length - 30) + ";"; + //console.log(sqlQry); + sqlServerConnection + .request() + .query(sqlQry, function (error1, results1, fileds1) { + res.send( + JSON.stringify({ + status: 200, + error: error1, + response: results1.recordset, + }) + ); + console.log( + new Date().toUTCString() + " - " + req.originalUrl + "/ error 500" + ); + }); + } + ); + }); + + router.get("/getAcompanhamentoAulas", verifyJWT, (req, res) => { + execSQLQuery( + `select distinct + co.name as 'Curso', + (select count(*) from classes cl where cl.idcourses = co.idcourses) as 'AulasCadastradas', + (select count(*) from classes cl inner join stepclass sc on sc.idclasses = cl.idclasses where cl.idcourses = co.idcourses) as 'VezesAssistida', + (select cl.name from classes cl inner join stepclass sc on sc.idclasses = cl.idclasses where cl.idcourses = co.idcourses and cl.download = 0 order by cl.ordem desc limit 1) as 'UltimaAssistida', + (select cl.description from classes cl inner join stepclass sc on sc.idclasses = cl.idclasses where cl.idcourses = co.idcourses and cl.download = 0 order by cl.ordem desc limit 1) as 'Tema', + (select un.unityname from classes cl inner join stepclass sc on sc.idclasses = cl.idclasses inner join units un on un.idunits = sc.idunits where cl.idcourses = co.idcourses and cl.download = 0 order by cl.ordem desc limit 1) as 'Unidade', + (select date_format(sc.insert_date, '%d/%m/%Y %H:%i') from classes cl inner join stepclass sc on sc.idclasses = cl.idclasses where cl.idcourses = co.idcourses and cl.download = 0 order by cl.ordem desc limit 1) as 'Data' + from courses co + inner join classes cl on cl.idcourses = co.idcourses + order by co.name asc;`, + res, + req.originalUrl + ); + }); + + router.get("/unitscursoferias", (req, res) => { + mysqlConnection.query( + `select idunits, unityname from units where idunits in (21, 22, 23, 24, 31, 32, 35, 36, 38);`, + function (error, results, fields) { + res.send( + JSON.stringify({ + status: 200, + error: error, + results: results, + }) + ); + console.log(req.originalUrl); + } + ); + }); + + router.post("/captacaoferias", (req, res) => { + //console.log(req.body); + let idunits = req.body.unidade; + const nome = req.body.nome; + const telefone = req.body.telefone; + let minecraft = req.body.minecraft || "off"; + let caneta3d = req.body.caneta3d || "off"; + let cursos = ""; + if (minecraft == "on" && caneta3d == "off") cursos = "16"; + if (minecraft == "off" && caneta3d == "on") cursos = "17"; + if (minecraft == "on" && caneta3d == "on") cursos = "16,17"; + try { + idunits = idunits[0]; + } catch (e) { + idunits = 14; + } + mysqlConnection.query( + `select * from units where idunits = ${idunits};`, + function (error, Unidade, fields) { + //console.log(Unidade); + Unidade = Unidade[0]; + // Unidade['email'], + + //#region EMAIL CAPTACAO + let TextoEmail = ` +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
Olá ${ + Unidade.manager + }! +
+
+
+ Sua unidade recebeu uma inscrição para o curso de férias. +
+
+ Os seguintes cursos foram escolhidos: +
+
${ + minecraft == "on" + ? '
Minecraft
' + : "" + } ${ + caneta3d == "on" + ? '
Caneta 3D
' + : "" + } +
+
+
+ Aqui está os dados para contato com o aluno: +
+
+
Nome: ${nome}
+
Telefone: ${telefone}
+
+
+
+ +
+
+
+
+
+
+
+ + + + + + +
+
+
+ `; + //#endregion + + EnviarEmail( + Unidade["email"], + "Inscrição para curso de férias", + TextoEmail, + function (Sucesso) { + let Rota = "http://myrobot.com.br/cursodeferias?"; + console.log(req.originalUrl); + if (Sucesso) { + Rota += "1"; + mysqlConnection.query( + `insert into leadscursosferias (idunits, nome, telefone, cursos) values (?, ?, ?, ?);`, + [idunits, nome, telefone, cursos], + function (error, Unidade, fields) { + res.redirect(Rota); + } + ); + } else { + Rota += "0"; + res.redirect(Rota); + } + } + ); + } + ); + }); + + router.post("/captacaosite", (req, res) => { + const idunits = req.body.idunits; + const nome = req.body.nome; + const telefone = req.body.telefone; + const email = req.body.email; + mysqlConnection.query( + `select * from units where idunits = ${idunits};`, + function (error, Unidade, fields) { + Unidade = Unidade[0]; + EnviarEmail( + Unidade["email"], + "Inscrição de interesse através do site", + "AQUI VAI IR O EMAIL PARA O FRANQUEADO COM AS INFORMAÇÕES DO LEAD CAPTURADO", + function (Sucesso) { + let Rota = "https://myrobot.com.br?"; + console.log(req.originalUrl); + if (Sucesso) { + Rota += "1"; + mysqlConnection.query( + `insert into leadssite (nome, telefone, email, idunits) values (?, ?, ?, ?);`, + [nome, telefone, email, idunits], + function (error, Lead, fields) { + res.redirect(Rota); + } + ); + } else { + Rota += "0"; + res.redirect(Rota); + } + } + ); + } + ); + }); + + function EnviarEmail(email, Assunto, Texto, callback) { + const request = require("request"); + request.post( + "http://18.228.91.135:3337/api/email/send", + { + json: { + from: "MyRobot School ", + to: email, + subject: Assunto, + text: Texto, + }, + }, + function (error, response, body) { + if (!error && response.statusCode == 200) { + console.log("Sucesso ao enviar e-mail!"); + callback(true); + } else { + console.log("Falha ao enviar e-mail!"); + callback(false); + } + } + ); + } + + return router; +}; + +module.exports = routes; + +function alarmGetUnits(req, res, type) { + var sqlQry = `select idunits, unityname, + reference_db, ip_externo, porta_mysql + from units + cross join config + where enabled = 1 + and units.idunits > 14 + and tk_api = '${req.params.tk}'`; + + mysqlConnection.query(sqlQry, function (error, results, fields) { + if (!error && results.length != 0) { + if (type == 1) { + generateUnitsAlarmDate(results, res); + } else if (type == 2) { + alarmClassesToday(results, res); + } + } else { + console.log("Erro:"); + console.log("Token Inválido"); + res.status(500).send({ error: "Token Inválido" }); + } + }); +} + +function alarmClassesToday(resultsUnits, res) { + var d = new Date(), + month = "" + (d.getMonth() + 1), + day = "" + d.getDate(), + year = d.getFullYear(); + + if (month.length < 2) month = "0" + month; + if (day.length < 2) day = "0" + day; + + var dateSQL = [year, month, day].join("-"); + + var sqlQry = ""; + + for (var i = 0; i < resultsUnits.length; i++) { + var database = resultsUnits[i]["reference_db"] + ".dbo."; + + var sqlQry = + sqlQry + + `SELECT DISTINCT Y.*, + CASE + WHEN DiaDaSemana = 1 THEN 'DOM' + WHEN DiaDaSemana = 2 THEN 'SEG' + WHEN DiaDaSemana = 3 THEN 'TER' + WHEN DiaDaSemana = 4 THEN 'QUA' + WHEN DiaDaSemana = 5 THEN 'QUI' + WHEN DiaDaSemana = 6 THEN 'SEX' + WHEN DiaDaSemana = 7 THEN 'SAB' + ELSE + '' + END AS DiaSemana, + Y.NUMEROVAGAS - Y.VAGASOCUPADAS AS VagasDisponiveis, + ${resultsUnits[i]["idunits"]} as MySQLUnitID, + '${resultsUnits[i]["unityname"]}' as MySQLUnitName + FROM ( + SELECT DISTINCT Z.* FROM ( + SELECT DISTINCT convert(varchar(10), TC.Data, 120) as Data, + convert(varchar(05), TC.HoraInicial, 108) as HoraInicial, + convert(varchar(05), TC.HoraFinal, 108) as HoraFinal, + T.Codigo AS CodigoTurma, T.NOME as DescricaoTurma, TC.CodigoCurso, + C.NomeVersao AS DescricaoCurso, TC.CodigoInstrutor, F.Nome as NomeInstrutor, + TC.CodigoSala, S.Descricao AS DescricaoSala, T.NumeroVagas, T.TipoTurma, + DATEPART(weekday, TC.Data) as DiaDaSemana, + coalesce(( + SELECT COUNT(*) + FROM ${database}TreinandosTurmas TT + WHERE TT.CODIGOTURMA = T.IDTURMA + AND TT.IdCurso = TC.CodigoCurso + AND TT.Faltoso = 0 + AND TT.IDMatricula > 190008 + ),0) + coalesce(( + SELECT COUNT(*) + FROM ${database}ReservaVagas RV + WHERE RV.IDTurma = T.IDTurma + AND RV.IDCurso = TC.CodigoCurso + AND RV.Concluida = 0 + AND RV.ReservaFlex = 0 + ),0) as VagasOcupadas, + TC.DATA AS DATAC, T.BloqueadaVenda, 0 AS IdPlantaoReposicao, T.IDTurma, + coalesce( + ( + SELECT COUNT(*) + FROM ${database}ReservaVagas RV + WHERE RV.IDTurma = T.IDTurma + AND RV.IDCurso = TC.CodigoCurso + AND RV.Concluida = 0 + AND RV.ReservaFlex = 0 + ),0) as QTDReservas + from ${database}Turmas T + INNER JOIN ${database}TurmasCalendario TC + on TC.IdTurma = T.IdTurma + INNER JOIN ${database}SALAS S + on S.Codigo = TC.CodigoSala + INNER JOIN ${database}Funcionarios F + ON F.IDFuncionario = TC.CodigoInstrutor + INNER JOIN ${database}Cursos C + ON C.Codigo = TC.CodigoCurso + WHERE T.TipoTurma <> 'F' + AND TC.DATA BETWEEN '${dateSQL}' AND '${dateSQL}' + AND CONVERT(CHAR(5), TC.HoraInicial, 108) + BETWEEN '00:00' AND '23:59' + AND CONVERT(CHAR(5), TC.HoraFinal, 108) BETWEEN '00:00' AND '23:59' + AND T.TipoTurma IN ('R','T','E','P','L','C','O') + + UNION + + SELECT Data, HoraInicial, HoraFinal, CodigoTurma, DescricaoTurma, CodigoCurso, DescricaoCurso, + CodigoInstrutor, NomeInstrutor, CodigoSala, DescricaoSala, NumeroVagas, TipoTurma, DiaDaSemana, + (( + select count(*) + from ( + select distinct TCV.IDTurma + from ${database}TurmasCalendario TCV + inner join ${database}Turmas TV + on TV.IdTurma = TCV.IdTurma + inner join ${database}TreinandosTurmas TTV + on TTV.CodigoTurma = TCV.IdTurma + and TTV.IDCurso = TCV.CodigoCurso + where TCV.Data = X.Data + and TCV.CodigoInstrutor = X.CodigoInstrutor + and ( + TCV.HoraInicial between X.HoraInicial and dateadd(minute,-1,X.HoraFinal) + or TCV.HoraFinal between dateadd(minute,1,X.HoraInicial) and X.HoraFinal + ) + AND TV.TipoTurma = 'F' + AND TTV.IDMatricula > 190008 + ) as L + ) + (coalesce( + ( + SELECT COUNT(*) + FROM ${database}ReservaVagas RV + WHERE ( + RV.HoraInicioFlex between convert(time(0),X.HoraInicial) and convert(time(0),dateadd(minute,-1,X.HoraFinal)) + OR RV.HoraTerminoFlex between convert(time(0),dateadd(minute,1,X.HoraInicial)) and convert(time(0),X.HoraFinal) + ) + AND RV.IDProfessorFlex = X.CodigoInstrutor + AND RV.Concluida = 0 + AND RV.ReservaFlex = 1 + ),0) + ) + ) as VagasOcupadas, DataC, BloqueadaVenda, + IdPlantaoReposicao, IDTurma, QTDReservas + FROM ( + SELECT convert(varchar(10), TC.Data, 120) as Data, + convert(varchar(05), TC.HoraInicial, 108) as HoraInicial, + convert(varchar(05), TC.HoraFinal, 108) as HoraFinal, + 'FLEX' as CodigoTurma, 'FLEX' as DescricaoTurma, + '' as CodigoCurso, 'FLEX' as DescricaoCurso, TC.CodigoInstrutor, + F.Nome as NomeInstrutor, TC.CodigoSala, S.Descricao AS DescricaoSala, + S.NumMicros as NumeroVagas, T.TipoTurma, DATEPART(weekday, TC.Data) as DiaDaSemana, + ( + coalesce(( + SELECT COUNT(*) + FROM ${database}TreinandosTurmas TT + WHERE TT.CODIGOTURMA = T.IDTURMA + AND TT.IdCurso = TC.CodigoCurso and TT.Faltoso = 0 + AND TT.IDMatricula > 190008 + ),0) + + coalesce( + ( + SELECT COUNT(*) + FROM ${database}ReservaVagas RV + WHERE ( + RV.HoraInicioFlex between convert(time(0),TC.HoraInicial) and convert(time(0),dateadd(minute,-1,TC.HoraFinal)) + OR RV.HoraTerminoFlex between convert(time(0),dateadd(minute,1,TC.HoraInicial)) and convert(time(0),TC.HoraFinal) + ) + AND RV.IDProfessorFlex = TC.CodigoInstrutor + AND RV.Concluida = 0 + AND RV.ReservaFlex = 1 + ) + ,0) + ) as VagasOcupadas, TC.DATA AS DATAC, T.BloqueadaVenda, 0 AS IdPlantaoReposicao, 0 AS IDTurma, + coalesce( + ( + SELECT COUNT(*) + FROM ${database}ReservaVagas RV + WHERE ( + RV.HoraInicioFlex between convert(time(0),TC.HoraInicial) and convert(time(0),dateadd(minute,-1,TC.HoraFinal)) + OR RV.HoraTerminoFlex between convert(time(0),dateadd(minute,1,TC.HoraInicial)) and convert(time(0),TC.HoraFinal) + ) + AND RV.IDProfessorFlex = TC.CodigoInstrutor + AND RV.Concluida = 0 + AND RV.ReservaFlex = 1 + ) + ,0) as QTDReservas + from ${database}Turmas T + INNER JOIN ${database}TurmasCalendario TC + on TC.IdTurma = T.IdTurma + INNER JOIN ${database}SALAS S + on S.Codigo = TC.CodigoSala + INNER JOIN ${database}Funcionarios F + ON F.IDFuncionario = TC.CodigoInstrutor + INNER JOIN ${database}Cursos C + ON C.Codigo = TC.CodigoCurso + WHERE TC.DATA BETWEEN '${dateSQL}' AND '${dateSQL}' + AND CONVERT(CHAR(5), TC.HoraInicial, 108) BETWEEN '00:00' AND '23:59' + AND CONVERT(CHAR(5), TC.HoraFinal, 108) BETWEEN '00:00' AND '23:59' AND T.TipoTurma = 'F' + ) AS X + GROUP BY Data, HoraInicial, HoraFinal, CodigoTurma, DescricaoTurma, CodigoCurso, DescricaoCurso, + CodigoInstrutor, NomeInstrutor, CodigoSala, DescricaoSala, TipoTurma, DiaDaSemana, DataC, NumeroVagas, + BloqueadaVenda, IdPlantaoReposicao, IdTurma, QTDReservas + + UNION + + SELECT DISTINCT convert(varchar(10), P.Data, 120) as Data, convert(varchar(05), P.HoraInicial, 108) as HoraInicial, + convert(varchar(05), P.HoraFinal, 108) as HoraFinal, '' as CodigoTurma, coalesce(P.Descricao,'') as DescricaoTurma, + P.IdTipoCursoExtra as CodigoCurso, AE.Descricao as DescricaoCurso, P.IdInstrutor as CodigoInstrutor, + F.Nome as NomeInstrutor, P.IdSala as CodigoSala, S.Descricao AS DescricaoSala, P.Vagas as NumeroVagas, + '-' as TipoTurma, DATEPART(weekday, P.Data) as DiaDaSemana, + ( + select COUNT(*) + from ${database}PlantaoReposicaoDetalhe PRD + where PRD.IdPlantaoReposicao = P.IDPlantaoReposicao + ) as VagasOcupadas, + P.DATA AS DATAC, 0 as BloqueadaVenda, P.IdPlantaoReposicao, + 0 as IDTurma, 0 as QTDReservas + FROM ${database}PlantaoReposicao P + left JOIN ${database}PlantaoReposicaoDetalhe PR + on PR.IdPlantaoReposicao = P.IdPlantaoReposicao + INNER JOIN ${database}TiposAulasExtras AE + on AE.IDTipoAulaExtra = P.IdTipoCursoExtra + INNER JOIN ${database}SALAS S + on S.Codigo = P.IDSala + INNER JOIN ${database}Funcionarios F + ON F.IDFuncionario = P.IDInstrutor + WHERE P.DATA BETWEEN '${dateSQL}' AND '${dateSQL}' + AND CONVERT(CHAR(5), P.HoraInicial, 108) BETWEEN '00:00' AND '23:59' + AND CONVERT(CHAR(5), P.HoraFinal, 108) BETWEEN '00:00' AND '23:59' + ) AS Z WHERE 1 = 1 + ) AS Y`; + + if (i < resultsUnits.length - 1) { + sqlQry = sqlQry + " union all "; + } else { + sqlQry = sqlQry + " ORDER BY Data"; + } + } + + sqlServerConnection + .request() + .query(sqlQry, function (error, results, fields) { + if (!error && results.length != 0) { + res.send( + JSON.stringify({ + status: 200, + error: null, + response: results.recordsets[0], + }) + ); + } else { + console.log("Erro:"); + console.log(error); + } + }); +} + +function generateUnitsAlarmDate(resultsUnits, res) { + var sqlQry = ""; + + for (var i = 0; i < resultsUnits.length; i++) { + var database = resultsUnits[i]["reference_db"] + ".dbo."; + + sqlQry = + sqlQry + + `select R.* + from ( + select + ( + select count(*) + from ${database}Chamadas CH + inner join ${database}ChamadasDetalhes CD + on CD.IDChamadas = CH.IDChamadas + where CH.IDTurma = TT.CodigoTurma + and CH.IDCurso = TT.IDCurso + and CD.Presente = 1 + ) as QTDChamadas, + TT.IDMatricula, + A.Nome as Aluno, + CUR.NomeVersao as Curso, + CUR.Codigo as IDCurso, + convert(varchar(10),( + select MIN(TC.Data) as Data + from ${database}TurmasCalendario TC + where TC.Ministrado = 0 + and TC.IdTurma = TT.CodigoTurma + and TC.Data >= convert(date,getdate(),121) + ),103) as DataProximaAula, + TD.Ordem, + ${resultsUnits[i]["idunits"]} as MySQLUnitID, + '${resultsUnits[i]["unityname"]}' as MySQLUnitName, + '${resultsUnits[i]["ip_externo"]}' as MySQLIPExterno, + '${resultsUnits[i]["porta_mysql"]}' as MySQLPort + from ${database}TreinandosTurmas TT + inner join ${database}Cursos CUR + on CUR.Codigo = TT.IDCurso + inner join ${database}Clientes A + on A.IDCliente = TT.IDTreinando + inner join ${database}TurmasDetalhe TD + on TD.IDTurma = TT.CodigoTurma + and TD.CodigoCurso = TT.IDCurso + where TT.IDMatricula > 190008 + and TT.Desistente = 0 + and CUR.CH_ProgTrein > ( + select sum(datediff(HOUR,CH.HoraInicio,CH.HoraTermino)) + from ${database}Chamadas CH + inner join ${database}ChamadasDetalhes CD + on CD.IDChamadas = CH.IDChamadas + where CH.IDTurma = TT.CodigoTurma + and CH.IDCurso = TT.IDCurso + ) + ) R + inner join ( + select TT.IDMatricula, + min(TD.Ordem) as Ordem + from ${database}TreinandosTurmas TT + inner join ${database}Cursos CUR + on CUR.Codigo = TT.IDCurso + inner join ${database}Clientes A + on A.IDCliente = TT.IDTreinando + inner join ${database}TurmasDetalhe TD + on TD.IDTurma = TT.CodigoTurma + and TD.CodigoCurso = TT.IDCurso + where TT.IDMatricula > 190008 + and TT.Desistente = 0 + and CUR.CH_ProgTrein > ( + select sum(datediff(HOUR,CH.HoraInicio,CH.HoraTermino)) + from ${database}Chamadas CH + inner join ${database}ChamadasDetalhes CD + on CD.IDChamadas = CH.IDChamadas + where CH.IDTurma = TT.CodigoTurma + and CH.IDCurso = TT.IDCurso + ) + group by IDMatricula + ) S + on R.IDMatricula = S.IDMatricula + and R.Ordem = S.Ordem`; + + if (i < resultsUnits.length - 1) { + sqlQry = sqlQry + " union all "; + } else { + sqlQry = sqlQry + " order by MySQLUnitID asc, QTDChamadas desc"; + } + } + + sqlServerConnection + .request() + .query(sqlQry, function (error, results, fields) { + if (!error && results.length != 0) { + ApplyMysqlData(results, res); + } else { + //res.send('Funcionário não tem acesso a "Inclusão de Controle de Chamadas"'); + console.log("Erro:"); + console.log(error); + } + }); +} + +function ApplyMysqlData( + results, + res, + returnMysql = null, + lastPos = 0, + lastUnit = 0, + arrCrashedUnits = [] +) { + try { + //console.log("MysqlUnit: " + results.recordsets[0][lastPos]['MySQLUnitID']) + + if ( + arrCrashedUnits.indexOf(results.recordsets[0][lastPos]["MySQLUnitID"]) == + -1 + ) { + //Se a conexão com a unidade não falhou (anteriormente) + if (results.recordsets[0][lastPos]["MySQLUnitID"] !== lastUnit) { + //Se a unidade não é mesma que a anterior faz a pesquisa no MySQL + lastUnit = results.recordsets[0][lastPos]["MySQLUnitID"]; + + var sqlQry2 = `select tpc.idcourses, count(c.idclasses) as QTDAulasCadastradas + from traineeprogramcourses tpc + inner join classes c + on c.idcourses = tpc.idcourses + where c.disabled = 0 + group by tpc.idcourses`; + + //console.log(sqlQry2); + + var mysqlReference = require("mysql"); + + var DadosConnection = { + host: results.recordsets[0][lastPos]["MySQLIPExterno"], + user: "myrobot", + password: "myrobot2019", + database: Variables("database_mysql"), + port: results.recordsets[0][lastPos]["MySQLPort"], + }; + + mysqlLocal2 = mysqlReference.createConnection(DadosConnection); + + mysqlLocal2.query(sqlQry2, function (error2, results2, fields2) { + if (!error2 && results2.length != 0) { + //Caso a conexão tenha sido correta e encontrado resultados + for (var i = 0; i < results2.length; i++) { + if ( + results2[i]["idcourses"] == + results.recordsets[0][lastPos]["IDCurso"] + ) { + results.recordsets[0][lastPos]["QTDAulasCadastradas"] = + results2[i]["QTDAulasCadastradas"]; + } + } + + if (lastPos < results.recordsets[0].length - 1) { + ApplyMysqlData( + results, + res, + results2, + lastPos + 1, + lastUnit, + arrCrashedUnits + ); + } else { + console.log("Consulta Alunos Controle"); + + res.send( + JSON.stringify({ + status: 200, + error: null, + response: results.recordsets[0], + }) + ); + } + } else { + //Caso a conexão tenha dados erro ou não encontrou resultados + console.log( + "Erro ao Acessar Banco de Dados: " + + results.recordsets[0][lastPos]["MySQLUnitName"] + ); + //console.log(DadosConnection); + //console.log(error2); + + //Adiciona a unidades crashadas + arrCrashedUnits.push(lastUnit); + + results.recordsets[0][lastPos]["QTDAulasCadastradas"] = null; + + if (lastPos < results.recordsets[0].length - 1) { + ApplyMysqlData( + results, + res, + results2, + lastPos + 1, + lastUnit, + arrCrashedUnits + ); + } else { + console.log("Consulta Alunos Controle"); + + res.send( + JSON.stringify({ + status: 200, + error: null, + response: results.recordsets[0], + }) + ); + } + } + }); + } else { + //Se o resultado já foi encontrado antes + for (var i = 0; i < returnMysql.length; i++) { + if ( + returnMysql[i]["idcourses"] == + results.recordsets[0][lastPos]["IDCurso"] + ) { + results.recordsets[0][lastPos]["QTDAulasCadastradas"] = + returnMysql[i]["QTDAulasCadastradas"]; + } + } + + if (lastPos < results.recordsets[0].length - 1) { + ApplyMysqlData( + results, + res, + returnMysql, + lastPos + 1, + lastUnit, + arrCrashedUnits + ); + } else { + console.log("Consulta Alunos Controle"); + + res.send( + JSON.stringify({ + status: 200, + error: null, + response: results.recordsets[0], + }) + ); + } + } + } else { + results.recordsets[0][lastPos]["QTDAulasCadastradas"] = null; + + //Se a conexão com o mysql falhou a unidade está dentro de crashadas + if (lastPos < results.recordsets[0].length - 1) { + ApplyMysqlData( + results, + res, + null, + lastPos + 1, + lastUnit, + arrCrashedUnits + ); + } else { + res.send( + JSON.stringify({ + status: 200, + error: null, + response: results.recordsets[0], + }) + ); + } + } + } catch (err) { + console.log("Erro de Consulta no MySQL"); + console.log(err); + res.send( + JSON.stringify({ + status: 500, + error: "Erro Geral", + response: "", + }) + ); + } +} diff --git a/controllers/usersController.js b/controllers/usersController.js new file mode 100644 index 0000000..d40e92e --- /dev/null +++ b/controllers/usersController.js @@ -0,0 +1,1171 @@ +require('../connections/mysql-server'); +require('../connections/sql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); +const { Router } = require('express'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.post('/authUser', (req, res) => { + //const password = encriptPassword(req.body.password); + const type = parseInt(req.body.type); + const password = req.body.password; + const user = req.body.login; + const db = req.body.db; + this.id = type + user + password; + const query = `SELECT + zu.user AS IDMatricula, + zu.userName AS Nome, + zu.idzoeusertype AS idusertype + FROM zoeusers zu + WHERE zu.enabled = 1 AND CONCAT(zu.idunits, '.dbo.') = '${db}' AND zu.user = '${user}' AND zu.password = '${password}';`; + //console.log(query); + execMySQLQueryLogin(query, res, req.originalUrl); + }); + + router.post('/authUserOld', (req, res) => { + const type = parseInt(req.body.type); + const password = encriptPassword(req.body.password); + const email = req.body.email; + const user = req.body.login; + this.id = type + user + password; + const db = req.body.db; + const ModoEmergencia = req.body.ME || false; + + /* if(db != "SGPInicial.dbo." && user == "190000"){ + //Vai entra não rapai + }else {*/ + switch (type) { + case 1: //funcionário + execSQLQueryLogin(`SELECT *, + 1 as 'idusertype' FROM ${db}Funcionarios WHERE IDFuncionario = '${user}' AND Senha = '${password}'`, res, req.originalUrl); + break; + case "1": //funcionário app + execSQLQueryLogin(`SELECT IDFuncionario, Nome, + 1 as 'idusertype' FROM ${db}Funcionarios WHERE IDFuncionario = '${user}' AND Senha = '${password}'`, res, req.originalUrl); + break; + case 2: //adm + execMySQLQueryLogin(`SELECT + * + FROM users + WHERE user = '${user}' AND password = '${password}' AND enabled = 1 AND idusertype in (2, 3, 6, 7, 8, 9, 10, 11, 12, 13);`, res, req.originalUrl); + break; + case 3: //First Access + execSQLQuery2(`SELECT + mt.IDMatricula, + c.e_mail, + c.Nome, + c.IDCliente, + c.SenhaIntranet + FROM ${db}MatriculasTreinandos mt + INNER JOIN ${db}Clientes c ON mt.IDTreinando = c.IDCliente + WHERE mt.IDMatricula = '${user}' AND c.e_mail = '${email}';`, res, req.originalUrl); + break; + case 4: //aluno + if (ModoEmergencia) { + execMySQLQueryLogin(`SELECT + ${user} AS IDMatricula, + '123' AS SenhaIntranet, + 'Aluno' AS Nome, + 4 as 'idusertype';`, res, req.originalUrl); + } + else { + //console.log("Matricula: " + user + " - Senha: '" + password + "'"); + // '      ' espaços em branco das senhas + if (user == "190000") + { + if (db == "SGPInicial.dbo." && password == encriptPassword("z0et3acherM02ster") ) + { + execSQLQueryLogin(`SELECT + '190000' as 'IDMatricula', + 'maker2019' as 'SenhaIntranet', + 'Sistema' as 'Nome', + 4 as 'idusertype';`, res, req.originalUrl); + } + else if(db != "SGPInicial.dbo." && password == encriptPassword("zoeteacher")) + { + execSQLQueryLogin(`SELECT + '190000' as 'IDMatricula', + 'maker2019' as 'SenhaIntranet', + 'Sistema' as 'Nome', + 4 as 'idusertype';`, res, req.originalUrl); + } + } + else if (user =="190024" && password == encriptPassword("123")) + { + execSQLQueryLogin(`SELECT + '190024' as 'IDMatricula', + 'maker2019' as 'SenhaIntranet', + 'Sistema' as 'Nome', + 4 as 'idusertype';`, res, req.originalUrl); + } + else if(user=="190025" && password == encriptPassword("123")) + { + execSQLQueryLogin(`SELECT + '190025' as 'IDMatricula', + 'maker2019' as 'SenhaIntranet', + 'Sistema' as 'Nome', + 4 as 'idusertype';`, res, req.originalUrl); + } + else if(user=="190026" && password == encriptPassword("123")) + { + execSQLQueryLogin(`SELECT + '190026' as 'IDMatricula', + 'maker2019' as 'SenhaIntranet', + 'Sistema' as 'Nome', + 4 as 'idusertype';`, res, req.originalUrl); + } + else if(user=="240001" && password == encriptPassword("123")) + { + execSQLQueryLogin(`SELECT + '240001' as 'IDMatricula', + '123' as 'SenhaIntranet', + 'ZoeSistema' as 'Nome', + 4 as 'idusertype';`, res, req.originalUrl); + } + else if (user == "190001" && password == encriptPassword("123")) { + execSQLQueryLogin(`SELECT + '190001' as 'IDMatricula', + '123' as 'SenhaIntranet', + 'Aluno Demonstração' as 'Nome', + 4 as 'idusertype';`, res, req.originalUrl); + } + else if (user == "190002" && password == encriptPassword("123")) { + mysqlConnection.query(`select * from usershomework uh inner join units un on un.idunits = uh.idunits where uh.idusers = ${user} and un.reference_db = '${db.split('.dbo.')[0]}';`, function(error, AlunoExiste, fields) { + if (AlunoExiste.length > 0 && AlunoExiste[0]['disabled'] == 1) { + res.send(JSON.stringify({ + "status": 500, + "error": "Usuário desativado", + "response": [], + "token": null + })); + } + else if (AlunoExiste.length > 0 && AlunoExiste[0]['disabled'] == 0) { + mysqlConnection.query(`update usershomework set disabled = 1 where idusers = ${user} and idunits = (select idunits from units where reference_db = '${db.split('.dbo.')[0]}');`, function(error, results, fields) { + execSQLQueryLogin(`SELECT + '190002' as 'IDMatricula', + '123' as 'SenhaIntranet', + 'Professor' as 'Nome', + 4 as 'idusertype';`, res, req.originalUrl); + }); + } + else { + mysqlConnection.query(`insert into usershomework (idusers, idunits, disabled) values (${user}, (select idunits from units where reference_db = '${db.split('.dbo.')[0]}'), 1);`, function(error, results, fields) { + execSQLQueryLogin(`SELECT + '190002' as 'IDMatricula', + '123' as 'SenhaIntranet', + 'Professor' as 'Nome', + 4 as 'idusertype';`, res, req.originalUrl); + }); + } + }); + } + else { + mysqlConnection.query(`SELECT desativado FROM alunosdesativados where idunits = (select idunits from units where reference_db = '${db.split('.dbo.')[0]}') and idusers = ${user};`, function(error, AlunoDesativado, fields) { + if (AlunoDesativado && AlunoDesativado.length > 0 && AlunoDesativado[0]['desativado'] == 1) { + res.send(JSON.stringify({ + "status": 500, + "error": "Usuário desativado", + "response": [], + "token": null + })); + console.log(new Date().toUTCString() + " - " + req.originalUrl + "/ error 500"); + } + else { + execSQLQueryLogin(`SELECT distinct + mt.IDMatricula, + c.SenhaIntranet, + c.Nome, + 4 as 'idusertype' + FROM ${db}MatriculasTreinandos mt + INNER JOIN ${db}Clientes c ON mt.IDTreinando = c.IDCliente + inner join ${db}TreinandosTurmas tt on tt.IDMatricula = mt.IDMatricula and tt.CodigoTurma > 0 + WHERE mt.IDMatricula = '${user}' AND c.SenhaIntranet = '${password}' and tt.Faltoso = 0 and tt.Concluiu = 0 and tt.Desistente = 0;`, res, req.originalUrl); + } + }); + } + } + break; + case 5: //franchisee + execMySQLQueryLogin(`SELECT + us.idusers, + us.name, + us.idunits, + (SELECT u.reference_db FROM units u WHERE u.idunits = us.idunits) AS 'db', + us.idusertype + FROM users us + WHERE us.user = '${user}' AND us.password = '${password}' AND us.enabled = 1 AND us.idusertype in (5, 14, 15, 16);`, res, req.originalUrl); + break; + default: + console.log("default"); + break; + } + //} + }); + + router.post('/loginzoerobot', (req, res) => { + const robot_id = req.body.robot_id; + const idusers = parseInt(req.body.idusers); + const idunits = parseInt(req.body.idunits); + const idusertype = parseInt(req.body.idusertype); + const password = req.body.password; + const db = req.body.db; + const micro = parseInt(req.body.micro) || 0; + execSQLQuery(`CALL loginzoerobot('${robot_id}', ${idusers}, ${idunits}, '${db}', '${password}', ${idusertype}, ${micro})`, res, req.originalUrl); + }) + + router.post('/getloginzoerobot', (req, res) => { + const robot_id = req.body.robot_id; + mysqlConnection.query(`CALL getloginzoerobot('${robot_id}')`, function(error, response, fields) { + res.send(response[0]); + }) + }) + + router.post('/updatezoerobotmicro', (req, res) => { + const robot_id = req.body.robot_id; + const micro = parseInt(req.body.micro); + execSQLQuery(`CALL updatezoerobotmicro('${robot_id}', ${micro})`, res, req.originalUrl); + }) + + + + router.get('/closeCon', (req, res) => { + console.log("Fechando conexões"); + mysqlConnection.end(); + res.send(true); + }) + + router.get('/authTeacher/:db/:login/:senha', (req, res) => { + let Login = req.params.login; + let Senha = encriptPassword(req.params.senha); + let Banco = req.params.db; + let sqlQuery = `SELECT IDFuncionario, Nome FROM ${Banco}.dbo.Funcionarios WHERE Nome = '${Login}' AND Senha = '${Senha}';`; + sqlServerConnection.request().query(sqlQuery, function (error, results, fields) { + const Caminho = `http:${req.headers.host.split(':')[0]}/assets/`; + try { + if (results.recordsets[0].length > 0) + res.redirect(Caminho + 'login_succefull.php'); + else + res.redirect(Caminho + 'restart_login.php'); + } + catch (e) { + res.redirect(Caminho + 'restart_login.php'); + } + }) + }) + + router.patch('/cadPass', (req, res) => { + const password = encriptPassword(req.body.password); + const user = req.body.login; + const db = req.body.db; + execSQLQuery2(` + UPDATE + ${db}Clientes + SET + SenhaIntranet = '${password}' + WHERE + IDCliente = ${user}`, + res, + req.originalUrl + ); + }) + + router.post('/ChangeUserIcon', (req, res) => { + console.log(req.body); + const idusers = parseInt(req.body.idusers); + const usericon = req.body.usericon; + execSQLQuery(` + UPDATE + myrobot.usersLevel + SET + usericon = '${usericon}' + WHERE + idusers = ${idusers}`, + res, + req.originalUrl + ); + }) + + router.patch('/ResetPass', (req, res) => { + const id = req.body.id; + const db = req.body.db; + execSQLQuery2(` + UPDATE + ${db}Clientes + SET + SenhaIntranet = null + WHERE + IDCliente = ${id}`, + res, + req.originalUrl + ); + }) + + router.post('/insert', verifyJWT, (req, res) => { + const idusertype = req.body.idusertype; + const idcities = req.body.idcities; + const idstates = req.body.idstates; + const name = req.body.name; + const user = req.body.user; + const password = encriptPassword(req.body.password); + const email = req.body.email; + const telephone = req.body.telephone; + const address = req.body.address; + const district = req.body.district; + const enabled = req.body.enabled ? 1 : 0; + const idunits = req.body.idunits; + + execSQLQuery(`INSERT INTO users (idusertype, idcities, idstates, name, user, password, email, telephone, address, district, enabled, idunits) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`, res, req.originalUrl, [idusertype, idcities, idstates, name, user, password, email, telephone, address, district, enabled, idunits]); + }); + + router.post('/givexp', (req, res) => { + + const xpAdd = parseInt(req.body.xpAdd); + const userId = parseInt(req.body.userId); + const unitid = parseInt(req.body.unitid); + + execSQLQuery(`UPDATE usersLevel SET usersxp = usersxp + ${xpAdd} where idusers = ${userId} AND idunit = ${unitid};`, res, req.originalUrl); + }); + + router.post('/createusersprofile', (req, res) => { + + const userId = parseInt(req.body.userId); + const unitId = parseInt(req.body.unitId); + + execSQLQuery(`INSERT INTO usersLevel (idusers, idunit,usersxp) VALUES (${userId}, ${unitId}, 0);`, res, req.originalUrl); + }); + + router.patch('/update', verifyJWT, (req, res) => { + const idusers = req.body.idusers; + const idusertype = req.body.idusertype; + const idcities = req.body.idcities; + const idstates = req.body.idstates; + const name = req.body.name; + const user = req.body.user; + const password = encriptPassword(req.body.password); + const email = req.body.email; + const telephone = req.body.telephone; + const address = req.body.address; + const district = req.body.district; + const enabled = req.body.enabled ? 1 : 0; + const idunits = req.body.idunits; + + execSQLQuery(`UPDATE users SET + idusertype = ${idusertype}, + idcities = ${idcities}, + idstates = ${idstates}, + name = '${name}', + user = '${user}', + password = '${password}', + email = '${email}', + telephone = '${telephone}', + address = '${address}', + district = '${district}', + enabled = ${enabled}, + idunits = ${idunits} + WHERE idusers = ${idusers};`, res, req.originalUrl, [idusertype, idcities, idstates, name, user, password, email, telephone, address, district, enabled, idunits, idusers]); + }); + + router.get('/disable/:idusers', verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + execSQLQuery(`UPDATE users SET + enabled = not enabled + WHERE idusers = ${idusers};`, res, req.originalUrl); + }); + + router.get('/getUser/:idusers', verifyJWT, (req, res) => { + const idusers = parseInt(req.params.idusers); + execSQLQuery(`SELECT + * + FROM users + WHERE idusers = ${idusers};`, res, req.originalUrl); + }); + + + router.get('/getUserType', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM usertype;`, res, req.originalUrl); + }); + + router.post('/inserirleveluser', verifyJWT, (req, res) => { + const idusers = req.body.idusers; + const idunit = req.body.idunits; + execSQLQuery(`INSERT INTO usersLevel (idusers, idunit) VALUES (?, ?);`, res, req.originalUrl, [idusers, idunit]); + }); + + router.post('/insertUserType', verifyJWT, (req, res) => { + const idusertype = req.body.idusertype; + const description = req.body.description; + const enabled = req.body.enabled ? 1 : 0; + execSQLQuery(`INSERT INTO usertype (description, enabled) VALUES (?, ?);`, res, req.originalUrl, [description, enabled]); + }); + + router.patch('/updateUserType', verifyJWT, (req, res) => { + const idusertype = req.body.idusertype; + const description = req.body.description; + const enabled = req.body.enabled ? 1 : 0; + execSQLQuery(`update usertype set description = ?, enabled = ? where idusertype = ?;`, res, req.originalUrl, [description, enabled, idusertype]); + }); + + + router.get('/getidusertype/:idusertype', (req, res) => { + const idusertype = parseInt(req.params.idusertype); + execSQLQuery(`SELECT + * + FROM usertype + WHERE idusertype = ${idusertype};`, res, req.originalUrl); + }); + //AVATAR + router.get('/getavatar', verifyJWT, (req, res) => { + execSQLQuery(`SELECT * FROM myrobot.avatarusers;`, res, req.originalUrl); + }); + //LEVEL + router.get('/getleveluser/:idusers/:idunit', (req, res) =>{ + const idusers = parseInt(req.params.idusers); + const idunit = parseInt(req.params.idunit); + let sqlQuery = `SELECT * + FROM usersLevel + WHERE idusers = ${idusers} AND idunit = ${idunit};`; + + /* console.log(sqlQuery); */ + execSQLQuery(sqlQuery, res, req.originalUrl); + }); + + router.get('/getEmployee/:banco', (req, res) => { + const db = req.params.banco; + execSQLQuery2(`SELECT distinct + fu.IDFuncionario, + fu.Nome, + fa.DescricaoAcesso + FROM ${db}Funcionarios fu + INNER JOIN ${db}FuncionariosAcesso fa ON fa.IDFuncionario = fu.IDFuncionario + WHERE fa.Permitido = 1 AND fa.DescricaoAcesso = 'EAD Acesso Online Professor';`, res, req.originalUrl); + }); + + router.get('/getEmployeeId/:id/:banco', (req, res) => { + id = parseInt(req.params.id); + const db = req.params.banco; + execSQLQuery2(` + SELECT distinct + ${db}Funcionarios.IDFuncionario, + ${db}Funcionarios.Nome, + ${db}FuncionariosAcesso.DescricaoAcesso + FROM + ${db}Funcionarios + INNER JOIN + ${db}FuncionariosAcesso + ON + ${db}FuncionariosAcesso.IDFuncionario = ${db}Funcionarios.IDFuncionario + WHERE + ${db}FuncionariosAcesso.Permitido = 1 + AND + ${db}Funcionarios.IDFuncionario = ${id} + AND + ${db}FuncionariosAcesso.DescricaoAcesso = 'EAD Acesso Online Professor'`, + res, + req.originalUrl + ); + }); + + router.get('/getUser', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + us.*, + ut.description + FROM users us + inner join usertype ut on ut.idusertype = us.idusertype;`, res, req.originalUrl); + }); + + router.get('/getStudentName/:id/:banco', verifyJWT, (req, res) => { + id = parseInt(req.params.id); + const db = req.params.banco; + execSQLQuery2(` + select top(1) + C.Nome + from + ${db}TreinandosTurmas TT + inner join + ${db}Clientes C + on + C.IDCliente = TT.IDTreinando + where + TT.IDMatricula = ${id};`, + res, + req.originalUrl + ); + }) + + router.get('/SolucaoProblemas', (req, res) => { + AtualizaConexaoMySQL(); + }); + + + router.get('/RelatorioAlunosAulasGeral/:idunits', (req, res) => { + const idunits = parseInt(req.params.idunits); + let condicao = `un.idunits = ${idunits}`; + if (idunits == 0) + condicao = "true"; + const sqlQuery = `select + *, + al.Aulas * 2 as 'HorasAssistidas' + from ( + select + un.idunits, + un.unityname as 'Unidade', + sc.idusers as 'Matricula', + count(*) as 'Aulas', + (select date_format(sc1.insert_date, '%d/%m/%Y %H:%i') from stepclass sc1 where sc1.idunits = sc.idunits and sc1.idusers = sc.idusers order by sc1.insert_date desc limit 1) as 'UltimaAula' + from stepclass sc + inner join units un on un.idunits = sc.idunits + where ${condicao} + group by un.idunits, sc.idusers, un.unityname + order by un.unityname, sc.idusers asc) al`; + mysqlConnection.query(sqlQuery, function(error, ListagemAulas, fields) { + mysqlConnection.query(`select * from units un where ${condicao};`, function(error, ListaUnidades, fields) { + LoopAlunosSQLServerGeral(ListagemAulas, ListaUnidades, 0, function(NovaListaAulas) { + let TabelaHtml = ` + + + Relatório de Alunos por Unidade + + + + + + + + + + + + + `; + for (let i = 0; i < NovaListaAulas.length; i++) { + TabelaHtml += `${(i % 2 === 0) ? '' : ''} + + + + + + + + + `; + } + TabelaHtml += `
UnidadeMatriculaAulasUltima AulaHoras AssistidasAlunoCanceladaSuspensa
${NovaListaAulas[i]['Unidade']}${NovaListaAulas[i]['Matricula']}${NovaListaAulas[i]['Aulas']}${NovaListaAulas[i]['UltimaAula']}${NovaListaAulas[i]['HorasAssistidas']}${NovaListaAulas[i]['Aluno']}${NovaListaAulas[i]['Cancelada']}${NovaListaAulas[i]['Suspensa']}
`; + res.send(JSON.stringify({"status": 200, "Dados": NovaListaAulas, "TabelaHtml": TabelaHtml})); + }) + }) + }) + }) + + function LoopAlunosSQLServerGeral(ListagemAulas, ListaUnidades, Index, callback) { + if (Index < ListaUnidades.length) { + const sqlQuery = `SELECT + mt.IDMatricula, + c.Nome, + tu.Cancelada, + tu.Suspensa + FROM ${ListaUnidades[Index]['reference_db']}.dbo.MatriculasTreinandos mt + INNER JOIN ${ListaUnidades[Index]['reference_db']}.dbo.Clientes c ON mt.IDTreinando = c.IDCliente + INNER JOIN ${ListaUnidades[Index]['reference_db']}.dbo.Turmas tu ON tu.IdTurma = mt.CodigoTurma;`; + sqlServerConnection.request().query(sqlQuery, function (error, AlunosUnidade, fields) { + AlunosUnidade = AlunosUnidade['recordset']; + if (AlunosUnidade && AlunosUnidade.length > 0) { + for (let i = 0; i < AlunosUnidade.length; i++) { + AlunosUnidade[i]['Encontrado'] = 0; + for (let o = 0; o < ListagemAulas.length; o++) { + if (ListagemAulas[o]['idunits'] == ListaUnidades[Index]['idunits']) { + if (ListagemAulas[o]['Matricula'] == AlunosUnidade[i]['IDMatricula']) { + ListagemAulas[o]['Aluno'] = AlunosUnidade[i]['Nome']; + ListagemAulas[o]['Cancelada'] = AlunosUnidade[i]['Cancelada']; + ListagemAulas[o]['Suspensa'] = AlunosUnidade[i]['Suspensa']; + AlunosUnidade[i]['Encontrado'] = 1; + } + } + } + if (AlunosUnidade[i]['Encontrado'] == 0) { + ListagemAulas.push({ + "idunits": ListaUnidades[Index]['idunits'], + "Unidade": ListaUnidades[Index]['unityname'], + "Matricula": AlunosUnidade[i]['IDMatricula'], + "Aulas": 0, + "HorasAssistidas": 0, + "Aluno": AlunosUnidade[i]['Nome'], + "Cancelada": AlunosUnidade[i]['Cancelada'], + "Suspensa": AlunosUnidade[i]['Suspensa'], + }); + } + } + } + Index++; + LoopAlunosSQLServer(ListagemAulas, ListaUnidades, Index, callback); + }) + } + else { + callback(ListagemAulas); + } + } + + router.get('/RelatorioAlunosAulas/:idunits', (req, res) => { + const idunits = parseInt(req.params.idunits); + let condicao = `un.idunits = ${idunits}`; + if (idunits == 0) + condicao = "true"; + const sqlQuery = `select + *, + al.Aulas * 2 as 'HorasAssistidas' + from ( + select + un.idunits, + un.unityname as 'Unidade', + sc.idusers as 'Matricula', + cl.idcourses, + /*(select co2.name from courses co2 where co2.idcourses = cl.idcourses) as 'Curso',*/ + count(*) as 'Aulas', + (select count(*) from stepclass sc1 where sc1.idunits = un.idunits and sc1.idusers = sc.idusers and sc1.idclasses in (select cl2.idclasses from classes cl2 where cl2.idcourses = cl.idcourses) and sc1.completedClass = 0) as 'Pendentes', + (select date_format(sc1.insert_date, '%d/%m/%Y %H:%i') from stepclass sc1 where sc1.idunits = sc.idunits and sc1.idusers = sc.idusers order by sc1.insert_date desc limit 1) as 'UltimaAula' + from stepclass sc + inner join classes cl on cl.idclasses = sc.idclasses and cl.idcourses in (select co.idcourses from courses co where co.aditional = 0 and co.extracourse = 0) + inner join units un on un.idunits = sc.idunits + where ${condicao} + group by un.idunits, sc.idusers, un.unityname, cl.idcourses + order by un.unityname, sc.idusers asc) al`; + mysqlConnection.query(sqlQuery, function(error, ListagemAulas, fields) { + mysqlConnection.query(`select * from units un where ${condicao};`, function(error, ListaUnidades, fields) { // un.enabled = 1 and + LoopAlunosSQLServer(ListagemAulas, ListaUnidades, 0, function(NovaListaAulas) { + let TabelaHtml = ` + + + Relatório de Alunos por Unidade + + + + + + + + + + + + + + + `; + for (let i = 0; i < NovaListaAulas.length; i++) { + TabelaHtml += `${(i % 2 === 0) ? '' : ''} + + + + + + + + + + + `; + } + TabelaHtml += `
UnidadeMatriculaCursoAulasPendentesUltima AulaHoras AssistidasAlunoCanceladaSuspensa
${NovaListaAulas[i]['Unidade']}${NovaListaAulas[i]['Matricula']}${NovaListaAulas[i]['Curso']}${NovaListaAulas[i]['Aulas']}${NovaListaAulas[i]['Pendentes']}${NovaListaAulas[i]['UltimaAula']}${NovaListaAulas[i]['HorasAssistidas']}${NovaListaAulas[i]['Aluno']}${NovaListaAulas[i]['Cancelada']}${NovaListaAulas[i]['Suspensa']}
`; + res.send(JSON.stringify({"status": 200, "Dados": NovaListaAulas, "TabelaHtml": TabelaHtml})); + }) + }) + }) + }) + + function LoopAlunosSQLServer(ListagemAulas, ListaUnidades, Index, callback) { + if (Index < ListaUnidades.length) { + const sqlQuery = `SELECT distinct + mt.IDMatricula, + c.Nome, + tu.IdTurma, + tu.Cancelada, + tu.Suspensa, + tc.CodigoCurso, + cu.NomeVersao as 'Curso', + (select count(*) from ${ListaUnidades[Index]['reference_db']}.dbo.Chamadas ch where ch.IDTurma = tu.IdTurma and ch.IDCurso = cu.Codigo) as 'Chamadas', + (select count(*) from ${ListaUnidades[Index]['reference_db']}.dbo.TurmasCalendario tc1 where tc1.IDTurma = tu.IdTurma and tc1.CodigoCurso = cu.Codigo and tc1.Ministrado = 1) as 'Ministradas' + FROM ${ListaUnidades[Index]['reference_db']}.dbo.MatriculasTreinandos mt + INNER JOIN ${ListaUnidades[Index]['reference_db']}.dbo.Clientes c ON mt.IDTreinando = c.IDCliente + LEFT JOIN ${ListaUnidades[Index]['reference_db']}.dbo.Turmas tu ON tu.IdTurma = mt.CodigoTurma + left join ${ListaUnidades[Index]['reference_db']}.dbo.TurmasCalendario tc on tc.IdTurma = tu.IdTurma + left join ${ListaUnidades[Index]['reference_db']}.dbo.Cursos cu on cu.Codigo = tc.CodigoCurso + order by mt.IDMatricula asc;`; + sqlServerConnection.request().query(sqlQuery, function (error, AlunosUnidade, fields) { + AlunosUnidade = AlunosUnidade['recordset']; + if (AlunosUnidade && AlunosUnidade.length > 0) { + //console.log(AlunosUnidade); + for (let i = 0; i < AlunosUnidade.length; i++) { + AlunosUnidade[i]['Encontrado'] = 0; + for (let o = 0; o < ListagemAulas.length; o++) { + if (ListagemAulas[o]['idunits'] == ListaUnidades[Index]['idunits'] && ListagemAulas[o]['Matricula'] == AlunosUnidade[i]['IDMatricula']) { + ListagemAulas[o]['Aluno'] = AlunosUnidade[i]['Nome']; + ListagemAulas[o]['Cancelada'] = (AlunosUnidade[i]['Cancelada'] != null) ? AlunosUnidade[i]['Cancelada'] : true; + ListagemAulas[o]['Suspensa'] = (AlunosUnidade[i]['Suspensa'] != null) ? AlunosUnidade[i]['Suspensa'] : true; + if (ListagemAulas[o]['idcourses'] == AlunosUnidade[i]['CodigoCurso']) { + ListagemAulas[o]['Curso'] = AlunosUnidade[i]['Curso']; + ListagemAulas[o]['Chamadas'] = AlunosUnidade[i]['Chamadas']; + ListagemAulas[o]['Ministradas'] = AlunosUnidade[i]['Ministradas']; + AlunosUnidade[i]['Encontrado'] = 1; + } + } + } + if (AlunosUnidade[i]['Encontrado'] == 0) { + ListagemAulas.push({ + "idunits": ListaUnidades[Index]['idunits'], + "Unidade": ListaUnidades[Index]['unityname'], + "Matricula": AlunosUnidade[i]['IDMatricula'], + "Curso": AlunosUnidade[i]['Curso'], + "Aulas": 0, + "Pendentes": 0, + "HorasAssistidas": 0, + "Aluno": AlunosUnidade[i]['Nome'], + "Cancelada": AlunosUnidade[i]['Cancelada'], + "Suspensa": AlunosUnidade[i]['Suspensa'], + "Chamadas": 0, + "Ministradas": 0, + }); + } + } + } + Index++; + LoopAlunosSQLServer(ListagemAulas, ListaUnidades, Index, callback); + }) + } + else { + callback(ListagemAulas); + } + } + + router.post('/insertLog', (req, res) => { + const desc = req.body.desc; + console.log(desc); + execSQLQuery(`insert into logs_general (description) + values (?);`, res, req.originalUrl, [desc]); + }); + + router.post('/transferirMatriculas', verifyJWT, (req, res) => { + const Matricula = parseInt(req.body.Matricula); + const idunitsD = parseInt(req.body.idunitsD); + const dbD = req.body.dbD; + const idunitsP = parseInt(req.body.idunitsP); + const dbP = req.body.dbP; + + // JUNTAR DADOS DO ALUNO A SER TRANSFERIDO + const SQLDadosAluno = `select distinct + tt.CodigoTurma, + mt.IDClienteResponsavel, + tt.IDTreinando, + pm.IDPreMatricula, + tt.IDMatricula + from ${dbD}TreinandosTurmas tt + inner join ${dbD}Matriculas mt on mt.IDMatricula = tt.IDMatricula + inner join ${dbD}PreMatricula pm on pm.IDPreMatricula = mt.IDPreMatricula + where tt.IDMatricula = ${Matricula};`; + //console.log(SQLDadosAluno); + sqlServerConnection.request().query(SQLDadosAluno, function (error, DadosAluno, fields) { + DadosAluno = DadosAluno['recordset'][0]; + // CRIAR E ABASTECER AS TABELAS A SEREM MIGRADAS + AdicionarTabelas(dbD, dbP, DadosAluno, function(success) { + // MONTAR E EXECUTAR SQL DE INSERT + MontaSQLInserts(dbP, DadosAluno, 0, 0, function(Sucesso) { + // CASO DE ALGUM ERRO NO PROCESSO, PARA A EXECUCAO + if (!Sucesso) { + res.send(DadosAluno); + return; + } + // REMOVER DADOS DUPLICADOS PARA MATRICULAS TREINANDOS + const SQLRemoverDuplicados = `SELECT + IDMatricula, + IDTreinando, + CodigoTurma, + COUNT(*) AS CNT + FROM ${dbP}MatriculasTreinandos + GROUP BY IDMatricula, IDTreinando, CodigoTurma + HAVING COUNT(*) > 1;`; + sqlServerConnection.request().query(SQLRemoverDuplicados, function (error, results, fields) { + console.log("Consulta de duplicados concluida com SUCESSO"); + const Duplicados = results['recordset']; + let SQLDeleteDup = `delete from ${dbP}MatriculasTreinandos where `; + let SQLInsertDup = `insert into ${dbP}MatriculasTreinandos (IDMatricula, IDTreinando, CodigoTurma) values `; + for (let i = 0; i < Duplicados.length; i++) { + if (i > 0) { + SQLInsertDup += `, `; + SQLDeleteDup += ` or `; + } + SQLInsertDup += `(${Duplicados[i]['IDMatricula']}, ${Duplicados[i]['IDTreinando']}, ${Duplicados[i]['CodigoTurma']})`; + SQLDeleteDup += `(IDMatricula = ${Duplicados[i]['IDMatricula']} and IDTreinando = ${Duplicados[i]['IDTreinando']} and CodigoTurma = ${Duplicados[i]['CodigoTurma']})`; + } + // REMOVER DUPLICADOS + sqlServerConnection.request().query(SQLDeleteDup, function (error, results2, fields) { + if (error) console.log("ERRO ao remover duplicados"); + else console.log("Remover duplicados concluido com SUCESSO"); + // INSERIR REGISTROS CORRETOS + sqlServerConnection.request().query(SQLInsertDup, function (error, results2, fields) { + if (error) console.log("ERRO ao incluir TreinandosTurmas"); + else console.log("Incluir TreinandosTurmas concluido com SUCESSO"); + // ATUALIZAR UNIDADE E MATRICULA NA TABELA STEPCLASS + const SQLStepClass = `update stepclass set idunits = ${idunitsP}, idusers = ${DadosAluno.Tabelas[21].Dados[0]['IDMatricula']} where idunits = ${idunitsD} and idusers = ${Matricula};`; + mysqlConnection.query(SQLStepClass, function (errorSC, resultsSC, fieldsSC) { + if (errorSC) console.log("ERRO ao atualizar STEPCLASS"); + else console.log("STEPCLASS atualizado com SUCESSO"); + // ATUALIZAR UNIDADE E MATRICULA NA TABELA USERGIVENASNWERS + const SQLUserGivenAnswers = `update usergivenanswers set idunits = ${idunitsP}, idusers = ${DadosAluno.Tabelas[21].Dados[0]['IDMatricula']} where idunits = ${idunitsD} and idusers = ${Matricula};`; + mysqlConnection.query(SQLUserGivenAnswers, function (errorUG, resultsUG, fieldsUG) { + if (errorUG) console.log("ERRO ao atualizar USERGIVENANSWERS"); + else console.log("USERGIVENANSWERS atualizado com SUCESSO"); + // ATUALIZAR UNIDADE E MATRICULA NA TABELA USERSTAGES + const SQLUserStages = `update userstages set idunits = ${idunitsP}, idusers = ${DadosAluno.Tabelas[21].Dados[0]['IDMatricula']} where idunits = ${idunitsD} and idusers = ${Matricula};`; + mysqlConnection.query(SQLUserStages, function (errorUS, resultsUS, fieldsUS) { + if (errorUS) console.log("ERRO ao atualizar USERSTAGES"); + else console.log("USERSTAGES atualizado com SUCESSO"); + // ATUALIZAR UNIDADE E MATRICULA NA TABELA QRCODES + const SQLQRCode = `update qrcodes set idunits = ${idunitsP}, idusers = ${DadosAluno.Tabelas[21].Dados[0]['IDMatricula']} where idunits = ${idunitsD} and idusers = ${Matricula};`; + mysqlConnection.query(SQLQRCode, function (errorQR, resultsQR, fieldsQR) { + if (errorQR) console.log("ERRO ao atualizar QRCODE"); + else console.log("QRCODE atualizado com SUCESSO"); + // ATUALIZAR UNIDADE E MATRICULA NA TABELA BARCODES + const SQLBarCode = `update barcodes set idunits = ${idunitsP}, idusers = ${DadosAluno.Tabelas[21].Dados[0]['IDMatricula']} where idunits = ${idunitsD} and idusers = ${Matricula};`; + mysqlConnection.query(SQLBarCode, function (errorBC, resultsBC, fieldsBC) { + if (errorBC) console.log("ERRO ao atualizar BARCODE"); + else console.log("BARCODE atualizado com SUCESSO"); + // TRANCAR ALUNO NA UNIDADE ANTERIOR + const SQLPreRequerimento = `insert into ${dbD}PreRequerimento (IDTreinando, IDMatricula, Data, IDFuncionario, IDTurma, TipoRequerimento, TipoRequerimentoAnt, Status, IDMotivo, DescricaoMotivo) values + (${DadosAluno.IDTreinando}, ${DadosAluno.IDMatricula}, '2021-02-19', 1250, 0, 'T', 'T', 'C', 6, 'Aluno transferido para outra unidade');`; + sqlServerConnection.request().query(SQLPreRequerimento, function (error, resPR, fields) { + if (error) console.log("ERRO ao criar PreRequerimento"); + else console.log("PreRequerimento criado com sucesso"); + const SQLGetIDs = `select + coalesce((select top(1) IdTransferencia from ${dbD}Transferencias order by IdTransferencia desc), 0) + 1 as 'IDTransferencia', + coalesce((select top(1) IDPreRequerimento from ${dbD}PreRequerimento order by IDPreRequerimento desc), 1) as 'IDPreRequerimento';`; + sqlServerConnection.request().query(SQLGetIDs, function (error, resIDs, fields) { + if (error) console.log("ERRO ao reunir IDs para Transferencia"); + else console.log("Reunido IDs para Transferencia com SUCESSO"); + const IDs = resIDs['recordset'][0]; + const SQLTransferencia = `insert into ${dbD}Transferencias (IdTransferencia, IDTreinando, IDMatricula, DataTransferencia, Motivo, CobrarTaxa, ValorTaxa, VencimentoTaxa, FuncionarioResponsavel, ObsAviso, TipoTransferencia, ParcelasTaxa, IDMotivo, IDPreRequerimento) values + (${IDs.IDTransferencia}, ${DadosAluno.IDTreinando}, ${DadosAluno.IDMatricula}, '2021-02-19', 'Aluno transferido para outra unidade', 0, 0, '2021-02-19', 1250, '', 'T', 1, 6, ${IDs.IDPreRequerimento});`; + sqlServerConnection.request().query(SQLTransferencia, function (error, resTransf, fields) { + if (error) console.log("ERRO ao criar Transferencia"); + else console.log("Transferencia criada com sucesso"); + let SQLTransfDet = `insert into ${dbD}TransferenciasDetalhe (IDTransferencia, IDCurso, CodigoTurma, IDTreinando) values `; + for (let i = 0; i < DadosAluno.Tabelas[22].Dados.length; i++) { + if (i > 0) + SQLTransfDet += `, `; + SQLTransfDet += `(${IDs.IDTransferencia}, ${DadosAluno.Tabelas[22].Dados[i].IDCurso}, ${DadosAluno.CodigoTurma}, ${DadosAluno.IDTreinando})`; + } + sqlServerConnection.request().query(SQLTransfDet, function (error, resTransfDet, fields) { + if (error) console.log("ERRO ao criar TransferenciaDetalhes"); + else console.log("TransferenciaDetalhes criado com sucesso"); + const SQLRemoverTurma = `update ${dbD}TreinandosTurmas set CodigoTurma = 0 where IDMatricula = ${DadosAluno.IDMatricula} and IDTreinando = ${DadosAluno.IDTreinando};`; + sqlServerConnection.request().query(SQLRemoverTurma, function (error, resRemTurma, fields) { + if (error) console.log("ERRO ao setar CodigoTurma = 0 em TreinandosTurmas"); + else console.log("CodigoTurma = 0 realizado com sucesso"); + res.send(DadosAluno); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + + }); + + }); + + function AdicionarTabelas(dbD, dbP, DadosAluno, callback) { + let Tabelas = []; + let Campos0 = [{"Forcar": true, "CampoP": "IDFuncionario", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "Turmas", "IdTurma", `IdTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos0, true, function(Success) { + let Campos1 = [{"Forcar": true, "CampoP": "IDAtendente", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "Atendimentos", "IdAtendimento", `select at.* from ${dbD}Atendimentos at inner join ${dbD}Matriculas mt on mt.IDAtendimento = at.IdAtendimento where mt.IDMatricula = ${DadosAluno['IDMatricula']};`, Tabelas, Campos1, true, function(Success) { + let Campos2 = [{"IdxT": 1, "IdxD": 0, "CampoD": "IdAtendimento", "CampoP": "IdAtendimento", "Seq": true}, {"Forcar": true, "CampoP": "IDFuncionarioCadastro", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "AtendimentosCabecalho", "", `select ac.* from ${dbD}AtendimentosCabecalho ac inner join ${dbD}Matriculas mt on mt.IDAtendimento = ac.IdAtendimento where mt.IDMatricula = ${DadosAluno['IDMatricula']};`, Tabelas, Campos2, true, function(Success) { + let Campos3 = [{"IdxT": 1, "IdxD": 0, "CampoD": "IdAtendimento", "CampoP": "IDAtendimento", "Seq": true}, {"Forcar": true, "CampoP": "IDAtendente", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "AtendimentosComissoes", "", `select ac.* from ${dbD}AtendimentosComissoes ac inner join ${dbD}Matriculas mt on mt.IDAtendimento = ac.IdAtendimento where mt.IDMatricula = ${DadosAluno['IDMatricula']};`, Tabelas, Campos3, true, function(Success) { + let Campos4 = [{"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IdTurma", "Seq": false}, {"Forcar": true, "CampoP": "IDFuncionarioInstrutor", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "AtendimentosFuncionarios", "", `IdTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos4, false, function(Success) { + let Campos5 = [{"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IDTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "Notas", "", `IDTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos5, true, function(Success) { + let Campos6 = [{"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IdTurma", "Seq": false}, {"Forcar": true, "CampoP": "IDFuncionario", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "TransacoesTurmas", "IDTransacao", `IdTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos6, true, function(Success) { + let Campos7 = [{"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IdTurma", "Seq": false}, {"Forcar": true, "CampoP": "CodigoInstrutor", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "TransacoesTurmasCalendario", "", `IdTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos7, true, function(Success) { + let Campos8 = [{"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IDTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "TransacoesTurmasDetalhe", "", `IdTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos8, true, function(Success) { + let Campos9 = [{"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IdTurma", "Seq": false}, {"Forcar": true, "CampoP": "IdInstrutor", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "TurmasAgendaCalendario", "IdTurmasAgendaCalendario", `IdTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos9, true, function(Success) { + let Campos10 = [{"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IDTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "TurmasDetalhe", "", `IdTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos10, true, function(Success) { + let Campos11 = [{"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IdTurma", "Seq": false}, {"Forcar": true, "CampoP": "CodigoInstrutor", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "TurmasCalendario", "IdTurmasCalendario", `IdTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos11, true, function(Success) { + let Campos12 = [{"Forcar": true, "CampoP": "FuncionarioCadastro", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "Clientes", "IDCliente", `IDCliente in (${DadosAluno['IDClienteResponsavel']}, ${DadosAluno['IDTreinando']});`, Tabelas, Campos12, true, function(Success) { + let Campos13 = [{"IdxT": 12, "IdxD": 0, "CampoD": "IDCliente", "CampoP": "IDResponsavel", "Seq": false}, {"Forcar": true, "CampoP": "IDFuncionario", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "PreMatricula", "IDPreMatricula", `IDPreMatricula = ${DadosAluno['IDPreMatricula']}`, Tabelas, Campos13, true, function(Success) { + let Campos14 = [{"IdxT": 13, "IdxD": 0, "CampoD": "IDPreMatricula", "CampoP": "IDPreMatricula", "Seq": false}, {"IdxT": 12, "IdxD": (Tabelas[12].Dados.length - 1), "CampoD": "IDCliente", "CampoP": "IDTreinando", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "PreMatriculaTreinandos", "", `IDPreMatricula = ${DadosAluno['IDPreMatricula']}`, Tabelas, Campos14, true, function(Success) { + let Campos15 = [{"IdxT": 13, "IdxD": 0, "CampoD": "IDPreMatricula", "CampoP": "IDPreMatricula", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "PreMatriculaParcelas", "", `IDPreMatricula = ${DadosAluno['IDPreMatricula']}`, Tabelas, Campos15, true, function(Success) { + let Campos16 = [{"IdxT": 13, "IdxD": 0, "CampoD": "IDPreMatricula", "CampoP": "IDPreMatricula", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "PreMatriculaFinanceiroMaterial", "", `IDPreMatricula = ${DadosAluno['IDPreMatricula']}`, Tabelas, Campos16, true, function(Success) { + let Campos17 = [{"IdxT": 13, "IdxD": 0, "CampoD": "IDPreMatricula", "CampoP": "IDPreMatricula", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IDTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "PreMatriculaCursos", "", `IDPreMatricula = ${DadosAluno['IDPreMatricula']}`, Tabelas, Campos17, true, function(Success) { + let Campos18 = [{"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IDTurma", "Seq": false}, {"Forcar": true, "CampoP": "IDInstrutor", "Valor": 1250}, {"Forcar": true, "CampoP": "IDFuncionarioAPP", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "Chamadas", "IDChamadas", `IDTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos18, true, function(Success) { + let Campos19 = [{"IdxT": 18, "IdxD": 0, "CampoD": "IDChamadas", "CampoP": "IDChamadas", "Seq": true}]; + PreencheDadosTabela(dbD, dbP, 0, "ChamadasConteudos", "", `select cd.* from ${dbD}Chamadas ch inner join ${dbD}ChamadasConteudos cd on cd.IDChamadas = ch.IDChamadas where ch.IDTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos19, true, function(Success) { + let Campos20 = [{"IdxT": 18, "IdxD": 0, "CampoD": "IDChamadas", "CampoP": "IDChamadas", "Seq": true}, {"IdxT": 12, "IdxD": (Tabelas[12].Dados.length - 1), "CampoD": "IDCliente", "CampoP": "IDTreinando", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "ChamadasDetalhes", "", `select cd.* from ${dbD}Chamadas ch inner join ${dbD}ChamadasDetalhes cd on cd.IDChamadas = ch.IDChamadas where ch.IDTurma = ${DadosAluno['CodigoTurma']}`, Tabelas, Campos20, true, function(Success) { + let Campos21 = [{"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "CodigoTurma", "Seq": false}, {"IdxT": 12, "IdxD": 0, "CampoD": "IDCliente", "CampoP": "IDClienteResponsavel", "Seq": false}, {"IdxT": 1, "IdxD": 0, "CampoD": "IdAtendimento", "CampoP": "IDAtendimento", "Seq": false}, {"IdxT": 13, "IdxD": 0, "CampoD": "IDPreMatricula", "CampoP": "IDPreMatricula", "Seq": false}, {"Forcar": true, "CampoP": "FuncionarioVenda", "Valor": 1250}, {"Forcar": true, "CampoP": "FuncionarioCadastro", "Valor": 1250}]; + let Ano = (new Date().getFullYear() - 2000) * 10000; + PreencheDadosTabela(dbD, dbP, Ano, "Matriculas", "IDMatricula", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos21, true, function(Success) { + let Campos22 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 12, "IdxD": (Tabelas[12].Dados.length - 1), "CampoD": "IDCliente", "CampoP": "IDTreinando", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "CodigoTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "TreinandosTurmas", "", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos22, true, function(Success) { + let Campos23 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 12, "IdxD": (Tabelas[12].Dados.length - 1), "CampoD": "IDCliente", "CampoP": "IDTreinando", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IDTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "TreinandosTurmasMateriais", "", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos23, true, function(Success) { + let Campos24 = [{"Ignorar": true, "CampoP": "NumeroProva"}, {"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 12, "IdxD": (Tabelas[12].Dados.length - 1), "CampoD": "IDCliente", "CampoP": "IDTreinando", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IDTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "NotasDetalhesSequencial", "NumeroProva", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos24, true, function(Success) { + let Campos25 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 12, "IdxD": (Tabelas[12].Dados.length - 1), "CampoD": "IDCliente", "CampoP": "IDTreinando", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IDTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "NotasDetalhes", "", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos25, true, function(Success) { + let Campos26 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 12, "IdxD": (Tabelas[12].Dados.length - 1), "CampoD": "IDCliente", "CampoP": "IDTreinando", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "CodigoTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "MatriculasTreinandos", "", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos26, true, function(Success) { + let Campos27 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "MatriculasProdutos", "", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos27, true, function(Success) { + let Campos28 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "CodigoTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "MatriculasCursos", "", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos28, true, function(Success) { + let Campos29 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 12, "IdxD": (Tabelas[12].Dados.length - 1), "CampoD": "IDCliente", "CampoP": "IDTreinando", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "CodigoTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "HistoricoTreinandosTurmas", "", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos29, true, function(Success) { + let Campos30 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 12, "IdxD": 0, "CampoD": "IDCliente", "CampoP": "IDClienteResponsavel", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "CodigoTurma", "Seq": false}, {"Forcar": true, "CampoP": "FuncionarioCadastro", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "HistoricoMatriculas", "", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos30, true, function(Success) { + let Campos31 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 12, "IdxD": (Tabelas[12].Dados.length - 1), "CampoD": "IDCliente", "CampoP": "IDTreinando", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IDTurma", "Seq": false}, {"Forcar": true, "CampoP": "IDFuncionario", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "HistoricoFaltas", "IDHistFalta", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos31, true, function(Success) { + let Campos32 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 12, "IdxD": (Tabelas[12].Dados.length - 1), "CampoD": "IDCliente", "CampoP": "IDTreinando", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IDTurma", "Seq": false}, {"Forcar": true, "CampoP": "IDFuncionario", "Valor": 1250}]; + PreencheDadosTabela(dbD, dbP, 0, "HistoricoEvadidos", "", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos32, true, function(Success) { + let Campos33 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 12, "IdxD": (Tabelas[12].Dados.length - 1), "CampoD": "IDCliente", "CampoP": "IDTreinando", "Seq": false}, {"IdxT": 0, "IdxD": 0, "CampoD": "IdTurma", "CampoP": "IDTurma", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "Evadidos", "", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos33, true, function(Success) { + let Campos34 = [{"IdxT": 21, "IdxD": 0, "CampoD": "IDMatricula", "CampoP": "IDMatricula", "Seq": false}, {"IdxT": 12, "IdxD": 0, "CampoD": "IDCliente", "CampoP": "Cliente", "Seq": false}]; + PreencheDadosTabela(dbD, dbP, 0, "ContasReceber", "IDContasReceber", `IDMatricula = ${DadosAluno['IDMatricula']}`, Tabelas, Campos34, true, function(Success) { + DadosAluno['Tabelas'] = Tabelas; + callback(true); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + + }); + } + + function PreencheDadosTabela(dbD, dbP, AcrescimoID, NomeTabela, IDTabela, Consulta, Tabelas, CamposReplace, ErroCritico, callback) { + let Query = ``; + if (Consulta[0] == "s") + Query = Consulta; + else + Query = `select * from ${dbD}${NomeTabela} where ${Consulta};` + sqlServerConnection.request().query(Query, function (error, Dados, fields) { + const SQLID = (IDTabela != "") ? `select top(1) (${IDTabela} + 1) as 'ID' from ${dbP}${NomeTabela} order by ${IDTabela} desc;` : "select 0 as 'ID';"; + sqlServerConnection.request().query(SQLID, function (error, ID, fields) { + ID = (ID['recordset'].length > 0) ? ID['recordset'][0]['ID'] : (1 + AcrescimoID); + if (Dados) { + Dados = Dados['recordset']; + + for (let i = 0; i < Dados.length; i++) { + if (IDTabela != "") + Dados[i][IDTabela] = (ID + i); + for (let o = 0; o < CamposReplace.length; o++) { + if (CamposReplace[o].Forcar) { + Dados[i][CamposReplace[o].CampoP] = CamposReplace[o].Valor; + } + else if (!CamposReplace[o].Ignorar) { + Dados[i][CamposReplace[o].CampoP] = Tabelas[CamposReplace[o].IdxT].Dados[CamposReplace[o].IdxD][CamposReplace[o].CampoD] + ((Dados.length > 1 && CamposReplace[o].Seq) ? i : 0); + } + } + } + + Tabelas.push({"Tabela": NomeTabela, "IDTabela": IDTabela, "Dados": Dados, "ProxID": ID, "SQL": "", "CamposReplace": CamposReplace, "ErroCritico": ErroCritico}); + console.log(`Tabela ${NomeTabela} consultada com sucesso`); + } + else { + Tabelas.push({"Tabela": NomeTabela, "IDTabela": IDTabela, "Dados": [], "ProxID": 0, "SQL": "", "CamposReplace": CamposReplace, "ErroCritico": ErroCritico}); + console.log(`Erro ao consultar tabela ${NomeTabela}`); + console.log(Consulta); + //console.log(error); + } + callback(true); + }); + }); + } + + function MontaSQLInserts(dbP, DadosAluno, IndexT, IndexD, callback) { + let ModoInsert = true; + if (IndexT < DadosAluno.Tabelas.length) { + if (IndexD < DadosAluno.Tabelas[IndexT].Dados.length) { + DadosAluno.Tabelas[IndexT]['SQL'] += "insert into " + dbP + DadosAluno.Tabelas[IndexT].Tabela + " ("; + for (let key in DadosAluno.Tabelas[IndexT].Dados[IndexD]) { + if (DadosAluno.Tabelas[IndexT]['SQL'][DadosAluno.Tabelas[IndexT]['SQL'].length - 1] != "(") + DadosAluno.Tabelas[IndexT]['SQL'] += ", "; + let InsereCampo = true; + for (let j = 0; j < DadosAluno.Tabelas[IndexT].CamposReplace.length; j++) { + if (DadosAluno.Tabelas[IndexT].CamposReplace[j].Ignorar && DadosAluno.Tabelas[IndexT].CamposReplace[j].CampoP == key) { + InsereCampo = false; + break; + } + } + if (InsereCampo) + DadosAluno.Tabelas[IndexT]['SQL'] += key; + } + DadosAluno.Tabelas[IndexT]['SQL'] += ") values ("; + for (let key in DadosAluno.Tabelas[IndexT].Dados[IndexD]) { + let InsereCampo = true; + for (let j = 0; j < DadosAluno.Tabelas[IndexT].CamposReplace.length; j++) { + if (DadosAluno.Tabelas[IndexT].CamposReplace[j].Ignorar && DadosAluno.Tabelas[IndexT].CamposReplace[j].CampoP == key) { + InsereCampo = false; + break; + } + } + if (InsereCampo) { + // SE NAO FOR O PRIMEIRO VALOR INSERIDO + if (DadosAluno.Tabelas[IndexT]['SQL'][DadosAluno.Tabelas[IndexT]['SQL'].length - 1] != "(") + DadosAluno.Tabelas[IndexT]['SQL'] += ", "; + // SE FOR DATA + if (DadosAluno.Tabelas[IndexT].Dados[IndexD][key] && (DadosAluno.Tabelas[IndexT].Dados[IndexD][key].toString().includes(" (Horário ") || DadosAluno.Tabelas[IndexT].Dados[IndexD][key].toString().includes(" Time)"))) { + DadosAluno.Tabelas[IndexT].Dados[IndexD][key] = new Date(DadosAluno.Tabelas[IndexT].Dados[IndexD][key].toString()).toISOString().replace('T', ' ').split('.')[0]; + } + if (DadosAluno.Tabelas[IndexT].Dados[IndexD][key] == null) + DadosAluno.Tabelas[IndexT]['SQL'] += "null"; + else + DadosAluno.Tabelas[IndexT]['SQL'] += "'" + DadosAluno.Tabelas[IndexT].Dados[IndexD][key] + "'"; + } + } + DadosAluno.Tabelas[IndexT]['SQL'] += "); "; + IndexD++; + MontaSQLInserts(dbP, DadosAluno, IndexT, IndexD, callback); + } + else { + if (ModoInsert) { + sqlServerConnection.request().query(DadosAluno.Tabelas[IndexT]['SQL'], function (error, Dados, fields) { + if (error && DadosAluno.Tabelas[IndexT].ErroCritico) { + console.log("INSERT SQL EXECUTADO com ERRO na tabela " + DadosAluno.Tabelas[IndexT].Tabela); + console.log(DadosAluno.Tabelas[IndexT]['SQL']); + console.log(error); + callback(false); + return; + } + else { + console.log("INSERT SQL EXECUTADO com SUCESSO na tabela " + DadosAluno.Tabelas[IndexT].Tabela); + } + IndexT++; + IndexD = 0; + setTimeout(() => { + MontaSQLInserts(dbP, DadosAluno, IndexT, IndexD, callback); + }, 300); + }); + } + else { + IndexT++; + IndexD = 0; + MontaSQLInserts(dbP, DadosAluno, IndexT, IndexD, callback); + } + } + } + else { + callback(ModoInsert); + } + } + + router.get('/getOnlineUsers/:tempo/:idunits', (req, res) => { + const Tempo = req.params.tempo; + const idunits = req.params.idunits; + const SQLOnline = `select + concat(un.reference_db, '.dbo.') as 'Banco', + un.unityname as 'Unidade', + co.name as 'Curso', + cl.name as 'Aula', + cl.description as 'Pauta', + sc.idusers as 'Matricula', + case when sc.completedClass = 1 then 'Sim' else 'Não' end as 'Concluida', + date_format(sc.insert_date, '%d/%m/%Y %h:%i') as 'IniciadoEm', + date_format(sc.update_date, '%d/%m/%Y %h:%i') as 'VistoUltimo', + (select count(*) from stepclass sc1 where sc1.idunits = sc.idunits and sc1.insert_date > date_format (now(), '%y-%m-%d')) as 'AulasHoje', + (select count(*) from stepclass sc1 where sc1.insert_date > date_format(now(), '%y-%m-%d')) as 'TotalAulas' + from stepclass sc + inner join units un on un.idunits = sc.idunits + inner join classes cl on cl.idclasses = sc.idclasses + inner join courses co on co.idcourses = cl.idcourses + where ${(idunits == 0) ? 'true' : 'sc.idunits = ' + idunits} and sc.update_date > date_sub(now(), interval ${Tempo} minute) + order by sc.update_date desc;`; + mysqlConnection.query(SQLOnline, function (error, Alunos, fields) { + let SQLNomes = ``; + for (let i = 0; i < Alunos.length; i++) { + if (SQLNomes != ``) + SQLNomes += ` union all `; + SQLNomes += `select distinct + '${Alunos[i].Unidade}' as Unidade, + tt.IDMatricula as 'Matricula', + cl.Nome, + '${Alunos[i].Curso}' as Curso, + '${Alunos[i].Aula}' as Aula, + '${Alunos[i].Concluida}' as Concluida, + '${Alunos[i].IniciadoEm}' as IniciadoEm, + '${Alunos[i].VistoUltimo}' as VistoUltimo + from ${Alunos[i].Banco}TreinandosTurmas tt + inner join ${Alunos[i].Banco}Clientes cl on cl.IDCliente = tt.IDTreinando + where tt.IDMatricula = ${Alunos[i].Matricula}` + } + execSQLQuery2(SQLNomes, res, req.originalUrl); + }); + }); + + + + + + return router; +} + +module.exports = routes; diff --git a/controllers/videoController.js b/controllers/videoController.js new file mode 100644 index 0000000..f9071bb --- /dev/null +++ b/controllers/videoController.js @@ -0,0 +1,427 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +require('../helpers/config'); +const formidable = require('formidable'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +var accessToken = "b78050152a551b71665045f03a2161fa"; +var clientSecret = "VumfHSuZcTIAe6hyvHgrRGv+UVX9xEQlX1HqFgiA+7DDhLIIXt1hjy2mP3Ht/MQyYs++ja8Ok5+aWabRRJ5uGY+dQDIlmZGeWpplffT6VowLOLe6JEYH4OLdmv5sNQtR"; +var clientIDVimeo = "addbd91428cb667f7c5d50e47626ddb8554170cb"; + +router.use(bodyParser.urlencoded({ + parameterLimit: 100000, + limit: '2000mb', + extended: true +})); +router.use(bodyParser.json({ + parameterLimit: 100000, + limit: '2000mb', + extended: true +})); + +const routes = function () { + + router.get('/', verifyJWT, (req, res) => { + execSQLQuery(`SELECT + * + FROM media;`, res, req.originalUrl); + }); + + router.get('/getAllMedia', (req, res) => { + execSQLQuery(`SELECT + * + FROM media;`, res, req.originalUrl); + }); + + router.get('/getMedia/:idmedia', verifyJWT, (req, res) => { + const idmedia = parseInt(req.params.idmedia); + execSQLQuery(`SELECT + * + FROM media + WHERE idmedia = ${idmedia};`, res, req.originalUrl); + }); + + router.get('/viewvideo/:_key', (req, res) => { + var _key = req.params._key; + execSQLQueryVideo(`SELECT * FROM videoaccess WHERE _key = '${_key}' AND expired = 0`, res, req.originalUrl); + }); + + router.post('/insertVA', verifyJWT, (req, res) => { + const idvideoaccess = req.body.idvideoaccess; + const _key = (req.body._key).trim(); + const expired = req.body.expired ? 1 : 0; + const url = req.body.url; + const tag = req.body.tag; + + execSQLQuery(`INSERT INTO videoaccess(_key, expired, url, tag) + VALUES (?, ?, ?, ?);`, res, req.originalUrl, [_key, expired, url, tag]); + }); + + router.patch('/updateVA', verifyJWT, (req, res) => { + const idvideoaccess = req.body.idvideoaccess; + const _key = (req.body._key).trim(); + const expired = req.body.expired ? 1 : 0; + const url = req.body.url; + execSQLQuery(`UPDATE videoaccess SET + _key = ?, + expired = ?, + url = ? + WHERE idvideoaccess = ?;`, res, req.originalUrl, [_key, expired, url, idvideoaccess]); + }); + + router.get('/getVA/:tag', verifyJWT, (req, res) => { + const tag = req.params.tag; + execSQLQuery(`SELECT * FROM videoaccess WHERE tag = '${tag}' AND expired = 0;`, res, req.originalUrl); + }); + + router.post('/insertMedia', verifyJWT, (req, res) => { + const idmedia = req.body.idmedia; + const description = req.body.description; + const publishid = req.body.publishid; + const type = req.body.type; + execSQLQuery(`INSERT INTO media(description, publishid, type) + VALUES (?, ?, ?);`, res, req.originalUrl, [description, publishid, type]); + }); + + router.patch('/updateMedia', verifyJWT, (req, res) => { + const idmedia = req.body.idmedia; + const description = req.body.description; + const publishid = req.body.publishid; + const type = req.body.type; + execSQLQuery(`UPDATE media SET + description = ?, + publishid = ?, + type = ? + WHERE idmedia = ?;`, res, req.originalUrl, [description, publishid, type, idmedia]); + }); + + router.get('/backVideo/:idvideo/:Online', (req, res) => { + var idvideos = req.params.idvideo; + var dir = Variables('src_media') + 'videos/tmp/var/www/html/videos/' + idvideos + '.mp4'; + const fs = require('fs'); + + if (fs.existsSync(dir)) { + console.log("Requisição de vídeo: " + idvideos); + res.send(true); + } + else { + const shell = require('shelljs'); + shell.exec(`unzip -o -P "${Variables('passdecrypt')}" ${Variables('src_media')}videos/${idvideos}.zip -d ${Variables('src_media')}videos/tmp/`, function (ResExtract) { + console.log("RESULTADO: " + ResExtract); + if (ResExtract == 0) { // EXTRAIDO COM SUCESSO + shell.exec(`chmod -R 777 ${Variables('src_media')}videos/tmp/`); + if (fs.existsSync(dir)) { + console.log("Requisição de vídeo: " + idvideos); + res.send(true); + } + else { + res.send(false); + } + } + else { // ERRO AO EXTRAIR ( BAIXA O ARQUIVO DO SERVIDOR E REPRODUZ NO VIMEO ) + shell.exec('cd ' + Variables('src_media') + 'videos/;wget http://18.228.91.135/videos/' + idvideos + '.zip', function (sucesso) { + console.log(sucesso); + }); + res.send(false); + } + }); + /*require('all-unpacker').unpack(Variables('src_media') + 'videos/' + idvideos + '.zip', { + targetDir: Variables('src_media') + 'videos/tmp/', + password: Variables('passdecrypt'), + forceOverwrite: true, + }, function(err, files, text) { + if (err) { + console.error(err); + shell.exec('cd ' + Variables('src_media') + 'videos/;wget http://18.228.91.135/videos/' + idvideos + '.zip', function (sucesso) { + console.log(sucesso); + }); + if (check == 0) { + res.redirect("https://player.vimeo.com/video/" + idvideos); + } + else { + res.send(false); + } + } + if (files) console.log('files', files); + if (text) { + console.log('text', text); + fs.readFile(dir, (err, data) => { + if (err) throw err; + console.log("Requisição de vídeo: " + idvideos); + if (check == 0) { + res.setHeader('Content-Type', 'video/mp4'); + res.send(data); + } + else { + res.send(true); + } + }); + //res.redirect(dir); + }; + });*/ + } + }); + + router.get('/deleteVideo/:publishid', verifyJWT, (req, res) => { + const publishid = req.params.publishid; + let Vimeo = require('vimeo').Vimeo; + let client = new Vimeo(clientIDVimeo, clientSecret, accessToken); + client.request({ + method: 'DELETE', + path: '/videos/' + publishid, + }, function (error, body, status_code, headers) { + mysqlConnection.query(`DELETE FROM media WHERE publishid = '${publishid}';`, function (error, results, fields) { + const fs = require('fs'); + fs.unlink(Variables('src_media') + 'videos/' + publishid + '.zip', function(Sucesso) { + res.send(JSON.stringify({ + "status": 200, + "error": error, + "response": results + })); + console.log(req.originalUrl + "/ success 200"); + }); + }); + }); + }) + + let uploads = {}; + + router.post('/uploadwithProgress', verifyJWT, (req, res, next) => { + let fs = require('fs'); + let fileId = req.headers['x-file-id']; + let startByte = parseInt(req.headers['x-start-byte'], 10); + let name = req.headers['name']; + let fileSize = parseInt(req.headers['size'], 10); + let Copiar = req.headers['Copiar'] || "1"; + let ext = '.mp4'; + console.log('file Size', fileSize, fileId, startByte); + if (uploads[fileId] && fileSize == uploads[fileId].bytesReceived) { + res.end(); + return; + } + console.log(fileSize); + + if (!fileId) { + res.writeHead(400, "No file id"); + res.end(400); + } + console.log(uploads[fileId]); + if (!uploads[fileId]) + uploads[fileId] = {}; + + let upload = uploads[fileId]; //Bytes of file already present + + let fileStream; + + let Caminho = `${Variables('src_media')}videos/`; + let dir = `${Caminho}${name}`; + + //checking bytes of file uploaded and sending to server + if (!startByte) { + upload.bytesReceived = 0; + let name = req.headers['name']; + fileStream = fs.createWriteStream(dir + ext, { + flags: 'w' //with "w"(write stream ) it keeps on adding data + }); + } else { + if (upload.bytesReceived != startByte) {//if same name file is sent with different size it will not upload + res.writeHead(400, "Wrong start byte"); + res.end(upload.bytesReceived); + return; + } + // append to existing file + fileStream = fs.createWriteStream(dir + ext, { + flags: 'a' + }); + } + req.on('data', function (data) { + upload.bytesReceived += data.length; //adding length of data we are adding + }); + req.pipe(fileStream); + // when the request is finished, and all its data is written + fileStream.on('close', function () { + console.log(upload.bytesReceived, fileSize); + if (upload.bytesReceived == fileSize) { + console.log("Upload finished"); + delete uploads[fileId]; + + // can do something else with the uploaded file here + + UploadVimeo(name, dir + ext, function(URI) { + if (URI == false) { + // ERRO + fs.unlink(dir + ext, function(Sucesso) { + res.send({ 'status': 'falhou' }); + res.end(); + }) + } + else { + // SUCESSO + let novoNome = URI.split('/')[2]; + if (Copiar == "1") { + fs.rename(dir + ext, Caminho + novoNome + ext, function(Sucesso) { + zipVideoSync(novoNome, Caminho + novoNome, function(Sucesso) { + res.send({ 'status': 'uploaded', 'uri': URI }); + res.end(); + }); + }) + } + else { + fs.unlink(dir + ext, function(Sucesso) { + res.send({ 'status': 'uploaded', 'uri': URI }); + res.end(); + }) + } + } + }) + + } else { + // connection lost, leave the unfinished file around + console.log("File unfinished, stopped at " + upload.bytesReceived); + res.writeHead(500, "Server Error"); + res.end(); + } + }); + + // in case of I/O error - finish the request + fileStream.on('error', function (err) { + console.log("fileStream error", err); + res.writeHead(500, "File error"); + res.end(); + }); + + }); + + router.get('/status', verifyJWT, (req, res) => { + //console.log('Successfully came'); + //From GET request 3 parameters below and store in variable + let fileId = req.headers['x-file-id']; + let name = req.headers['name']; + let fileSize = parseInt(req.headers['size'], 10); + console.log(name); + if (name) { + try { + let stats = fs.statSync(`${Variables('src_media')}videos/${name}`); //grabs file information and returns + //checking file exists or not + if (stats.isFile()) { + console.log(`fileSize is ${fileSize} and already uploaded file size ${stats.size}`); + if (fileSize == stats.size) { + res.send({ 'status': 'file is present' }) //returns if file exists + return; + } + if (!uploads[fileId]) + uploads[fileId] = {} + console.log(uploads[fileId]); + uploads[fileId]['bytesReceived'] = stats.size;//checks total amount of file uploaded + console.log(uploads[fileId], stats.size); + } + } catch (er) { + + } + + } + let upload = uploads[fileId]; + if (upload) + res.send({ "uploaded": upload.bytesReceived });//returns to FrontEnd amout of bytes uploaded + else + res.send({ "uploaded": 0 }); + + }); + + router.get('/SolucaoProblemas/:publishid/:tentativa', verifyJWT, (req, res) => { + const publishid = req.params.publishid; + const tentativa = parseInt(req.params.tentativa); + const fs = require('fs'); + if (tentativa == 1) { + fs.unlink(Variables('src_media') + 'videos/tmp/var/www/html/videos/' + publishid + '.mp4', function(Sucesso) { + console.log("Video MP4 excluido com sucesso!"); + res.send(true); + }); + } + else { + fs.unlink(Variables('src_media') + 'videos/' + publishid + '.zip', function(Sucesso) { + console.log("Video ZIP excluido com sucesso!"); + fs.unlink(Variables('src_media') + 'videos/tmp/var/www/html/videos/' + publishid + '.mp4', function(Sucesso) { + console.log("Video MP4 excluido com sucesso!"); + res.send(true); + }); + }); + } + }); + + return router; +}; + +function UploadVimeo(description, oldpath, callback) { + let Vimeo = require('vimeo').Vimeo; + let client = new Vimeo(clientIDVimeo, clientSecret, accessToken); + client.upload( + oldpath, + { + 'name': description, + 'description': description + }, + function (uri) { + console.log('Your video URI is: ' + uri); + callback(uri); + }, + function (bytes_uploaded, bytes_total) { + var percentage = (bytes_uploaded / bytes_total * 100).toFixed(2) + console.log(bytes_uploaded, bytes_total, percentage + '%') + }, + function (error) { + console.log('Failed because: ' + error) + callback(false); + }) +} + +function zipVideoSync(name, dir, callback) { + const fs = require('fs'); + require('all-unpacker').pack(Variables('src_media') + 'videos/' + name + '.zip', { + targetDir: Variables('src_media') + 'videos/' + name + '.mp4', + password: Variables('passdecrypt'), + }, function(err, files, text) { + if (err) return console.error(err); + if (files) console.log('files', files); + if (text) { + console.log('text', text); + if(fs.unlinkSync(dir + '.mp4')) + console.log("Falha ao excluir"); + else + console.log("Excluído com sucesso!"); + callback(true); + }; + }); +} + +module.exports = routes; + +/* + //função pack - inserida no index.js da biblioteca all-unpacker// + + unpackAll.pack = function pack(archiveFile, options, callback) { + if (!callback) return new Error('No callback function'); + if (!archiveFile) archiveFile = options.archiveFile; + if (!archiveFile) return callback(Error("Error: archiveFile or options.archiveFile missing."), null); + if (!options) options = {}; + + var unar = options.unar; + if (!unar) unar = (process.platform != "linux") ? path.join(__dirname,'zip') : 'zip'; + var ar = [unar]; + + if (options.password) { + ar.push('-P'); + ar.push(options.password); + } + + ar.push('SOURCEFILE'); + + var targetDir = options.targetDir; + ar.push(targetDir); + + var cmd = quote(ar).replace('SOURCEFILE', archiveFile); + exec_unar(cmd, targetDir, callback); + }; + */ \ No newline at end of file diff --git a/controllers/visitasController.js b/controllers/visitasController.js new file mode 100644 index 0000000..3b526d3 --- /dev/null +++ b/controllers/visitasController.js @@ -0,0 +1,427 @@ +require('../connections/mysql-server'); +require('../helpers/CheckToken'); +const express = require('express'); +const router = express.Router(); +const bodyParser = require('body-parser'); + +router.use(bodyParser.urlencoded({ extended: true })); +router.use(bodyParser.json()); + +var routes = function () { + + router.get('/getAllFormasAtendimento/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT + * + FROM ${db}FormasAtendimento where IDFormaAtendimento > 100;`, res, req.originalUrl); + }); + + router.get('/getAllVeiculos/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT + * + FROM ${db}Veiculos where IDVeiculo > 100;`, res, req.originalUrl); + }); + + router.get('/getAllProdutosVendas/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT + * + FROM ${db}ProdutosVendas where IDProduto > 100;`, res, req.originalUrl); + }); + + router.get('/getAllResultadosAtendimento/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT + * + FROM ${db}ResultadosAtendimento where IDResultadoAtendimento > 100;`, res, req.originalUrl); + }); + + router.get('/getAllFuncionarios/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT + * + FROM ${db}Funcionarios;`, res, req.originalUrl); + }); + + router.post('/CadastrarControleDeVisita/:db', verifyJWT, (req, res) => { + const db = req.params.db; + const IDControle = parseInt(req.body.IDControle); + const IDFormaAtendimento = parseInt(req.body.IDFormaAtendimento); + const IDVeiculo = parseInt(req.body.IDVeiculo); + const IDProduto = parseInt(req.body.IDProduto); + const IDFuncionario = parseInt(req.body.IDFuncionario); + const Nome = req.body.Nome; + const Telefone = req.body.Telefone; + const CursoPraVoce = req.body.CursoPraVoce ? 1 : 0; + const Concluido = req.body.Concluido ? 1 : 0; + const CursoPraQuem = req.body.CursoPraQuem; + const Observacao = req.body.Observacao; + const Data = req.body.Data; + const Hora = req.body.Hora; + const PessoaFisica = req.body.PessoaFisica ? 1 : 0; + const IDPessoa = parseInt(req.body.IDPessoa); + const IDFuncionarioTelemarketing = parseInt(req.body.IDFuncionarioTelemarketing); + const IDAtendimento = parseInt(req.body.IDAtendimento) || 0; + const Celular = req.body.Celular; + const Email = req.body.Email; + + execSQLQuery2(`INSERT INTO ${db}ControleAtendimento (IDControle, IDFormaAtendimento, IDVeiculo, IDProduto, IDFuncionario, Nome, Telefone, CursoPraVoce, Concluido, CursoPraQuem, Observacao, Data, Hora, PessoaFisica, IDPessoa, IDFuncionarioTelemarketing, IDAtendimento, Celular, Email) + VALUES (${IDControle}, ${IDFormaAtendimento}, ${IDVeiculo}, ${IDProduto}, ${IDFuncionario}, '${Nome}', '${Telefone}', ${CursoPraVoce}, ${Concluido}, '${CursoPraQuem}', '${Observacao}', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, ${PessoaFisica}, ${IDPessoa}, ${IDFuncionarioTelemarketing}, ${IDAtendimento}, '${Celular}', '${Email}');`, res, req.originalUrl); + }); + + router.patch('/AtualizarControleDeVisita/:db', verifyJWT, (req, res) => { + const db = req.params.db; + const IDControle = parseInt(req.body.IDControle); + const IdAtendimento = parseInt(req.body.IDAtendimento); + execSQLQuery2(`UPDATE ${db}ControleAtendimento SET IDAtendimento = ${IdAtendimento} WHERE IDControle = ${IDControle};`, res, req.originalUrl); + }); + + router.post('/CadastrarPessoa/:db', verifyJWT, (req, res) => { + const db = req.params.db; + const IDPessoa = parseInt(req.body.IDPessoa); + const IDFuncionarioCadastro = parseInt(req.body.IDFuncionarioCadastro); + const Nome = req.body.Nome; + const FoneResidencial = req.body.FoneResidencial; + const Celular = req.body.Celular; + + execSQLQuery2(`INSERT INTO ${db}Pessoas (IDPessoa, IDResponsavel, IDFuncionarioCadastro, IDCupom, IDOrigemCadastro, Nome, NomeFantasia, Sexo, DataNascimento, Endereco, Complemento, Bairro, Cidade, CEP, UF, FoneResidencial, FoneComercial, Celular, Fax, CPF, RG, CGC, InscricaoEstadual, Profissao, EmpresaTrabalha, EnderecoEmpresa, BairroEmpresa, CidadeEmpresa, CEPEmpresa, UFEmpresa, NomePai, NomeMae, NomeConjugue, e_mail, Data, DataRetorno, ResponsavelEmpresa, Contato, PessoaFisica) + VALUES (${IDPessoa}, 0, ${IDFuncionarioCadastro}, 0, 0, '${Nome}', null, '', '1900-01-01', '', null, '', '', '', '', '${FoneResidencial}', '', '${Celular}', null, '', '', null, null, '', '', '', '', '', '', '', '', '', '', '', CURRENT_TIMESTAMP, null, null, null, 1);`, res, req.originalUrl); + }); + + router.post('/CadastrarAtendimento/:db', verifyJWT, (req, res) => { + const db = req.params.db; + const IdAtendimento = parseInt(req.body.IdAtendimento); + const IDAtendente = parseInt(req.body.IDAtendente); + const Resumo = req.body.Resumo; + const IDFormaAtendimento = parseInt(req.body.IDFormaAtendimento); + const IDResultadoAtendimento = parseInt(req.body.IDResultadoAtendimento); + const ProximoRetorno = req.body.ProximoRetorno; + const Finalizado = req.body.Finalizado ? 1 : 0; + const Concluido = req.body.Concluido ? 1 : 0; + const DataVisita = req.body.DataVisita; + + const SQLInsert = `INSERT INTO ${db}Atendimentos (IdAtendimento, IDAtendente, DataHora, Data, Hora, Resumo, IDFormaAtendimento, IDResultadoAtendimento, ProximoRetorno, DataVisita, Finalizado, Concluido, IDFuncionarioCadastro) VALUES (${IdAtendimento}, ${IDAtendente}, CURRENT_TIMESTAMP, null, null, '${Resumo}', ${IDFormaAtendimento}, ${IDResultadoAtendimento}, ${(ProximoRetorno) ? "'" + ProximoRetorno + "'" : null}, '${DataVisita}', ${Finalizado}, ${Concluido}, null);`; + console.log(SQLInsert); + execSQLQuery2(SQLInsert, res, req.originalUrl); + }); + + router.post('/CadastrarAtendimentosCabecalho/:db', verifyJWT, (req, res) => { + const db = req.params.db; + const IdAtendimento = parseInt(req.body.IdAtendimento); + const IDPessoa = parseInt(req.body.IDPessoa); + const IDResultadoAtendimento = parseInt(req.body.IDResultadoAtendimento); + const ProximoRetorno = req.body.ProximoRetorno; + const Concluido = req.body.Concluido ? 1 : 0; + const IDFuncionarioCadastro = parseInt(req.body.IDFuncionarioCadastro); + + execSQLQuery2(`INSERT INTO ${db}AtendimentosCabecalho (IdAtendimento, IDPessoa, IDResultadoAtendimento, ProximoRetorno, DataAtendimento, Concluido, SemInteresse, NivelInteresse, IDFuncionarioCadastro, IDTipoCurso, IDMatricula, Automatico) VALUES (${IdAtendimento}, ${IDPessoa}, ${IDResultadoAtendimento}, ${(ProximoRetorno) ? "'" + ProximoRetorno + "'" : null}, CURRENT_TIMESTAMP, ${Concluido}, 0, 0, ${IDFuncionarioCadastro}, 0, null, 0);`, res, req.originalUrl); + if (IDResultadoAtendimento == 102) { + sqlServerConnection.request().query(`update ${db}AtendimentosCabecalho set Concluido = 1 where IdAtendimento = ${IdAtendimento};`, function (error, results, fields) { + console.log("Fechou Matrícula"); + }); + } + }); + + router.post('/CadastrarPessoasProdutos/:db', verifyJWT, (req, res) => { + const db = req.params.db; + const IDProduto = parseInt(req.body.IDProduto); + const IDPessoa = parseInt(req.body.IDPessoa); + + execSQLQuery2(`INSERT INTO ${db}PessoasProdutos (IDPessoa, IDProduto) VALUES (${IDPessoa}, ${IDProduto});`, res, req.originalUrl); + }); + + router.get('/getAllControleAtendimento/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT + * + FROM ${db}ControleAtendimento + ORDER BY IDControle ASC;`, res, req.originalUrl); + }); + + router.get('/getAllPessoas/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT + * + FROM ${db}Pessoas + ORDER BY IDPessoa ASC;`, res, req.originalUrl); + }); + + router.get('/getAllAtendimentos/:db', verifyJWT, (req, res) => { + const db = req.params.db; + execSQLQuery2(`SELECT + * + FROM ${db}Atendimentos + ORDER BY IdAtendimento ASC;`, res, req.originalUrl); + }); + + router.post('/CadastrarVeiculo/:db', verifyJWT, (req, res) => { + const db = req.params.db; + const IDVeiculo = parseInt(req.body.IDVeiculo); + const Descricao = req.body.Descricao; + + execSQLQuery2(`INSERT INTO ${db}Veiculos (IDVeiculo, Descricao) VALUES (${IDVeiculo}, '${Descricao}');`, res, req.originalUrl); + }); + + router.post('/getVisitasCadastradas/:db', verifyJWT, (req, res) => { + const IDFuncionario = parseInt(req.body.IDFuncionario); + const DataInicial = req.body.DataInicial; + const DataFinal = req.body.DataFinal; + const Tipo = req.body.Tipo; + const db = req.params.db; + let SQLServerQuery = `select distinct * from ( + select distinct + ctd.IDControle, + --ctd.IDFormaAtendimento, + ctd.IDProduto, + ctd.IDPessoa, + ctd.IDVeiculo, + rat.Descricao as 'Resultado', + --fat.Descricao as 'FormaAtendimento', + --vei.Descricao as 'Divulgacao', + --pv.Descricao as 'Curso', + --fun.Nome as 'Funcionario', + ctd.Nome as 'Cliente', + ctd.Celular as 'Celular', + (convert(varchar, ctd.Data, 103) + ' ' + convert(varchar, ctd.Data, 8)) as 'DataL', + (convert(varchar, atd.ProximoRetorno, 103) + ' ' + convert(varchar, atd.ProximoRetorno, 8)) as 'Retorno', + ctd.Data, + atd.ProximoRetorno, + ctd.Observacao + /*from ${db}ControleAtendimento ctd + left join ${db}Atendimentos atd on atd.IdAtendimento = ctd.IDAtendimento and convert(varchar, atd.Data, 120) = convert(varchar, ctd.Data, 120) + left join ${db}PessoasProdutos pp on pp.IDPessoa = ctd.IDPessoa + left join ${db}ProdutosVendas pv on pv.IDProduto = ctd.IDProduto + left join ${db}ResultadosAtendimento rat on rat.IDResultadoAtendimento = atd.IDResultadoAtendimento + inner join ${db}FormasAtendimento fat on fat.IDFormaAtendimento = ctd.IDFormaAtendimento + inner join ${db}Veiculos vei on vei.IDVeiculo = ctd.IDVeiculo + inner join ${db}Funcionarios fun on fun.IDFuncionario = ctd.IDFuncionario*/ + from ${db}ControleAtendimento ctd + left join ${db}Atendimentos atd on atd.IdAtendimento = ctd.IDAtendimento and convert(varchar, atd.DataVisita, 100) = convert(varchar, ctd.Data, 100) + --inner join ${db}PessoasProdutos pp on pp.IDPessoa = ctd.IDPessoa + --inner join ${db}ProdutosVendas pv on pv.IDProduto = pp.IDProduto + inner join ${db}ResultadosAtendimento rat on rat.IDResultadoAtendimento = atd.IDResultadoAtendimento + --inner join ${db}FormasAtendimento fat on fat.IDFormaAtendimento = ctd.IDFormaAtendimento + --inner join ${db}Veiculos vei on vei.IDVeiculo = ctd.IDVeiculo + --inner join ${db}Funcionarios fun on fun.IDFuncionario = ctd.IDFuncionario + where ${(IDFuncionario > 0) ? ('(ctd.IDFuncionarioTelemarketing = ' + IDFuncionario + ' or ctd.IDFuncionario = ' + IDFuncionario + ' or atd.IDAtendente = ' + IDFuncionario + ')') : '1=1'} and ${(DataInicial == null || DataFinal == null) ? '1=1' : Tipo + " between '" + DataInicial + " 00:00' and '" + DataFinal + " 23:59'"} + + union all + + select distinct + (select top 1 ctd2.IDControle from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'IDControle', + (select top 1 ctd2.IDProduto from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'IDProduto', + (select top 1 ctd2.IDPessoa from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'IDPessoa', + (select top 1 ctd2.IDVeiculo from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'IDVeiculo', + rat.Descricao as 'Resultado', + (select top 1 ctd2.Nome from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'Cliente', + (select top 1 ctd2.Celular from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'Celular', + (select top 1 (convert(varchar, ctd2.Data, 103) + ' ' + convert(varchar, ctd2.Data, 8)) from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'DataL', + (convert(varchar, atd.ProximoRetorno, 103) + ' ' + convert(varchar, atd.ProximoRetorno, 8)) as 'Retorno', + (select top 1 ctd2.Data from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'Data', + atd.ProximoRetorno, + (select top 1 ctd2.Observacao from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'Observacao' + from ${db}Atendimentos atd + left join ${db}ResultadosAtendimento rat on rat.IDResultadoAtendimento = atd.IDResultadoAtendimento + where atd.IdAtendimento in (select IDAtendimento from ${db}ControleAtendimento where IDFuncionarioTelemarketing = ${IDFuncionario} and IDAtendimento != 0) + ) R + where ${(Tipo == "ProximoRetorno") ? 'R.ProximoRetorno is not null' : '1=1'} + order by R.${Tipo} desc;`; + let NewSQLQuery = `select distinct + R.IDControle, max(R.IDProduto) as 'IDProduto', R.IDPessoa, R.IDVeiculo, R.Resultado, R.Cliente, R.Celular, R.DataL, R.Retorno, R.Data, R.ProximoRetorno, R.Observacao + from ( + select distinct + ctd.IDControle, + (select top(1) pp.IDProduto from ${db}PessoasProdutos pp where pp.IDPessoa = ctd.IDPessoa order by IDProduto asc) as 'IDProduto', + ctd.IDPessoa, + ctd.IDVeiculo, + rat.Descricao as 'Resultado', + ctd.Nome as 'Cliente', + ctd.Celular as 'Celular', + (convert(varchar, ctd.Data, 103) + ' ' + convert(varchar, ctd.Data, 8)) as 'DataL', + (convert(varchar, atd.ProximoRetorno, 103) + ' ' + convert(varchar, atd.ProximoRetorno, 8)) as 'Retorno', + ctd.Data, + atd.ProximoRetorno, + atd.Resumo as 'Observacao' + from ${db}ControleAtendimento ctd + left join ${db}Atendimentos atd on atd.IdAtendimento = ctd.IDAtendimento and convert(varchar, atd.DataVisita, 100) = convert(varchar, ctd.Data, 100) + inner join ${db}ResultadosAtendimento rat on rat.IDResultadoAtendimento = atd.IDResultadoAtendimento + where 1=1 and 1=1 + + union all + + select distinct + (select top 1 ctd2.IDControle from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'IDControle', + (select top 1 ctd2.IDProduto from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'IDProduto', + (select top 1 ctd2.IDPessoa from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'IDPessoa', + (select top 1 ctd2.IDVeiculo from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'IDVeiculo', + rat.Descricao as 'Resultado', + (select top 1 ctd2.Nome from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'Cliente', + (select top 1 ctd2.Celular from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'Celular', + (select top 1 (convert(varchar, ctd2.Data, 103) + ' ' + convert(varchar, ctd2.Data, 8)) from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'DataL', + (convert(varchar, atd.ProximoRetorno, 103) + ' ' + convert(varchar, atd.ProximoRetorno, 8)) as 'Retorno', + (select top 1 ctd2.Data from ${db}ControleAtendimento ctd2 where ctd2.IDAtendimento = atd.IDAtendimento) as 'Data', + atd.ProximoRetorno, + atd.Resumo as 'Observacao' + from ${db}Atendimentos atd + left join ${db}ResultadosAtendimento rat on rat.IDResultadoAtendimento = atd.IDResultadoAtendimento + where atd.IdAtendimento in (select IDAtendimento from ${db}ControleAtendimento where IDFuncionarioTelemarketing = 0 and IDAtendimento != 0) + ) R + where 1=1 + group by R.IDControle, R.IDPessoa, R.IDVeiculo, R.Resultado, R.Cliente, R.Celular, R.DataL, R.Retorno, R.Data, R.ProximoRetorno, R.Observacao + order by R.Data desc;`; + let NewSQLQuery2 = `select distinct + ctd.IDControle, + (select top(1) pp.IDProduto from ${db}PessoasProdutos pp where pp.IDPessoa = ctd.IDPessoa order by IDProduto asc) as 'IDProduto', + ctd.IDPessoa, + ctd.IDVeiculo, + rat.Descricao as 'Resultado', + ctd.Nome as 'Cliente', + ctd.Celular as 'Celular', + (convert(varchar, ctd.Data, 103) + ' ' + convert(varchar, ctd.Data, 8)) as 'DataL', + (convert(varchar, atd.ProximoRetorno, 103) + ' ' + convert(varchar, atd.ProximoRetorno, 8)) as 'Retorno', + ctd.Data, + atd.ProximoRetorno, + atd.Resumo as 'Observacao' + from ${db}ControleAtendimento ctd + left join ${db}Atendimentos atd on atd.IdAtendimento = ctd.IDAtendimento and convert(varchar, atd. DataVisita, 100) = convert(varchar, ctd.Data, 100) + inner join ${db}ResultadosAtendimento rat on rat.IDResultadoAtendimento = atd.IDResultadoAtendimento + where 1=1 and 1=1 + order by ctd.Data desc;`; + //console.log(SQLServerQuery); + execSQLQuery2(NewSQLQuery2, res, req.originalUrl); + }); + + router.get('/getAtendimentosPessoa/:Celular/:db', verifyJWT, (req, res) => { + const db = req.params.db; + const Celular = req.params.Celular; + execSQLQuery2(`select + atd.* + from ${db}Atendimentos atd + inner join ${db}ControleAtendimento cat on cat.IDAtendimento = atd.IdAtendimento + where cat.Celular = '${Celular}' + order by atd.DataHora desc;`, res, req.originalUrl); + }); + + router.get('/getVisitasAbertas/:idunits', verifyJWT, (req, res) => { + const idunits = parseInt(req.params.idunits); + execSQLQuery(`select *, date_format(data_checkin, '%Y-%m-%d %H:%i:%s') as 'DataL' from visitas where idunits = ${idunits} and checkout = 0 order by data_checkin desc;`, res, req.originalUrl); + }); + + router.post('/FazerCheckIn', verifyJWT, (req, res) => { + const idvisitas = req.body.idvisitas; + const idunits = parseInt(req.body.idunits); + const idcontrole = parseInt(req.body.idcontrole); + const idatendimento = parseInt(req.body.idatendimento); + const idformaatendimento = parseInt(req.body.idformaatendimento); + const idveiculo = parseInt(req.body.idveiculo); + const idproduto = parseInt(req.body.idproduto); + const idpessoa = parseInt(req.body.idpessoa); + const idresultadoatendimento = parseInt(req.body.idresultadoatendimento); + const nome = req.body.nome; + const telefone = req.body.telefone; + const checkin = req.body.checkin ? 1 : 0; + const data_checkin = req.body.data_checkin; + const idusers_checkin = parseInt(req.body.idusers_checkin); + const checkout = req.body.checkout ? 1 : 0; + const data_checkout = req.body.data_checkout; + const idusers_checkout = parseInt(req.body.idusers_checkout); + const retorno = req.body.retorno; + + execSQLQuery(`insert into visitas (idunits, idcontrole, idformaatendimento, idveiculo, idproduto, idpessoa, nome, telefone, checkin, data_checkin, idusers_checkin) values (?, ?, ?, ?, ?, ?, ?, ?, ?, now(), ?);`, res, req.originalUrl, [idunits, idcontrole, idformaatendimento, idveiculo, idproduto, idpessoa, nome, telefone, checkin, idusers_checkin]); + }); + + router.post('/FazerCheckOut', verifyJWT, (req, res) => { + const idvisitas = parseInt(req.body.idvisitas); + const idunits = parseInt(req.body.idunits); + const idcontrole = parseInt(req.body.idcontrole); + const idatendimento = parseInt(req.body.idatendimento); + const idformaatendimento = parseInt(req.body.idformaatendimento); + const idveiculo = parseInt(req.body.idveiculo); + const idproduto = parseInt(req.body.idproduto); + const idpessoa = parseInt(req.body.idpessoa); + const idresultadoatendimento = parseInt(req.body.idresultadoatendimento); + const nome = req.body.nome; + const telefone = req.body.telefone; + const checkin = req.body.checkin ? 1 : 0; + const data_checkin = req.body.data_checkin; + const idusers_checkin = parseInt(req.body.idusers_checkin); + const checkout = req.body.checkout ? 1 : 0; + const data_checkout = req.body.data_checkout; + const idusers_checkout = parseInt(req.body.idusers_checkout); + const retorno = req.body.retorno; + + execSQLQuery(`update visitas set + idatendimento = ?, + idproduto = ?, + idresultadoatendimento = ?, + checkout = ?, + data_checkout = now(), + idusers_checkout = ?, + retorno = ? + where idvisitas = ?;`, res, req.originalUrl, [idatendimento, idproduto, idresultadoatendimento, checkout, idusers_checkout, retorno, idvisitas]); + }); + + + router.get('/getEnviosLeads/:idunits', verifyJWT, (req, res) => { + const idunits = parseInt(req.params.idunits); + execSQLQuery(`select idenviosleads, descricao, date_format(data_envio, '%d/%m/%Y %H:%i:%s') as 'data_envio' from enviosleads where idunits = ${idunits} order by data_envio desc;`, res, req.originalUrl); + }); + + router.delete('/deleteEnviosLeads/:idenviosleads', verifyJWT, (req, res) => { + const idenviosleads = parseInt(req.params.idenviosleads); + execSQLQuery(`delete from enviosleads where idenviosleads = ${idenviosleads};`, res, req.originalUrl); + }); + + router.post('/CadastrarEnvio', verifyJWT, (req, res) => { + const idunits = parseInt(req.body.idunits); + const descricao = req.body.descricao; + execSQLQuery(`insert into enviosleads (idunits, descricao) values (?, ?);`, res, req.originalUrl, [idunits, descricao]); + }); + + + router.get('/getLeadsFranqueados/:idunits', verifyJWT, (req, res) => { + const idunits = parseInt(req.params.idunits); + execSQLQuery(`select lf.*, date_format(lf.insert_date, '%d/%m/%Y %H:%i:%s') as 'data_cadastro', case when lf.visto = 0 then 'Não' else 'Sim' end as 'status' from leadsfranqueados lf where lf.idunits = ${idunits} order by data_cadastro desc;`, res, req.originalUrl); + }); + + router.delete('/deleteLeadsFranqueados/:idleadsfranqueados', verifyJWT, (req, res) => { + const idleadsfranqueados = parseInt(req.params.idleadsfranqueados); + execSQLQuery(`delete from leadsfranqueados where idleadsfranqueados = ${idleadsfranqueados};`, res, req.originalUrl); + }); + + router.post('/CadastrarLeadFranqueado', verifyJWT, (req, res) => { + const idunits = parseInt(req.body.idunits); + const aluno = req.body.aluno; + const responsavel = req.body.responsavel; + const email = req.body.email; + const telefone1 = req.body.telefone1; + const telefone2 = req.body.telefone2; + const telefone3 = req.body.telefone3; + execSQLQuery(`insert into leadsfranqueados (idunits, aluno, responsavel, email, telefone1, telefone2, telefone3) values (?, ?, ?, ?, ?, ?, ?);`, res, req.originalUrl, [idunits, aluno, responsavel, email, telefone1, telefone2, telefone3]); + }); + + router.patch('/AtualizarLeadFranqueado', verifyJWT, (req, res) => { + const idleadsfranqueados = parseInt(req.body.idleadsfranqueados); + const aluno = req.body.aluno; + const responsavel = req.body.responsavel; + const email = req.body.email; + const telefone1 = req.body.telefone1; + const telefone2 = req.body.telefone2; + const telefone3 = req.body.telefone3; + const visto = req.body.visto ? 1 : 0; + execSQLQuery(`update leadsfranqueados set + aluno = ?, + responsavel = ?, + email = ?, + telefone1 = ?, + telefone2 = ?, + telefone3 = ?, + visto = ? + where idleadsfranqueados = ?;`, res, req.originalUrl, [aluno, responsavel, email, telefone1, telefone2, telefone3, visto, idleadsfranqueados]); + }); + + return router; +}; + +module.exports = routes; diff --git a/forever.json b/forever.json new file mode 100644 index 0000000..e291e09 --- /dev/null +++ b/forever.json @@ -0,0 +1,10 @@ +[ + { + "uid": "zoe_api", + "append": true, + "watch": false, + "script": "server.js", + "sourceDir": "/var/www/zoe_api/", + "workingDir": "/var/www/zoe_api/" + } +] diff --git a/helpers/CheckToken.js b/helpers/CheckToken.js new file mode 100644 index 0000000..d326a0a --- /dev/null +++ b/helpers/CheckToken.js @@ -0,0 +1,118 @@ +require("dotenv-safe").load(); +var jwt = require('jsonwebtoken'); + +//#region Encript +function LTrim(x) { + return x.replace(/^\s+/, ""); +} + +global.encriptPassword = function encriptPassword(password, amount = 10) { + return Cript(RPad(password, amount), " "); +} + +function RPad(St, Tm) { + text = (LTrim(St) + " ").substr(0, Tm); + return text; +} + +function Cript(St, Pw) { + x = ""; + + p = 0; + + for (i = 0; i < St.length; i++) { + + if (p > Pw.length) { + p = 1; + } + j = ord(Pw.substr(p, 1)) + 128; + n = ord(St.substr(i, 1)); + + x = x + Again(n, j); + p = 0; + } + + return x; +} + +function Again(n, j) { + exitloop = false; + + while (exitloop == false) { + + n = n ^ j; + + if (n < 31) { + n = 128 + n; + } else if ((n > 127) && (n < 159)) { + n = n - 128; + } else { + exitloop = true; + } + } + return String.fromCharCode(n); +} + +function ord(string) { + var str = string + '' + var code = str.charCodeAt(0) + + if (code >= 0xD800 && code <= 0xDBFF) { + var hi = code + if (str.length === 1) { + return code + } + var low = str.charCodeAt(1) + return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000 + } + if (code >= 0xDC00 && code <= 0xDFFF) { + return code + } + return code +} +//#endregion + +global.verifyJWT = function verifyJWT(req, res, next) { + //console.log(req.headers.token); + var token = decodeURI(req.headers.token); + if(!token) + token = req.params.tk || req.body.token; + //console.log(token); + //token = encriptPassword(token, token.length); + //console.log(token); + if (!token) return res.status(401).send({ auth: false, message: 'Não foi enviado token' }); + + jwt.verify(token, process.env.SECRET, function (err, decoded) { + if (err) { + //console.log(err); + res.status(200).send({ status: 'expired' }); + } + else { + req.idusers = decoded.id; + next(); + } + }); +} + +global.fixApostrofe = function fixApostrofe(content) { + for (let i = 0; i < 20; i++) { + content = content.replace("'", '''); + } + return content; +} + +global.fixAspas = function fixAspas(content) { + for (let i = 0; i < 20; i++) { + content = content.replace('"', '"'); + } + return content; +} + +global.replaceAll = function ReplaceAll(Texto, Palavras, TrocarPor, Vezes) { + for (let i = 0; i < Vezes; i++) { + for (let o = 0; o < Palavras.length; o++) { + Texto = Texto.replace(Palavras[o], TrocarPor[o]); + } + } + return Texto; +} \ No newline at end of file diff --git a/helpers/config.js b/helpers/config.js new file mode 100644 index 0000000..de45918 --- /dev/null +++ b/helpers/config.js @@ -0,0 +1,103 @@ +var Online = true; // MODO PRODUCAO - ACESSA O BANCO ONLINE QUANDO TRUE - ACESSA O BANCO LOCAL QUANDO FALSE +var linux = true; // MODO DESENVOLVIMENTO - TRUE PARA LINUX OU FALSE PARA WINDOWS +var passdecrypt = ""; // CHAVE DE DESCRIPTOGRAFIA DOS VIDEOS - ADIQUIRE VALOR COM CONSULTA AO BANCO +var porta_mysql = "3306"; // PORTA PADRAO MYSQL +var tk_fixed = ""; // TOKEN FIXO - ADIQUIRE VALOR COM CONSULTA AO BANCO + +global.Variables = function Variables(data) { + var ret; + switch (data) { + case 'passdecrypt': + ret = passdecrypt; + break; + case 'tk_fixed': + ret = tk_fixed; + break; + case 'portHttp': + ret = 3337; + break; + case 'portHttps': + ret = 1338; + break; + case 'time_token': + ret = 36000; // 9000 = 2,5 horas + break; + case 'src_qrcodes': + ret = 'http://18.228.91.135/qrlotes/'; + break; + case 'ip_mysql': + if(Online == true) + ret = '18.228.91.135'; + //ret = '10.23.0.79'; + else + ret = '127.0.0.1'; + break; + case 'user_mysql': + if(Online == true) + ret = 'root'; + else + ret = 'myrobot'; + break; + case 'password_mysql': + if(Online == true) + //ret = '123123'; + ret = 'maker2018**=='; + else + ret = 'myrobot2019'; + break; + case 'database_mysql': + ret = 'myrobot'; + break; + case 'ip_sqlServer': + ret = '18.231.41.93'; + break; + case 'porta_mysql': + ret = porta_mysql; + break; + case 'user_sqlServer': + ret = 'Usuario'; + break; + case 'password_sqlServer': + ret = 'AbbAchUs'; + break; + case 'src_media': + if(linux == false) + ret = 'C:/var/www/html/'; + else + ret = '/var/www/html/'; + break; + case 'src_fotos': + if(linux == false) + ret = 'C:/var/www/fotos/'; + else + ret = '/var/www/fotos/'; + break; + case 'local': + if(Online == true) + ret = 'Online'; + else + ret = 'Local'; + break; + case 'linux': + ret = linux; + break; + } + return ret; +} + +global.Variables_Set = function Variables_Set(Variavel, Valor) { + switch (Variavel) { + case "local": + Online = Valor; + break; + } +} + +// CONSULTA VALORES PADROES NO BANCO +require('../connections/mysql-server'); +mysqlConnection.query(`SELECT * FROM config;`, function (error, results, fields) { + if (!error && results.length > 0) { + passdecrypt = results[0]['passdecrypt']; + tk_fixed = results[0]['tk_fixed']; + } +}) diff --git a/helpers/generateBarCode.js b/helpers/generateBarCode.js new file mode 100644 index 0000000..7e59172 --- /dev/null +++ b/helpers/generateBarCode.js @@ -0,0 +1,28 @@ +var fs = require('fs'); +var JsBarcode = require('jsbarcode'); +var { createCanvas } = require("canvas"); +var canvas = createCanvas(); +var JSZip = require("jszip"); +var zip = new JSZip(); + +function NovoGeradorBarCode(numBarCodeGerado) { + for (i = 0; i < numBarCodeGerado; i++) { + let random = Math.random(); + console.log(random); + let date = new Date; + random = random.toString().match(/[^.][0-9]{6}/)[0]; + let month = (date.getMonth() + 1).toString().padStart(2, "0"); + let day = date.getDate().toString().padStart(2, "0"); + let milli = date.getMilliseconds().toString().slice(1,3); + let barCode = random.concat(month, day, milli); + console.log('barcode',barCode); + JsBarcode(canvas, barCode); + zip.file(`barcode_${i}.png`, canvas.toBuffer()); + } + + zip.generateNodeStream({type:'nodebuffer',streamFiles:true}) + .pipe(fs.createWriteStream('C:\\Users\\Maker\\Desktop\\out.zip')) + .on('finish', function () { + console.log("out.zip written."); + }); +} diff --git a/helpers/helper.js b/helpers/helper.js new file mode 100644 index 0000000..d925d1f --- /dev/null +++ b/helpers/helper.js @@ -0,0 +1,333 @@ +class Helpers { + + constructor() { + var jwt = require('jsonwebtoken'); + } + + verifyJWT(req, res, next){ + var token = req.headers['x-access-token']; + if (!token) return res.status(401).send({ auth: false, message: 'Não foi enviado token' }); + + jwt.verify(token, process.env.SECRET, function(err, decoded) { + if (err) return res.status(500).send({ auth: false, message: 'Falha na autenticação do token' }); + + // se tudo estiver ok, salva no request para uso posterior + req.idusers = decoded.id; + next(); + }); + } +} + +module.exports = Helpers; + + +/* index.js da biblioteca all-unpacker + +(function () { + 'use strict'; + + // see http://unarchiver.c3.cx/commandline + // unar and lsar + var log = require('npmlog'); + var path = require('path'); + var exec = require('child_process').exec; + var os = require('os'); + + // from http://github.com/substack/node-shell-quote, needed to remove more escaping + var map = require('array-map'); + function quote(xs) { + return map(xs, function (s) { + return String(s).replace(/([#!"$&'(),;<=>?@\[\\\]^`{|}])/g, '\\$1'); + }).join(' '); + }; + // + + module.exports = unpackAll.list = unpackAll; + + var archiveTypePattern = /: [A-Z,7]*$/g; + + var escapeFileName = function(s) { + return '"'+s+'"'; + //if (isWindows()) return '"'+s+'"'; + //// '"'+cmd.replace(/(["\s'$`\\])/g,'\\$1')+'"' + //return s; + }; + + var isInt = function isInt(x) { + return !isNaN(x) && eval(x).toString().length == parseInt(eval(x)).toString().length; + }; + + + unpackAll.defaultListFilter = function defaultListFilter(s) { + return s && s != '' + && s.indexOf('\r') == -1 + && s.indexOf('\n') == -1 + && !s.match(archiveTypePattern); + }; + + function exec_unar(runcmd, extractDir, docallback) { + exec(runcmd, function (err, stdout, stderr) { + if (err) return docallback(Error(err), null); + if (stderr && stderr.length > 0) return docallback(Error('Error: ' + stderr), null); + if (stdout && stdout.length > 0) { + if (stdout.indexOf('No files extracted')>=1) return docallback(Error('Error: No files extracted'), null); + } + return docallback(null, extractDir, stdout); + }); + } + + unpackAll.pack = function pack(archiveFile, options, callback) { + if (!callback) return new Error('No callback function'); + if (!archiveFile) archiveFile = options.archiveFile; + if (!archiveFile) return callback(Error("Error: archiveFile or options.archiveFile missing."), null); + if (!options) options = {}; + + var unar = options.unar; + if (!unar) unar = (process.platform != "linux") ? path.join(__dirname,'zip') : 'zip'; + var ar = [unar]; + + if (options.password) { + ar.push('-P'); + ar.push(options.password); + } + + ar.push('SOURCEFILE'); + + var targetDir = options.targetDir; + ar.push(targetDir); + + var cmd = quote(ar).replace('SOURCEFILE', archiveFile); + exec_unar(cmd, targetDir, callback); + }; + + unpackAll.unpackZip = function unpackZip(archiveFile, options, callback) { + if (!callback) return new Error('No callback function'); + if (!archiveFile) archiveFile = options.archiveFile; + if (!archiveFile) return callback(Error("Error: archiveFile or options.archiveFile missing."), null); + if (!options) options = {}; + + var unar = options.unar; + if (!unar) unar = (process.platform != "linux") ? path.join(__dirname,'unzip') : 'unzip'; + var ar = [unar]; + + if (options.password) { + ar.push('-P'); + ar.push(options.password); + } + + ar.push('SOURCEFILE'); + + if (options.forceDirectory) ar.push('-d'); + + var targetDir = options.targetDir; + ar.push(targetDir); + + var cmd = quote(ar).replace('SOURCEFILE', archiveFile); + exec_unar(cmd, targetDir, callback); + }; + + unpackAll.unpack = function unpack(archiveFile, options, callback) { + if (!callback) return new Error('No callback function'); + if (!archiveFile) archiveFile = options.archiveFile; + if (!archiveFile) return callback(Error("Error: archiveFile or options.archiveFile missing."), null); + if (!options) options = {}; + + // Unar command: + var unar = options.unar; + if (!unar) unar = (process.platform != "linux") ? path.join(__dirname,'unar') : 'unar'; + var ar = [unar]; + + // Archive file (source): + ar.push('SOURCEFILE'); + //ar.push(archiveFile); + + // -output-directory (-o) : The directory to write the contents of the archive to. Defaults to the current directory. + ar.push('-o'); + var targetDir = options.targetDir; + if (!targetDir) targetDir = path.join(os.tmpdir(), 'tmp'); + ar.push(targetDir); + + // -force-overwrite (-f): Always overwrite files when a file to be unpacked already exists on disk. By default, the program asks the user if possible, otherwise skips the file. + if (options.forceOverwrite) ar.push('-f'); + + // -force-rename (-r): Always rename files when a file to be unpacked already exists on disk. + if (options.forceRename) ar.push('-r'); + + // -force-skip (-s): Always skip files when a file to be unpacked already exists on disk. + if (options.forceSkip) ar.push('-s'); + + // -force-directory (-d): Always create a containing directory for the contents of the unpacked archive. By default, a directory is created if there is more than one top-level file or folder. + if (options.forceDirectory) ar.push('-d'); + + // -no-directory (-D): Never create a containing directory for the contents of the unpacked archive. + if (options.noDirectory) ar.push('-D'); + + // -no-recursion (-nr): Do not attempt to extract archives contained in other archives. For instance, when unpacking a .tar.gz file, only unpack the .gz file and not its contents. + if (options.noRecursion) ar.push('-nr'); + + // -copy-time (-t): Copy the file modification time from the archive file to the containing directory, if one is created. + if (options.copyTime) ar.push('-t'); + + // -quiet (-q): Run in quiet mode. + if (options.quiet) ar.push('-q'); + + // -password (-p) : The password to use for decrypting protected archives. + if (options.password) { + ar.push('-p'); + ar.push(options.password); + } + // -password-encoding (-E) : The encoding to use for the password for the archive, when it is not known. If not specified, then either the encoding given by the -encoding option or the auto-detected encoding is used. + if (options.passwordEncoding) { + ar.push('-E'); + ar.push(options.passwordEncoding); + } + + // -encoding (-e) : The encoding to use for filenames in the archive, when it is not known. If not specified, the program attempts to auto-detect the encoding used. Use "help" or "list" as the argument to give + if (options.encoding) { + ar.push('-e'); + ar.push(options.encoding); + } + + if (options.indexes) { + // -indexes (-i): Instead of specifying the files to unpack as filenames or wildcard patterns, specify them as indexes, as output by lsar. + if (Array.isArray(options.indexes)) { + options.indexes.forEach(function (idx) { + ar.push('-i'); + ar.push(''+idx); // string! + }); + } else if (isInt(options.indexes)) { + console.error('options.indexes must be an array of integer, but it is: ' + JSON.stringify(options.indexes)) + } + } else if (options.files) { + if (Array.isArray(options.files)) { + options.files.forEach(function (s) { + ar.push(s); + }); + } else { + ar.push(options.files); + } + } + + //if (!options.quiet) log.info('command', quote(ar)); + + var cmd = quote(ar).replace('SOURCEFILE', archiveFile); + //if (!options.quiet) log.info('cmd', cmd); + exec_unar(cmd, targetDir, callback); + }; // unpackAll.unpack + + unpackAll.unpackonly = function unpackonly(archiveFile, unpackDir, unpackOnly, callback) { + if (!callback) return new Error('No callback function'); + if (!archiveFile) return callback(Error("Error: archiveFile missing."), null); + if (!unpackDir) return callback(Error("Error: target Directory missing."), null); + if (!unpackOnly) return callback(Error("Error: files or directory to extract form archive missing."), null); + + // Unar command: + var unar = (process.platform != "linux") ? path.join(__dirname,'unar') : 'unar'; + var ar = [unar]; + + // Archive file (source): + ar.push('SOURCEFILE'); + //ar.push(archiveFile); + + // -output-directory (-o) : The directory to write the contents of the archive to. Defaults to the current directory. + ar.push('-o'); + ar.push(unpackDir); + + // -force-overwrite (-f): Always overwrite files when a file to be unpacked already exists on disk. By default, the program asks the user if possible, otherwise skips the file. + ar.push('-f'); + + // -no-directory (-D): Never create a containing directory for the contents of the unpacked archive. + ar.push('-D'); + + // -copy-time (-t): Copy the file modification time from the archive file to the containing directory, if one is created. + ar.push('-t'); + + if (unpackOnly) { + if (Array.isArray(unpackOnly)) { + unpackOnly.forEach(function (s) { + ar.push(s); + }); + } else { + ar.push(unpackOnly); + } + } + + //log.info('command', quote(ar)); + + var cmd = quote(ar).replace('SOURCEFILE', escapeFileName(archiveFile)); + //log.info('cmd', cmd); + exec_unar(cmd, unpackDir, callback); + }; // unpackAll.unpackonly + + unpackAll.list = function list(archiveFile, options, callback) { + if (!callback) return new Error('No callback function'); + if (!archiveFile) archiveFile = options.archiveFile; + if (!archiveFile) return callback(Error("Error: archiveFile or options.archiveFile missing."), null); + + if (!options) options = {}; + + // Usar command: + var lsar = options.lsar; + if (!lsar) lsar = (process.platform != "linux") ? path.join(__dirname,'lsar') : 'lsar'; + var ar = [lsar]; + + // Archive file (source): + ar.push('SOURCEFILE'); + + // -no-recursion (-nr): Do not attempt to extract archives contained in other archives. For instance, when unpacking a .tar.gz file, only unpack the .gz file and not its contents. + if (options.noRecursion) ar.push('-nr'); + + // -password (-p) : The password to use for decrypting protected archives. + if (options.password) { + ar.push('-p'); + ar.push(options.password); + } + // -password-encoding (-E) : The encoding to use for the password for the archive, when it is not known. If not specified, then either the encoding given by the -encoding option or the auto-detected encoding is used. + if (options.passwordEncoding) { + ar.push('-E'); + ar.push(options.passwordEncoding); + } + + // -encoding (-e) : The encoding to use for filenames in the archive, when it is not known. If not specified, the program attempts to auto-detect the encoding used. Use "help" or "list" as the argument to give + if (options.encoding) { + ar.push('-e'); + ar.push(options.encoding); + } + + // -print-encoding (-pe): Print the auto-detected encoding and the confidence factor after the file list + if (options.printEncoding) { + ar.push('-pe'); + ar.push(options.printEncoding); + } + + // -json (-j): Print the listing in JSON format. + if (options.json) ar.push('-j'); + + // -json-ascii (-ja): Print the listing in JSON format, encoded as pure ASCII text. + if (options.jsonAscii) ar.push('-ja'); + + var cmd = quote(ar).replace('SOURCEFILE', escapeFileName(archiveFile)); + if (!options.quiet) log.info('cmd', cmd); + exec(cmd, function (err, stdout, stderr) { + if (err) return callback(Error(err), null); + if (stderr && stderr.length > 0) return callback(Error('Error: ' + stderr), null); + + var lines = stdout.split(/(\r?\n)/g); + if (lines.length > 0) { + var files = lines.filter(unpackAll.defaultListFilter); + return callback(null, files); + + } else { + return callback(Error('Error: no files foound in archive. ' + stderr), null); + } + }); + }; // unpackAll.list + + unpackAll(); + + function unpackAll() { + } + +})(); + +*/ \ No newline at end of file diff --git a/helpers/mycsv.csv b/helpers/mycsv.csv new file mode 100644 index 0000000..e91201e --- /dev/null +++ b/helpers/mycsv.csv @@ -0,0 +1,3 @@ +FIRSTLINE;SECONDLINE +D28B 6277;B8F2 3011 +BE2B 6277;48F1 3011 diff --git a/helpers/serialBook.js b/helpers/serialBook.js new file mode 100644 index 0000000..a913290 --- /dev/null +++ b/helpers/serialBook.js @@ -0,0 +1,115 @@ +const { v4: uuidv4 } = require("uuid"); +const fs = require("fs"); +const { stringify } = require("csv-stringify"); + +let columns = { + fisrt: "FIRSTLINE", + second: "SECONDLINE", +}; +var serialList = []; + +function genSerialList(quantity, results) { + let oldValues = []; + Object.values(results).forEach((element) => { + oldValues.push(element.serial); + }); + serialList = []; + return new Promise((resolve, reject) => { + while (serialList.length < quantity) { + let uui = uuidv4(); + uui = uui.replace(/-/gm, ""); + uui = uui.toUpperCase(); + let milliseconds = Date.now().toString(); + milliseconds = milliseconds.match(/[0-9]{4}/gm); + let partition = uui.match(/[0-9A-Z]{4}/gm); + + let head = partition[0].concat( + " ", + milliseconds[1], + " ", + partition[1], + " ", + milliseconds[2] + ); + let body = partition[2].concat( + " ", + milliseconds[1], + " ", + partition[3], + " ", + milliseconds[2] + ); + let legs = partition[4].concat( + " ", + milliseconds[1], + " ", + partition[5], + " ", + milliseconds[2] + ); + let tail = partition[6].concat( + " ", + milliseconds[1], + " ", + partition[7], + " ", + milliseconds[2] + ); + + let now = new Date(); + oldValues.includes(head) + ? "" + : serialList.push({ serial: head, createdAt: now, updatedAt: now }); + oldValues.includes(body) + ? "" + : serialList.push({ serial: body, createdAt: now, updatedAt: now }); + oldValues.includes(legs) + ? "" + : serialList.push({ serial: legs, createdAt: now, updatedAt: now }); + oldValues.includes(tail) + ? "" + : serialList.push({ serial: tail, createdAt: now, updatedAt: now }); + } + + serialList = serialList.slice(0, quantity); + resolve(serialList); + }); +} + +function generateCSV(list) { + return new Promise((resolve, reject) => { + let filename = `${__dirname}\\mycsv.csv`; + let data = []; + Object.values(list).forEach((element) => { + let partSerial = element.serial.match(/[0-9A-Z]{4}/gm); + data.push([ + partSerial[0].concat(" ", partSerial[1]), + partSerial[2].concat(" ", partSerial[3]), + ]); + }); + stringify( + data, + { + header: true, + columns: columns, + delimiter: ";", + }, + (err, output) => { + if (err) { + reject(err); + } + fs.writeFile(filename, output, (err) => { + if (err) { + reject(err); + } + resolve(filename); + }); + } + ); + }); +} + +module.exports = { + genSerialList, + generateCSV, +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e82013e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,9701 @@ +{ + "name": "myrobot_api", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "myrobot_api", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@google-cloud/speech": "^4.2.0", + "alexa-sdk": "^1.0.25", + "alexa-verifier": "^2.0.1", + "alexa-verifier-middleware": "^1.0.2", + "all-unpacker": "^0.1.2", + "angularx-qrcode": "^1.5.3", + "archiver": "^3.0.0", + "ask-sdk-core": "^2.7.0", + "ask-sdk-model": "^1.18.0", + "async": "^2.6.2", + "base-64": "^0.1.0", + "base64-img": "^1.0.4", + "base64-to-image": "^1.0.2", + "base64topdf": "^1.1.8", + "body-parser": "^1.19.0", + "canvas": "^2.9.1", + "cors": "^2.8.5", + "csv-stringify": "^6.1.0", + "del": "^4.1.1", + "dotenv-safe": "^6.1.0", + "express": "^4.17.1", + "express-formidable": "^1.2.0", + "express-routes-map": "0.0.1", + "fastest-levenshtein": "^1.0.12", + "file-base64": "^1.0.0", + "forever": "^1.0.0", + "formidable": "^1.2.1", + "gzipme": "^0.1.2", + "ibm-watson": "^6.0.0", + "joi": "^13.7.0", + "jsbarcode": "^3.11.5", + "jsonwebtoken": "^8.5.1", + "jszip": "^3.10.0", + "lokijs": "^1.5.6", + "minizip-asm.js": "^1.0.10", + "mp3-to-wav": "^0.1.11", + "mssql": "^4.3.7", + "multer": "^1.4.1", + "mysql": "^2.18.1", + "ng2-file-upload": "^1.3.0", + "node-7z": "^1.1.0", + "node-7z-forall": "^1.0.0", + "node-lame": "^1.2.0", + "node-unrar": "^0.1.5", + "nodemailer": "^4.7.0", + "nodemon": "^1.19.4", + "rand-token": "^0.4.0", + "rimraf": "^2.6.3", + "rxjs-compat": "^6.5.2", + "shelljs": "^0.8.3", + "striptags": "^3.1.1", + "tedious": "^2.7.1", + "unrar": "^0.1.7", + "unrar-promise": "^2.0.1", + "unzip": "^0.1.11", + "unzipper": "^0.9.15", + "vimeo": "^2.1.1", + "winrarjs": "0.0.16", + "xmlhttprequest": "^1.8.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dependencies": { + "@babel/highlight": "^7.12.13" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" + }, + "node_modules/@babel/highlight": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@google-cloud/common": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.5.0.tgz", + "integrity": "sha512-10d7ZAvKhq47L271AqvHEd8KzJqGU45TY+rwM2Z3JHuB070FeTi7oJJd7elfrnKaEvaktw3hH2wKnRWxk/3oWQ==", + "dependencies": { + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^6.1.1", + "retry-request": "^4.1.1", + "teeny-request": "^7.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", + "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/speech": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@google-cloud/speech/-/speech-4.2.0.tgz", + "integrity": "sha512-5QlL2Gg0CGLT5kS6gWiZuRy0layCnXeS5+CkHPJsqvTmmY5Ssf+XIDoocp9uBkrVwwPjKm74mFlSTTL5HnlBwQ==", + "dependencies": { + "@google-cloud/common": "^3.0.0", + "@types/pumpify": "^1.4.1", + "google-gax": "^2.9.2", + "protobufjs": "^6.8.6", + "pumpify": "^2.0.0", + "stream-events": "^1.0.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.2.5.tgz", + "integrity": "sha512-CBCNwedw8McnEBq9jvoiJikws16WN0OiHFejQPovY71XkFWSiIqgvydYiDwpvIYDJmhPQ7qZNzW9BPndhXbx1Q==", + "dependencies": { + "@types/node": "^12.12.47", + "google-auth-library": "^6.1.1", + "semver": "^6.2.0" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/@types/node": { + "version": "12.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.15.tgz", + "integrity": "sha512-lowukE3GUI+VSYSu6VcBXl14d61Rp5hA1D+61r16qnwC0lYNSqdxcvRh0pswejorHfS+HgwBasM8jLXz0/aOsw==" + }, + "node_modules/@grpc/grpc-js/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.6.tgz", + "integrity": "sha512-DT14xgw3PSzPxwS13auTEwxhMMOoz33DPUKNtmYK/QYbBSpLXJy78FGGs5yVoxVobEqPm4iW9MOIoz0A3bLTRQ==", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "protobufjs": "^6.8.6" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@honeo/check": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@honeo/check/-/check-1.6.1.tgz", + "integrity": "sha512-DNzAs3sLH4mBAPbc9EAProajdp62qTWZDpa3lO/1DfDJ5boVnKN0L93rQ8Dqkj9cBeJxDL6v0tX4vBBr1eoO0g==" + }, + "node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/types/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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/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==" + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/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==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/async/-/async-3.2.5.tgz", + "integrity": "sha512-fdtHUdfIxSfU6crUgUOEb6vxdquAOa75bh1sQVL/ePkmQDNo8Aj1056eGGI9cPls5tLRhnAyfoXljEk+hmhbxg==" + }, + "node_modules/@types/duplexify": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@types/duplexify/-/duplexify-3.6.0.tgz", + "integrity": "sha512-5zOA53RUlzN74bvrSGwjudssD9F3a797sDZQkiYpUOxW+WHaXTCPz4/d5Dgi6FKnOqZ2CpaTo0DhgIfsXAOE/A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" + }, + "node_modules/@types/extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/extend/-/extend-3.0.1.tgz", + "integrity": "sha512-R1g/VyKFFI2HLC1QGAeTtCBWCo6n75l41OnsVYNbmKG+kempOESaodf6BeJyUM3Q0rKa/NQcTHbB2+66lNnxLw==" + }, + "node_modules/@types/file-type": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/file-type/-/file-type-5.2.2.tgz", + "integrity": "sha512-GWtM4fyqfb+bec4ocpo51/y4x0b83Je+iA6eV131LT9wL0//G+1UgwbkMg7w61ceOwR+KkZXK00z44jrrNljWg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dependencies": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/isstream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@types/isstream/-/isstream-0.1.0.tgz", + "integrity": "sha512-jo6R5XtVMgu1ej3H4o9NXiUE/4ZxyxmDrGslGiBa4/ugJr+Olw2viio/F2Vlc+zrwC9HJzuApOCCVC2g5jqV0w==" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + }, + "node_modules/@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" + }, + "node_modules/@types/node": { + "version": "12.0.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.8.tgz", + "integrity": "sha512-b8bbUOTwzIY3V5vDTY1fIJ+ePKDUBqt2hC2woVGotdQQhG/2Sh62HOKHrT7ab+VerXAcPyAiTEipPu/FsreUtg==" + }, + "node_modules/@types/pumpify": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@types/pumpify/-/pumpify-1.4.1.tgz", + "integrity": "sha512-l7u/Dnh1OG9T7VH6TvulR0g8oE8hgIW5409mSUKi8Vxw2+JV18aTa06Sv5bvNjrD0zbsB/cuZ/iTFQgFNfzIuw==", + "dependencies": { + "@types/duplexify": "*", + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==" + }, + "node_modules/@types/websocket": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.1.tgz", + "integrity": "sha512-f5WLMpezwVxCLm1xQe/kdPpQIOmL0TXYx2O15VYfYzc7hTIdxiOoOvez+McSIw3b7z/1zGovew9YSL7+h4h7/Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "15.0.13", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", + "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", + "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dependencies": { + "mime-db": "1.40.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ajax-request": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/ajax-request/-/ajax-request-1.2.3.tgz", + "integrity": "sha1-mfy+wdbSeS+F+pSVNTMr0U9fN5A=", + "dependencies": { + "file-system": "^2.1.1", + "utils-extend": "^1.0.7" + } + }, + "node_modules/ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "optional": true, + "dependencies": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "node_modules/alexa-sdk": { + "version": "1.0.25", + "resolved": "https://registry.npmjs.org/alexa-sdk/-/alexa-sdk-1.0.25.tgz", + "integrity": "sha512-+FVFNi+mxBZm2HL+oi5u4JTNjQ2uDs4Tp9eqcWIxL3AAD+AU4a6gWpu6LEjxIVCqaI1Ro/RyDm3mnJZA9g6G8w==", + "deprecated": "This version of the Alexa Skills Kit SDK is no longer supported. Please use the v2 release found here: https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs", + "dependencies": { + "aws-sdk": "^2.4.7", + "i18next": "^3.4.1", + "i18next-sprintf-postprocessor": "^0.2.2" + } + }, + "node_modules/alexa-verifier": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/alexa-verifier/-/alexa-verifier-2.0.1.tgz", + "integrity": "sha1-kL9OCLXIqpBz4hHpzR28Q6zGm4M=", + "dependencies": { + "node-forge": "^0.7.0", + "validator": "^9.0.0" + } + }, + "node_modules/alexa-verifier-middleware": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alexa-verifier-middleware/-/alexa-verifier-middleware-1.0.2.tgz", + "integrity": "sha512-ytRxmTLFnVq504U00AuG0BkpHLXGTFKwau1Nvs/2/ceztouzuCi/XOAFFjOL3R53GmCtNp1vdXcOK4mIUq00eA==", + "dependencies": { + "alexa-verifier": "^2.0.1" + } + }, + "node_modules/all-unpacker": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/all-unpacker/-/all-unpacker-0.1.2.tgz", + "integrity": "sha512-1EnS2FyBNMt6wCQ9j9tZOYVneMgdF399BUbH5cIqEWJMHWmckTtXDF9bxdhPLEti5zNYD2bPLHtW9/liLqrctA==", + "deprecated": "use node-unar", + "hasInstallScript": true, + "dependencies": { + "array-map": "~0.0.0", + "npmlog": "^4.1.2" + }, + "optionalDependencies": { + "node-wget": "^0.4.2", + "system-installer": "^1.1.0", + "unzipper": "^0.9.3" + } + }, + "node_modules/angularx-qrcode": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/angularx-qrcode/-/angularx-qrcode-1.5.3.tgz", + "integrity": "sha512-9WTsnOGNv3IvSriVSHOc7k6PIBcqqjivAQXhEF9SjDYgcio63zCkcsAC627vSaTqUoDkgE5MRoT4PO2UMROk2w==", + "dependencies": { + "qrcodejs2": "0.0.2" + }, + "peerDependencies": { + "@angular/common": ">= 5.0.0 < 7.3.0", + "@angular/core": ">= 5.0.0 < 7.3.0" + } + }, + "node_modules/ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dependencies": { + "string-width": "^2.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "node_modules/archiver": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.0.0.tgz", + "integrity": "sha512-5QeR6Xc5hSA9X1rbQfcuQ6VZuUXOaEdB65Dhmk9duuRJHYif/ZyJfuyJqsQrj34PFjU5emv5/MmfgA8un06onw==", + "dependencies": { + "archiver-utils": "^2.0.0", + "async": "^2.0.0", + "buffer-crc32": "^0.2.1", + "glob": "^7.0.0", + "readable-stream": "^2.0.0", + "tar-stream": "^1.5.0", + "zip-stream": "^2.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.0.0.tgz", + "integrity": "sha512-JRBgcVvDX4Mwu2RBF8bBaHcQCSxab7afsxAPYDQ5W+19quIPP5CfKE7Ql+UHs9wYvwsaNR8oDuhtf5iqrKmzww==", + "dependencies": { + "glob": "^7.0.0", + "graceful-fs": "^4.1.0", + "lazystream": "^1.0.0", + "lodash.assign": "^4.2.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.toarray": "^4.4.0", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + }, + "node_modules/are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "http://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=" + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ask-sdk-core": { + "version": "2.7.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ask-sdk-core/-/ask-sdk-core-2.7.0.tgz", + "integrity": "sha1-R3Bk2FAlAUnww8Th1RDHgJEJ6Yw=", + "dependencies": { + "ask-sdk-runtime": "^2.7.0" + }, + "peerDependencies": { + "ask-sdk-model": "^1.9.0" + } + }, + "node_modules/ask-sdk-model": { + "version": "1.18.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ask-sdk-model/-/ask-sdk-model-1.18.0.tgz", + "integrity": "sha1-iROsggyaJBWjliLZLA99jQf3z/U=" + }, + "node_modules/ask-sdk-runtime": { + "version": "2.7.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ask-sdk-runtime/-/ask-sdk-runtime-2.7.0.tgz", + "integrity": "sha1-KQXtmSHZ2WHIdw69KRFstMcjazk=" + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "optional": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "dependencies": { + "lodash": "^4.17.11" + } + }, + "node_modules/async-each": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.2.tgz", + "integrity": "sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/atob-lite": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/atob-lite/-/atob-lite-2.0.0.tgz", + "integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=" + }, + "node_modules/audio-buffer": { + "version": "4.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/audio-buffer/-/audio-buffer-4.0.4.tgz", + "integrity": "sha1-zbA4ValRocKTGsHnsAqdnTpNSFg=", + "deprecated": "Depends on Web-Audio-API implementation. Use either web-audio-api, web-audio-js or web-audio-engine package.", + "dependencies": { + "audio-context": "^1.0.0" + } + }, + "node_modules/audio-buffer-from": { + "version": "1.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/audio-buffer-from/-/audio-buffer-from-1.1.1.tgz", + "integrity": "sha1-a6HdDUY84Z57oZ+R9eH3JReNONg=", + "dependencies": { + "audio-buffer": "^4.0.4", + "audio-context": "^1.0.1", + "audio-format": "^2.0.0", + "is-audio-buffer": "^1.0.11", + "is-plain-obj": "^1.1.0", + "pcm-convert": "^1.6.0", + "pick-by-alias": "^1.2.0", + "string-to-arraybuffer": "^1.0.0" + } + }, + "node_modules/audio-context": { + "version": "1.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/audio-context/-/audio-context-1.0.3.tgz", + "integrity": "sha1-quVjZpGozcFfyRBZcEy8fC+3q/k=", + "deprecated": "Depends on Web-Audio-API implementation. Use either web-audio-api, web-audio-js or web-audio-engine package." + }, + "node_modules/audio-format": { + "version": "2.3.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/audio-format/-/audio-format-2.3.2.tgz", + "integrity": "sha1-8j/HOzCMbfuhkE2m1M2cdiFzGr0=", + "dependencies": { + "is-audio-buffer": "^1.0.11", + "is-buffer": "^1.1.5", + "is-plain-obj": "^1.1.0", + "pick-by-alias": "^1.2.0", + "sample-rate": "^2.0.0" + } + }, + "node_modules/av": { + "version": "0.4.9", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/av/-/av-0.4.9.tgz", + "integrity": "sha1-jHFl9zlYClQeyVBxQjSSs//cbiA=", + "dependencies": { + "coffeeify": "^0.6.0" + }, + "optionalDependencies": { + "speaker": "^0.3.0" + } + }, + "node_modules/aws-sdk": { + "version": "2.585.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.585.0.tgz", + "integrity": "sha512-T3JG4JZUmELqxT4hwJa93xns/TWIllaeYoyhRPGwXUj78vhCYJUiigtU6WRYLu84AMoZAGT/pVkARH7vfxpq9Q==", + "dependencies": { + "buffer": "4.9.1", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/aws-sdk/node_modules/buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "deprecated": "This version of 'buffer' is out-of-date. You must update to v4.9.2 or newer", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "optional": true + }, + "node_modules/axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "dependencies": { + "follow-redirects": "^1.10.0" + } + }, + "node_modules/axios-cookiejar-support": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-1.0.1.tgz", + "integrity": "sha512-IZJxnAJ99XxiLqNeMOqrPbfR7fRyIfaoSLdPUf4AMQEGkH8URs0ghJK/xtqBsD+KsSr3pKl4DEQjCn834pHMig==", + "dependencies": { + "is-redirect": "^1.0.0", + "pify": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@types/tough-cookie": ">=2.3.3", + "axios": ">=0.16.2", + "tough-cookie": ">=2.3.3" + } + }, + "node_modules/axios-cookiejar-support/node_modules/pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base-64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", + "integrity": "sha1-eAqZyE59YAJgNhURxId2E78k9rs=" + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-img": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/base64-img/-/base64-img-1.0.4.tgz", + "integrity": "sha1-PiLVXWx0okVT2EDSsbwSp9sHjTU=", + "dependencies": { + "ajax-request": "^1.2.0", + "file-system": "^2.1.0" + } + }, + "node_modules/base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + }, + "node_modules/base64-to-image": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-to-image/-/base64-to-image-1.0.2.tgz", + "integrity": "sha1-pvMGBuUhdNJJn87iHuu3S3pzHGk=" + }, + "node_modules/base64topdf": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/base64topdf/-/base64topdf-1.1.8.tgz", + "integrity": "sha1-w8nGOkeDy4uZx8rSgYWF1LXk9dg=", + "dependencies": { + "fs": "0.0.1-security" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/big-integer": { + "version": "1.6.44", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.44.tgz", + "integrity": "sha512-7MzElZPTyJ2fNvBkPxtFQ2fWIkVmuzw41+BZHSzpEq3ymB2MfeKp1+yXl/tS75xCx+WnyV+yb0kp+K1C3UNwmQ==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/big-number": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/big-number/-/big-number-0.3.1.tgz", + "integrity": "sha1-rHMCDApZu3nrF8LOLbd/d9l04BM=", + "engines": { + "node": ">= 0.4.x" + } + }, + "node_modules/bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", + "engines": { + "node": "*" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz", + "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha1-EDU8npRTNLwFEabZCzj7x8nFBN8=", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" + }, + "node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/body-parser/node_modules/mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dependencies": { + "mime-db": "1.40.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/body-parser/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "optional": true, + "dependencies": { + "hoek": "4.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/boom/node_modules/hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "dependencies": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/broadway": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/broadway/-/broadway-0.3.6.tgz", + "integrity": "sha1-fb7waLlUt5B5Jf1USWO1eKkCuno=", + "dependencies": { + "cliff": "0.1.9", + "eventemitter2": "0.4.14", + "nconf": "0.6.9", + "utile": "0.2.1", + "winston": "0.8.0" + }, + "engines": { + "node": ">= 0.6.4" + } + }, + "node_modules/broadway/node_modules/async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + }, + "node_modules/broadway/node_modules/cliff": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/cliff/-/cliff-0.1.9.tgz", + "integrity": "sha1-ohHgnGo947oa8n0EnTASUNGIErw=", + "dependencies": { + "colors": "0.x.x", + "eyes": "0.1.x", + "winston": "0.8.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/broadway/node_modules/utile": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/utile/-/utile-0.2.1.tgz", + "integrity": "sha1-kwyI6ZCY1iIINMNWy9mncFItkNc=", + "dependencies": { + "async": "~0.2.9", + "deep-equal": "*", + "i": "0.3.x", + "mkdirp": "0.x.x", + "ncp": "0.4.x", + "rimraf": "2.x.x" + }, + "engines": { + "node": ">= 0.6.4" + } + }, + "node_modules/broadway/node_modules/winston": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-0.8.0.tgz", + "integrity": "sha1-YdCDD6aZcGISIGsKK1ymmpMENmg=", + "dependencies": { + "async": "0.2.x", + "colors": "0.6.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "pkginfo": "0.3.x", + "stack-trace": "0.0.x" + }, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.1.tgz", + "integrity": "sha1-qfuAbOgUXVQoUQznLyeLs2OmOL8=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/bufferutil": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "dependencies": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/busboy/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/busboy/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/busboy/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caller": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/caller/-/caller-0.0.1.tgz", + "integrity": "sha1-83odbqEOgp2UchrimpC7T7Uqt2c=", + "dependencies": { + "tape": "~2.3.2" + } + }, + "node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/canvas": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.9.1.tgz", + "integrity": "sha512-vSQti1uG/2gjv3x6QLOZw7TctfufaerTWbVe+NSduHxxLGB+qf3kFgQ6n66DSnuoINtVUjrLLIK2R+lxrBG07A==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.15.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/canvas/node_modules/nan": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==" + }, + "node_modules/capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "optional": true + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==" + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cliff": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/cliff/-/cliff-0.1.10.tgz", + "integrity": "sha1-U74z6p9ZvshWCe4wCsQgdgPlIBM=", + "dependencies": { + "colors": "~1.0.3", + "eyes": "~0.1.8", + "winston": "0.8.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/cliff/node_modules/colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "optional": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/coffee-script": { + "version": "1.7.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/coffee-script/-/coffee-script-1.7.1.tgz", + "integrity": "sha1-YplqhheAx15tUGnROCJyO3NAS/w=", + "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)", + "dependencies": { + "mkdirp": "~0.3.5" + }, + "bin": { + "cake": "bin/cake", + "coffee": "bin/coffee" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/coffee-script/node_modules/mkdirp": { + "version": "0.3.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)" + }, + "node_modules/coffeeify": { + "version": "0.6.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/coffeeify/-/coffeeify-0.6.0.tgz", + "integrity": "sha1-dcq6my6Sx4NskkZciDtqzJ2JRlI=", + "dependencies": { + "coffee-script": "~1.7.0", + "convert-source-map": "~0.3.3", + "through": "~2.3.4" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colors": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combine-errors": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/combine-errors/-/combine-errors-3.0.3.tgz", + "integrity": "sha1-9N9nQAg+VwOjGBEQwrEFUfAD2oY=", + "dependencies": { + "custom-error-instance": "2.1.1", + "lodash.uniqby": "4.5.0" + } + }, + "node_modules/combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + }, + "node_modules/component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "node_modules/compress-commons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", + "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", + "dependencies": { + "buffer-crc32": "^0.2.1", + "crc32-stream": "^2.0.0", + "normalize-path": "^2.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/compress-commons/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/configstore": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.5.tgz", + "integrity": "sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==", + "dependencies": { + "dot-prop": "^4.2.1", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/configstore/node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "node_modules/console-wrapper": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-wrapper/-/console-wrapper-1.1.0.tgz", + "integrity": "sha1-gsb5zRTGKVtLlRMpD6PMFnVniQM=" + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition/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/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "0.3.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/convert-source-map/-/convert-source-map-0.3.5.tgz", + "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=" + }, + "node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "hasInstallScript": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dependencies": { + "buffer": "^5.1.0" + } + }, + "node_modules/crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "dependencies": { + "crc": "^3.4.4", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dependencies": { + "capture-stack-trace": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/cryptiles": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.4.tgz", + "integrity": "sha512-8I1sgZHfVwcSOY6mSGpVU3lw/GSIZvusg8dD2+OGehCJpOhQRLNcH0qb9upQnOH4XhgxxFJSg6E2kx95deb1Tw==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "optional": true, + "dependencies": { + "boom": "5.x.x" + } + }, + "node_modules/cryptiles/node_modules/boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "optional": true, + "dependencies": { + "hoek": "4.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/cryptiles/node_modules/hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "engines": { + "node": ">=4" + } + }, + "node_modules/csv-stringify": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.1.0.tgz", + "integrity": "sha512-rdBqiy77TczvhGlpLHyoph2adMs6WMnmQY4PBRqeIWykI1FLnVCppnRdso8faGj2+eN7izk9YlbFyZkOrL9rAQ==" + }, + "node_modules/custom-error-instance": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/custom-error-instance/-/custom-error-instance-2.1.1.tgz", + "integrity": "sha1-PPY5FIemYppiR+sMoM4ACBt+Nho=" + }, + "node_modules/cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defined": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz", + "integrity": "sha1-817qfXBekzuvE7LwOz+D2SFAOz4=" + }, + "node_modules/del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dependencies": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "dependencies": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/dicer/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/dicer/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/dicer/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/director": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/director/-/director-1.2.7.tgz", + "integrity": "sha1-v9N0EHX9f7GlsuE2WMX0vsd3NvM=", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/dot-prop": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz", + "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==", + "dependencies": { + "is-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dotenv": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", + "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/dotenv-safe": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/dotenv-safe/-/dotenv-safe-6.1.0.tgz", + "integrity": "sha512-O02OUTS+XmoRNZR4kRjJ9jlUGvQoXpMeTVVEBc8hUtgvPTgVZpsZH7TOocq4RVDpPrs2xGPwj6gIWjqRX+ErHA==", + "dependencies": { + "dotenv": "^6.1.0" + } + }, + "node_modules/dtype": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/dtype/-/dtype-2.0.0.tgz", + "integrity": "sha1-zQUjI84GFETs0uj1dI9popvihDQ=", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "node_modules/duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/duplexify/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "optional": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" + }, + "node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-stream": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-0.5.3.tgz", + "integrity": "sha1-t3uTCfcQet3+q2PwwOr9jbC9jBw=", + "dependencies": { + "optimist": "0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/event-stream/node_modules/optimist": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.2.8.tgz", + "integrity": "sha1-6YGrfiaLRXlIWTtVZ0wJmoFcrDE=", + "dependencies": { + "wordwrap": ">=0.0.1 <0.1.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=" + }, + "node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dependencies": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dependencies": { + "fill-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-range/node_modules/fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dependencies": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-range/node_modules/is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-range/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-range/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/expect/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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/expect/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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/expect/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==" + }, + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-formidable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/express-formidable/-/express-formidable-1.2.0.tgz", + "integrity": "sha512-w1vXjF3gb50UKTNkFaW8/4rqY4dUrKfZ1sAZzwAF9YxCAgj/29QZsycf71di0GkskrZOAkubk9pvGYfxyAMYiw==", + "dependencies": { + "formidable": "^1.0.17" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/express-routes-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/express-routes-map/-/express-routes-map-0.0.1.tgz", + "integrity": "sha1-HAD/8sKu9/0kkrB/ZYYE3GoA+k4=" + }, + "node_modules/express/node_modules/mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dependencies": { + "mime-db": "1.40.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/express/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/express/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "dependencies": { + "type": "^2.0.0" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.3.0.tgz", + "integrity": "sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg==" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "engines": [ + "node >=0.6.0" + ], + "optional": true + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "optional": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "optional": true + }, + "node_modules/fast-text-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", + "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" + }, + "node_modules/file-base64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-base64/-/file-base64-1.0.0.tgz", + "integrity": "sha1-eDpVEUzVF6kuX3hXvqDFj6fh0Uc=", + "dependencies": { + "into-stream": "^2.0.0" + } + }, + "node_modules/file-exists": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/file-exists/-/file-exists-3.0.2.tgz", + "integrity": "sha1-HWs8GXgQtD+FiS5+7UeKY3sathQ=", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/file-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/file-match/-/file-match-1.0.2.tgz", + "integrity": "sha1-ycrSZdLIrfOoFHWw30dYWQafrvc=", + "dependencies": { + "utils-extend": "^1.0.6" + } + }, + "node_modules/file-system": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/file-system/-/file-system-2.2.2.tgz", + "integrity": "sha1-fWWDPjojR9zZVqgTxncVPtPt2Yc=", + "dependencies": { + "file-match": "^1.0.1", + "utils-extend": "^1.0.4" + } + }, + "node_modules/file-type": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-7.7.1.tgz", + "integrity": "sha512-bTrKkzzZI6wH+NXhyD3SOXtb2zXTw2SbwI2RxUlRcXVsnN7jNL5hJzVQLYv7FOQhxFkK4XWdAflEaWFpaLLWpQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90=", + "optional": true + }, + "node_modules/filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/flatiron": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/flatiron/-/flatiron-0.4.3.tgz", + "integrity": "sha1-JIz3mj2n19w3nioRySonGcu1QPY=", + "dependencies": { + "broadway": "~0.3.2", + "director": "1.2.7", + "optimist": "0.6.0", + "prompt": "0.2.14" + }, + "bin": { + "flatiron": "bin/flatiron" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/flatiron/node_modules/optimist": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.0.tgz", + "integrity": "sha1-aUJIJvNAX3nxQub8PZrljU27kgA=", + "dependencies": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "node_modules/flatten-vertex-data": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/flatten-vertex-data/-/flatten-vertex-data-1.0.2.tgz", + "integrity": "sha1-iJ/WC+pQYAbKM5Ve4RBRdftiAhk=", + "dependencies": { + "dtype": "^2.0.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz", + "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/forever/-/forever-1.0.0.tgz", + "integrity": "sha512-ZaNWo5aMdtfui5GZWxaPcmFPW/TaaJZgGE0/p47lhn0FGRhFehuG338zuUURIqjn0dZEmgNPUAahZMOdykEAiw==", + "dependencies": { + "async": "~0.2.9", + "cliff": "~0.1.9", + "clone": "^1.0.2", + "colors": "~0.6.2", + "flatiron": "~0.4.2", + "forever-monitor": "~1.7.0", + "mkdirp": "0.x.x", + "nconf": "~0.6.9", + "nssocket": "~0.5.1", + "object-assign": "^3.0.0", + "optimist": "~0.6.0", + "path-is-absolute": "~1.0.0", + "prettyjson": "^1.1.2", + "shush": "^1.0.0", + "utile": "~0.3.0", + "winston": "~0.8.1" + }, + "bin": { + "forever": "bin/forever" + }, + "engines": { + "node": ">= 0.8.x" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/forever-monitor": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/forever-monitor/-/forever-monitor-1.7.1.tgz", + "integrity": "sha1-XYIPSjp42y2BriZx8Vi56GoJG7g=", + "dependencies": { + "broadway": "~0.3.6", + "chokidar": "^1.0.1", + "minimatch": "~3.0.2", + "ps-tree": "0.0.x", + "utile": "~0.2.1" + }, + "engines": { + "node": ">= 0.8.x" + } + }, + "node_modules/forever-monitor/node_modules/anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dependencies": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "node_modules/forever-monitor/node_modules/arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dependencies": { + "arr-flatten": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-monitor/node_modules/array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-monitor/node_modules/async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + }, + "node_modules/forever-monitor/node_modules/braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dependencies": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-monitor/node_modules/chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "dependencies": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + }, + "optionalDependencies": { + "fsevents": "^1.0.0" + } + }, + "node_modules/forever-monitor/node_modules/expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dependencies": { + "is-posix-bracket": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-monitor/node_modules/extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-monitor/node_modules/glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dependencies": { + "is-glob": "^2.0.0" + } + }, + "node_modules/forever-monitor/node_modules/is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-monitor/node_modules/is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-monitor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-monitor/node_modules/micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dependencies": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-monitor/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-monitor/node_modules/utile": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/utile/-/utile-0.2.1.tgz", + "integrity": "sha1-kwyI6ZCY1iIINMNWy9mncFItkNc=", + "dependencies": { + "async": "~0.2.9", + "deep-equal": "*", + "i": "0.3.x", + "mkdirp": "0.x.x", + "ncp": "0.4.x", + "rimraf": "2.x.x" + }, + "engines": { + "node": ">= 0.6.4" + } + }, + "node_modules/forever/node_modules/async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + }, + "node_modules/forever/node_modules/object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/formidable": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", + "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau" + }, + "node_modules/forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", + "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=" + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-extra/node_modules/graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/fsevents": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", + "bundleDependencies": [ + "node-pre-gyp" + ], + "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/fsevents/node_modules/abbrev": { + "version": "1.1.1", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/ansi-regex": { + "version": "2.1.1", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "inBundle": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/aproba": { + "version": "1.2.0", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/are-we-there-yet": { + "version": "1.1.5", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "inBundle": true, + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/fsevents/node_modules/balanced-match": { + "version": "1.0.0", + "integrity": "sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/brace-expansion": { + "version": "1.1.11", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "inBundle": true, + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/fsevents/node_modules/chownr": { + "version": "1.1.1", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/code-point-at": { + "version": "1.1.0", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "inBundle": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/concat-map": { + "version": "0.0.1", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/console-control-strings": { + "version": "1.1.0", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/core-util-is": { + "version": "1.0.2", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/debug": { + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "inBundle": true, + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/fsevents/node_modules/deep-extend": { + "version": "0.6.0", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "inBundle": true, + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/fsevents/node_modules/delegates": { + "version": "1.0.0", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/detect-libc": { + "version": "1.0.3", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "inBundle": true, + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/fsevents/node_modules/fs-minipass": { + "version": "1.2.5", + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "inBundle": true, + "optional": true, + "dependencies": { + "minipass": "^2.2.1" + } + }, + "node_modules/fsevents/node_modules/fs.realpath": { + "version": "1.0.0", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/gauge": { + "version": "2.7.4", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "inBundle": true, + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/fsevents/node_modules/glob": { + "version": "7.1.3", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "inBundle": true, + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fsevents/node_modules/has-unicode": { + "version": "2.0.1", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/iconv-lite": { + "version": "0.4.24", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "inBundle": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/ignore-walk": { + "version": "3.0.1", + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "inBundle": true, + "optional": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/fsevents/node_modules/inflight": { + "version": "1.0.6", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "inBundle": true, + "optional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/fsevents/node_modules/inherits": { + "version": "2.0.3", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/ini": { + "version": "1.3.5", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "deprecated": "Please update to ini >=1.3.6 to avoid a prototype pollution issue", + "inBundle": true, + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/fsevents/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "inBundle": true, + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/isarray": { + "version": "1.0.0", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/minimatch": { + "version": "3.0.4", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "inBundle": true, + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fsevents/node_modules/minimist": { + "version": "0.0.8", + "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/minipass": { + "version": "2.3.5", + "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "inBundle": true, + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/fsevents/node_modules/minizlib": { + "version": "1.2.1", + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "inBundle": true, + "optional": true, + "dependencies": { + "minipass": "^2.2.1" + } + }, + "node_modules/fsevents/node_modules/mkdirp": { + "version": "0.5.1", + "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "inBundle": true, + "optional": true, + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/fsevents/node_modules/ms": { + "version": "2.0.0", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/needle": { + "version": "2.2.4", + "integrity": "sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA==", + "inBundle": true, + "optional": true, + "dependencies": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 0.10.x" + } + }, + "node_modules/fsevents/node_modules/node-pre-gyp": { + "version": "0.10.3", + "integrity": "sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A==", + "deprecated": "Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future", + "inBundle": true, + "optional": true, + "dependencies": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/fsevents/node_modules/nopt": { + "version": "4.0.1", + "integrity": "sha512-+5XZFpQZEY0cg5JaxLwGxDlKNKYxuXwGt8/Oi3UXm5/4ymrJve9d2CURituxv3rSrVCGZj4m1U1JlHTdcKt2Ng==", + "inBundle": true, + "optional": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/fsevents/node_modules/npm-bundled": { + "version": "1.0.5", + "integrity": "sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/npm-packlist": { + "version": "1.2.0", + "integrity": "sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ==", + "inBundle": true, + "optional": true, + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "node_modules/fsevents/node_modules/npmlog": { + "version": "4.1.2", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "inBundle": true, + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/fsevents/node_modules/number-is-nan": { + "version": "1.0.1", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "inBundle": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/object-assign": { + "version": "4.1.1", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "inBundle": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/once": { + "version": "1.4.0", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "inBundle": true, + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/fsevents/node_modules/os-homedir": { + "version": "1.0.2", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "inBundle": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/os-tmpdir": { + "version": "1.0.2", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "inBundle": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/osenv": { + "version": "0.1.5", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "inBundle": true, + "optional": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/fsevents/node_modules/path-is-absolute": { + "version": "1.0.1", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "inBundle": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/process-nextick-args": { + "version": "2.0.0", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/rc": { + "version": "1.2.8", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "inBundle": true, + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/fsevents/node_modules/rc/node_modules/minimist": { + "version": "1.2.0", + "integrity": "sha512-7Wl+Jz+IGWuSdgsQEJ4JunV0si/iMhg42MnQQG6h1R6TNeVenp4U9x5CC5v/gYqz/fENLQITAWXidNtVL0NNbw==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/readable-stream": { + "version": "2.3.6", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "inBundle": true, + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/fsevents/node_modules/rimraf": { + "version": "2.6.3", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "inBundle": true, + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/fsevents/node_modules/safe-buffer": { + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/safer-buffer": { + "version": "2.1.2", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/sax": { + "version": "1.2.4", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/semver": { + "version": "5.6.0", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "inBundle": true, + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/fsevents/node_modules/set-blocking": { + "version": "2.0.0", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/signal-exit": { + "version": "3.0.2", + "integrity": "sha512-meQNNykwecVxdu1RlYMKpQx4+wefIYpmxi6gexo/KAbwquJrBUrBmKYJrE8KFkVQAAVWEnwNdu21PgrD77J3xA==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/string_decoder": { + "version": "1.1.1", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "inBundle": true, + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/fsevents/node_modules/string-width": { + "version": "1.0.2", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "inBundle": true, + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/strip-ansi": { + "version": "3.0.1", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "inBundle": true, + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/strip-json-comments": { + "version": "2.0.1", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "inBundle": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/tar": { + "version": "4.4.8", + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "inBundle": true, + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/fsevents/node_modules/util-deprecate": { + "version": "1.0.2", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/wide-align": { + "version": "1.1.3", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "inBundle": true, + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/fsevents/node_modules/wrappy": { + "version": "1.0.2", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "inBundle": true, + "optional": true + }, + "node_modules/fsevents/node_modules/yallist": { + "version": "3.0.3", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "inBundle": true, + "optional": true + }, + "node_modules/fstream": { + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-0.1.31.tgz", + "integrity": "sha1-czfwWPu7vvqMn1YaKMqwhJICyYg=", + "dependencies": { + "graceful-fs": "~3.0.2", + "inherits": "~2.0.0", + "mkdirp": "0.5", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gaxios": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.1.0.tgz", + "integrity": "sha512-vb0to8xzGnA2qcgywAjtshOKKVDf2eQhJoiL6fHhgW5tVN7wNk7egnYIO9zotfn3lQ3De1VPdf7V5/BWfCtCmg==", + "dependencies": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gaxios/node_modules/is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/gcp-metadata": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.1.tgz", + "integrity": "sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw==", + "dependencies": { + "gaxios": "^4.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/generic-pool": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.7.1.tgz", + "integrity": "sha512-ug6DAZoNgWm6q5KhPFA+hzXfBLFQu5sTXxPpv44DmE0A2g+CiHoq9LTVdkXpZMkYVMoGw83F6W+WT0h0MFMK/w==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "engines": { + "node": ">=4" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dependencies": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-base/node_modules/glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dependencies": { + "is-glob": "^2.0.0" + } + }, + "node_modules/glob-base/node_modules/is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-base/node_modules/is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dependencies": { + "ini": "^1.3.4" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/google-auth-library": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", + "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", + "dependencies": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/google-auth-library/node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-auth-library/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-auth-library/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/google-auth-library/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/google-gax": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.10.0.tgz", + "integrity": "sha512-K+1JK5ofNl5k30LsI8UQb/DeLMEbhL/SWirCx0L9pnMcApSfAjRAO7yajXT5X1vicxDBnNSwKs+cu4elxpYraw==", + "dependencies": { + "@grpc/grpc-js": "~1.2.0", + "@grpc/proto-loader": "^0.5.1", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "fast-text-encoding": "^1.0.3", + "google-auth-library": "^6.1.3", + "is-stream-ended": "^0.1.4", + "node-fetch": "^2.6.1", + "protobufjs": "^6.10.2", + "retry-request": "^4.0.0" + }, + "bin": { + "compileProtos": "build/tools/compileProtos.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/google-p12-pem": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz", + "integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==", + "dependencies": { + "node-forge": "^0.10.0" + }, + "bin": { + "gp12-pem": "build/src/bin/gp12-pem.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/google-p12-pem/node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dependencies": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "3.0.11", + "resolved": "http://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", + "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", + "deprecated": "please upgrade to graceful-fs 4 for compatibility with current and future versions of Node.js", + "dependencies": { + "natives": "^1.1.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/gtoken": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.2.1.tgz", + "integrity": "sha512-OY0BfPKe3QnMsY9MzTHTSKn+Vl2l1CcLe6BwDEQj00mbbkl5nyQ/7EUREstg4fQNZ8iYE7br4JJ7TdKeDOPWmw==", + "dependencies": { + "gaxios": "^4.0.0", + "google-p12-pem": "^3.0.3", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gtoken/node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/gtoken/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/gzipme": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/gzipme/-/gzipme-0.1.2.tgz", + "integrity": "sha512-VyCqotMYe8tew1Y99p79U3qoerRyPJ4AaiS8ep4Pe30srW/3mENro7wpxFzII2Le9r7Par4CpkPy3L8qOaeDBQ==", + "dependencies": { + "commander": "2.11.0" + }, + "bin": { + "gzipme": "bin/gzipme" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "deprecated": "this library is no longer supported", + "optional": true, + "dependencies": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "deprecated": "This module moved to @hapi/hawk. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.", + "optional": true, + "dependencies": { + "boom": "4.x.x", + "cryptiles": "3.x.x", + "hoek": "4.x.x", + "sntp": "2.x.x" + }, + "engines": { + "node": ">=4.5.0" + } + }, + "node_modules/hawk/node_modules/hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/i": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz", + "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/i18next": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-3.5.2.tgz", + "integrity": "sha1-kwOQ1cMYzqpIWLUt0OQOayA/n0E=" + }, + "node_modules/i18next-sprintf-postprocessor": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/i18next-sprintf-postprocessor/-/i18next-sprintf-postprocessor-0.2.2.tgz", + "integrity": "sha1-LkCfEENXk4Jpi2otpwzapVHWfqQ=" + }, + "node_modules/ibm-cloud-sdk-core": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/ibm-cloud-sdk-core/-/ibm-cloud-sdk-core-2.7.2.tgz", + "integrity": "sha512-vULI1BO9gki1ALmkjQgz1tcsa/jHRBzpqZBcwDgiwjPcyLTTKGBy8e1XWOvYp3Wog5YKX+kWQwSCJdKjiUHSHg==", + "dependencies": { + "@types/file-type": "~5.2.1", + "@types/isstream": "^0.1.0", + "@types/node": "~10.14.19", + "@types/tough-cookie": "^4.0.0", + "axios": "^0.21.1", + "axios-cookiejar-support": "^1.0.0", + "camelcase": "^5.3.1", + "debug": "^4.1.1", + "dotenv": "^6.2.0", + "expect": "^26.1.0", + "extend": "^3.0.2", + "file-type": "^7.7.1", + "form-data": "^2.3.3", + "isstream": "~0.1.2", + "jsonwebtoken": "^8.5.1", + "lodash.isempty": "^4.4.0", + "mime-types": "~2.1.18", + "object.omit": "~3.0.0", + "object.pick": "~1.3.0", + "semver": "^6.2.0", + "tough-cookie": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ibm-cloud-sdk-core/node_modules/@types/node": { + "version": "10.14.22", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.22.tgz", + "integrity": "sha512-9taxKC944BqoTVjE+UT3pQH0nHZlTvITwfsOZqyc+R3sfJuxaTtxWjfn1K2UlxyPcKHf0rnaXcVFrS9F9vf0bw==" + }, + "node_modules/ibm-cloud-sdk-core/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ibm-cloud-sdk-core/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/ibm-cloud-sdk-core/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ibm-cloud-sdk-core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ibm-cloud-sdk-core/node_modules/object.omit": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-3.0.0.tgz", + "integrity": "sha512-EO+BCv6LJfu+gBIF3ggLicFebFLN5zqzz/WWJlMFfkMyGth+oBkhxzDl0wx2W4GkLzuQs/FsSkXZb2IMWQqmBQ==", + "dependencies": { + "is-extendable": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ibm-cloud-sdk-core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/ibm-cloud-sdk-core/node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ibm-watson": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ibm-watson/-/ibm-watson-6.0.0.tgz", + "integrity": "sha512-jycUmtCBaRXtE2x9q5jtPGVM0VifO3fRJ8weXiZSDVX4jYzvld6AKKqfzDhmWWEFiJ8VTfzllUBE6BA7agUI3Q==", + "dependencies": { + "@types/async": "^3.2.1", + "@types/extend": "^3.0.1", + "@types/isstream": "^0.1.0", + "@types/node": "^13.13.4", + "@types/websocket": "^1.0.0", + "async": "^3.2.0", + "camelcase": "^6.0.0", + "extend": "~3.0.2", + "ibm-cloud-sdk-core": "^2.7.0", + "isstream": "~0.1.2", + "websocket": "^1.0.28" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/ibm-watson/node_modules/@types/node": { + "version": "13.13.42", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.42.tgz", + "integrity": "sha512-g+w2QgbW7k2CWLOXzQXbO37a7v5P9ObPvYahKphdBLV5aqpbVZRhTpWCT0SMRqX1i30Aig791ZmIM2fJGL2S8A==" + }, + "node_modules/ibm-watson/node_modules/async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "node_modules/ibm-watson/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "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": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + }, + "node_modules/import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "deprecated": "Please update to ini >=1.3.6 to avoid a prototype pollution issue", + "engines": { + "node": "*" + } + }, + "node_modules/interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/into-stream": { + "version": "2.0.1", + "resolved": "http://registry.npmjs.org/into-stream/-/into-stream-2.0.1.tgz", + "integrity": "sha1-25sANpRFPq4JHYpchMwRUHt4HTE=", + "dependencies": { + "from2": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-audio-buffer": { + "version": "1.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-audio-buffer/-/is-audio-buffer-1.1.0.tgz", + "integrity": "sha1-9MfydNIBgPmT+bFlB2jLd77dRHA=" + }, + "node_modules/is-base64": { + "version": "0.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-base64/-/is-base64-0.1.0.tgz", + "integrity": "sha1-pvIGEMbvSGOlHLoyvAIiVEuTJiI=" + }, + "node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-blob": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-blob/-/is-blob-2.0.1.tgz", + "integrity": "sha1-f95X74eCoVS8Dzvcqg/9zLbDN2c=", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dependencies": { + "ci-info": "^1.5.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dependencies": { + "is-primitive": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dependencies": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-installed-globally/node_modules/is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dependencies": { + "path-is-inside": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.1.0.tgz", + "integrity": "sha512-Sc5j3/YnM8tDeyCsVeKlm/0p95075DyLmDEIkSgQ7mXkrOX+uTCtmQFm0CYzVyJwcCCmO3k8qfJt17SxQwB5Zw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dependencies": { + "is-path-inside": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dependencies": { + "path-is-inside": "^1.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dependencies": { + "has": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream-ended": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", + "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==" + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dependencies": { + "punycode": "2.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "node_modules/jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-diff/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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/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==" + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/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==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-matcher-utils/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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/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==" + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/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==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-message-util/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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/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==" + }, + "node_modules/jest-message-util/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jest-message-util/node_modules/micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/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==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/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==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dependencies": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/js-base64": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.1.tgz", + "integrity": "sha512-G5x2saUTupU9D/xBY9snJs3TxvwX8EkpLFiYlPpDt/VmMHOXprnSU1nxiTmFbijCX4BLF/cMRIfAcC5BiMYgFQ==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/jsbarcode": { + "version": "3.11.5", + "resolved": "https://registry.npmjs.org/jsbarcode/-/jsbarcode-3.11.5.tgz", + "integrity": "sha512-zv3KsH51zD00I/LrFzFSM6dst7rDn0vIMzaiZFL7qusTjPZiPtxg3zxetp0RR7obmjTw4f6NyGgbdkBCgZUIrA==", + "bin": { + "auto.js": "bin/barcodes/CODE128/auto.js", + "Barcode.js": "bin/barcodes/Barcode.js", + "barcodes": "bin/barcodes", + "canvas.js": "bin/renderers/canvas.js", + "checksums.js": "bin/barcodes/MSI/checksums.js", + "codabar": "bin/barcodes/codabar", + "CODE128": "bin/barcodes/CODE128", + "CODE128_AUTO.js": "bin/barcodes/CODE128/CODE128_AUTO.js", + "CODE128.js": "bin/barcodes/CODE128/CODE128.js", + "CODE128A.js": "bin/barcodes/CODE128/CODE128A.js", + "CODE128B.js": "bin/barcodes/CODE128/CODE128B.js", + "CODE128C.js": "bin/barcodes/CODE128/CODE128C.js", + "CODE39": "bin/barcodes/CODE39", + "constants.js": "bin/barcodes/ITF/constants.js", + "defaults.js": "bin/options/defaults.js", + "EAN_UPC": "bin/barcodes/EAN_UPC", + "EAN.js": "bin/barcodes/EAN_UPC/EAN.js", + "EAN13.js": "bin/barcodes/EAN_UPC/EAN13.js", + "EAN2.js": "bin/barcodes/EAN_UPC/EAN2.js", + "EAN5.js": "bin/barcodes/EAN_UPC/EAN5.js", + "EAN8.js": "bin/barcodes/EAN_UPC/EAN8.js", + "encoder.js": "bin/barcodes/EAN_UPC/encoder.js", + "ErrorHandler.js": "bin/exceptions/ErrorHandler.js", + "exceptions": "bin/exceptions", + "exceptions.js": "bin/exceptions/exceptions.js", + "fixOptions.js": "bin/help/fixOptions.js", + "GenericBarcode": "bin/barcodes/GenericBarcode", + "getOptionsFromElement.js": "bin/help/getOptionsFromElement.js", + "getRenderProperties.js": "bin/help/getRenderProperties.js", + "help": "bin/help", + "index.js": "bin/renderers/index.js", + "index.tmp.js": "bin/barcodes/index.tmp.js", + "ITF": "bin/barcodes/ITF", + "ITF.js": "bin/barcodes/ITF/ITF.js", + "ITF14.js": "bin/barcodes/ITF/ITF14.js", + "JsBarcode.js": "bin/JsBarcode.js", + "linearizeEncodings.js": "bin/help/linearizeEncodings.js", + "merge.js": "bin/help/merge.js", + "MSI": "bin/barcodes/MSI", + "MSI.js": "bin/barcodes/MSI/MSI.js", + "MSI10.js": "bin/barcodes/MSI/MSI10.js", + "MSI1010.js": "bin/barcodes/MSI/MSI1010.js", + "MSI11.js": "bin/barcodes/MSI/MSI11.js", + "MSI1110.js": "bin/barcodes/MSI/MSI1110.js", + "object.js": "bin/renderers/object.js", + "options": "bin/options", + "optionsFromStrings.js": "bin/help/optionsFromStrings.js", + "pharmacode": "bin/barcodes/pharmacode", + "renderers": "bin/renderers", + "shared.js": "bin/renderers/shared.js", + "svg.js": "bin/renderers/svg.js", + "UPC.js": "bin/barcodes/EAN_UPC/UPC.js", + "UPCE.js": "bin/barcodes/EAN_UPC/UPCE.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-bigint/node_modules/bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "engines": { + "node": "*" + } + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "optional": true + }, + "node_modules/json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "optional": true + }, + "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": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "optional": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonfile/node_modules/graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "optional": true + }, + "node_modules/jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "engines": { + "node": "*" + } + }, + "node_modules/jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + } + }, + "node_modules/jsonwebtoken/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/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "engines": [ + "node >=0.6.0" + ], + "optional": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/jszip": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.0.tgz", + "integrity": "sha512-LDfVtOLtOxb9RXkYOwPyNBTQDL4eUbqahtoY6x07GiDJHwSYvn8sHHIw8wINImV3MqbMNve2gSuM1DDqEKk09Q==", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dependencies": { + "package-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lazy": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", + "integrity": "sha1-2qBoIGKCVCwIgojpdcKXwa53tpA=", + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=" + }, + "node_modules/lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "node_modules/lodash._baseiteratee": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash._baseiteratee/-/lodash._baseiteratee-4.7.0.tgz", + "integrity": "sha1-NKm1VDVycnw9sueO2uPA6eZr0QI=", + "dependencies": { + "lodash._stringtopath": "~4.8.0" + } + }, + "node_modules/lodash._basetostring": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz", + "integrity": "sha1-kyfJ3FFYhmt/pLnUL0Y45XZt2d8=" + }, + "node_modules/lodash._baseuniq": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz", + "integrity": "sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg=", + "dependencies": { + "lodash._createset": "~4.0.0", + "lodash._root": "~3.0.0" + } + }, + "node_modules/lodash._createset": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/lodash._createset/-/lodash._createset-4.0.3.tgz", + "integrity": "sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=" + }, + "node_modules/lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" + }, + "node_modules/lodash._stringtopath": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/lodash._stringtopath/-/lodash._stringtopath-4.8.0.tgz", + "integrity": "sha1-lBvPDmQmbl/B1m/tCmlZVExXaCQ=", + "dependencies": { + "lodash._basetostring": "~4.12.0" + } + }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "node_modules/lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" + }, + "node_modules/lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" + }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" + }, + "node_modules/lodash.uniqby": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.5.0.tgz", + "integrity": "sha1-o6F7v2LutiQPSRhG6XwcTipeHiE=", + "dependencies": { + "lodash._baseiteratee": "~4.7.0", + "lodash._baseuniq": "~4.6.0" + } + }, + "node_modules/lokijs": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.6.tgz", + "integrity": "sha512-xJoDXy8TASTjmXMKr4F8vvNUCu4dqlwY5gmn0g5BajGt1GM3goDCafNiGAh/sfrWgkfWu1J4OfsxWm8yrWweJA==" + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/macos-release": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.2.0.tgz", + "integrity": "sha512-iV2IDxZaX8dIcM7fG6cI46uNmHUxHE4yN+Z8tKHAW1TBPMZDIKHf/3L+YnOuj/FK9il14UaVdHmiQ1tsi90ltA==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/make-dir/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "engines": { + "node": ">=4" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/match-stream": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/match-stream/-/match-stream-0.0.2.tgz", + "integrity": "sha1-mesFAJOzTf+t5CG5rAtBCpz6F88=", + "dependencies": { + "buffers": "~0.1.1", + "readable-stream": "~1.0.0" + } + }, + "node_modules/match-stream/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/match-stream/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/match-stream/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "bin": { + "mime": "cli.js" + } + }, + "node_modules/mime-db": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", + "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.19", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", + "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", + "dependencies": { + "mime-db": "~1.35.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "node_modules/minipass": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/minizip-asm.js": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/minizip-asm.js/-/minizip-asm.js-1.0.10.tgz", + "integrity": "sha1-WdSmMaRmIXKSUf2OtI5aV8Qx3Vs=" + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "deprecated": "Critical bug fixed in v2.0.1, please upgrade to the latest version.", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mp3": { + "version": "0.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mp3/-/mp3-0.1.0.tgz", + "integrity": "sha1-5T5HI+NGmO4//dzbYL+INWpJEME=", + "peerDependencies": { + "av": "~0.4.0" + } + }, + "node_modules/mp3-to-wav": { + "version": "0.1.11", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mp3-to-wav/-/mp3-to-wav-0.1.11.tgz", + "integrity": "sha1-uFB45xWhQzz1GsTgBfJEqTj5pX4=", + "dependencies": { + "audio-buffer-from": "^1.1.1", + "av": "^0.4.9", + "fs-extra": "^7.0.1", + "is-buffer": "^2.0.3", + "mp3": "^0.1.0", + "node-wav": "0.0.2", + "to-array-buffer": "^3.1.1", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/mp3-to-wav/node_modules/is-buffer": { + "version": "2.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha1-PlcvI8hBGlz9lVfISeNmXgspBiM=", + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/mssql": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mssql/-/mssql-4.3.7.tgz", + "integrity": "sha512-+cs1uBD2Hut6UNeCnJHUeikWKIEhMTlr8s1bOw2BaVTPcyau1fFUqt1rQRilEq/GsyGkkzrE+TKw0jlvbW5cWQ==", + "dependencies": { + "debug": "^3.2.6", + "generic-pool": "^3.6.1", + "tedious": "^2.7.1" + }, + "bin": { + "mssql": "bin/mssql" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mssql/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/mssql/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/multer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.1.tgz", + "integrity": "sha512-zzOLNRxzszwd+61JFuAo0fxdQfvku12aNJgnla0AQ+hHxFmfc/B7jBVuPr5Rmvu46Jze/iJrFpSOsD7afO8SDw==", + "deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.10.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==" + }, + "node_modules/mysql": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", + "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", + "dependencies": { + "bignumber.js": "9.0.0", + "readable-stream": "2.3.7", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mysql/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/mysql/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/nan": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", + "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==", + "optional": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/native-duplexpair": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/native-duplexpair/-/native-duplexpair-1.0.0.tgz", + "integrity": "sha1-eJkHjmS/PIo9cyYBs9QP8F21j6A=" + }, + "node_modules/natives": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz", + "integrity": "sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==", + "deprecated": "This module relies on Node.js's internals and will break at some point. Do not use it, and update to graceful-fs@4.x." + }, + "node_modules/nconf": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.6.9.tgz", + "integrity": "sha1-lXDvFe1vmuays8jV5xtm0xk81mE=", + "dependencies": { + "async": "0.2.9", + "ini": "1.x.x", + "optimist": "0.6.0" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/nconf/node_modules/async": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.9.tgz", + "integrity": "sha1-32MGD789Myhqdqr21Vophtn/hhk=" + }, + "node_modules/nconf/node_modules/optimist": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.0.tgz", + "integrity": "sha1-aUJIJvNAX3nxQub8PZrljU27kgA=", + "dependencies": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "node_modules/ncp": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", + "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=", + "bin": { + "ncp": "bin/ncp" + } + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "node_modules/ng2-file-upload": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ng2-file-upload/-/ng2-file-upload-1.3.0.tgz", + "integrity": "sha512-Pudxik6LWYsT8hNiEW7RfjgGWAnvfQywxwJYMdt1snTUe+KnlRc/QqPv3QEQW6plXTanuLkYz/TbqilSfSHOsw==", + "peerDependencies": { + "@angular/common": "^2.3.1 || >=4.0.0", + "@angular/core": "^2.3.1 || >=4.0.0" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node_modules/node-7z": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/node-7z/-/node-7z-1.1.0.tgz", + "integrity": "sha512-pVU+HitGdO14m/rwGAwp3xMXScNUyc04plFvCPhof4QIj93LrILrD2Dz4ODDbVrtqxbx9jxGbJJnbSwr43DQHw==", + "dependencies": { + "cross-spawn": "^6.0.4", + "debug": "^4.1.1", + "lodash": "^4.17.11", + "normalize-path": "^3.0.0", + "regexp-polyfill": "^1.0.1" + } + }, + "node_modules/node-7z-forall": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-7z-forall/-/node-7z-forall-1.0.0.tgz", + "integrity": "sha512-ugiNr51RlQSgqLiGVvw3waZQtjutz61Ka2Lojp/r/Ocso23naGU3pR8ELUZklolRogqLuB3JV7E9Zibuo+3o/w==", + "deprecated": "use node-7z-archive", + "hasInstallScript": true, + "dependencies": { + "cross-spawn": "^6.0.5", + "when": "^3.7.8" + }, + "optionalDependencies": { + "all-unpacker": "^0.1.2", + "fs-extra": "^7.0.0", + "macos-release": "^2.0.0", + "node-wget": "^0.4.2", + "retrying-promise": "^0.0.4", + "system-installer": "^1.1.0" + } + }, + "node_modules/node-7z-forall/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/node-7z/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/node-7z/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/node-7z/node_modules/lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "node_modules/node-7z/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-forge": { + "version": "0.7.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/node-forge/-/node-forge-0.7.6.tgz", + "integrity": "sha1-/fO0GK7h+U8O9kLNY0hsd8qXJKw=", + "engines": { + "node": "*" + } + }, + "node_modules/node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-lame": { + "version": "1.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/node-lame/-/node-lame-1.2.0.tgz", + "integrity": "sha1-smZrfavboOzlct8/0e87/hCfqhg=", + "engines": { + "node": ">=10.13" + } + }, + "node_modules/node-unrar": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/node-unrar/-/node-unrar-0.1.5.tgz", + "integrity": "sha1-pA7BsK+RzO+b5A+VXEyp79ILfVI=", + "dependencies": { + "shell-escape": "^0.2.0" + } + }, + "node_modules/node-unrar-js": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/node-unrar-js/-/node-unrar-js-0.8.1.tgz", + "integrity": "sha1-NRiO96rrq4VC/d0jfUBA8fP+5u4=" + }, + "node_modules/node-wav": { + "version": "0.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/node-wav/-/node-wav-0.0.2.tgz", + "integrity": "sha1-ictjz4zWbsirRV9bpIZOX8tGBeg=", + "engines": { + "node": ">=4.4.0" + } + }, + "node_modules/node-wget": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/node-wget/-/node-wget-0.4.3.tgz", + "integrity": "sha512-sltt/nc4NJeI4CuncyBFZZ7W4Wz3Q1oM8h27mYEbj5OihXMsuqJpplPl0WUZTSpXy8AyGczT08jIBsXHxdCtgg==", + "optional": true, + "dependencies": { + "request": "~2.85.0" + }, + "bin": { + "wget": "cli.js" + }, + "engines": { + "node": ">=0.8.6" + } + }, + "node_modules/nodemailer": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-4.7.0.tgz", + "integrity": "sha512-IludxDypFpYw4xpzKdMAozBSkzKHmNBvGanUREjJItgJ2NYcK/s8+PggVhj7c2yGFQykKsnnmv1+Aqo0ZfjHmw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/nodemon": { + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", + "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", + "hasInstallScript": true, + "dependencies": { + "chokidar": "^2.1.8", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.5.0" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/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/nodemon/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/nssocket": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.5.3.tgz", + "integrity": "sha1-iDyi7GBfXtZKTVGQsmJUAZKPj40=", + "dependencies": { + "eventemitter2": "~0.4.14", + "lazy": "~1.0.11" + }, + "engines": { + "node": ">= 0.8.x" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-is": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", + "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dependencies": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dependencies": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "node_modules/over": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/over/-/over-0.0.5.tgz", + "integrity": "sha1-8phS5w/X4l82DgE6jsRMgq7bVwg=", + "engines": { + "node": "*" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dependencies": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dependencies": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-glob/node_modules/is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-glob/node_modules/is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "node_modules/pcm-convert": { + "version": "1.6.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pcm-convert/-/pcm-convert-1.6.5.tgz", + "integrity": "sha1-gbXy0ML7OG7bi59pziN04JOut8w=", + "dependencies": { + "audio-format": "^2.3.2", + "is-audio-buffer": "^1.0.11", + "is-buffer": "^1.1.5", + "object-assign": "^4.1.1" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "optional": true + }, + "node_modules/pick-by-alias": { + "version": "1.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pick-by-alias/-/pick-by-alias-1.2.0.tgz", + "integrity": "sha1-X3yysfIabh6ISgyHhVqko3NhEHs=" + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkginfo": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", + "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/pretty-format/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format/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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/pretty-format/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==" + }, + "node_modules/prettyjson": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.1.tgz", + "integrity": "sha1-/P+rQdGcq0365eV15kJGYZsS0ok=", + "dependencies": { + "colors": "^1.1.2", + "minimist": "^1.2.0" + }, + "bin": { + "prettyjson": "bin/prettyjson" + } + }, + "node_modules/prettyjson/node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/prettyjson/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "node_modules/process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "node_modules/prompt": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/prompt/-/prompt-0.2.14.tgz", + "integrity": "sha1-V3VPZPVD/XsIRXB8gY7OYY8F/9w=", + "dependencies": { + "pkginfo": "0.x.x", + "read": "1.0.x", + "revalidator": "0.1.x", + "utile": "0.2.x", + "winston": "0.8.x" + }, + "engines": { + "node": ">= 0.6.6" + } + }, + "node_modules/prompt/node_modules/async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + }, + "node_modules/prompt/node_modules/utile": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/utile/-/utile-0.2.1.tgz", + "integrity": "sha1-kwyI6ZCY1iIINMNWy9mncFItkNc=", + "dependencies": { + "async": "~0.2.9", + "deep-equal": "*", + "i": "0.3.x", + "mkdirp": "0.x.x", + "ncp": "0.4.x", + "rimraf": "2.x.x" + }, + "engines": { + "node": ">= 0.6.4" + } + }, + "node_modules/proper-lockfile": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-2.0.1.tgz", + "integrity": "sha1-FZ+wYZPTIAP0s2kd0uwaY0qoDR0=", + "dependencies": { + "graceful-fs": "^4.1.2", + "retry": "^0.10.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/proper-lockfile/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, + "node_modules/protobufjs": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", + "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": "^13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/@types/node": { + "version": "13.13.40", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.40.tgz", + "integrity": "sha512-eKaRo87lu1yAXrzEJl0zcJxfUMDT5/mZalFyOkT44rnQps41eS2pfWzbaulSPpQLFNy29bFqn+Y5lOTL8ATlEQ==" + }, + "node_modules/proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ps-tree": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-0.0.3.tgz", + "integrity": "sha1-2/jXUqf+Ivp9WGNWiUmWEOknbdw=", + "dependencies": { + "event-stream": "~0.5" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "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==" + }, + "node_modules/pullstream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pullstream/-/pullstream-0.4.1.tgz", + "integrity": "sha1-1vs79a7Wl+gxFQ6xACwlo/iuExQ=", + "dependencies": { + "over": ">= 0.0.5 < 1", + "readable-stream": "~1.0.31", + "setimmediate": ">= 1.0.2 < 2", + "slice-stream": ">= 1.0.0 < 2" + } + }, + "node_modules/pullstream/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/pullstream/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/pullstream/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "dependencies": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qrcodejs2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/qrcodejs2/-/qrcodejs2-0.0.2.tgz", + "integrity": "sha1-Rlr+Xjnxn6zsuTLBH3oYYQkUauE=" + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" + }, + "node_modules/rand-token": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/rand-token/-/rand-token-0.4.0.tgz", + "integrity": "sha512-FLNNsir2R+XY8LKsZ+8u/w0qZ4sGit7cpNdznsI77cAVob6UlVPueDKRyjJ3W1Q6FJLgAVH98JvlqqpSaL7NEQ==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "dependencies": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/randomatic/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==" + }, + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/readdirp/node_modules/graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "node_modules/regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dependencies": { + "is-equal-shallow": "^0.1.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/regexp-polyfill/-/regexp-polyfill-1.0.1.tgz", + "integrity": "sha512-kyYqOUpy+/MYja6oXu8kNHO2f0BfN/7cb3X3xn2rRGDY8rUUsrti97+BO46TlTOhxDaY7t6AyFERue5x+ZRvcA==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", + "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", + "dependencies": { + "define-properties": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dependencies": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dependencies": { + "rc": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "node_modules/repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/request": { + "version": "2.85.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", + "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "optional": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "hawk": "~6.0.2", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "stringstream": "~0.0.5", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "node_modules/resolve": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", + "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated" + }, + "node_modules/resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dependencies": { + "through": "~2.3.4" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "engines": { + "node": "*" + } + }, + "node_modules/retry-request": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.3.tgz", + "integrity": "sha512-QnRZUpuPNgX0+D1xVxul6DbJ9slvo4Rm6iV/dn63e048MvGbUZiKySVt6Tenp04JqmchxjiLltGerOJys7kJYQ==", + "dependencies": { + "debug": "^4.1.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/retry-request/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/retry-request/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/retrying-promise": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/retrying-promise/-/retrying-promise-0.0.4.tgz", + "integrity": "sha1-k2KkIVHHLZizkkaxrwYdTvqDE6w=", + "optional": true, + "engines": { + "node": ">=5.6.0" + } + }, + "node_modules/revalidator": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz", + "integrity": "sha1-/s5hv6DBtSoga9axgZgYS91SOjs=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rxjs-compat": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.5.2.tgz", + "integrity": "sha512-TRMkTp4FgSxE2HtGvxmgRukh3JqdFM7ejAj1Ti/VdodbPGfWvZR5+KdLKRV9jVDFyu2SknM8RD+PR54KGnoLjg==" + }, + "node_modules/safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dependencies": { + "ret": "~0.1.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==" + }, + "node_modules/sample-rate": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/sample-rate/-/sample-rate-2.0.1.tgz", + "integrity": "sha1-P1CJaSYrLHKaldTUK3laWzNhC9A=" + }, + "node_modules/sanitize-filename": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz", + "integrity": "sha1-YS2hyWRz+gLczaktzVtKsWSmdyo=", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + }, + "node_modules/semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dependencies": { + "semver": "^5.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "node_modules/set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "deprecated": "Critical bug fixed in v3.0.1, please upgrade to the latest version.", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-escape": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/shell-escape/-/shell-escape-0.2.0.tgz", + "integrity": "sha1-aP0CXrBJC09WegJ/C/IkgLX4QTM=" + }, + "node_modules/shelljs": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", + "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shush": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shush/-/shush-1.0.0.tgz", + "integrity": "sha1-wnQVqeRY8v7TmyfPjrN8ADeCtDE=", + "dependencies": { + "caller": "~0.0.1", + "strip-json-comments": "~0.1.1" + } + }, + "node_modules/shush/node_modules/strip-json-comments": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz", + "integrity": "sha1-Fkxk43Coo8wAyeAbU55WmCPw7lQ=", + "bin": { + "strip-json-comments": "cli.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-stream/-/slice-stream-1.0.0.tgz", + "integrity": "sha1-WzO9ZvATsaf4ZGCwPUY97DmtPqA=", + "dependencies": { + "readable-stream": "~1.0.31" + } + }, + "node_modules/slice-stream/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/slice-stream/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/slice-stream/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "deprecated": "This module moved to @hapi/sntp. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.", + "optional": true, + "dependencies": { + "hoek": "4.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/sntp/node_modules/hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dependencies": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated" + }, + "node_modules/speaker": { + "version": "0.3.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/speaker/-/speaker-0.3.1.tgz", + "integrity": "sha1-GZZfh7VL4pFVSCbCyTOOCv1bdZQ=", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "^1.2.1", + "debug": "^2.2.0", + "nan": "^2.2.0", + "readable-stream": "^2.0.5" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==" + }, + "node_modules/sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "optional": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "engines": { + "node": "*" + } + }, + "node_modules/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-to-arraybuffer": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/string-to-arraybuffer/-/string-to-arraybuffer-1.0.2.tgz", + "integrity": "sha1-FhFH+63qAuKLCTUALOxMQPHKfwo=", + "dependencies": { + "atob-lite": "^2.0.0", + "is-base64": "^0.1.0" + } + }, + "node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", + "optional": true + }, + "node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/striptags": { + "version": "3.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/striptags/-/striptags-3.1.1.tgz", + "integrity": "sha1-yMPn/db7S7OjKjt1LltePjgJPr0=" + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" + }, + "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==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/system-installer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/system-installer/-/system-installer-1.1.0.tgz", + "integrity": "sha512-qW+M9sTuZaJhBPMMbo3mHRzLZaIFJwGYcn7K9R/czAtlgF6PiehZ18+sFJGZsRa2MGDJZKKKv0IaiAdV7O8tgw==", + "deprecated": "use node-sys", + "optional": true, + "dependencies": { + "which": "^1.3.1" + }, + "bin": { + "system-installer": "cli.js" + } + }, + "node_modules/tape": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tape/-/tape-2.3.3.tgz", + "integrity": "sha1-Lnzgox3wn41oUWZKcYQuDKUFevc=", + "dependencies": { + "deep-equal": "~0.1.0", + "defined": "~0.0.0", + "inherits": "~2.0.1", + "jsonify": "~0.0.0", + "resumer": "~0.0.0", + "through": "~2.3.4" + }, + "bin": { + "tape": "bin/tape" + } + }, + "node_modules/tape/node_modules/deep-equal": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.1.2.tgz", + "integrity": "sha1-skbCuApXCkfBG+HZvRBw7IeLh84=" + }, + "node_modules/tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/tedious": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/tedious/-/tedious-2.7.1.tgz", + "integrity": "sha512-u3ciATGm5byim91b3+c3MVTvY1zKjDmhUhnBQZXKymT2Vb9w322dziPQY6MhBNyBEcNONPsAMR+7/Uub7NYABQ==", + "dependencies": { + "babel-runtime": "^6.26.0", + "big-number": "0.3.1", + "bl": "^1.2.2", + "depd": "^1.1.2", + "iconv-lite": "^0.4.23", + "native-duplexpair": "^1.0.0", + "punycode": "^2.1.0", + "readable-stream": "^2.3.6", + "sprintf-js": "^1.1.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/teeny-request": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.1.tgz", + "integrity": "sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==", + "dependencies": { + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "stream-events": "^1.0.5", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/teeny-request/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==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dependencies": { + "execa": "^0.7.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-array-buffer": { + "version": "3.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/to-array-buffer/-/to-array-buffer-3.2.0.tgz", + "integrity": "sha1-y2hN1pGnNow7JJwjSNdSJ/fU27Q=", + "dependencies": { + "flatten-vertex-data": "^1.0.2", + "is-blob": "^2.0.1", + "string-to-arraybuffer": "^1.0.0" + } + }, + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "deprecated": "This module has moved and is now available at @hapi/topo. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.", + "dependencies": { + "hoek": "6.x.x" + } + }, + "node_modules/topo/node_modules/hoek": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", + "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==", + "deprecated": "This module has moved and is now available at @hapi/hoek. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues." + }, + "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==", + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dependencies": { + "punycode": "^1.4.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "engines": { + "node": "*" + } + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tus-js-client": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-1.8.0.tgz", + "integrity": "sha512-qPX3TywqzxocTxUZtcS8X7Aik72SVMa0jKi4hWyfvRV+s9raVzzYGaP4MoJGaF0yOgm2+b6jXaVEHogxcJ8LGw==", + "dependencies": { + "buffer-from": "^0.1.1", + "combine-errors": "^3.0.3", + "extend": "^3.0.2", + "js-base64": "^2.4.9", + "lodash.throttle": "^4.1.1", + "proper-lockfile": "^2.0.1", + "url-parse": "^1.4.3" + } + }, + "node_modules/tus-js-client/node_modules/buffer-from": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", + "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==" + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "node_modules/type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha1-qX7nqf9CaRufeD/xvFES/j/KkIA=", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, + "node_modules/union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value/node_modules/set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "deprecated": "Critical bug fixed in v3.0.1, please upgrade to the latest version.", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dependencies": { + "crypto-random-string": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unrar": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/unrar/-/unrar-0.1.7.tgz", + "integrity": "sha1-VGVwCA8EDeMDzNnEf3535zzZ5/g=", + "engines": { + "node": ">= 0.10.21" + } + }, + "node_modules/unrar-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unrar-promise/-/unrar-promise-2.0.1.tgz", + "integrity": "sha512-tZ2ULjeOO9cVEOVMLnYyiV2FYhq3+VaNqnKLHhFNNB+bglQ7iXIJCtKAOcn9n/i4PmIRcoL2lXlECO3thEj5zg==", + "dependencies": { + "@honeo/check": "^1.6.1", + "console-wrapper": "^1.1.0", + "fs-extra": "^7.0.1", + "node-unrar-js": "^0.8.1", + "sanitize-filename": "^1.6.1" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unzip": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/unzip/-/unzip-0.1.11.tgz", + "integrity": "sha1-iXScY7BY19kNYZ+GuYqhU107l/A=", + "dependencies": { + "binary": ">= 0.3.0 < 1", + "fstream": ">= 0.1.30 < 1", + "match-stream": ">= 0.0.2 < 1", + "pullstream": ">= 0.4.1 < 1", + "readable-stream": "~1.0.31", + "setimmediate": ">= 1.0.1 < 2" + } + }, + "node_modules/unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "engines": { + "node": ">=4" + } + }, + "node_modules/unzip/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/unzip/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/unzip/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/unzipper": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.9.15.tgz", + "integrity": "sha512-2aaUvO4RAeHDvOCuEtth7jrHFaCKTSXPqUkXwADaLBzGbgZGzUDccoEdJ5lW+3RmfpOZYNx0Rw6F6PUzM6caIA==", + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/unzipper/node_modules/graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dependencies": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated" + }, + "node_modules/url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", + "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/utile": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/utile/-/utile-0.3.0.tgz", + "integrity": "sha1-E1LDQOuCDk2N26A5pPv6oy7U7zo=", + "dependencies": { + "async": "~0.9.0", + "deep-equal": "~0.2.1", + "i": "0.3.x", + "mkdirp": "0.x.x", + "ncp": "1.0.x", + "rimraf": "2.x.x" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/utile/node_modules/async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, + "node_modules/utile/node_modules/deep-equal": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.2.2.tgz", + "integrity": "sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0=" + }, + "node_modules/utile/node_modules/ncp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz", + "integrity": "sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=", + "bin": { + "ncp": "bin/ncp" + } + }, + "node_modules/utils-extend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/utils-extend/-/utils-extend-1.0.8.tgz", + "integrity": "sha1-zP17ZFQPjpDuIe7Fd2nQZRyril8=" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/validator": { + "version": "9.4.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/validator/-/validator-9.4.1.tgz", + "integrity": "sha1-q/Rm05i1Yc0kMFARLG/x3mzBJmM=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "engines": [ + "node >=0.6.0" + ], + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vimeo": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/vimeo/-/vimeo-2.1.1.tgz", + "integrity": "sha512-6aBlIOdnCgGSigkH54DHsb1n+mW0NIAgxmh+AVEC5hwjfy6zaUtkSIrlMJbYSOwwEfkjpIBR7L8gfWDRmLaEmw==", + "deprecated": "This package was migrated. For the latest features, run: npm i @vimeo/vimeo.", + "dependencies": { + "tus-js-client": "^1.5.1" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/websocket": { + "version": "1.0.33", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.33.tgz", + "integrity": "sha512-XwNqM2rN5eh3G2CUQE3OHZj+0xfdH42+OFK6LdC2yqiC0YU8e5UK0nYre220T0IyyN031V/XOvtHvXozvJYFWA==", + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/when": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", + "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=" + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dependencies": { + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/winrarjs": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/winrarjs/-/winrarjs-0.0.16.tgz", + "integrity": "sha1-ftethlNOIXvLBl5pZAOcFcgg9Q0=", + "dependencies": { + "file-exists": "^3.0.2", + "mime": "^1.3.4", + "shell-escape": "^0.2.0" + } + }, + "node_modules/winston": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-0.8.3.tgz", + "integrity": "sha1-ZLar9M0Brcrv1QCTk7HY6L7BnbA=", + "dependencies": { + "async": "0.2.x", + "colors": "0.6.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "pkginfo": "0.3.x", + "stack-trace": "0.0.x" + }, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/winston/node_modules/async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + }, + "node_modules/wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/write-file-atomic/node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + }, + "node_modules/xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "engines": { + "node": ">=4" + } + }, + "node_modules/xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "node_modules/xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "node_modules/zip-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.0.1.tgz", + "integrity": "sha512-c+eUhhkDpaK87G/py74wvWLtz2kzMPNCCkUApkun50ssE0oQliIQzWpTnwjB+MTKVIf2tGzIgHyqW/Y+W77ecQ==", + "dependencies": { + "archiver-utils": "^2.0.0", + "compress-commons": "^1.2.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..1e51325 --- /dev/null +++ b/package.json @@ -0,0 +1,72 @@ +{ + "name": "myrobot_api", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@google-cloud/speech": "^4.2.0", + "alexa-sdk": "^1.0.25", + "alexa-verifier": "^2.0.1", + "alexa-verifier-middleware": "^1.0.2", + "all-unpacker": "^0.1.2", + "angularx-qrcode": "^1.5.3", + "archiver": "^3.0.0", + "ask-sdk-core": "^2.7.0", + "ask-sdk-model": "^1.18.0", + "async": "^2.6.2", + "base-64": "^0.1.0", + "base64-img": "^1.0.4", + "base64-to-image": "^1.0.2", + "base64topdf": "^1.1.8", + "body-parser": "^1.19.0", + "canvas": "^2.9.1", + "cors": "^2.8.5", + "csv-stringify": "^6.1.0", + "del": "^4.1.1", + "dotenv-safe": "^6.1.0", + "express": "^4.17.1", + "express-formidable": "^1.2.0", + "express-routes-map": "0.0.1", + "fastest-levenshtein": "^1.0.12", + "file-base64": "^1.0.0", + "forever": "^1.0.0", + "formidable": "^1.2.1", + "gzipme": "^0.1.2", + "ibm-watson": "^6.0.0", + "joi": "^13.7.0", + "jsbarcode": "^3.11.5", + "jsonwebtoken": "^8.5.1", + "jszip": "^3.10.0", + "lokijs": "^1.5.6", + "minizip-asm.js": "^1.0.10", + "mp3-to-wav": "^0.1.11", + "mssql": "^4.3.7", + "multer": "^1.4.1", + "mysql": "^2.18.1", + "ng2-file-upload": "^1.3.0", + "node-7z": "^1.1.0", + "node-7z-forall": "^1.0.0", + "node-lame": "^1.2.0", + "node-unrar": "^0.1.5", + "nodemailer": "^4.7.0", + "nodemon": "^1.19.4", + "rand-token": "^0.4.0", + "rimraf": "^2.6.3", + "rxjs-compat": "^6.5.2", + "shelljs": "^0.8.3", + "striptags": "^3.1.1", + "tedious": "^2.7.1", + "unrar": "^0.1.7", + "unrar-promise": "^2.0.1", + "unzip": "^0.1.11", + "unzipper": "^0.9.15", + "vimeo": "^2.1.1", + "winrarjs": "0.0.16", + "xmlhttprequest": "^1.8.0" + } +} diff --git a/server.js b/server.js new file mode 100644 index 0000000..81f0acc --- /dev/null +++ b/server.js @@ -0,0 +1,160 @@ +require("./helpers/config"); +const express = require("express"); +const https = require("https"); +const http = require("http"); +const fs = require("fs"); +const app = express(); +const portHttp = Variables("portHttp"); +const portHttps = Variables("portHttps"); +const cors = require("cors"); +const bodyParser = require("body-parser"); +const cluster = require("cluster"); +const numCPUs = require("os").cpus().length; +let HttpsLigado = false; + +var corsOptions = { + origin: "*", + optionsSuccessStatus: 200, +}; + +app.use(cors(corsOptions)); +app.use(bodyParser.urlencoded({ extended: true })); +app.use(bodyParser.json()); + +app.use(function (req, res, next) { + res.header("Access-Control-Allow-Origin", "*"); + res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT"); + res.header( + "Access-Control-Allow-Headers", + "Origin, X-Requested-With, Content-Type, Accept, Authorization" + ); + next(); +}); + +if (cluster.isMaster) { + console.log(`Master ${process.pid} is running`); + + for (let i = 0; i < numCPUs; i++) { + cluster.fork(); + } + + cluster.on("exit", (worker, code, signal) => { + console.log(`worker ${worker.process.pid} died`); + }); +} else { + console.log(`Worker ${process.pid} started`); + + app.get("/cluster", (req, res) => { + let worker = cluster.worker.id; + res.send(`Running on worker with id ==> ${worker}`); + }); + + http.createServer(app).listen(portHttp, function () { + console.log("API running success"); + }); + + if (HttpsLigado) { + var httpsOptions = { + key: fs.readFileSync("/etc/ca-certificates/myrobotlab_com_br.key"), + cert: fs.readFileSync("/etc/ca-certificates/myrobotlab_com_br.crt"), + }; + https.createServer(httpsOptions, app).listen(portHttps); + } +} + +const unityController = require("./controllers/unityController")(); +const courseController = require("./controllers/courseController")(); +const addressController = require("./controllers/addressController")(); +const classController = require("./controllers/classController")(); +const sqlServerController = require("./controllers/sqlServerController")(); +const productsController = require("./controllers/productsController")(); +const loginController = require("./controllers/loginController")(); +const exerciseController = require("./controllers/exerciseController")(); +const questionController = require("./controllers/questionController")(); +const answerController = require("./controllers/answerController")(); +const traineeprogramController = require("./controllers/traineeprogramController")(); +const traineeprogramcoursesController = require("./controllers/traineeprogramcoursesController")(); +const textController = require("./controllers/textController")(); +const classescontentController = require("./controllers/classescontentController")(); +const videoController = require("./controllers/videoController")(); +const usersController = require("./controllers/usersController")(); +const emailController = require("./controllers/emailController")(); +const typescourseController = require("./controllers/typescourseController")(); +const migrationController = require("./controllers/migrationController")(); +const slidesController = require("./controllers/slidesController")(); +const conceptsController = require("./controllers/conceptsController")(); +const teacherController = require("./controllers/teacherController")(); +const franchiseeController = require("./controllers/franchiseeController")(); +const appController = require("./controllers/appController")(); +const qrController = require("./controllers/qrController")(); +const curiositiesController = require("./controllers/curiositiesController")(); +const barcodeController = require("./controllers/barcodeController")(); +const elloController = require("./controllers/elloController")(); +const fileController = require("./controllers/fileController")(); +const alexaController = require("./controllers/alexaController")(); +const animationsController = require("./controllers/animationsController")(); +const iyrcController = require("./controllers/iyrcController")(); +const chatController = require("./controllers/chatController")(); +const chamadaController = require("./controllers/chamadaController")(); +const holidayController = require("./controllers/holidayController")(); +const charactersController = require("./controllers/charactersController")(); +const visitasController = require("./controllers/visitasController")(); +const chattimeController = require("./controllers/chattimeController")(); +const relatorioController = require("./controllers/relatorioController")(); +const configController = require("./controllers/configController")(); +const listenrepeatController = require("./controllers/listenrepeatController")(); +const customizeController = require("./controllers/customizeController")(); +const ig40Controller = require("./controllers/ig40Controller")(); +const permissoesController = require("./controllers/permissoesController")(); +const agendaController = require("./controllers/agendaController")(); +const studentController = require("./controllers/studentController")(); +const unileverController = require("./controllers/unileverController")(); + +app.use("/api/units", unityController); +app.use("/api/courses", courseController); +app.use("/api/address", addressController); +app.use("/api/classes", classController); +app.use("/api/sqlserver", sqlServerController); +app.use("/api/products", productsController); +app.use("/api/access", loginController); +app.use("/api/exercises", exerciseController); +app.use("/api/questions", questionController); +app.use("/api/answers", answerController); +app.use("/api/products", productsController); +app.use("/api/traineeprogram", traineeprogramController); +app.use("/api/traineeprogramcourses", traineeprogramcoursesController); +app.use("/api/text", textController); +app.use("/api/classescontent", classescontentController); +app.use("/api/videos", videoController); +app.use("/api/email", emailController); +app.use("/api/typescourse", typescourseController); +app.use("/api/migration", migrationController); +app.use("/api/users", usersController); +app.use("/api/slides", slidesController); +app.use("/api/concepts", conceptsController); +app.use("/api/teacher", teacherController); +app.use("/api/franchisee", franchiseeController); +app.use("/api/app", appController); +app.use("/api/qr", qrController); +app.use("/api/curiosities", curiositiesController); +app.use("/api/barcode", barcodeController); +app.use("/api/ello", elloController); +app.use("/api/files", fileController); +app.use("/api/alexa", alexaController); +app.use("/api/animations", animationsController); +app.use("/api/iyrc", iyrcController); +app.use("/api/chat", chatController); +app.use("/api/chamadas", chamadaController); +app.use("/api/holidays", holidayController); +app.use("/api/characters", charactersController); +app.use("/api/visitas", visitasController); +app.use("/api/chattime", chattimeController); +app.use("/api/relatorios", relatorioController); +app.use("/api/config", configController); +app.use("/api/listenrepeat", listenrepeatController); +app.use("/api/customize", customizeController); +app.use("/api/ig40", ig40Controller); +app.use("/api/permissoes", permissoesController); +app.use("/api/agenda", agendaController); +app.use("/api/student", studentController); +app.use("/api/unilever", unileverController); diff --git a/wgetOut b/wgetOut new file mode 100644 index 0000000..e69de29