This commit is contained in:
Dooho Yi 2023-06-27 23:37:11 +09:00
commit 643a795f05
19 changed files with 2620 additions and 0 deletions

61
.gitignore vendored Normal file
View file

@ -0,0 +1,61 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# next.js build output
.next

24
LICENSE Normal file
View file

@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org>

13
README.md Normal file
View file

@ -0,0 +1,13 @@
# rover
## concept
- a node express web server which serves a public webpage with a maze
- this simple webpage will be accesible for smartphones and computers
- interactions will generate websocket messages which will travel to one computer that is running puredata
## notes
- this server supports https protocol and automatic redirection of http to https
- to make connections go global and unlimited by any physical spaces, run app.js @ e.g. amazon aws ec2 server, and then connect to it as a client: run receiver.js @ localhost
- for smartphones, LTE connection is recommended. 'cause one wifi router can handle limited clients at the same time. if the router is crowded, connections may delay or drop. connections by LTE is relatively stable and trustful.

43
app.js Normal file
View file

@ -0,0 +1,43 @@
//built-in
const path = require("path");
// const fs = require('fs').promises;
//fastify
const fastify = require("fastify")({
logger: false,
});
fastify.register(require("fastify-static"), {
root: path.join(__dirname, "public"),
prefix: "/"
});
//socket.io
var io = require("socket.io")(fastify.server, {
pingInterval: 1000,
pingTimeout: 3000
});
//socket.io events
io.on("connection", function(socket) {
//connection notify
console.log("someone connected.");
socket.on("disconnect", function() { console.log("someone disconnected."); });
//on 'rover'
socket.on('rover', function(rover) {
socket.broadcast.emit('rover', rover);
})
});
//listen
var port = process.env.PORT || 8080;
fastify.listen(port, function (err, address) {
if (err) {
fastify.log.error(err)
process.exit(1)
}
console.log(`Your app is listening on ${address}`)
fastify.log.info(`server listening on ${address}`)
});

965
package-lock.json generated Normal file
View file

@ -0,0 +1,965 @@
{
"name": "rover",
"version": "1.0.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@fastify/ajv-compiler": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-1.1.0.tgz",
"integrity": "sha512-gvCOUNpXsWrIQ3A4aXCLIdblL0tDq42BG/2Xw7oxbil9h11uow10ztS2GuFazNBfjbrsZ5nl+nPl5jDSjj5TSg==",
"requires": {
"ajv": "^6.12.6"
}
},
"@fastify/error": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@fastify/error/-/error-2.0.0.tgz",
"integrity": "sha512-wI3fpfDT0t7p8E6dA2eTECzzOd+bZsZCJ2Hcv+Onn2b7ZwK3RwD27uW2QDaMtQhAfWQQP+WNK7nKf0twLsBf9w=="
},
"@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
},
"@types/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
},
"@types/cors": {
"version": "2.8.13",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
"integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
"requires": {
"@types/node": "*"
}
},
"@types/node": {
"version": "18.11.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
"integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ=="
},
"abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"dev": true
},
"abstract-logging": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz",
"integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA=="
},
"accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
"requires": {
"mime-types": "~2.1.34",
"negotiator": "0.6.3"
}
},
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
}
},
"archy": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
"integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw=="
},
"atomic-sleep": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
"integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="
},
"avvio": {
"version": "7.2.5",
"resolved": "https://registry.npmjs.org/avvio/-/avvio-7.2.5.tgz",
"integrity": "sha512-AOhBxyLVdpOad3TujtC9kL/9r3HnTkxwQ5ggOsYrvvZP1cCFvzHWJd5XxZDFuTn+IN8vkKSG5SEJrd27vCSbeA==",
"requires": {
"archy": "^1.0.0",
"debug": "^4.0.0",
"fastq": "^1.6.1",
"queue-microtask": "^1.1.2"
}
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"base64id": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"requires": {
"fill-range": "^7.0.1"
}
},
"chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"dev": true,
"requires": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"fsevents": "~2.3.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"cookie": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
},
"cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"requires": {
"object-assign": "^4",
"vary": "^1"
}
},
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"deepmerge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ=="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg=="
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
},
"engine.io": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz",
"integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==",
"requires": {
"@types/cookie": "^0.4.1",
"@types/cors": "^2.8.12",
"@types/node": ">=10.0.0",
"accepts": "~1.3.4",
"base64id": "2.0.0",
"cookie": "~0.4.1",
"cors": "~2.8.5",
"debug": "~4.3.1",
"engine.io-parser": "~5.0.3",
"ws": "~8.2.3"
},
"dependencies": {
"cookie": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA=="
}
}
},
"engine.io-parser": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz",
"integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg=="
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
},
"fast-decode-uri-component": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz",
"integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
"fast-json-stringify": {
"version": "2.7.13",
"resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-2.7.13.tgz",
"integrity": "sha512-ar+hQ4+OIurUGjSJD1anvYSDcUflywhKjfxnsW4TBTD7+u0tJufv6DKRWoQk3vI6YBOWMoz0TQtfbe7dxbQmvA==",
"requires": {
"ajv": "^6.11.0",
"deepmerge": "^4.2.2",
"rfdc": "^1.2.0",
"string-similarity": "^4.0.1"
}
},
"fast-redact": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz",
"integrity": "sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw=="
},
"fast-safe-stringify": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
},
"fastify": {
"version": "3.29.4",
"resolved": "https://registry.npmjs.org/fastify/-/fastify-3.29.4.tgz",
"integrity": "sha512-BEyKidZQvscNaiF1BLh+YLE7AzHH03NexhPzrwZP6KBQ+jG2czdgq72X+RFB5rK9hbqdaafVb5yiWN+hCvHfYg==",
"requires": {
"@fastify/ajv-compiler": "^1.0.0",
"@fastify/error": "^2.0.0",
"abstract-logging": "^2.0.0",
"avvio": "^7.1.2",
"content-type": "^1.0.4",
"fast-json-stringify": "^2.5.2",
"find-my-way": "^4.5.0",
"flatstr": "^1.0.12",
"light-my-request": "^4.2.0",
"pino": "^6.13.0",
"process-warning": "^1.0.0",
"proxy-addr": "^2.0.7",
"rfdc": "^1.1.4",
"secure-json-parse": "^2.0.0",
"semver": "^7.3.2",
"tiny-lru": "^8.0.1"
}
},
"fastify-plugin": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-3.0.1.tgz",
"integrity": "sha512-qKcDXmuZadJqdTm6vlCqioEbyewF60b/0LOFCcYN1B6BIZGlYJumWWOYs70SFYLDAH4YqdE1cxH/RKMG7rFxgA=="
},
"fastify-static": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/fastify-static/-/fastify-static-3.4.0.tgz",
"integrity": "sha512-5y9xTNiPTj6/jDwzH6CqBIcI3/yZtocUiHoLud2NYPfHSOLlS6eW6DTheiU8b9WWlfmHfqOjwFFBdhiH1+nBhg==",
"requires": {
"fastify-plugin": "^3.0.0",
"glob": "^7.1.4",
"readable-stream": "^3.4.0",
"send": "^0.17.1"
}
},
"fastq": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz",
"integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==",
"requires": {
"reusify": "^1.0.4"
}
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"find-my-way": {
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-4.5.1.tgz",
"integrity": "sha512-kE0u7sGoUFbMXcOG/xpkmz4sRLCklERnBcg7Ftuu1iAxsfEt2S46RLJ3Sq7vshsEy2wJT2hZxE58XZK27qa8kg==",
"requires": {
"fast-decode-uri-component": "^1.0.1",
"fast-deep-equal": "^3.1.3",
"safe-regex2": "^2.0.0",
"semver-store": "^0.3.0"
}
},
"flatstr": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/flatstr/-/flatstr-1.0.12.tgz",
"integrity": "sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw=="
},
"forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"optional": true
},
"glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"requires": {
"is-glob": "^4.0.1"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true
},
"http-errors": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
"integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.1"
}
},
"ignore-by-default": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
},
"is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"requires": {
"binary-extensions": "^2.0.0"
}
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true
},
"is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"requires": {
"is-extglob": "^2.1.1"
}
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
"light-my-request": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-4.12.0.tgz",
"integrity": "sha512-0y+9VIfJEsPVzK5ArSIJ8Dkxp8QMP7/aCuxCUtG/tr9a2NoOf/snATE/OUc05XUplJCEnRh6gTkH7xh9POt1DQ==",
"requires": {
"ajv": "^8.1.0",
"cookie": "^0.5.0",
"process-warning": "^1.0.0",
"set-cookie-parser": "^2.4.1"
},
"dependencies": {
"ajv": {
"version": "8.11.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz",
"integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==",
"requires": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
}
},
"json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
}
}
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"requires": {
"yallist": "^4.0.0"
}
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
},
"mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"requires": {
"mime-db": "1.52.0"
}
},
"minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
},
"nodemon": {
"version": "2.0.20",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz",
"integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==",
"dev": true,
"requires": {
"chokidar": "^3.5.2",
"debug": "^3.2.7",
"ignore-by-default": "^1.0.1",
"minimatch": "^3.1.2",
"pstree.remy": "^1.1.8",
"semver": "^5.7.1",
"simple-update-notifier": "^1.0.7",
"supports-color": "^5.5.0",
"touch": "^3.1.0",
"undefsafe": "^2.0.5"
},
"dependencies": {
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
}
}
},
"nopt": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
"integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
"dev": true,
"requires": {
"abbrev": "1"
}
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
"requires": {
"ee-first": "1.1.1"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"requires": {
"wrappy": "1"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
},
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true
},
"pino": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/pino/-/pino-6.14.0.tgz",
"integrity": "sha512-iuhEDel3Z3hF9Jfe44DPXR8l07bhjuFY3GMHIXbjnY9XcafbyDDwl2sN2vw2GjMPf5Nkoe+OFao7ffn9SXaKDg==",
"requires": {
"fast-redact": "^3.0.0",
"fast-safe-stringify": "^2.0.8",
"flatstr": "^1.0.12",
"pino-std-serializers": "^3.1.0",
"process-warning": "^1.0.0",
"quick-format-unescaped": "^4.0.3",
"sonic-boom": "^1.0.2"
}
},
"pino-std-serializers": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz",
"integrity": "sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg=="
},
"process-warning": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz",
"integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q=="
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"requires": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
}
},
"pstree.remy": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
"integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
"dev": true
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
},
"quick-format-unescaped": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
"integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"requires": {
"picomatch": "^2.2.1"
}
},
"require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
},
"ret": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz",
"integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ=="
},
"reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
},
"rfdc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"safe-regex2": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz",
"integrity": "sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==",
"requires": {
"ret": "~0.2.0"
}
},
"secure-json-parse": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.6.0.tgz",
"integrity": "sha512-B9osKohb6L+EZ6Kve3wHKfsAClzOC/iISA2vSuCe5Jx5NAKiwitfxx8ZKYapHXr0sYRj7UZInT7pLb3rp2Yx6A=="
},
"semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"requires": {
"lru-cache": "^6.0.0"
}
},
"semver-store": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/semver-store/-/semver-store-0.3.0.tgz",
"integrity": "sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg=="
},
"send": {
"version": "0.17.2",
"resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
"integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==",
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "1.8.1",
"mime": "1.6.0",
"ms": "2.1.3",
"on-finished": "~2.3.0",
"range-parser": "~1.2.1",
"statuses": "~1.5.0"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
},
"dependencies": {
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
}
}
},
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
}
}
},
"set-cookie-parser": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.5.1.tgz",
"integrity": "sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ=="
},
"setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"simple-update-notifier": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
"integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==",
"dev": true,
"requires": {
"semver": "~7.0.0"
},
"dependencies": {
"semver": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
"dev": true
}
}
},
"socket.io": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz",
"integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==",
"requires": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"debug": "~4.3.2",
"engine.io": "~6.2.1",
"socket.io-adapter": "~2.4.0",
"socket.io-parser": "~4.2.1"
}
},
"socket.io-adapter": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz",
"integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg=="
},
"socket.io-parser": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz",
"integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==",
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
}
},
"sonic-boom": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz",
"integrity": "sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==",
"requires": {
"atomic-sleep": "^1.0.0",
"flatstr": "^1.0.12"
}
},
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="
},
"string-similarity": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.4.tgz",
"integrity": "sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ=="
},
"string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"requires": {
"safe-buffer": "~5.2.0"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
},
"tiny-lru": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-8.0.2.tgz",
"integrity": "sha512-ApGvZ6vVvTNdsmt676grvCkUCGwzG9IqXma5Z07xJgiC5L7akUMof5U8G2JTI9Rz/ovtVhJBlY6mNhEvtjzOIg=="
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": {
"is-number": "^7.0.0"
}
},
"toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
},
"touch": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
"integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
"dev": true,
"requires": {
"nopt": "~1.0.10"
}
},
"undefsafe": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
"dev": true
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"requires": {
"punycode": "^2.1.0"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"ws": {
"version": "8.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA=="
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
}

28
package.json Normal file
View file

@ -0,0 +1,28 @@
{
"name": "rover",
"version": "1.0.1",
"description": "",
"main": "app.js",
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js"
},
"dependencies": {
"fastify": "3.29.4",
"fastify-static": "3.4.0",
"socket.io": "4.5.4"
},
"engines": {
"node": "12.x"
},
"repository": {
"url": "https://glitch.com/edit/#!/glitch-hello-node"
},
"license": "MIT",
"devDependencies": {
"nodemon": "^2.0.15"
},
"volta": {
"node": "12.22.12"
}
}

90
pd/rover.pd Normal file
View file

@ -0,0 +1,90 @@
#N struct 1005-point float x0 float y0 float xs float ys float fg float in float gridx float gridy;
#N struct 1451-point float x0 float y0 float xs float ys float fg float in float gridx float gridy;
#N canvas 286 118 989 427 10;
#X obj 20 15 udpreceive 57000;
#X floatatom 20 119 5 0 0 3 x - - 0;
#X floatatom 54 119 5 0 0 3 y - - 0;
#X obj 20 36 unpackOSC;
#X obj 20 57 routeOSC /rover;
#X floatatom 89 119 5 0 0 3 z - - 0;
#X obj 20 78 unpack f f f f f f f;
#X floatatom 136 129 5 0 0 3 pan - - 0;
#X floatatom 170 129 5 0 0 3 tilt - - 0;
#X floatatom 205 129 5 0 0 3 rot - - 0;
#X obj 185 55 tgl 18 0 empty empty grounded? 0 -9 0 10 #fcfcfc #000000 #000000 0 1;
#X obj 355 101 slider2d 300 300 0 127 0 127 1 255 255 255 0 0 0 0 0 0 5 5 empty empty;
#X obj 20 198 pack;
#X obj 20 221 list prepend set;
#X obj 20 245 list trim;
#N canvas 495 298 450 300 archive 0;
#X obj 27 216 tgl 15 0 empty empty connected? 17 7 0 10 #fcfcfc #000000 #000000 0 1;
#X msg 137 204 disconnect;
#X msg 38 168 connect localhost 57001;
#X obj 27 195 udpsend;
#X obj 27 126 packOSC;
#X msg 27 105 /hue \$1;
#X obj 30 69 hsl 128 15 0 255 0 0 empty empty hue -2 -8 0 10 #fcfcfc #000000 #000000 0 1;
#X text 82 29 send back some msg. to web;
#X connect 1 0 3 0;
#X connect 2 0 3 0;
#X connect 3 0 0 0;
#X connect 4 0 3 0;
#X connect 5 0 4 0;
#X connect 6 0 5 0;
#X restore 900 10 pd archive;
#X msg 534 50 size 300;
#X obj 664 101 slider2d 300 300 -3.15 3.15 -3.15 3.15 1 255 255 255 0 0 0 0 0 0 -0.168 -0.278 empty empty;
#X obj 136 316 pack;
#X obj 136 339 list prepend set;
#X obj 136 363 list trim;
#X obj 20 268 s position;
#X obj 136 386 s head;
#X obj 355 67 r position;
#X obj 534 27 loadbang;
#X obj 664 62 r head;
#X floatatom 136 291 5 0 0 0 - - - 0;
#X floatatom 170 218 5 0 0 0 - - - 0;
#X obj 13 343 loadbang;
#X obj 13 366 pi 2;
#X obj 13 388 v PI2;
#X obj 68 366 pi 1;
#X obj 68 388 v PI;
#X msg 743 49 range -3.15 3.15;
#X listbox 661 18 20 0 0 0 - - - 0;
#X obj 136 242 expr if($f1 >= 0 \, fmod($f1+PI \, PI2)-PI \, fmod($f1-PI \, PI2)+PI), f 21;
#X obj 170 169 expr if($f1 >= 0 \, fmod($f1+PI \, PI2)-PI \, fmod($f1-PI \, PI2)+PI), f 21;
#X connect 0 0 3 0;
#X connect 1 0 12 0;
#X connect 3 0 4 0;
#X connect 4 0 6 0;
#X connect 5 0 12 1;
#X connect 6 0 1 0;
#X connect 6 1 2 0;
#X connect 6 2 5 0;
#X connect 6 3 7 0;
#X connect 6 4 8 0;
#X connect 6 5 9 0;
#X connect 6 6 10 0;
#X connect 7 0 35 0;
#X connect 8 0 36 0;
#X connect 12 0 13 0;
#X connect 13 0 14 0;
#X connect 14 0 21 0;
#X connect 16 0 11 0;
#X connect 16 0 17 0;
#X connect 18 0 19 0;
#X connect 19 0 20 0;
#X connect 20 0 22 0;
#X connect 23 0 11 0;
#X connect 24 0 16 0;
#X connect 25 0 17 0;
#X connect 25 0 34 0;
#X connect 26 0 18 0;
#X connect 27 0 18 1;
#X connect 28 0 29 0;
#X connect 28 0 31 0;
#X connect 29 0 30 0;
#X connect 31 0 32 0;
#X connect 33 0 17 0;
#X connect 35 0 26 0;
#X connect 36 0 27 0;

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

21
public/index.html Normal file
View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<!-- libraries -->
<link type="text/css" rel="stylesheet" href="./lib/tachyons-4.9.1.min.css" />
<script type="text/javascript" src="./lib/p5-v1.5.0.min.js"></script>
<script type="text/javascript" src="./lib/socket.io-v4.5.4.min.js"></script>
<script type="text/javascript" src="./lib/util.js"></script>
<style>
</style>
</head>
<body>
<script src="p5.RoverCam.js"></script>
<script src="sketch.js"></script>
</body>
</html>

BIN
public/lib/inconsolata.otf Normal file

Binary file not shown.

2
public/lib/p5-v1.5.0.min.js vendored Normal file

File diff suppressed because one or more lines are too long

7
public/lib/socket.io-v4.5.4.min.js vendored Executable file

File diff suppressed because one or more lines are too long

3
public/lib/tachyons-4.9.1.min.css vendored Normal file

File diff suppressed because one or more lines are too long

300
public/lib/util.js Normal file
View file

@ -0,0 +1,300 @@
// re-map values from 'from' to 'to'
//
// usage form #1 : map(val, from, to, loop)
// 'from', 'to' should be array with 2 numbers. like: [0, 1], [-10, 30], [0.5, 52.4] ...
// 'loop' could be 'true' to extrapolate beyond from[1] and to[1]
//
// examples
//
// map(val, [30, 40], [2, 3]); // assuming 'val' is in the range [30, 40], what is propotionally matching number in the range [2, 3];
//
// map(32, [30, 40], [2, 3]) -> 2.2
// map(32, [30, 40], [3, 2]) -> 2.8 // flip
// map(29, [30, 40], [2, 3]) -> 2 // below mininum input range will forced to minimum output value
// map(43, [30, 40], [2, 3]) -> 3 // below maximun input range will forced to maximun output value
// map(43, [30, 40], [2, 3], true) -> 2.3 // allowing 'looping'
// map(33, [30, 40], [2, 3], true) -> 2.3 // looping portion (43-40 -> 3) will be reapplied (30 + 3) will result same as above line
// map(13, [30, 40], [2, 3], true) -> 2 // looping only allow 'beyond maximum'.. not 'under minimum'
//
// usage form #2 : map(val, object)
// 'object' should contain following items
// object.from
// object.to
// object.loop
// same as above but use instead 'object' form
//
// examples
//
// map(33, {
// from: [30, 40],
// to: [2, 3],
// loop: true
// });
function map(val, from, to, loop) {
if (typeof from === 'object') {
if (Array.isArray(from)) { // direct form (array)
from = from || [0, 1];
to = to || [0, 1];
if (val < from[0]) return to[0];
if (loop === true) { // 'looping'
return (val - from[0]) % (from[1] - from[0]) * (to[1] - to[0]) / (from[1] - from[0]) + to[0];
} else {
if (val > from[1]) return to[1];
return (val - from[0]) * (to[1] - to[0]) / (from[1] - from[0]) + to[0];
}
} else { // object form
var object = from;
object.from = object.from || [0, 1];
object.to = object.to || [0, 1];
if (val < object.from[0]) return object.to[0];
if (object.loop === true) { // 'looping'
return (val - object.from[0]) % (object.from[1] - object.from[0]) * (object.to[1] - object.to[0]) / (object.from[1] - object.from[0]) + object.to[0];
} else {
if (val > object.from[1]) return object.to[1];
return (val - object.from[0]) * (object.to[1] - object.to[0]) / (object.from[1] - object.from[0]) + object.to[0];
}
}
}
}
// re-map values from [0, 1] to 'to'
// refer to 'map' description to understand 'loop'
// ex) known values lies in [0, 1] -> [2, 3] : map2(val, [2, 3]);
function map2(val, to, loop) {
if (typeof to === 'object') {
if (Array.isArray(to)) { // direct form (array)
return map(val, [0, 1], to, loop);
} else { // object form
return map(val, [0, 1], to.to, to.loop);
}
}
}
// get a random real number in range of [min, max)
function getRandom(min, max) {
return map2(Math.random(), [min, max]);
}
// get a random integer value in set of {min, ... , max}
function getRandomInt(min, max) {
return Math.floor(getRandom(min, max + 1));
}
//use in onFrame(event) to get loopping 'timeline' for animation build-up
// ex) getTimeline(event.time, [0, 30]) will return a changing number from 0 to 1, for 30 seconds.
// time: could be event.time or event.count
// event.time.. will be more time-wise precise
// event.count.. will be more frame-wise precise
// ex) getTimeline(event.count, [0, 30]) will return a changing number from 0 to 1, for 30 frames (roughly 0.5 sec. in 60 fps animation).
//
// examples
//
// getTimeline(event.time, [0, 30]) // from 0 sec. to 30 sec., change value from 0 to 1
// getTimeline(event.time, [0, 30], [3, 2]) // from 0 sec. to 30 sec., change value from 3 to 2
// getTimeline(event.time, [0, 30], [3, 2], true) // from 0 sec. to 30 sec., change value from 3 to 2, and repeat forever.
// getTimeline(event.time, [3, 10]) // from 0 sec. to 3 sec. stay at 0, from 3 sec. to 10 sec., change value from 0 to 1
// getTimeline(event.time, { // object form
// from: [3, 10],
// to: [4, 15],
// loop: true
// });
function getTimeline(time, from, to, loop) {
return map(time, from, to, loop);
}
//use in onFrame(event) to get loopping 'timeline' for animation build-up
// ex) getTimepoint(event.time, [0, 10], path) will return a moving point along with 'path' for 10 seconds
// and use is as a point, like
// ex) a.position = getTimepoint(event.time, [0, 10], path);
// or get y-coord and use it as a number, like
// ex) a.fillColor.hue = getTimepoint(event.time, [0, 10], path).y;
// if expected range of y values are.. [0, 100], then..
// a.fillColor.hue = map(getTimepoint(event.time, [0, 10], path).y, [0, 100], [0, 360]);
// to fit whole range of hue circle.
function getTimepoint(time, path, from, to, loop) {
return path.getPointAt(getTimeline(time, from, to, loop) * path.length % path.length);
}
// //detect 'visibilitychange' in modern browsers (e.g. changing tab)
// // ref) https://stackoverflow.com/a/19519701 ("Detect if browser tab is active or user has switched away")
// // ex)
// // __visibility(function() {
// // document.title = __visibility() ? 'Visible' : 'Not visible';
// // });
// var __visibility = (function() {
// //investigate property list in the browser
// var stateKey, eventKey, keys = {
// hidden: "visibilitychange",
// webkitHidden: "webkitvisibilitychange",
// mozHidden: "mozvisibilitychange",
// msHidden: "msvisibilitychange"
// };
// //confirm what eventkey to be used
// for (stateKey in keys) {
// if (stateKey in document) {
// eventKey = keys[stateKey];
// break;
// }
// }
// //build the function and then let it be used
// return function(c) {
// //this function will have 2 usecases
// // 1) simple call: __visibility() will return current visibility state
// // 2) call with callback: __visibility(function(){}) will assign a callback for the event
// //in this callback function use usecase #1 to get actual visibility.
// if (c) {
// document.addEventListener(eventKey, c);
// }
// return !document[stateKey];
// }
// })();
//
// //prepare a new master to be used
// var master = new Tone.AmplitudeEnvelope({
// attack: 1,
// decay: 0,
// sustain: 1,
// release: 1
// }).toMaster();
//
// function onVisibilityChange() {
// //document.title = __visibility() ? 'Visible' : 'Not visible';
// if (__visibility() == true) {
// master.triggerAttack();
// } else {
// master.triggerRelease();
// }
// }
// //register handler
// __visibility(onVisibilityChange);
// //initial state check
// onVisibilityChange();
//
// //a first touch getter! (only for iphone)
// function getTheFirstTouchiOS() {
// if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
// var _silence = new Tone.Player({
// url: 'lib/_silence.wav',
// onload: function() {
// new paper.Path.Rectangle({
// point: [0, 0],
// size: paper.view.size,
// fillColor: 'white',
// opacity: 0.8,
// onClick: function() {
// _silence.start();
// this.remove();
// }
// }).bringToFront();
// }
// }).toMaster();
// }
// }
// //SVG helpers
// function SVGSymbol(uri) {
// return new Promise(function(resolve, reject) {
// paper.project.importSVG(uri, {
// expandShapes: true,
// onLoad: function(svg) {
// resolve(new paper.Symbol(svg));
// }
// });
// });
// }
// function SVGImportSimple(uri) {
// return new Promise(function(resolve, reject) {
// paper.project.importSVG(uri, function(svg) {
// resolve(svg);
// });
// });
// }
// function SVGImport(uri) {
// return new Promise(function(resolve, reject) {
// paper.project.importSVG(uri, function(svg) {
// svg.parent.remove(svg);
// resolve(svg);
// });
// });
// }
// function SVGImport_size1(uri) {
// return new Promise(function(resolve, reject) {
// paper.project.importSVG(uri, function(svg) {
// svg.parent.remove(svg);
// svg.scale(1 / svg.bounds.size.width);
// resolve(svg);
// });
// });
// }
// function SVGNamedImport(uri, name) {
// return new Promise(function(resolve, reject) {
// paper.project.importSVG(uri, function(svg) {
// svg.remove();
// var item = svg.getItem({
// name: name
// });
// item.applyMatrix = true;
// resolve(item);
// });
// });
// }
// function SVGNamedSymbol(uri, name) {
// return new Promise(function(resolve, reject) {
// paper.project.importSVG(uri, function(svg) {
// resolve(new paper.Symbol(
// svg.getItem({
// name: name
// })
// ));
// });
// });
// }
// function RasterImport(uri) {
// return new Promise(function(resolve, reject) {
// var raster = new paper.Raster(uri);
// raster.onLoad = function() {
// raster.remove();
// raster.applyMatrix = true;
// resolve(raster);
// };
// });
// }
// function RasterImport_size1(uri) {
// return new Promise(function(resolve, reject) {
// var raster = new paper.Raster(uri);
// raster.onLoad = function() {
// raster.remove();
// raster.applyMatrix = true;
// raster.scale(1 / raster.size.width);
// resolve(raster);
// };
// });
// }
function AudioImport(url) {
return new Promise(function(resolve, reject) {
var audio = new Tone.Player(url, function() {
resolve(audio);
}).toMaster();
});
}
//
// a unique string generator
//
// references:
// https://gist.github.com/gordonbrander/2230317
// https://gist.github.com/6174/6062387
// https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
//
function uniqueID() {
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
}

187
public/p5.RoverCam.js Normal file
View file

@ -0,0 +1,187 @@
/*
*
* The p5.RoverCam library - First-Person 3D CameraControl for p5.js and WEBGL.
*
* Copyright © 2020 by p5.RoverCam authors
*
* Source: https://github.com/freshfork/p5.RoverCam
*
* MIT License: https://opensource.org/licenses/MIT
*
*
* explanatory note:
*
* p5.RoverCam is a derivative of the QueasyCam Library by Josh Castle,
* ported to JavaScript for p5.js from github.com/jrc03c/queasycam
*
* updates
* 20200628 incorporate pointerLock and overridable controller method
* 20200629 add support for switching between multiple cameras
* 20200701 v1.1.0 fix registerMethod and allow for p5js instance mode
*/
// First-person camera control
// Mouse:
// left/right : yaw
// up/down : pitch
// click : enter/leave pointerLock
// Keys: a/d : yaw or left/right if pointerLock
// w/s : forward/backward
// e/q : up/down
class RoverCam {
constructor(instance) {
this.sensitivity = 0.02;
this.friction = 0.8;
this.speed = 0.1;
this.reset();
this.active = true; // use the setActive method
this.enableControl = true; // used to enable/disable controls
if (instance !== undefined) this.p5 = instance;
else this.p5 = p5.instance;
if (this.p5 !== null)
this.p5.registerMethod('post', () => {
if (this.active) this.draw();
});
}
// Application can override the following method
controller() { // default behavior
if (!this.enableControl) return;
if (RoverCam.pointerLock) {
this.yaw(this.p5.movedX * this.sensitivity / 10); // mouse left/right
this.pitch(this.p5.movedY * this.sensitivity / 10); // mouse up/down
if (this.p5.keyIsDown(65) || this.p5.keyIsDown(this.p5.LEFT_ARROW)) this.moveY(this.speed); // a
if (this.p5.keyIsDown(68) || this.p5.keyIsDown(this.p5.RIGHT_ARROW)) this.moveY(-this.speed); // d
} else { // otherwise yaw/pitch with keys
if (this.p5.keyIsDown(65) || this.p5.keyIsDown(this.p5.LEFT_ARROW)) this.yaw(-this.sensitivity); // a
if (this.p5.keyIsDown(68) || this.p5.keyIsDown(this.p5.RIGHT_ARROW)) this.yaw(this.sensitivity); // d
if (this.p5.keyIsDown(82)) this.pitch(-this.sensitivity); // r
if (this.p5.keyIsDown(70)) this.pitch(this.sensitivity); // f
}
if (this.p5.keyIsDown(87) || this.p5.keyIsDown(this.p5.UP_ARROW)) this.moveX(this.speed); // w
if (this.p5.keyIsDown(83) || this.p5.keyIsDown(this.p5.DOWN_ARROW)) this.moveX(-this.speed); // s
if (this.p5.keyIsDown(69)) this.moveZ(this.speed); // e
if (this.p5.keyIsDown(81)) this.moveZ(-this.speed); // q
if (this.p5.keyIsDown(107) || this.p5.keyIsDown(187)) this.fov(-this.sensitivity / 10); // +
if (this.p5.keyIsDown(109) || this.p5.keyIsDown(189)) this.fov(this.sensitivity / 10); // -
// test roll TBD
//if(this.p5.keyIsDown(90)) this.roll(this.sensitivity); // z
//if(this.p5.keyIsDown(67)) this.roll(-this.sensitivity); // c
}
// Primitive internal camera control methods
moveX(speed) {
this.velocity.add(p5.Vector.mult(this.forward, speed));
}
moveY(speed) {
this.velocity.add(p5.Vector.mult(this.right, speed));
}
moveZ(speed) {
this.velocity.add(p5.Vector.mult(this.up, -speed));
}
yaw(angle) {
this.pan += angle;
}
pitch(angle) {
this.tilt += angle;
this.tilt = this.clamp(this.tilt, -Math.PI / 2.01, Math.PI / 2.01);
if (this.tilt == Math.PI / 2.0) this.tilt += 0.001;
}
roll(angle) { // TBD: useful for flight sim or sloped racetracks
this.rot += angle;
}
fov(angle) {
this.fovy += angle;
this.width = 0; // trigger a perspective call in the draw loop
}
reset() {
this.pan = 0.0;
this.tilt = 0.0;
this.rot = 0.0;
this.fovy = 1.0;
this.width = 0; // trigger a perspective call in the draw loop
this.height = 0;
this.position = new p5.Vector(0, 0, 0);
this.velocity = new p5.Vector(0, 0, 0);
this.up = new p5.Vector(0, 1, 0);
this.right = new p5.Vector(1, 0, 0);
this.forward = new p5.Vector(0, 0, 1);
}
setActive(active) { // method to switch between multiple cameras
this.active = active;
if (active) this.width = 0; // trigger a perspective call in the draw loop
}
setState(state) { // state object can have fov,active,rotation,position
if (state.fov !== undefined) {
this.fovy = state.fov;
this.width = 0; // trigger a perspective call in the draw loop;
}
if (state.active !== undefined) this.active = state.active;
if (state.rotation !== undefined) {
this.pan = state.rotation[0];
this.tilt = state.rotation[1];
this.rot = state.rotation[2];
}
if (state.position !== undefined) this.position = new p5.Vector(state.position[0], state.position[1], state.position[2]);
}
// This method is called after the main p5.js draw loop
draw() {
if (this.p5.width !== this.width || this.p5.height !== this.height) {
this.p5.perspective(this.fovy, this.p5.width / this.p5.height, 0.01, 1000.0);
this.width = this.p5.width;
this.height = this.p5.height;
}
// Call the potentially overridden controller method
this.controller();
this.forward = new p5.Vector(Math.cos(this.pan), Math.tan(this.tilt), Math.sin(this.pan));
this.forward.normalize();
this.right = new p5.Vector(Math.cos(this.pan - Math.PI / 2.0), 0, Math.sin(this.pan - Math.PI / 2.0));
// TBD: handle roll command (using this.rot)
this.velocity.mult(this.friction);
this.position.add(this.velocity);
let center = p5.Vector.add(this.position, this.forward);
this.p5.camera(this.position.x, this.position.y, this.position.z, center.x, center.y, center.z, this.up.x, this.up.y, this.up.z);
}
clamp(aNumber, aMin, aMax) {
return (aNumber > aMax ? aMax :
aNumber < aMin ? aMin :
aNumber);
}
}
RoverCam.version = "1.1.0";
// Optional pointerLock applies to all RoverCam instances
RoverCam.pointerLock = false;
RoverCam.usePointerLock = (instance) => {
if (instance === undefined) instance = p5.instance;
if (instance === null) return;
RoverCam.canvas = instance._renderer.elt;
// ffd8 - click into pointerlock example based on:
// https://p5js.org/reference/#/p5/exitPointerLock
document.addEventListener('click', () => {
if (!RoverCam.pointerLock) {
RoverCam.pointerLock = true;
instance.requestPointerLock();
} else {
instance.exitPointerLock();
RoverCam.pointerLock = false;
}
}, false);
document.addEventListener('pointerlockchange', RoverCam.onPointerlockChange, false);
}
// handle exit from pointerLock when user presses ESCAPE
RoverCam.onPointerlockChange = () => {
if (document.pointerLockElement !== RoverCam.canvas &&
document.mozPointerLockElement !== RoverCam.canvas) RoverCam.pointerLock = false;
}
p5.prototype.createRoverCam = function() {
return new RoverCam(this);
}

271
public/sketch.js Normal file
View file

@ -0,0 +1,271 @@
//networking - socket.io
var socket = io(window.location.protocol + "//" + window.location.host);
socket.on("connect", function () {
console.log("connected!");
socket.on("disconnect", () => console.log("disconnected!"));
});
class Block {
constructor(x, y, z, w, h, d) {
this.position = createVector(x, y, z);
this.dimensions = createVector(w, h, d);
this.fillColor = color(random(150, 200));
this.visited = false;
}
update() {
let playerLeft = player.position.x - player.dimensions.x / 2;
let playerRight = player.position.x + player.dimensions.x / 2;
let playerTop = player.position.y - player.dimensions.y / 2;
let playerBottom = player.position.y + player.dimensions.y / 2;
let playerFront = player.position.z - player.dimensions.z / 2;
let playerBack = player.position.z + player.dimensions.z / 2;
let boxLeft = this.position.x - this.dimensions.x / 2;
let boxRight = this.position.x + this.dimensions.x / 2;
let boxTop = this.position.y - this.dimensions.y / 2;
let boxBottom = this.position.y + this.dimensions.y / 2;
let boxFront = this.position.z - this.dimensions.z / 2;
let boxBack = this.position.z + this.dimensions.z / 2;
let boxLeftOverlap = playerRight - boxLeft;
let boxRightOverlap = boxRight - playerLeft;
let boxTopOverlap = playerBottom - boxTop;
let boxBottomOverlap = boxBottom - playerTop;
let boxFrontOverlap = playerBack - boxFront;
let boxBackOverlap = boxBack - playerFront;
if (((playerLeft > boxLeft && playerLeft < boxRight || (playerRight > boxLeft && playerRight < boxRight)) && ((playerTop > boxTop && playerTop < boxBottom) || (playerBottom > boxTop && playerBottom < boxBottom)) && ((playerFront > boxFront && playerFront < boxBack) || (playerBack > boxFront && playerBack < boxBack)))) {
let xOverlap = max(min(boxLeftOverlap, boxRightOverlap), 0);
let yOverlap = max(min(boxTopOverlap, boxBottomOverlap), 0);
let zOverlap = max(min(boxFrontOverlap, boxBackOverlap), 0);
if (xOverlap < yOverlap && xOverlap < zOverlap) {
if (boxLeftOverlap < boxRightOverlap) {
player.position.x = boxLeft - player.dimensions.x / 2;
} else {
player.position.x = boxRight + player.dimensions.x / 2;
}
} else if (yOverlap < xOverlap && yOverlap < zOverlap) {
if (boxTopOverlap < boxBottomOverlap) {
player.position.y = boxTop - player.dimensions.y / 2;
player.velocity.y = 0;
player.grounded = true;
} else {
player.position.y = boxBottom + player.dimensions.y / 2;
}
} else if (zOverlap < xOverlap && zOverlap < yOverlap) {
if (boxFrontOverlap < boxBackOverlap) {
player.position.z = boxFront - player.dimensions.x / 2;
} else {
player.position.z = boxBack + player.dimensions.x / 2;
}
}
}
// prevent player from falling out of the maze
if (player.position.x < 0) player.position.x = 0.01;
if (player.position.z < 0) player.position.z = 0.01;
if (player.position.x > 55) player.position.x = 54.99;
if (player.position.z > 55) player.position.z = 54.99;
if (player.position.y > 55) maze.setPlayerAtStart(player);
}
display() {
push();
translate(this.position.x, this.position.y, this.position.z);
fill(this.fillColor);
box(this.dimensions.x, this.dimensions.y, this.dimensions.z);
pop();
}
pushDown() {
this.position.y += 5;
}
}
class Maze {
constructor(size) {
this.blocks = new Array(size);
for (let i = 0; i < size; i++) {
this.blocks[i] = new Array(size);
for (let j = 0; j < size; j++) {
let x = i * 5;
let y = 0;
let z = j * 5;
this.blocks[i][j] = new Block(x, y, z, 5, 5, 5);
}
}
this.start = this.blocks[1][1];
this.blocks[1][1].fillColor = color(63, 127, 63);
var m = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0],
[0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0],
[0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
for (let i = 1; i < size - 1; i++)
for (let j = 1; j < size - 1; j++)
if (m[i][j]) this.blocks[i][j].pushDown();
else this.blocks[i][j].fillColor = color(127);
this.blocks[3][3].fillColor = color(127, 63, 63);
}
update() {
for (let i = 0; i < this.blocks.length; i++) {
for (let j = 0; j < this.blocks[i].length; j++) {
this.blocks[i][j].update();
}
}
}
display() {
for (let i = 0; i < this.blocks.length; i++) {
for (let j = 0; j < this.blocks[i].length; j++) {
this.blocks[i][j].display();
}
}
}
setPlayerAtStart(player) {
player.reset();
player.position = p5.Vector.add(this.start.position, createVector(0, -15, 0));
}
}
class Player extends RoverCam {
constructor() {
super();
this.dimensions = createVector(1, 3, 1); // min elevation = 0.2
this.velocity = createVector(0, 0, 0);
this.gravity = createVector(0, 0.03, 0);
this.grounded = false;
this.speed = 0.04;
this.sensitivity = 0.02;
}
update() {
// ffd8 - add SHIFT for running!
this.speed = 0.04;
this.sensitivity = 0.02;
if (keyIsDown(16)) {
this.sensitivity = 0.04;
this.speed = 0.08;
}
if (keyIsPressed && key == 'e') {
this.grounded = false;
return;
}
this.velocity.add(this.gravity);
this.position.add(this.velocity);
if (this.grounded && keyIsDown(32)) { // space
this.grounded = false;
this.velocity.y = -1.5;
this.position.y -= 0.2;
}
//event: 'rover'
socket.emit('rover', {
px: this.position.x,
py: this.position.y,
pz: this.position.z,
pan: this.pan,
tilt: this.tilt,
rot: this.rot,
grounded: this.grounded
});
}
}
var player, maze, f, help = false;
function preload() {
f = loadFont('lib/inconsolata.otf');
}
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
strokeWeight(0.04);
textFont(f);
textSize(10);
player = new Player();
RoverCam.usePointerLock();
maze = new Maze(12);
maze.setPlayerAtStart(player);
frameRate(60);
strokeWeight(2);
}
function keyPressed() {
if (key == 'h') help = !help;
// ffd8 - respawn with DELETE or BACKSPACE
if (keyCode == 8 || keyCode == 46) {
maze.setPlayerAtStart(player);
}
}
function windowResized() {
resizeCanvas(window.innerWidth, window.innerHeight, WEBGL);
}
function draw() {
background(0, 0, 51);
maze.update();
maze.display();
player.update();
//drawAxes();
if (help || frameCount < 400) { // Heads Up Display extension by jWilliam
push(); // this affects the frame rate
camera(0, 0, (height / 2.0) / tan(PI * 30.0 / 180.0), 0, 0, 0, 0, 1, 0);
ortho(-width / 2, width / 2, -height / 2, height / 2, 0, 1000);
fill(0, 0, 0, 200);
noStroke();
translate(-380, -380, 0);
scale(2);
rect(0, 0, 140, 85);
fill(127);
text('mouse: left/right : pan', 10, 10);
text(' up/down : tilt', 10, 20);
text(' click : ptrlock', 10, 30);
text(' keys: a/d : left/right', 10, 40);
text(' w/s : fwd/bkwd', 10, 50);
text(' e/q : up/down', 10, 60);
text(' space : jump', 10, 70);
text(' h : help', 10, 80);
pop();
}
}
function drawAxes() {
push();
noStroke();
fill(127, 0, 0); // X red
translate(75, 0.5, 0.5);
box(150, 1, 1);
pop();
push();
noStroke();
fill(0, 127, 0); // Y green
translate(0.5, 75, 0.5);
box(1, 150, 1);
pop();
push();
noStroke();
fill(0, 0, 127); // Z blue
translate(0.5, 0.5, 75);
box(1, 1, 150);
pop();
}

525
receiver/package-lock.json generated Normal file
View file

@ -0,0 +1,525 @@
{
"name": "rover-receiver",
"version": "1.0.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@serialport/binding-mock": {
"version": "10.2.2",
"resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz",
"integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==",
"optional": true,
"requires": {
"@serialport/bindings-interface": "^1.2.1",
"debug": "^4.3.3"
}
},
"@serialport/bindings-cpp": {
"version": "10.7.0",
"resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-10.7.0.tgz",
"integrity": "sha512-Xx1wA2UCG2loS32hxNvWJI4smCzGKhWqE85//fLRzHoGgE1lSLe3Nk7W40/ebrlGFHWRbQZmeaIF4chb2XLliA==",
"optional": true,
"requires": {
"@serialport/bindings-interface": "1.2.1",
"@serialport/parser-readline": "^10.2.1",
"debug": "^4.3.2",
"node-addon-api": "^4.3.0",
"node-gyp-build": "^4.3.0"
},
"dependencies": {
"@serialport/bindings-interface": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.1.tgz",
"integrity": "sha512-63Dyqz2gtryRDDckFusOYqLYhR3Hq/M4sEdbF9i/VsvDb6T+tNVgoAKUZ+FMrXXKnCSu+hYbk+MTc0XQANszxw==",
"optional": true
}
}
},
"@serialport/bindings-interface": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz",
"integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==",
"optional": true
},
"@serialport/parser-byte-length": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-10.3.0.tgz",
"integrity": "sha512-pJ/VoFemzKRRNDHLhFfPThwP40QrGaEnm9TtwL7o2GihEPwzBg3T0bN13ew5TpbbUYZdMpUtpm3CGfl6av9rUQ==",
"optional": true
},
"@serialport/parser-cctalk": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-10.3.0.tgz",
"integrity": "sha512-8ujmk8EvVbDPrNF4mM33bWvUYJOZ0wXbY3WCRazHRWvyCdL0VO0DQvW81ZqgoTpiDQZm5r8wQu9rmuemahF6vQ==",
"optional": true
},
"@serialport/parser-delimiter": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-10.3.0.tgz",
"integrity": "sha512-9E4Vj6s0UbbcCCTclwegHGPYjJhdm9qLCS0lowXQDEQC5naZnbsELemMHs93nD9jHPcyx1B4oXkMnVZLxX5TYw==",
"optional": true
},
"@serialport/parser-inter-byte-timeout": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-10.3.0.tgz",
"integrity": "sha512-wKP0QK85NHgvT6BBB1qBfKBBU4pf8kespNXAZBUYmFT+P4n8r8IZE2mqigCD+AiZcfWNQoAizwOsT/Jx/qeVig==",
"optional": true
},
"@serialport/parser-packet-length": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-10.3.0.tgz",
"integrity": "sha512-bj0cWzt8YSQj/E5fRQVYdi4TsfTlZQrXlXrUwjyTsCONv8IPOHzsz+yY0fw5SEMiJtaLyqvPkCHLsttOd/zFsg==",
"optional": true
},
"@serialport/parser-readline": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-10.3.0.tgz",
"integrity": "sha512-ki3ATZ3/RAqnqGROBKE7k+OeZ0DZXZ53GTca4q71OU5RazbbNhTOBQLKLXD3v9QZXCMJdg4hGW/2Y0DuMUqMQg==",
"optional": true,
"requires": {
"@serialport/parser-delimiter": "10.3.0"
}
},
"@serialport/parser-ready": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-10.3.0.tgz",
"integrity": "sha512-1owywJ4p592dJyVrEJZPIh6pUZ3/y/LN6kGTDH2wxdewRUITo/sGvDy0er5i2+dJD3yuowiAz0dOHSdz8tevJA==",
"optional": true
},
"@serialport/parser-regex": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-10.3.0.tgz",
"integrity": "sha512-tIogTs7CvTH+UUFnsvE7i33MSISyTPTGPWlglWYH2/5coipXY503jlaYS1YGe818wWNcSx6YAjMZRdhTWwM39w==",
"optional": true
},
"@serialport/parser-slip-encoder": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-10.3.0.tgz",
"integrity": "sha512-JI0ILF5sylWn8f0MuMzHFBix/iMUTa79/Z95KaPZYnVaEdA7h7hh/o21Jmon/26P3RJwL1SNJCjZ81zfan+LtQ==",
"optional": true
},
"@serialport/parser-spacepacket": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-10.3.0.tgz",
"integrity": "sha512-PDF73ClEPsClD1FEJZHNuBevDKsJCkqy/XD5+S5eA6+tY5D4HLrVgSWsg+3qqB6+dlpwf2CzHe+uO8D3teuKHA==",
"optional": true
},
"@serialport/stream": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-10.3.0.tgz",
"integrity": "sha512-7sooi5fHogYNVEJwxVdg872xO6TuMgQd2E9iRmv+o8pk/1dbBnPkmH6Ka3st1mVE+0KnIJqVlgei+ncSsqXIGw==",
"optional": true,
"requires": {
"@serialport/bindings-interface": "1.2.1",
"debug": "^4.3.2"
},
"dependencies": {
"@serialport/bindings-interface": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.1.tgz",
"integrity": "sha512-63Dyqz2gtryRDDckFusOYqLYhR3Hq/M4sEdbF9i/VsvDb6T+tNVgoAKUZ+FMrXXKnCSu+hYbk+MTc0XQANszxw==",
"optional": true
}
}
},
"@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
},
"abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"dev": true
},
"anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
}
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"requires": {
"fill-range": "^7.0.1"
}
},
"chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"dev": true,
"requires": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"fsevents": "~2.3.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"engine.io-client": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.3.tgz",
"integrity": "sha512-aXPtgF1JS3RuuKcpSrBtimSjYvrbhKW9froICH4s0F3XQWLxsKNxqzG39nnvQZQnva4CMvUK63T7shevxRyYHw==",
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.0.3",
"ws": "~8.2.3",
"xmlhttprequest-ssl": "~2.0.0"
}
},
"engine.io-parser": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz",
"integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg=="
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"optional": true
},
"glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"requires": {
"is-glob": "^4.0.1"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true
},
"ignore-by-default": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
"dev": true
},
"is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"requires": {
"binary-extensions": "^2.0.0"
}
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true
},
"is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"requires": {
"is-extglob": "^2.1.1"
}
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
},
"long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
},
"minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node-addon-api": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
"integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==",
"optional": true
},
"node-gyp-build": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz",
"integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==",
"optional": true
},
"nodemon": {
"version": "2.0.20",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz",
"integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==",
"dev": true,
"requires": {
"chokidar": "^3.5.2",
"debug": "^3.2.7",
"ignore-by-default": "^1.0.1",
"minimatch": "^3.1.2",
"pstree.remy": "^1.1.8",
"semver": "^5.7.1",
"simple-update-notifier": "^1.0.7",
"supports-color": "^5.5.0",
"touch": "^3.1.0",
"undefsafe": "^2.0.5"
},
"dependencies": {
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
}
}
},
"nopt": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
"integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
"dev": true,
"requires": {
"abbrev": "1"
}
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
},
"osc": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/osc/-/osc-2.4.3.tgz",
"integrity": "sha512-6FrgHg7DbL+e0YYOhqIa0mT4+2y4uG4K3PGFdhf75oSj1Zp2O93sgbw/T/O6bXNY3QCA3Skiy2OOdszSi45nGQ==",
"requires": {
"long": "4.0.0",
"serialport": "10.4.0",
"slip": "1.0.2",
"wolfy87-eventemitter": "5.2.9",
"ws": "8.5.0"
},
"dependencies": {
"ws": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz",
"integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg=="
}
}
},
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true
},
"pstree.remy": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
"integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
"dev": true
},
"readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"requires": {
"picomatch": "^2.2.1"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
},
"serialport": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/serialport/-/serialport-10.4.0.tgz",
"integrity": "sha512-PszPM5SnFMgSXom60PkKS2A9nMlNbHkuoyRBlzdSWw9rmgOn258+V0dYbWMrETJMM+TJV32vqBzjg5MmmUMwMw==",
"optional": true,
"requires": {
"@serialport/binding-mock": "10.2.2",
"@serialport/bindings-cpp": "10.7.0",
"@serialport/parser-byte-length": "10.3.0",
"@serialport/parser-cctalk": "10.3.0",
"@serialport/parser-delimiter": "10.3.0",
"@serialport/parser-inter-byte-timeout": "10.3.0",
"@serialport/parser-packet-length": "10.3.0",
"@serialport/parser-readline": "10.3.0",
"@serialport/parser-ready": "10.3.0",
"@serialport/parser-regex": "10.3.0",
"@serialport/parser-slip-encoder": "10.3.0",
"@serialport/parser-spacepacket": "10.3.0",
"@serialport/stream": "10.3.0",
"debug": "^4.3.3"
}
},
"simple-update-notifier": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
"integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==",
"dev": true,
"requires": {
"semver": "~7.0.0"
},
"dependencies": {
"semver": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
"dev": true
}
}
},
"slip": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/slip/-/slip-1.0.2.tgz",
"integrity": "sha512-XrcHe3NAcyD3wO+O4I13RcS4/3AF+S9RvGNj9JhJeS02HyImwD2E3QWLrmn9hBfL+fB6yapagwxRkeyYzhk98g=="
},
"socket.io-client": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.4.tgz",
"integrity": "sha512-ZpKteoA06RzkD32IbqILZ+Cnst4xewU7ZYK12aS1mzHftFFjpoMz69IuhP/nL25pJfao/amoPI527KnuhFm01g==",
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.2.3",
"socket.io-parser": "~4.2.1"
}
},
"socket.io-parser": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz",
"integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==",
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": {
"is-number": "^7.0.0"
}
},
"touch": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
"integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
"dev": true,
"requires": {
"nopt": "~1.0.10"
}
},
"undefsafe": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
"dev": true
},
"wolfy87-eventemitter": {
"version": "5.2.9",
"resolved": "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz",
"integrity": "sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw=="
},
"ws": {
"version": "8.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA=="
},
"xmlhttprequest-ssl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
"integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A=="
}
}
}

24
receiver/package.json Normal file
View file

@ -0,0 +1,24 @@
{
"name": "rover-receiver",
"version": "1.0.1",
"description": "",
"main": "receiver.js",
"scripts": {
"start": "node receiver.js",
"dev": "nodemon receiver.js"
},
"dependencies": {
"osc": "^2.4.3",
"socket.io-client": "^4.5.4"
},
"engines": {
"node": "12.x"
},
"repository": {
"url": "https://glitch.com/edit/#!/glitch-hello-node"
},
"license": "MIT",
"devDependencies": {
"nodemon": "^2.0.15"
}
}

56
receiver/receiver.js Normal file
View file

@ -0,0 +1,56 @@
const args = process.argv.slice(2);
var host = args[0];
if (!host) host = 'http://localhost:8080';
console.log(
"connecting to the host... : \n" +
"\t --> " + host + "\n"
);
var socket = require('socket.io-client')(host);
var osc = require("osc");
var udp = new osc.UDPPort({
localAddress: '0.0.0.0',
//NOTE: '127.0.0.1' doesn't work!! for comm. between different machines
localPort: 57001,
remoteAddress: '0.0.0.0',
remotePort: 57000,
metadata: true
});
Promise.all([
new Promise(function(resolve, reject) {
udp.on("ready", function() {
resolve(0);
console.log('udp ready..');
});
})
]).then(function(results) {
socket.on('connect', () => console.log("[osc-receiver] i'm connected."));
socket.on('disconnect', () => console.log("[osc-receiver] i'm disconnected."));
socket.on('rover', function(rover) {
udp.send({
address: "/rover",
args: [
{ type: "f", value: rover.px },
{ type: "f", value: rover.py },
{ type: "f", value: rover.pz },
{ type: "f", value: rover.pan },
{ type: "f", value: rover.tilt },
{ type: "f", value: rover.rot },
{ type: "f", value: rover.grounded }
]
});
});
});
udp.open();
udp.on("ready", function() {
console.log(
"[udp] ready (udp) : \n" +
"\tlistening on --> " + udp.options.localAddress + ":" + udp.options.localPort + "\n" +
"\tspeaking to -> " + udp.options.remoteAddress + ":" + udp.options.remotePort + "\n"
);
});