├── .gitignore ├── LICENSE ├── README.md ├── css └── style.css ├── frames.html ├── images ├── .gitignore └── 1.png ├── index.html ├── js └── jquery.js ├── lib └── artnet_server.js ├── package-lock.json ├── package.json └── weblight.js /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | .DS_Store 14 | 15 | node_modules 16 | 17 | nodeDocker.sh 18 | 19 | .idea 20 | *.iml 21 | .project 22 | .com.greenworldsoft.syncfolderspro 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Michael Träger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![NPM](https://nodei.co/npm/artnet-weblight.png?compact=true)](https://npmjs.org/package/artnet-weblight) 2 | 3 | # Artnet Weblight 4 | 5 | Use your Browser as an Artnet lighting device! 6 | 7 | It supports dimmer, red, green and blue channels as well as border, blur and images. 8 | 9 | Installation: `npm install -g artnet-weblight` Start: `weblight` 10 | 11 | Start from source with `node weblight.js`. 12 | Webinterface will be available at `localhost:3000`. It uses standard Artnet port `6454`. 13 | 14 | 15 | ## Devices 16 | 17 | Each virtual device has 10 channels. First device 0 starts at channel 1, second device 1 at channel 11 and so on... 18 | 19 | 50 devices are possible on one universe (one instance of this application). 20 | 21 | Access devices via `address:port/device#`, e.g. `localhost:3000/0`. 22 | 23 | ### Images 24 | The images can be placed in `/images`. Every image has 10 dmx-values where it is visible. 25 | The images can/should be numbered XX.filetype (e.g. 1.png) for preserving correct order. 26 | 27 | Image 0 is empty. So you can use 25 images. Images are channel 6. 28 | 29 | 30 | ### Channels 31 | 1. Dimmer 32 | 2. Red 33 | 3. Green 34 | 4. Blue 35 | 5. Border size 36 | 6. Blur (for Border) 37 | 7. Image overlay 38 | 39 | 40 | ## More 41 | 42 | ### Debugging Artnet 43 | Use `http://localhost:3000/0?debug` for debugging values. 44 | 45 | ### Frame View 46 | Use `http://localhost:3000/frames` to see the first four devices on one page with debug info enabled. 47 | 48 | Configure Frame view with params `count` (default 4) and `debug` (default true). Starting device can be varied by using another frame-id, e.g. `/frames/10`. 49 | 50 | Example: `http://localhost:3000/frames/10?count=5&debug=false` 51 | 52 | 53 | ### Testing 54 | For Testing you can use https://github.com/mtraeger/dmx-webcontrol and configure a (separate) universe like this: 55 | ``` 56 | "monitor": { 57 | "output": { 58 | "driver": "artnet", 59 | "device": "localhost" 60 | }, 61 | "devices": [ 62 | { 63 | "label": "Monitor 1", 64 | "type": "artnet-weblight", 65 | "address": 1 66 | }, 67 | { 68 | "label": "Monitor 2", 69 | "type": "artnet-weblight", 70 | "address": 11 71 | }, 72 | { 73 | "label": "Monitor 3", 74 | "type": "artnet-weblight", 75 | "address": 21 76 | } 77 | ] 78 | } 79 | ``` 80 | 81 | ### Notes 82 | 83 | Some sort of color correction can be done by using the dimmer channel to reduce the overall brightness of the rgb channels. Dimming down to e.g. 80% can bring the monitor colors more towards your physical devices. 84 | 85 | 86 | ### Todo 87 | * Config-File 88 | * circle radius 89 | * color correction - adopt to physical devices (e.g. by predefined dimmer factor to reduce collor brilliance) 90 | * show identifier (and debug info) via dmx - maybe on image channel 91 | * web interface for selecting images / videos + maybe upload 92 | 93 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | html { 2 | background-color: black; 3 | } 4 | 5 | body { 6 | width: 100%; 7 | height: 100vh; 8 | margin: 0px; 9 | padding: 0px; 10 | overflow: hidden; 11 | /*box-shadow: 0px 0px 50px 10px #000000 inset;*/ 12 | background-repeat: no-repeat; 13 | background-position: center center; 14 | background-size: contain; 15 | } 16 | 17 | #debug { 18 | display: none; 19 | position: fixed; 20 | background-color: white; 21 | top: 10px; 22 | margin: 10px; 23 | padding: 10px; 24 | /*mix-blend-mode: hard-light;*/ 25 | } 26 | 27 | #circlebox { 28 | overflow: hidden; 29 | width: 100%; 30 | height: 100vh; 31 | margin: 0 auto; 32 | background-color: transparent; 33 | } 34 | 35 | #circlebox:after { 36 | flex: 1; 37 | content: ''; 38 | position: absolute; 39 | border-radius: 100%; 40 | width: 50vw; 41 | height: 50vh; 42 | box-shadow: 0px 0px 0px 2000px #000000; 43 | /* TODO blur complete box: inset */ 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /frames.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Artnet Weblight Frames 5 | 6 | 7 | 29 | 30 | 31 | 32 |
33 | 34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /images/.gitignore: -------------------------------------------------------------------------------- 1 | *.* 2 | !.gitignore 3 | !1.png 4 | -------------------------------------------------------------------------------- /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtraeger/artnet-weblight/ce459e835ecee55e14a2a1de2b7b043c33b24eca/images/1.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Artnet Weblight 5 | 6 | 7 | 8 | 9 | 42 | 43 | 44 | 45 |
46 | 47 |
48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /lib/artnet_server.js: -------------------------------------------------------------------------------- 1 | var dgram = require('dgram'); 2 | 3 | // ArtNet server class from https://github.com/BrianMMcclain/artnet-node 4 | // Removed events for running on node v8 5 | exports.listen = function(port, cb) { 6 | this.port = port; 7 | 8 | // Set up the socket 9 | var sock = dgram.createSocket("udp4", function (msg, peer) { 10 | var data = new Array(); 11 | for (i = 0; i < msg.length; i++) { 12 | var d = msg.toString().charCodeAt(i); 13 | // Since we can't do unsigned 8-bit integers, do some normalization 14 | if (d < 0) { 15 | d = 0; 16 | } else if (d > 255) { 17 | d = 255; 18 | } 19 | 20 | // Append the byte to the array 21 | data.push(d); 22 | } 23 | 24 | // Deseralize the data - magic numbers are as per the Art-Net protocol 25 | var sequence = data[12]; 26 | var physical = data[13]; 27 | var universe = (data[14] * 256) + data[15]; 28 | var length = (data[16] * 256) + data[17]; 29 | 30 | // Modified from original lib to fix values > 127 31 | // var rawBuffer = Buffer.from(msg) 32 | var rawBuffer = new Buffer(msg) //TODO deprecated 33 | 34 | var rawData = new Array(); 35 | for (i = 0; i < length; i++) { 36 | rawData.push(rawBuffer.readUInt8(i + 18)); 37 | } 38 | 39 | // Build the associative array to return 40 | var retData = {sequence: sequence, physical: physical, universe: universe, length: length, data: rawData}; 41 | 42 | // And call the callback passing the deseralized data 43 | cb(retData, peer); 44 | }); 45 | sock.bind(port); 46 | }; 47 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "artnet-weblight", 3 | "version": "1.0.2", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "version": "1.0.2", 9 | "license": "MIT", 10 | "dependencies": { 11 | "artnet-node": "0.1.x", 12 | "commander": "^2.18.0", 13 | "express": "^4.16.3", 14 | "glob": "^7.1.3", 15 | "socket.io": "^4.4.1" 16 | }, 17 | "bin": { 18 | "weblight": "weblight.js" 19 | } 20 | }, 21 | "node_modules/@socket.io/base64-arraybuffer": { 22 | "version": "1.0.2", 23 | "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", 24 | "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==", 25 | "engines": { 26 | "node": ">= 0.6.0" 27 | } 28 | }, 29 | "node_modules/@types/component-emitter": { 30 | "version": "1.2.11", 31 | "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", 32 | "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==" 33 | }, 34 | "node_modules/@types/cookie": { 35 | "version": "0.4.1", 36 | "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", 37 | "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" 38 | }, 39 | "node_modules/@types/cors": { 40 | "version": "2.8.12", 41 | "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", 42 | "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" 43 | }, 44 | "node_modules/@types/node": { 45 | "version": "17.0.21", 46 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", 47 | "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==" 48 | }, 49 | "node_modules/accepts": { 50 | "version": "1.3.8", 51 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 52 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 53 | "dependencies": { 54 | "mime-types": "~2.1.34", 55 | "negotiator": "0.6.3" 56 | }, 57 | "engines": { 58 | "node": ">= 0.6" 59 | } 60 | }, 61 | "node_modules/array-flatten": { 62 | "version": "1.1.1", 63 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 64 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 65 | }, 66 | "node_modules/artnet-node": { 67 | "version": "0.1.0", 68 | "resolved": "https://registry.npmjs.org/artnet-node/-/artnet-node-0.1.0.tgz", 69 | "integrity": "sha1-L7ubgAVc4a5UbDgfw4F48oO9R4E=", 70 | "engines": { 71 | "node": ">=0.6" 72 | } 73 | }, 74 | "node_modules/balanced-match": { 75 | "version": "1.0.2", 76 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 77 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 78 | }, 79 | "node_modules/base64id": { 80 | "version": "2.0.0", 81 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", 82 | "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", 83 | "engines": { 84 | "node": "^4.5.0 || >= 5.9" 85 | } 86 | }, 87 | "node_modules/body-parser": { 88 | "version": "1.19.2", 89 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", 90 | "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", 91 | "dependencies": { 92 | "bytes": "3.1.2", 93 | "content-type": "~1.0.4", 94 | "debug": "2.6.9", 95 | "depd": "~1.1.2", 96 | "http-errors": "1.8.1", 97 | "iconv-lite": "0.4.24", 98 | "on-finished": "~2.3.0", 99 | "qs": "6.9.7", 100 | "raw-body": "2.4.3", 101 | "type-is": "~1.6.18" 102 | }, 103 | "engines": { 104 | "node": ">= 0.8" 105 | } 106 | }, 107 | "node_modules/brace-expansion": { 108 | "version": "1.1.11", 109 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 110 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 111 | "dependencies": { 112 | "balanced-match": "^1.0.0", 113 | "concat-map": "0.0.1" 114 | } 115 | }, 116 | "node_modules/bytes": { 117 | "version": "3.1.2", 118 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 119 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 120 | "engines": { 121 | "node": ">= 0.8" 122 | } 123 | }, 124 | "node_modules/commander": { 125 | "version": "2.20.3", 126 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 127 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" 128 | }, 129 | "node_modules/component-emitter": { 130 | "version": "1.3.0", 131 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", 132 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" 133 | }, 134 | "node_modules/concat-map": { 135 | "version": "0.0.1", 136 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 137 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 138 | }, 139 | "node_modules/content-disposition": { 140 | "version": "0.5.4", 141 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 142 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 143 | "dependencies": { 144 | "safe-buffer": "5.2.1" 145 | }, 146 | "engines": { 147 | "node": ">= 0.6" 148 | } 149 | }, 150 | "node_modules/content-type": { 151 | "version": "1.0.4", 152 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 153 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 154 | "engines": { 155 | "node": ">= 0.6" 156 | } 157 | }, 158 | "node_modules/cookie": { 159 | "version": "0.4.2", 160 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", 161 | "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", 162 | "engines": { 163 | "node": ">= 0.6" 164 | } 165 | }, 166 | "node_modules/cookie-signature": { 167 | "version": "1.0.6", 168 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 169 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 170 | }, 171 | "node_modules/cors": { 172 | "version": "2.8.5", 173 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 174 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 175 | "dependencies": { 176 | "object-assign": "^4", 177 | "vary": "^1" 178 | }, 179 | "engines": { 180 | "node": ">= 0.10" 181 | } 182 | }, 183 | "node_modules/debug": { 184 | "version": "2.6.9", 185 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 186 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 187 | "dependencies": { 188 | "ms": "2.0.0" 189 | } 190 | }, 191 | "node_modules/depd": { 192 | "version": "1.1.2", 193 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 194 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 195 | "engines": { 196 | "node": ">= 0.6" 197 | } 198 | }, 199 | "node_modules/destroy": { 200 | "version": "1.0.4", 201 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 202 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 203 | }, 204 | "node_modules/ee-first": { 205 | "version": "1.1.1", 206 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 207 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 208 | }, 209 | "node_modules/encodeurl": { 210 | "version": "1.0.2", 211 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 212 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 213 | "engines": { 214 | "node": ">= 0.8" 215 | } 216 | }, 217 | "node_modules/engine.io": { 218 | "version": "6.1.3", 219 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.3.tgz", 220 | "integrity": "sha512-rqs60YwkvWTLLnfazqgZqLa/aKo+9cueVfEi/dZ8PyGyaf8TLOxj++4QMIgeG3Gn0AhrWiFXvghsoY9L9h25GA==", 221 | "dependencies": { 222 | "@types/cookie": "^0.4.1", 223 | "@types/cors": "^2.8.12", 224 | "@types/node": ">=10.0.0", 225 | "accepts": "~1.3.4", 226 | "base64id": "2.0.0", 227 | "cookie": "~0.4.1", 228 | "cors": "~2.8.5", 229 | "debug": "~4.3.1", 230 | "engine.io-parser": "~5.0.3", 231 | "ws": "~8.2.3" 232 | }, 233 | "engines": { 234 | "node": ">=10.0.0" 235 | } 236 | }, 237 | "node_modules/engine.io-parser": { 238 | "version": "5.0.3", 239 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz", 240 | "integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==", 241 | "dependencies": { 242 | "@socket.io/base64-arraybuffer": "~1.0.2" 243 | }, 244 | "engines": { 245 | "node": ">=10.0.0" 246 | } 247 | }, 248 | "node_modules/engine.io/node_modules/debug": { 249 | "version": "4.3.3", 250 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 251 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 252 | "dependencies": { 253 | "ms": "2.1.2" 254 | }, 255 | "engines": { 256 | "node": ">=6.0" 257 | }, 258 | "peerDependenciesMeta": { 259 | "supports-color": { 260 | "optional": true 261 | } 262 | } 263 | }, 264 | "node_modules/engine.io/node_modules/ms": { 265 | "version": "2.1.2", 266 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 267 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 268 | }, 269 | "node_modules/escape-html": { 270 | "version": "1.0.3", 271 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 272 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 273 | }, 274 | "node_modules/etag": { 275 | "version": "1.8.1", 276 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 277 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", 278 | "engines": { 279 | "node": ">= 0.6" 280 | } 281 | }, 282 | "node_modules/express": { 283 | "version": "4.17.3", 284 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", 285 | "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", 286 | "dependencies": { 287 | "accepts": "~1.3.8", 288 | "array-flatten": "1.1.1", 289 | "body-parser": "1.19.2", 290 | "content-disposition": "0.5.4", 291 | "content-type": "~1.0.4", 292 | "cookie": "0.4.2", 293 | "cookie-signature": "1.0.6", 294 | "debug": "2.6.9", 295 | "depd": "~1.1.2", 296 | "encodeurl": "~1.0.2", 297 | "escape-html": "~1.0.3", 298 | "etag": "~1.8.1", 299 | "finalhandler": "~1.1.2", 300 | "fresh": "0.5.2", 301 | "merge-descriptors": "1.0.1", 302 | "methods": "~1.1.2", 303 | "on-finished": "~2.3.0", 304 | "parseurl": "~1.3.3", 305 | "path-to-regexp": "0.1.7", 306 | "proxy-addr": "~2.0.7", 307 | "qs": "6.9.7", 308 | "range-parser": "~1.2.1", 309 | "safe-buffer": "5.2.1", 310 | "send": "0.17.2", 311 | "serve-static": "1.14.2", 312 | "setprototypeof": "1.2.0", 313 | "statuses": "~1.5.0", 314 | "type-is": "~1.6.18", 315 | "utils-merge": "1.0.1", 316 | "vary": "~1.1.2" 317 | }, 318 | "engines": { 319 | "node": ">= 0.10.0" 320 | } 321 | }, 322 | "node_modules/finalhandler": { 323 | "version": "1.1.2", 324 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 325 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 326 | "dependencies": { 327 | "debug": "2.6.9", 328 | "encodeurl": "~1.0.2", 329 | "escape-html": "~1.0.3", 330 | "on-finished": "~2.3.0", 331 | "parseurl": "~1.3.3", 332 | "statuses": "~1.5.0", 333 | "unpipe": "~1.0.0" 334 | }, 335 | "engines": { 336 | "node": ">= 0.8" 337 | } 338 | }, 339 | "node_modules/forwarded": { 340 | "version": "0.2.0", 341 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 342 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 343 | "engines": { 344 | "node": ">= 0.6" 345 | } 346 | }, 347 | "node_modules/fresh": { 348 | "version": "0.5.2", 349 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 350 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", 351 | "engines": { 352 | "node": ">= 0.6" 353 | } 354 | }, 355 | "node_modules/fs.realpath": { 356 | "version": "1.0.0", 357 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 358 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 359 | }, 360 | "node_modules/glob": { 361 | "version": "7.2.0", 362 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 363 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 364 | "dependencies": { 365 | "fs.realpath": "^1.0.0", 366 | "inflight": "^1.0.4", 367 | "inherits": "2", 368 | "minimatch": "^3.0.4", 369 | "once": "^1.3.0", 370 | "path-is-absolute": "^1.0.0" 371 | }, 372 | "engines": { 373 | "node": "*" 374 | }, 375 | "funding": { 376 | "url": "https://github.com/sponsors/isaacs" 377 | } 378 | }, 379 | "node_modules/http-errors": { 380 | "version": "1.8.1", 381 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", 382 | "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", 383 | "dependencies": { 384 | "depd": "~1.1.2", 385 | "inherits": "2.0.4", 386 | "setprototypeof": "1.2.0", 387 | "statuses": ">= 1.5.0 < 2", 388 | "toidentifier": "1.0.1" 389 | }, 390 | "engines": { 391 | "node": ">= 0.6" 392 | } 393 | }, 394 | "node_modules/iconv-lite": { 395 | "version": "0.4.24", 396 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 397 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 398 | "dependencies": { 399 | "safer-buffer": ">= 2.1.2 < 3" 400 | }, 401 | "engines": { 402 | "node": ">=0.10.0" 403 | } 404 | }, 405 | "node_modules/inflight": { 406 | "version": "1.0.6", 407 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 408 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 409 | "dependencies": { 410 | "once": "^1.3.0", 411 | "wrappy": "1" 412 | } 413 | }, 414 | "node_modules/inherits": { 415 | "version": "2.0.4", 416 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 417 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 418 | }, 419 | "node_modules/ipaddr.js": { 420 | "version": "1.9.1", 421 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 422 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 423 | "engines": { 424 | "node": ">= 0.10" 425 | } 426 | }, 427 | "node_modules/media-typer": { 428 | "version": "0.3.0", 429 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 430 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", 431 | "engines": { 432 | "node": ">= 0.6" 433 | } 434 | }, 435 | "node_modules/merge-descriptors": { 436 | "version": "1.0.1", 437 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 438 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 439 | }, 440 | "node_modules/methods": { 441 | "version": "1.1.2", 442 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 443 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", 444 | "engines": { 445 | "node": ">= 0.6" 446 | } 447 | }, 448 | "node_modules/mime": { 449 | "version": "1.6.0", 450 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 451 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 452 | "bin": { 453 | "mime": "cli.js" 454 | }, 455 | "engines": { 456 | "node": ">=4" 457 | } 458 | }, 459 | "node_modules/mime-db": { 460 | "version": "1.52.0", 461 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 462 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 463 | "engines": { 464 | "node": ">= 0.6" 465 | } 466 | }, 467 | "node_modules/mime-types": { 468 | "version": "2.1.35", 469 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 470 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 471 | "dependencies": { 472 | "mime-db": "1.52.0" 473 | }, 474 | "engines": { 475 | "node": ">= 0.6" 476 | } 477 | }, 478 | "node_modules/minimatch": { 479 | "version": "3.1.2", 480 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 481 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 482 | "dependencies": { 483 | "brace-expansion": "^1.1.7" 484 | }, 485 | "engines": { 486 | "node": "*" 487 | } 488 | }, 489 | "node_modules/ms": { 490 | "version": "2.0.0", 491 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 492 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 493 | }, 494 | "node_modules/negotiator": { 495 | "version": "0.6.3", 496 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 497 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 498 | "engines": { 499 | "node": ">= 0.6" 500 | } 501 | }, 502 | "node_modules/object-assign": { 503 | "version": "4.1.1", 504 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 505 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 506 | "engines": { 507 | "node": ">=0.10.0" 508 | } 509 | }, 510 | "node_modules/on-finished": { 511 | "version": "2.3.0", 512 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 513 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 514 | "dependencies": { 515 | "ee-first": "1.1.1" 516 | }, 517 | "engines": { 518 | "node": ">= 0.8" 519 | } 520 | }, 521 | "node_modules/once": { 522 | "version": "1.4.0", 523 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 524 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 525 | "dependencies": { 526 | "wrappy": "1" 527 | } 528 | }, 529 | "node_modules/parseurl": { 530 | "version": "1.3.3", 531 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 532 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 533 | "engines": { 534 | "node": ">= 0.8" 535 | } 536 | }, 537 | "node_modules/path-is-absolute": { 538 | "version": "1.0.1", 539 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 540 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 541 | "engines": { 542 | "node": ">=0.10.0" 543 | } 544 | }, 545 | "node_modules/path-to-regexp": { 546 | "version": "0.1.7", 547 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 548 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 549 | }, 550 | "node_modules/proxy-addr": { 551 | "version": "2.0.7", 552 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 553 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 554 | "dependencies": { 555 | "forwarded": "0.2.0", 556 | "ipaddr.js": "1.9.1" 557 | }, 558 | "engines": { 559 | "node": ">= 0.10" 560 | } 561 | }, 562 | "node_modules/qs": { 563 | "version": "6.9.7", 564 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", 565 | "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", 566 | "engines": { 567 | "node": ">=0.6" 568 | }, 569 | "funding": { 570 | "url": "https://github.com/sponsors/ljharb" 571 | } 572 | }, 573 | "node_modules/range-parser": { 574 | "version": "1.2.1", 575 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 576 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 577 | "engines": { 578 | "node": ">= 0.6" 579 | } 580 | }, 581 | "node_modules/raw-body": { 582 | "version": "2.4.3", 583 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", 584 | "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", 585 | "dependencies": { 586 | "bytes": "3.1.2", 587 | "http-errors": "1.8.1", 588 | "iconv-lite": "0.4.24", 589 | "unpipe": "1.0.0" 590 | }, 591 | "engines": { 592 | "node": ">= 0.8" 593 | } 594 | }, 595 | "node_modules/safe-buffer": { 596 | "version": "5.2.1", 597 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 598 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 599 | "funding": [ 600 | { 601 | "type": "github", 602 | "url": "https://github.com/sponsors/feross" 603 | }, 604 | { 605 | "type": "patreon", 606 | "url": "https://www.patreon.com/feross" 607 | }, 608 | { 609 | "type": "consulting", 610 | "url": "https://feross.org/support" 611 | } 612 | ] 613 | }, 614 | "node_modules/safer-buffer": { 615 | "version": "2.1.2", 616 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 617 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 618 | }, 619 | "node_modules/send": { 620 | "version": "0.17.2", 621 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", 622 | "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", 623 | "dependencies": { 624 | "debug": "2.6.9", 625 | "depd": "~1.1.2", 626 | "destroy": "~1.0.4", 627 | "encodeurl": "~1.0.2", 628 | "escape-html": "~1.0.3", 629 | "etag": "~1.8.1", 630 | "fresh": "0.5.2", 631 | "http-errors": "1.8.1", 632 | "mime": "1.6.0", 633 | "ms": "2.1.3", 634 | "on-finished": "~2.3.0", 635 | "range-parser": "~1.2.1", 636 | "statuses": "~1.5.0" 637 | }, 638 | "engines": { 639 | "node": ">= 0.8.0" 640 | } 641 | }, 642 | "node_modules/send/node_modules/ms": { 643 | "version": "2.1.3", 644 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 645 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 646 | }, 647 | "node_modules/serve-static": { 648 | "version": "1.14.2", 649 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", 650 | "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", 651 | "dependencies": { 652 | "encodeurl": "~1.0.2", 653 | "escape-html": "~1.0.3", 654 | "parseurl": "~1.3.3", 655 | "send": "0.17.2" 656 | }, 657 | "engines": { 658 | "node": ">= 0.8.0" 659 | } 660 | }, 661 | "node_modules/setprototypeof": { 662 | "version": "1.2.0", 663 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 664 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 665 | }, 666 | "node_modules/socket.io": { 667 | "version": "4.4.1", 668 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz", 669 | "integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==", 670 | "license": "MIT", 671 | "dependencies": { 672 | "accepts": "~1.3.4", 673 | "base64id": "~2.0.0", 674 | "debug": "~4.3.2", 675 | "engine.io": "~6.1.0", 676 | "socket.io-adapter": "~2.3.3", 677 | "socket.io-parser": "~4.0.4" 678 | }, 679 | "engines": { 680 | "node": ">=10.0.0" 681 | } 682 | }, 683 | "node_modules/socket.io-adapter": { 684 | "version": "2.3.3", 685 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz", 686 | "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==" 687 | }, 688 | "node_modules/socket.io-parser": { 689 | "version": "4.0.4", 690 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", 691 | "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", 692 | "dependencies": { 693 | "@types/component-emitter": "^1.2.10", 694 | "component-emitter": "~1.3.0", 695 | "debug": "~4.3.1" 696 | }, 697 | "engines": { 698 | "node": ">=10.0.0" 699 | } 700 | }, 701 | "node_modules/socket.io-parser/node_modules/debug": { 702 | "version": "4.3.3", 703 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 704 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 705 | "dependencies": { 706 | "ms": "2.1.2" 707 | }, 708 | "engines": { 709 | "node": ">=6.0" 710 | }, 711 | "peerDependenciesMeta": { 712 | "supports-color": { 713 | "optional": true 714 | } 715 | } 716 | }, 717 | "node_modules/socket.io-parser/node_modules/ms": { 718 | "version": "2.1.2", 719 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 720 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 721 | }, 722 | "node_modules/socket.io/node_modules/debug": { 723 | "version": "4.3.3", 724 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 725 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 726 | "dependencies": { 727 | "ms": "2.1.2" 728 | }, 729 | "engines": { 730 | "node": ">=6.0" 731 | }, 732 | "peerDependenciesMeta": { 733 | "supports-color": { 734 | "optional": true 735 | } 736 | } 737 | }, 738 | "node_modules/socket.io/node_modules/ms": { 739 | "version": "2.1.2", 740 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 741 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 742 | }, 743 | "node_modules/statuses": { 744 | "version": "1.5.0", 745 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 746 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", 747 | "engines": { 748 | "node": ">= 0.6" 749 | } 750 | }, 751 | "node_modules/toidentifier": { 752 | "version": "1.0.1", 753 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 754 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 755 | "engines": { 756 | "node": ">=0.6" 757 | } 758 | }, 759 | "node_modules/type-is": { 760 | "version": "1.6.18", 761 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 762 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 763 | "dependencies": { 764 | "media-typer": "0.3.0", 765 | "mime-types": "~2.1.24" 766 | }, 767 | "engines": { 768 | "node": ">= 0.6" 769 | } 770 | }, 771 | "node_modules/unpipe": { 772 | "version": "1.0.0", 773 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 774 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", 775 | "engines": { 776 | "node": ">= 0.8" 777 | } 778 | }, 779 | "node_modules/utils-merge": { 780 | "version": "1.0.1", 781 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 782 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", 783 | "engines": { 784 | "node": ">= 0.4.0" 785 | } 786 | }, 787 | "node_modules/vary": { 788 | "version": "1.1.2", 789 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 790 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", 791 | "engines": { 792 | "node": ">= 0.8" 793 | } 794 | }, 795 | "node_modules/wrappy": { 796 | "version": "1.0.2", 797 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 798 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 799 | }, 800 | "node_modules/ws": { 801 | "version": "8.2.3", 802 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", 803 | "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", 804 | "engines": { 805 | "node": ">=10.0.0" 806 | }, 807 | "peerDependencies": { 808 | "bufferutil": "^4.0.1", 809 | "utf-8-validate": "^5.0.2" 810 | }, 811 | "peerDependenciesMeta": { 812 | "bufferutil": { 813 | "optional": true 814 | }, 815 | "utf-8-validate": { 816 | "optional": true 817 | } 818 | } 819 | } 820 | }, 821 | "dependencies": { 822 | "@socket.io/base64-arraybuffer": { 823 | "version": "1.0.2", 824 | "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", 825 | "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==" 826 | }, 827 | "@types/component-emitter": { 828 | "version": "1.2.11", 829 | "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", 830 | "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==" 831 | }, 832 | "@types/cookie": { 833 | "version": "0.4.1", 834 | "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", 835 | "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" 836 | }, 837 | "@types/cors": { 838 | "version": "2.8.12", 839 | "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", 840 | "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" 841 | }, 842 | "@types/node": { 843 | "version": "17.0.21", 844 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", 845 | "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==" 846 | }, 847 | "accepts": { 848 | "version": "1.3.8", 849 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 850 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 851 | "requires": { 852 | "mime-types": "~2.1.34", 853 | "negotiator": "0.6.3" 854 | } 855 | }, 856 | "array-flatten": { 857 | "version": "1.1.1", 858 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 859 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 860 | }, 861 | "artnet-node": { 862 | "version": "0.1.0", 863 | "resolved": "https://registry.npmjs.org/artnet-node/-/artnet-node-0.1.0.tgz", 864 | "integrity": "sha1-L7ubgAVc4a5UbDgfw4F48oO9R4E=" 865 | }, 866 | "balanced-match": { 867 | "version": "1.0.2", 868 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 869 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 870 | }, 871 | "base64id": { 872 | "version": "2.0.0", 873 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", 874 | "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" 875 | }, 876 | "body-parser": { 877 | "version": "1.19.2", 878 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", 879 | "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", 880 | "requires": { 881 | "bytes": "3.1.2", 882 | "content-type": "~1.0.4", 883 | "debug": "2.6.9", 884 | "depd": "~1.1.2", 885 | "http-errors": "1.8.1", 886 | "iconv-lite": "0.4.24", 887 | "on-finished": "~2.3.0", 888 | "qs": "6.9.7", 889 | "raw-body": "2.4.3", 890 | "type-is": "~1.6.18" 891 | } 892 | }, 893 | "brace-expansion": { 894 | "version": "1.1.11", 895 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 896 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 897 | "requires": { 898 | "balanced-match": "^1.0.0", 899 | "concat-map": "0.0.1" 900 | } 901 | }, 902 | "bytes": { 903 | "version": "3.1.2", 904 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 905 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 906 | }, 907 | "commander": { 908 | "version": "2.20.3", 909 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 910 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" 911 | }, 912 | "component-emitter": { 913 | "version": "1.3.0", 914 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", 915 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" 916 | }, 917 | "concat-map": { 918 | "version": "0.0.1", 919 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 920 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 921 | }, 922 | "content-disposition": { 923 | "version": "0.5.4", 924 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 925 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 926 | "requires": { 927 | "safe-buffer": "5.2.1" 928 | } 929 | }, 930 | "content-type": { 931 | "version": "1.0.4", 932 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 933 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 934 | }, 935 | "cookie": { 936 | "version": "0.4.2", 937 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", 938 | "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" 939 | }, 940 | "cookie-signature": { 941 | "version": "1.0.6", 942 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 943 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 944 | }, 945 | "cors": { 946 | "version": "2.8.5", 947 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 948 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 949 | "requires": { 950 | "object-assign": "^4", 951 | "vary": "^1" 952 | } 953 | }, 954 | "debug": { 955 | "version": "2.6.9", 956 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 957 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 958 | "requires": { 959 | "ms": "2.0.0" 960 | } 961 | }, 962 | "depd": { 963 | "version": "1.1.2", 964 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 965 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 966 | }, 967 | "destroy": { 968 | "version": "1.0.4", 969 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 970 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 971 | }, 972 | "ee-first": { 973 | "version": "1.1.1", 974 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 975 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 976 | }, 977 | "encodeurl": { 978 | "version": "1.0.2", 979 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 980 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 981 | }, 982 | "engine.io": { 983 | "version": "6.1.3", 984 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.3.tgz", 985 | "integrity": "sha512-rqs60YwkvWTLLnfazqgZqLa/aKo+9cueVfEi/dZ8PyGyaf8TLOxj++4QMIgeG3Gn0AhrWiFXvghsoY9L9h25GA==", 986 | "requires": { 987 | "@types/cookie": "^0.4.1", 988 | "@types/cors": "^2.8.12", 989 | "@types/node": ">=10.0.0", 990 | "accepts": "~1.3.4", 991 | "base64id": "2.0.0", 992 | "cookie": "~0.4.1", 993 | "cors": "~2.8.5", 994 | "debug": "~4.3.1", 995 | "engine.io-parser": "~5.0.3", 996 | "ws": "~8.2.3" 997 | }, 998 | "dependencies": { 999 | "debug": { 1000 | "version": "4.3.3", 1001 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 1002 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 1003 | "requires": { 1004 | "ms": "2.1.2" 1005 | } 1006 | }, 1007 | "ms": { 1008 | "version": "2.1.2", 1009 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1010 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1011 | } 1012 | } 1013 | }, 1014 | "engine.io-parser": { 1015 | "version": "5.0.3", 1016 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz", 1017 | "integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==", 1018 | "requires": { 1019 | "@socket.io/base64-arraybuffer": "~1.0.2" 1020 | } 1021 | }, 1022 | "escape-html": { 1023 | "version": "1.0.3", 1024 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 1025 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 1026 | }, 1027 | "etag": { 1028 | "version": "1.8.1", 1029 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 1030 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 1031 | }, 1032 | "express": { 1033 | "version": "4.17.3", 1034 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", 1035 | "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", 1036 | "requires": { 1037 | "accepts": "~1.3.8", 1038 | "array-flatten": "1.1.1", 1039 | "body-parser": "1.19.2", 1040 | "content-disposition": "0.5.4", 1041 | "content-type": "~1.0.4", 1042 | "cookie": "0.4.2", 1043 | "cookie-signature": "1.0.6", 1044 | "debug": "2.6.9", 1045 | "depd": "~1.1.2", 1046 | "encodeurl": "~1.0.2", 1047 | "escape-html": "~1.0.3", 1048 | "etag": "~1.8.1", 1049 | "finalhandler": "~1.1.2", 1050 | "fresh": "0.5.2", 1051 | "merge-descriptors": "1.0.1", 1052 | "methods": "~1.1.2", 1053 | "on-finished": "~2.3.0", 1054 | "parseurl": "~1.3.3", 1055 | "path-to-regexp": "0.1.7", 1056 | "proxy-addr": "~2.0.7", 1057 | "qs": "6.9.7", 1058 | "range-parser": "~1.2.1", 1059 | "safe-buffer": "5.2.1", 1060 | "send": "0.17.2", 1061 | "serve-static": "1.14.2", 1062 | "setprototypeof": "1.2.0", 1063 | "statuses": "~1.5.0", 1064 | "type-is": "~1.6.18", 1065 | "utils-merge": "1.0.1", 1066 | "vary": "~1.1.2" 1067 | } 1068 | }, 1069 | "finalhandler": { 1070 | "version": "1.1.2", 1071 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 1072 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 1073 | "requires": { 1074 | "debug": "2.6.9", 1075 | "encodeurl": "~1.0.2", 1076 | "escape-html": "~1.0.3", 1077 | "on-finished": "~2.3.0", 1078 | "parseurl": "~1.3.3", 1079 | "statuses": "~1.5.0", 1080 | "unpipe": "~1.0.0" 1081 | } 1082 | }, 1083 | "forwarded": { 1084 | "version": "0.2.0", 1085 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 1086 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 1087 | }, 1088 | "fresh": { 1089 | "version": "0.5.2", 1090 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1091 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 1092 | }, 1093 | "fs.realpath": { 1094 | "version": "1.0.0", 1095 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1096 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 1097 | }, 1098 | "glob": { 1099 | "version": "7.2.0", 1100 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 1101 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 1102 | "requires": { 1103 | "fs.realpath": "^1.0.0", 1104 | "inflight": "^1.0.4", 1105 | "inherits": "2", 1106 | "minimatch": "^3.0.4", 1107 | "once": "^1.3.0", 1108 | "path-is-absolute": "^1.0.0" 1109 | } 1110 | }, 1111 | "http-errors": { 1112 | "version": "1.8.1", 1113 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", 1114 | "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", 1115 | "requires": { 1116 | "depd": "~1.1.2", 1117 | "inherits": "2.0.4", 1118 | "setprototypeof": "1.2.0", 1119 | "statuses": ">= 1.5.0 < 2", 1120 | "toidentifier": "1.0.1" 1121 | } 1122 | }, 1123 | "iconv-lite": { 1124 | "version": "0.4.24", 1125 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1126 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1127 | "requires": { 1128 | "safer-buffer": ">= 2.1.2 < 3" 1129 | } 1130 | }, 1131 | "inflight": { 1132 | "version": "1.0.6", 1133 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1134 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1135 | "requires": { 1136 | "once": "^1.3.0", 1137 | "wrappy": "1" 1138 | } 1139 | }, 1140 | "inherits": { 1141 | "version": "2.0.4", 1142 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1143 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1144 | }, 1145 | "ipaddr.js": { 1146 | "version": "1.9.1", 1147 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 1148 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 1149 | }, 1150 | "media-typer": { 1151 | "version": "0.3.0", 1152 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1153 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 1154 | }, 1155 | "merge-descriptors": { 1156 | "version": "1.0.1", 1157 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1158 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 1159 | }, 1160 | "methods": { 1161 | "version": "1.1.2", 1162 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1163 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 1164 | }, 1165 | "mime": { 1166 | "version": "1.6.0", 1167 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1168 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 1169 | }, 1170 | "mime-db": { 1171 | "version": "1.52.0", 1172 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1173 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 1174 | }, 1175 | "mime-types": { 1176 | "version": "2.1.35", 1177 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1178 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1179 | "requires": { 1180 | "mime-db": "1.52.0" 1181 | } 1182 | }, 1183 | "minimatch": { 1184 | "version": "3.1.2", 1185 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1186 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1187 | "requires": { 1188 | "brace-expansion": "^1.1.7" 1189 | } 1190 | }, 1191 | "ms": { 1192 | "version": "2.0.0", 1193 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1194 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1195 | }, 1196 | "negotiator": { 1197 | "version": "0.6.3", 1198 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1199 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 1200 | }, 1201 | "object-assign": { 1202 | "version": "4.1.1", 1203 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1204 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1205 | }, 1206 | "on-finished": { 1207 | "version": "2.3.0", 1208 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1209 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1210 | "requires": { 1211 | "ee-first": "1.1.1" 1212 | } 1213 | }, 1214 | "once": { 1215 | "version": "1.4.0", 1216 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1217 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1218 | "requires": { 1219 | "wrappy": "1" 1220 | } 1221 | }, 1222 | "parseurl": { 1223 | "version": "1.3.3", 1224 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1225 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 1226 | }, 1227 | "path-is-absolute": { 1228 | "version": "1.0.1", 1229 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1230 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 1231 | }, 1232 | "path-to-regexp": { 1233 | "version": "0.1.7", 1234 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1235 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 1236 | }, 1237 | "proxy-addr": { 1238 | "version": "2.0.7", 1239 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1240 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1241 | "requires": { 1242 | "forwarded": "0.2.0", 1243 | "ipaddr.js": "1.9.1" 1244 | } 1245 | }, 1246 | "qs": { 1247 | "version": "6.9.7", 1248 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", 1249 | "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" 1250 | }, 1251 | "range-parser": { 1252 | "version": "1.2.1", 1253 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1254 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 1255 | }, 1256 | "raw-body": { 1257 | "version": "2.4.3", 1258 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", 1259 | "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", 1260 | "requires": { 1261 | "bytes": "3.1.2", 1262 | "http-errors": "1.8.1", 1263 | "iconv-lite": "0.4.24", 1264 | "unpipe": "1.0.0" 1265 | } 1266 | }, 1267 | "safe-buffer": { 1268 | "version": "5.2.1", 1269 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1270 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 1271 | }, 1272 | "safer-buffer": { 1273 | "version": "2.1.2", 1274 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1275 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1276 | }, 1277 | "send": { 1278 | "version": "0.17.2", 1279 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", 1280 | "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", 1281 | "requires": { 1282 | "debug": "2.6.9", 1283 | "depd": "~1.1.2", 1284 | "destroy": "~1.0.4", 1285 | "encodeurl": "~1.0.2", 1286 | "escape-html": "~1.0.3", 1287 | "etag": "~1.8.1", 1288 | "fresh": "0.5.2", 1289 | "http-errors": "1.8.1", 1290 | "mime": "1.6.0", 1291 | "ms": "2.1.3", 1292 | "on-finished": "~2.3.0", 1293 | "range-parser": "~1.2.1", 1294 | "statuses": "~1.5.0" 1295 | }, 1296 | "dependencies": { 1297 | "ms": { 1298 | "version": "2.1.3", 1299 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1300 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1301 | } 1302 | } 1303 | }, 1304 | "serve-static": { 1305 | "version": "1.14.2", 1306 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", 1307 | "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", 1308 | "requires": { 1309 | "encodeurl": "~1.0.2", 1310 | "escape-html": "~1.0.3", 1311 | "parseurl": "~1.3.3", 1312 | "send": "0.17.2" 1313 | } 1314 | }, 1315 | "setprototypeof": { 1316 | "version": "1.2.0", 1317 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1318 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 1319 | }, 1320 | "socket.io": { 1321 | "version": "4.4.1", 1322 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz", 1323 | "integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==", 1324 | "requires": { 1325 | "accepts": "~1.3.4", 1326 | "base64id": "~2.0.0", 1327 | "debug": "~4.3.2", 1328 | "engine.io": "~6.1.0", 1329 | "socket.io-adapter": "~2.3.3", 1330 | "socket.io-parser": "~4.0.4" 1331 | }, 1332 | "dependencies": { 1333 | "debug": { 1334 | "version": "4.3.3", 1335 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 1336 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 1337 | "requires": { 1338 | "ms": "2.1.2" 1339 | } 1340 | }, 1341 | "ms": { 1342 | "version": "2.1.2", 1343 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1344 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1345 | } 1346 | } 1347 | }, 1348 | "socket.io-adapter": { 1349 | "version": "2.3.3", 1350 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz", 1351 | "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==" 1352 | }, 1353 | "socket.io-parser": { 1354 | "version": "4.0.4", 1355 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", 1356 | "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", 1357 | "requires": { 1358 | "@types/component-emitter": "^1.2.10", 1359 | "component-emitter": "~1.3.0", 1360 | "debug": "~4.3.1" 1361 | }, 1362 | "dependencies": { 1363 | "debug": { 1364 | "version": "4.3.3", 1365 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 1366 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 1367 | "requires": { 1368 | "ms": "2.1.2" 1369 | } 1370 | }, 1371 | "ms": { 1372 | "version": "2.1.2", 1373 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1374 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1375 | } 1376 | } 1377 | }, 1378 | "statuses": { 1379 | "version": "1.5.0", 1380 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1381 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 1382 | }, 1383 | "toidentifier": { 1384 | "version": "1.0.1", 1385 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1386 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 1387 | }, 1388 | "type-is": { 1389 | "version": "1.6.18", 1390 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1391 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1392 | "requires": { 1393 | "media-typer": "0.3.0", 1394 | "mime-types": "~2.1.24" 1395 | } 1396 | }, 1397 | "unpipe": { 1398 | "version": "1.0.0", 1399 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1400 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1401 | }, 1402 | "utils-merge": { 1403 | "version": "1.0.1", 1404 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1405 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 1406 | }, 1407 | "vary": { 1408 | "version": "1.1.2", 1409 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1410 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1411 | }, 1412 | "wrappy": { 1413 | "version": "1.0.2", 1414 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1415 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1416 | }, 1417 | "ws": { 1418 | "version": "8.2.3", 1419 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", 1420 | "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", 1421 | "requires": {} 1422 | } 1423 | } 1424 | } 1425 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "artnet-weblight", 3 | "version": "1.0.2", 4 | "author": "Michael Träger", 5 | "description": "Artnet-Weblight Device Server - Use your Browser as an Artnet lighting device!", 6 | "url": "https://github.com/mtraeger/artnet-weblight", 7 | "main": "weblight.js", 8 | "bin": { 9 | "weblight": "./weblight.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/mtraeger/artnet-weblight.git" 14 | }, 15 | "keywords": [ 16 | "artnet", 17 | "art-net", 18 | "server", 19 | "dmx", 20 | "rgb" 21 | ], 22 | "dependencies": { 23 | "artnet-node": "0.1.x", 24 | "commander": "^2.18.0", 25 | "express": "^4.16.3", 26 | "glob": "^7.1.3", 27 | "socket.io": "^4.4.1" 28 | }, 29 | "license": "MIT" 30 | } 31 | -------------------------------------------------------------------------------- /weblight.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | "use strict"; 3 | 4 | // const artnet = require('artnet-node').Server; 5 | const artnet = require('./lib/artnet_server'); // NPM-Version of artnet-lib is buggy... 6 | const express = require('express'); 7 | const app = express(); 8 | const http = require('http').Server(app); 9 | const io = require('socket.io')(http); 10 | const glob = require("glob"); 11 | 12 | 13 | const config = {}; 14 | config.artnet = {}; 15 | config.artnet.port = 6454; 16 | config.artnet.universe = 0; 17 | 18 | 19 | const buffer = new Array(512).fill(0); //TODO maybe node buffer? 20 | 21 | 22 | http.listen(3000, function () { 23 | console.log('Web listening on *:3000'); 24 | }); 25 | 26 | 27 | console.log("Starting Artnet server on port " + config.artnet.port) 28 | const srv = artnet.listen(config.artnet.port, function (msg, peer) { 29 | // console.log("-----------------"); 30 | // console.log("From: " + peer.address); 31 | // console.log("Sequence: " + msg.sequence); 32 | // console.log("Physical: " + msg.physical); 33 | // console.log("Universe: " + msg.universe); 34 | // console.log("Length: " + msg.length); 35 | // console.log("Data: " + msg.data); 36 | // console.log("-----------------"); 37 | 38 | if (msg.universe !== config.artnet.universe) { 39 | console.log("Wrong Universe, aborting msg processing."); 40 | return; 41 | } 42 | 43 | new Array(msg.data.length) 44 | .fill(0) 45 | .map(function (val, index) { 46 | const value = msg.data[index]; //TODO msg.data.readUInt8(i); | buf.readUInt8(index); 47 | 48 | if (buffer[index] === value) { 49 | return; 50 | } 51 | 52 | buffer[index] = value; 53 | 54 | let deviceId = ((index - 5) / 10).toFixed(0); 55 | if (deviceId < 1) deviceId = 0; 56 | updateClient(deviceId); 57 | }); 58 | }); 59 | 60 | 61 | app.get('/js/jquery.js', function (req, res) { 62 | res.sendFile(__dirname + '/js/jquery.js') 63 | }); 64 | 65 | app.get('/css/style.css', function (req, res) { 66 | res.sendFile(__dirname + '/css/style.css') 67 | }); 68 | 69 | app.use('/images', express.static("images")); 70 | 71 | app.get('/frames', function (req, res) { 72 | res.sendFile(__dirname + '/frames.html') 73 | }); 74 | 75 | app.get('/frames/:id', function (req, res) { 76 | res.sendFile(__dirname + '/frames.html') 77 | }); 78 | 79 | app.get('/', function (req, res) { 80 | // Overview Page 81 | const channels = buffer 82 | .map((value, index) => { 83 | const tmp = {}; 84 | tmp[index] = value; 85 | return tmp 86 | }) 87 | .filter((channel, index) => channel[index] > 0) 88 | .map(channels => Object.keys(channels)[0]) 89 | .map(channel => ((channel - 5) / 10).toFixed(0)) 90 | .map(channel => { 91 | if (channel < 1) { 92 | return 0 93 | } 94 | return channel 95 | }); 96 | 97 | const channelSet = new Set(channels); 98 | 99 | let text = "

Artnet Weblight

"; 100 | text += "Devices with channel values > 0:"; 101 | text += "
"; 109 | text += "Show Multiple Frames"; 110 | res.send(text); 111 | }); 112 | 113 | app.get('/:id', function (req, res) { 114 | const channelId = req.params.id * 10; 115 | const channel = channelId + 1; 116 | 117 | if (channel + 10 > 512) { 118 | res.sendStatus(416); 119 | return; 120 | } 121 | 122 | res.sendFile(__dirname + '/index.html'); 123 | 124 | updateClient(req.params.id); 125 | }); 126 | 127 | 128 | io.on('connection', function (socket) { 129 | updateAllClients(); 130 | }); 131 | 132 | 133 | let imageFiles = []; 134 | glob("images/*", {}, function (er, files) { 135 | imageFiles = files; 136 | }); 137 | 138 | 139 | function updateClient(deviceId) { 140 | const deviceNr = deviceId * 10; 141 | 142 | const imageNumber = (buffer[deviceNr + 6] / 10).toFixed(0); 143 | let imagePath = imageFiles[parseInt(imageNumber) - 1]; //TODO improve via name matching 144 | if (!imagePath) imagePath = "none"; 145 | 146 | io.sockets.emit('dev' + deviceId, { 147 | r: buffer[deviceNr + 1], 148 | g: buffer[deviceNr + 2], 149 | b: buffer[deviceNr + 3], 150 | a: (buffer[deviceNr + 0] / 255).toFixed(3), 151 | border: buffer[deviceNr + 4], 152 | blur: buffer[deviceNr + 5], 153 | image: imagePath 154 | }); 155 | } 156 | 157 | 158 | function updateAllClients() { 159 | for (let i = 0; i <= 50; i++) { 160 | updateClient(i); 161 | } 162 | } 163 | --------------------------------------------------------------------------------