HW7: done task 4

This commit is contained in:
Claudio Maggioni 2019-11-13 16:07:57 +01:00
parent ef9219d436
commit d13d2ac182
11 changed files with 388 additions and 324 deletions

View file

@ -1,5 +1,6 @@
// vim: set ts=2 sw=2 et tw=80:
const debug = require('debug')('canvas-server');
const express = require('express');
const path = require('path');
const logger = require('morgan');
@ -28,19 +29,19 @@ app.set('view options', { layout: false });
app.use(methodOverride('_method'));
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.urlencoded({ extended: false, limit: '50mb' }));
// parse application/json
app.use(bodyParser.json());
app.use(bodyParser.json({ limit: '50mb' }));
// Needed to make fetch_tests passs
app.use(bodyParser.text({ type: '*/*' }));
app.use(bodyParser.text({ type: '*/*', limit: '50mb' }));
app.use(express.static('public'));
// Initialize routers here
const routers = require('./routes/routers');
app.use('/', routers.root);
// app.use('/favorites', routers.favourites_db);
// app.use('/favorites', routers.favourites_db_promises);
@ -48,4 +49,44 @@ app.use('/favorites', routers.favourites_db_asaw);
app.use('/bookmarked', routers.bookmarked);
app.use('/test/fetch', routers.fetch_tests);
app.set('port', process.env.PORT || 3000);
const server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
// Socket.io code
const io = require('socket.io')(server);
let id = 1;
io.on('connection', (socket) => {
console.log('client connected');
socket.emit('sessionId', { id: id++ });
socket.on('message', (msg) => {
console.log('message: ',msg);
msg.user = encodeURIComponent(msg.user);
msg.text = encodeURIComponent(msg.text);
socket.broadcast.emit('message', msg);
});
socket.on('disconnect', () => {
console.log('client disconnected');
});
});
const eventBus = require('./pubsub');
eventBus.on('favorite.created', (event) => {
io.emit('favorite.created', event);
});
eventBus.on('favorite.updated', (event) => {
io.emit('favorite.updated', event);
});
eventBus.on('favorite.deleted', (event) => {
io.emit('favorite.deleted', event);
});
module.exports = app;

View file

@ -1,9 +1,3 @@
#!/usr/bin/env node
var debug = require('debug')('canvas-server');
var app = require('../app');
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});

View file

@ -28,6 +28,7 @@
"mongoose": "^5.7.7",
"morgan": "^1.9.0",
"request": "^2.88.0",
"socket.io": "^2.3.0",
"supertest": "^3.0.0"
},
"devDependencies": {

View file

@ -11,6 +11,7 @@ class App {
render_timestamp = 0;
render_last = null;
render_timeout = null;
socketSessionId = null;
registerFavoriteEvents(_id, dom) {
const form = dom.querySelector('form');
@ -46,21 +47,22 @@ class App {
const formData = new FormData(form);
const name = formData.get('name');
const dataURL = formData.get('dataURL');
const query = '?socketid=' + this.socketSessionId;
switch (action) {
case 'data-update':
p = doJSONRequest('PUT', '/favorites/' + _id, {},
p = doJSONRequest('PUT', '/favorites/' + _id + query, {},
{ name, dataURL });
break;
case 'data-delete':
p = doJSONRequest('DELETE', '/favorites/' + _id);
p = doJSONRequest('DELETE', '/favorites/' + _id + query);
break;
case 'data-bookmark':
p = doJSONRequest('PUT', `/favorites/${_id}/bookmarked`,
p = doJSONRequest('PUT', `/favorites/${_id}/bookmarked` + query,
{}, { bookmarked: true });
break;
case 'data-del-bookmark':
p = doJSONRequest('PUT', `/favorites/${_id}/bookmarked`,
p = doJSONRequest('PUT', `/favorites/${_id}/bookmarked` + query,
{}, { bookmarked: false });
break;
default:
@ -151,6 +153,48 @@ class App {
.catch(console.error);
}
initSocket() {
const socket = io();
socket.on('connect', () => {
console.log("Socket connected");
});
socket.on('sessionId', (msg) => {
console.log("Socket session id is", msg.id);
this.socketSessionId = msg.id;
});
socket.on('disconnect', (reason) => {
console.log("Socket disconnected");
});
socket.on('reconnect', (attemptNumber) => {
console.log("Socket reconnected");
});
socket.on('favorite.created', (msg) => {
if (msg.socketid != this.socketSessionId) {
console.log(msg);
this.renderFavorite(msg, 'top');
}
});
socket.on('favorite.updated', (msg) => {
if (msg.socketid != this.socketSessionId) {
this.renderFavorite(msg, document
.getElementById('favorite_' + msg._id));
}
console.log(msg);
});
socket.on('favorite.deleted', (msg) => {
if (msg.socketid != this.socketSessionId) {
document.getElementById('favorite_' + msg._id).remove();
}
});
}
constructor(conf) {
if (!(typeof conf === 'object' && conf)) {
throw new Error('Argument conf different from specification');
@ -164,6 +208,7 @@ class App {
this.ctx = this.canvas.getContext('2d');
this.favourites = document.querySelector('div#favourites');
this.initSocket();
this.getFavorites(false);
const nameFilter = document.getElementById('name-filter');
@ -211,7 +256,8 @@ class App {
bookmarked: false
};
doJSONRequest("POST", "/favorites", {}, data)
doJSONRequest("POST", "/favorites?socketid=" + this.socketSessionId,
{}, data)
.then(data => this.renderFavorite(data, 'top'))
.catch(console.error);
});
@ -225,6 +271,11 @@ class App {
imgCanvas.width = this.canvas.width;
imgCanvas.height = this.canvas.height;
const img = document.createElement('img');
imgCanvas.getContext('2d').drawImage(player, 0, 0, imgCanvas.width,
imgCanvas.height);
console.log(imgCanvas.toDataURL());
img.src = imgCanvas.toDataURL();
img.addEventListener('load', () => {
this.background = img;

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,5 @@
const EventEmitter = require('events');
const emitter = new EventEmitter();
module.exports = emitter;

View file

@ -1,162 +0,0 @@
/** @module root/router */
'use strict';
// vim: set ts=2 sw=2 et tw=80:
const fs = require('fs');
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Favorite = mongoose.model('Favorite');
const { error, renderFav, parseId, notFound } = require('../utils');
function findAndRender(filter, req, res) {
Favorite.find(filter, (err, favs) => {
if (err) {
return error(err, res);
}
renderFav(req, res, favs);
});
}
router.post('/', (req, res) => {
if (!req.body.name || !req.body.dataURL) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Bad create form parameters');
return;
}
const data = {
name: req.body.name,
dataURL: req.body.dataURL,
bookmarked: req.body.bookmarked
}
const favourite = new Favorite(data);
if (req.body._id) {
favourite._id = req.body._id;
} else {
favourite._id = mongoose.Types.ObjectId();
}
favourite.save((err, fav) => {
if (err) {
return error(err, res);
}
res.status = 201;
renderFav(req, res, fav, false);
});
});
router.get('/', (req, res) => {
findAndRender({}, req, res);
});
router.get('/search', (req, res) => {
const filter = Object.assign({}, req.query);
delete filter['dataURL'];
delete filter['_method'];
findAndRender(filter, req, res);
});
function findOne(id) {
return (req, res) => {
Favorite.findById(id(req), (err, fav) => {
if (err) {
return error(err, res);
}
if (notFound(fav, res)) {
return;
}
renderFav(req, res, fav, false);
});
};
}
router.get('/:id', findOne(req => parseId(req)));
function handleUpdate(partial = false) {
return (req, res) => {
const edit = {};
for (const key of ['dataURL', 'name']) {
if (req.body[key]) {
edit[key] = req.body[key];
} else if (!partial) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Bad PUT form parameters');
return;
}
}
if (req.body.bookmarked !== undefined) {
edit.bookmarked = req.body.bookmarked;
}
Favorite.findByIdAndUpdate(parseId(req), { $set: edit }, {
new: false,
upsert: true,
setDefaultsOnInsert: true,
passRawResult: true,
}, (err, fav) => {
if (err) {
return error(err, res);
}
if (fav == null) {
res.status = 201;
findOne(() => parseId(req))(req, res);
return;
}
res.status = 200;
renderFav(req, res, fav, false);
});
};
}
router.put('/:id', handleUpdate());
router.patch('/:id', handleUpdate(true));
router.delete('/:id', (req, res) => {
Favorite.findByIdAndDelete(parseId(req), (err, fav) => {
if (err) {
return error(err, res);
}
if (notFound(fav, res)) {
return;
}
res.format({
json: () => res.writeHead(204),
html: () => res.writeHead(302, { 'Location': '/favorites' })
});
res.end();
});
});
router.put('/:id/bookmarked', (req, res) => {
Favorite.findByIdAndUpdate(parseId(req), {
$set: { bookmarked: req.body.bookmarked }
}, { new: true }, (err, fav) => {
if (notFound(fav, res)) {
return;
}
if (!req.body.bookmarked) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Bad PUT bookmark form parameters');
} else {
renderFav(req, res, fav, false);
}
});
});
/** router for /root */
module.exports = router;

View file

@ -8,9 +8,22 @@ const router = express.Router();
const mongoose = require('mongoose');
const Favorite = mongoose.model('Favorite');
const eventBus = require('../../pubsub');
const { error, catchErrs, renderFav, parseId, notFound } = require('../utils');
function socketEmit(req, name, fav) {
const obj = {
_id: fav._id,
name: fav.name,
dataURL: fav.dataURL,
bookmarked: fav.bookmarked,
socketid: req.query.socketid
};
eventBus.emit(name, obj);
}
async function findAndRender(filter, req, res) {
try {
if (filter.name) {
@ -46,6 +59,9 @@ router.post('/', async (req, res) => {
try {
const fav = await favourite.save();
res.status = 201;
socketEmit(req, 'favorite.created', fav);
renderFav(req, res, fav, false);
} catch(e) {
error(e, res);
@ -65,7 +81,7 @@ router.get('/search', async (req, res) => {
await findAndRender(filter, req, res);
});
function findOne(id) {
function findOne(id, created = false) {
return async (req, res) => {
try {
const fav = await Favorite.findById(id(req));
@ -74,6 +90,10 @@ function findOne(id) {
return;
}
if (created) {
socketEmit(req, 'favorite.created', fav);
}
renderFav(req, res, fav, false);
} catch(e) {
error(e, res);
@ -109,12 +129,15 @@ function handleUpdate(partial = false) {
if (fav == null) {
res.status = 201;
await findOne(() => parseId(req))(req, res);
await findOne(() => parseId(req), true)(req, res);
return;
}
res.status = 200;
Object.assign(fav, edit);
socketEmit(req, 'favorite.updated', fav);
renderFav(req, res, fav, false);
} catch (e) {
error(e, res);
@ -134,6 +157,8 @@ router.delete('/:id', async (req, res) => {
return;
}
socketEmit(req, 'favorite.deleted', { _id: fav.id });
res.format({
json: () => res.writeHead(204),
html: () => res.writeHead(302, { 'Location': '/favorites' })
@ -157,6 +182,8 @@ router.put('/:id/bookmarked', async (req, res) => {
req.body.bookmarked === "true";
fav.save();
socketEmit(req, 'favorite.created', fav);
renderFav(req, res, fav, false);
} catch (e) {
notFound(null, res);

View file

@ -1,142 +0,0 @@
/** @module root/router */
'use strict';
// vim: set ts=2 sw=2 et tw=80:
const fs = require('fs');
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Favorite = mongoose.model('Favorite');
const { error, catchErrs, renderFav, parseId, notFound } = require('../utils');
function findAndRender(filter, req, res) {
catchErrs(Favorite.find(filter), res).then(favs => {
renderFav(req, res, favs);
});
}
router.post('/', (req, res) => {
if (!req.body.name || !req.body.dataURL) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Bad create form parameters');
return;
}
const data = {
name: req.body.name,
dataURL: req.body.dataURL,
bookmarked: req.body.bookmarked,
};
const favourite = new Favorite(data);
if (req.body._id) {
favourite._id = req.body._id;
} else {
favourite._id = mongoose.Types.ObjectId();
}
catchErrs(favourite.save(), res).then(fav => {
res.status = 201;
renderFav(req, res, fav, false);
});
});
router.get('/', (req, res) => {
findAndRender({}, req, res);
});
router.get('/search', (req, res) => {
const filter = Object.assign({}, req.query);
delete filter['dataURL'];
delete filter['_method'];
findAndRender(filter, req, res);
});
function findOne(id) {
return (req, res) => {
catchErrs(Favorite.findById(id(req)), res).then(fav => {
if (notFound(fav, res)) {
return;
}
renderFav(req, res, fav, false);
});
};
}
router.get('/:id', findOne(req => parseId(req)));
function handleUpdate(partial = false) {
return (req, res) => {
const edit = {};
for (const key of ['dataURL', 'name']) {
if (req.body[key]) {
edit[key] = req.body[key];
} else if (!partial) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Bad PUT form parameters');
return;
}
}
if (req.body.bookmarked !== undefined) {
edit.bookmarked = req.body.bookmarked;
}
catchErrs(Favorite.findByIdAndUpdate(parseId(req), { $set: edit }, {
new: false,
upsert: true,
setDefaultsOnInsert: true,
}), res).then(fav => {
if (fav == null) {
res.status = 201;
findOne(() => parseId(req))(req, res);
return;
}
res.status = 200;
renderFav(req, res, fav, false);
});
};
}
router.put('/:id', handleUpdate());
router.patch('/:id', handleUpdate(true));
router.delete('/:id', (req, res) => {
catchErrs(Favorite.findByIdAndDelete(parseId(req)), res).then(fav => {
if (notFound(fav, res)) {
return;
}
res.format({
json: () => res.writeHead(204),
html: () => res.writeHead(302, { 'Location': '/favorites' })
});
res.end();
});
});
router.put('/:id/bookmarked', (req, res) => {
catchErrs(Favorite.findByIdAndUpdate(parseId(req), {
$set: { bookmarked: req.body.bookmarked }
}, { new: true }), res).then(fav => {
if (notFound(fav, res)) {
return;
}
if (!req.body.bookmarked) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Bad PUT bookmark form parameters');
} else {
renderFav(req, res, fav, false);
}
});
});
/** router for /root */
module.exports = router;

View file

@ -37,6 +37,7 @@
<script src="dustjs-linkedin/dust-full.min.js"></script>
<script src="js/views.js"></script>
<script src="js/fetch.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="scripts/brushes.js"></script>
<script src="scripts/undo.js"></script>
<!-- <script src="scripts/clock.js"></script> -->

View file

@ -7,7 +7,7 @@ abbrev@1:
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
accepts@~1.3.7:
accepts@~1.3.4, accepts@~1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
@ -15,6 +15,11 @@ accepts@~1.3.7:
mime-types "~2.1.24"
negotiator "0.6.2"
after@0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=
ajv@^6.5.5:
version "6.10.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52"
@ -93,6 +98,11 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
arraybuffer.slice@~0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
@ -115,6 +125,11 @@ async-each@^1.0.0:
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
async-limiter@^1.0.0, async-limiter@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@ -135,11 +150,26 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
backo2@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
integrity sha1-MasayLEpNjRj41s+u2n038+6eUc=
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
base64-arraybuffer@0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg=
base64id@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6"
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
base@^0.11.1:
version "0.11.2"
resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
@ -167,11 +197,23 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
better-assert@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522"
integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=
dependencies:
callsite "1.0.0"
binary-extensions@^1.0.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==
blob@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683"
integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==
bluebird@3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
@ -256,6 +298,11 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
callsite@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
@ -325,11 +372,26 @@ commander@2.11.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==
component-bind@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1"
integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=
component-emitter@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=
component-emitter@^1.2.0, component-emitter@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
component-inherit@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143"
integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@ -357,6 +419,11 @@ cookie-signature@1.0.6:
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
cookie@0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
cookie@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
@ -391,7 +458,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
dependencies:
ms "2.0.0"
debug@3.1.0:
debug@3.1.0, debug@~3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
@ -405,6 +472,13 @@ debug@^3.1.0, debug@^3.2.6:
dependencies:
ms "^2.1.1"
debug@~4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"
decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
@ -493,6 +567,46 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
engine.io-client@~3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.0.tgz#82a642b42862a9b3f7a188f41776b2deab643700"
integrity sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA==
dependencies:
component-emitter "1.2.1"
component-inherit "0.0.3"
debug "~4.1.0"
engine.io-parser "~2.2.0"
has-cors "1.1.0"
indexof "0.0.1"
parseqs "0.0.5"
parseuri "0.0.5"
ws "~6.1.0"
xmlhttprequest-ssl "~1.5.4"
yeast "0.1.2"
engine.io-parser@~2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed"
integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==
dependencies:
after "0.8.2"
arraybuffer.slice "~0.0.7"
base64-arraybuffer "0.1.5"
blob "0.0.5"
has-binary2 "~1.0.2"
engine.io@~3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.4.0.tgz#3a962cc4535928c252759a00f98519cb46c53ff3"
integrity sha512-XCyYVWzcHnK5cMz7G4VTu2W7zJS7SM1QkcelghyIk/FmobWBtXE7fwhBusEKvCSqc3bMh8fNFMlUkCKTFRxH2w==
dependencies:
accepts "~1.3.4"
base64id "2.0.0"
cookie "0.3.1"
debug "~4.1.0"
engine.io-parser "~2.2.0"
ws "^7.1.2"
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@ -841,6 +955,18 @@ har-validator@~5.1.0:
ajv "^6.5.5"
har-schema "^2.0.0"
has-binary2@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d"
integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==
dependencies:
isarray "2.0.1"
has-cors@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39"
integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=
has-flag@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
@ -932,6 +1058,11 @@ ignore-walk@^3.0.1:
dependencies:
minimatch "^3.0.4"
indexof@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@ -1117,6 +1248,11 @@ isarray@1.0.0, isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
isarray@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e"
integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=
isobject@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
@ -1543,6 +1679,11 @@ object-assign@^4.1.0:
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
object-component@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291"
integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=
object-copy@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
@ -1621,6 +1762,20 @@ parse-glob@^3.0.4:
is-extglob "^1.0.0"
is-glob "^2.0.0"
parseqs@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d"
integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=
dependencies:
better-assert "~1.0.0"
parseuri@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a"
integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=
dependencies:
better-assert "~1.0.0"
parseurl@~1.3.2, parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@ -2023,6 +2178,61 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
socket.io-adapter@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b"
integrity sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=
socket.io-client@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4"
integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==
dependencies:
backo2 "1.0.2"
base64-arraybuffer "0.1.5"
component-bind "1.0.0"
component-emitter "1.2.1"
debug "~4.1.0"
engine.io-client "~3.4.0"
has-binary2 "~1.0.2"
has-cors "1.1.0"
indexof "0.0.1"
object-component "0.0.3"
parseqs "0.0.5"
parseuri "0.0.5"
socket.io-parser "~3.3.0"
to-array "0.1.4"
socket.io-parser@~3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f"
integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==
dependencies:
component-emitter "1.2.1"
debug "~3.1.0"
isarray "2.0.1"
socket.io-parser@~3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.4.0.tgz#370bb4a151df2f77ce3345ff55a7072cc6e9565a"
integrity sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ==
dependencies:
component-emitter "1.2.1"
debug "~4.1.0"
isarray "2.0.1"
socket.io@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.3.0.tgz#cd762ed6a4faeca59bc1f3e243c0969311eb73fb"
integrity sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==
dependencies:
debug "~4.1.0"
engine.io "~3.4.0"
has-binary2 "~1.0.2"
socket.io-adapter "~1.1.0"
socket.io-client "2.3.0"
socket.io-parser "~3.4.0"
source-map-resolve@^0.5.0:
version "0.5.2"
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259"
@ -2173,6 +2383,11 @@ tar@^4:
safe-buffer "^5.1.2"
yallist "^3.0.3"
to-array@0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"
integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA=
to-object-path@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
@ -2312,7 +2527,31 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
ws@^7.1.2:
version "7.2.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.0.tgz#422eda8c02a4b5dba7744ba66eebbd84bcef0ec7"
integrity sha512-+SqNqFbwTm/0DC18KYzIsMTnEWpLwJsiasW/O17la4iDRRIO9uaHbvKiAS3AHgTiuuWerK/brj4O6MYZkei9xg==
dependencies:
async-limiter "^1.0.0"
ws@~6.1.0:
version "6.1.4"
resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9"
integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==
dependencies:
async-limiter "~1.0.0"
xmlhttprequest-ssl@~1.5.4:
version "1.5.5"
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=
yallist@^3.0.0, yallist@^3.0.3:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
yeast@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk=