├── .gitignore ├── .nvmrc ├── README.md ├── package-lock.json ├── package.json └── src ├── bluetooth.js ├── cli.js ├── divoom.js └── util.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v16.16.0 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # divoom-control 2 | 3 | A little Node.js project to control Divoom devices, specifically the Pixoo that I have in my office. 4 | 5 | It has a CLI, as well as exported functions that can be accessed programmatically. 6 | 7 | ```text 8 | Commands: 9 | divoom-control get-devices Listed paired Bluetooth devices (note: does not work on linux) 10 | divoom-control display-color Display a static color on the Divoom device. 11 | divoom-control display-custom Display the custom channel on the Divoom device. 12 | divoom-control display-date-time Display the date/time channel on the Divoom device. 13 | divoom-control display-image Display image on the Divoom device (supports JPG, PNG, BMP and GIF incl. animation) 14 | divoom-control set-brightness Set the global brightness of the Divoom device. 15 | divoom-control set-date-time Set the date/time of the Divoom device to now. 16 | ``` 17 | 18 | ## Setup (Linux) 19 | ```text 20 | sudo apt install nodejs npm 21 | sudo apt install build-essential libbluetooth-dev 22 | npm ci 23 | node src/cli.js display-color -a XX:XX:XX:XX:XX:XX -c ff0000 -b 100 24 | ``` 25 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "divoom-control", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "divoom-control", 9 | "version": "1.0.0", 10 | "license": "Apache-2.0", 11 | "dependencies": { 12 | "bluetooth-serial-port": "git+https://github.com/tinyprinter/node-bluetooth-serial-port.git", 13 | "node-divoom-timebox-evo": "^0.3.0", 14 | "yargs": "^17.5.1" 15 | }, 16 | "bin": { 17 | "divoom-control": "src/cli.js" 18 | } 19 | }, 20 | "node_modules/@ctrl/tinycolor": { 21 | "version": "2.6.1", 22 | "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-2.6.1.tgz", 23 | "integrity": "sha512-xKN3lAA+xbNhP+JX3sLhzA65IGiKqun/Yf9jBlZX7Og0SxlCrrqKxqTd6ccn20fv3Cgcvq6KnjPhnmS+v7uAwQ==", 24 | "engines": { 25 | "node": ">=8.0.0" 26 | } 27 | }, 28 | "node_modules/@jimp/bmp": { 29 | "version": "0.6.8", 30 | "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.6.8.tgz", 31 | "integrity": "sha512-uxVgSkI62uAzk5ZazYHEHBehow590WAkLKmDXLzkr/XP/Hv2Fx1T4DKwJ/15IY5ktq5VAhAUWGXTyd8KWFsx7w==", 32 | "dependencies": { 33 | "@jimp/utils": "^0.6.8", 34 | "bmp-js": "^0.1.0", 35 | "core-js": "^2.5.7" 36 | }, 37 | "peerDependencies": { 38 | "@jimp/custom": ">=0.3.5" 39 | } 40 | }, 41 | "node_modules/@jimp/core": { 42 | "version": "0.6.8", 43 | "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.6.8.tgz", 44 | "integrity": "sha512-JOFqBBcSNiDiMZJFr6OJqC6viXj5NVBQISua0eacoYvo4YJtTajOIxC4MqWyUmGrDpRMZBR8QhSsIOwsFrdROA==", 45 | "dependencies": { 46 | "@jimp/utils": "^0.6.8", 47 | "any-base": "^1.1.0", 48 | "buffer": "^5.2.0", 49 | "core-js": "^2.5.7", 50 | "exif-parser": "^0.1.12", 51 | "file-type": "^9.0.0", 52 | "load-bmfont": "^1.3.1", 53 | "mkdirp": "0.5.1", 54 | "phin": "^2.9.1", 55 | "pixelmatch": "^4.0.2", 56 | "tinycolor2": "^1.4.1" 57 | } 58 | }, 59 | "node_modules/@jimp/core/node_modules/file-type": { 60 | "version": "9.0.0", 61 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", 62 | "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==", 63 | "engines": { 64 | "node": ">=6" 65 | } 66 | }, 67 | "node_modules/@jimp/custom": { 68 | "version": "0.6.8", 69 | "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.6.8.tgz", 70 | "integrity": "sha512-FrYlzZRVXP2vuVwd7Nc2dlK+iZk4g6IaT1Ib8Z6vU5Kkwlt83FJIPJ2UUFABf3bF5big0wkk8ZUihWxE4Nzdng==", 71 | "dependencies": { 72 | "@jimp/core": "^0.6.8", 73 | "core-js": "^2.5.7" 74 | } 75 | }, 76 | "node_modules/@jimp/gif": { 77 | "version": "0.6.8", 78 | "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.6.8.tgz", 79 | "integrity": "sha512-yyOlujjQcgz9zkjM5ihZDEppn9d1brJ7jQHP5rAKmqep0G7FU1D0AKcV+Ql18RhuI/CgWs10wAVcrQpmLnu4Yw==", 80 | "dependencies": { 81 | "@jimp/utils": "^0.6.8", 82 | "core-js": "^2.5.7", 83 | "omggif": "^1.0.9" 84 | }, 85 | "peerDependencies": { 86 | "@jimp/custom": ">=0.3.5" 87 | } 88 | }, 89 | "node_modules/@jimp/jpeg": { 90 | "version": "0.6.8", 91 | "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.6.8.tgz", 92 | "integrity": "sha512-rGtXbYpFXAn471qLpTGvhbBMNHJo5KiufN+vC5AWyufntmkt5f0Ox2Cx4ijuBMDtirZchxbMLtrfGjznS4L/ew==", 93 | "dependencies": { 94 | "@jimp/utils": "^0.6.8", 95 | "core-js": "^2.5.7", 96 | "jpeg-js": "^0.3.4" 97 | }, 98 | "peerDependencies": { 99 | "@jimp/custom": ">=0.3.5" 100 | } 101 | }, 102 | "node_modules/@jimp/plugin-blit": { 103 | "version": "0.6.8", 104 | "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.6.8.tgz", 105 | "integrity": "sha512-7Tl6YpKTSpvwQbnGNhsfX2zyl3jRVVopd276Y2hF2zpDz9Bycow7NdfNU/4Nx1jaf96X6uWOtSVINcQ7rGd47w==", 106 | "dependencies": { 107 | "@jimp/utils": "^0.6.8", 108 | "core-js": "^2.5.7" 109 | }, 110 | "peerDependencies": { 111 | "@jimp/custom": ">=0.3.5" 112 | } 113 | }, 114 | "node_modules/@jimp/plugin-blur": { 115 | "version": "0.6.8", 116 | "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.6.8.tgz", 117 | "integrity": "sha512-NpZCMKxXHLDQsX9zPlWtpMA660DQStY6/z8ZetyxCDbqrLe9YCXpeR4MNhdJdABIiwTm1W5FyFF4kp81PHJx3Q==", 118 | "dependencies": { 119 | "@jimp/utils": "^0.6.8", 120 | "core-js": "^2.5.7" 121 | }, 122 | "peerDependencies": { 123 | "@jimp/custom": ">=0.3.5" 124 | } 125 | }, 126 | "node_modules/@jimp/plugin-color": { 127 | "version": "0.6.8", 128 | "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.6.8.tgz", 129 | "integrity": "sha512-jjFyU0zNmGOH2rjzHuOMU4kaia0oo82s/7UYfn5h7OUkmUZTd6Do3ZSK1PiXA7KR+s4B76/Omm6Doh/0SGb7BQ==", 130 | "dependencies": { 131 | "@jimp/utils": "^0.6.8", 132 | "core-js": "^2.5.7", 133 | "tinycolor2": "^1.4.1" 134 | }, 135 | "peerDependencies": { 136 | "@jimp/custom": ">=0.3.5" 137 | } 138 | }, 139 | "node_modules/@jimp/plugin-contain": { 140 | "version": "0.6.8", 141 | "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.6.8.tgz", 142 | "integrity": "sha512-p/P2wCXhAzbmEgXvGsvmxLmbz45feF6VpR4m9suPSOr8PC/i/XvTklTqYEUidYYAft4vHgsYJdS74HKSMnH8lw==", 143 | "dependencies": { 144 | "@jimp/utils": "^0.6.8", 145 | "core-js": "^2.5.7" 146 | }, 147 | "peerDependencies": { 148 | "@jimp/custom": ">=0.3.5", 149 | "@jimp/plugin-blit": ">=0.3.5", 150 | "@jimp/plugin-resize": ">=0.3.5", 151 | "@jimp/plugin-scale": ">=0.3.5" 152 | } 153 | }, 154 | "node_modules/@jimp/plugin-cover": { 155 | "version": "0.6.8", 156 | "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.6.8.tgz", 157 | "integrity": "sha512-2PvWgk+PJfRsfWDI1G8Fpjrsu0ZlpNyZxO2+fqWlVo6y/y2gP4v08FqvbkcqSjNlOu2IDWIFXpgyU0sTINWZLg==", 158 | "dependencies": { 159 | "@jimp/utils": "^0.6.8", 160 | "core-js": "^2.5.7" 161 | }, 162 | "peerDependencies": { 163 | "@jimp/custom": ">=0.3.5", 164 | "@jimp/plugin-crop": ">=0.3.5", 165 | "@jimp/plugin-resize": ">=0.3.5", 166 | "@jimp/plugin-scale": ">=0.3.5" 167 | } 168 | }, 169 | "node_modules/@jimp/plugin-crop": { 170 | "version": "0.6.8", 171 | "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.6.8.tgz", 172 | "integrity": "sha512-CbrcpWE2xxPK1n/JoTXzhRUhP4mO07mTWaSavenCg664oQl/9XCtL+A0FekuNHzIvn4myEqvkiTwN7FsbunS/Q==", 173 | "dependencies": { 174 | "@jimp/utils": "^0.6.8", 175 | "core-js": "^2.5.7" 176 | }, 177 | "peerDependencies": { 178 | "@jimp/custom": ">=0.3.5" 179 | } 180 | }, 181 | "node_modules/@jimp/plugin-displace": { 182 | "version": "0.6.8", 183 | "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.6.8.tgz", 184 | "integrity": "sha512-RmV2bPxoPE6mrPxtYSPtHxm2cGwBQr5a2p+9gH6SPy+eUMrbGjbvjwKNfXWUYD0leML+Pt5XOmAS9pIROmuruQ==", 185 | "dependencies": { 186 | "@jimp/utils": "^0.6.8", 187 | "core-js": "^2.5.7" 188 | }, 189 | "peerDependencies": { 190 | "@jimp/custom": ">=0.3.5" 191 | } 192 | }, 193 | "node_modules/@jimp/plugin-dither": { 194 | "version": "0.6.8", 195 | "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.6.8.tgz", 196 | "integrity": "sha512-x6V/qjxe+xypjpQm7GbiMNqci1EW5UizrcebOhHr8AHijOEqHd2hjXh5f6QIGfrkTFelc4/jzq1UyCsYntqz9Q==", 197 | "dependencies": { 198 | "@jimp/utils": "^0.6.8", 199 | "core-js": "^2.5.7" 200 | }, 201 | "peerDependencies": { 202 | "@jimp/custom": ">=0.3.5" 203 | } 204 | }, 205 | "node_modules/@jimp/plugin-flip": { 206 | "version": "0.6.8", 207 | "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.6.8.tgz", 208 | "integrity": "sha512-4il6Da6G39s9MyWBEee4jztEOUGJ40E6OlPjkMrdpDNvge6hYEAB31BczTYBP/CEY74j4LDSoY5LbcU4kv06yA==", 209 | "dependencies": { 210 | "@jimp/utils": "^0.6.8", 211 | "core-js": "^2.5.7" 212 | }, 213 | "peerDependencies": { 214 | "@jimp/custom": ">=0.3.5", 215 | "@jimp/plugin-rotate": ">=0.3.5" 216 | } 217 | }, 218 | "node_modules/@jimp/plugin-gaussian": { 219 | "version": "0.6.8", 220 | "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.6.8.tgz", 221 | "integrity": "sha512-pVOblmjv7stZjsqloi4YzHVwAPXKGdNaHPhp4KP4vj41qtc6Hxd9z/+VWGYRTunMFac84gUToe0UKIXd6GhoKw==", 222 | "dependencies": { 223 | "@jimp/utils": "^0.6.8", 224 | "core-js": "^2.5.7" 225 | }, 226 | "peerDependencies": { 227 | "@jimp/custom": ">=0.3.5" 228 | } 229 | }, 230 | "node_modules/@jimp/plugin-invert": { 231 | "version": "0.6.8", 232 | "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.6.8.tgz", 233 | "integrity": "sha512-11zuLiXDHr6tFv4U8aieXqNXQEKbDbSBG/h+X62gGTNFpyn8EVPpncHhOqrAFtZUaPibBqMFlNJ15SzwC7ExsQ==", 234 | "dependencies": { 235 | "@jimp/utils": "^0.6.8", 236 | "core-js": "^2.5.7" 237 | }, 238 | "peerDependencies": { 239 | "@jimp/custom": ">=0.3.5" 240 | } 241 | }, 242 | "node_modules/@jimp/plugin-mask": { 243 | "version": "0.6.8", 244 | "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.6.8.tgz", 245 | "integrity": "sha512-hZJ0OiKGJyv7hDSATwJDkunB1Ie80xJnONMgpUuUseteK45YeYNBOiZVUe8vum8QI1UwavgBzcvQ9u4fcgXc9g==", 246 | "dependencies": { 247 | "@jimp/utils": "^0.6.8", 248 | "core-js": "^2.5.7" 249 | }, 250 | "peerDependencies": { 251 | "@jimp/custom": ">=0.3.5" 252 | } 253 | }, 254 | "node_modules/@jimp/plugin-normalize": { 255 | "version": "0.6.8", 256 | "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.6.8.tgz", 257 | "integrity": "sha512-Q4oYhU+sSyTJI7pMZlg9/mYh68ujLfOxXzQGEXuw0sHGoGQs3B0Jw7jmzGa6pIS06Hup5hD2Zuh1ppvMdjJBfQ==", 258 | "dependencies": { 259 | "@jimp/utils": "^0.6.8", 260 | "core-js": "^2.5.7" 261 | }, 262 | "peerDependencies": { 263 | "@jimp/custom": ">=0.3.5" 264 | } 265 | }, 266 | "node_modules/@jimp/plugin-print": { 267 | "version": "0.6.8", 268 | "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.6.8.tgz", 269 | "integrity": "sha512-2aokejGn4Drv1FesnZGqh5KEq0FQtR0drlmtyZrBH+r9cx7hh0Qgf4D1BOTDEgXkfSSngjGRjKKRW/fwOrVXYw==", 270 | "dependencies": { 271 | "@jimp/utils": "^0.6.8", 272 | "core-js": "^2.5.7", 273 | "load-bmfont": "^1.4.0" 274 | }, 275 | "peerDependencies": { 276 | "@jimp/custom": ">=0.3.5", 277 | "@jimp/plugin-blit": ">=0.3.5" 278 | } 279 | }, 280 | "node_modules/@jimp/plugin-resize": { 281 | "version": "0.6.8", 282 | "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.6.8.tgz", 283 | "integrity": "sha512-27nPh8L1YWsxtfmV/+Ub5dOTpXyC0HMF2cu52RQSCYxr+Lm1+23dJF70AF1poUbUe+FWXphwuUxQzjBJza9UoA==", 284 | "dependencies": { 285 | "@jimp/utils": "^0.6.8", 286 | "core-js": "^2.5.7" 287 | }, 288 | "peerDependencies": { 289 | "@jimp/custom": ">=0.3.5" 290 | } 291 | }, 292 | "node_modules/@jimp/plugin-rotate": { 293 | "version": "0.6.8", 294 | "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.6.8.tgz", 295 | "integrity": "sha512-GbjETvL05BDoLdszNUV4Y0yLkHf177MnqGqilA113LIvx9aD0FtUopGXYfRGVvmtTOTouoaGJUc+K6qngvKxww==", 296 | "dependencies": { 297 | "@jimp/utils": "^0.6.8", 298 | "core-js": "^2.5.7" 299 | }, 300 | "peerDependencies": { 301 | "@jimp/custom": ">=0.3.5", 302 | "@jimp/plugin-blit": ">=0.3.5", 303 | "@jimp/plugin-crop": ">=0.3.5", 304 | "@jimp/plugin-resize": ">=0.3.5" 305 | } 306 | }, 307 | "node_modules/@jimp/plugin-scale": { 308 | "version": "0.6.8", 309 | "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.6.8.tgz", 310 | "integrity": "sha512-GzIYWR/oCUK2jAwku23zt19V1ssaEU4pL0x2XsLNKuuJEU6DvEytJyTMXCE7OLG/MpDBQcQclJKHgiyQm5gIOQ==", 311 | "dependencies": { 312 | "@jimp/utils": "^0.6.8", 313 | "core-js": "^2.5.7" 314 | }, 315 | "peerDependencies": { 316 | "@jimp/custom": ">=0.3.5", 317 | "@jimp/plugin-resize": ">=0.3.5" 318 | } 319 | }, 320 | "node_modules/@jimp/plugins": { 321 | "version": "0.6.8", 322 | "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.6.8.tgz", 323 | "integrity": "sha512-fMcTI72Vn/Lz6JftezTURmyP5ml/xGMe0Ljx2KRJ85IWyP33vDmGIUuutFiBEbh2+y7lRT+aTSmjs0QGa/xTmQ==", 324 | "dependencies": { 325 | "@jimp/plugin-blit": "^0.6.8", 326 | "@jimp/plugin-blur": "^0.6.8", 327 | "@jimp/plugin-color": "^0.6.8", 328 | "@jimp/plugin-contain": "^0.6.8", 329 | "@jimp/plugin-cover": "^0.6.8", 330 | "@jimp/plugin-crop": "^0.6.8", 331 | "@jimp/plugin-displace": "^0.6.8", 332 | "@jimp/plugin-dither": "^0.6.8", 333 | "@jimp/plugin-flip": "^0.6.8", 334 | "@jimp/plugin-gaussian": "^0.6.8", 335 | "@jimp/plugin-invert": "^0.6.8", 336 | "@jimp/plugin-mask": "^0.6.8", 337 | "@jimp/plugin-normalize": "^0.6.8", 338 | "@jimp/plugin-print": "^0.6.8", 339 | "@jimp/plugin-resize": "^0.6.8", 340 | "@jimp/plugin-rotate": "^0.6.8", 341 | "@jimp/plugin-scale": "^0.6.8", 342 | "core-js": "^2.5.7", 343 | "timm": "^1.6.1" 344 | }, 345 | "peerDependencies": { 346 | "@jimp/custom": ">=0.3.5" 347 | } 348 | }, 349 | "node_modules/@jimp/png": { 350 | "version": "0.6.8", 351 | "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.6.8.tgz", 352 | "integrity": "sha512-JHHg/BZ7KDtHQrcG+a7fztw45rdf7okL/YwkN4qU5FH7Fcrp41nX5QnRviDtD9hN+GaNC7kvjvcqRAxW25qjew==", 353 | "dependencies": { 354 | "@jimp/utils": "^0.6.8", 355 | "core-js": "^2.5.7", 356 | "pngjs": "^3.3.3" 357 | }, 358 | "peerDependencies": { 359 | "@jimp/custom": ">=0.3.5" 360 | } 361 | }, 362 | "node_modules/@jimp/tiff": { 363 | "version": "0.6.8", 364 | "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.6.8.tgz", 365 | "integrity": "sha512-iWHbxd+0IKWdJyJ0HhoJCGYmtjPBOusz1z1HT/DnpePs/Lo3TO4d9ALXqYfUkyG74ZK5jULZ69KLtwuhuJz1bg==", 366 | "dependencies": { 367 | "core-js": "^2.5.7", 368 | "utif": "^2.0.1" 369 | }, 370 | "peerDependencies": { 371 | "@jimp/custom": ">=0.3.5" 372 | } 373 | }, 374 | "node_modules/@jimp/types": { 375 | "version": "0.6.8", 376 | "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.6.8.tgz", 377 | "integrity": "sha512-vCZ/Cp2osy69VP21XOBACfHI5HeR60Rfd4Jidj4W73UL+HrFWOtyQiJ7hlToyu1vI5mR/NsUQpzyQvz56ADm5A==", 378 | "dependencies": { 379 | "@jimp/bmp": "^0.6.8", 380 | "@jimp/gif": "^0.6.8", 381 | "@jimp/jpeg": "^0.6.8", 382 | "@jimp/png": "^0.6.8", 383 | "@jimp/tiff": "^0.6.8", 384 | "core-js": "^2.5.7", 385 | "timm": "^1.6.1" 386 | }, 387 | "peerDependencies": { 388 | "@jimp/custom": ">=0.3.5" 389 | } 390 | }, 391 | "node_modules/@jimp/utils": { 392 | "version": "0.6.8", 393 | "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.6.8.tgz", 394 | "integrity": "sha512-7RDfxQ2C/rarNG9iso5vmnKQbcvlQjBIlF/p7/uYj72WeZgVCB+5t1fFBKJSU4WhniHX4jUMijK+wYGE3Y3bGw==", 395 | "dependencies": { 396 | "core-js": "^2.5.7" 397 | } 398 | }, 399 | "node_modules/@types/node": { 400 | "version": "12.19.11", 401 | "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.11.tgz", 402 | "integrity": "sha512-bwVfNTFZOrGXyiQ6t4B9sZerMSShWNsGRw8tC5DY1qImUNczS9SjT4G6PnzjCnxsu5Ubj6xjL2lgwddkxtQl5w==" 403 | }, 404 | "node_modules/ansi-regex": { 405 | "version": "5.0.1", 406 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 407 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 408 | "engines": { 409 | "node": ">=8" 410 | } 411 | }, 412 | "node_modules/ansi-styles": { 413 | "version": "4.3.0", 414 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 415 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 416 | "dependencies": { 417 | "color-convert": "^2.0.1" 418 | }, 419 | "engines": { 420 | "node": ">=8" 421 | }, 422 | "funding": { 423 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 424 | } 425 | }, 426 | "node_modules/any-base": { 427 | "version": "1.1.0", 428 | "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", 429 | "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" 430 | }, 431 | "node_modules/base64-js": { 432 | "version": "1.5.1", 433 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 434 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 435 | "funding": [ 436 | { 437 | "type": "github", 438 | "url": "https://github.com/sponsors/feross" 439 | }, 440 | { 441 | "type": "patreon", 442 | "url": "https://www.patreon.com/feross" 443 | }, 444 | { 445 | "type": "consulting", 446 | "url": "https://feross.org/support" 447 | } 448 | ] 449 | }, 450 | "node_modules/bindings": { 451 | "version": "1.5.0", 452 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", 453 | "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", 454 | "dependencies": { 455 | "file-uri-to-path": "1.0.0" 456 | } 457 | }, 458 | "node_modules/bluetooth-serial-port": { 459 | "version": "2.2.7", 460 | "resolved": "git+ssh://git@github.com/tinyprinter/node-bluetooth-serial-port.git#9e431d31fdd6d08f013fd8fe1341feb7b2a5418b", 461 | "integrity": "sha512-GfFw4ZRlThLVuzLil8AgWGR6vVmm8xJYzST0srHFAyM5oNMei9wK9sTmZSyTvmeObOdF1r/9PNzbJYmUH9OqOw==", 462 | "hasInstallScript": true, 463 | "license": "MIT", 464 | "os": [ 465 | "darwin", 466 | "linux", 467 | "win32" 468 | ], 469 | "dependencies": { 470 | "bindings": "1.5.0", 471 | "nan": "latest", 472 | "stable": "^0.1.8" 473 | }, 474 | "engines": { 475 | "node": ">= 10.x", 476 | "npm": ">= 1.1.x" 477 | }, 478 | "optionalDependencies": { 479 | "@types/node": "^14.0.5" 480 | } 481 | }, 482 | "node_modules/bluetooth-serial-port/node_modules/@types/node": { 483 | "version": "14.14.16", 484 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.16.tgz", 485 | "integrity": "sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw==", 486 | "optional": true 487 | }, 488 | "node_modules/bmp-js": { 489 | "version": "0.1.0", 490 | "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", 491 | "integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM=" 492 | }, 493 | "node_modules/buffer": { 494 | "version": "5.7.1", 495 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 496 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 497 | "funding": [ 498 | { 499 | "type": "github", 500 | "url": "https://github.com/sponsors/feross" 501 | }, 502 | { 503 | "type": "patreon", 504 | "url": "https://www.patreon.com/feross" 505 | }, 506 | { 507 | "type": "consulting", 508 | "url": "https://feross.org/support" 509 | } 510 | ], 511 | "dependencies": { 512 | "base64-js": "^1.3.1", 513 | "ieee754": "^1.1.13" 514 | } 515 | }, 516 | "node_modules/buffer-equal": { 517 | "version": "0.0.1", 518 | "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", 519 | "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=", 520 | "engines": { 521 | "node": ">=0.4.0" 522 | } 523 | }, 524 | "node_modules/cliui": { 525 | "version": "7.0.4", 526 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 527 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 528 | "dependencies": { 529 | "string-width": "^4.2.0", 530 | "strip-ansi": "^6.0.0", 531 | "wrap-ansi": "^7.0.0" 532 | } 533 | }, 534 | "node_modules/color-convert": { 535 | "version": "2.0.1", 536 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 537 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 538 | "dependencies": { 539 | "color-name": "~1.1.4" 540 | }, 541 | "engines": { 542 | "node": ">=7.0.0" 543 | } 544 | }, 545 | "node_modules/color-name": { 546 | "version": "1.1.4", 547 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 548 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 549 | }, 550 | "node_modules/core-js": { 551 | "version": "2.6.12", 552 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", 553 | "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", 554 | "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", 555 | "hasInstallScript": true 556 | }, 557 | "node_modules/dom-walk": { 558 | "version": "0.1.2", 559 | "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", 560 | "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" 561 | }, 562 | "node_modules/emoji-regex": { 563 | "version": "8.0.0", 564 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 565 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 566 | }, 567 | "node_modules/escalade": { 568 | "version": "3.1.1", 569 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 570 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 571 | "engines": { 572 | "node": ">=6" 573 | } 574 | }, 575 | "node_modules/exif-parser": { 576 | "version": "0.1.12", 577 | "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", 578 | "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=" 579 | }, 580 | "node_modules/file-type": { 581 | "version": "12.4.2", 582 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-12.4.2.tgz", 583 | "integrity": "sha512-UssQP5ZgIOKelfsaB5CuGAL+Y+q7EmONuiwF3N5HAH0t27rvrttgi6Ra9k/+DVaY9UF6+ybxu5pOXLUdA8N7Vg==", 584 | "engines": { 585 | "node": ">=8" 586 | } 587 | }, 588 | "node_modules/file-uri-to-path": { 589 | "version": "1.0.0", 590 | "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", 591 | "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" 592 | }, 593 | "node_modules/get-caller-file": { 594 | "version": "2.0.5", 595 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 596 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 597 | "engines": { 598 | "node": "6.* || 8.* || >= 10.*" 599 | } 600 | }, 601 | "node_modules/gifwrap": { 602 | "version": "0.9.2", 603 | "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.2.tgz", 604 | "integrity": "sha512-fcIswrPaiCDAyO8xnWvHSZdWChjKXUanKKpAiWWJ/UTkEi/aYKn5+90e7DE820zbEaVR9CE2y4z9bzhQijZ0BA==", 605 | "dependencies": { 606 | "image-q": "^1.1.1", 607 | "omggif": "^1.0.10" 608 | } 609 | }, 610 | "node_modules/global": { 611 | "version": "4.4.0", 612 | "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", 613 | "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", 614 | "dependencies": { 615 | "min-document": "^2.19.0", 616 | "process": "^0.11.10" 617 | } 618 | }, 619 | "node_modules/ieee754": { 620 | "version": "1.2.1", 621 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 622 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 623 | "funding": [ 624 | { 625 | "type": "github", 626 | "url": "https://github.com/sponsors/feross" 627 | }, 628 | { 629 | "type": "patreon", 630 | "url": "https://www.patreon.com/feross" 631 | }, 632 | { 633 | "type": "consulting", 634 | "url": "https://feross.org/support" 635 | } 636 | ] 637 | }, 638 | "node_modules/image-q": { 639 | "version": "1.1.1", 640 | "resolved": "https://registry.npmjs.org/image-q/-/image-q-1.1.1.tgz", 641 | "integrity": "sha1-/IQJlmRGC5DKhi2TALa/u7+/gFY=", 642 | "engines": { 643 | "node": ">=0.9.0" 644 | } 645 | }, 646 | "node_modules/is-fullwidth-code-point": { 647 | "version": "3.0.0", 648 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 649 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 650 | "engines": { 651 | "node": ">=8" 652 | } 653 | }, 654 | "node_modules/is-function": { 655 | "version": "1.0.2", 656 | "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", 657 | "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" 658 | }, 659 | "node_modules/jimp": { 660 | "version": "0.6.8", 661 | "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.6.8.tgz", 662 | "integrity": "sha512-F7emeG7Hp61IM8VFbNvWENLTuHe0ghizWPuP4JS9ujx2r5mCVYEd/zdaz6M2M42ZdN41blxPajLWl9FXo7Mr2Q==", 663 | "dependencies": { 664 | "@jimp/custom": "^0.6.8", 665 | "@jimp/plugins": "^0.6.8", 666 | "@jimp/types": "^0.6.8", 667 | "core-js": "^2.5.7", 668 | "regenerator-runtime": "^0.13.3" 669 | } 670 | }, 671 | "node_modules/jpeg-js": { 672 | "version": "0.3.7", 673 | "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.3.7.tgz", 674 | "integrity": "sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ==" 675 | }, 676 | "node_modules/load-bmfont": { 677 | "version": "1.4.1", 678 | "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz", 679 | "integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==", 680 | "dependencies": { 681 | "buffer-equal": "0.0.1", 682 | "mime": "^1.3.4", 683 | "parse-bmfont-ascii": "^1.0.3", 684 | "parse-bmfont-binary": "^1.0.5", 685 | "parse-bmfont-xml": "^1.1.4", 686 | "phin": "^2.9.1", 687 | "xhr": "^2.0.1", 688 | "xtend": "^4.0.0" 689 | } 690 | }, 691 | "node_modules/mime": { 692 | "version": "1.6.0", 693 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 694 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 695 | "bin": { 696 | "mime": "cli.js" 697 | }, 698 | "engines": { 699 | "node": ">=4" 700 | } 701 | }, 702 | "node_modules/min-document": { 703 | "version": "2.19.0", 704 | "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", 705 | "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", 706 | "dependencies": { 707 | "dom-walk": "^0.1.0" 708 | } 709 | }, 710 | "node_modules/minimist": { 711 | "version": "0.0.8", 712 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 713 | "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==" 714 | }, 715 | "node_modules/mkdirp": { 716 | "version": "0.5.1", 717 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 718 | "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", 719 | "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", 720 | "dependencies": { 721 | "minimist": "0.0.8" 722 | }, 723 | "bin": { 724 | "mkdirp": "bin/cmd.js" 725 | } 726 | }, 727 | "node_modules/nan": { 728 | "version": "2.14.2", 729 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", 730 | "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" 731 | }, 732 | "node_modules/node-divoom-timebox-evo": { 733 | "version": "0.3.0", 734 | "resolved": "https://registry.npmjs.org/node-divoom-timebox-evo/-/node-divoom-timebox-evo-0.3.0.tgz", 735 | "integrity": "sha512-zmFNLeEIAt/NLZLDlzaaHQUFOLg/tnPFoGs0fzY5411hXOZC/NAMft440nJK8G6j2nnx4CbG6UH8+7DbPdSNvg==", 736 | "dependencies": { 737 | "@ctrl/tinycolor": "^2.5.3", 738 | "@types/node": "^12.7.3", 739 | "file-type": "^12.2.0", 740 | "gifwrap": "^0.9.2", 741 | "jimp": "^0.6.4" 742 | } 743 | }, 744 | "node_modules/omggif": { 745 | "version": "1.0.10", 746 | "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", 747 | "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" 748 | }, 749 | "node_modules/pako": { 750 | "version": "1.0.11", 751 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", 752 | "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" 753 | }, 754 | "node_modules/parse-bmfont-ascii": { 755 | "version": "1.0.6", 756 | "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", 757 | "integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=" 758 | }, 759 | "node_modules/parse-bmfont-binary": { 760 | "version": "1.0.6", 761 | "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", 762 | "integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=" 763 | }, 764 | "node_modules/parse-bmfont-xml": { 765 | "version": "1.1.4", 766 | "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", 767 | "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", 768 | "dependencies": { 769 | "xml-parse-from-string": "^1.0.0", 770 | "xml2js": "^0.4.5" 771 | } 772 | }, 773 | "node_modules/parse-headers": { 774 | "version": "2.0.3", 775 | "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", 776 | "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==" 777 | }, 778 | "node_modules/phin": { 779 | "version": "2.9.3", 780 | "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", 781 | "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==" 782 | }, 783 | "node_modules/pixelmatch": { 784 | "version": "4.0.2", 785 | "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", 786 | "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=", 787 | "dependencies": { 788 | "pngjs": "^3.0.0" 789 | }, 790 | "bin": { 791 | "pixelmatch": "bin/pixelmatch" 792 | } 793 | }, 794 | "node_modules/pngjs": { 795 | "version": "3.4.0", 796 | "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", 797 | "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", 798 | "engines": { 799 | "node": ">=4.0.0" 800 | } 801 | }, 802 | "node_modules/process": { 803 | "version": "0.11.10", 804 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", 805 | "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", 806 | "engines": { 807 | "node": ">= 0.6.0" 808 | } 809 | }, 810 | "node_modules/regenerator-runtime": { 811 | "version": "0.13.7", 812 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", 813 | "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" 814 | }, 815 | "node_modules/require-directory": { 816 | "version": "2.1.1", 817 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 818 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 819 | "engines": { 820 | "node": ">=0.10.0" 821 | } 822 | }, 823 | "node_modules/sax": { 824 | "version": "1.2.4", 825 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 826 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" 827 | }, 828 | "node_modules/stable": { 829 | "version": "0.1.8", 830 | "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", 831 | "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", 832 | "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" 833 | }, 834 | "node_modules/string-width": { 835 | "version": "4.2.3", 836 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 837 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 838 | "dependencies": { 839 | "emoji-regex": "^8.0.0", 840 | "is-fullwidth-code-point": "^3.0.0", 841 | "strip-ansi": "^6.0.1" 842 | }, 843 | "engines": { 844 | "node": ">=8" 845 | } 846 | }, 847 | "node_modules/strip-ansi": { 848 | "version": "6.0.1", 849 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 850 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 851 | "dependencies": { 852 | "ansi-regex": "^5.0.1" 853 | }, 854 | "engines": { 855 | "node": ">=8" 856 | } 857 | }, 858 | "node_modules/timm": { 859 | "version": "1.7.1", 860 | "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", 861 | "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==" 862 | }, 863 | "node_modules/tinycolor2": { 864 | "version": "1.4.2", 865 | "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", 866 | "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==", 867 | "engines": { 868 | "node": "*" 869 | } 870 | }, 871 | "node_modules/utif": { 872 | "version": "2.0.1", 873 | "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", 874 | "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==", 875 | "dependencies": { 876 | "pako": "^1.0.5" 877 | } 878 | }, 879 | "node_modules/wrap-ansi": { 880 | "version": "7.0.0", 881 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 882 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 883 | "dependencies": { 884 | "ansi-styles": "^4.0.0", 885 | "string-width": "^4.1.0", 886 | "strip-ansi": "^6.0.0" 887 | }, 888 | "engines": { 889 | "node": ">=10" 890 | }, 891 | "funding": { 892 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 893 | } 894 | }, 895 | "node_modules/xhr": { 896 | "version": "2.6.0", 897 | "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", 898 | "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", 899 | "dependencies": { 900 | "global": "~4.4.0", 901 | "is-function": "^1.0.1", 902 | "parse-headers": "^2.0.0", 903 | "xtend": "^4.0.0" 904 | } 905 | }, 906 | "node_modules/xml-parse-from-string": { 907 | "version": "1.0.1", 908 | "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", 909 | "integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig=" 910 | }, 911 | "node_modules/xml2js": { 912 | "version": "0.4.23", 913 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", 914 | "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", 915 | "dependencies": { 916 | "sax": ">=0.6.0", 917 | "xmlbuilder": "~11.0.0" 918 | }, 919 | "engines": { 920 | "node": ">=4.0.0" 921 | } 922 | }, 923 | "node_modules/xmlbuilder": { 924 | "version": "11.0.1", 925 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 926 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", 927 | "engines": { 928 | "node": ">=4.0" 929 | } 930 | }, 931 | "node_modules/xtend": { 932 | "version": "4.0.2", 933 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 934 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 935 | "engines": { 936 | "node": ">=0.4" 937 | } 938 | }, 939 | "node_modules/y18n": { 940 | "version": "5.0.5", 941 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", 942 | "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", 943 | "engines": { 944 | "node": ">=10" 945 | } 946 | }, 947 | "node_modules/yargs": { 948 | "version": "17.5.1", 949 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", 950 | "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", 951 | "dependencies": { 952 | "cliui": "^7.0.2", 953 | "escalade": "^3.1.1", 954 | "get-caller-file": "^2.0.5", 955 | "require-directory": "^2.1.1", 956 | "string-width": "^4.2.3", 957 | "y18n": "^5.0.5", 958 | "yargs-parser": "^21.0.0" 959 | }, 960 | "engines": { 961 | "node": ">=12" 962 | } 963 | }, 964 | "node_modules/yargs-parser": { 965 | "version": "21.1.1", 966 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", 967 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", 968 | "engines": { 969 | "node": ">=12" 970 | } 971 | } 972 | }, 973 | "dependencies": { 974 | "@ctrl/tinycolor": { 975 | "version": "2.6.1", 976 | "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-2.6.1.tgz", 977 | "integrity": "sha512-xKN3lAA+xbNhP+JX3sLhzA65IGiKqun/Yf9jBlZX7Og0SxlCrrqKxqTd6ccn20fv3Cgcvq6KnjPhnmS+v7uAwQ==" 978 | }, 979 | "@jimp/bmp": { 980 | "version": "0.6.8", 981 | "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.6.8.tgz", 982 | "integrity": "sha512-uxVgSkI62uAzk5ZazYHEHBehow590WAkLKmDXLzkr/XP/Hv2Fx1T4DKwJ/15IY5ktq5VAhAUWGXTyd8KWFsx7w==", 983 | "requires": { 984 | "@jimp/utils": "^0.6.8", 985 | "bmp-js": "^0.1.0", 986 | "core-js": "^2.5.7" 987 | } 988 | }, 989 | "@jimp/core": { 990 | "version": "0.6.8", 991 | "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.6.8.tgz", 992 | "integrity": "sha512-JOFqBBcSNiDiMZJFr6OJqC6viXj5NVBQISua0eacoYvo4YJtTajOIxC4MqWyUmGrDpRMZBR8QhSsIOwsFrdROA==", 993 | "requires": { 994 | "@jimp/utils": "^0.6.8", 995 | "any-base": "^1.1.0", 996 | "buffer": "^5.2.0", 997 | "core-js": "^2.5.7", 998 | "exif-parser": "^0.1.12", 999 | "file-type": "^9.0.0", 1000 | "load-bmfont": "^1.3.1", 1001 | "mkdirp": "0.5.1", 1002 | "phin": "^2.9.1", 1003 | "pixelmatch": "^4.0.2", 1004 | "tinycolor2": "^1.4.1" 1005 | }, 1006 | "dependencies": { 1007 | "file-type": { 1008 | "version": "9.0.0", 1009 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", 1010 | "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==" 1011 | } 1012 | } 1013 | }, 1014 | "@jimp/custom": { 1015 | "version": "0.6.8", 1016 | "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.6.8.tgz", 1017 | "integrity": "sha512-FrYlzZRVXP2vuVwd7Nc2dlK+iZk4g6IaT1Ib8Z6vU5Kkwlt83FJIPJ2UUFABf3bF5big0wkk8ZUihWxE4Nzdng==", 1018 | "requires": { 1019 | "@jimp/core": "^0.6.8", 1020 | "core-js": "^2.5.7" 1021 | } 1022 | }, 1023 | "@jimp/gif": { 1024 | "version": "0.6.8", 1025 | "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.6.8.tgz", 1026 | "integrity": "sha512-yyOlujjQcgz9zkjM5ihZDEppn9d1brJ7jQHP5rAKmqep0G7FU1D0AKcV+Ql18RhuI/CgWs10wAVcrQpmLnu4Yw==", 1027 | "requires": { 1028 | "@jimp/utils": "^0.6.8", 1029 | "core-js": "^2.5.7", 1030 | "omggif": "^1.0.9" 1031 | } 1032 | }, 1033 | "@jimp/jpeg": { 1034 | "version": "0.6.8", 1035 | "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.6.8.tgz", 1036 | "integrity": "sha512-rGtXbYpFXAn471qLpTGvhbBMNHJo5KiufN+vC5AWyufntmkt5f0Ox2Cx4ijuBMDtirZchxbMLtrfGjznS4L/ew==", 1037 | "requires": { 1038 | "@jimp/utils": "^0.6.8", 1039 | "core-js": "^2.5.7", 1040 | "jpeg-js": "^0.3.4" 1041 | } 1042 | }, 1043 | "@jimp/plugin-blit": { 1044 | "version": "0.6.8", 1045 | "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.6.8.tgz", 1046 | "integrity": "sha512-7Tl6YpKTSpvwQbnGNhsfX2zyl3jRVVopd276Y2hF2zpDz9Bycow7NdfNU/4Nx1jaf96X6uWOtSVINcQ7rGd47w==", 1047 | "requires": { 1048 | "@jimp/utils": "^0.6.8", 1049 | "core-js": "^2.5.7" 1050 | } 1051 | }, 1052 | "@jimp/plugin-blur": { 1053 | "version": "0.6.8", 1054 | "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.6.8.tgz", 1055 | "integrity": "sha512-NpZCMKxXHLDQsX9zPlWtpMA660DQStY6/z8ZetyxCDbqrLe9YCXpeR4MNhdJdABIiwTm1W5FyFF4kp81PHJx3Q==", 1056 | "requires": { 1057 | "@jimp/utils": "^0.6.8", 1058 | "core-js": "^2.5.7" 1059 | } 1060 | }, 1061 | "@jimp/plugin-color": { 1062 | "version": "0.6.8", 1063 | "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.6.8.tgz", 1064 | "integrity": "sha512-jjFyU0zNmGOH2rjzHuOMU4kaia0oo82s/7UYfn5h7OUkmUZTd6Do3ZSK1PiXA7KR+s4B76/Omm6Doh/0SGb7BQ==", 1065 | "requires": { 1066 | "@jimp/utils": "^0.6.8", 1067 | "core-js": "^2.5.7", 1068 | "tinycolor2": "^1.4.1" 1069 | } 1070 | }, 1071 | "@jimp/plugin-contain": { 1072 | "version": "0.6.8", 1073 | "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.6.8.tgz", 1074 | "integrity": "sha512-p/P2wCXhAzbmEgXvGsvmxLmbz45feF6VpR4m9suPSOr8PC/i/XvTklTqYEUidYYAft4vHgsYJdS74HKSMnH8lw==", 1075 | "requires": { 1076 | "@jimp/utils": "^0.6.8", 1077 | "core-js": "^2.5.7" 1078 | } 1079 | }, 1080 | "@jimp/plugin-cover": { 1081 | "version": "0.6.8", 1082 | "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.6.8.tgz", 1083 | "integrity": "sha512-2PvWgk+PJfRsfWDI1G8Fpjrsu0ZlpNyZxO2+fqWlVo6y/y2gP4v08FqvbkcqSjNlOu2IDWIFXpgyU0sTINWZLg==", 1084 | "requires": { 1085 | "@jimp/utils": "^0.6.8", 1086 | "core-js": "^2.5.7" 1087 | } 1088 | }, 1089 | "@jimp/plugin-crop": { 1090 | "version": "0.6.8", 1091 | "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.6.8.tgz", 1092 | "integrity": "sha512-CbrcpWE2xxPK1n/JoTXzhRUhP4mO07mTWaSavenCg664oQl/9XCtL+A0FekuNHzIvn4myEqvkiTwN7FsbunS/Q==", 1093 | "requires": { 1094 | "@jimp/utils": "^0.6.8", 1095 | "core-js": "^2.5.7" 1096 | } 1097 | }, 1098 | "@jimp/plugin-displace": { 1099 | "version": "0.6.8", 1100 | "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.6.8.tgz", 1101 | "integrity": "sha512-RmV2bPxoPE6mrPxtYSPtHxm2cGwBQr5a2p+9gH6SPy+eUMrbGjbvjwKNfXWUYD0leML+Pt5XOmAS9pIROmuruQ==", 1102 | "requires": { 1103 | "@jimp/utils": "^0.6.8", 1104 | "core-js": "^2.5.7" 1105 | } 1106 | }, 1107 | "@jimp/plugin-dither": { 1108 | "version": "0.6.8", 1109 | "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.6.8.tgz", 1110 | "integrity": "sha512-x6V/qjxe+xypjpQm7GbiMNqci1EW5UizrcebOhHr8AHijOEqHd2hjXh5f6QIGfrkTFelc4/jzq1UyCsYntqz9Q==", 1111 | "requires": { 1112 | "@jimp/utils": "^0.6.8", 1113 | "core-js": "^2.5.7" 1114 | } 1115 | }, 1116 | "@jimp/plugin-flip": { 1117 | "version": "0.6.8", 1118 | "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.6.8.tgz", 1119 | "integrity": "sha512-4il6Da6G39s9MyWBEee4jztEOUGJ40E6OlPjkMrdpDNvge6hYEAB31BczTYBP/CEY74j4LDSoY5LbcU4kv06yA==", 1120 | "requires": { 1121 | "@jimp/utils": "^0.6.8", 1122 | "core-js": "^2.5.7" 1123 | } 1124 | }, 1125 | "@jimp/plugin-gaussian": { 1126 | "version": "0.6.8", 1127 | "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.6.8.tgz", 1128 | "integrity": "sha512-pVOblmjv7stZjsqloi4YzHVwAPXKGdNaHPhp4KP4vj41qtc6Hxd9z/+VWGYRTunMFac84gUToe0UKIXd6GhoKw==", 1129 | "requires": { 1130 | "@jimp/utils": "^0.6.8", 1131 | "core-js": "^2.5.7" 1132 | } 1133 | }, 1134 | "@jimp/plugin-invert": { 1135 | "version": "0.6.8", 1136 | "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.6.8.tgz", 1137 | "integrity": "sha512-11zuLiXDHr6tFv4U8aieXqNXQEKbDbSBG/h+X62gGTNFpyn8EVPpncHhOqrAFtZUaPibBqMFlNJ15SzwC7ExsQ==", 1138 | "requires": { 1139 | "@jimp/utils": "^0.6.8", 1140 | "core-js": "^2.5.7" 1141 | } 1142 | }, 1143 | "@jimp/plugin-mask": { 1144 | "version": "0.6.8", 1145 | "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.6.8.tgz", 1146 | "integrity": "sha512-hZJ0OiKGJyv7hDSATwJDkunB1Ie80xJnONMgpUuUseteK45YeYNBOiZVUe8vum8QI1UwavgBzcvQ9u4fcgXc9g==", 1147 | "requires": { 1148 | "@jimp/utils": "^0.6.8", 1149 | "core-js": "^2.5.7" 1150 | } 1151 | }, 1152 | "@jimp/plugin-normalize": { 1153 | "version": "0.6.8", 1154 | "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.6.8.tgz", 1155 | "integrity": "sha512-Q4oYhU+sSyTJI7pMZlg9/mYh68ujLfOxXzQGEXuw0sHGoGQs3B0Jw7jmzGa6pIS06Hup5hD2Zuh1ppvMdjJBfQ==", 1156 | "requires": { 1157 | "@jimp/utils": "^0.6.8", 1158 | "core-js": "^2.5.7" 1159 | } 1160 | }, 1161 | "@jimp/plugin-print": { 1162 | "version": "0.6.8", 1163 | "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.6.8.tgz", 1164 | "integrity": "sha512-2aokejGn4Drv1FesnZGqh5KEq0FQtR0drlmtyZrBH+r9cx7hh0Qgf4D1BOTDEgXkfSSngjGRjKKRW/fwOrVXYw==", 1165 | "requires": { 1166 | "@jimp/utils": "^0.6.8", 1167 | "core-js": "^2.5.7", 1168 | "load-bmfont": "^1.4.0" 1169 | } 1170 | }, 1171 | "@jimp/plugin-resize": { 1172 | "version": "0.6.8", 1173 | "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.6.8.tgz", 1174 | "integrity": "sha512-27nPh8L1YWsxtfmV/+Ub5dOTpXyC0HMF2cu52RQSCYxr+Lm1+23dJF70AF1poUbUe+FWXphwuUxQzjBJza9UoA==", 1175 | "requires": { 1176 | "@jimp/utils": "^0.6.8", 1177 | "core-js": "^2.5.7" 1178 | } 1179 | }, 1180 | "@jimp/plugin-rotate": { 1181 | "version": "0.6.8", 1182 | "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.6.8.tgz", 1183 | "integrity": "sha512-GbjETvL05BDoLdszNUV4Y0yLkHf177MnqGqilA113LIvx9aD0FtUopGXYfRGVvmtTOTouoaGJUc+K6qngvKxww==", 1184 | "requires": { 1185 | "@jimp/utils": "^0.6.8", 1186 | "core-js": "^2.5.7" 1187 | } 1188 | }, 1189 | "@jimp/plugin-scale": { 1190 | "version": "0.6.8", 1191 | "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.6.8.tgz", 1192 | "integrity": "sha512-GzIYWR/oCUK2jAwku23zt19V1ssaEU4pL0x2XsLNKuuJEU6DvEytJyTMXCE7OLG/MpDBQcQclJKHgiyQm5gIOQ==", 1193 | "requires": { 1194 | "@jimp/utils": "^0.6.8", 1195 | "core-js": "^2.5.7" 1196 | } 1197 | }, 1198 | "@jimp/plugins": { 1199 | "version": "0.6.8", 1200 | "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.6.8.tgz", 1201 | "integrity": "sha512-fMcTI72Vn/Lz6JftezTURmyP5ml/xGMe0Ljx2KRJ85IWyP33vDmGIUuutFiBEbh2+y7lRT+aTSmjs0QGa/xTmQ==", 1202 | "requires": { 1203 | "@jimp/plugin-blit": "^0.6.8", 1204 | "@jimp/plugin-blur": "^0.6.8", 1205 | "@jimp/plugin-color": "^0.6.8", 1206 | "@jimp/plugin-contain": "^0.6.8", 1207 | "@jimp/plugin-cover": "^0.6.8", 1208 | "@jimp/plugin-crop": "^0.6.8", 1209 | "@jimp/plugin-displace": "^0.6.8", 1210 | "@jimp/plugin-dither": "^0.6.8", 1211 | "@jimp/plugin-flip": "^0.6.8", 1212 | "@jimp/plugin-gaussian": "^0.6.8", 1213 | "@jimp/plugin-invert": "^0.6.8", 1214 | "@jimp/plugin-mask": "^0.6.8", 1215 | "@jimp/plugin-normalize": "^0.6.8", 1216 | "@jimp/plugin-print": "^0.6.8", 1217 | "@jimp/plugin-resize": "^0.6.8", 1218 | "@jimp/plugin-rotate": "^0.6.8", 1219 | "@jimp/plugin-scale": "^0.6.8", 1220 | "core-js": "^2.5.7", 1221 | "timm": "^1.6.1" 1222 | } 1223 | }, 1224 | "@jimp/png": { 1225 | "version": "0.6.8", 1226 | "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.6.8.tgz", 1227 | "integrity": "sha512-JHHg/BZ7KDtHQrcG+a7fztw45rdf7okL/YwkN4qU5FH7Fcrp41nX5QnRviDtD9hN+GaNC7kvjvcqRAxW25qjew==", 1228 | "requires": { 1229 | "@jimp/utils": "^0.6.8", 1230 | "core-js": "^2.5.7", 1231 | "pngjs": "^3.3.3" 1232 | } 1233 | }, 1234 | "@jimp/tiff": { 1235 | "version": "0.6.8", 1236 | "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.6.8.tgz", 1237 | "integrity": "sha512-iWHbxd+0IKWdJyJ0HhoJCGYmtjPBOusz1z1HT/DnpePs/Lo3TO4d9ALXqYfUkyG74ZK5jULZ69KLtwuhuJz1bg==", 1238 | "requires": { 1239 | "core-js": "^2.5.7", 1240 | "utif": "^2.0.1" 1241 | } 1242 | }, 1243 | "@jimp/types": { 1244 | "version": "0.6.8", 1245 | "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.6.8.tgz", 1246 | "integrity": "sha512-vCZ/Cp2osy69VP21XOBACfHI5HeR60Rfd4Jidj4W73UL+HrFWOtyQiJ7hlToyu1vI5mR/NsUQpzyQvz56ADm5A==", 1247 | "requires": { 1248 | "@jimp/bmp": "^0.6.8", 1249 | "@jimp/gif": "^0.6.8", 1250 | "@jimp/jpeg": "^0.6.8", 1251 | "@jimp/png": "^0.6.8", 1252 | "@jimp/tiff": "^0.6.8", 1253 | "core-js": "^2.5.7", 1254 | "timm": "^1.6.1" 1255 | } 1256 | }, 1257 | "@jimp/utils": { 1258 | "version": "0.6.8", 1259 | "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.6.8.tgz", 1260 | "integrity": "sha512-7RDfxQ2C/rarNG9iso5vmnKQbcvlQjBIlF/p7/uYj72WeZgVCB+5t1fFBKJSU4WhniHX4jUMijK+wYGE3Y3bGw==", 1261 | "requires": { 1262 | "core-js": "^2.5.7" 1263 | } 1264 | }, 1265 | "@types/node": { 1266 | "version": "12.19.11", 1267 | "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.11.tgz", 1268 | "integrity": "sha512-bwVfNTFZOrGXyiQ6t4B9sZerMSShWNsGRw8tC5DY1qImUNczS9SjT4G6PnzjCnxsu5Ubj6xjL2lgwddkxtQl5w==" 1269 | }, 1270 | "ansi-regex": { 1271 | "version": "5.0.1", 1272 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1273 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" 1274 | }, 1275 | "ansi-styles": { 1276 | "version": "4.3.0", 1277 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1278 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1279 | "requires": { 1280 | "color-convert": "^2.0.1" 1281 | } 1282 | }, 1283 | "any-base": { 1284 | "version": "1.1.0", 1285 | "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", 1286 | "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" 1287 | }, 1288 | "base64-js": { 1289 | "version": "1.5.1", 1290 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 1291 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" 1292 | }, 1293 | "bindings": { 1294 | "version": "1.5.0", 1295 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", 1296 | "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", 1297 | "requires": { 1298 | "file-uri-to-path": "1.0.0" 1299 | } 1300 | }, 1301 | "bluetooth-serial-port": { 1302 | "version": "git+ssh://git@github.com/tinyprinter/node-bluetooth-serial-port.git#9e431d31fdd6d08f013fd8fe1341feb7b2a5418b", 1303 | "integrity": "sha512-GfFw4ZRlThLVuzLil8AgWGR6vVmm8xJYzST0srHFAyM5oNMei9wK9sTmZSyTvmeObOdF1r/9PNzbJYmUH9OqOw==", 1304 | "from": "bluetooth-serial-port@git+https://github.com/tinyprinter/node-bluetooth-serial-port.git", 1305 | "requires": { 1306 | "@types/node": "^14.0.5", 1307 | "bindings": "1.5.0", 1308 | "nan": "latest", 1309 | "stable": "^0.1.8" 1310 | }, 1311 | "dependencies": { 1312 | "@types/node": { 1313 | "version": "14.14.16", 1314 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.16.tgz", 1315 | "integrity": "sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw==", 1316 | "optional": true 1317 | } 1318 | } 1319 | }, 1320 | "bmp-js": { 1321 | "version": "0.1.0", 1322 | "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", 1323 | "integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM=" 1324 | }, 1325 | "buffer": { 1326 | "version": "5.7.1", 1327 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 1328 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 1329 | "requires": { 1330 | "base64-js": "^1.3.1", 1331 | "ieee754": "^1.1.13" 1332 | } 1333 | }, 1334 | "buffer-equal": { 1335 | "version": "0.0.1", 1336 | "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", 1337 | "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" 1338 | }, 1339 | "cliui": { 1340 | "version": "7.0.4", 1341 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 1342 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 1343 | "requires": { 1344 | "string-width": "^4.2.0", 1345 | "strip-ansi": "^6.0.0", 1346 | "wrap-ansi": "^7.0.0" 1347 | } 1348 | }, 1349 | "color-convert": { 1350 | "version": "2.0.1", 1351 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1352 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1353 | "requires": { 1354 | "color-name": "~1.1.4" 1355 | } 1356 | }, 1357 | "color-name": { 1358 | "version": "1.1.4", 1359 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1360 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 1361 | }, 1362 | "core-js": { 1363 | "version": "2.6.12", 1364 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", 1365 | "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" 1366 | }, 1367 | "dom-walk": { 1368 | "version": "0.1.2", 1369 | "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", 1370 | "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" 1371 | }, 1372 | "emoji-regex": { 1373 | "version": "8.0.0", 1374 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1375 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 1376 | }, 1377 | "escalade": { 1378 | "version": "3.1.1", 1379 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 1380 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" 1381 | }, 1382 | "exif-parser": { 1383 | "version": "0.1.12", 1384 | "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", 1385 | "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=" 1386 | }, 1387 | "file-type": { 1388 | "version": "12.4.2", 1389 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-12.4.2.tgz", 1390 | "integrity": "sha512-UssQP5ZgIOKelfsaB5CuGAL+Y+q7EmONuiwF3N5HAH0t27rvrttgi6Ra9k/+DVaY9UF6+ybxu5pOXLUdA8N7Vg==" 1391 | }, 1392 | "file-uri-to-path": { 1393 | "version": "1.0.0", 1394 | "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", 1395 | "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" 1396 | }, 1397 | "get-caller-file": { 1398 | "version": "2.0.5", 1399 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 1400 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" 1401 | }, 1402 | "gifwrap": { 1403 | "version": "0.9.2", 1404 | "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.2.tgz", 1405 | "integrity": "sha512-fcIswrPaiCDAyO8xnWvHSZdWChjKXUanKKpAiWWJ/UTkEi/aYKn5+90e7DE820zbEaVR9CE2y4z9bzhQijZ0BA==", 1406 | "requires": { 1407 | "image-q": "^1.1.1", 1408 | "omggif": "^1.0.10" 1409 | } 1410 | }, 1411 | "global": { 1412 | "version": "4.4.0", 1413 | "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", 1414 | "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", 1415 | "requires": { 1416 | "min-document": "^2.19.0", 1417 | "process": "^0.11.10" 1418 | } 1419 | }, 1420 | "ieee754": { 1421 | "version": "1.2.1", 1422 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 1423 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" 1424 | }, 1425 | "image-q": { 1426 | "version": "1.1.1", 1427 | "resolved": "https://registry.npmjs.org/image-q/-/image-q-1.1.1.tgz", 1428 | "integrity": "sha1-/IQJlmRGC5DKhi2TALa/u7+/gFY=" 1429 | }, 1430 | "is-fullwidth-code-point": { 1431 | "version": "3.0.0", 1432 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1433 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" 1434 | }, 1435 | "is-function": { 1436 | "version": "1.0.2", 1437 | "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", 1438 | "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" 1439 | }, 1440 | "jimp": { 1441 | "version": "0.6.8", 1442 | "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.6.8.tgz", 1443 | "integrity": "sha512-F7emeG7Hp61IM8VFbNvWENLTuHe0ghizWPuP4JS9ujx2r5mCVYEd/zdaz6M2M42ZdN41blxPajLWl9FXo7Mr2Q==", 1444 | "requires": { 1445 | "@jimp/custom": "^0.6.8", 1446 | "@jimp/plugins": "^0.6.8", 1447 | "@jimp/types": "^0.6.8", 1448 | "core-js": "^2.5.7", 1449 | "regenerator-runtime": "^0.13.3" 1450 | } 1451 | }, 1452 | "jpeg-js": { 1453 | "version": "0.3.7", 1454 | "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.3.7.tgz", 1455 | "integrity": "sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ==" 1456 | }, 1457 | "load-bmfont": { 1458 | "version": "1.4.1", 1459 | "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz", 1460 | "integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==", 1461 | "requires": { 1462 | "buffer-equal": "0.0.1", 1463 | "mime": "^1.3.4", 1464 | "parse-bmfont-ascii": "^1.0.3", 1465 | "parse-bmfont-binary": "^1.0.5", 1466 | "parse-bmfont-xml": "^1.1.4", 1467 | "phin": "^2.9.1", 1468 | "xhr": "^2.0.1", 1469 | "xtend": "^4.0.0" 1470 | } 1471 | }, 1472 | "mime": { 1473 | "version": "1.6.0", 1474 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1475 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 1476 | }, 1477 | "min-document": { 1478 | "version": "2.19.0", 1479 | "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", 1480 | "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", 1481 | "requires": { 1482 | "dom-walk": "^0.1.0" 1483 | } 1484 | }, 1485 | "minimist": { 1486 | "version": "0.0.8", 1487 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1488 | "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==" 1489 | }, 1490 | "mkdirp": { 1491 | "version": "0.5.1", 1492 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1493 | "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", 1494 | "requires": { 1495 | "minimist": "0.0.8" 1496 | } 1497 | }, 1498 | "nan": { 1499 | "version": "2.14.2", 1500 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", 1501 | "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" 1502 | }, 1503 | "node-divoom-timebox-evo": { 1504 | "version": "0.3.0", 1505 | "resolved": "https://registry.npmjs.org/node-divoom-timebox-evo/-/node-divoom-timebox-evo-0.3.0.tgz", 1506 | "integrity": "sha512-zmFNLeEIAt/NLZLDlzaaHQUFOLg/tnPFoGs0fzY5411hXOZC/NAMft440nJK8G6j2nnx4CbG6UH8+7DbPdSNvg==", 1507 | "requires": { 1508 | "@ctrl/tinycolor": "^2.5.3", 1509 | "@types/node": "^12.7.3", 1510 | "file-type": "^12.2.0", 1511 | "gifwrap": "^0.9.2", 1512 | "jimp": "^0.6.4" 1513 | } 1514 | }, 1515 | "omggif": { 1516 | "version": "1.0.10", 1517 | "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", 1518 | "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" 1519 | }, 1520 | "pako": { 1521 | "version": "1.0.11", 1522 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", 1523 | "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" 1524 | }, 1525 | "parse-bmfont-ascii": { 1526 | "version": "1.0.6", 1527 | "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", 1528 | "integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=" 1529 | }, 1530 | "parse-bmfont-binary": { 1531 | "version": "1.0.6", 1532 | "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", 1533 | "integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=" 1534 | }, 1535 | "parse-bmfont-xml": { 1536 | "version": "1.1.4", 1537 | "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", 1538 | "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", 1539 | "requires": { 1540 | "xml-parse-from-string": "^1.0.0", 1541 | "xml2js": "^0.4.5" 1542 | } 1543 | }, 1544 | "parse-headers": { 1545 | "version": "2.0.3", 1546 | "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", 1547 | "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==" 1548 | }, 1549 | "phin": { 1550 | "version": "2.9.3", 1551 | "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", 1552 | "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==" 1553 | }, 1554 | "pixelmatch": { 1555 | "version": "4.0.2", 1556 | "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", 1557 | "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=", 1558 | "requires": { 1559 | "pngjs": "^3.0.0" 1560 | } 1561 | }, 1562 | "pngjs": { 1563 | "version": "3.4.0", 1564 | "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", 1565 | "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" 1566 | }, 1567 | "process": { 1568 | "version": "0.11.10", 1569 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", 1570 | "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" 1571 | }, 1572 | "regenerator-runtime": { 1573 | "version": "0.13.7", 1574 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", 1575 | "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" 1576 | }, 1577 | "require-directory": { 1578 | "version": "2.1.1", 1579 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1580 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" 1581 | }, 1582 | "sax": { 1583 | "version": "1.2.4", 1584 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 1585 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" 1586 | }, 1587 | "stable": { 1588 | "version": "0.1.8", 1589 | "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", 1590 | "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" 1591 | }, 1592 | "string-width": { 1593 | "version": "4.2.3", 1594 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1595 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1596 | "requires": { 1597 | "emoji-regex": "^8.0.0", 1598 | "is-fullwidth-code-point": "^3.0.0", 1599 | "strip-ansi": "^6.0.1" 1600 | } 1601 | }, 1602 | "strip-ansi": { 1603 | "version": "6.0.1", 1604 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1605 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1606 | "requires": { 1607 | "ansi-regex": "^5.0.1" 1608 | } 1609 | }, 1610 | "timm": { 1611 | "version": "1.7.1", 1612 | "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", 1613 | "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==" 1614 | }, 1615 | "tinycolor2": { 1616 | "version": "1.4.2", 1617 | "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", 1618 | "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==" 1619 | }, 1620 | "utif": { 1621 | "version": "2.0.1", 1622 | "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", 1623 | "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==", 1624 | "requires": { 1625 | "pako": "^1.0.5" 1626 | } 1627 | }, 1628 | "wrap-ansi": { 1629 | "version": "7.0.0", 1630 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 1631 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 1632 | "requires": { 1633 | "ansi-styles": "^4.0.0", 1634 | "string-width": "^4.1.0", 1635 | "strip-ansi": "^6.0.0" 1636 | } 1637 | }, 1638 | "xhr": { 1639 | "version": "2.6.0", 1640 | "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", 1641 | "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", 1642 | "requires": { 1643 | "global": "~4.4.0", 1644 | "is-function": "^1.0.1", 1645 | "parse-headers": "^2.0.0", 1646 | "xtend": "^4.0.0" 1647 | } 1648 | }, 1649 | "xml-parse-from-string": { 1650 | "version": "1.0.1", 1651 | "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", 1652 | "integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig=" 1653 | }, 1654 | "xml2js": { 1655 | "version": "0.4.23", 1656 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", 1657 | "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", 1658 | "requires": { 1659 | "sax": ">=0.6.0", 1660 | "xmlbuilder": "~11.0.0" 1661 | } 1662 | }, 1663 | "xmlbuilder": { 1664 | "version": "11.0.1", 1665 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 1666 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" 1667 | }, 1668 | "xtend": { 1669 | "version": "4.0.2", 1670 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 1671 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" 1672 | }, 1673 | "y18n": { 1674 | "version": "5.0.5", 1675 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", 1676 | "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" 1677 | }, 1678 | "yargs": { 1679 | "version": "17.5.1", 1680 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", 1681 | "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", 1682 | "requires": { 1683 | "cliui": "^7.0.2", 1684 | "escalade": "^3.1.1", 1685 | "get-caller-file": "^2.0.5", 1686 | "require-directory": "^2.1.1", 1687 | "string-width": "^4.2.3", 1688 | "y18n": "^5.0.5", 1689 | "yargs-parser": "^21.0.0" 1690 | } 1691 | }, 1692 | "yargs-parser": { 1693 | "version": "21.1.1", 1694 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", 1695 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" 1696 | } 1697 | } 1698 | } 1699 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "divoom-control", 3 | "version": "1.0.0", 4 | "description": "A little Node.js project to control Divoom devices, specifically the Pixoo that I have in my office.", 5 | "main": "src/divoom.js", 6 | "bin": { 7 | "divoom-control": "src/cli.js" 8 | }, 9 | "author": "Matt (IPv4) Cowley", 10 | "license": "Apache-2.0", 11 | "dependencies": { 12 | "bluetooth-serial-port": "git+https://github.com/tinyprinter/node-bluetooth-serial-port.git", 13 | "node-divoom-timebox-evo": "^0.3.0", 14 | "yargs": "^17.5.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/bluetooth.js: -------------------------------------------------------------------------------- 1 | const btSerial = new (require('bluetooth-serial-port')).BluetoothSerialPort(); 2 | const { sleep } = require('./util'); 3 | 4 | const CONNECT_MAX_ATTEMPTS = 3; 5 | const CONNECT_ATTEMPT_DELAY = 500; 6 | 7 | /** 8 | * Write a buffer of data to the serial bluetooth connection. 9 | * 10 | * @param {Buffer} buffer The data buffer to send. 11 | * @return {Promise} 12 | */ 13 | module.exports.write = buffer => new Promise((resolve, reject) => { 14 | btSerial.write(buffer, (err, bytes) => err ? reject(err) : resolve(bytes)); 15 | }); 16 | 17 | /** 18 | * Connect to the Divoom device. 19 | * 20 | * @param {String} address The bluetooth address of the Divoom device. 21 | * @return {Promise} 22 | */ 23 | module.exports.connect = async address => { 24 | // Attempt to connect to the device 25 | const connectAttempt = () => new Promise((resolve, reject) => { 26 | // Find the device 27 | btSerial.findSerialPortChannel(address, channel => { 28 | // Connect to the device 29 | btSerial.connect(address, channel, function() { 30 | // Log any data we get from the device 31 | btSerial.on('data', buffer => { 32 | console.log(`[DIVOOM]: ${buffer}`); 33 | }); 34 | 35 | // We connected, resolve 36 | resolve('Connected'); 37 | }, () => reject('Cannot connect')); 38 | }, () => reject('Not found')); 39 | }); 40 | 41 | // Track connection attempts 42 | let attempts = 0; 43 | 44 | // Log a connection attempt 45 | const log = msg => console.log(`[LOCAL]: Connection ${attempts}/${CONNECT_MAX_ATTEMPTS}: ${msg}`); 46 | 47 | // Let's try connecting 48 | while (attempts < CONNECT_MAX_ATTEMPTS) { 49 | try { 50 | const res = await connectAttempt(); 51 | log(res); 52 | return res; 53 | } catch (err) { 54 | log(err); 55 | attempts++; 56 | await sleep(CONNECT_ATTEMPT_DELAY); 57 | } 58 | } 59 | 60 | throw new Error('Could not connect'); 61 | }; 62 | 63 | /** 64 | * Get the name and address of each paired Bluetooth device. 65 | * 66 | * @return {Promise} 67 | */ 68 | module.exports.getDevices = () => new Promise(resolve => { 69 | const format = device => `${device.name}: ${device.address.split('-').join(':')}`; 70 | btSerial.listPairedDevices(data => resolve(data.map(device => format(device)))); 71 | }); 72 | 73 | /** 74 | * Close the connection to the Bluetooth device. 75 | */ 76 | module.exports.close = () => btSerial.close(); 77 | -------------------------------------------------------------------------------- /src/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const yargs = require('yargs/yargs'); 4 | const fs = require('fs'); 5 | const { hideBin } = require('yargs/helpers'); 6 | const { getDevices, connect, close } = require('./bluetooth'); 7 | const { displayColor, displayCustom, setBrightness, displayDateTime, setDateTime, displayImage } = require('./divoom'); 8 | 9 | // Define all the CLI commands 10 | const commands = yargs => yargs 11 | .command('get-devices', 'Listed paired Bluetooth devices', () => {}, async () => { 12 | const devices = await getDevices(); 13 | console.log(devices.join('\n')); 14 | }) 15 | .command('display-color', 'Display a static color on the Divoom device.', yargs => { 16 | yargs.option('address', { 17 | alias: 'a', 18 | type: 'string', 19 | description: 'The Bluetooth address of the Divoom device.' 20 | }).option('color', { 21 | alias: 'c', 22 | type: 'string', 23 | description: 'The color to set the display to, a hex string.' 24 | }).option('brightness', { 25 | alias: 'b', 26 | type: 'integer', 27 | description: 'The brightness of the display, ranging 0 - 100.' 28 | }).demandOption(['a', 'c', 'b']); 29 | }, async argv => { 30 | await connect(argv.address); 31 | await displayColor(argv.color, argv.brightness); 32 | close(); 33 | }) 34 | .command('display-custom', 'Display the custom channel on the Divoom device.', yargs => { 35 | yargs.option('address', { 36 | alias: 'a', 37 | type: 'string', 38 | description: 'The Bluetooth address of the Divoom device.' 39 | }).demandOption(['a']); 40 | }, async argv => { 41 | await connect(argv.address); 42 | await displayCustom(); 43 | close(); 44 | }) 45 | .command('display-date-time', 'Display the date/time channel on the Divoom device.', yargs => { 46 | yargs.option('address', { 47 | alias: 'a', 48 | type: 'string', 49 | description: 'The Bluetooth address of the Divoom device.' 50 | }).demandOption(['a']); 51 | }, async argv => { 52 | await connect(argv.address); 53 | await displayDateTime(); 54 | close(); 55 | }) 56 | .command('display-image', 'Display an image on the Divoom device.', yargs => { 57 | yargs.option('address', { 58 | alias: 'a', 59 | type: 'string', 60 | description: 'The Bluetooth address of the Divoom device.' 61 | }).option('filename', { 62 | alias: 'f', 63 | type: 'string', 64 | description: 'The file to display. GIF, PNG, BMP or JPG.' 65 | }).demandOption(['a', 'f']); 66 | }, async argv => { 67 | await connect(argv.address); 68 | await displayImage(fs.realpathSync(argv.filename)); 69 | close(); 70 | }) 71 | .command('set-brightness', 'Set the global brightness of the Divoom device.', yargs => { 72 | yargs.option('address', { 73 | alias: 'a', 74 | type: 'string', 75 | description: 'The Bluetooth address of the Divoom device.' 76 | }).option('brightness', { 77 | alias: 'b', 78 | type: 'integer', 79 | description: 'The brightness of the display, ranging 0 - 100.' 80 | }).demandOption(['a', 'b']); 81 | }, async argv => { 82 | await connect(argv.address); 83 | await setBrightness(argv.brightness); 84 | close(); 85 | }) 86 | .command('set-date-time', 'Set the date/time of the Divoom device to now.', yargs => { 87 | yargs.option('address', { 88 | alias: 'a', 89 | type: 'string', 90 | description: 'The Bluetooth address of the Divoom device.' 91 | }).demandOption(['a']); 92 | }, async argv => { 93 | await connect(argv.address); 94 | await setDateTime(); 95 | close(); 96 | }); 97 | 98 | // Run the CLI interface 99 | const main = () => commands(yargs(hideBin(process.argv))).argv; 100 | 101 | main(); 102 | -------------------------------------------------------------------------------- /src/divoom.js: -------------------------------------------------------------------------------- 1 | const Divoom = require('node-divoom-timebox-evo'); 2 | const { write } = require('./bluetooth'); 3 | 4 | /** 5 | * Display a static color on the Divoom device. 6 | * 7 | * @param {String} color The color to set the display to, a hex string. 8 | * @param {Number} brightness The brightness of the display, ranging 0 - 100. 9 | * 10 | * @return {Promise} 11 | */ 12 | module.exports.displayColor = async (color, brightness) => { 13 | const d = new Divoom.LightningChannel({ color, brightness }); 14 | for (const buffer of d.messages.asBinaryBuffer()) 15 | await write(buffer); 16 | }; 17 | 18 | /** 19 | * Display the custom channel on the Divoom device. 20 | * 21 | * @return {Promise} 22 | */ 23 | module.exports.displayCustom = async () => { 24 | const d = new Divoom.CustomChannel(); 25 | for (const buffer of d.messages.asBinaryBuffer()) 26 | await write(buffer); 27 | }; 28 | 29 | /** 30 | * Display the date/time channel on the Divoom device. 31 | * 32 | * @return {Promise} 33 | */ 34 | module.exports.displayDateTime = async () => { 35 | const d = new Divoom.TimeChannel({}); 36 | for (const buffer of d.messages.asBinaryBuffer()) 37 | await write(buffer); 38 | }; 39 | 40 | /** 41 | * Set the global brightness of the Divoom device. 42 | * 43 | * @param {Number} brightness The brightness of the display, ranging 0 - 100. 44 | * 45 | * @return {Promise} 46 | */ 47 | module.exports.setBrightness = async brightness => { 48 | const d = new Divoom.BrightnessCommand({ brightness }); 49 | for (const buffer of d.messages.asBinaryBuffer()) 50 | await write(buffer); 51 | }; 52 | 53 | /** 54 | * Set the date/time of the Divoom device. 55 | * 56 | * @param {Date} [date] The new date for the device, defaults to now. 57 | * 58 | * @return {Promise} 59 | */ 60 | module.exports.setDateTime = async date => { 61 | date = date === undefined ? new Date() : date; 62 | const d = new Divoom.DateTimeCommand({ date }); 63 | for (const buffer of d.messages.asBinaryBuffer()) 64 | await write(buffer); 65 | }; 66 | 67 | 68 | /** 69 | * Display an image on the Divoom device. 70 | * 71 | * @param {String} filename Filename to read the image from (absolute path) 72 | * 73 | * @return {Promise} 74 | */ 75 | module.exports.displayImage = async (filename) => { 76 | const d = new Divoom.DisplayAnimation(); 77 | const messages = await d.read(filename); 78 | 79 | for (const buffer of messages.asBinaryBuffer()) 80 | await write(buffer); 81 | }; 82 | -------------------------------------------------------------------------------- /src/util.js: -------------------------------------------------------------------------------- 1 | module.exports.sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); 2 | --------------------------------------------------------------------------------