Compare commits
	
		
			6 Commits
		
	
	
		
			feat/smsga
			...
			dependabot
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					6047a970f8 | ||
| 1cf43a3768 | |||
| e1daf00609 | |||
| 3a6a9122e1 | |||
| 0d14305ded | |||
| 40b4a0657f | 
@@ -22,7 +22,6 @@ const validateUsername = (username) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const io = (io) => {
 | 
					const io = (io) => {
 | 
				
			||||||
  io.on("connection", socket => {
 | 
					  io.on("connection", socket => {
 | 
				
			||||||
    console.log("does this happend first")
 | 
					 | 
				
			||||||
    let username = null;
 | 
					    let username = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    socket.on("username", msg => {
 | 
					    socket.on("username", msg => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,152 +0,0 @@
 | 
				
			|||||||
var url = require("url");
 | 
					 | 
				
			||||||
const path = require("path");
 | 
					 | 
				
			||||||
const SSE = require(`${__base}/helpers/SSE.js`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
let messages = [];
 | 
					 | 
				
			||||||
let connections = [];
 | 
					 | 
				
			||||||
let history = [];
 | 
					 | 
				
			||||||
let lastMessageId = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function subscribeToLogs(req, res){
 | 
					 | 
				
			||||||
  const base64encode = req.query?.contentTransferEncoding == 'base64' || false;
 | 
					 | 
				
			||||||
  const clientId = Date.now();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const sseClient = new SSE(res, clientId, base64encode)
 | 
					 | 
				
			||||||
  connections.push(sseClient);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  req.on('close', () => clientClosed(clientId));
 | 
					 | 
				
			||||||
  req.on('error', console.log);
 | 
					 | 
				
			||||||
  sendMissingMessageToClient(sseClient, req);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function removeConnection(clientConnection) {
 | 
					 | 
				
			||||||
  const connectionIndex = connections.indexOf(clientConnection);
 | 
					 | 
				
			||||||
  if (connectionIndex !== -1) {
 | 
					 | 
				
			||||||
    connections.splice(connectionIndex, 1);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function broadcast(hist
 | 
					 | 
				
			||||||
  oryMessage, id) {
 | 
					 | 
				
			||||||
  console.log(`sending to all ${connections.length} of our connections.`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  connections.forEach(client => {
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      client.writeMessage(historyMessage, id);
 | 
					 | 
				
			||||||
    } catch (error) {
 | 
					 | 
				
			||||||
      console.log(`got error while sending message to client: ${client.clientId}`, error);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const clientClosed = (clientId) => {
 | 
					 | 
				
			||||||
  console.log(`${clientId} close event received`);
 | 
					 | 
				
			||||||
  const client = connections.find(client => client.clientId == clientId);
 | 
					 | 
				
			||||||
  clearTimeout(client.manualShutdown)
 | 
					 | 
				
			||||||
  removeConnection(client);
 | 
					 | 
				
			||||||
  console.log(`Client success removed: ${connections}`);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const state = (req, res) => {
 | 
					 | 
				
			||||||
  return res.json({
 | 
					 | 
				
			||||||
    connections: connections.length
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function sendMissingMessageToClient(seeClient, req) {
 | 
					 | 
				
			||||||
  var urlParts = url.parse(req.url, true);
 | 
					 | 
				
			||||||
  let localHistory = [...history];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (req.headers['last-event-id']) {
 | 
					 | 
				
			||||||
    const index = parseInt(req.headers['last-event-id']);
 | 
					 | 
				
			||||||
    console.log("last-event-id FOUND from header!", index)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    localHistory = localHistory.slice(index);
 | 
					 | 
				
			||||||
  } else if (urlParts.query["lastMessageId"]) {
 | 
					 | 
				
			||||||
    const index = urlParts.query["lastMessageId"];
 | 
					 | 
				
			||||||
    console.log("last-event-id FOUND from url!", index)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    localHistory = localHistory.slice(index);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  localHistory.forEach(el => seeClient.writeMessage(el.message, el.lastMessageId))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// const addMessageFromApi = (req, res) => {
 | 
					 | 
				
			||||||
//   const { message } = req.params;
 | 
					 | 
				
			||||||
//       addMessage(message)
 | 
					 | 
				
			||||||
//     return res.json({
 | 
					 | 
				
			||||||
//       success: true,
 | 
					 | 
				
			||||||
//       connections: connections.length,
 | 
					 | 
				
			||||||
//       message: JSON.stringify(message)
 | 
					 | 
				
			||||||
//     })
 | 
					 | 
				
			||||||
//   // try {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//   // } catch (error) {
 | 
					 | 
				
			||||||
//   //   console.error
 | 
					 | 
				
			||||||
//   //   return res.json({
 | 
					 | 
				
			||||||
//   //     success: false,
 | 
					 | 
				
			||||||
//   //     connections: connections.length,
 | 
					 | 
				
			||||||
//   //     message: JSON.stringify(message),
 | 
					 | 
				
			||||||
//   //     error
 | 
					 | 
				
			||||||
//   //   })
 | 
					 | 
				
			||||||
//   // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const kickClient = (req, res) => {
 | 
					 | 
				
			||||||
  const { id } = req.params;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // console.log("connections:", connections )
 | 
					 | 
				
			||||||
  const client = connections.find(client => client.clientId == id);
 | 
					 | 
				
			||||||
  if (client) {
 | 
					 | 
				
			||||||
    client.end();
 | 
					 | 
				
			||||||
    return res.json({
 | 
					 | 
				
			||||||
      success: true,
 | 
					 | 
				
			||||||
      connections: connections.length,
 | 
					 | 
				
			||||||
      message: 'Client success removed'
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    return res.status(404).json({
 | 
					 | 
				
			||||||
      success: false,
 | 
					 | 
				
			||||||
      message: "Client not found"
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const addMessage = (message) => {
 | 
					 | 
				
			||||||
  console.log(`adding messagE: ${message}`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ++lastMessageId;
 | 
					 | 
				
			||||||
  const timestamp = new Date();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  let historyMessage;
 | 
					 | 
				
			||||||
  if (typeof message === 'string') {
 | 
					 | 
				
			||||||
    historyMessage = {
 | 
					 | 
				
			||||||
      message,
 | 
					 | 
				
			||||||
      timestamp
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    historyMessage = {
 | 
					 | 
				
			||||||
      ...message,
 | 
					 | 
				
			||||||
      timestamp
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  history.push({message: historyMessage, lastMessageId});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (connections.length > 0) {
 | 
					 | 
				
			||||||
    broadcast(historyMessage, lastMessageId);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    console.log("Message added to history, but no clients to send to")
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = {
 | 
					 | 
				
			||||||
  subscribeToLogs,
 | 
					 | 
				
			||||||
  state,
 | 
					 | 
				
			||||||
  addMessage,
 | 
					 | 
				
			||||||
  kickClient,
 | 
					 | 
				
			||||||
  addMessageFromApi
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -4,7 +4,6 @@ const prizeDistribution = require(path.join(__dirname, "../prizeDistribution"));
 | 
				
			|||||||
const prelotteryWineRepository = require(path.join(__dirname, "../prelotteryWine"));
 | 
					const prelotteryWineRepository = require(path.join(__dirname, "../prelotteryWine"));
 | 
				
			||||||
const winnerRepository = require(path.join(__dirname, "../winner"));
 | 
					const winnerRepository = require(path.join(__dirname, "../winner"));
 | 
				
			||||||
const message = require(path.join(__dirname, "../message"));
 | 
					const message = require(path.join(__dirname, "../message"));
 | 
				
			||||||
const logger = require(`${__base}/logger`);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const start = async (req, res) => {
 | 
					const start = async (req, res) => {
 | 
				
			||||||
  const allWinners = await winnerRepository.allWinners(true);
 | 
					  const allWinners = await winnerRepository.allWinners(true);
 | 
				
			||||||
@@ -29,7 +28,6 @@ const start = async (req, res) => {
 | 
				
			|||||||
    .catch(error => {
 | 
					    .catch(error => {
 | 
				
			||||||
      const { statusCode, message } = error;
 | 
					      const { statusCode, message } = error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      logger.error(error)
 | 
					 | 
				
			||||||
      return res.status(statusCode || 500).send({
 | 
					      return res.status(statusCode || 500).send({
 | 
				
			||||||
        message: message || "Unexpected error occured while starting prize distribution.",
 | 
					        message: message || "Unexpected error occured while starting prize distribution.",
 | 
				
			||||||
        success: false
 | 
					        success: false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,82 +0,0 @@
 | 
				
			|||||||
class SSE {
 | 
					 | 
				
			||||||
  constructor(response, clientId, base64encode=false) {
 | 
					 | 
				
			||||||
    if (!(this instanceof SSE)) {
 | 
					 | 
				
			||||||
      return new SSE(response, clientId, base64encode);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    this.response = response;
 | 
					 | 
				
			||||||
    this.clientId = clientId;
 | 
					 | 
				
			||||||
    this.base64encodeData = base64encode;
 | 
					 | 
				
			||||||
    this.delay = 1000;
 | 
					 | 
				
			||||||
    this.lastMessageId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.manualShutdown;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.setupEventStream();
 | 
					 | 
				
			||||||
    this.welcomeClient();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  welcomeClient() {
 | 
					 | 
				
			||||||
    console.log("welcome client")
 | 
					 | 
				
			||||||
    this.response.write('id\n\n'); // reset the id counter
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  setupEventStream() {
 | 
					 | 
				
			||||||
    this.response.writeHead(200, {
 | 
					 | 
				
			||||||
      'Content-Type': 'text/event-stream',
 | 
					 | 
				
			||||||
      'Cache-Control': 'no-cache',
 | 
					 | 
				
			||||||
      'Connection': 'keep-alive'
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  setupMessageData(message) {
 | 
					 | 
				
			||||||
    if (typeof message === 'string') {
 | 
					 | 
				
			||||||
      message = { message: message }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    message.type = message.type != null ? message.type : 'message';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    message = JSON.stringify(message, null, 1);
 | 
					 | 
				
			||||||
    if (this.base64encodeData === true) {
 | 
					 | 
				
			||||||
      message = btoa(message);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return message;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  writeMessage(message, id=null) {
 | 
					 | 
				
			||||||
    console.log(`Sending message to client: ${this.clientId}, id: ${id} ${this.id}`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    message = this.setupMessageData(message);
 | 
					 | 
				
			||||||
    this.id = id || this.id
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.response.write(`id: ${id}\n`);
 | 
					 | 
				
			||||||
    this.response.write(`retry: 10000\n`)
 | 
					 | 
				
			||||||
    this.response.write(`data: ${message}\n\n`)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  writeClose() {
 | 
					 | 
				
			||||||
    const message = {
 | 
					 | 
				
			||||||
      message: 'Server asking client to close connection',
 | 
					 | 
				
			||||||
      type: 'end'
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const data = this.setupMessageData(message);
 | 
					 | 
				
			||||||
    this.response.write(`data: ${data}\n\n`);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  end() {
 | 
					 | 
				
			||||||
    console.log("END CALLED, asking client to close")
 | 
					 | 
				
			||||||
    this.writeClose();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // give it a safe buffer of time before we shut it down manually
 | 
					 | 
				
			||||||
    const res = this.response;
 | 
					 | 
				
			||||||
    this.manualShutdown = setTimeout(() => {
 | 
					 | 
				
			||||||
      console.log("forcing server side")
 | 
					 | 
				
			||||||
      res.end()
 | 
					 | 
				
			||||||
    }, 2000)
 | 
					 | 
				
			||||||
    this.response.end();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = SSE;
 | 
					 | 
				
			||||||
@@ -1,57 +0,0 @@
 | 
				
			|||||||
const winston = require('winston');
 | 
					 | 
				
			||||||
const httpContext = require("express-http-context");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const logLevel = 'trace';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const customLevels = {
 | 
					 | 
				
			||||||
  levels: {
 | 
					 | 
				
			||||||
    fatal: 0,
 | 
					 | 
				
			||||||
    error: 1,
 | 
					 | 
				
			||||||
    warning: 2,
 | 
					 | 
				
			||||||
    info: 3,
 | 
					 | 
				
			||||||
    debug: 4,
 | 
					 | 
				
			||||||
    trace: 5
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  colors: {
 | 
					 | 
				
			||||||
    trace: 'blue',
 | 
					 | 
				
			||||||
    debug: 'white',
 | 
					 | 
				
			||||||
    info: 'green',
 | 
					 | 
				
			||||||
    warning: 'yellow',
 | 
					 | 
				
			||||||
    error: 'red',
 | 
					 | 
				
			||||||
    fatal: 'red'
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const appendSessionId = winston.format(info => {
 | 
					 | 
				
			||||||
  info.sessionId = httpContext.get("sessionId");
 | 
					 | 
				
			||||||
  return info
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const logger = winston.createLogger({
 | 
					 | 
				
			||||||
  level: logLevel,
 | 
					 | 
				
			||||||
  levels: customLevels.levels,
 | 
					 | 
				
			||||||
  transports: [
 | 
					 | 
				
			||||||
    new winston.transports.File({
 | 
					 | 
				
			||||||
      filename: `${__base}/logs/all-logs.log`,
 | 
					 | 
				
			||||||
      format: winston.format.combine(
 | 
					 | 
				
			||||||
        appendSessionId(),
 | 
					 | 
				
			||||||
        winston.format.json()
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
winston.addColors(customLevels.colors);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (process.env.NODE_ENV !== 'production') {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  logger.add(new winston.transports.Console({
 | 
					 | 
				
			||||||
    format: winston.format.combine(
 | 
					 | 
				
			||||||
      winston.format.colorize(),
 | 
					 | 
				
			||||||
      winston.format.simple()
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
  }));
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = logger;
 | 
					 | 
				
			||||||
							
								
								
									
										170
									
								
								api/logs.js
									
									
									
									
									
								
							
							
						
						
									
										170
									
								
								api/logs.js
									
									
									
									
									
								
							@@ -1,170 +0,0 @@
 | 
				
			|||||||
var url = require("url");
 | 
					 | 
				
			||||||
const path = require("path");
 | 
					 | 
				
			||||||
const SSE = require(`${__base}/helpers/SSE.js`);
 | 
					 | 
				
			||||||
// const logsRepository = require(path.join(__dirname, "../logs"));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
let messages = [];
 | 
					 | 
				
			||||||
let connections = [];
 | 
					 | 
				
			||||||
let history = [];
 | 
					 | 
				
			||||||
let lastMessageId = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// class SSEHandler {
 | 
					 | 
				
			||||||
//   constructor(req, res) {
 | 
					 | 
				
			||||||
//     this.req = req;
 | 
					 | 
				
			||||||
//     this.res = res;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//     this.base64Encode = this.clientRequestedBase64Encoding();
 | 
					 | 
				
			||||||
//     this.setupClient()
 | 
					 | 
				
			||||||
//   }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//   setupClient() {
 | 
					 | 
				
			||||||
//     this.
 | 
					 | 
				
			||||||
//   }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//   get clientRequestedBase64Encoding() {
 | 
					 | 
				
			||||||
//     return this.req.query.contentTransferEncoding === 'base64' || false;
 | 
					 | 
				
			||||||
//   }
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function subscribeToLogs(req, res){
 | 
					 | 
				
			||||||
  const base64encode = req.query?.contentTransferEncoding == 'base64' || false;
 | 
					 | 
				
			||||||
  const clientId = Date.now();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const sseClient = new SSE(res, clientId, base64encode)
 | 
					 | 
				
			||||||
  connections.push(sseClient);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  req.on('close', () => clientClosed(clientId));
 | 
					 | 
				
			||||||
  req.on('error', console.log);
 | 
					 | 
				
			||||||
  sendMissingMessageToClient(sseClient, req);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function sendMissingMessageToClient(seeClient, req) {
 | 
					 | 
				
			||||||
  var urlParts = url.parse(req.url, true);
 | 
					 | 
				
			||||||
  let localHistory = [...history];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (req.headers['last-event-id']) {
 | 
					 | 
				
			||||||
    const index = parseInt(req.headers['last-event-id']);
 | 
					 | 
				
			||||||
    console.log("last-event-id FOUND from header!", index)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    localHistory = localHistory.slice(index);
 | 
					 | 
				
			||||||
  } else if (urlParts.query["lastMessageId"]) {
 | 
					 | 
				
			||||||
    const index = urlParts.query["lastMessageId"];
 | 
					 | 
				
			||||||
    console.log("last-event-id FOUND from url!", index)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    localHistory = localHistory.slice(index);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  localHistory.forEach(el => seeClient.writeMessage(el.message, el.lastMessageId))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function removeConnection(clientConnection) {
 | 
					 | 
				
			||||||
  const connectionIndex = connections.indexOf(clientConnection);
 | 
					 | 
				
			||||||
  if (connectionIndex !== -1) {
 | 
					 | 
				
			||||||
    connections.splice(connectionIndex, 1);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const clientClosed = (clientId) => {
 | 
					 | 
				
			||||||
  console.log(`${clientId} close event received`);
 | 
					 | 
				
			||||||
  const client = connections.find(client => client.clientId == clientId);
 | 
					 | 
				
			||||||
  clearTimeout(client.manualShutdown)
 | 
					 | 
				
			||||||
  removeConnection(client);
 | 
					 | 
				
			||||||
  console.log(`Client success removed: ${connections}`);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const state = (req, res) => {
 | 
					 | 
				
			||||||
  return res.json({
 | 
					 | 
				
			||||||
    connections: connections.length
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function broadcast(historyMessage, id) {
 | 
					 | 
				
			||||||
  console.log(`sending to all ${connections.length} of our connections.`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  connections.forEach(client => {
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      client.writeMessage(historyMessage, id);
 | 
					 | 
				
			||||||
    } catch (error) {
 | 
					 | 
				
			||||||
      console.log(`got error while sending message to client: ${client.clientId}`, error);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// const addMessageFromApi = (req, res) => {
 | 
					 | 
				
			||||||
//   const { message } = req.params;
 | 
					 | 
				
			||||||
//       addMessage(message)
 | 
					 | 
				
			||||||
//     return res.json({
 | 
					 | 
				
			||||||
//       success: true,
 | 
					 | 
				
			||||||
//       connections: connections.length,
 | 
					 | 
				
			||||||
//       message: JSON.stringify(message)
 | 
					 | 
				
			||||||
//     })
 | 
					 | 
				
			||||||
//   // try {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//   // } catch (error) {
 | 
					 | 
				
			||||||
//   //   console.error
 | 
					 | 
				
			||||||
//   //   return res.json({
 | 
					 | 
				
			||||||
//   //     success: false,
 | 
					 | 
				
			||||||
//   //     connections: connections.length,
 | 
					 | 
				
			||||||
//   //     message: JSON.stringify(message),
 | 
					 | 
				
			||||||
//   //     error
 | 
					 | 
				
			||||||
//   //   })
 | 
					 | 
				
			||||||
//   // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const kickClient = (req, res) => {
 | 
					 | 
				
			||||||
  const { id } = req.params;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // console.log("connections:", connections )
 | 
					 | 
				
			||||||
  const client = connections.find(client => client.clientId == id);
 | 
					 | 
				
			||||||
  if (client) {
 | 
					 | 
				
			||||||
    client.end();
 | 
					 | 
				
			||||||
    return res.json({
 | 
					 | 
				
			||||||
      success: true,
 | 
					 | 
				
			||||||
      connections: connections.length,
 | 
					 | 
				
			||||||
      message: 'Client success removed'
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    return res.status(404).json({
 | 
					 | 
				
			||||||
      success: false,
 | 
					 | 
				
			||||||
      message: "Client not found"
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const addMessage = (message) => {
 | 
					 | 
				
			||||||
  console.log(`adding messagE: ${message}`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ++lastMessageId;
 | 
					 | 
				
			||||||
  const timestamp = new Date();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  let historyMessage;
 | 
					 | 
				
			||||||
  if (typeof message === 'string') {
 | 
					 | 
				
			||||||
    historyMessage = {
 | 
					 | 
				
			||||||
      message,
 | 
					 | 
				
			||||||
      timestamp
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    historyMessage = {
 | 
					 | 
				
			||||||
      ...message,
 | 
					 | 
				
			||||||
      timestamp
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  history.push({message: historyMessage, lastMessageId});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (connections.length > 0) {
 | 
					 | 
				
			||||||
    broadcast(historyMessage, lastMessageId);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    console.log("Message added to history, but no clients to send to")
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = {
 | 
					 | 
				
			||||||
  subscribeToLogs,
 | 
					 | 
				
			||||||
  state,
 | 
					 | 
				
			||||||
  addMessage,
 | 
					 | 
				
			||||||
  kickClient,
 | 
					 | 
				
			||||||
  addMessageFromApi
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,9 +1,6 @@
 | 
				
			|||||||
const https = require("https");
 | 
					const https = require("https");
 | 
				
			||||||
const path = require("path");
 | 
					const path = require("path");
 | 
				
			||||||
const config = require(path.join(__dirname + "/../config/defaults/lottery"));
 | 
					const config = require(path.join(__dirname + "/../config/defaults/lottery"));
 | 
				
			||||||
const logger = require(path.join(`${__base}/logger`));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const { addMessage } = require(`${__base}/controllers/logsController`);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const dateString = date => {
 | 
					const dateString = date => {
 | 
				
			||||||
  if (typeof date == "string") {
 | 
					  if (typeof date == "string") {
 | 
				
			||||||
@@ -17,8 +14,7 @@ const dateString = date => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function sendInitialMessageToWinners(winners) {
 | 
					async function sendInitialMessageToWinners(winners) {
 | 
				
			||||||
  // const numbers = winners.map(winner => ({ msisdn: `47${winner.phoneNumber}` }));
 | 
					  const numbers = winners.map(winner => ({ msisdn: `47${winner.phoneNumber}` }));
 | 
				
			||||||
  const numbers = [{msisdn: '4741498549'}]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const body = {
 | 
					  const body = {
 | 
				
			||||||
    sender: "Vinlottis",
 | 
					    sender: "Vinlottis",
 | 
				
			||||||
@@ -27,14 +23,6 @@ async function sendInitialMessageToWinners(winners) {
 | 
				
			|||||||
    recipients: numbers,
 | 
					    recipients: numbers,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  addMessage({
 | 
					 | 
				
			||||||
    message: 'Sending bulk winner confirmation message to all winners',
 | 
					 | 
				
			||||||
    recipients: body.recipients,
 | 
					 | 
				
			||||||
    smsText: body.message,
 | 
					 | 
				
			||||||
    sender: body.sender,
 | 
					 | 
				
			||||||
    template: 'sendInitialMessageToWinners'
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return gatewayRequest(body);
 | 
					  return gatewayRequest(body);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -62,7 +50,7 @@ async function sendWineConfirmation(winnerObject, wineObject, date) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function sendLastWinnerMessage(winnerObject, wineObject) {
 | 
					async function sendLastWinnerMessage(winnerObject, wineObject) {
 | 
				
			||||||
  logger.log(`User ${winnerObject.id} is only one left, chosing wine for him/her.`);
 | 
					  console.log(`User ${winnerObject.id} is only one left, chosing wine for him/her.`);
 | 
				
			||||||
  winnerObject.timestamp_sent = new Date().getTime();
 | 
					  winnerObject.timestamp_sent = new Date().getTime();
 | 
				
			||||||
  winnerObject.timestamp_limit = new Date().getTime();
 | 
					  winnerObject.timestamp_limit = new Date().getTime();
 | 
				
			||||||
  await winnerObject.save();
 | 
					  await winnerObject.save();
 | 
				
			||||||
@@ -83,10 +71,7 @@ puttet bakerst i køen. Du vil få en ny SMS når det er din tur igjen.`
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function sendMessageToNumber(phoneNumber, message) {
 | 
					async function sendMessageToNumber(phoneNumber, message) {
 | 
				
			||||||
  logger.info(`Attempting to send message`, {
 | 
					  console.log(`Attempting to send message to ${phoneNumber}.`);
 | 
				
			||||||
    phoneNumber,
 | 
					 | 
				
			||||||
    message
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const body = {
 | 
					  const body = {
 | 
				
			||||||
    sender: "Vinlottis",
 | 
					    sender: "Vinlottis",
 | 
				
			||||||
@@ -94,14 +79,6 @@ async function sendMessageToNumber(phoneNumber, message) {
 | 
				
			|||||||
    recipients: [{ msisdn: `47${phoneNumber}` }],
 | 
					    recipients: [{ msisdn: `47${phoneNumber}` }],
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  addMessage({
 | 
					 | 
				
			||||||
    recipients: body.recipients,
 | 
					 | 
				
			||||||
    smsText: body.message,
 | 
					 | 
				
			||||||
    sender: body.sender,
 | 
					 | 
				
			||||||
    message: `Sending message`,
 | 
					 | 
				
			||||||
    template: 'sendMessageToNumber'
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  return gatewayRequest(body);
 | 
					  return gatewayRequest(body);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -116,52 +93,29 @@ async function gatewayRequest(body) {
 | 
				
			|||||||
        "Content-Type": "application/json",
 | 
					        "Content-Type": "application/json",
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    // body.recipients = [{msisdn: `123123123123123123123123128937123987192837`}]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const req = https.request(options, res => {
 | 
					    const req = https.request(options, res => {
 | 
				
			||||||
      const { statusCode, statusMessage } = res;
 | 
					      console.log(`statusCode: ${res.statusCode}`);
 | 
				
			||||||
      logger.info(`Response from gatewayapi.`, {
 | 
					      console.log(`statusMessage: ${res.statusMessage}`);
 | 
				
			||||||
        statusMessage,
 | 
					 | 
				
			||||||
        statusCode
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      addMessage({
 | 
					 | 
				
			||||||
        message: `Gateway api response`,
 | 
					 | 
				
			||||||
        statusMessage,
 | 
					 | 
				
			||||||
        statusCode,
 | 
					 | 
				
			||||||
        type: res.statusCode == 200 ? 'message' : 'error'
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      res.setEncoding("utf8");
 | 
					      res.setEncoding("utf8");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (res.statusCode == 200) {
 | 
					      if (res.statusCode == 200) {
 | 
				
			||||||
        res.on("data", data => {
 | 
					        res.on("data", data => {
 | 
				
			||||||
          logger.info("Response from message gateway", { data });
 | 
					          console.log("Response from message gateway:", data);
 | 
				
			||||||
          data = JSON.parse(data);
 | 
					 | 
				
			||||||
          addMessage({ ...data, message: `Response from message gateway` });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
          resolve(data);
 | 
					          resolve(JSON.parse(data));
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        res.on("data", data => {
 | 
					        res.on("data", data => {
 | 
				
			||||||
          console.log('error data:', data)
 | 
					 | 
				
			||||||
          data = JSON.parse(data);
 | 
					          data = JSON.parse(data);
 | 
				
			||||||
          if (data['message'] != null) {
 | 
					 | 
				
			||||||
            data['errorMessage'] = data.message
 | 
					 | 
				
			||||||
            delete data.message
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          message = `SMS request returned error from provider!`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          addMessage({ ...data, message, type: 'error' });
 | 
					 | 
				
			||||||
          // addMessage(`Gateway error: ${data["message"] || JSON.stringify(JSON.parse(data))}\n\n`);
 | 
					 | 
				
			||||||
          return reject("Gateway error: " + data["message"] || data);
 | 
					          return reject("Gateway error: " + data["message"] || data);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    req.on("error", error => {
 | 
					    req.on("error", error => {
 | 
				
			||||||
      logger.error("Error from sms service.",{error});
 | 
					      console.error(`Error from sms service: ${error}`);
 | 
				
			||||||
      addMessage({ ...error, message: `Error from sms service`, type: 'error' });
 | 
					 | 
				
			||||||
      reject(`Error from sms service: ${error}`);
 | 
					      reject(`Error from sms service: ${error}`);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,23 +0,0 @@
 | 
				
			|||||||
const crypto = require("crypto");
 | 
					 | 
				
			||||||
const httpContext = require("express-http-context");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const addIdToRequest = (req, res, next) => {
 | 
					 | 
				
			||||||
  try {
 | 
					 | 
				
			||||||
    crypto.randomBytes(16, (err, buf) => {
 | 
					 | 
				
			||||||
      if (err) {
 | 
					 | 
				
			||||||
        // log err
 | 
					 | 
				
			||||||
        id = null;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      id = buf.toString("hex");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      httpContext.set("sessionId", id);
 | 
					 | 
				
			||||||
      next();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  } catch (err) {
 | 
					 | 
				
			||||||
    // log err
 | 
					 | 
				
			||||||
    httpContext.set("sessionId", null);
 | 
					 | 
				
			||||||
    next();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = addIdToRequest;
 | 
					 | 
				
			||||||
@@ -12,7 +12,7 @@ const setupHeaders = (req, res, next) => {
 | 
				
			|||||||
  res.set("Access-Control-Allow-Headers", "Content-Type")
 | 
					  res.set("Access-Control-Allow-Headers", "Content-Type")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Security
 | 
					  // Security
 | 
				
			||||||
  // res.set("X-Content-Type-Options", "nosniff");
 | 
					  res.set("X-Content-Type-Options", "nosniff");
 | 
				
			||||||
  res.set("X-XSS-Protection", "1; mode=block");
 | 
					  res.set("X-XSS-Protection", "1; mode=block");
 | 
				
			||||||
  res.set("X-Frame-Options", "SAMEORIGIN");
 | 
					  res.set("X-Frame-Options", "SAMEORIGIN");
 | 
				
			||||||
  res.set("X-DNS-Prefetch-Control", "off");
 | 
					  res.set("X-DNS-Prefetch-Control", "off");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,18 +6,14 @@ let lrangeAsync;
 | 
				
			|||||||
try {
 | 
					try {
 | 
				
			||||||
  const redis = require("redis");
 | 
					  const redis = require("redis");
 | 
				
			||||||
  console.log("Trying to connect with redis..");
 | 
					  console.log("Trying to connect with redis..");
 | 
				
			||||||
  client = redis.createClient({
 | 
					  client = redis.createClient();
 | 
				
			||||||
    host: '127.0.0.1',
 | 
					 | 
				
			||||||
    no_ready_check: true,
 | 
					 | 
				
			||||||
    auth_pass: 'sOmE_sEcUrE_pAsS'
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  client.zcount = promisify(client.zcount).bind(client);
 | 
					  client.zcount = promisify(client.zcount).bind(client);
 | 
				
			||||||
  client.zadd = promisify(client.zadd).bind(client);
 | 
					  client.zadd = promisify(client.zadd).bind(client);
 | 
				
			||||||
  client.zrevrange = promisify(client.zrevrange).bind(client);
 | 
					  client.zrevrange = promisify(client.zrevrange).bind(client);
 | 
				
			||||||
  client.del = promisify(client.del).bind(client);
 | 
					  client.del = promisify(client.del).bind(client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  client.on("connect", console.log("Redis connection established!"));
 | 
					  client.on("connect", () => console.log("Redis connection established!"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  client.on("error", function(err) {
 | 
					  client.on("error", function(err) {
 | 
				
			||||||
    client.quit();
 | 
					    client.quit();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,6 @@ const lotteryController = require(path.join(__dirname, "/controllers/lotteryCont
 | 
				
			|||||||
const prizeDistributionController = require(path.join(__dirname, "/controllers/prizeDistributionController"));
 | 
					const prizeDistributionController = require(path.join(__dirname, "/controllers/prizeDistributionController"));
 | 
				
			||||||
const wineController = require(path.join(__dirname, "/controllers/wineController"));
 | 
					const wineController = require(path.join(__dirname, "/controllers/wineController"));
 | 
				
			||||||
const messageController = require(path.join(__dirname, "/controllers/messageController"));
 | 
					const messageController = require(path.join(__dirname, "/controllers/messageController"));
 | 
				
			||||||
const logsController = require(path.join(__dirname, "/controllers/logsController"));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = express.Router();
 | 
					const router = express.Router();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -76,11 +75,6 @@ router.get("/lottery/latest", lotteryController.latestLottery);
 | 
				
			|||||||
router.get("/lottery/:epoch", lotteryController.lotteryByDate);
 | 
					router.get("/lottery/:epoch", lotteryController.lotteryByDate);
 | 
				
			||||||
router.get("/lotteries/", lotteryController.allLotteries);
 | 
					router.get("/lotteries/", lotteryController.allLotteries);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.get("/logs/sms", logsController.subscribeToLogs);
 | 
					 | 
				
			||||||
router.get("/logs/sms/:message", logsController.addMessageFromApi);
 | 
					 | 
				
			||||||
router.get("/logs/status", logsController.state);
 | 
					 | 
				
			||||||
router.get("/logs/kick/:id", logsController.kickClient);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// router.get("/lottery/prize-distribution/status", mustBeAuthenticated, prizeDistributionController.status);
 | 
					// router.get("/lottery/prize-distribution/status", mustBeAuthenticated, prizeDistributionController.status);
 | 
				
			||||||
router.post("/lottery/prize-distribution/start", mustBeAuthenticated, prizeDistributionController.start);
 | 
					router.post("/lottery/prize-distribution/start", mustBeAuthenticated, prizeDistributionController.start);
 | 
				
			||||||
// router.post("/lottery/prize-distribution/stop", mustBeAuthenticated, prizeDistributionController.stop);
 | 
					// router.post("/lottery/prize-distribution/stop", mustBeAuthenticated, prizeDistributionController.stop);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,17 +0,0 @@
 | 
				
			|||||||
const path = require("path");
 | 
					 | 
				
			||||||
const { addMessage } = require(path.join(__dirname + "/redis.js"));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const io = (io) => {
 | 
					 | 
				
			||||||
  io.on("connection", socket => {
 | 
					 | 
				
			||||||
    let localData = null;
 | 
					 | 
				
			||||||
    console.log("does this happend second")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    socket.on("message", msg => {
 | 
					 | 
				
			||||||
      msg.localData = localData;
 | 
					 | 
				
			||||||
      msg.timestamp = new Date().getTime();
 | 
					 | 
				
			||||||
      io.emit("message", msg);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = io;
 | 
					 | 
				
			||||||
@@ -31,7 +31,7 @@ let webpackConfig = merge(commonConfig(true), {
 | 
				
			|||||||
    }),
 | 
					    }),
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  devServer: {
 | 
					  devServer: {
 | 
				
			||||||
    compress: false,
 | 
					    compress: true,
 | 
				
			||||||
    historyApiFallback: true,
 | 
					    historyApiFallback: true,
 | 
				
			||||||
    host: "0.0.0.0",
 | 
					    host: "0.0.0.0",
 | 
				
			||||||
    disableHostCheck: true,
 | 
					    disableHostCheck: true,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
        <label>Din vinlottis kode:</label>
 | 
					        <label>Din vinlottis kode:</label>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <div class="codeinput-container">
 | 
					      <div id="code-container" class="codeinput-container">
 | 
				
			||||||
        <input v-model="code" placeholder="KODE" @keyup.enter="submit" />
 | 
					        <input v-model="code" placeholder="KODE" @keyup.enter="submit" />
 | 
				
			||||||
        <button class="vin-button" @click="submit">ENTER</button>
 | 
					        <button class="vin-button" @click="submit">ENTER</button>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
@@ -56,15 +56,24 @@ export default {
 | 
				
			|||||||
      const { video } = this.$refs;
 | 
					      const { video } = this.$refs;
 | 
				
			||||||
      video.paused ? video.play() : video.pause();
 | 
					      video.paused ? video.play() : video.pause();
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    smh() {
 | 
				
			||||||
 | 
					      let inputContainer = document.getElementById('code-container')
 | 
				
			||||||
 | 
					      inputContainer.classList.add('shake')
 | 
				
			||||||
 | 
					      if (this.timeout)
 | 
				
			||||||
 | 
					        clearTimeout(this.timeout)
 | 
				
			||||||
 | 
					      this.timeout = setTimeout(() => inputContainer.classList.remove('shake'), 600);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    submit() {
 | 
					    submit() {
 | 
				
			||||||
      const site = __sites__.find(site => site.code == this.code);
 | 
					      const site = __sites__.find(site => site.code?.toLowerCase() == this.code?.toLowerCase());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (site) {
 | 
					      if (site) {
 | 
				
			||||||
        createCookie("accesscode", site.code, 14);
 | 
					        createCookie("accesscode", site.code, 14);
 | 
				
			||||||
        window.location.href = `${window.location.protocol}//${site.domain}`;
 | 
					        const path = (location.pathname+location.search).substr(1)
 | 
				
			||||||
 | 
					        const redirectUrl = `${window.location.protocol}//${site.domain}/${path}`
 | 
				
			||||||
 | 
					        window.location.href = redirectUrl;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        this.smh()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -127,6 +136,11 @@ video {
 | 
				
			|||||||
    width: 80%;
 | 
					    width: 80%;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &.shake {
 | 
				
			||||||
 | 
					    animation: shake 0.6s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
 | 
				
			||||||
 | 
					    animation-iteration-count: infinite;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  input {
 | 
					  input {
 | 
				
			||||||
    max-width: 24rem;
 | 
					    max-width: 24rem;
 | 
				
			||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
@@ -145,6 +159,7 @@ video {
 | 
				
			|||||||
  button {
 | 
					  button {
 | 
				
			||||||
    height: 100%;
 | 
					    height: 100%;
 | 
				
			||||||
    max-height: unset;
 | 
					    max-height: unset;
 | 
				
			||||||
 | 
					    font-weight: bold;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -180,6 +195,7 @@ video {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    label {
 | 
					    label {
 | 
				
			||||||
      color: rgba(255, 255, 255, 0.82);
 | 
					      color: rgba(255, 255, 255, 0.82);
 | 
				
			||||||
 | 
					      text-shadow: 1px 1px black;
 | 
				
			||||||
      font-size: 1.5rem;
 | 
					      font-size: 1.5rem;
 | 
				
			||||||
      font-weight: 500;
 | 
					      font-weight: 500;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -205,4 +221,27 @@ video {
 | 
				
			|||||||
.button-container {
 | 
					.button-container {
 | 
				
			||||||
  margin-top: 4rem;
 | 
					  margin-top: 4rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@keyframes shake {
 | 
				
			||||||
 | 
					  10%,
 | 
				
			||||||
 | 
					  90% {
 | 
				
			||||||
 | 
					    transform: translate3d(-1px, 0, 0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  20%,
 | 
				
			||||||
 | 
					  80% {
 | 
				
			||||||
 | 
					    transform: translate3d(2px, 0, 0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  30%,
 | 
				
			||||||
 | 
					  50%,
 | 
				
			||||||
 | 
					  70% {
 | 
				
			||||||
 | 
					    transform: translate3d(-4px, 0, 0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  40%,
 | 
				
			||||||
 | 
					  60% {
 | 
				
			||||||
 | 
					    transform: translate3d(4px, 0, 0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,6 @@ import RegisterWinePage from "@/components/admin/RegisterWinePage";
 | 
				
			|||||||
import archiveLotteryPage from "@/components/admin/archiveLotteryPage";
 | 
					import archiveLotteryPage from "@/components/admin/archiveLotteryPage";
 | 
				
			||||||
import registerAttendeePage from "@/components/admin/registerAttendeePage";
 | 
					import registerAttendeePage from "@/components/admin/registerAttendeePage";
 | 
				
			||||||
import DrawWinnerPage from "@/components/admin/DrawWinnerPage";
 | 
					import DrawWinnerPage from "@/components/admin/DrawWinnerPage";
 | 
				
			||||||
import PrizeDistributionPage from "@/components/admin/PrizeDistributionPage";
 | 
					 | 
				
			||||||
import PushPage from "@/components/admin/PushPage";
 | 
					import PushPage from "@/components/admin/PushPage";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
@@ -38,12 +37,6 @@ export default {
 | 
				
			|||||||
          slug: "draw",
 | 
					          slug: "draw",
 | 
				
			||||||
          counter: null
 | 
					          counter: null
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          name: "Prisutdeling",
 | 
					 | 
				
			||||||
          component: PrizeDistributionPage,
 | 
					 | 
				
			||||||
          slug: "price",
 | 
					 | 
				
			||||||
          counter: null
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          name: "Arkiver lotteri",
 | 
					          name: "Arkiver lotteri",
 | 
				
			||||||
          component: archiveLotteryPage,
 | 
					          component: archiveLotteryPage,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,14 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="prize-distribution">
 | 
				
			||||||
 | 
					      <h2>Prisutdeling</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <div class="button-container">
 | 
				
			||||||
 | 
					        <button class="vin-button" @click="startPrizeDistribution">Start automatisk prisutdeling med SMS</button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2 v-if="winners.length > 0">Vinnere</h2>
 | 
					    <h2 v-if="winners.length > 0">Vinnere</h2>
 | 
				
			||||||
    <div class="winners" v-if="winners.length > 0">
 | 
					    <div class="winners" v-if="winners.length > 0">
 | 
				
			||||||
      <div :class="winner.color + '-raffle'" class="raffle-element" v-for="(winner, index) in winners" :key="index">
 | 
					      <div :class="winner.color + '-raffle'" class="raffle-element" v-for="(winner, index) in winners" :key="index">
 | 
				
			||||||
@@ -173,7 +181,29 @@ export default {
 | 
				
			|||||||
      this.drawingWinner = false;
 | 
					      this.drawingWinner = false;
 | 
				
			||||||
      this.secondsLeft = this.drawTime;
 | 
					      this.secondsLeft = this.drawTime;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    startPrizeDistribution() {
 | 
				
			||||||
 | 
					      if (!window.confirm("Er du sikker på at du vil starte prisutdeling?")) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      this.drawingWinner = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const options = { method: "POST" };
 | 
				
			||||||
 | 
					      fetch(`/api/lottery/prize-distribution/start`, options)
 | 
				
			||||||
 | 
					        .then(resp => resp.json())
 | 
				
			||||||
 | 
					        .then(response => {
 | 
				
			||||||
 | 
					          if (response.success) {
 | 
				
			||||||
 | 
					            this.$toast.info({
 | 
				
			||||||
 | 
					              title: `Startet prisutdeling. SMS'er sendt ut!`
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            this.$toast.error({
 | 
				
			||||||
 | 
					              title: `Klarte ikke starte prisutdeling`,
 | 
				
			||||||
 | 
					              description: response.message
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    notifyWinner(winner) {
 | 
					    notifyWinner(winner) {
 | 
				
			||||||
      const options = { method: "POST" };
 | 
					      const options = { method: "POST" };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,198 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <div class="page-container">
 | 
					 | 
				
			||||||
    <h1>Prisutdeling</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <div class="prize-distribution">
 | 
					 | 
				
			||||||
      <h2>Prisutdeling</h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <div class="button-container">
 | 
					 | 
				
			||||||
        <button class="vin-button" @click="startPrizeDistribution">
 | 
					 | 
				
			||||||
          Start automatisk prisutdeling med SMS
 | 
					 | 
				
			||||||
        </button>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <div class="sms-service-output">
 | 
					 | 
				
			||||||
      <h2>Logger</h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <div class="connection-status">
 | 
					 | 
				
			||||||
        <p>{{ logConnectionStatus }}</p>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <button @click="closeConnection">Close connection</button>
 | 
					 | 
				
			||||||
      <button @click="connectToEventStream">Open connection</button>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <div class="terminal">
 | 
					 | 
				
			||||||
        <ul v-if="logs.length">
 | 
					 | 
				
			||||||
          <li v-for="(log, index) in reversedLogs" :class="{selected: selectedIndexs.find(el => el === index) !== undefined}">
 | 
					 | 
				
			||||||
            <!-- <span class="line">{{ secondsAgo(log) }}</span> -->
 | 
					 | 
				
			||||||
            <span class="line">{{ logLength - index }}</span>
 | 
					 | 
				
			||||||
            <LogMessage :log="log" @toggleMessage="(value) => setSelectedIndex(index, value)" />
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
        </ul> 
 | 
					 | 
				
			||||||
        <p v-else>No logs yet...</p>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script>
 | 
					 | 
				
			||||||
import LogMessage from "@/components/admin/logMessage";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
  components: { LogMessage },
 | 
					 | 
				
			||||||
  computed: {
 | 
					 | 
				
			||||||
    reversedLogs() {
 | 
					 | 
				
			||||||
      return [...this.logs].reverse()
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    logLength() {
 | 
					 | 
				
			||||||
      return this.logs.length;
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  data() {
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
      source: null,
 | 
					 | 
				
			||||||
      logConnectionStatus: 'Disconnected',
 | 
					 | 
				
			||||||
      logs: [],
 | 
					 | 
				
			||||||
      selectedIndexs: []
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  created() {
 | 
					 | 
				
			||||||
    this.connectToEventStream();
 | 
					 | 
				
			||||||
    window.addEventListener('beforeunload', this.closeConnection);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  beforeDestroy() {
 | 
					 | 
				
			||||||
    this.closeConnection();
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  methods: {
 | 
					 | 
				
			||||||
    setSelectedIndex(index, value) {
 | 
					 | 
				
			||||||
      if (value === true) {
 | 
					 | 
				
			||||||
        this.selectedIndexs.push(index);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        this.selectedIndexs = this.selectedIndexs.filter(el => el !== index);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    closeConnection() {
 | 
					 | 
				
			||||||
      console.log("close event received");
 | 
					 | 
				
			||||||
      this.logConnectionStatus = 'closed';
 | 
					 | 
				
			||||||
      this.source.close();
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    secondsAgo(log) {
 | 
					 | 
				
			||||||
      const seconds = Math.floor((new Date() - new Date(log.timestamp)) / 1000)
 | 
					 | 
				
			||||||
      return `${seconds} s`
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    connectToEventStream() {
 | 
					 | 
				
			||||||
      let SOURCE_URL = '/api/logs/sms?contentTransferEncoding=base64'
 | 
					 | 
				
			||||||
      if (this.lastMessageId) {
 | 
					 | 
				
			||||||
        SOURCE_URL = `${SOURCE_URL}&lastMessageId=${this.lastMessageId}`
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      this.source = new EventSource(SOURCE_URL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (this.logs.length) {
 | 
					 | 
				
			||||||
        this.logs.push({
 | 
					 | 
				
			||||||
          message: '- - - new session - - -',
 | 
					 | 
				
			||||||
          timestamp: new Date(),
 | 
					 | 
				
			||||||
          type: 'INFO'
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      this.source.onmessage = (event) => this.handleMessage(event);
 | 
					 | 
				
			||||||
      this.source.onopen = (event) => this.handleConnectionOpened(event);
 | 
					 | 
				
			||||||
      this.source.onerror = (event) => this.handleError(error);
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    handleConnectionOpened(event) {
 | 
					 | 
				
			||||||
      this.logConnectionStatus = 'Connected';
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    handleMessage(event) {
 | 
					 | 
				
			||||||
      this.lastMessageId = event.lastEventId;
 | 
					 | 
				
			||||||
      let message = JSON.parse(atob(event.data));
 | 
					 | 
				
			||||||
      if (message.type === 'close') {
 | 
					 | 
				
			||||||
        this.closeConnection();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      this.logs.push(message);
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    handleError(event) {
 | 
					 | 
				
			||||||
      if (event.eventPhase == EventSource.CLOSED) {
 | 
					 | 
				
			||||||
        console.log("Server closed connection, clean up client side");
 | 
					 | 
				
			||||||
        this.source.close();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (event.target.readyState == EventSource.CLOSED) 
 | 
					 | 
				
			||||||
        this.logConnectionStatus = "Disconnected"
 | 
					 | 
				
			||||||
      else if (event.target.readyState == EventSource.CONNECTING)
 | 
					 | 
				
			||||||
        this.logConnectionStatus = "Connecting..."
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        console.warning('Unknown SSE event state');
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    startPrizeDistribution() {
 | 
					 | 
				
			||||||
      if (!window.confirm("Er du sikker på at du vil starte prisutdeling?")) {
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const options = { method: "POST" };
 | 
					 | 
				
			||||||
      fetch(`/api/lottery/prize-distribution/start`, options)
 | 
					 | 
				
			||||||
        .then(resp => resp.json())
 | 
					 | 
				
			||||||
        .then(response => {
 | 
					 | 
				
			||||||
          if (response.success) {
 | 
					 | 
				
			||||||
            this.$toast.info({
 | 
					 | 
				
			||||||
              title: `Startet prisutdeling. SMS'er sendt ut!`,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            this.$toast.error({
 | 
					 | 
				
			||||||
              title: `Klarte ikke starte prisutdeling`,
 | 
					 | 
				
			||||||
              description: response.message,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
.terminal {
 | 
					 | 
				
			||||||
  padding: 1.5rem 1rem 1rem;
 | 
					 | 
				
			||||||
  background-color: #333333;
 | 
					 | 
				
			||||||
  color: white;
 | 
					 | 
				
			||||||
  font-family: "Roboto Mono", Monaco, "Courier New", monospace;
 | 
					 | 
				
			||||||
  font-size: 14px;
 | 
					 | 
				
			||||||
  line-height: 24px;
 | 
					 | 
				
			||||||
  font-weight: 400;
 | 
					 | 
				
			||||||
  white-space: pre;
 | 
					 | 
				
			||||||
  max-width: 90vw;
 | 
					 | 
				
			||||||
  overflow-x: auto;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ul {
 | 
					 | 
				
			||||||
    margin: 0;
 | 
					 | 
				
			||||||
    padding: 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  li {
 | 
					 | 
				
			||||||
    text-decoration: none;
 | 
					 | 
				
			||||||
    list-style-type: none;
 | 
					 | 
				
			||||||
    margin: 0;
 | 
					 | 
				
			||||||
    padding: 0;
 | 
					 | 
				
			||||||
    display: flex;
 | 
					 | 
				
			||||||
    width: fit-content;
 | 
					 | 
				
			||||||
    transition: all 0.3s ease;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    &.selected {
 | 
					 | 
				
			||||||
      background-color: lightgrey;
 | 
					 | 
				
			||||||
      color: black;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  .line {
 | 
					 | 
				
			||||||
    padding-right: 0.5rem;
 | 
					 | 
				
			||||||
    border-right: 2px solid grey;
 | 
					 | 
				
			||||||
    min-width: 1.5rem;
 | 
					 | 
				
			||||||
    text-align: right;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  p {
 | 
					 | 
				
			||||||
    margin: 0;
 | 
					 | 
				
			||||||
    padding: 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
@@ -1,146 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <div class="flex column">
 | 
					 | 
				
			||||||
    <div @click="toggleMessage" :class="{error: log.type === 'error', open: messageOpen}" class="flex log" :data-details="`${log.type} @ ${log.timestamp}`">
 | 
					 | 
				
			||||||
        <Chevron class="chevron" :rotate="messageOpen" />
 | 
					 | 
				
			||||||
        <span>{{ log.message }}</span>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    <transition name="slide">
 | 
					 | 
				
			||||||
      <div v-if="messageOpen" class="details">{{ otherData(log) }}</div>
 | 
					 | 
				
			||||||
    </transition>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script>
 | 
					 | 
				
			||||||
import Chevron from "@/ui/Chevron";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
  components: { Chevron },
 | 
					 | 
				
			||||||
  props: {
 | 
					 | 
				
			||||||
    log: {
 | 
					 | 
				
			||||||
      type: String,
 | 
					 | 
				
			||||||
      required: true
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  data() {
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
      messageOpen: null
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  methods: {
 | 
					 | 
				
			||||||
    toggleMessage(index) {
 | 
					 | 
				
			||||||
      this.messageOpen = !this.messageOpen;
 | 
					 | 
				
			||||||
      this.$emit('toggleMessage', this.messageOpen)
 | 
					 | 
				
			||||||
      setTimeout(() => {
 | 
					 | 
				
			||||||
        document.getElementsByClassName('selected')[0].classList.add('error')
 | 
					 | 
				
			||||||
      }, 1000)
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    otherData(data) {
 | 
					 | 
				
			||||||
      const ldata = { ...data };
 | 
					 | 
				
			||||||
      delete ldata.type;
 | 
					 | 
				
			||||||
      delete ldata.message
 | 
					 | 
				
			||||||
      if (Object.keys(ldata).length > 0) {
 | 
					 | 
				
			||||||
        return Object.keys(data).map(key => {
 | 
					 | 
				
			||||||
          if (typeof data[key] === 'object') {
 | 
					 | 
				
			||||||
            return `${key}: ${JSON.stringify(data[key], null, 1)}`
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          return `${key}: ${data[key]}`}
 | 
					 | 
				
			||||||
        ).join('\n')
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return '';
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
.details {
 | 
					 | 
				
			||||||
  display: inline-flex;
 | 
					 | 
				
			||||||
  background-color: inherit;
 | 
					 | 
				
			||||||
  color: inherit;
 | 
					 | 
				
			||||||
  margin: 0.2rem 0.2rem 0;
 | 
					 | 
				
			||||||
  padding: 0 1rem 0.5rem;
 | 
					 | 
				
			||||||
  border-bottom: 1px solid #333333;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.chevron {
 | 
					 | 
				
			||||||
  padding-right: 0.5rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.slide-enter-active {
 | 
					 | 
				
			||||||
   -moz-transition-duration: 0.2s;
 | 
					 | 
				
			||||||
   -webkit-transition-duration: 0.2s;
 | 
					 | 
				
			||||||
   -o-transition-duration: 0.2s;
 | 
					 | 
				
			||||||
   transition-duration: 0.2s;
 | 
					 | 
				
			||||||
   -moz-transition-timing-function: ease;
 | 
					 | 
				
			||||||
   -webkit-transition-timing-function: ease;
 | 
					 | 
				
			||||||
   -o-transition-timing-function: ease;
 | 
					 | 
				
			||||||
   transition-timing-function: ease;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.slide-leave-active {
 | 
					 | 
				
			||||||
   -moz-transition-duration: 0.3s;
 | 
					 | 
				
			||||||
   -webkit-transition-duration: 0.3s;
 | 
					 | 
				
			||||||
   -o-transition-duration: 0.3s;
 | 
					 | 
				
			||||||
   transition-duration: 0.3s;
 | 
					 | 
				
			||||||
   -moz-transition-timing-function: ease;
 | 
					 | 
				
			||||||
   -webkit-transition-timing-function: ease;
 | 
					 | 
				
			||||||
   -o-transition-timing-function: ease;
 | 
					 | 
				
			||||||
   transition-timing-function: ease;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.slide-enter-to, .slide-leave {
 | 
					 | 
				
			||||||
   max-height: 100px;
 | 
					 | 
				
			||||||
   overflow: hidden;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.slide-enter, .slide-leave-to {
 | 
					 | 
				
			||||||
   overflow: hidden;
 | 
					 | 
				
			||||||
   max-height: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.log {
 | 
					 | 
				
			||||||
  padding: 0 0.5rem;
 | 
					 | 
				
			||||||
  position: relative;
 | 
					 | 
				
			||||||
  // width: 100%;
 | 
					 | 
				
			||||||
  cursor: pointer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  &.error {
 | 
					 | 
				
			||||||
    border-top-right-radius: 1rem;
 | 
					 | 
				
			||||||
    border-bottom-right-radius: 1rem;
 | 
					 | 
				
			||||||
    background-color: #F24647;
 | 
					 | 
				
			||||||
    color: white;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  &.error.open {
 | 
					 | 
				
			||||||
    border-top-right-radius: 0px;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  &:hover {
 | 
					 | 
				
			||||||
    background-color: rgba(128, 127, 127, 0.8);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    &.error {
 | 
					 | 
				
			||||||
      background-color: #F24647;
 | 
					 | 
				
			||||||
      border-top-left-radius: 0px;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    &.error:after {
 | 
					 | 
				
			||||||
      background-color: rgba(#F24647, .8);
 | 
					 | 
				
			||||||
      border-radius: 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    &:after {
 | 
					 | 
				
			||||||
      pointer-events: none;
 | 
					 | 
				
			||||||
      content: attr(data-details);
 | 
					 | 
				
			||||||
      display: block;
 | 
					 | 
				
			||||||
      color: white;
 | 
					 | 
				
			||||||
      position: absolute;
 | 
					 | 
				
			||||||
      top: -22px;
 | 
					 | 
				
			||||||
      line-height: 22px;
 | 
					 | 
				
			||||||
      left: 0;
 | 
					 | 
				
			||||||
      background-color: inherit;
 | 
					 | 
				
			||||||
      padding: 0 .5rem;
 | 
					 | 
				
			||||||
      border-top-right-radius: 6px;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
@@ -97,7 +97,7 @@ export default {
 | 
				
			|||||||
    this.socket = null;
 | 
					    this.socket = null;
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  mounted() {
 | 
					  mounted() {
 | 
				
			||||||
    this.socket = io('/chat');
 | 
					    this.socket = io(window.location.origin);
 | 
				
			||||||
    this.socket.on("chat", msg => {
 | 
					    this.socket.on("chat", msg => {
 | 
				
			||||||
      this.chatHistory.push(msg);
 | 
					      this.chatHistory.push(msg);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,22 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-down" :class="{rotate}"><polyline points="6 9 12 15 18 9"></polyline></svg>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script>
 | 
					 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
  props: {
 | 
					 | 
				
			||||||
    rotate: false,
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
.feather-chevron-down {
 | 
					 | 
				
			||||||
  transition: all .3s ease;
 | 
					 | 
				
			||||||
  transform-origin: 12px;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  &.rotate {
 | 
					 | 
				
			||||||
    transform: rotate(-180deg);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
@@ -19,14 +19,6 @@ function daysAgo(date) {
 | 
				
			|||||||
  return Math.round(Math.abs((new Date() - new Date(date)) / day));
 | 
					  return Math.round(Math.abs((new Date() - new Date(date)) / day));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function minimalHumanDateResolution(seconds) {
 | 
					 | 
				
			||||||
  if (seconds < 999) {
 | 
					 | 
				
			||||||
    return `${seconds}s`;
 | 
					 | 
				
			||||||
  } else if (seconds) {
 | 
					 | 
				
			||||||
    return true
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function createCookie(name, value, days) {
 | 
					export function createCookie(name, value, days) {
 | 
				
			||||||
  if (days) {
 | 
					  if (days) {
 | 
				
			||||||
    var date = new Date();
 | 
					    var date = new Date();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,7 +60,7 @@ function redirectIfHasAccessCodeAndOnIncorrectDomain(accessCode) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const accessCode = readCookie("accesscode");
 | 
					const accessCode = readCookie("accesscode");
 | 
				
			||||||
redirectIfHasAccessCodeAndOnIncorrectDomain(accessCode);
 | 
					redirectIfHasAccessCodeAndOnIncorrectDomain(1);
 | 
				
			||||||
const component = accessCode ? Vinlottis : AccessCodePage;
 | 
					const component = accessCode ? Vinlottis : AccessCodePage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
new Vue({
 | 
					new Vue({
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,6 @@
 | 
				
			|||||||
    "connect-mongo": "^3.2.0",
 | 
					    "connect-mongo": "^3.2.0",
 | 
				
			||||||
    "cross-env": "^7.0.3",
 | 
					    "cross-env": "^7.0.3",
 | 
				
			||||||
    "express": "^4.17.1",
 | 
					    "express": "^4.17.1",
 | 
				
			||||||
    "express-http-context": "^1.2.4",
 | 
					 | 
				
			||||||
    "express-session": "^1.17.0",
 | 
					    "express-session": "^1.17.0",
 | 
				
			||||||
    "moment": "^2.24.0",
 | 
					    "moment": "^2.24.0",
 | 
				
			||||||
    "mongoose": "^5.11.4",
 | 
					    "mongoose": "^5.11.4",
 | 
				
			||||||
@@ -39,8 +38,7 @@
 | 
				
			|||||||
    "vue": "~2.6",
 | 
					    "vue": "~2.6",
 | 
				
			||||||
    "vue-router": "~3.5.1",
 | 
					    "vue-router": "~3.5.1",
 | 
				
			||||||
    "vuex": "^3.6.0",
 | 
					    "vuex": "^3.6.0",
 | 
				
			||||||
    "web-push": "^3.4.3",
 | 
					    "web-push": "^3.4.3"
 | 
				
			||||||
    "winston": "^3.3.3"
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@babel/core": "~7.12",
 | 
					    "@babel/core": "~7.12",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +0,0 @@
 | 
				
			|||||||
settings.json
 | 
					 | 
				
			||||||
@@ -5,18 +5,12 @@ const io = require("socket.io")(server);
 | 
				
			|||||||
const path = require("path");
 | 
					const path = require("path");
 | 
				
			||||||
const session = require("express-session");
 | 
					const session = require("express-session");
 | 
				
			||||||
const User = require(path.join(__dirname + "/api/schemas/User"));
 | 
					const User = require(path.join(__dirname + "/api/schemas/User"));
 | 
				
			||||||
global.__base = path.join(__dirname, "/api/");
 | 
					 | 
				
			||||||
global.__middleware = path.join(__dirname, "/api/middleware");
 | 
					 | 
				
			||||||
global.__controllers = path.join(__dirname, "/api/controllers");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const apiRouter = require(path.join(__dirname + "/api/router.js"));
 | 
					const apiRouter = require(path.join(__dirname + "/api/router.js"));
 | 
				
			||||||
const subscriptionApi = require(path.join(__dirname + "/api/subscriptions"));
 | 
					const subscriptionApi = require(path.join(__dirname + "/api/subscriptions"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//This is required for the chat to work
 | 
					//This is required for the chat to work
 | 
				
			||||||
const chat = require(path.join(__dirname + "/api/chat"))(io);
 | 
					const chat = require(path.join(__dirname + "/api/chat"))(io);
 | 
				
			||||||
const smsGatewayLogs = require(path.join(__dirname + "/api/smsGatewayLogs"))(io);
 | 
					 | 
				
			||||||
io.of('/chat', chat)
 | 
					 | 
				
			||||||
io.of('/logs/sms-gateway', smsGatewayLogs)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const mongoose = require("mongoose");
 | 
					const mongoose = require("mongoose");
 | 
				
			||||||
const MongoStore = require("connect-mongo")(session);
 | 
					const MongoStore = require("connect-mongo")(session);
 | 
				
			||||||
@@ -58,9 +52,6 @@ if (process.env.NODE_ENV == "development") {
 | 
				
			|||||||
// parse application/json
 | 
					// parse application/json
 | 
				
			||||||
app.use(express.json());
 | 
					app.use(express.json());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const addIdToRequest = require(`${__middleware}/addIdToRequest`);
 | 
					 | 
				
			||||||
app.use(addIdToRequest);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app.use(
 | 
					app.use(
 | 
				
			||||||
  session({
 | 
					  session({
 | 
				
			||||||
    secret: "passport-tutorial",
 | 
					    secret: "passport-tutorial",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										272
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										272
									
								
								yarn.lock
									
									
									
									
									
								
							@@ -804,15 +804,6 @@
 | 
				
			|||||||
    "@babel/helper-validator-identifier" "^7.12.11"
 | 
					    "@babel/helper-validator-identifier" "^7.12.11"
 | 
				
			||||||
    to-fast-properties "^2.0.0"
 | 
					    to-fast-properties "^2.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@dabh/diagnostics@^2.0.2":
 | 
					 | 
				
			||||||
  version "2.0.2"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31"
 | 
					 | 
				
			||||||
  integrity sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    colorspace "1.1.x"
 | 
					 | 
				
			||||||
    enabled "2.0.x"
 | 
					 | 
				
			||||||
    kuler "^2.0.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"@discoveryjs/json-ext@^0.5.0":
 | 
					"@discoveryjs/json-ext@^0.5.0":
 | 
				
			||||||
  version "0.5.2"
 | 
					  version "0.5.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752"
 | 
					  resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752"
 | 
				
			||||||
@@ -902,14 +893,6 @@
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a"
 | 
					  resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a"
 | 
				
			||||||
  integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==
 | 
					  integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@types/body-parser@*":
 | 
					 | 
				
			||||||
  version "1.19.1"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.1.tgz#0c0174c42a7d017b818303d4b5d969cb0b75929c"
 | 
					 | 
				
			||||||
  integrity sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    "@types/connect" "*"
 | 
					 | 
				
			||||||
    "@types/node" "*"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"@types/bson@*":
 | 
					"@types/bson@*":
 | 
				
			||||||
  version "4.0.3"
 | 
					  version "4.0.3"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/bson/-/bson-4.0.3.tgz#30889d2ffde6262abbe38659364c631454999fbf"
 | 
					  resolved "https://registry.yarnpkg.com/@types/bson/-/bson-4.0.3.tgz#30889d2ffde6262abbe38659364c631454999fbf"
 | 
				
			||||||
@@ -917,25 +900,11 @@
 | 
				
			|||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@types/node" "*"
 | 
					    "@types/node" "*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@types/cls-hooked@^4.2.1":
 | 
					 | 
				
			||||||
  version "4.3.3"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/cls-hooked/-/cls-hooked-4.3.3.tgz#c09e2f8dc62198522eaa18a5b6b873053154bd00"
 | 
					 | 
				
			||||||
  integrity sha512-gNstDTb/ty5h6gJd6YpSPgsLX9LmRpaKJqGFp7MRlYxhwp4vXXKlJ9+bt1TZ9KbVNXE+Mbxy2AYXcpY21DDtJw==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    "@types/node" "*"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"@types/component-emitter@^1.2.10":
 | 
					"@types/component-emitter@^1.2.10":
 | 
				
			||||||
  version "1.2.10"
 | 
					  version "1.2.10"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.10.tgz#ef5b1589b9f16544642e473db5ea5639107ef3ea"
 | 
					  resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.10.tgz#ef5b1589b9f16544642e473db5ea5639107ef3ea"
 | 
				
			||||||
  integrity sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==
 | 
					  integrity sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@types/connect@*":
 | 
					 | 
				
			||||||
  version "3.4.35"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1"
 | 
					 | 
				
			||||||
  integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    "@types/node" "*"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"@types/cookie@^0.4.0":
 | 
					"@types/cookie@^0.4.0":
 | 
				
			||||||
  version "0.4.0"
 | 
					  version "0.4.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.0.tgz#14f854c0f93d326e39da6e3b6f34f7d37513d108"
 | 
					  resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.0.tgz#14f854c0f93d326e39da6e3b6f34f7d37513d108"
 | 
				
			||||||
@@ -972,25 +941,6 @@
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.46.tgz#0fb6bfbbeabd7a30880504993369c4bf1deab1fe"
 | 
					  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.46.tgz#0fb6bfbbeabd7a30880504993369c4bf1deab1fe"
 | 
				
			||||||
  integrity sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==
 | 
					  integrity sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@types/express-serve-static-core@^4.17.18":
 | 
					 | 
				
			||||||
  version "4.17.24"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz#ea41f93bf7e0d59cd5a76665068ed6aab6815c07"
 | 
					 | 
				
			||||||
  integrity sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    "@types/node" "*"
 | 
					 | 
				
			||||||
    "@types/qs" "*"
 | 
					 | 
				
			||||||
    "@types/range-parser" "*"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"@types/express@^4.16.0":
 | 
					 | 
				
			||||||
  version "4.17.13"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034"
 | 
					 | 
				
			||||||
  integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    "@types/body-parser" "*"
 | 
					 | 
				
			||||||
    "@types/express-serve-static-core" "^4.17.18"
 | 
					 | 
				
			||||||
    "@types/qs" "*"
 | 
					 | 
				
			||||||
    "@types/serve-static" "*"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"@types/glob@^7.1.1":
 | 
					"@types/glob@^7.1.1":
 | 
				
			||||||
  version "7.1.3"
 | 
					  version "7.1.3"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
 | 
					  resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
 | 
				
			||||||
@@ -1009,11 +959,6 @@
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
 | 
					  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
 | 
				
			||||||
  integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
 | 
					  integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@types/mime@^1":
 | 
					 | 
				
			||||||
  version "1.3.2"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
 | 
					 | 
				
			||||||
  integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"@types/minimatch@*":
 | 
					"@types/minimatch@*":
 | 
				
			||||||
  version "3.0.4"
 | 
					  version "3.0.4"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21"
 | 
					  resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21"
 | 
				
			||||||
@@ -1037,24 +982,6 @@
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
 | 
					  resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
 | 
				
			||||||
  integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
 | 
					  integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@types/qs@*":
 | 
					 | 
				
			||||||
  version "6.9.7"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
 | 
					 | 
				
			||||||
  integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"@types/range-parser@*":
 | 
					 | 
				
			||||||
  version "1.2.4"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
 | 
					 | 
				
			||||||
  integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"@types/serve-static@*":
 | 
					 | 
				
			||||||
  version "1.13.10"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9"
 | 
					 | 
				
			||||||
  integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    "@types/mime" "^1"
 | 
					 | 
				
			||||||
    "@types/node" "*"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"@types/source-list-map@*":
 | 
					"@types/source-list-map@*":
 | 
				
			||||||
  version "0.1.2"
 | 
					  version "0.1.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
 | 
					  resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
 | 
				
			||||||
@@ -1472,13 +1399,6 @@ async-each@^1.0.1:
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
 | 
					  resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
 | 
				
			||||||
  integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
 | 
					  integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async-hook-jl@^1.7.6:
 | 
					 | 
				
			||||||
  version "1.7.6"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/async-hook-jl/-/async-hook-jl-1.7.6.tgz#4fd25c2f864dbaf279c610d73bf97b1b28595e68"
 | 
					 | 
				
			||||||
  integrity sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    stack-chain "^1.3.7"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async-limiter@~1.0.0:
 | 
					async-limiter@~1.0.0:
 | 
				
			||||||
  version "1.0.1"
 | 
					  version "1.0.1"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
 | 
					  resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
 | 
				
			||||||
@@ -1491,11 +1411,6 @@ async@^2.6.2:
 | 
				
			|||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    lodash "^4.17.14"
 | 
					    lodash "^4.17.14"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async@^3.1.0:
 | 
					 | 
				
			||||||
  version "3.2.2"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/async/-/async-3.2.2.tgz#2eb7671034bb2194d45d30e31e24ec7e7f9670cd"
 | 
					 | 
				
			||||||
  integrity sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
atob@^2.1.2:
 | 
					atob@^2.1.2:
 | 
				
			||||||
  version "2.1.2"
 | 
					  version "2.1.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
 | 
					  resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
 | 
				
			||||||
@@ -2002,15 +1917,6 @@ clone-response@^1.0.2:
 | 
				
			|||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    mimic-response "^1.0.0"
 | 
					    mimic-response "^1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cls-hooked@^4.2.2:
 | 
					 | 
				
			||||||
  version "4.2.2"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
 | 
					 | 
				
			||||||
  integrity sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    async-hook-jl "^1.7.6"
 | 
					 | 
				
			||||||
    emitter-listener "^1.0.1"
 | 
					 | 
				
			||||||
    semver "^5.4.1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
coa@^2.0.2:
 | 
					coa@^2.0.2:
 | 
				
			||||||
  version "2.0.2"
 | 
					  version "2.0.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3"
 | 
					  resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3"
 | 
				
			||||||
@@ -2060,14 +1966,6 @@ color-string@^1.5.4:
 | 
				
			|||||||
    color-name "^1.0.0"
 | 
					    color-name "^1.0.0"
 | 
				
			||||||
    simple-swizzle "^0.2.2"
 | 
					    simple-swizzle "^0.2.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
color-string@^1.6.0:
 | 
					 | 
				
			||||||
  version "1.6.0"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.6.0.tgz#c3915f61fe267672cb7e1e064c9d692219f6c312"
 | 
					 | 
				
			||||||
  integrity sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    color-name "^1.0.0"
 | 
					 | 
				
			||||||
    simple-swizzle "^0.2.2"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
color@^3.0.0:
 | 
					color@^3.0.0:
 | 
				
			||||||
  version "3.1.3"
 | 
					  version "3.1.3"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e"
 | 
					  resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e"
 | 
				
			||||||
@@ -2076,32 +1974,11 @@ color@^3.0.0:
 | 
				
			|||||||
    color-convert "^1.9.1"
 | 
					    color-convert "^1.9.1"
 | 
				
			||||||
    color-string "^1.5.4"
 | 
					    color-string "^1.5.4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
color@^3.1.3:
 | 
					 | 
				
			||||||
  version "3.2.1"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164"
 | 
					 | 
				
			||||||
  integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    color-convert "^1.9.3"
 | 
					 | 
				
			||||||
    color-string "^1.6.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
colorette@^1.2.1, colorette@^1.2.2:
 | 
					colorette@^1.2.1, colorette@^1.2.2:
 | 
				
			||||||
  version "1.2.2"
 | 
					  version "1.2.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
 | 
					  resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
 | 
				
			||||||
  integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
 | 
					  integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
colors@^1.2.1:
 | 
					 | 
				
			||||||
  version "1.4.0"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
 | 
					 | 
				
			||||||
  integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
colorspace@1.1.x:
 | 
					 | 
				
			||||||
  version "1.1.4"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243"
 | 
					 | 
				
			||||||
  integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    color "^3.1.3"
 | 
					 | 
				
			||||||
    text-hex "1.0.x"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commander@^2.20.0:
 | 
					commander@^2.20.0:
 | 
				
			||||||
  version "2.20.3"
 | 
					  version "2.20.3"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
 | 
					  resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
 | 
				
			||||||
@@ -2469,9 +2346,9 @@ debug@3.1.0:
 | 
				
			|||||||
    ms "2.0.0"
 | 
					    ms "2.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
debug@4, debug@^4.1.0, debug@^4.1.1, debug@~4.3.1:
 | 
					debug@4, debug@^4.1.0, debug@^4.1.1, debug@~4.3.1:
 | 
				
			||||||
  version "4.3.1"
 | 
					  version "4.3.3"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
 | 
					  resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
 | 
				
			||||||
  integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
 | 
					  integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    ms "2.1.2"
 | 
					    ms "2.1.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2703,13 +2580,6 @@ electron-to-chromium@^1.3.719:
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.723.tgz#52769a75635342a4db29af5f1e40bd3dad02c877"
 | 
					  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.723.tgz#52769a75635342a4db29af5f1e40bd3dad02c877"
 | 
				
			||||||
  integrity sha512-L+WXyXI7c7+G1V8ANzRsPI5giiimLAUDC6Zs1ojHHPhYXb3k/iTABFmWjivEtsWrRQymjnO66/rO2ZTABGdmWg==
 | 
					  integrity sha512-L+WXyXI7c7+G1V8ANzRsPI5giiimLAUDC6Zs1ojHHPhYXb3k/iTABFmWjivEtsWrRQymjnO66/rO2ZTABGdmWg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
emitter-listener@^1.0.1:
 | 
					 | 
				
			||||||
  version "1.1.2"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8"
 | 
					 | 
				
			||||||
  integrity sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    shimmer "^1.2.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
emoji-regex@^7.0.1:
 | 
					emoji-regex@^7.0.1:
 | 
				
			||||||
  version "7.0.3"
 | 
					  version "7.0.3"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
 | 
					  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
 | 
				
			||||||
@@ -2725,11 +2595,6 @@ emojis-list@^3.0.0:
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
 | 
					  resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
 | 
				
			||||||
  integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
 | 
					  integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enabled@2.0.x:
 | 
					 | 
				
			||||||
  version "2.0.0"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2"
 | 
					 | 
				
			||||||
  integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
encodeurl@~1.0.2:
 | 
					encodeurl@~1.0.2:
 | 
				
			||||||
  version "1.0.2"
 | 
					  version "1.0.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
 | 
					  resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
 | 
				
			||||||
@@ -2759,16 +2624,16 @@ engine.io-client@~4.1.0:
 | 
				
			|||||||
    yeast "0.1.2"
 | 
					    yeast "0.1.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
engine.io-parser@~4.0.0, engine.io-parser@~4.0.1:
 | 
					engine.io-parser@~4.0.0, engine.io-parser@~4.0.1:
 | 
				
			||||||
  version "4.0.2"
 | 
					  version "4.0.3"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.2.tgz#e41d0b3fb66f7bf4a3671d2038a154024edb501e"
 | 
					  resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.3.tgz#83d3a17acfd4226f19e721bb22a1ee8f7662d2f6"
 | 
				
			||||||
  integrity sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==
 | 
					  integrity sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    base64-arraybuffer "0.1.4"
 | 
					    base64-arraybuffer "0.1.4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
engine.io@~4.1.0:
 | 
					engine.io@~4.1.0:
 | 
				
			||||||
  version "4.1.1"
 | 
					  version "4.1.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.1.tgz#9a8f8a5ac5a5ea316183c489bf7f5b6cf91ace5b"
 | 
					  resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.2.tgz#f96ceb56d4b39cc7ca5bd29a20e9c99c1ad1a765"
 | 
				
			||||||
  integrity sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w==
 | 
					  integrity sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    accepts "~1.3.4"
 | 
					    accepts "~1.3.4"
 | 
				
			||||||
    base64id "2.0.0"
 | 
					    base64id "2.0.0"
 | 
				
			||||||
@@ -2988,15 +2853,6 @@ expand-brackets@^2.1.4:
 | 
				
			|||||||
    snapdragon "^0.8.1"
 | 
					    snapdragon "^0.8.1"
 | 
				
			||||||
    to-regex "^3.0.1"
 | 
					    to-regex "^3.0.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
express-http-context@^1.2.4:
 | 
					 | 
				
			||||||
  version "1.2.4"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/express-http-context/-/express-http-context-1.2.4.tgz#49769d0e260836278996e728d9a3e7f3735f0531"
 | 
					 | 
				
			||||||
  integrity sha512-jPpBbF1MWWdRcUU1rxsX0CPnA8ueEj8xgWvpRGHoXWGI4l5KqhPY4Bq+Gt6s2IhqHQQ0g0wIvJ3jFfbUuJJycQ==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    "@types/cls-hooked" "^4.2.1"
 | 
					 | 
				
			||||||
    "@types/express" "^4.16.0"
 | 
					 | 
				
			||||||
    cls-hooked "^4.2.2"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
express-session@^1.17.0:
 | 
					express-session@^1.17.0:
 | 
				
			||||||
  version "1.17.1"
 | 
					  version "1.17.1"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.1.tgz#36ecbc7034566d38c8509885c044d461c11bf357"
 | 
					  resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.1.tgz#36ecbc7034566d38c8509885c044d461c11bf357"
 | 
				
			||||||
@@ -3098,11 +2954,6 @@ faye-websocket@^0.11.3:
 | 
				
			|||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    websocket-driver ">=0.5.1"
 | 
					    websocket-driver ">=0.5.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fecha@^4.2.0:
 | 
					 | 
				
			||||||
  version "4.2.1"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce"
 | 
					 | 
				
			||||||
  integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
file-loader@^6.2.0:
 | 
					file-loader@^6.2.0:
 | 
				
			||||||
  version "6.2.0"
 | 
					  version "6.2.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d"
 | 
					  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d"
 | 
				
			||||||
@@ -3170,11 +3021,6 @@ find-up@^4.0.0:
 | 
				
			|||||||
    locate-path "^5.0.0"
 | 
					    locate-path "^5.0.0"
 | 
				
			||||||
    path-exists "^4.0.0"
 | 
					    path-exists "^4.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn.name@1.x.x:
 | 
					 | 
				
			||||||
  version "1.1.0"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc"
 | 
					 | 
				
			||||||
  integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
follow-redirects@^1.0.0:
 | 
					follow-redirects@^1.0.0:
 | 
				
			||||||
  version "1.14.0"
 | 
					  version "1.14.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.0.tgz#f5d260f95c5f8c105894491feee5dc8993b402fe"
 | 
					  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.0.tgz#f5d260f95c5f8c105894491feee5dc8993b402fe"
 | 
				
			||||||
@@ -4214,11 +4060,6 @@ klona@^2.0.4:
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0"
 | 
					  resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0"
 | 
				
			||||||
  integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==
 | 
					  integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
kuler@^2.0.0:
 | 
					 | 
				
			||||||
  version "2.0.0"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3"
 | 
					 | 
				
			||||||
  integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
last-call-webpack-plugin@^3.0.0:
 | 
					last-call-webpack-plugin@^3.0.0:
 | 
				
			||||||
  version "3.0.0"
 | 
					  version "3.0.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555"
 | 
					  resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555"
 | 
				
			||||||
@@ -4301,17 +4142,6 @@ lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
 | 
					  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
 | 
				
			||||||
  integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
 | 
					  integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logform@^2.2.0:
 | 
					 | 
				
			||||||
  version "2.3.0"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/logform/-/logform-2.3.0.tgz#a3997a05985de2ebd325ae0d166dffc9c6fe6b57"
 | 
					 | 
				
			||||||
  integrity sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    colors "^1.2.1"
 | 
					 | 
				
			||||||
    fecha "^4.2.0"
 | 
					 | 
				
			||||||
    ms "^2.1.1"
 | 
					 | 
				
			||||||
    safe-stable-stringify "^1.1.0"
 | 
					 | 
				
			||||||
    triple-beam "^1.3.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
loglevel@^1.6.8:
 | 
					loglevel@^1.6.8:
 | 
				
			||||||
  version "1.7.1"
 | 
					  version "1.7.1"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
 | 
					  resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
 | 
				
			||||||
@@ -4452,13 +4282,25 @@ mime-db@1.47.0, "mime-db@>= 1.43.0 < 2":
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c"
 | 
					  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c"
 | 
				
			||||||
  integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
 | 
					  integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.24:
 | 
					mime-db@1.51.0:
 | 
				
			||||||
 | 
					  version "1.51.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c"
 | 
				
			||||||
 | 
					  integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mime-types@^2.1.27, mime-types@~2.1.17:
 | 
				
			||||||
  version "2.1.30"
 | 
					  version "2.1.30"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d"
 | 
					  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d"
 | 
				
			||||||
  integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==
 | 
					  integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    mime-db "1.47.0"
 | 
					    mime-db "1.47.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mime-types@~2.1.24:
 | 
				
			||||||
 | 
					  version "2.1.34"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24"
 | 
				
			||||||
 | 
					  integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    mime-db "1.51.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mime@1.6.0:
 | 
					mime@1.6.0:
 | 
				
			||||||
  version "1.6.0"
 | 
					  version "1.6.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
 | 
					  resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
 | 
				
			||||||
@@ -4849,13 +4691,6 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
 | 
				
			|||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    wrappy "1"
 | 
					    wrappy "1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
one-time@^1.0.0:
 | 
					 | 
				
			||||||
  version "1.0.0"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45"
 | 
					 | 
				
			||||||
  integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    fn.name "1.x.x"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
onetime@^5.1.2:
 | 
					onetime@^5.1.2:
 | 
				
			||||||
  version "5.1.2"
 | 
					  version "5.1.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
 | 
					  resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
 | 
				
			||||||
@@ -5603,7 +5438,7 @@ rc@^1.2.8:
 | 
				
			|||||||
    minimist "^1.2.0"
 | 
					    minimist "^1.2.0"
 | 
				
			||||||
    strip-json-comments "~2.0.1"
 | 
					    strip-json-comments "~2.0.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.3.5, readable-stream@^2.3.7:
 | 
					readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.3.5:
 | 
				
			||||||
  version "2.3.7"
 | 
					  version "2.3.7"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
 | 
					  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
 | 
				
			||||||
  integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
 | 
					  integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
 | 
				
			||||||
@@ -5616,7 +5451,7 @@ readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.3.5, readable
 | 
				
			|||||||
    string_decoder "~1.1.1"
 | 
					    string_decoder "~1.1.1"
 | 
				
			||||||
    util-deprecate "~1.0.1"
 | 
					    util-deprecate "~1.0.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0:
 | 
					readable-stream@^3.0.6, readable-stream@^3.1.1:
 | 
				
			||||||
  version "3.6.0"
 | 
					  version "3.6.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
 | 
					  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
 | 
				
			||||||
  integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
 | 
					  integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
 | 
				
			||||||
@@ -5897,11 +5732,6 @@ safe-regex@^1.1.0:
 | 
				
			|||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    ret "~0.1.10"
 | 
					    ret "~0.1.10"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
safe-stable-stringify@^1.1.0:
 | 
					 | 
				
			||||||
  version "1.1.1"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz#c8a220ab525cd94e60ebf47ddc404d610dc5d84a"
 | 
					 | 
				
			||||||
  integrity sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0:
 | 
					"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0:
 | 
				
			||||||
  version "2.1.2"
 | 
					  version "2.1.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
 | 
					  resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
 | 
				
			||||||
@@ -6112,11 +5942,6 @@ shebang-regex@^3.0.0:
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
 | 
					  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
 | 
				
			||||||
  integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
 | 
					  integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
shimmer@^1.2.0:
 | 
					 | 
				
			||||||
  version "1.2.1"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
 | 
					 | 
				
			||||||
  integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sift@13.5.2:
 | 
					sift@13.5.2:
 | 
				
			||||||
  version "13.5.2"
 | 
					  version "13.5.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/sift/-/sift-13.5.2.tgz#24a715e13c617b086166cd04917d204a591c9da6"
 | 
					  resolved "https://registry.yarnpkg.com/sift/-/sift-13.5.2.tgz#24a715e13c617b086166cd04917d204a591c9da6"
 | 
				
			||||||
@@ -6337,16 +6162,6 @@ stable@^0.1.8:
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
 | 
					  resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
 | 
				
			||||||
  integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
 | 
					  integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
stack-chain@^1.3.7:
 | 
					 | 
				
			||||||
  version "1.3.7"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
 | 
					 | 
				
			||||||
  integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
stack-trace@0.0.x:
 | 
					 | 
				
			||||||
  version "0.0.10"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
 | 
					 | 
				
			||||||
  integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
stackframe@^1.1.1:
 | 
					stackframe@^1.1.1:
 | 
				
			||||||
  version "1.2.0"
 | 
					  version "1.2.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303"
 | 
					  resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303"
 | 
				
			||||||
@@ -6558,11 +6373,6 @@ terser@^5.5.1:
 | 
				
			|||||||
    source-map "~0.7.2"
 | 
					    source-map "~0.7.2"
 | 
				
			||||||
    source-map-support "~0.5.19"
 | 
					    source-map-support "~0.5.19"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
text-hex@1.0.x:
 | 
					 | 
				
			||||||
  version "1.0.0"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5"
 | 
					 | 
				
			||||||
  integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
thunky@^1.0.2:
 | 
					thunky@^1.0.2:
 | 
				
			||||||
  version "1.1.0"
 | 
					  version "1.1.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
 | 
					  resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
 | 
				
			||||||
@@ -6632,11 +6442,6 @@ touch@^3.1.0:
 | 
				
			|||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    nopt "~1.0.10"
 | 
					    nopt "~1.0.10"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
triple-beam@^1.2.0, triple-beam@^1.3.0:
 | 
					 | 
				
			||||||
  version "1.3.0"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9"
 | 
					 | 
				
			||||||
  integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ts-custom-error@^3.0.0:
 | 
					ts-custom-error@^3.0.0:
 | 
				
			||||||
  version "3.2.0"
 | 
					  version "3.2.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/ts-custom-error/-/ts-custom-error-3.2.0.tgz#ff8f80a3812bab9dc448536312da52dce1b720fb"
 | 
					  resolved "https://registry.yarnpkg.com/ts-custom-error/-/ts-custom-error-3.2.0.tgz#ff8f80a3812bab9dc448536312da52dce1b720fb"
 | 
				
			||||||
@@ -7168,29 +6973,6 @@ wildcard@^2.0.0:
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec"
 | 
					  resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec"
 | 
				
			||||||
  integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==
 | 
					  integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
winston-transport@^4.4.0:
 | 
					 | 
				
			||||||
  version "4.4.0"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59"
 | 
					 | 
				
			||||||
  integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    readable-stream "^2.3.7"
 | 
					 | 
				
			||||||
    triple-beam "^1.2.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
winston@^3.3.3:
 | 
					 | 
				
			||||||
  version "3.3.3"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170"
 | 
					 | 
				
			||||||
  integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    "@dabh/diagnostics" "^2.0.2"
 | 
					 | 
				
			||||||
    async "^3.1.0"
 | 
					 | 
				
			||||||
    is-stream "^2.0.0"
 | 
					 | 
				
			||||||
    logform "^2.2.0"
 | 
					 | 
				
			||||||
    one-time "^1.0.0"
 | 
					 | 
				
			||||||
    readable-stream "^3.4.0"
 | 
					 | 
				
			||||||
    stack-trace "0.0.x"
 | 
					 | 
				
			||||||
    triple-beam "^1.3.0"
 | 
					 | 
				
			||||||
    winston-transport "^4.4.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
wrap-ansi@^5.1.0:
 | 
					wrap-ansi@^5.1.0:
 | 
				
			||||||
  version "5.1.0"
 | 
					  version "5.1.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"
 | 
					  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"
 | 
				
			||||||
@@ -7223,9 +7005,9 @@ ws@^6.2.1:
 | 
				
			|||||||
    async-limiter "~1.0.0"
 | 
					    async-limiter "~1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ws@^7.3.1, ws@~7.4.2:
 | 
					ws@^7.3.1, ws@~7.4.2:
 | 
				
			||||||
  version "7.4.5"
 | 
					  version "7.4.6"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.5.tgz#a484dd851e9beb6fdb420027e3885e8ce48986c1"
 | 
					  resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
 | 
				
			||||||
  integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==
 | 
					  integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
xdg-basedir@^4.0.0:
 | 
					xdg-basedir@^4.0.0:
 | 
				
			||||||
  version "4.0.0"
 | 
					  version "4.0.0"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user