{"_id":"karaoke-eternal","_rev":"51-9af9a1d1876140ceae8521f8113c3b93","name":"karaoke-eternal","dist-tags":{"latest":"2.0.2","beta":"2.0.2-beta.2"},"versions":{"1.0.0":{"name":"karaoke-eternal","version":"1.0.0","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"author":{"name":"RadRoot LLC"},"license":"ISC","_id":"karaoke-eternal@1.0.0","maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"homepage":"https://www.karaoke-eternal.com","bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"bin":{"karaoke-eternal-server":"server/main.js"},"dist":{"shasum":"a16465d8b4f3c2744033f8b238ad9639651ff66f","tarball":"https://registry.npmjs.org/karaoke-eternal/-/karaoke-eternal-1.0.0.tgz","fileCount":79,"integrity":"sha512-8la2b2UhlKu3xOSlNnF4T4+AsU8xQxMezkfaXlJB+aO/U6B6TRaK+vbiS9VL6oDxyh2mOt4Sc8qhFZho1Cx3Ng==","signatures":[{"sig":"MEUCIFWoC8k5WJeaQN/T34jqX2cm8ABu/Dmbxk1Ag0lMx/l2AiEA5B8EV/sykg0RluS2LN58p2iNk0/d0Oylbcwr81B0xDQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":4808272,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJig+VfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmriig//dRrR4yRDZjWzLbfsNGm2esvzjZa/gjebLQRJ1T984JGk408v\r\nkRoHhbkQ6zV8D9fTLdqx1OZVPprN9QqvslbvYsjtTELIzGfycUsXJz2MLgWm\r\nZOZtAE1biDVVDORsEQP2/oCtLMnk0iz3iLDf8YarnnE5Y2sCI02t94UO6PTG\r\n/D+qV2njSPiGkqNLJPZD+/Pg1DGOqQvH8pbOyGll57nUXk9sTldcVPuzd0gq\r\nDp4ub7Upq64UFZkCOoaa6gQbrV2T/5kUGA4/fzxp+tHrPTMh+ASQFFz7ZmyH\r\n9m1FzabMvopK5IfYuQouN/gusEXSCTHgi4PrbDsp8+wthXm9DWDS34JxKXdz\r\n6FnB/yhAe+JcA/ljzfdkOswHDav0Wv53Gpi2tg0dOsdWJNq80uUB0ZuPgjca\r\n1AyQJo6INa8RlfY+ByIFpbErjjjL9TrTPZj8oBvG6S05GmUO/x5ZPTiFI0mA\r\ng6Zro6IBS7wHzEtBj3AULY8f0/E1g/KaykqztZD98f69NamsBSfRQvqfabVR\r\nTacp/EwCbfcipQGzpqlnhz5nuBQ/g/nPYT+InZb17Lj32io2hXWaa0VPkQc3\r\n2P616dYXBai6YYNhwO99/G7ts4vF8YiBqGPh3BrhV5BszraOdAKsOqD5oGTH\r\nsiMGH+Nd1S4l2kLxWSnAS0XlsCSuiS9SFbw=\r\n=tEo1\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./server/main.js","_from":"file:karaoke-eternal-1.0.0.tgz","engines":{"npm":">=8.0.0","node":">=16.0.0"},"scripts":{"dev":"NODE_ENV=development nodemon --ignore build --ignore dist --ignore src -- -p3000","dist":"DEBUG=electron-builder:* electron-builder -c config/electron-builder.config.js","lint":"eslint .","test":"echo \"Error: no test specified\" && exit 1","build":"rimraf build && webpack --config config/webpack.config.js","serve":"node server/main.js","start":"electron . -p 3000","server":"npm run serve","lint:fix":"npm run lint -- --fix","serve:docs":"hugo serve --source docs -b http://$(hostname) --bind 0.0.0.0","install-app-deps":"electron-builder install-app-deps"},"_npmUser":{"name":"radrootllc","email":"hi@radroot.com"},"_resolved":"/Users/brandon/Sites/karaoke-eternal/karaoke-eternal-1.0.0.tgz","_integrity":"sha512-8la2b2UhlKu3xOSlNnF4T4+AsU8xQxMezkfaXlJB+aO/U6B6TRaK+vbiS9VL6oDxyh2mOt4Sc8qhFZho1Cx3Ng==","repository":{"url":"git+https://github.com/bhj/KaraokeEternal.git","type":"git"},"_npmVersion":"8.5.5","description":"Open karaoke party system","directories":{},"productName":"Karaoke Eternal Server","_nodeVersion":"16.15.0","dependencies":{"koa":"^2.13.4","vm2":"^3.9.9","yargs":"^17.5.0","bcrypt":"^5.0.1","rimraf":"^3.0.2","sqlate":"^2.2.0","sqlite":"^4.1.1","sqlite3":"^5.0.8","fs-extra":"^10.1.0","koa-body":"^5.0.0","koa-mount":"^4.0.0","koa-range":"^0.3.0","socket.io":"^4.5.0","koa-logger":"^3.2.1","koa-router":"^10.1.1","koa-static":"^5.0.0","ctx-compose":"^3.0.0","koa-favicon":"^2.1.0","electron-log":"^4.4.7","jsonwebtoken":"^8.5.1","@babel/runtime":"^7.17.9","music-metadata":"^7.12.3","@jcoreio/async-throttle":"^1.4.3"},"_hasShrinkwrap":false,"devDependencies":{"react":"^17.0.2","redux":"^4.2.0","eslint":"^8.15.0","history":"^5.3.0","nodemon":"^2.0.16","webpack":"^5.72.1","electron":"^18.2.3","reselect":"^4.1.5","rc-slider":"^10.0.0","react-dom":"^17.0.2","cdgraphics":"^6.0.0","css-loader":"^6.7.1","fast-fuzzy":"^1.11.1","prop-types":"^15.8.1","screenfull":"^6.0.1","@babel/core":"^7.17.10","butterchurn":"^3.0.0-beta.4","file-loader":"^6.2.0","html-loader":"^3.1.0","react-redux":"^8.0.1","redux-thunk":"^2.4.1","webpack-cli":"^4.9.2","babel-loader":"^8.2.5","react-window":"^1.8.7","react-refresh":"^0.13.0","redux-persist":"^6.0.0","redux-throttle":"^0.1.1","eslint-plugin-n":"^15.2.0","markdown-loader":"^8.0.0","react-swipeable":"^7.0.0","electron-builder":"^23.0.3","modern-normalize":"^1.1.0","react-github-btn":"^1.2.2","react-router-dom":"^6.3.0","socket.io-client":"^4.5.0","@babel/preset-env":"^7.17.10","blueimp-load-image":"^5.16.0","react-flip-toolkit":"^7.0.14","@babel/preset-react":"^7.16.7","butterchurn-presets":"^3.0.0-beta.4","eslint-plugin-react":"^7.29.4","html-webpack-plugin":"^5.5.0","react-beautiful-dnd":"^13.1.0","redux-optimistic-ui":"^3.1.0","use-resize-observer":"^9.0.0","@babel/eslint-parser":"^7.17.0","@babel/eslint-plugin":"^7.17.7","eslint-plugin-import":"^2.26.0","eslint-plugin-promise":"^6.0.0","react-highlight-words":"^0.18.0","eslint-config-standard":"^17.0.0","license-webpack-plugin":"^4.0.2","react-responsive-modal":"^6.2.0","react-transition-group":"^4.4.2","webpack-dev-middleware":"^5.3.1","webpack-hot-middleware":"^2.25.1","webpack-node-externals":"^3.0.0","mini-css-extract-plugin":"^2.6.0","eslint-plugin-react-hooks":"^4.5.0","@babel/plugin-transform-runtime":"^7.17.10","@babel/plugin-syntax-dynamic-import":"^7.8.3","case-sensitive-paths-webpack-plugin":"^2.4.0","@pmmmwh/react-refresh-webpack-plugin":"^0.5.6","@babel/plugin-proposal-class-properties":"^7.16.7","@babel/plugin-proposal-object-rest-spread":"^7.17.3"},"_npmOperationalInternal":{"tmp":"tmp/karaoke-eternal_1.0.0_1652811102744_0.8542886009006019","host":"s3://npm-registry-packages"}},"2.0.0-beta.5":{"name":"karaoke-eternal","version":"2.0.0-beta.5","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"author":{"name":"RadRoot LLC"},"license":"ISC","_id":"karaoke-eternal@2.0.0-beta.5","maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"homepage":"https://www.karaoke-eternal.com","bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"bin":{"karaoke-eternal-server":"build/server/main.js"},"dist":{"shasum":"bfdbeea7ec197fa5ecf35f7ea2a04e8feb06c06a","tarball":"https://registry.npmjs.org/karaoke-eternal/-/karaoke-eternal-2.0.0-beta.5.tgz","fileCount":79,"integrity":"sha512-+L0Hcv1rr9sttFYHXfbEK1OszDdU6E8XUgKvFvYgB3epSjzM07JT79elTA6aGgw9WhUgQnwbrnb7AtLtI2Ptxw==","signatures":[{"sig":"MEUCIDemuXv1ll4SJlaFFLHvWISuyExqmwmCTYMXdaa+aSu3AiEAys2/D2LgQNkLxjhREKpMwJaRo3Si0HhE93pA+qpKoPE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4887740},"main":"./build/server/main.js","type":"module","_from":"file:karaoke-eternal-2.0.0-beta.5.tgz","engines":{"npm":">=11","node":">=24"},"scripts":{"dev":"NODE_ENV=development tsx watch server/main.ts -p 3000","lint":"eslint .","test":"echo \"Error: no test specified\" && exit 1","build":"npm run build:server ; npm run build:client","serve":"node build/server/main.js","server":"npm run serve","lint:fix":"npm run lint -- --fix","serve:docs":"hugo serve --source docs -b http://$(hostname) --bind 0.0.0.0","build:client":"webpack --config config/webpack.config.js","build:server":"rm -rf build/server ; tsc -p config/tsconfig.server.json --noEmitOnError false ; mkdir -p build/server/lib ; cp -R server/lib/schemas build/server/lib/"},"_npmUser":{"name":"radrootllc","email":"hi@radroot.com"},"_resolved":"/Users/brandon/Sites/KaraokeEternal/karaoke-eternal-2.0.0-beta.5.tgz","overrides":{"is-generator-function":"1.0.10","get-generator-function":"1.0.10"},"_integrity":"sha512-+L0Hcv1rr9sttFYHXfbEK1OszDdU6E8XUgKvFvYgB3epSjzM07JT79elTA6aGgw9WhUgQnwbrnb7AtLtI2Ptxw==","repository":{"url":"git+https://github.com/bhj/KaraokeEternal.git","type":"git"},"_npmVersion":"11.6.2","description":"Open karaoke party system","directories":{},"productName":"Karaoke Eternal Server","_nodeVersion":"24.11.1","dependencies":{"koa":"^2.16.3","json5":"^2.2.3","yargs":"^18.0.0","bcrypt":"^5.1.1","json-e":"^4.8.0","sqlate":"^2.2.0","sqlite":"^5.1.1","sqlite3":"^5.1.7","unzipit":"^1.4.3","fs-extra":"^11.3.2","koa-body":"^6.0.1","koa-mount":"^4.2.0","koa-range":"^0.3.0","socket.io":"^4.8.1","koa-logger":"^3.2.1","koa-static":"^5.0.0","@koa/router":"^13.1.1","ctx-compose":"^3.0.0","koa-favicon":"^2.1.0","electron-log":"^5.4.3","jsonwebtoken":"^9.0.3","@babel/runtime":"^7.28.4","music-metadata":"^11.10.3","@jcoreio/async-throttle":"^1.7.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"^4.21.0","clsx":"^2.1.1","react":"^18.3.1","eslint":"^9.39.1","globals":"^16.5.0","history":"^5.3.0","nodemon":"^3.1.11","webpack":"^5.103.0","rc-slider":"^11.1.9","react-dom":"^18.3.1","cdgraphics":"^7.0.0","css-loader":"^7.1.2","fast-fuzzy":"^1.12.0","prop-types":"^15.8.1","screenfull":"^6.0.2","typescript":"^5.9.3","@babel/core":"^7.28.5","butterchurn":"^3.0.0-beta.4","file-loader":"^6.2.0","html-loader":"^5.1.0","react-redux":"^9.2.0","webpack-cli":"^6.0.1","@types/react":"^19.2.7","@types/yargs":"^17.0.35","babel-loader":"^10.0.0","gl-chromakey":"^2.0.0","react-router":"^7.10.1","react-window":"^2.2.3","@types/bcrypt":"^6.0.0","react-refresh":"^0.18.0","redux-persist":"^6.0.0","redux-throttle":"^0.1.1","use-long-press":"^3.3.0","@types/fs-extra":"^11.0.4","eslint-plugin-n":"^17.23.1","markdown-loader":"^8.0.0","react-swipeable":"^7.0.2","@reduxjs/toolkit":"^2.11.0","@types/koa-mount":"^4.0.5","@types/koa-range":"^0.3.6","@types/react-dom":"^19.2.3","modern-normalize":"^3.0.1","socket.io-client":"^4.8.1","@babel/preset-env":"^7.28.5","@hello-pangea/dnd":"^18.0.1","@types/koa-logger":"^3.1.5","@types/koa-static":"^4.0.4","react-qrcode-logo":"^4.0.0","typescript-eslint":"^8.48.1","@types/koa-favicon":"^2.1.4","@types/koa__router":"^12.0.5","@types/webpack-env":"^1.18.8","blueimp-load-image":"^5.16.0","react-flip-toolkit":"^7.2.4","@babel/preset-react":"^7.28.5","@types/jsonwebtoken":"^9.0.10","@types/react-window":"^1.8.8","butterchurn-presets":"^3.0.0-beta.4","eslint-plugin-react":"^7.37.5","html-webpack-plugin":"^5.6.5","redux-optimistic-ui":"^3.1.0","use-resize-observer":"^9.1.0","@babel/eslint-parser":"^7.28.5","@babel/eslint-plugin":"^7.27.1","eslint-plugin-import":"^2.32.0","eslint-plugin-promise":"^7.2.1","react-highlight-words":"^0.21.0","license-webpack-plugin":"^4.0.2","react-transition-group":"^4.4.5","webpack-dev-middleware":"^7.4.5","webpack-hot-middleware":"^2.26.1","webpack-node-externals":"^3.0.0","mini-css-extract-plugin":"^2.9.4","@babel/preset-typescript":"^7.28.5","@stylistic/eslint-plugin":"^5.6.1","@types/blueimp-load-image":"^5.16.6","@typescript-eslint/parser":"^8.18.2","eslint-plugin-react-hooks":"^7.0.1","@types/redux-optimistic-ui":"^0.4.14","eslint-plugin-react-refresh":"^0.4.24","@types/react-highlight-words":"^0.20.0","@types/react-transition-group":"^4.4.12","@types/webpack-hot-middleware":"^2.25.12","typescript-plugin-css-modules":"^5.2.0","@babel/plugin-transform-runtime":"^7.28.5","@typescript-eslint/eslint-plugin":"^8.18.2","case-sensitive-paths-webpack-plugin":"^2.4.0","@pmmmwh/react-refresh-webpack-plugin":"^0.6.2"},"_npmOperationalInternal":{"tmp":"tmp/karaoke-eternal_2.0.0-beta.5_1764993587594_0.7390198676956765","host":"s3://npm-registry-packages-npm-production"}},"2.0.0-beta.6":{"name":"karaoke-eternal","version":"2.0.0-beta.6","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"author":{"name":"RadRoot LLC"},"license":"ISC","_id":"karaoke-eternal@2.0.0-beta.6","maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"homepage":"https://www.karaoke-eternal.com","bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"bin":{"karaoke-eternal-server":"build/server/main.js"},"dist":{"shasum":"c9c1f9d5511d363e194e3cf162f326709301faf7","tarball":"https://registry.npmjs.org/karaoke-eternal/-/karaoke-eternal-2.0.0-beta.6.tgz","fileCount":79,"integrity":"sha512-MJeH11mIFV3gDV5L3b2Jl/oTj350llK3wNZg6UKWAsJrkZXUa4EeERmTSV0BbNFkEgu5m96MdWf8Kbika/PeZQ==","signatures":[{"sig":"MEQCIFlQgS2Jl86l28EBhTI72VvWn6QJm4SrW15EyL2ioxktAiB3U9dMNiViAB+ShK8LZSTreDqFnVfANwbjTYCSafmJQw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4887738},"main":"./build/server/main.js","type":"module","_from":"file:karaoke-eternal-2.0.0-beta.6.tgz","engines":{"npm":">=11","node":">=24"},"scripts":{"dev":"NODE_ENV=development tsx watch server/main.ts -p 3000","lint":"eslint .","test":"echo \"Error: no test specified\" && exit 1","build":"npm run build:server ; npm run build:client","serve":"node build/server/main.js","server":"npm run serve","lint:fix":"npm run lint -- --fix","serve:docs":"hugo serve --source docs -b http://$(hostname) --bind 0.0.0.0","build:client":"webpack --config config/webpack.config.js","build:server":"rm -rf build/server ; tsc -p config/tsconfig.server.json --noEmitOnError false ; mkdir -p build/server/lib ; cp -R server/lib/schemas build/server/lib/"},"_npmUser":{"name":"radrootllc","email":"hi@radroot.com"},"_resolved":"/Users/brandon/Sites/KaraokeEternal/karaoke-eternal-2.0.0-beta.6.tgz","overrides":{"is-generator-function":"1.0.10","get-generator-function":"1.0.10"},"_integrity":"sha512-MJeH11mIFV3gDV5L3b2Jl/oTj350llK3wNZg6UKWAsJrkZXUa4EeERmTSV0BbNFkEgu5m96MdWf8Kbika/PeZQ==","repository":{"url":"git+https://github.com/bhj/KaraokeEternal.git","type":"git"},"_npmVersion":"11.6.2","description":"Open karaoke party system","directories":{},"productName":"Karaoke Eternal Server","_nodeVersion":"24.11.1","dependencies":{"koa":"^2.16.3","json5":"^2.2.3","yargs":"^18.0.0","bcrypt":"^5.1.1","json-e":"^4.8.0","sqlate":"^2.2.0","sqlite":"^5.1.1","sqlite3":"^5.1.7","unzipit":"^1.4.3","fs-extra":"^11.3.2","koa-body":"^6.0.1","koa-mount":"^4.2.0","koa-range":"^0.3.0","socket.io":"^4.8.1","koa-logger":"^3.2.1","koa-static":"^5.0.0","@koa/router":"^13.1.1","ctx-compose":"^3.0.0","koa-favicon":"^2.1.0","electron-log":"^5.4.3","jsonwebtoken":"^9.0.3","@babel/runtime":"^7.28.4","music-metadata":"^11.10.3","@jcoreio/async-throttle":"^1.7.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"^4.21.0","clsx":"^2.1.1","react":"^18.3.1","eslint":"^9.39.1","globals":"^16.5.0","history":"^5.3.0","nodemon":"^3.1.11","webpack":"^5.103.0","rc-slider":"^11.1.9","react-dom":"^18.3.1","cdgraphics":"^7.0.0","css-loader":"^7.1.2","fast-fuzzy":"^1.12.0","prop-types":"^15.8.1","screenfull":"^6.0.2","typescript":"^5.9.3","@babel/core":"^7.28.5","butterchurn":"^3.0.0-beta.4","file-loader":"^6.2.0","html-loader":"^5.1.0","react-redux":"^9.2.0","webpack-cli":"^6.0.1","@types/react":"^19.2.7","@types/yargs":"^17.0.35","babel-loader":"^10.0.0","gl-chromakey":"^2.0.0","react-router":"^7.10.1","react-window":"^2.2.3","@types/bcrypt":"^6.0.0","react-refresh":"^0.18.0","redux-persist":"^6.0.0","redux-throttle":"^0.1.1","use-long-press":"^3.3.0","@types/fs-extra":"^11.0.4","eslint-plugin-n":"^17.23.1","markdown-loader":"^8.0.0","react-swipeable":"^7.0.2","@reduxjs/toolkit":"^2.11.0","@types/koa-mount":"^4.0.5","@types/koa-range":"^0.3.6","@types/react-dom":"^19.2.3","modern-normalize":"^3.0.1","socket.io-client":"^4.8.1","@babel/preset-env":"^7.28.5","@hello-pangea/dnd":"^18.0.1","@types/koa-logger":"^3.1.5","@types/koa-static":"^4.0.4","react-qrcode-logo":"^4.0.0","typescript-eslint":"^8.48.1","@types/koa-favicon":"^2.1.4","@types/koa__router":"^12.0.5","@types/webpack-env":"^1.18.8","blueimp-load-image":"^5.16.0","react-flip-toolkit":"^7.2.4","@babel/preset-react":"^7.28.5","@types/jsonwebtoken":"^9.0.10","@types/react-window":"^1.8.8","butterchurn-presets":"^3.0.0-beta.4","eslint-plugin-react":"^7.37.5","html-webpack-plugin":"^5.6.5","redux-optimistic-ui":"^3.1.0","use-resize-observer":"^9.1.0","@babel/eslint-parser":"^7.28.5","@babel/eslint-plugin":"^7.27.1","eslint-plugin-import":"^2.32.0","eslint-plugin-promise":"^7.2.1","react-highlight-words":"^0.21.0","license-webpack-plugin":"^4.0.2","react-transition-group":"^4.4.5","webpack-dev-middleware":"^7.4.5","webpack-hot-middleware":"^2.26.1","webpack-node-externals":"^3.0.0","mini-css-extract-plugin":"^2.9.4","@babel/preset-typescript":"^7.28.5","@stylistic/eslint-plugin":"^5.6.1","@types/blueimp-load-image":"^5.16.6","@typescript-eslint/parser":"^8.18.2","eslint-plugin-react-hooks":"^7.0.1","@types/redux-optimistic-ui":"^0.4.14","eslint-plugin-react-refresh":"^0.4.24","@types/react-highlight-words":"^0.20.0","@types/react-transition-group":"^4.4.12","@types/webpack-hot-middleware":"^2.25.12","typescript-plugin-css-modules":"^5.2.0","@babel/plugin-transform-runtime":"^7.28.5","@typescript-eslint/eslint-plugin":"^8.18.2","case-sensitive-paths-webpack-plugin":"^2.4.0","@pmmmwh/react-refresh-webpack-plugin":"^0.6.2"},"_npmOperationalInternal":{"tmp":"tmp/karaoke-eternal_2.0.0-beta.6_1765152148452_0.8943140250116246","host":"s3://npm-registry-packages-npm-production"}},"2.0.0-beta.7":{"name":"karaoke-eternal","version":"2.0.0-beta.7","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"author":{"name":"RadRoot LLC"},"license":"ISC","_id":"karaoke-eternal@2.0.0-beta.7","maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"homepage":"https://www.karaoke-eternal.com","bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"bin":{"karaoke-eternal-server":"build/server/main.js"},"dist":{"shasum":"96c155cab508ba25dab3a7e3adb852630913ea8b","tarball":"https://registry.npmjs.org/karaoke-eternal/-/karaoke-eternal-2.0.0-beta.7.tgz","fileCount":77,"integrity":"sha512-Im9X7ORyOLihV6raCxwnSA4U1DS31Wpe2r60B7U5K1cbNvg6PxnEqv250fwCglvmijoC5jkQV2nAvMXki/m8ag==","signatures":[{"sig":"MEUCICRmWWdlgEzgVrav9T9J2D8WTmgwZW2Hpr+c1Wy7/HMoAiEA3SxMEI2EKBQEbyjPiKGjrbld0dF2aGl9zy6tH7PUAds=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4850872},"main":"./build/server/main.js","type":"module","_from":"file:karaoke-eternal-2.0.0-beta.7.tgz","engines":{"npm":">=11","node":">=24"},"scripts":{"dev":"NODE_ENV=development tsx watch server/main.ts -p 3000","lint":"eslint .","test":"echo \"Error: no test specified\" && exit 1","build":"npm run build:server ; npm run build:client","serve":"node build/server/main.js","server":"npm run serve","lint:fix":"npm run lint -- --fix","serve:docs":"hugo serve --source docs -b http://$(hostname) --bind 0.0.0.0","build:client":"webpack --config config/webpack.config.js","build:server":"rm -rf build/server ; tsc -p config/tsconfig.server.json --noEmitOnError false ; mkdir -p build/server/lib ; cp -R server/lib/schemas build/server/lib/"},"_npmUser":{"name":"radrootllc","email":"hi@radroot.com"},"_resolved":"/Users/brandon/Sites/KaraokeEternal/karaoke-eternal-2.0.0-beta.7.tgz","overrides":{"is-generator-function":"1.0.10","get-generator-function":"1.0.10"},"_integrity":"sha512-Im9X7ORyOLihV6raCxwnSA4U1DS31Wpe2r60B7U5K1cbNvg6PxnEqv250fwCglvmijoC5jkQV2nAvMXki/m8ag==","repository":{"url":"git+https://github.com/bhj/KaraokeEternal.git","type":"git"},"_npmVersion":"11.6.2","description":"Open karaoke party system","directories":{},"productName":"Karaoke Eternal Server","_nodeVersion":"24.11.1","dependencies":{"koa":"^2.16.3","json5":"^2.2.3","yargs":"^18.0.0","bcrypt":"^5.1.1","json-e":"^4.8.0","sqlate":"^2.2.0","sqlite":"^5.1.1","sqlite3":"^5.1.7","unzipit":"^1.4.3","fs-extra":"^11.3.3","koa-body":"^6.0.1","koa-mount":"^4.2.0","koa-range":"^0.3.0","socket.io":"^4.8.1","koa-logger":"^3.2.1","koa-static":"^5.0.0","@koa/router":"^13.1.1","ctx-compose":"^3.0.0","koa-favicon":"^2.1.0","electron-log":"^5.4.3","jsonwebtoken":"^9.0.3","@babel/runtime":"^7.28.4","music-metadata":"^11.10.3","@jcoreio/async-throttle":"^1.7.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"^4.21.0","clsx":"^2.1.1","react":"^18.3.1","eslint":"^9.39.2","globals":"^16.5.0","history":"^5.3.0","nodemon":"^3.1.11","webpack":"^5.104.1","rc-slider":"^11.1.9","react-dom":"^18.3.1","cdgraphics":"^7.0.0","css-loader":"^7.1.2","fast-fuzzy":"^1.12.0","prop-types":"^15.8.1","screenfull":"^6.0.2","typescript":"^5.9.3","@babel/core":"^7.28.5","butterchurn":"^3.0.0-beta.4","file-loader":"^6.2.0","html-loader":"^5.1.0","react-redux":"^9.2.0","webpack-cli":"^6.0.1","@types/react":"^19.2.7","@types/yargs":"^17.0.35","babel-loader":"^10.0.0","gl-chromakey":"^2.0.0","react-router":"^7.11.0","react-window":"^2.2.3","@types/bcrypt":"^6.0.0","react-refresh":"^0.18.0","redux-persist":"^6.0.0","redux-throttle":"^0.1.1","use-long-press":"^3.3.0","@types/fs-extra":"^11.0.4","eslint-plugin-n":"^17.23.1","markdown-loader":"^8.0.0","react-swipeable":"^7.0.2","@reduxjs/toolkit":"^2.11.2","@types/koa-mount":"^4.0.5","@types/koa-range":"^0.3.6","@types/react-dom":"^19.2.3","modern-normalize":"^3.0.1","socket.io-client":"^4.8.1","@babel/preset-env":"^7.28.5","@hello-pangea/dnd":"^18.0.1","@types/koa-logger":"^3.1.5","@types/koa-static":"^4.0.4","react-qrcode-logo":"^4.0.0","typescript-eslint":"^8.50.0","@types/koa-favicon":"^2.1.4","@types/koa__router":"^12.0.5","@types/webpack-env":"^1.18.8","blueimp-load-image":"^5.16.0","react-flip-toolkit":"^7.2.4","@babel/preset-react":"^7.28.5","@types/jsonwebtoken":"^9.0.10","@types/react-window":"^1.8.8","butterchurn-presets":"^3.0.0-beta.4","eslint-plugin-react":"^7.37.5","html-webpack-plugin":"^5.6.5","redux-optimistic-ui":"^3.1.0","use-resize-observer":"^9.1.0","@babel/eslint-parser":"^7.28.5","@babel/eslint-plugin":"^7.27.1","eslint-plugin-import":"^2.32.0","eslint-plugin-promise":"^7.2.1","react-highlight-words":"^0.21.0","license-webpack-plugin":"^4.0.2","react-transition-group":"^4.4.5","webpack-dev-middleware":"^7.4.5","webpack-hot-middleware":"^2.26.1","webpack-node-externals":"^3.0.0","mini-css-extract-plugin":"^2.9.4","@babel/preset-typescript":"^7.28.5","@stylistic/eslint-plugin":"^5.6.1","@types/blueimp-load-image":"^5.16.6","@typescript-eslint/parser":"^8.18.2","eslint-plugin-react-hooks":"^7.0.1","@types/redux-optimistic-ui":"^0.4.14","eslint-plugin-react-refresh":"^0.4.26","@types/react-highlight-words":"^0.20.1","@types/react-transition-group":"^4.4.12","@types/webpack-hot-middleware":"^2.25.12","typescript-plugin-css-modules":"^5.2.0","@babel/plugin-transform-runtime":"^7.28.5","@typescript-eslint/eslint-plugin":"^8.18.2","case-sensitive-paths-webpack-plugin":"^2.4.0","@pmmmwh/react-refresh-webpack-plugin":"^0.6.2"},"_npmOperationalInternal":{"tmp":"tmp/karaoke-eternal_2.0.0-beta.7_1766346878138_0.7923376493947714","host":"s3://npm-registry-packages-npm-production"}},"2.0.0-beta.8":{"name":"karaoke-eternal","version":"2.0.0-beta.8","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"author":{"name":"RadRoot LLC"},"license":"ISC","_id":"karaoke-eternal@2.0.0-beta.8","maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"homepage":"https://www.karaoke-eternal.com","bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"bin":{"karaoke-eternal-server":"build/server/main.js"},"dist":{"shasum":"34469caab715f3a1f26b9974b1101a74f1a1d48d","tarball":"https://registry.npmjs.org/karaoke-eternal/-/karaoke-eternal-2.0.0-beta.8.tgz","fileCount":77,"integrity":"sha512-W6wkxI9aNCP/H8xQI6wHRNcBwck18BTiI9ueif5d3YK0M7stsC30ex3WpsXxiEGrLovNmqwYTmM5TM4iwCAeKg==","signatures":[{"sig":"MEUCIQD5NdNeFCMA9hV7PQyocogKuJlXG+lWEOBN3WT7TqU+KwIgcW2NdLpBoRtkzCo+78PyAerp3CWlBG/0o9sR42A/x1w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4852995},"main":"./build/server/main.js","type":"module","_from":"file:karaoke-eternal-2.0.0-beta.8.tgz","engines":{"npm":">=11","node":">=24"},"scripts":{"dev":"NODE_ENV=development tsx watch server/main.ts -p 3000","lint":"eslint .","test":"echo \"Error: no test specified\" && exit 1","build":"npm run build:server ; npm run build:client","serve":"node build/server/main.js","server":"npm run serve","lint:fix":"npm run lint -- --fix","serve:docs":"hugo serve --source docs -b http://$(hostname) --bind 0.0.0.0","build:client":"webpack --config config/webpack.config.js","build:server":"rm -rf build/server ; tsc -p config/tsconfig.server.json --noEmitOnError false ; mkdir -p build/server/lib ; cp -R server/lib/schemas build/server/lib/"},"_npmUser":{"name":"radrootllc","email":"hi@radroot.com"},"_resolved":"/Users/brandon/Sites/KaraokeEternal/karaoke-eternal-2.0.0-beta.8.tgz","overrides":{"is-generator-function":"1.0.10","get-generator-function":"1.0.10"},"_integrity":"sha512-W6wkxI9aNCP/H8xQI6wHRNcBwck18BTiI9ueif5d3YK0M7stsC30ex3WpsXxiEGrLovNmqwYTmM5TM4iwCAeKg==","repository":{"url":"git+https://github.com/bhj/KaraokeEternal.git","type":"git"},"_npmVersion":"11.6.2","description":"Open karaoke party system","directories":{},"productName":"Karaoke Eternal Server","_nodeVersion":"24.11.1","dependencies":{"koa":"^2.16.3","json5":"^2.2.3","yargs":"^18.0.0","bcrypt":"^5.1.1","json-e":"^4.8.0","sqlate":"^2.2.0","sqlite":"^5.1.1","sqlite3":"^5.1.7","unzipit":"^1.4.3","fs-extra":"^11.3.3","koa-body":"^6.0.1","koa-mount":"^4.2.0","koa-range":"^0.3.0","socket.io":"^4.8.1","koa-logger":"^3.2.1","koa-static":"^5.0.0","@koa/router":"^13.1.1","ctx-compose":"^3.0.0","koa-favicon":"^2.1.0","electron-log":"^5.4.3","jsonwebtoken":"^9.0.3","@babel/runtime":"^7.28.4","music-metadata":"^11.10.3","@jcoreio/async-throttle":"^1.7.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"^4.21.0","clsx":"^2.1.1","react":"^18.3.1","eslint":"^9.39.2","globals":"^16.5.0","history":"^5.3.0","nodemon":"^3.1.11","webpack":"^5.104.1","rc-slider":"^11.1.9","react-dom":"^18.3.1","cdgraphics":"^7.0.0","css-loader":"^7.1.2","fast-fuzzy":"^1.12.0","prop-types":"^15.8.1","screenfull":"^6.0.2","typescript":"^5.9.3","@babel/core":"^7.28.5","butterchurn":"^3.0.0-beta.4","file-loader":"^6.2.0","html-loader":"^5.1.0","react-redux":"^9.2.0","webpack-cli":"^6.0.1","@types/react":"^19.2.7","@types/yargs":"^17.0.35","babel-loader":"^10.0.0","gl-chromakey":"^2.0.0","react-router":"^7.11.0","react-window":"^2.2.3","@types/bcrypt":"^6.0.0","react-refresh":"^0.18.0","redux-persist":"^6.0.0","redux-throttle":"^0.1.1","use-long-press":"^3.3.0","@types/fs-extra":"^11.0.4","eslint-plugin-n":"^17.23.1","markdown-loader":"^8.0.0","react-swipeable":"^7.0.2","@reduxjs/toolkit":"^2.11.2","@types/koa-mount":"^4.0.5","@types/koa-range":"^0.3.6","@types/react-dom":"^19.2.3","modern-normalize":"^3.0.1","socket.io-client":"^4.8.1","@babel/preset-env":"^7.28.5","@hello-pangea/dnd":"^18.0.1","@types/koa-logger":"^3.1.5","@types/koa-static":"^4.0.4","react-qrcode-logo":"^4.0.0","typescript-eslint":"^8.50.0","@types/koa-favicon":"^2.1.4","@types/koa__router":"^12.0.5","@types/webpack-env":"^1.18.8","blueimp-load-image":"^5.16.0","react-flip-toolkit":"^7.2.4","@babel/preset-react":"^7.28.5","@types/jsonwebtoken":"^9.0.10","@types/react-window":"^1.8.8","butterchurn-presets":"^3.0.0-beta.4","eslint-plugin-react":"^7.37.5","html-webpack-plugin":"^5.6.5","redux-optimistic-ui":"^3.1.0","use-resize-observer":"^9.1.0","@babel/eslint-parser":"^7.28.5","@babel/eslint-plugin":"^7.27.1","eslint-plugin-import":"^2.32.0","eslint-plugin-promise":"^7.2.1","react-highlight-words":"^0.21.0","license-webpack-plugin":"^4.0.2","react-transition-group":"^4.4.5","webpack-dev-middleware":"^7.4.5","webpack-hot-middleware":"^2.26.1","webpack-node-externals":"^3.0.0","mini-css-extract-plugin":"^2.9.4","@babel/preset-typescript":"^7.28.5","@stylistic/eslint-plugin":"^5.6.1","@types/blueimp-load-image":"^5.16.6","@typescript-eslint/parser":"^8.18.2","eslint-plugin-react-hooks":"^7.0.1","@types/redux-optimistic-ui":"^0.4.14","eslint-plugin-react-refresh":"^0.4.26","@types/react-highlight-words":"^0.20.1","@types/react-transition-group":"^4.4.12","@types/webpack-hot-middleware":"^2.25.12","typescript-plugin-css-modules":"^5.2.0","@babel/plugin-transform-runtime":"^7.28.5","@typescript-eslint/eslint-plugin":"^8.18.2","case-sensitive-paths-webpack-plugin":"^2.4.0","@pmmmwh/react-refresh-webpack-plugin":"^0.6.2"},"_npmOperationalInternal":{"tmp":"tmp/karaoke-eternal_2.0.0-beta.8_1766549833125_0.10568103630557357","host":"s3://npm-registry-packages-npm-production"}},"2.0.0-beta.9":{"name":"karaoke-eternal","version":"2.0.0-beta.9","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"author":{"name":"RadRoot LLC"},"license":"ISC","_id":"karaoke-eternal@2.0.0-beta.9","maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"homepage":"https://www.karaoke-eternal.com","bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"bin":{"karaoke-eternal-server":"build/server/main.js"},"dist":{"shasum":"3c7b6049497c4302494e79b66a119f107e3e14fa","tarball":"https://registry.npmjs.org/karaoke-eternal/-/karaoke-eternal-2.0.0-beta.9.tgz","fileCount":77,"integrity":"sha512-7IFEfh8wqDTI7fHKLmnjCgsiAHNcuQ+W0U5iwlHqlLt0aSNkIc54KSk9p57AQzykfdkJWuK+pWJmmR0/j5AHtw==","signatures":[{"sig":"MEUCIQD/CYUz4gMvK3bH1JuUmuTdDFpB5n7zsCEVw4hQ0S0b8AIgTkb2sr3tTwQzaNphIYEGXBFDyLrnV8r5JdGTiYGEzUA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4853712},"main":"./build/server/main.js","type":"module","_from":"file:karaoke-eternal-2.0.0-beta.9.tgz","engines":{"npm":">=11","node":">=24"},"scripts":{"dev":"NODE_ENV=development tsx watch server/main.ts -p 3000","lint":"eslint .","test":"echo \"Error: no test specified\" && exit 1","build":"npm run build:server ; npm run build:client","serve":"node build/server/main.js","server":"npm run serve","lint:fix":"npm run lint -- --fix","serve:docs":"hugo serve --source docs -b http://$(hostname) --bind 0.0.0.0","build:client":"webpack --config config/webpack.config.js","build:server":"rm -rf build/server ; tsc -p config/tsconfig.server.json --noEmitOnError false ; mkdir -p build/server/lib ; cp -R server/lib/schemas build/server/lib/"},"_npmUser":{"name":"radrootllc","email":"hi@radroot.com"},"_resolved":"/Users/brandon/Sites/KaraokeEternal/karaoke-eternal-2.0.0-beta.9.tgz","overrides":{"is-generator-function":"1.0.10","get-generator-function":"1.0.10"},"_integrity":"sha512-7IFEfh8wqDTI7fHKLmnjCgsiAHNcuQ+W0U5iwlHqlLt0aSNkIc54KSk9p57AQzykfdkJWuK+pWJmmR0/j5AHtw==","repository":{"url":"git+https://github.com/bhj/KaraokeEternal.git","type":"git"},"_npmVersion":"11.6.2","description":"Open karaoke party system","directories":{},"productName":"Karaoke Eternal Server","_nodeVersion":"24.11.1","dependencies":{"koa":"^2.16.3","json5":"^2.2.3","yargs":"^18.0.0","bcrypt":"^5.1.1","json-e":"^4.8.0","sqlate":"^2.2.0","sqlite":"^5.1.1","sqlite3":"^5.1.7","unzipit":"^1.4.3","fs-extra":"^11.3.3","koa-body":"^6.0.1","koa-mount":"^4.2.0","koa-range":"^0.3.0","socket.io":"^4.8.3","koa-logger":"^3.2.1","koa-static":"^5.0.0","@koa/router":"^13.1.1","ctx-compose":"^3.0.0","koa-favicon":"^2.1.0","electron-log":"^5.4.3","jsonwebtoken":"^9.0.3","@babel/runtime":"^7.28.4","music-metadata":"^11.10.3","@jcoreio/async-throttle":"^1.7.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"^4.21.0","clsx":"^2.1.1","react":"^18.3.1","eslint":"^9.39.2","globals":"^16.5.0","history":"^5.3.0","nodemon":"^3.1.11","webpack":"^5.104.1","rc-slider":"^11.1.9","react-dom":"^18.3.1","cdgraphics":"^7.0.0","css-loader":"^7.1.2","fast-fuzzy":"^1.12.0","prop-types":"^15.8.1","screenfull":"^6.0.2","typescript":"^5.9.3","@babel/core":"^7.28.5","butterchurn":"^3.0.0-beta.4","file-loader":"^6.2.0","html-loader":"^5.1.0","react-redux":"^9.2.0","webpack-cli":"^6.0.1","@types/react":"^19.2.7","@types/yargs":"^17.0.35","babel-loader":"^10.0.0","gl-chromakey":"^2.0.0","react-router":"^7.11.0","react-window":"^2.2.3","@types/bcrypt":"^6.0.0","react-refresh":"^0.18.0","redux-persist":"^6.0.0","redux-throttle":"^0.1.1","use-long-press":"^3.3.0","@types/fs-extra":"^11.0.4","eslint-plugin-n":"^17.23.1","markdown-loader":"^8.0.0","react-swipeable":"^7.0.2","@reduxjs/toolkit":"^2.11.2","@types/koa-mount":"^4.0.5","@types/koa-range":"^0.3.6","@types/react-dom":"^19.2.3","modern-normalize":"^3.0.1","socket.io-client":"^4.8.3","@babel/preset-env":"^7.28.5","@hello-pangea/dnd":"^18.0.1","@types/koa-logger":"^3.1.5","@types/koa-static":"^4.0.4","react-qrcode-logo":"^4.0.0","typescript-eslint":"^8.50.1","@types/koa-favicon":"^2.1.4","@types/koa__router":"^12.0.5","@types/webpack-env":"^1.18.8","blueimp-load-image":"^5.16.0","react-flip-toolkit":"^7.2.4","@babel/preset-react":"^7.28.5","@types/jsonwebtoken":"^9.0.10","@types/react-window":"^1.8.8","butterchurn-presets":"^3.0.0-beta.4","eslint-plugin-react":"^7.37.5","html-webpack-plugin":"^5.6.5","redux-optimistic-ui":"^3.1.0","use-resize-observer":"^9.1.0","@babel/eslint-parser":"^7.28.5","@babel/eslint-plugin":"^7.27.1","eslint-plugin-import":"^2.32.0","eslint-plugin-promise":"^7.2.1","react-highlight-words":"^0.21.0","license-webpack-plugin":"^4.0.2","react-transition-group":"^4.4.5","webpack-dev-middleware":"^7.4.5","webpack-hot-middleware":"^2.26.1","webpack-node-externals":"^3.0.0","mini-css-extract-plugin":"^2.9.4","@babel/preset-typescript":"^7.28.5","@stylistic/eslint-plugin":"^5.6.1","@types/blueimp-load-image":"^5.16.6","@typescript-eslint/parser":"^8.18.2","eslint-plugin-react-hooks":"^7.0.1","@types/redux-optimistic-ui":"^0.4.14","eslint-plugin-react-refresh":"^0.4.26","@types/react-highlight-words":"^0.20.1","@types/react-transition-group":"^4.4.12","@types/webpack-hot-middleware":"^2.25.12","typescript-plugin-css-modules":"^5.2.0","@babel/plugin-transform-runtime":"^7.28.5","@typescript-eslint/eslint-plugin":"^8.18.2","case-sensitive-paths-webpack-plugin":"^2.4.0","@pmmmwh/react-refresh-webpack-plugin":"^0.6.2"},"_npmOperationalInternal":{"tmp":"tmp/karaoke-eternal_2.0.0-beta.9_1766603113148_0.052788326320482915","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"karaoke-eternal","version":"2.0.0","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"author":{"name":"RadRoot LLC"},"license":"ISC","_id":"karaoke-eternal@2.0.0","maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"homepage":"https://www.karaoke-eternal.com","bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"bin":{"karaoke-eternal-server":"build/server/main.js"},"dist":{"shasum":"1e3ce2593a1abb5e5b96681302e39dddf4630617","tarball":"https://registry.npmjs.org/karaoke-eternal/-/karaoke-eternal-2.0.0.tgz","fileCount":77,"integrity":"sha512-SqiUx5HnSxUrzasB/hU31VVrgs2ZdTl12a96hLC7aXD5JmWdRzz7gjWrNymj6P5WRVudd31OaBAY1F7nmZgA/w==","signatures":[{"sig":"MEUCICtUyAcrST9xaCErC+kv5dauOMe7YnCLxPyuoGo1rvG6AiEA7atKTH/y3QfmomM92iKtbfeyfZn83CJngtrFpxxGx4Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4854030},"main":"./build/server/main.js","type":"module","engines":{"npm":">=11","node":">=24"},"gitHead":"bff53a6f4ce523b044d05163f0fabe9ff2dc942b","scripts":{"dev":"NODE_ENV=development tsx watch server/main.ts -p 3000","lint":"eslint .","test":"echo \"Error: no test specified\" && exit 1","build":"npm run build:server ; npm run build:client","serve":"node build/server/main.js","server":"npm run serve","lint:fix":"npm run lint -- --fix","docs:serve":"hugo serve --source docs -b http://localhost:1313 --bind 0.0.0.0","build:client":"webpack --config config/webpack.config.js","build:server":"rm -rf build/server ; tsc -p config/tsconfig.server.json --noEmitOnError false ; mkdir -p build/server/lib ; cp -R server/lib/schemas build/server/lib/"},"_npmUser":{"name":"radrootllc","email":"hi@radroot.com"},"overrides":{"is-generator-function":"1.0.10","get-generator-function":"1.0.10"},"repository":{"url":"git+https://github.com/bhj/KaraokeEternal.git","type":"git"},"_npmVersion":"11.6.2","description":"Open karaoke party system","directories":{},"productName":"Karaoke Eternal Server","_nodeVersion":"24.11.1","dependencies":{"koa":"^2.16.3","json5":"^2.2.3","yargs":"^18.0.0","bcrypt":"^5.1.1","json-e":"^4.8.0","sqlate":"^2.2.0","sqlite":"^5.1.1","sqlite3":"^5.1.7","unzipit":"^1.4.3","fs-extra":"^11.3.3","koa-body":"^6.0.1","koa-mount":"^4.2.0","koa-range":"^0.3.0","socket.io":"^4.8.3","koa-logger":"^3.2.1","koa-static":"^5.0.0","@koa/router":"^13.1.1","ctx-compose":"^3.0.0","koa-favicon":"^2.1.0","electron-log":"^5.4.3","jsonwebtoken":"^9.0.3","@babel/runtime":"^7.28.4","music-metadata":"^11.10.3","@jcoreio/async-throttle":"^1.7.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","clsx":"^2.1.1","react":"^18.3.1","eslint":"^9.39.2","globals":"^16.5.0","history":"^5.3.0","nodemon":"^3.1.11","webpack":"^5.104.1","rc-slider":"^11.1.9","react-dom":"^18.3.1","cdgraphics":"^7.0.0","css-loader":"^7.1.2","fast-fuzzy":"^1.12.0","prop-types":"^15.8.1","screenfull":"^6.0.2","typescript":"^5.9.3","@babel/core":"^7.28.5","butterchurn":"^3.0.0-beta.4","file-loader":"^6.2.0","html-loader":"^5.1.0","react-redux":"^9.2.0","webpack-cli":"^6.0.1","@types/react":"^19.2.7","@types/yargs":"^17.0.35","babel-loader":"^10.0.0","gl-chromakey":"^2.0.0","react-router":"^7.11.0","react-window":"^2.2.3","@types/bcrypt":"^6.0.0","react-refresh":"^0.18.0","redux-persist":"^6.0.0","redux-throttle":"^0.1.1","use-long-press":"^3.3.0","@types/fs-extra":"^11.0.4","eslint-plugin-n":"^17.23.1","markdown-loader":"^8.0.0","react-swipeable":"^7.0.2","@reduxjs/toolkit":"^2.11.2","@types/koa-mount":"^4.0.5","@types/koa-range":"^0.3.6","@types/react-dom":"^19.2.3","modern-normalize":"^3.0.1","socket.io-client":"^4.8.3","@babel/preset-env":"^7.28.5","@hello-pangea/dnd":"^18.0.1","@types/koa-logger":"^3.1.5","@types/koa-static":"^4.0.4","react-qrcode-logo":"^4.0.0","typescript-eslint":"^8.50.1","@types/koa-favicon":"^2.1.4","@types/koa__router":"^12.0.5","@types/webpack-env":"^1.18.8","blueimp-load-image":"^5.16.0","react-flip-toolkit":"^7.2.4","@babel/preset-react":"^7.28.5","@types/jsonwebtoken":"^9.0.10","@types/react-window":"^1.8.8","butterchurn-presets":"^3.0.0-beta.4","eslint-plugin-react":"^7.37.5","html-webpack-plugin":"^5.6.5","redux-optimistic-ui":"^3.1.0","use-resize-observer":"^9.1.0","@babel/eslint-parser":"^7.28.5","@babel/eslint-plugin":"^7.27.1","eslint-plugin-import":"^2.32.0","eslint-plugin-promise":"^7.2.1","react-highlight-words":"^0.21.0","license-webpack-plugin":"^4.0.2","react-transition-group":"^4.4.5","webpack-dev-middleware":"^7.4.5","webpack-hot-middleware":"^2.26.1","webpack-node-externals":"^3.0.0","mini-css-extract-plugin":"^2.9.4","@babel/preset-typescript":"^7.28.5","@stylistic/eslint-plugin":"^5.6.1","@types/blueimp-load-image":"^5.16.6","@typescript-eslint/parser":"^8.18.2","eslint-plugin-react-hooks":"^7.0.1","@types/redux-optimistic-ui":"^0.4.14","eslint-plugin-react-refresh":"^0.4.26","@types/react-highlight-words":"^0.20.1","@types/react-transition-group":"^4.4.12","@types/webpack-hot-middleware":"^2.25.12","typescript-plugin-css-modules":"^5.2.0","@babel/plugin-transform-runtime":"^7.28.5","@typescript-eslint/eslint-plugin":"^8.18.2","case-sensitive-paths-webpack-plugin":"^2.4.0","@pmmmwh/react-refresh-webpack-plugin":"^0.6.2"},"_npmOperationalInternal":{"tmp":"tmp/karaoke-eternal_2.0.0_1766787568854_0.968454864943407","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"karaoke-eternal","version":"2.0.1","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"author":{"name":"RadRoot LLC"},"license":"ISC","_id":"karaoke-eternal@2.0.1","maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"homepage":"https://www.karaoke-eternal.com","bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"bin":{"karaoke-eternal-server":"build/server/main.js"},"dist":{"shasum":"082d40574bc811ebe8bacbf9dce0a54d46562955","tarball":"https://registry.npmjs.org/karaoke-eternal/-/karaoke-eternal-2.0.1.tgz","fileCount":79,"integrity":"sha512-wKS/C832IbmBNLDHUqlTtIZg+RgwaTicEJ1DDWVWt0iYZjYQbPW74Hc8qt1yBHwkIvRsvxNpoGwZpbwCiZrMaw==","signatures":[{"sig":"MEUCIERx3hOTMH43NbNMYmZ61/XdhEuEE9KTf37rWt+wEGuZAiEA4qsylc/gF6W7QHXN1AKj9TrQjsuoZp2+7izt+YsYGP4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4857996},"main":"./build/server/main.js","type":"module","_from":"file:karaoke-eternal-2.0.1.tgz","engines":{"npm":">=11","node":">=24"},"scripts":{"dev":"NODE_ENV=development tsx watch server/main.ts -p 3000","lint":"eslint .","test":"vitest run --config config/vitest.config.ts","build":"npm run build:server ; npm run build:client","serve":"node build/server/main.js","server":"npm run serve","lint:fix":"npm run lint -- --fix","typecheck":"tsc -b --noEmit","docs:serve":"hugo serve --source docs -b http://localhost:1313 --bind 0.0.0.0","build:client":"webpack --config config/webpack.config.js","build:server":"rm -rf build/server ; tsc -p config/tsconfig.server.json --noEmitOnError false ; mkdir -p build/server/lib ; cp -R server/lib/schemas build/server/lib/"},"_npmUser":{"name":"radrootllc","email":"hi@radroot.com"},"_resolved":"/Users/brandon/Sites/KaraokeEternal/karaoke-eternal-2.0.1.tgz","overrides":{"is-generator-function":"1.0.10","get-generator-function":"1.0.10"},"_integrity":"sha512-wKS/C832IbmBNLDHUqlTtIZg+RgwaTicEJ1DDWVWt0iYZjYQbPW74Hc8qt1yBHwkIvRsvxNpoGwZpbwCiZrMaw==","repository":{"url":"git+https://github.com/bhj/KaraokeEternal.git","type":"git"},"_npmVersion":"11.6.2","description":"Open karaoke party system","directories":{},"productName":"Karaoke Eternal Server","_nodeVersion":"24.11.1","dependencies":{"koa":"^2.16.3","json5":"^2.2.3","yargs":"^18.0.0","bcrypt":"^5.1.1","json-e":"^4.8.0","sqlate":"^2.2.0","sqlite":"^5.1.1","sqlite3":"^5.1.7","unzipit":"^1.4.3","fs-extra":"^11.3.3","koa-body":"^6.0.1","koa-mount":"^4.2.0","koa-range":"^0.3.0","socket.io":"^4.8.3","koa-logger":"^3.2.1","koa-static":"^5.0.0","@koa/router":"^13.1.1","ctx-compose":"^3.0.0","koa-favicon":"^2.1.0","electron-log":"^5.4.3","jsonwebtoken":"^9.0.3","@babel/runtime":"^7.28.4","music-metadata":"^11.10.5","@jcoreio/async-throttle":"^1.7.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","clsx":"^2.1.1","react":"^18.3.1","eslint":"^9.39.2","vitest":"^4.0.16","globals":"^17.0.0","history":"^5.3.0","nodemon":"^3.1.11","webpack":"^5.104.1","rc-slider":"^11.1.9","react-dom":"^18.3.1","cdgraphics":"^7.0.0","css-loader":"^7.1.2","fast-fuzzy":"^1.12.0","prop-types":"^15.8.1","screenfull":"^6.0.2","typescript":"^5.9.3","@babel/core":"^7.28.5","butterchurn":"^3.0.0-beta.4","file-loader":"^6.2.0","html-loader":"^5.1.0","react-redux":"^9.2.0","webpack-cli":"^6.0.1","@types/react":"^19.2.8","@types/yargs":"^17.0.35","babel-loader":"^10.0.0","gl-chromakey":"^2.0.0","react-router":"^7.12.0","react-window":"^2.2.4","@types/bcrypt":"^6.0.0","react-refresh":"^0.18.0","redux-persist":"^6.0.0","redux-throttle":"^0.1.1","use-long-press":"^3.3.0","@types/fs-extra":"^11.0.4","eslint-plugin-n":"^17.23.1","markdown-loader":"^8.0.0","react-swipeable":"^7.0.2","@reduxjs/toolkit":"^2.11.2","@types/koa-mount":"^4.0.5","@types/koa-range":"^0.3.6","@types/react-dom":"^19.2.3","modern-normalize":"^3.0.1","socket.io-client":"^4.8.3","@babel/preset-env":"^7.28.5","@hello-pangea/dnd":"^18.0.1","@types/koa-logger":"^3.1.5","@types/koa-static":"^4.0.4","react-qrcode-logo":"^4.0.0","typescript-eslint":"^8.52.0","@types/koa-favicon":"^2.1.4","@types/koa__router":"^12.0.5","@types/webpack-env":"^1.18.8","blueimp-load-image":"^5.16.0","react-flip-toolkit":"^7.2.4","@babel/preset-react":"^7.28.5","@types/jsonwebtoken":"^9.0.10","@types/react-window":"^1.8.8","butterchurn-presets":"^3.0.0-beta.4","eslint-plugin-react":"^7.37.5","html-webpack-plugin":"^5.6.5","redux-optimistic-ui":"^3.1.0","use-resize-observer":"^9.1.0","@babel/eslint-parser":"^7.28.5","@babel/eslint-plugin":"^7.27.1","eslint-plugin-import":"^2.32.0","eslint-plugin-promise":"^7.2.1","react-highlight-words":"^0.21.0","license-webpack-plugin":"^4.0.2","react-transition-group":"^4.4.5","webpack-dev-middleware":"^7.4.5","webpack-hot-middleware":"^2.26.1","webpack-node-externals":"^3.0.0","mini-css-extract-plugin":"^2.9.4","@babel/preset-typescript":"^7.28.5","@stylistic/eslint-plugin":"^5.7.0","@types/blueimp-load-image":"^5.16.6","@typescript-eslint/parser":"^8.18.2","eslint-plugin-react-hooks":"^7.0.1","@types/redux-optimistic-ui":"^0.4.14","eslint-plugin-react-refresh":"^0.4.26","@types/react-highlight-words":"^0.20.1","@types/react-transition-group":"^4.4.12","@types/webpack-hot-middleware":"^2.25.12","typescript-plugin-css-modules":"^5.2.0","@babel/plugin-transform-runtime":"^7.28.5","@typescript-eslint/eslint-plugin":"^8.18.2","case-sensitive-paths-webpack-plugin":"^2.4.0","@pmmmwh/react-refresh-webpack-plugin":"^0.6.2"},"_npmOperationalInternal":{"tmp":"tmp/karaoke-eternal_2.0.1_1768081412536_0.6204058084423276","host":"s3://npm-registry-packages-npm-production"}},"2.0.2-beta.0":{"name":"karaoke-eternal","version":"2.0.2-beta.0","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"author":{"name":"RadRoot LLC"},"license":"ISC","_id":"karaoke-eternal@2.0.2-beta.0","maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"homepage":"https://www.karaoke-eternal.com","bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"bin":{"karaoke-eternal-server":"build/server/main.js"},"dist":{"shasum":"dec2d4f91f39fe05aed5b873f423237b7b71694b","tarball":"https://registry.npmjs.org/karaoke-eternal/-/karaoke-eternal-2.0.2-beta.0.tgz","fileCount":79,"integrity":"sha512-oQf8Tq30klLAccvo9Z7c2bIQyKI+s/rdLpJnCi6J4hLDbPfaiy5KFUgCQwjzDVt1TTtncYbvkPXgMiWCHGAZvg==","signatures":[{"sig":"MEUCIQCzwp47FZL7azANl3t+OnYV6+uD86uxQ1+i1sFSjoTfwgIgDJ1mgn8in0TkEDCQfTQB5IP0fm7RKewr4nWwWl8wlMg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4865464},"main":"./build/server/main.js","type":"module","_from":"file:karaoke-eternal-2.0.2-beta.0.tgz","engines":{"npm":">=11","node":">=24"},"scripts":{"dev":"NODE_ENV=development tsx watch server/main.ts -p 3000","lint":"eslint .","test":"vitest run --config config/vitest.config.ts","build":"npm run build:server ; npm run build:client","serve":"node build/server/main.js","server":"npm run serve","lint:fix":"npm run lint -- --fix","typecheck":"tsc -b --noEmit","docs:serve":"hugo serve --source docs -b http://localhost:1313 --bind 0.0.0.0","build:client":"webpack --config config/webpack.config.js","build:server":"rm -rf build/server ; tsc -p config/tsconfig.server.json --noEmitOnError false ; mkdir -p build/server/lib ; cp -R server/lib/schemas build/server/lib/"},"_npmUser":{"name":"radrootllc","email":"hi@radroot.com"},"_resolved":"/Users/brandon/Sites/KaraokeEternal/karaoke-eternal-2.0.2-beta.0.tgz","overrides":{"is-generator-function":"1.0.10","get-generator-function":"1.0.10"},"_integrity":"sha512-oQf8Tq30klLAccvo9Z7c2bIQyKI+s/rdLpJnCi6J4hLDbPfaiy5KFUgCQwjzDVt1TTtncYbvkPXgMiWCHGAZvg==","repository":{"url":"git+https://github.com/bhj/KaraokeEternal.git","type":"git"},"_npmVersion":"11.6.2","description":"Open karaoke party system","directories":{},"productName":"Karaoke Eternal Server","_nodeVersion":"24.13.0","dependencies":{"koa":"^3.1.1","json5":"^2.2.3","yargs":"^18.0.0","json-e":"^4.8.1","sqlate":"^2.2.0","unzipit":"^1.4.3","bcryptjs":"^3.0.3","koa-body":"^7.0.1","koa-mount":"^4.2.0","koa-range":"^0.3.0","socket.io":"^4.8.3","koa-logger":"^4.0.0","koa-static":"^5.0.0","@koa/router":"^15.3.0","ctx-compose":"^3.0.0","koa-favicon":"^2.1.0","electron-log":"^5.4.3","jsonwebtoken":"^9.0.3","@babel/runtime":"^7.28.6","music-metadata":"^11.11.0","@jcoreio/async-throttle":"^1.7.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"^4.21.0","clsx":"^2.1.1","react":"^18.3.1","eslint":"^9.39.2","vitest":"^4.0.18","globals":"^17.2.0","history":"^5.3.0","nodemon":"^3.1.11","webpack":"^5.104.1","rc-slider":"^11.1.9","react-dom":"^18.3.1","cdgraphics":"^7.0.0","css-loader":"^7.1.3","fast-fuzzy":"^1.12.0","screenfull":"^6.0.2","typescript":"^5.9.3","@babel/core":"^7.28.6","butterchurn":"^3.0.0-beta.4","file-loader":"^6.2.0","html-loader":"^5.1.0","react-redux":"^9.2.0","webpack-cli":"^6.0.1","@types/react":"^19.2.10","@types/yargs":"^17.0.35","babel-loader":"^10.0.0","gl-chromakey":"^2.0.0","react-router":"^7.13.0","react-window":"^2.2.5","@types/bcrypt":"^6.0.0","react-refresh":"^0.18.0","redux-persist":"^6.0.0","redux-throttle":"^0.1.1","use-long-press":"^3.3.0","@types/fs-extra":"^11.0.4","eslint-plugin-n":"^17.23.2","markdown-loader":"^8.0.0","react-swipeable":"^7.0.2","@reduxjs/toolkit":"^2.11.2","@types/koa-mount":"^4.0.5","@types/koa-range":"^0.3.6","@types/react-dom":"^19.2.3","modern-normalize":"^3.0.1","socket.io-client":"^4.8.3","@babel/preset-env":"^7.28.6","@hello-pangea/dnd":"^18.0.1","@types/koa-logger":"^3.1.5","@types/koa-static":"^4.0.4","react-qrcode-logo":"^4.0.0","typescript-eslint":"^8.54.0","@types/koa-favicon":"^2.1.4","@types/webpack-env":"^1.18.8","blueimp-load-image":"^5.16.0","react-flip-toolkit":"^7.2.4","@babel/preset-react":"^7.28.5","@types/jsonwebtoken":"^9.0.10","@types/react-window":"^1.8.8","butterchurn-presets":"^3.0.0-beta.4","eslint-plugin-react":"^7.37.5","html-webpack-plugin":"^5.6.6","redux-optimistic-ui":"^3.1.0","use-resize-observer":"^9.1.0","@babel/eslint-parser":"^7.28.6","@babel/eslint-plugin":"^7.27.1","eslint-plugin-import":"^2.32.0","eslint-plugin-promise":"^7.2.1","react-highlight-words":"^0.21.0","license-webpack-plugin":"^4.0.2","react-transition-group":"^4.4.5","webpack-dev-middleware":"^7.4.5","webpack-hot-middleware":"^2.26.1","webpack-node-externals":"^3.0.0","mini-css-extract-plugin":"^2.10.0","@babel/preset-typescript":"^7.28.5","@stylistic/eslint-plugin":"^5.7.1","@types/blueimp-load-image":"^5.16.6","@typescript-eslint/parser":"^8.18.2","eslint-plugin-react-hooks":"^7.0.1","@types/redux-optimistic-ui":"^0.4.14","eslint-plugin-react-refresh":"^0.4.26","@types/react-highlight-words":"^0.20.1","@types/react-transition-group":"^4.4.12","@types/webpack-hot-middleware":"^2.25.12","typescript-plugin-css-modules":"^5.2.0","@babel/plugin-transform-runtime":"^7.28.5","@typescript-eslint/eslint-plugin":"^8.18.2","case-sensitive-paths-webpack-plugin":"^2.4.0","@pmmmwh/react-refresh-webpack-plugin":"^0.6.2"},"_npmOperationalInternal":{"tmp":"tmp/karaoke-eternal_2.0.2-beta.0_1769570756756_0.18735192100689813","host":"s3://npm-registry-packages-npm-production"}},"2.0.2-beta.2":{"name":"karaoke-eternal","version":"2.0.2-beta.2","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"author":{"name":"RadRoot LLC"},"license":"ISC","_id":"karaoke-eternal@2.0.2-beta.2","maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"homepage":"https://www.karaoke-eternal.com","bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"bin":{"karaoke-eternal-server":"build/server/main.js"},"dist":{"shasum":"62fcaf380b4221d548f391592c9c90c8cf14d06b","tarball":"https://registry.npmjs.org/karaoke-eternal/-/karaoke-eternal-2.0.2-beta.2.tgz","fileCount":79,"integrity":"sha512-tmLk/XEjBpVexLOPsWptP/8Q2GEzKDWg9EspzsHSFxCe9kAlRo27RGy0cZHyrGEQLqdcmpHdf4pjywll0GyrWQ==","signatures":[{"sig":"MEYCIQDbDqAUFnO4KN2XRjpGr8klpPqJH6xzW0y4V6SYV3b1uQIhAIkrvjJxJ1v6xSNFixxDeznqb4QuiBHSMFsvgSWQa1iL","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4911282},"main":"./build/server/main.js","type":"module","_from":"file:karaoke-eternal-2.0.2-beta.2.tgz","engines":{"npm":">=11","node":">=24"},"scripts":{"dev":"NODE_ENV=development tsx watch server/main.ts -p 3000","lint":"eslint .","test":"vitest run --config config/vitest.config.ts","build":"npm run build:server ; npm run build:client","serve":"node build/server/main.js","server":"npm run serve","lint:fix":"npm run lint -- --fix","typecheck":"tsc -b --noEmit","docs:serve":"hugo serve --source docs -b http://localhost:1313 --bind 0.0.0.0","build:client":"webpack --config config/webpack.config.js","build:server":"rm -rf build/server ; tsc -p config/tsconfig.server.json --noEmitOnError false ; mkdir -p build/server/lib ; cp -R server/lib/schemas build/server/lib/"},"_npmUser":{"name":"radrootllc","email":"hi@radroot.com"},"_resolved":"/Users/brandon/Sites/KaraokeEternal/karaoke-eternal-2.0.2-beta.2.tgz","overrides":{"is-generator-function":"1.0.10","get-generator-function":"1.0.10"},"_integrity":"sha512-tmLk/XEjBpVexLOPsWptP/8Q2GEzKDWg9EspzsHSFxCe9kAlRo27RGy0cZHyrGEQLqdcmpHdf4pjywll0GyrWQ==","repository":{"url":"git+https://github.com/bhj/KaraokeEternal.git","type":"git"},"_npmVersion":"11.6.2","description":"Open karaoke party system","directories":{},"productName":"Karaoke Eternal Server","_nodeVersion":"24.13.0","dependencies":{"koa":"^3.1.1","json5":"^2.2.3","yargs":"^18.0.0","json-e":"^4.8.1","sqlate":"^2.2.0","unzipit":"^1.4.3","bcryptjs":"^3.0.3","koa-body":"^7.0.1","koa-mount":"^4.2.0","koa-range":"^0.3.0","socket.io":"^4.8.3","koa-logger":"^4.0.0","koa-static":"^5.0.0","@koa/router":"^15.3.0","ctx-compose":"^3.0.0","koa-favicon":"^2.1.0","electron-log":"^5.4.3","jsonwebtoken":"^9.0.3","@babel/runtime":"^7.28.6","music-metadata":"^11.11.2","@jcoreio/async-throttle":"^1.7.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"^4.21.0","clsx":"^2.1.1","react":"^18.3.1","eslint":"^9.39.2","vitest":"^4.0.18","globals":"^17.3.0","history":"^5.3.0","nodemon":"^3.1.11","webpack":"^5.105.0","rc-slider":"^11.1.9","react-dom":"^18.3.1","cdgraphics":"^7.0.0","css-loader":"^7.1.3","fast-fuzzy":"^1.12.0","screenfull":"^6.0.2","typescript":"^5.9.3","@babel/core":"^7.29.0","butterchurn":"^3.0.0-beta.4","file-loader":"^6.2.0","html-loader":"^5.1.0","react-redux":"^9.2.0","webpack-cli":"^6.0.1","@types/react":"^19.2.13","@types/yargs":"^17.0.35","babel-loader":"^10.0.0","gl-chromakey":"^2.0.0","react-router":"^7.13.0","react-window":"^2.2.6","@types/bcrypt":"^6.0.0","react-refresh":"^0.18.0","redux-persist":"^6.0.0","redux-throttle":"^0.1.1","use-long-press":"^3.3.0","@types/fs-extra":"^11.0.4","eslint-plugin-n":"^17.23.2","markdown-loader":"^8.0.0","react-swipeable":"^7.0.2","@reduxjs/toolkit":"^2.11.2","@types/koa-mount":"^4.0.5","@types/koa-range":"^0.3.6","@types/react-dom":"^19.2.3","modern-normalize":"^3.0.1","socket.io-client":"^4.8.3","@babel/preset-env":"^7.29.0","@hello-pangea/dnd":"^18.0.1","@types/koa-logger":"^3.1.5","@types/koa-static":"^4.0.4","react-qrcode-logo":"^4.0.0","typescript-eslint":"^8.54.0","@types/koa-favicon":"^2.1.4","@types/webpack-env":"^1.18.8","blueimp-load-image":"^5.16.0","react-flip-toolkit":"^7.2.4","@babel/preset-react":"^7.28.5","@types/jsonwebtoken":"^9.0.10","@types/react-window":"^1.8.8","butterchurn-presets":"^3.0.0-beta.4","eslint-plugin-react":"^7.37.5","html-webpack-plugin":"^5.6.6","redux-optimistic-ui":"^3.1.0","use-resize-observer":"^9.1.0","@babel/eslint-parser":"^7.28.6","@babel/eslint-plugin":"^7.27.1","eslint-plugin-import":"^2.32.0","eslint-plugin-promise":"^7.2.1","react-highlight-words":"^0.21.0","license-webpack-plugin":"^4.0.2","react-compiler-runtime":"^1.0.0","react-transition-group":"^4.4.5","webpack-dev-middleware":"^7.4.5","webpack-hot-middleware":"^2.26.1","webpack-node-externals":"^3.0.0","mini-css-extract-plugin":"^2.10.0","@babel/preset-typescript":"^7.28.5","@stylistic/eslint-plugin":"^5.7.1","@types/blueimp-load-image":"^5.16.6","@typescript-eslint/parser":"^8.18.2","eslint-plugin-react-hooks":"^7.0.1","@types/redux-optimistic-ui":"^0.4.14","babel-plugin-react-compiler":"^1.0.0","eslint-plugin-react-refresh":"^0.4.26","@types/react-highlight-words":"^0.20.1","@types/react-transition-group":"^4.4.12","@types/webpack-hot-middleware":"^2.25.12","typescript-plugin-css-modules":"^5.2.0","@babel/plugin-transform-runtime":"^7.29.0","@typescript-eslint/eslint-plugin":"^8.18.2","case-sensitive-paths-webpack-plugin":"^2.4.0","@pmmmwh/react-refresh-webpack-plugin":"^0.6.2"},"_npmOperationalInternal":{"tmp":"tmp/karaoke-eternal_2.0.2-beta.2_1770417882941_0.6467421554243773","host":"s3://npm-registry-packages-npm-production"}},"2.0.2":{"name":"karaoke-eternal","version":"2.0.2","description":"Open karaoke party system","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"homepage":"https://www.karaoke-eternal.com","type":"module","main":"./build/server/main.js","engines":{"node":">=24","npm":">=11"},"scripts":{"docs:serve":"hugo serve --source docs -b http://localhost:1313 --bind 0.0.0.0","dev":"NODE_ENV=development tsx watch server/main.ts -p 3000","lint":"eslint .","lint:fix":"npm run lint -- --fix","test":"vitest run --config config/vitest.config.ts","typecheck":"tsc -b --noEmit","build":"npm run build:server ; npm run build:client","build:client":"webpack --config config/webpack.config.js","build:server":"rm -rf build/server ; tsc -p config/tsconfig.server.json --noEmitOnError false ; mkdir -p build/server/lib ; cp -R server/lib/schemas build/server/lib/","serve":"node build/server/main.js","server":"npm run serve"},"bin":{"karaoke-eternal-server":"build/server/main.js"},"repository":{"type":"git","url":"git+https://github.com/bhj/KaraokeEternal.git"},"productName":"Karaoke Eternal Server","author":{"name":"RadRoot LLC"},"license":"ISC","overrides":{"is-generator-function":"1.0.10","get-generator-function":"1.0.10"},"dependencies":{"@babel/runtime":"^7.28.6","@jcoreio/async-throttle":"^1.7.0","@koa/router":"^15.3.0","bcryptjs":"^3.0.3","ctx-compose":"^3.0.0","electron-log":"^5.4.3","json-e":"^4.8.1","json5":"^2.2.3","jsonwebtoken":"^9.0.3","koa":"^3.1.1","koa-body":"^7.0.1","koa-favicon":"^2.1.0","koa-logger":"^4.0.0","koa-mount":"^4.2.0","koa-range":"^0.3.0","koa-static":"^5.0.0","music-metadata":"^11.12.0","socket.io":"^4.8.3","sqlate":"^2.2.0","unzipit":"^1.4.3","yargs":"^18.0.0"},"devDependencies":{"@babel/core":"^7.29.0","@babel/eslint-parser":"^7.28.6","@babel/eslint-plugin":"^7.27.1","@babel/plugin-transform-runtime":"^7.29.0","@babel/preset-env":"^7.29.0","@babel/preset-react":"^7.28.5","@babel/preset-typescript":"^7.28.5","@hello-pangea/dnd":"^18.0.1","@pmmmwh/react-refresh-webpack-plugin":"^0.6.2","@reduxjs/toolkit":"^2.11.2","@stylistic/eslint-plugin":"^5.8.0","@types/bcrypt":"^6.0.0","@types/blueimp-load-image":"^5.16.6","@types/fs-extra":"^11.0.4","@types/jsonwebtoken":"^9.0.10","@types/koa-favicon":"^2.1.4","@types/koa-logger":"^3.1.5","@types/koa-mount":"^4.0.5","@types/koa-range":"^0.3.6","@types/koa-static":"^4.0.4","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@types/react-highlight-words":"^0.20.1","@types/react-transition-group":"^4.4.12","@types/react-window":"^1.8.8","@types/redux-optimistic-ui":"^0.4.14","@types/webpack-env":"^1.18.8","@types/webpack-hot-middleware":"^2.25.12","@types/yargs":"^17.0.35","@typescript-eslint/eslint-plugin":"^8.18.2","@typescript-eslint/parser":"^8.18.2","babel-loader":"^10.0.0","babel-plugin-react-compiler":"^1.0.0","blueimp-load-image":"^5.16.0","butterchurn":"^3.0.0-beta.4","butterchurn-presets":"^3.0.0-beta.4","case-sensitive-paths-webpack-plugin":"^2.4.0","cdgraphics":"^7.0.0","clsx":"^2.1.1","css-loader":"^7.1.3","eslint":"^9.39.2","eslint-plugin-import":"^2.32.0","eslint-plugin-n":"^17.23.2","eslint-plugin-promise":"^7.2.1","eslint-plugin-react":"^7.37.5","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.26","fast-fuzzy":"^1.12.0","file-loader":"^6.2.0","gl-chromakey":"^2.0.0","globals":"^17.3.0","history":"^5.3.0","html-loader":"^5.1.0","html-webpack-plugin":"^5.6.6","license-webpack-plugin":"^4.0.2","markdown-loader":"^8.0.0","mini-css-extract-plugin":"^2.10.0","modern-normalize":"^3.0.1","nodemon":"^3.1.11","rc-slider":"^11.1.9","react":"^18.3.1","react-compiler-runtime":"^1.0.0","react-dom":"^18.3.1","react-flip-toolkit":"^7.2.4","react-highlight-words":"^0.21.0","react-qrcode-logo":"^4.0.0","react-redux":"^9.2.0","react-refresh":"^0.18.0","react-router":"^7.13.0","react-swipeable":"^7.0.2","react-transition-group":"^4.4.5","react-window":"^2.2.7","redux-optimistic-ui":"^3.1.0","redux-persist":"^6.0.0","redux-throttle":"^0.1.1","screenfull":"^6.0.2","socket.io-client":"^4.8.3","tsx":"^4.21.0","typescript":"^5.9.3","typescript-eslint":"^8.55.0","typescript-plugin-css-modules":"^5.2.0","use-long-press":"^3.3.0","use-resize-observer":"^9.1.0","vitest":"^4.0.18","webpack":"^5.105.2","webpack-cli":"^6.0.1","webpack-dev-middleware":"^7.4.5","webpack-hot-middleware":"^2.26.1","webpack-node-externals":"^3.0.0"},"_id":"karaoke-eternal@2.0.2","bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"_integrity":"sha512-jS3phxZAX2R+7xuZj+RMGuaPXklfCacPMUzJyFh7zdr8lV92CR0C8UB4kHP+q8qiI0L93nVJTBZUk715PxmSgA==","_resolved":"/Users/brandon/Sites/KaraokeEternal/karaoke-eternal-2.0.2.tgz","_from":"file:karaoke-eternal-2.0.2.tgz","_nodeVersion":"24.13.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-jS3phxZAX2R+7xuZj+RMGuaPXklfCacPMUzJyFh7zdr8lV92CR0C8UB4kHP+q8qiI0L93nVJTBZUk715PxmSgA==","shasum":"95bc9b4108c2656329d51e8354174219d922c3bb","tarball":"https://registry.npmjs.org/karaoke-eternal/-/karaoke-eternal-2.0.2.tgz","fileCount":79,"unpackedSize":4912462,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC9vf3TZsI0v0bhHaO3tIZ0xeRhg9x1vbnKl0IAtuzX5QIhANBlheBGhYkSRlLrttpmtR1Y8rCkLzgqIVTQq/D5muE1"}]},"_npmUser":{"name":"radrootllc","email":"hi@radroot.com"},"directories":{},"maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/karaoke-eternal_2.0.2_1771108412965_0.845603617863232"},"_hasShrinkwrap":false}},"time":{"created":"2022-05-09T06:37:38.356Z","modified":"2026-02-14T22:33:33.368Z","0.9.0-beta.0":"2022-05-09T06:37:38.563Z","0.9.0-beta.1":"2022-05-11T02:19:41.808Z","0.9.0-beta.2":"2022-05-12T05:55:26.497Z","0.9.0-beta.3":"2022-05-14T01:00:28.133Z","0.9.0-beta.4":"2022-05-15T22:53:41.397Z","1.0.0":"2022-05-17T18:11:43.036Z","2.0.0-dev.0":"2024-07-20T01:27:34.777Z","2.0.0-dev.1":"2024-07-20T01:34:22.112Z","2.0.0-dev.2":"2024-07-20T02:33:38.824Z","2.0.0-dev.3":"2024-07-21T18:29:51.451Z","2.0.0-dev.4":"2024-07-28T22:32:28.687Z","2.0.0-dev.5":"2024-07-29T01:26:42.487Z","2.0.0-dev.6":"2024-07-29T01:41:16.224Z","2.0.0-beta.0":"2025-11-30T02:06:30.388Z","2.0.0-beta.1":"2025-11-30T23:30:40.852Z","2.0.0-beta.2":"2025-12-01T00:43:30.475Z","2.0.0-beta.3":"2025-12-03T03:22:11.486Z","2.0.0-beta.4":"2025-12-05T22:03:19.179Z","2.0.0-beta.5":"2025-12-06T03:59:47.829Z","2.0.0-beta.6":"2025-12-08T00:02:28.733Z","2.0.0-beta.7":"2025-12-21T19:54:38.346Z","2.0.0-beta.8":"2025-12-24T04:17:13.328Z","2.0.0-beta.9":"2025-12-24T19:05:13.370Z","2.0.0":"2025-12-26T22:19:29.071Z","2.0.1-beta.0":"2026-01-09T00:43:35.285Z","2.0.1":"2026-01-10T21:43:32.752Z","2.0.2-beta.0":"2026-01-28T03:25:56.990Z","2.0.2-beta.1":"2026-02-06T22:34:50.036Z","2.0.2-beta.2":"2026-02-06T22:44:43.176Z","2.0.2":"2026-02-14T22:33:33.242Z"},"bugs":{"url":"https://github.com/bhj/KaraokeEternal/issues"},"author":{"name":"RadRoot LLC"},"license":"ISC","homepage":"https://www.karaoke-eternal.com","keywords":["karaoke","party","player","lyrics","cdgraphics","cdg","mp3+g","mp4","webgl"],"repository":{"type":"git","url":"git+https://github.com/bhj/KaraokeEternal.git"},"description":"Open karaoke party system","maintainers":[{"name":"radrootllc","email":"hi@radroot.com"}],"readme":"# Karaoke Eternal\n\nHost awesome karaoke parties where everyone can easily find and queue songs from their phone's browser. The player is also fully browser-based with support for MP3+G, MP4 videos and WebGL visualizations. The server is self-hosted and runs on nearly everything.\n\n[![Karaoke Eternal](/docs/assets/images/README.jpg?raw=true)](/docs/assets/images/README.jpg?raw=true)\n\n<p align=\"center\">\n  <i>App in mobile browser (top) controlling player in desktop browser (bottom)</i>\n</p>\n\n## Features\n\n- Plays:\n  - MP3+G (MP3 with CDG lyrics; including zipped)\n  - MP4 videos\n  - Music-synced visualizations (with automatic lyrics background removal)\n- Fast, modern mobile browser app designed for \"karaoke conditions\"\n- Easy joining with QR codes and guest accounts\n- Multiple simultaneous rooms/queues (optionally password-protected)\n- Dynamic queues keep parties fair, fun and no-fuss\n- Fully self-hosted\n- No ads or telemetry\n\nMicrophones are *not* required since the player itself only outputs music - this allows your audio setup to be as simple or complex as you like. See the [F.A.Q.](https://www.karaoke-eternal.com/faq/#recommended-audio-microphone-setup) for more information.\n\n## Getting Started\n\n Karaoke Eternal basically has 3 parts. See [Getting Started](https://www.karaoke-eternal.com/docs/getting-started/) to get up and running step-by-step, or jump to the documentation for each part below:\n \n- **[Server:](https://www.karaoke-eternal.com/docs/karaoke-eternal-server/)** Runs on pretty much anything to serve the web app and your media files, including a Windows PC, Mac, or a dedicated server like a Raspberry Pi or Synology NAS.\n- **[App:](https://www.karaoke-eternal.com/docs/karaoke-eternal-app/)** Fast, modern mobile web app designed for \"karaoke conditions\".\n- **[Player:](https://www.karaoke-eternal.com/docs/karaoke-eternal-app/#player)** Just another part of the app, but meant to run fullscreen on the system handling audio/video for a [room](https://www.karaoke-eternal.com/docs/karaoke-eternal-app/#rooms-admin-only)\n\n## Installation\n\nThere are several [installation methods](https://www.karaoke-eternal.com/docs/karaoke-eternal-server/#installation) available for Karaoke Eternal Server.\n\n## Discord & Support\n\nJoin the [Karaoke Eternal Discord Server](https://discord.gg/PgqVtFq) for general support and development chat, or just to say hi!\n\n## Contributing & Development\n\nContributions are welcome! Please join the `#dev` channel of the [Discord Server](https://discord.gg/PgqVtFq) before embarking on major features; the project's scope is limited to ensure success.\n\nMake sure you have [Node.js](https://nodejs.org/en/) v24 or later, then:\n\n1. Fork and clone the repo\n2. `npm i`\n3. `npm run dev` and look for \"Web server running at\" for the **server URL**\n","readmeFilename":"README.md"}