diff --git a/README.md b/README.md index 9dc3052..cded2df 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,20 @@ -CENTVRION +CENTURION ========= ## Introduction -The projects consists of two projects, a frontend written in React, and a backend written in javascript. Both communicate with a websocket. +The projects consists of two projects, a frontend written in React, and a backend written in Typescript (Node). Both communicate with a websocket. ## Setup -Download centurion.m4a and place it in frontend/public/centurion.m4a +1. Download the various song files and place them in `frontend/public/songs/`. Easiest way to do this is to get them from production (E.g. `https://centurion.svia.nl/songs/centurion.m4a`) +2. Run `npm i` in the root directory, frontend, and backend. +3. Prepare the pre-commit hooks by running `npm run prepare`. -Start the backend with `npm run app` and the frontend with `npm run start`. +ESLint is used for linting, Prettier for formatting. Currently, there are no tests. Tread carefully. + +## Starting + +* Start the frontend by running `npm run start` in the frontend directory. +* Idem for the backend. diff --git a/backend/.eslintrc.js b/backend/.eslintrc.js new file mode 100644 index 0000000..ea2fe81 --- /dev/null +++ b/backend/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + "ignorePatterns": [".eslintrc.js"], + "parserOptions": { + "tsconfigRootDir": __dirname, + "project": ["./tsconfig.json"] + } +}; diff --git a/backend/Dockerfile b/backend/Dockerfile index 7364ee9..a23f51c 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,11 +1,13 @@ -FROM node:13-alpine +FROM node:16-alpine WORKDIR /app -COPY package.json yarn.lock ./ -RUN yarn install +# Install TS manually since it's only included in the parent's package.json +RUN npm install --global typescript@^4.5.2 +COPY package.json package-lock.json ./ +RUN npm ci --no-progress --no-optional COPY tsconfig.json ./ - COPY src src/ -COPY data data/ -CMD ["npm", "run", "app"] +RUN npm run build + +CMD ["npm", "run", "start-compiled"] diff --git a/backend/package-lock.json b/backend/package-lock.json new file mode 100644 index 0000000..2688997 --- /dev/null +++ b/backend/package-lock.json @@ -0,0 +1,1455 @@ +{ + "name": "centurion-via-backend", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "centurion-via-backend", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "express": "^4.17.1", + "socket.io": "^4.4.0" + }, + "devDependencies": { + "@types/express": "^4.17.13", + "@types/node": "^16.11.12", + "ts-node": "^10.4.0" + } + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/component-emitter": { + "version": "1.2.11", + "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==" + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "node_modules/@types/cors": { + "version": "2.8.12", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + }, + "node_modules/@types/express": { + "version": "4.17.13", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.26", + "integrity": "sha512-zeu3tpouA043RHxW0gzRxwCHchMgftE8GArRsvYT0ByDMbn19olQHx5jLue0LxWY6iYtXb7rXmuVtSkhy9YZvQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "16.11.12", + "integrity": "sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/serve-static": { + "version": "1.13.10", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/accepts": { + "version": "1.3.7", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.6.0", + "integrity": "sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.1", + "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64id": { + "version": "2.0.0", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/body-parser": { + "version": "1.19.0", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bytes": { + "version": "3.1.0", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/cors": { + "version": "2.8.5", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/debug": { + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "node_modules/diff": { + "version": "4.0.2", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/engine.io": { + "version": "6.1.0", + "integrity": "sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw==", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.0", + "ws": "~8.2.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.0.2", + "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==", + "dependencies": { + "base64-arraybuffer": "~1.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.4.1", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.3", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/engine.io/node_modules/ms": { + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/escape-html": { + "version": "1.0.3", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/etag": { + "version": "1.8.1", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.17.1", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors": { + "version": "1.7.2", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/methods": { + "version": "1.1.2", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.51.0", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.34", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/negotiator": { + "version": "0.6.2", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.7.0", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/send": { + "version": "0.17.1", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node_modules/serve-static": { + "version": "1.14.1", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "node_modules/socket.io": { + "version": "4.4.0", + "integrity": "sha512-bnpJxswR9ov0Bw6ilhCvO38/1WPtE3eA2dtxi2Iq4/sFebiDJQzgKNYA7AuVVdGW09nrESXd90NbZqtDd9dzRQ==", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.1.0", + "socket.io-adapter": "~2.3.3", + "socket.io-parser": "~4.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.3.3", + "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==" + }, + "node_modules/socket.io-parser": { + "version": "4.0.4", + "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", + "dependencies": { + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.3", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser/node_modules/ms": { + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.3", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io/node_modules/ms": { + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/statuses": { + "version": "1.5.0", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-node": { + "version": "10.4.0", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "4.5.2", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ws": { + "version": "8.2.3", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yn": { + "version": "3.1.1", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.8", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "@types/body-parser": { + "version": "1.19.2", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/component-emitter": { + "version": "1.2.11", + "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==" + }, + "@types/connect": { + "version": "3.4.35", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/cookie": { + "version": "0.4.1", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "@types/cors": { + "version": "2.8.12", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + }, + "@types/express": { + "version": "4.17.13", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.26", + "integrity": "sha512-zeu3tpouA043RHxW0gzRxwCHchMgftE8GArRsvYT0ByDMbn19olQHx5jLue0LxWY6iYtXb7rXmuVtSkhy9YZvQ==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/mime": { + "version": "1.3.2", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "@types/node": { + "version": "16.11.12", + "integrity": "sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==" + }, + "@types/qs": { + "version": "6.9.7", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "@types/serve-static": { + "version": "1.13.10", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "accepts": { + "version": "1.3.7", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "8.6.0", + "integrity": "sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "arg": { + "version": "4.1.3", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "base64-arraybuffer": { + "version": "1.0.1", + "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==" + }, + "base64id": { + "version": "2.0.0", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, + "body-parser": { + "version": "1.19.0", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "bytes": { + "version": "3.1.0", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "component-emitter": { + "version": "1.3.0", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "content-disposition": { + "version": "0.5.3", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "cors": { + "version": "2.8.5", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "create-require": { + "version": "1.1.1", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "diff": { + "version": "4.0.2", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "engine.io": { + "version": "6.1.0", + "integrity": "sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw==", + "requires": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.0", + "ws": "~8.2.3" + }, + "dependencies": { + "cookie": { + "version": "0.4.1", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, + "debug": { + "version": "4.3.3", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "engine.io-parser": { + "version": "5.0.2", + "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==", + "requires": { + "base64-arraybuffer": "~1.0.1" + } + }, + "escape-html": { + "version": "1.0.3", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.1", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "finalhandler": { + "version": "1.1.2", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.2.0", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "http-errors": { + "version": "1.7.2", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.3", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.9.1", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "make-error": { + "version": "1.3.6", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.51.0", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + }, + "mime-types": { + "version": "2.1.34", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "requires": { + "mime-db": "1.51.0" + } + }, + "ms": { + "version": "2.0.0", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "object-assign": { + "version": "4.1.1", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "on-finished": { + "version": "2.3.0", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "parseurl": { + "version": "1.3.3", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "proxy-addr": { + "version": "2.0.7", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "qs": { + "version": "6.7.0", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send": { + "version": "0.17.1", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "socket.io": { + "version": "4.4.0", + "integrity": "sha512-bnpJxswR9ov0Bw6ilhCvO38/1WPtE3eA2dtxi2Iq4/sFebiDJQzgKNYA7AuVVdGW09nrESXd90NbZqtDd9dzRQ==", + "requires": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.1.0", + "socket.io-adapter": "~2.3.3", + "socket.io-parser": "~4.0.4" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "socket.io-adapter": { + "version": "2.3.3", + "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==" + }, + "socket.io-parser": { + "version": "4.0.4", + "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", + "requires": { + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "statuses": { + "version": "1.5.0", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "toidentifier": { + "version": "1.0.0", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "ts-node": { + "version": "10.4.0", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + } + }, + "type-is": { + "version": "1.6.18", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typescript": { + "version": "4.5.2", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "dev": true, + "peer": true + }, + "unpipe": { + "version": "1.0.0", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "ws": { + "version": "8.2.3", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "requires": {} + }, + "yn": { + "version": "3.1.1", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/backend/package.json b/backend/package.json index 4f83c0d..42bfef4 100644 --- a/backend/package.json +++ b/backend/package.json @@ -5,18 +5,21 @@ "main": "./src/index.js", "scripts": { "build": "tsc", - "app": "ts-node src/index.ts" + "start-compiled": "node build/index.js", + "start": "ts-node src/index.ts", + "check": "tsc --noEmit", + "lint": "eslint 'src/**/*.{ts,tsx}'", + "fix": "eslint --fix 'src/**/*.{ts,tsx}'" }, "author": "", "license": "ISC", "dependencies": { "express": "^4.17.1", - "socket.io": "^2.3.0" + "socket.io": "^4.4.0" }, "devDependencies": { - "@types/express": "^4.17.6", - "@types/socket.io": "^2.1.4", - "ts-node": "^8.8.2", - "typescript": "^3.8.3" + "@types/express": "^4.17.13", + "@types/node": "^16.11.12", + "ts-node": "^10.4.0" } } diff --git a/backend/src/Room.ts b/backend/src/Room.ts index ba5bf77..2d7be79 100644 --- a/backend/src/Room.ts +++ b/backend/src/Room.ts @@ -1,210 +1,167 @@ -import {Socket} from "socket.io"; - import User from "./User"; -import {getIndex, getNextShot, getTimeline, getTimelineNames, indexForTime} from "./timeline"; -import {getCurrentTime} from "./util"; +import { getTimeline, getTimelineNames } from "./timeline"; +import { getCurrentTime } from "./util"; export interface RoomOptions { - seekTime: number - timelineName: string + seekTime: number; + timelineName: string; +} + +export interface TickerMessage { + user: User; + message: string; +} + +// FIXME: dedupe with frontend +export interface SerializedRoom { + id: number; + userCount: number; + isLeader: boolean; + running: boolean; + startTime?: number; + seekTime: number; + timelineName: string; + readyToParticipate: boolean; + speedFactor: number; + ticker: string[]; + users?: { id: string; readyToParticipate: boolean }[]; } export default class Room { - id: number = 0; - users: User[] = []; - leader: User | null = null; + id = 0; + users: User[] = []; + leader: User | null = null; - running = false; - startTime = 0; - currentSeconds = 0; - timelineIndex: number = 0; + ticker: TickerMessage[] = []; - seekTime: number = 0; - timelineName: string = 'Centurion'; + running = false; + startTime: number | undefined = undefined; - // For debugging purposes - speedFactor = 1; - autoStart = false; + seekTime = 0; + timelineName = "Centurion"; - constructor(name: number) { - this.id = name; - } + // For debugging purposes + speedFactor = 1; - serialize(user: User) { - return { - 'id': this.id, - 'userCount': this.users.length, - 'isLeader': this.leader == user, - 'running': this.running, - 'startTime': this.startTime, - 'timelineName': this.timelineName, - 'seekTime': this.seekTime, - 'readyToParticipate': user.readyToParticipate || this.leader == user, - 'speedFactor': this.speedFactor - } - } + constructor(name: number) { + this.id = name; + } - serializeTimeline(user: User) { - return getTimeline(this.timelineName); - } + serialize(user?: User) { + const obj: SerializedRoom = { + id: this.id, + userCount: this.users.length, + isLeader: this.leader === user, + running: this.running, + startTime: this.startTime, + timelineName: this.timelineName, + seekTime: this.seekTime, + readyToParticipate: this.getLeader()?.readyToParticipate || false, + speedFactor: this.speedFactor, + ticker: this.ticker.map((i) => i.message), + }; - sync() { - this.users.forEach(u => u.sync()); + if (typeof user === "undefined" || this.leader === user) { + obj["users"] = this.users.map((u) => u.serialize()); } - join(user: User) { - this.users.push(user); - user.setRoom(this); + return obj; + } - if (!this.hasLeader()) { - this.setLeader(user); - } + serializeTimeline() { + return getTimeline(this.timelineName); + } - if (this.autoStart) { - this.seekTime = 2500000; - this.running = true; - this.start(); - } + sync() { + this.users.forEach((u) => u.sync()); + } - this.sync(); + async join(user: User) { + this.users.push(user); + await user.setRoom(this); + + if (!this.hasLeader()) { + this.setLeader(user); } - leave(user: User) { - this.users.splice(this.users.indexOf(user), 1); - user.setRoom(null); + this.sync(); + } - if (this.leader == user) { - this.setRandomLeader(); - } + async leave(user: User) { + this.removeTickerMessageForUser(user); + this.users.splice(this.users.indexOf(user), 1); + await user.setRoom(null); - this.sync(); + if (this.leader == user) { + this.setRandomLeader(); } - onBeforeDelete() { - } + this.sync(); + } - setOptions(options: any) { - this.seekTime = Math.max(0, Math.min(options.seekTime, 250 * 60 * 1000)) - if (getTimelineNames().indexOf(options.timelineName) >= 0) { - this.timelineName = options.timelineName; - } - this.sync() + setOptions(options: { seekTime: number; timelineName: string }) { + this.seekTime = Math.max(0, Math.min(options.seekTime, 250 * 60 * 1000)); + if (getTimelineNames().indexOf(options.timelineName) >= 0) { + this.timelineName = options.timelineName; } + this.sync(); + } - start() { - this.running = true; - this.startTime = getCurrentTime() - this.seekTime + start() { + this.running = true; + this.startTime = getCurrentTime() - this.seekTime; + this.sync(); + } - this.sync(); - } + /** + * + * @returns {boolean} + */ + hasUsers() { + return this.users.length !== 0; + } - run(io: Socket) { - this.running = true; - this.startTime = Date.now(); - - // io.to(this.id.toString()).emit('timeline', { - // 'timeline': { - // } - // }); - - const doTick = () => { - if (this.users.length === 0) { - // this room is over. - return; - } - - const timestamp = getIndex(this.timelineIndex); - const nextShot = getNextShot(this.timelineIndex); - - if (!timestamp) { - // We are done. - io.to(this.id.toString()).emit('tick_event', { - tick: { - current: this.currentSeconds - } - }); - console.log("Done"); - this.running = false; - return; - } - - console.log("ticking", this.currentSeconds); - - io.to(this.id.toString()).emit('tick_event', { - tick: { - current: this.currentSeconds, - next: timestamp, - nextShot: nextShot - } - }); - - if (this.currentSeconds >= timestamp.timestamp) { - this.timelineIndex += 1; - } - - this.currentSeconds += 1; - // We spend some time processing, wait a bit less than 1000ms - const nextTickTime = this.startTime + (1000 * this.currentSeconds / this.speedFactor); - const waitTime = nextTickTime - Date.now(); - console.log("waiting", waitTime); - setTimeout(doTick, Math.floor(waitTime / this.speedFactor)); - }; - - doTick(); + setRandomLeader() { + if (this.hasUsers()) { + this.leader = this.users[0]; } + } - /** - * - * @param io - * @param {number} time - */ - seek(io: Socket, time: number) { - this.currentSeconds = time; - this.startTime = Date.now() - time * 1000; - this.timelineIndex = indexForTime(this.currentSeconds); - io.to(this.id.toString()).emit('seek', time); - } + hasLeader(): boolean { + return this.leader != null; + } - /** - * - * @returns {boolean} - */ - hasUsers() { - return this.users.length !== 0; - } + setLeader(user: User) { + this.leader = user; + } - setRandomLeader() { - if (this.hasUsers()) { - this.leader = this.users[0]; - } - } + getLeader(): User | null { + return this.leader; + } - /** - * - * @param id - * @returns {User|undefined} - */ - getUser(id: string) { - return this.users.find(u => u.id === id); - } + submitTickerMessage(user: User, message: string) { + message = message.replace("\n", ""); - /** - * - * @param {string} id - */ - removeUser(id: string) { - this.users = this.users.filter(u => u.id !== id); - } + this.removeTickerMessageForUser(user); - hasLeader(): boolean { - return this.leader != null; - } + this.ticker.push({ + user: user, + message: message, + }); - setLeader(user: User) { - this.leader = user; - } + this.sync(); + } - getLeader(): User | null { - return this.leader; + removeTickerMessageForUser(user: User) { + let existing = -1; + for (let i = 0; i < this.ticker.length; i++) { + if (this.ticker[i].user === user) { + existing = i; + break; + } } -}; + if (existing >= 0) { + this.ticker.splice(existing, 1); + } + } +} diff --git a/backend/src/Service.ts b/backend/src/Service.ts index 8a5456e..4041ffb 100644 --- a/backend/src/Service.ts +++ b/backend/src/Service.ts @@ -1,140 +1,163 @@ -import {Socket} from "socket.io"; +import { Socket } from "socket.io"; -import User from './User' -import Room, {RoomOptions} from './Room' -import {getCurrentTime, randomInt} from "./util"; +import User from "./User"; +import Room, { RoomOptions } from "./Room"; +import { getCurrentTime } from "./util"; export default class Service { - private roomIdToRooms = new Map(); - private socketsToUsers = new Map(); + private roomIdToRooms = new Map(); + private socketsToUsers = new Map(); - onSocketConnect(socket: Socket) { - let user = new User(socket); - this.socketsToUsers.set(socket.id, user); - user.sync(); + get rooms(): Room[] { + const rooms = []; + for (const [, room] of this.roomIdToRooms) { + rooms.push(room); } - onSocketDisconnect(socket: Socket) { - let user = this.getUser(socket); + return rooms; + } - if (user.room != null) { - user.room.leave(user); - } + onSocketConnect(socket: Socket) { + const user = new User(socket); + this.socketsToUsers.set(socket.id, user); + user.sync(); + } - this.deleteEmptyRooms(); + async onSocketDisconnect(socket: Socket) { + const user = this.getUser(socket); - user.onDisconnect(); + if (user.room != null) { + await user.room.leave(user); } - onTimeSync(socket: Socket, requestId: number, clientTime: number) { - let user = this.getUser(socket); + this.deleteEmptyRooms(); + } - let now = getCurrentTime(); - user.emit('time_sync', { - 'requestId': requestId, - 'clientDiff': now - clientTime, - 'serverTime': now - }) - } - - onSetRoomOptions(socket: Socket, options: RoomOptions) { - let user = this.getUser(socket); + onTimeSync(socket: Socket, requestId: number, clientTime: number) { + const user = this.getUser(socket); - if (user.room?.getLeader() == user) { - user.room!!.setOptions(options) - } - } + const now = getCurrentTime(); + user.emit("time_sync", { + requestId: requestId, + clientDiff: now - clientTime, + serverTime: now, + }); + } - onRequestStart(socket: Socket) { - let user = this.getUser(socket); + onSetRoomOptions(socket: Socket, options: RoomOptions) { + const user = this.getUser(socket); - if (user.room?.getLeader() == user) { - user.room!!.start(); - } + if (user.room?.getLeader() == user) { + user.room.setOptions(options); } + } - onRequestJoin(socket: Socket, roomId: number): boolean { - let user = this.getUser(socket); - if (user.room && user.room.id == roomId) return false; + onRequestStart(socket: Socket) { + const user = this.getUser(socket); - if (user.room) { - user.room.leave(user); - this.deleteEmptyRooms(); - } + if (user.room?.getLeader() === user) { + user.room.start(); + user.room.sync(); + } + } - if (!this.roomIdToRooms.has(roomId)) { - this.createRoomWithId(roomId); - } + async onRequestJoin(socket: Socket, roomId: number) { + const user = this.getUser(socket); + if (user.room && user.room.id == roomId) return false; - let room = this.roomIdToRooms.get(roomId)!!; - room.join(user); + if (user.room) { + await user.room.leave(user); + this.deleteEmptyRooms(); + } - return true; + if (!this.roomIdToRooms.has(roomId)) { + this.createRoomWithId(roomId); } - onRequestReady(socket: Socket) { - let user = this.getUser(socket); - if (!user.room || user.readyToParticipate) return; - user.readyToParticipate = true; - user.sync(); + const room = this.roomIdToRooms.get(roomId); + if (!room) { + return false; } - onRequestJoinRandom(socket: Socket) { - let user = this.getUser(socket); + await room.join(user); - if (user.room) { - user.room.leave(user); - this.deleteEmptyRooms(); - } + return true; + } - const room = this.createRandomRoom(); - if (!room) throw Error('Too many rooms active'); - room.join(user); - } + onRequestSetReady(socket: Socket) { + const user = this.getUser(socket); + if (!user.room || user.readyToParticipate) return; + user.readyToParticipate = true; + user.room.sync(); + } - hasRoomId(roomId: number): boolean { - return this.roomIdToRooms.has(roomId); - } + async onRequestJoinRandom(socket: Socket) { + const user = this.getUser(socket); - private getUser(socket: Socket): User { - let user = this.socketsToUsers.get(socket.id); - if (!user) { - throw new Error('User not found'); - } - return user; + if (user.room) { + await user.room.leave(user); + this.deleteEmptyRooms(); } - private deleteEmptyRooms() { - for (let room of this.roomIdToRooms.values()) { - if (room.users.length == 0) { - this.deleteRoom(room); - } - } - } + const room = this.createRandomRoom(); + if (!room) throw Error("Too many rooms active"); + await room.join(user); + } + + hasRoomId(roomId: number): boolean { + return this.roomIdToRooms.has(roomId); + } - private createRandomRoom(): Room | null { - let tries = 0; - while (tries++ < 1000) { - const randomId = randomInt(100, Math.max(1000, this.roomIdToRooms.size * 2)); - if (this.roomIdToRooms.has(randomId)) continue; + submitTickerMessage(socket: Socket, message: string) { + const user = this.getUser(socket); - return this.createRoomWithId(randomId); - } - return null; + if (!user.room) { + throw new Error("User has no room"); } - private createRoomWithId(roomId: number): Room { - if (this.roomIdToRooms.has(roomId)) { - throw new Error('A room with the given id already exists'); - } + user.room.submitTickerMessage(user, message); + } - let room = new Room(roomId); - this.roomIdToRooms.set(roomId, room); - return room; + private getUser(socket: Socket): User { + const user = this.socketsToUsers.get(socket.id); + if (!user) { + throw new Error("User not found"); + } + return user; + } + + private deleteEmptyRooms() { + for (const room of this.roomIdToRooms.values()) { + if (room.users.length == 0) { + this.deleteRoom(room); + } } + } + + private createRandomRoom(): Room | null { + let tries = 0; + let i = 1; + while (tries++ < 1000) { + if (this.roomIdToRooms.has(i)) { + i++; + } else { + return this.createRoomWithId(i); + } + } + return null; + } - private deleteRoom(room: Room) { - this.roomIdToRooms.get(room.id)!!.onBeforeDelete(); - this.roomIdToRooms.delete(room.id) + private createRoomWithId(roomId: number): Room { + if (this.roomIdToRooms.has(roomId)) { + throw new Error("A room with the given id already exists"); } + + const room = new Room(roomId); + this.roomIdToRooms.set(roomId, room); + return room; + } + + private deleteRoom(room: Room) { + this.roomIdToRooms.delete(room.id); + } } diff --git a/backend/src/User.ts b/backend/src/User.ts index b40145e..ecb4520 100644 --- a/backend/src/User.ts +++ b/backend/src/User.ts @@ -1,108 +1,131 @@ -import {Socket} from "socket.io"; +import { Socket } from "socket.io"; -import Room from "./Room"; -import {getTimelineNames} from "./timeline"; +import Room, { SerializedRoom } from "./Room"; +import { getTimelineNames } from "./timeline"; -export default class User { - socket: Socket; - id: string; - - room: Room | null = null; - readyToParticipate: boolean = false; +export interface Config { + availableTimelines: string[]; +} - constructor(socket: Socket) { - this.socket = socket; - this.id = socket.id; +export default class User { + socket: Socket; + id: string; + + room: Room | null = null; + readyToParticipate = false; + + constructor(socket: Socket) { + this.socket = socket; + this.id = socket.id; + } + + serialize() { + return { + id: this.id, + readyToParticipate: this.readyToParticipate, + }; + } + + async setRoom(room: Room | null) { + if (this.room === room) return; + + if (this.room !== null) { + await this.socket.leave(this.room.id.toString()); + this.readyToParticipate = false; } - onDisconnect() { - if (this.room != null) { + this.room = room; - } + if (this.room !== null) { + await this.socket.join(this.room.id.toString()); } - setRoom(room: Room | null) { - if (this.room === room) return; + this.sync(); + } + + getConfig() { + return { + availableTimelines: getTimelineNames(), + }; + } + + sentConfig: Config | null = null; + sentRoom: SerializedRoom | null = null; + sentTimelineName: string | null = null; + + sync() { + // Config + const config = this.getConfig(); + if (!this.syncEquals(this.sentConfig, config)) { + this.sentConfig = Object.assign({}, config); + this.emit("config", { + config: this.sentConfig, + }); + } - if (this.room != null) { - this.socket.leave(this.room.id.toString()); - this.readyToParticipate = false; - } + // Room + if (!this.syncEquals(this.sentRoom, this.room?.serialize(this))) { + this.sentRoom = this.room + ? (JSON.parse( + JSON.stringify(this.room.serialize(this)) + ) as SerializedRoom) + : null; + + this.emit("room", { + room: this.sentRoom, + }); + } - this.room = room; + // Timeline + if (!this.syncEquals(this.sentTimelineName, this.room?.timelineName)) { + this.sentTimelineName = this.room?.timelineName || null; + this.emit("timeline", { + timeline: + this.sentTimelineName == null ? null : this.room?.serializeTimeline(), + }); + } + } - if (this.room != null) { - this.socket.join(this.room.id.toString()); - } + emit(eventName: string, obj: unknown) { + this.socket.emit(eventName, obj); + } - this.sync(); + syncEquals(obj1: unknown, obj2: unknown): boolean { + if (typeof obj1 !== typeof obj2) { + return false; } - getConfig() { - return { - 'availableTimelines': getTimelineNames() - } + if (typeof obj1 !== "object") { + // Both are not 'object' + return Object.is(obj1, obj2); } - sentConfig: any = null; - sentRoom: any = null; - sentTimelineName: string | null = null; - - sync() { - // Config - let config = this.getConfig(); - if (!this.syncEquals(this.sentConfig, config)) { - this.sentConfig = config; - this.emit('config', { - 'config': this.sentConfig - }); - } - - // Room - if (!this.syncEquals(this.sentRoom, this.room?.serialize(this))) { - this.sentRoom = this.room?.serialize(this); - this.emit('room', { - 'room': this.sentRoom - }) - } - - // Timeline - if (!this.syncEquals(this.sentTimelineName, this.room?.timelineName)) { - this.sentTimelineName = this.room?.timelineName || null; - this.emit('timeline', { - 'timeline': this.sentTimelineName == null ? null : this.room!!.serializeTimeline(this) - }) - } + if (obj1 === null && obj2 === null) { + return true; } - emit(eventName: string, obj: any) { - this.socket.emit(eventName, obj); + if (obj1 === null || obj2 === null) { + return false; } - syncEquals(obj1: any, obj2: any): boolean { - if (obj1 === undefined && obj2 === undefined) - return true; - - if ((obj1 === undefined && obj2 !== undefined) || (obj1 !== undefined && obj2 === undefined)) - return false; - - if (obj1 === null && obj2 === null) - return true; - - if ((obj1 === null && obj2 !== null) || (obj1 !== null && obj2 === null)) - return false; - - if (typeof (obj1) !== typeof (obj2)) - return false; - - if (typeof (obj1) === 'string' || typeof (obj1) === 'number' || typeof (obj1) === 'boolean') { - return obj1 === obj2; - } - - if (Object.keys(obj1).length !== Object.keys(obj2).length) return false + if (typeof obj2 !== "object") { + // This can not happen ;) + throw new TypeError("Obj2 is not object while obj1 is."); + } - return Object.keys(obj1).every(key => - obj2.hasOwnProperty(key) && this.syncEquals(obj1[key], obj2[key]) - ); + if (Object.keys(obj1).length !== Object.keys(obj2).length) { + return false; } + + return Object.keys(obj1).every((key: string) => { + if (!(key in obj1) || !(key in obj2)) { + return false; + } + + return this.syncEquals( + obj1[key as keyof object], + obj2[key as keyof object] + ); + }); + } } diff --git a/backend/data/timelines.js b/backend/src/data/timelines.ts similarity index 53% rename from backend/data/timelines.js rename to backend/src/data/timelines.ts index 97ed8f7..7b536e2 100644 --- a/backend/data/timelines.js +++ b/backend/src/data/timelines.ts @@ -1,2774 +1,2132 @@ -module.exports = { - 'timelines': [ - { - 'name': 'Centurion', - 'songFile': 'songs/centurion.mp3', - 'feed': [ +// FIXME: dedupes these types from front-end +export interface TimelineItem { + id?: string; + timestamp: number; + events: TimestampEvent[]; +} - { - "timestamp": 0, - "events": [ - { - "type": "shot", - "text": [ - "Zet je schrap!", - "We gaan zo beginnen" - ], - "shotCount": 0 - } - ] - }, - { - "timestamp": 42, - "events": [ - { - "type": "talk", - "text": [ - "Daar gaan we!", - "Dit was het startsein, je hoeft nog niet te drinken" - ] - }, - { - "type": "song", - "text": [ - "Nena", - "99 Luftballons" - ] - } - ] - }, - { - "timestamp": 108, - "events": [ - { - "type": "shot", - "text": [ - "De eerste!", - "Nog 99 shotjes" - ], - "shotCount": 1 - } - ] - }, - { - "timestamp": 148, - "events": [ - { - "type": "song", - "text": [ - "Hermes House Band", - "Country Roads" - ] - } - ] - }, - { - "timestamp": 167, - "events": [ - { - "type": "shot", - "text": [ - "Nummertje twee!", - "Nog 98 shotjes" - ], - "shotCount": 2 - } - ] - }, - { - "timestamp": 185, - "events": [ - { - "type": "song", - "text": [ - "Vinzzent", - "Dromendans" - ] - } - ] - }, - { - "timestamp": 223, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 97 shotjes" - ], - "shotCount": 3 - }, - { - "type": "song", - "text": [ - "Linda, Roos & Jessica", - "Ademnood" - ] - } - ] - }, - { - "timestamp": 283, - "events": [ - { - "type": "shot", - "text": [ - "Lustrum!", - "Nog 96 shotjes" - ], - "shotCount": 4 - }, - { - "type": "song", - "text": [ - "Peter de Koning", - "Het is altijd lente in de ogen van de tandarts-assistente" - ] - } - ] - }, - { - "timestamp": 340, - "events": [ - { - "type": "shot", - "text": [ - "Niet gooien!", - "Nog 95 shotjes" - ], - "shotCount": 5 - }, - { - "type": "song", - "text": [ - "Liquido", - "Narcotic" - ] - } - ] - }, - { - "timestamp": 412, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 94 shotjes" - ], - "shotCount": 6 - }, - { - "type": "song", - "text": [ - "Snoop Dogg feat. Pharrell", - "Drop It Like It's Hot" - ] - } - ] - }, - { - "timestamp": 449, - "events": [ - { - "type": "song", - "text": [ - "M.O.P.", - "Ante Up" - ] - } - ] - }, - { - "timestamp": 459, - "events": [ - { - "type": "shot", - "text": [ - "Pweeeep!", - "Nog 93 shotjes" - ], - "shotCount": 7 - } - ] - }, - { - "timestamp": 514, - "events": [ - { - "type": "shot", - "text": [ - "Trek een ad!", - "Nog 92 shotjes" - ], - "shotCount": 8 - }, - { - "type": "song", - "text": [ - "Los Del Rio", - "Macarena" - ] - } - ] - }, - { - "timestamp": 560, - "events": [ - { - "type": "song", - "text": [ - "Spice Girls", - "Wannabe" - ] - } - ] - }, - { - "timestamp": 574, - "events": [ - { - "type": "shot", - "text": [ - "We zijn er nog lang niet!", - "Nog 91 shotjes" - ], - "shotCount": 9 - } - ] - }, - { - "timestamp": 617, - "events": [ - { - "type": "song", - "text": [ - "Major Lazer feat. Busy Signal, The Flexican & FS Green", - "Watch Out For This (Bumaye)" - ] - } - ] - }, - { - "timestamp": 635, - "events": [ - { - "type": "shot", - "text": [ - "Nummer tien!", - "Nog 90 shotjes" - ], - "shotCount": 10 - } - ] - }, - { - "timestamp": 647, - "events": [ - { - "type": "time", - "text": [ - "Nog 90 minuten!", - "Geef alles, behalve op" - ] - } - ] - }, - { - "timestamp": 684, - "events": [ - { - "type": "song", - "text": [ - "Kabouter Plop", - "Kabouterdans" - ] - } - ] - }, - { - "timestamp": 699, - "events": [ - { - "type": "shot", - "text": [ - "Met vriendelijke toet!", - "Nog 89 shotjes" - ], - "shotCount": 11 - } - ] - }, - { - "timestamp": 725, - "events": [ - { - "type": "song", - "text": [ - "K3", - "Alle kleuren" - ] - } - ] - }, - { - "timestamp": 756, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 88 shotjes" - ], - "shotCount": 12 - } - ] - }, - { - "timestamp": 757, - "events": [ - { - "type": "song", - "text": [ - "Kinderen voor Kinderen", - "Tietenlied" - ] - } - ] - }, - { - "timestamp": 812, - "events": [ - { - "type": "shot", - "text": [ - "Ongeluksshotje 13!", - "Nog 87 shotjes" - ], - "shotCount": 13 - } - ] - }, - { - "timestamp": 814, - "events": [ - { - "type": "song", - "text": [ - "Guus Meeuwis", - "Het dondert en het bliksemt" - ] - } - ] - }, - { - "timestamp": 820, - "events": [ - { - "type": "talk", - "text": [ - "Carnaval is prachtig!", - "Leve de vervoerie" - ] - } - ] - }, - { - "timestamp": 874, - "events": [ - { - "type": "shot", - "text": [ - "Pweeeep!", - "Nog 86 shotjes" - ], - "shotCount": 14 - } - ] - }, - { - "timestamp": 876, - "events": [ - { - "type": "song", - "text": [ - "Harry Vermeegen", - "1-2-3-4 Dennis bier" - ] - } - ] - }, - { - "timestamp": 906, - "events": [ - { - "type": "song", - "text": [ - "Puhdys", - "Hey, wir woll’n die Eisbär'n sehn!" - ] - } - ] - }, - { - "timestamp": 935, - "events": [ - { - "type": "shot", - "text": [ - "Fünfzehn!", - "Nog 85 shotjes" - ], - "shotCount": 15 - } - ] - }, - { - "timestamp": 966, - "events": [ - { - "type": "song", - "text": [ - "DJ Ötzi", - "Burger Dance" - ] - } - ] - }, - { - "timestamp": 995, - "events": [ - { - "type": "shot", - "text": [ - "Toet!", - "Nog 84 shotjes" - ], - "shotCount": 16 - } - ] - }, - { - "timestamp": 996, - "events": [ - { - "type": "song", - "text": [ - "Mickie Krause", - "Hütte auf der Alm" - ] - } - ] - }, - { - "timestamp": 1030, - "events": [ - { - "type": "song", - "text": [ - "Ali B & Yes-R & The Partysquad", - "Rampeneren" - ] - } - ] - }, - { - "timestamp": 1046, - "events": [ - { - "type": "shot", - "text": [ - "Zuipen!", - "Nog 83 shotjes" - ], - "shotCount": 17 - } - ] - }, - { - "timestamp": 1107, - "events": [ - { - "type": "shot", - "text": [ - "Met dank aan bestuur 19; super 'vo", - "Nog 82 shotjes" - ], - "shotCount": 18 - }, - { - "type": "song", - "text": [ - "Martin Solveig", - "Intoxicated" - ] - } - ] - }, - { - "timestamp": 1137, - "events": [ - { - "type": "song", - "text": [ - "Nicki Minaj", - "Starships" - ] - } - ] - }, - { - "timestamp": 1173, - "events": [ - { - "type": "shot", - "text": [ - "Laatste shotje als tiener!", - "Nog 81 shotjes" - ], - "shotCount": 19 - } - ] - }, - { - "timestamp": 1222, - "events": [ - { - "type": "song", - "text": [ - "2Unlimited", - "Get Ready For This" - ] - } - ] - }, - { - "timestamp": 1233, - "events": [ - { - "type": "time", - "text": [ - "Nog 80 minuten!", - "Al 19 shotjes achter de rug" - ] - } - ] - }, - { - "timestamp": 1235, - "events": [ - { - "type": "shot", - "text": [ - "Adje!", - "Nog 80 shotjes" - ], - "shotCount": 20 - } - ] - }, - { - "timestamp": 1275, - "events": [ - { - "type": "song", - "text": [ - "The Village People", - "YMCA" - ] - } - ] - }, - { - "timestamp": 1288, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 79 shotjes" - ], - "shotCount": 21 - } - ] - }, - { - "timestamp": 1348, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 78 shotjes" - ], - "shotCount": 22 - } - ] - }, - { - "timestamp": 1350, - "events": [ - { - "type": "song", - "text": [ - "Carly Rae Jepsen ft Owl City", - "It's Always A Good Time" - ] - } - ] - }, - { - "timestamp": 1395, - "events": [ - { - "type": "song", - "text": [ - "Avicii", - "Levels" - ] - } - ] - }, - { - "timestamp": 1411, - "events": [ - { - "type": "shot", - "text": [ - "Claxon!", - "Nog 77 shotjes" - ], - "shotCount": 23 - } - ] - }, - { - "timestamp": 1456, - "events": [ - { - "type": "song", - "text": [ - "Flo-Rida feat. T-Pain", - "Low" - ] - } - ] - }, - { - "timestamp": 1471, - "events": [ - { - "type": "shot", - "text": [ - "En nu even op standje maximaal!", - "Nog 76 shotjes" - ], - "shotCount": 24 - } - ] - }, - { - "timestamp": 1486, - "events": [ - { - "type": "song", - "text": [ - "Taio Cruz", - "Hangover" - ] - } - ] - }, - { - "timestamp": 1522, - "events": [ - { - "type": "talk", - "text": [ - "Dit is nog het rustige stukje!", - "Zet hem maar op de bonk-bonk" - ] - } - ] - }, - { - "timestamp": 1530, - "events": [ - { - "type": "shot", - "text": [ - "Halve Abraham!", - "Nog 75 shotjes" - ], - "shotCount": 25 - } - ] - }, - { - "timestamp": 1545, - "events": [ - { - "type": "song", - "text": [ - "LMFAO", - "Party Rock Anthem" - ] - } - ] - }, - { - "timestamp": 1594, - "events": [ - { - "type": "shot", - "text": [ - "Hoch die Hände!", - "Nog 74 shotjes" - ], - "shotCount": 26 - }, - { - "type": "song", - "text": [ - "Hans Entertainment vs. Finger & Kadel", - "Hoch die Hände" - ] - } - ] - }, - { - "timestamp": 1623, - "events": [ - { - "type": "song", - "text": [ - "Galantis", - "No Money" - ] - } - ] - }, - { - "timestamp": 1653, - "events": [ - { - "type": "shot", - "text": [ - "Voel je 'm al?", - "Nog 73 shotjes" - ], - "shotCount": 27 - } - ] - }, - { - "timestamp": 1683, - "events": [ - { - "type": "song", - "text": [ - "Kid Cudi", - "Pursuit of Happiness (Steve Aoki remix)" - ] - } - ] - }, - { - "timestamp": 1712, - "events": [ - { - "type": "shot", - "text": [ - "Project X!", - "Nog 72 shotjes" - ], - "shotCount": 28 - } - ] - }, - { - "timestamp": 1741, - "events": [ - { - "type": "song", - "text": [ - "Yeah Yeah Yeahs", - "Heads Will Roll (A-Trak remix)" - ] - } - ] - }, - { - "timestamp": 1769, - "events": [ - { - "type": "shot", - "text": [ - "Pweeeep!", - "Nog 71 shotjes" - ], - "shotCount": 29 - } - ] - }, - { - "timestamp": 1814, - "events": [ - { - "type": "song", - "text": [ - "Michael Calfan", - "Resurrection" - ] - } - ] - }, - { - "timestamp": 1825, - "events": [ - { - "type": "time", - "text": [ - "Nog 70 minuten!", - "Half uurtje zit erop" - ] - } - ] - }, - { - "timestamp": 1829, - "events": [ - { - "type": "shot", - "text": [ - "Toet!", - "Nog 70 shotjes" - ], - "shotCount": 30 - } - ] - }, - { - "timestamp": 1858, - "events": [ - { - "type": "song", - "text": [ - "Basto!", - "Again and Again" - ] - } - ] - }, - { - "timestamp": 1887, - "events": [ - { - "type": "shot", - "text": [ - "Over de dertig!", - "Nog 69 (hehe) shotjes" - ], - "shotCount": 31 - } - ] - }, - { - "timestamp": 1916, - "events": [ - { - "type": "song", - "text": [ - "David Guetaa feat. Sia", - "Titanium" - ] - } - ] - }, - { - "timestamp": 1945, - "events": [ - { - "type": "shot", - "text": [ - "Trek een ad!", - "Nog 68 shotjes" - ], - "shotCount": 32 - } - ] - }, - { - "timestamp": 1959, - "events": [ - { - "type": "song", - "text": [ - "Gala", - "Freed From Desire" - ] - } - ] - }, - { - "timestamp": 2004, - "events": [ - { - "type": "shot", - "text": [ - "Nummertje 33!", - "Nog 67 shotjes!" - ], - "shotCount": 33 - } - ] - }, - { - "timestamp": 2034, - "events": [ - { - "type": "song", - "text": [ - "Wolter Kroes", - "Viva Hollandia" - ] - } - ] - }, - { - "timestamp": 2064, - "events": [ - { - "type": "shot", - "text": [ - "Voor het vaderland!", - "Nog 66 shotjes" - ], - "shotCount": 34 - } - ] - }, - { - "timestamp": 2125, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 65 shotjes" - ], - "shotCount": 35 - } - ] - }, - { - "timestamp": 2128, - "events": [ - { - "type": "song", - "text": [ - "Westlife", - "Uptown Girl" - ] - } - ] - }, - { - "timestamp": 2179, - "events": [ - { - "type": "song", - "text": [ - "Aqua", - "Barbie Girl" - ] - } - ] - }, - { - "timestamp": 2194, - "events": [ - { - "type": "shot", - "text": [ - "Pweeeep!", - "Nog 64 shotjes" - ], - "shotCount": 36 - } - ] - }, - { - "timestamp": 2225, - "events": [ - { - "type": "song", - "text": [ - "Guillerma & Tropical Danny", - "Toppertje" - ] - } - ] - }, - { - "timestamp": 2245, - "events": [ - { - "type": "shot", - "text": [ - "In dat keelgaatje!", - "Nog 63 shotjes" - ], - "shotCount": 37 - } - ] - }, - { - "timestamp": 2305, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 62 shotjes" - ], - "shotCount": 38 - }, - { - "type": "song", - "text": [ - "The Bloody Beetroots feat. Steve Aoki", - "Warp 1.9" - ] - } - ] - }, - { - "timestamp": 2374, - "events": [ - { - "type": "shot", - "text": [ - "Toet!", - "Nog 61 shotjes" - ], - "shotCount": 39 - }, - { - "type": "song", - "text": [ - "David Guetta & Showtek feat. Vassy", - "Bad" - ] - } - ] - }, - { - "timestamp": 2431, - "events": [ - { - "type": "shot", - "text": [ - "40 alweer!", - "Nog 60 shotjes" - ], - "shotCount": 40 - }, - { - "type": "song", - "text": [ - "Showtek & Justin Prime", - "Cannonball" - ] - } - ] - }, - { - "timestamp": 2444, - "events": [ - { - "type": "time", - "text": [ - "Nog 60 minuten!", - "Een klein uurtje" - ] - } - ] - }, - { - "timestamp": 2460, - "events": [ - { - "type": "song", - "text": [ - "Die Atzen", - "Disco Pogo" - ] - } - ] - }, - { - "timestamp": 2489, - "events": [ - { - "type": "shot", - "text": [ - "Zuipen!", - "Nog 59 shotjes" - ], - "shotCount": 41 - } - ] - }, - { - "timestamp": 2534, - "events": [ - { - "type": "song", - "text": [ - "Lorenz Büffel", - "Johnny Däpp" - ] - } - ] - }, - { - "timestamp": 2555, - "events": [ - { - "type": "shot", - "text": [ - "Dab dat glas naar je mond!", - "Nog 58 shotjes" - ], - "shotCount": 42 - } - ] - }, - { - "timestamp": 2587, - "events": [ - { - "type": "song", - "text": [ - "Zware Jongens", - "Jodeljump" - ] - } - ] - }, - { - "timestamp": 2606, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 57 shotjes" - ], - "shotCount": 43 - } - ] - }, - { - "timestamp": 2635, - "events": [ - { - "type": "song", - "text": [ - "Parla & Pardoux", - "Liberté" - ] - } - ] - }, - { - "timestamp": 2664, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 56 shotjes" - ], - "shotCount": 44 - } - ] - }, - { - "timestamp": 2695, - "events": [ - { - "type": "song", - "text": [ - "Markus Becker", - "Das rote Pferd" - ] - } - ] - }, - { - "timestamp": 2729, - "events": [ - { - "type": "shot", - "text": [ - "Pweeeep!", - "Nog 55 shotjes" - ], - "shotCount": 45 - } - ] - }, - { - "timestamp": 2743, - "events": [ - { - "type": "song", - "text": [ - "Olaf Henning", - "Cowboy und Indianer" - ] - } - ] - }, - { - "timestamp": 2784, - "events": [ - { - "type": "shot", - "text": [ - "Adje!", - "Nog 54 shotjes" - ], - "shotCount": 46 - } - ] - }, - { - "timestamp": 2785, - "events": [ - { - "type": "song", - "text": [ - "Ch!pz", - "Cowboy" - ] - } - ] - }, - { - "timestamp": 2824, - "events": [ - { - "type": "song", - "text": [ - "Toy-Box", - "Tarzan & Jane" - ] - } - ] - }, - { - "timestamp": 2850, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 53 shotjes" - ], - "shotCount": 47 - } - ] - }, - { - "timestamp": 2879, - "events": [ - { - "type": "song", - "text": [ - "Toy-Box", - "Sailor Song" - ] - } - ] - }, - { - "timestamp": 2919, - "events": [ - { - "type": "shot", - "text": [ - "Bijna op de helft!", - "Nog 52 shotjes" - ], - "shotCount": 48 - } - ] - }, - { - "timestamp": 2921, - "events": [ - { - "type": "song", - "text": [ - "Vengaboys", - "Boom, Boom, Boom, Boom!!" - ] - } - ] - }, - { - "timestamp": 2975, - "events": [ - { - "type": "shot", - "text": [ - "Bam!", - "Nog 51 shotjes" - ], - "shotCount": 49 - } - ] - }, - { - "timestamp": 2998, - "events": [ - { - "type": "song", - "text": [ - "Vengaboys", - "To Brazil!" - ] - } - ] - }, - { - "timestamp": 3024, - "events": [ - { - "type": "time", - "text": [ - "Nog 50 minuten!", - "We zijn op de helft!" - ] - } - ] - }, - { - "timestamp": 3039, - "events": [ - { - "type": "shot", - "text": [ - "Abraham!", - "Nog 50 shotjes" - ], - "shotCount": 50 - } - ] - }, - { - "timestamp": 3070, - "events": [ - { - "type": "song", - "text": [ - "Snollebollekes", - "Bam bam (bam)" - ] - } - ] - }, - { - "timestamp": 3104, - "events": [ - { - "type": "shot", - "text": [ - "Tweede helft!", - "Nog 49 shotjes" - ], - "shotCount": 51 - } - ] - }, - { - "timestamp": 3120, - "events": [ - { - "type": "song", - "text": [ - "Def Rhymz", - "Schudden" - ] - } - ] - }, - { - "timestamp": 3160, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 48 shotjes" - ], - "shotCount": 52 - } - ] - }, - { - "timestamp": 3190, - "events": [ - { - "type": "song", - "text": [ - "Cooldown Café", - "Hey baby" - ] - } - ] - }, - { - "timestamp": 3215, - "events": [ - { - "type": "shot", - "text": [ - "Pweeeep!", - "Nog 47 shotjes" - ], - "shotCount": 53 - } - ] - }, - { - "timestamp": 3232, - "events": [ - { - "type": "song", - "text": [ - "Gebroeders Ko", - "Schatje, mag ik je foto" - ] - } - ] - }, - { - "timestamp": 3279, - "events": [ - { - "type": "shot", - "text": [ - "Zuipen!", - "Nog 46 shotjes" - ], - "shotCount": 54 - }, - { - "type": "song", - "text": [ - "Guus Meeuwis", - "Het is een nacht" - ] - } - ] - }, - { - "timestamp": 3341, - "events": [ - { - "type": "shot", - "text": [ - "Adje!", - "Nog 45 shotjes" - ], - "shotCount": 55 - } - ] - }, - { - "timestamp": 3356, - "events": [ - { - "type": "song", - "text": [ - "Tom Waes", - "Dos cervezas" - ] - } - ] - }, - { - "timestamp": 3398, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 44 shotjes" - ], - "shotCount": 56 - } - ] - }, - { - "timestamp": 3412, - "events": [ - { - "type": "song", - "text": [ - "Peter Wackel", - "Vollgas" - ] - } - ] - }, - { - "timestamp": 3439, - "events": [ - { - "type": "song", - "text": [ - "Peter Wackel", - "Scheiß drauf!" - ] - } - ] - }, - { - "timestamp": 3465, - "events": [ - { - "type": "shot", - "text": [ - "Hard gaan!", - "Nog 43 shotjes" - ], - "shotCount": 57 - } - ] - }, - { - "timestamp": 3467, - "events": [ - { - "type": "song", - "text": [ - "Ikke Hüftgold", - "Dicke titten, kartoffelsalat" - ] - } - ] - }, - { - "timestamp": 3520, - "events": [ - { - "type": "shot", - "text": [ - "Hap, slok, weg!", - "Nog 42 shotjes" - ], - "shotCount": 58 - } - ] - }, - { - "timestamp": 3521, - "events": [ - { - "type": "song", - "text": [ - "Tim Toupet", - "Fliegerlied (So ein schöner Tag)" - ] - } - ] - }, - { - "timestamp": 3564, - "events": [ - { - "type": "song", - "text": [ - "Cooldown Café", - "Met z'n allen" - ] - } - ] - }, - { - "timestamp": 3577, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 41 shotjes" - ], - "shotCount": 59 - } - ] - }, - { - "timestamp": 3636, - "events": [ - { - "type": "time", - "text": [ - "Nog 40 minuten!", - "Uurtje achter de rug" - ] - } - ] - }, - { - "timestamp": 3643, - "events": [ - { - "type": "shot", - "text": [ - "Glas 60!", - "Nog 40 shotjes" - ], - "shotCount": 60 - } - ] - }, - { - "timestamp": 3659, - "events": [ - { - "type": "song", - "text": [ - "The Partysquad feat. Jayh, Sjaak & Reverse", - "Helemaal naar de klote" - ] - } - ] - }, - { - "timestamp": 3687, - "events": [ - { - "type": "song", - "text": [ - "K-Liber", - "Viben" - ] - } - ] - }, - { - "timestamp": 3700, - "events": [ - { - "type": "shot", - "text": [ - "Adje!", - "Nog 39 shotjes" - ], - "shotCount": 61 - } - ] - }, - { - "timestamp": 3753, - "events": [ - { - "type": "shot", - "text": [ - "Pweeeep!", - "Nog 38 shotjes" - ], - "shotCount": 62 - } - ] - }, - { - "timestamp": 3755, - "events": [ - { - "type": "song", - "text": [ - "FeestDJRuud & Dirtcaps feat. Sjaak & Kraantje Pappie", - "Weekend" - ] - } - ] - }, - { - "timestamp": 3808, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 37 shotjes" - ], - "shotCount": 63 - }, - { - "type": "song", - "text": [ - "Lawineboys", - "Joost" - ] - } - ] - }, - { - "timestamp": 3860, - "events": [ - { - "type": "song", - "text": [ - "Gebroeders Ko", - "Ik heb een toeter op mijn waterscooter" - ] - } - ] - }, - { - "timestamp": 3874, - "events": [ - { - "type": "shot", - "text": [ - "Toe-toe-toeter!", - "Nog 36 shotjes" - ], - "shotCount": 64 - } - ] - }, - { - "timestamp": 3904, - "events": [ - { - "type": "song", - "text": [ - "Gebroeders Ko", - "Tringeling" - ] - } - ] - }, - { - "timestamp": 3931, - "events": [ - { - "type": "shot", - "text": [ - "Tringeling!", - "Nog 35 shotjes" - ], - "shotCount": 65 - } - ] - }, - { - "timestamp": 3975, - "events": [ - { - "type": "song", - "text": [ - "Basshunter", - "Boten Anna" - ] - } - ] - }, - { - "timestamp": 3988, - "events": [ - { - "type": "shot", - "text": [ - "Zuipen!", - "Nog 34 shotjes" - ], - "shotCount": 66 - } - ] - }, - { - "timestamp": 4029, - "events": [ - { - "type": "song", - "text": [ - "Lawineboys", - "Wat zullen we drinken" - ] - } - ] - }, - { - "timestamp": 4050, - "events": [ - { - "type": "shot", - "text": [ - "Dorst!", - "Nog 33 shotjes" - ], - "shotCount": 67 - } - ] - }, - { - "timestamp": 4081, - "events": [ - { - "type": "song", - "text": [ - "Lamme Frans", - "Wakker met een biertje!" - ] - } - ] - }, - { - "timestamp": 4113, - "events": [ - { - "type": "shot", - "text": [ - "Biertje in de hand...", - "Nog 32 shotjes" - ], - "shotCount": 68 - } - ] - }, - { - "timestamp": 4124, - "events": [ - { - "type": "song", - "text": [ - "Lawineboys feat. DJ Jerome", - "Seks met die kale" - ] - } - ] - }, - { - "timestamp": 4175, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 31 shotjes" - ], - "shotCount": 69 - } - ] - }, - { - "timestamp": 4177, - "events": [ - { - "type": "song", - "text": [ - "Zombie Nation", - "Kernkraft 400" - ] - } - ] - }, - { - "timestamp": 4214, - "events": [ - { - "type": "time", - "text": [ - "Nog 30 minuten!", - "Half uurtje nog maar" - ] - } - ] - }, - { - "timestamp": 4228, - "events": [ - { - "type": "shot", - "text": [ - "Pweeeep!", - "Nog 30 shotjes" - ], - "shotCount": 70 - } - ] - }, - { - "timestamp": 4230, - "events": [ - { - "type": "song", - "text": [ - "DJ Boozywoozy", - "Party Affair" - ] - } - ] - }, - { - "timestamp": 4280, - "events": [ - { - "type": "shot", - "text": [ - "Tik maar achterover!", - "Nog 29 shotjes" - ], - "shotCount": 71 - } - ] - }, - { - "timestamp": 4289, - "events": [ - { - "type": "song", - "text": [ - "2Unlimited", - "No Limit" - ] - } - ] - }, - { - "timestamp": 4341, - "events": [ - { - "type": "shot", - "text": [ - "Alcoholic party!", - "Nog 28 shotjes" - ], - "shotCount": 72 - } - ] - }, - { - "timestamp": 4343, - "events": [ - { - "type": "song", - "text": [ - "DJ Kicken vs. MC-Q", - "Ain't No Party" - ] - } - ] - }, - { - "timestamp": 4408, - "events": [ - { - "type": "shot", - "text": [ - "Toet!", - "Nog 27 shotjes" - ], - "shotCount": 73 - } - ] - }, - { - "timestamp": 4411, - "events": [ - { - "type": "song", - "text": [ - "Jan Wayne", - "Becuase the Night" - ] - } - ] - }, - { - "timestamp": 4455, - "events": [ - { - "type": "song", - "text": [ - "Cascada", - "Everytime We Touch" - ] - } - ] - }, - { - "timestamp": 4467, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 26 shotjes" - ], - "shotCount": 74 - } - ] - }, - { - "timestamp": 4510, - "events": [ - { - "type": "song", - "text": [ - "Gigi D'Agostino", - "L'amour toujours" - ] - } - ] - }, - { - "timestamp": 4521, - "events": [ - { - "type": "shot", - "text": [ - "Shotje 75!", - "Nog 25 shotjes" - ], - "shotCount": 75 - } - ] - }, - { - "timestamp": 4573, - "events": [ - { - "type": "song", - "text": [ - "Jason Paige", - "Gotta Catch 'M All" - ] - } - ] - }, - { - "timestamp": 4578, - "events": [ - { - "type": "shot", - "text": [ - "Trek een ad!", - "Nog 24 shotjes" - ], - "shotCount": 76 - } - ] - }, - { - "timestamp": 4636, - "events": [ - { - "type": "song", - "text": [ - "Scooter", - "How Much Is The Fish" - ] - } - ] - }, - { - "timestamp": 4645, - "events": [ - { - "type": "shot", - "text": [ - "Pweeeep!", - "Nog 23 shotjes" - ], - "shotCount": 77 - } - ] - }, - { - "timestamp": 4675, - "events": [ - { - "type": "song", - "text": [ - "Scooter", - "Weekend" - ] - } - ] - }, - { - "timestamp": 4701, - "events": [ - { - "type": "shot", - "text": [ - "scToeter!", - "Nog 22 shotjes" - ], - "shotCount": 78 - } - ] - }, - { - "timestamp": 4714, - "events": [ - { - "type": "song", - "text": [ - "Scooter", - "One (Always Hardcore)" - ] - } - ] - }, - { - "timestamp": 4764, - "events": [ - { - "type": "shot", - "text": [ - "En door!", - "Nog 21 shotjes" - ], - "shotCount": 79 - } - ] - }, - { - "timestamp": 4766, - "events": [ - { - "type": "song", - "text": [ - "Scooter", - "Maria (I Like It Loud)" - ] - } - ] - }, - { - "timestamp": 4815, - "events": [ - { - "type": "time", - "text": [ - "Nog 20 minuten!", - "Geef alles, behalve over" - ] - } - ] - }, - { - "timestamp": 4818, - "events": [ - { - "type": "song", - "text": [ - "Scooter", - "J'adore Hardcore" - ] - } - ] - }, - { - "timestamp": 4829, - "events": [ - { - "type": "shot", - "text": [ - "Al 80 in de mik!", - "Nog 20 shotjes" - ], - "shotCount": 80 - } - ] - }, - { - "timestamp": 4860, - "events": [ - { - "type": "song", - "text": [ - "Wildstylez feat. Niels Geusebroek", - "Year of Summer" - ] - } - ] - }, - { - "timestamp": 4888, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 19 shotjes" - ], - "shotCount": 81 - } - ] - }, - { - "timestamp": 4929, - "events": [ - { - "type": "song", - "text": [ - "Brennan Heart & Wildstylez", - "Lose My Mind" - ] - } - ] - }, - { - "timestamp": 4953, - "events": [ - { - "type": "shot", - "text": [ - "Bakken vouwen!", - "Nog 18 shotjes" - ], - "shotCount": 82 - } - ] - }, - { - "timestamp": 5004, - "events": [ - { - "type": "shot", - "text": [ - "Pweeeep!", - "Nog 17 shotjes" - ], - "shotCount": 83 - } - ] - }, - { - "timestamp": 5006, - "events": [ - { - "type": "song", - "text": [ - "Starkoo", - "Ik wil je" - ] - } - ] - }, - { - "timestamp": 5059, - "events": [ - { - "type": "song", - "text": [ - "Feestteam", - "Let It Be" - ] - } - ] - }, - { - "timestamp": 5071, - "events": [ - { - "type": "shot", - "text": [ - "Let it bier!", - "Nog 16 shotjes" - ], - "shotCount": 84 - } - ] - }, - { - "timestamp": 5125, - "events": [ - { - "type": "shot", - "text": [ - "Adje numero 85!", - "Nog 15 shotjes" - ], - "shotCount": 85 - } - ] - }, - { - "timestamp": 5179, - "events": [ - { - "type": "song", - "text": [ - "DJ Nikolai & DJ Mike van Dijk", - "Piano Man" - ] - } - ] - }, - { - "timestamp": 5188, - "events": [ - { - "type": "shot", - "text": [ - "Toet!", - "Nog 14 shotjes" - ], - "shotCount": 86 - } - ] - }, - { - "timestamp": 5190, - "events": [ - { - "type": "talk", - "text": [ - "Gewoon doorgaan!", - "Deze Piano Man telt niet" - ] - } - ] - }, - { - "timestamp": 5237, - "events": [ - { - "type": "song", - "text": [ - "Robbie Williams", - "Angels" - ] - } - ] - }, - { - "timestamp": 5243, - "events": [ - { - "type": "shot", - "text": [ - "Drinken!", - "Nog 13 shotjes" - ], - "shotCount": 87 - } - ] - }, - { - "timestamp": 5278, - "events": [ - { - "type": "song", - "text": [ - "Enrique Iglesias", - "Hero" - ] - } - ] - }, - { - "timestamp": 5308, - "events": [ - { - "type": "shot", - "text": [ - "I can't be your biero!", - "Nog 12 shotjes" - ], - "shotCount": 88 - } - ] - }, - { - "timestamp": 5331, - "events": [ - { - "type": "song", - "text": [ - "Whitney Houston", - "I Will Always Love You" - ] - } - ] - }, - { - "timestamp": 5374, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 11 shotjes" - ], - "shotCount": 89 - } - ] - }, - { - "timestamp": 5380, - "events": [ - { - "type": "song", - "text": [ - "Mariah Carey", - "All I Want For Christmas" - ] - } - ] - }, - { - "timestamp": 5431, - "events": [ - { - "type": "shot", - "text": [ - "90 in de keel, hierna niet veel!", - "Nog 10 shotjes" - ], - "shotCount": 90 - } - ] - }, - { - "timestamp": 5441, - "events": [ - { - "type": "time", - "text": [ - "Nog 10 minuten!", - "De laatste loodjes" - ] - } - ] - }, - { - "timestamp": 5444, - "events": [ - { - "type": "song", - "text": [ - "Kraantje Pappie", - "Feesttent (FeestDJRuud remix)" - ] - } - ] - }, - { - "timestamp": 5488, - "events": [ - { - "type": "shot", - "text": [ - "Zuip je uit de dubbele cijfers!", - "Nog 9 shotjes" - ], - "shotCount": 91 - } - ] - }, - { - "timestamp": 5490, - "events": [ - { - "type": "song", - "text": [ - "New Kids feat. DJ Paul Elstak", - "Turbo" - ] - } - ] - }, - { - "timestamp": 5556, - "events": [ - { - "type": "shot", - "text": [ - "Zuipen!", - "Nog 8 shotjes" - ], - "shotCount": 92 - } - ] - }, - { - "timestamp": 5558, - "events": [ - { - "type": "song", - "text": [ - "Lipstick", - "I'm a Raver" - ] - } - ] - }, - { - "timestamp": 5591, - "events": [ - { - "type": "song", - "text": [ - "Nakatomi", - "Children of the Night" - ] - } - ] - }, - { - "timestamp": 5612, - "events": [ - { - "type": "shot", - "text": [ - "Pweeeep!", - "Nog 7 shotjes" - ], - "shotCount": 93 - } - ] - }, - { - "timestamp": 5614, - "events": [ - { - "type": "song", - "text": [ - "Charly Lownoise & Mental Theo", - "Wonderful Days" - ] - } - ] - }, - { - "timestamp": 5659, - "events": [ - { - "type": "song", - "text": [ - "DJ Paul Elstak", - "Luv You More" - ] - } - ] - }, - { - "timestamp": 5667, - "events": [ - { - "type": "shot", - "text": [ - "Bijna daar!", - "Nog 6 shotjes" - ], - "shotCount": 94 - } - ] - }, - { - "timestamp": 5704, - "events": [ - { - "type": "song", - "text": [ - "DJ Paul Elstak", - "Rainbow In The Sky" - ] - } - ] - }, - { - "timestamp": 5716, - "events": [ - { - "type": "time", - "text": [ - "Nog 5 minuten!", - "Zet de shotjes maar klaar" - ] - } - ] - }, - { - "timestamp": 5731, - "events": [ - { - "type": "shot", - "text": [ - "Toeter!", - "Nog 5 shotjes" - ], - "shotCount": 95 - } - ] - }, - { - "timestamp": 5733, - "events": [ - { - "type": "song", - "text": [ - "Evil Activities", - "Nobody Said It Was Easy" - ] - } - ] - }, - { - "timestamp": 5783, - "events": [ - { - "type": "shot", - "text": [ - "Slok 96!", - "Nog 4 shotjes" - ], - "shotCount": 96 - } - ] - }, - { - "timestamp": 5827, - "events": [ - { - "type": "song", - "text": [ - "Melrose", - "O" - ] - } - ] - }, - { - "timestamp": 5846, - "events": [ - { - "type": "shot", - "text": [ - "Voor de 97e keer!", - "Nog 3 shotjes" - ], - "shotCount": 97 - } - ] - }, - { - "timestamp": 5855, - "events": [ - { - "type": "song", - "text": [ - "Backstreet Boys", - "I Want It That Way" - ] - } - ] - }, - { - "timestamp": 5902, - "events": [ - { - "type": "shot", - "text": [ - "Nummer 98!", - "Nog 2 shotjes" - ], - "shotCount": 98 - } - ] - }, - { - "timestamp": 5933, - "events": [ - { - "type": "song", - "text": [ - "R. Kelly", - "The World's Greatest" - ] - } - ] - }, - { - "timestamp": 5970, - "events": [ - { - "type": "shot", - "text": [ - "Nummer 99!", - "Nog 1 shotje" - ], - "shotCount": 99 - } - ] - }, - { - "timestamp": 6020, - "events": [ - { - "type": "shot", - "text": [ - "CENTURION!", - "Geen shots meer" - ], - "shotCount": 100 - } - ] - } - ] +export const EVENT_PRIORITY: EventType[] = ["shot", "talk", "time", "song"]; +export type EventType = "talk" | "shot" | "song" | "time"; + +interface TimestampEventBase { + id?: string; + type: EventType; + text: string[]; +} + +interface TimestampEventShot extends TimestampEventBase { + type: "shot"; + shotCount: number; +} + +export type TimestampEvent = TimestampEventBase | TimestampEventShot; + +const timelines: { + timelines: { + name: string; + songFile: string; + feed: TimelineItem[]; + }[]; +} = { + timelines: [ + { + name: "Centurion", + songFile: "songs/centurion.m4a", + feed: [ + { + timestamp: 0, + events: [ + { + type: "talk", + text: ["Zet je schrap!", "We gaan zo beginnen"], + }, + ], + }, + { + timestamp: 42, + events: [ + { + type: "talk", + text: [ + "Daar gaan we!", + "Dit was het startsein, je hoeft nog niet te drinken", + ], + }, + { + type: "song", + text: ["Nena", "99 Luftballons"], + }, + ], + }, + { + timestamp: 108, + events: [ + { + type: "shot", + text: ["De eerste!", "Nog 99 shotjes"], + shotCount: 1, + }, + ], + }, + { + timestamp: 148, + events: [ + { + type: "song", + text: ["Hermes House Band", "Country Roads"], + }, + ], + }, + { + timestamp: 167, + events: [ + { + type: "shot", + text: ["Nummertje twee!", "Nog 98 shotjes"], + shotCount: 2, + }, + ], + }, + { + timestamp: 185, + events: [ + { + type: "song", + text: ["Vinzzent", "Dromendans"], + }, + ], + }, + { + timestamp: 223, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 97 shotjes"], + shotCount: 3, + }, + { + type: "song", + text: ["Linda, Roos & Jessica", "Ademnood"], + }, + ], + }, + { + timestamp: 283, + events: [ + { + type: "shot", + text: ["Niet gooien!", "Nog 96 shotjes"], + shotCount: 4, + }, + { + type: "song", + text: [ + "Peter de Koning", + "Het is altijd lente in de ogen van de tandarts-assistente", + ], + }, + ], + }, + { + timestamp: 340, + events: [ + { + type: "shot", + text: ["Lustrum!", "Nog 95 shotjes"], + shotCount: 5, + }, + { + type: "song", + text: ["Liquido", "Narcotic"], + }, + ], + }, + { + timestamp: 412, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 94 shotjes"], + shotCount: 6, + }, + { + type: "song", + text: ["Snoop Dogg feat. Pharrell", "Drop It Like It's Hot"], + }, + ], + }, + { + timestamp: 449, + events: [ + { + type: "song", + text: ["M.O.P.", "Ante Up"], + }, + ], + }, + { + timestamp: 459, + events: [ + { + type: "shot", + text: ["Pweeeep!", "Nog 93 shotjes"], + shotCount: 7, + }, + ], + }, + { + timestamp: 514, + events: [ + { + type: "shot", + text: ["Trek een ad!", "Nog 92 shotjes"], + shotCount: 8, + }, + { + type: "song", + text: ["Los Del Rio", "Macarena"], + }, + ], + }, + { + timestamp: 560, + events: [ + { + type: "song", + text: ["Spice Girls", "Wannabe"], + }, + ], + }, + { + timestamp: 574, + events: [ + { + type: "shot", + text: ["We zijn er nog lang niet!", "Nog 91 shotjes"], + shotCount: 9, + }, + ], + }, + { + timestamp: 617, + events: [ + { + type: "song", + text: [ + "Major Lazer feat. Busy Signal, The Flexican & FS Green", + "Watch Out For This (Bumaye)", + ], + }, + ], + }, + { + timestamp: 635, + events: [ + { + type: "shot", + text: ["Nummer tien!", "Nog 90 shotjes"], + shotCount: 10, + }, + ], + }, + { + timestamp: 647, + events: [ + { + type: "time", + text: ["Nog 90 minuten!", "Geef alles, behalve op"], + }, + ], + }, + { + timestamp: 650, + events: [ + { + type: "song", + text: ["André van Duin", "Er staat een paard in de gang"], + }, + ], + }, + { + timestamp: 667, + events: [ + { + type: "song", + text: ["Lil Kleine & Ronnie Flex", "Drank & Drugs"], + }, + ], + }, + { + timestamp: 684, + events: [ + { + type: "song", + text: ["Kabouter Plop", "Kabouterdans"], + }, + ], + }, + { + timestamp: 699, + events: [ + { + type: "shot", + text: ["Met vriendelijke toet!", "Nog 89 shotjes"], + shotCount: 11, + }, + ], + }, + { + timestamp: 725, + events: [ + { + type: "song", + text: ["K3", "Alle kleuren"], + }, + ], + }, + { + timestamp: 756, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 88 shotjes"], + shotCount: 12, + }, + ], + }, + { + timestamp: 757, + events: [ + { + type: "song", + text: ["Kinderen voor Kinderen", "Tietenlied"], + }, + ], + }, + { + timestamp: 812, + events: [ + { + type: "shot", + text: ["Ongeluksshotje 13!", "Nog 87 shotjes"], + shotCount: 13, + }, + ], + }, + { + timestamp: 814, + events: [ + { + type: "song", + text: ["Guus Meeuwis", "Het dondert en het bliksemt"], + }, + ], + }, + { + timestamp: 874, + events: [ + { + type: "shot", + text: ["Pweeeep!", "Nog 86 shotjes"], + shotCount: 14, + }, + ], + }, + { + timestamp: 876, + events: [ + { + type: "song", + text: ["Harry Vermeegen", "1-2-3-4 Dennis bier"], + }, + ], + }, + { + timestamp: 906, + events: [ + { + type: "song", + text: ["Puhdys", "Hey, wir woll’n die Eisbär'n sehn!"], + }, + ], + }, + { + timestamp: 935, + events: [ + { + type: "shot", + text: ["Fünfzehn!", "Nog 85 shotjes"], + shotCount: 15, + }, + ], + }, + { + timestamp: 966, + events: [ + { + type: "song", + text: ["DJ Ötzi", "Burger Dance"], + }, + ], + }, + { + timestamp: 995, + events: [ + { + type: "shot", + text: ["Toet!", "Nog 84 shotjes"], + shotCount: 16, + }, + ], + }, + { + timestamp: 996, + events: [ + { + type: "song", + text: ["Mickie Krause", "Hütte auf der Alm"], + }, + ], + }, + { + timestamp: 1030, + events: [ + { + type: "song", + text: ["Ali B & Yes-R & The Partysquad", "Rampeneren"], + }, + ], + }, + { + timestamp: 1046, + events: [ + { + type: "shot", + text: ["Zuipen!", "Nog 83 shotjes"], + shotCount: 17, + }, + ], + }, + { + timestamp: 1107, + events: [ + { + type: "shot", + text: ["18, legaal!", "Nog 82 shotjes"], + shotCount: 18, + }, + { + type: "song", + text: ["Martin Solveig", "Intoxicated"], + }, + ], + }, + { + timestamp: 1137, + events: [ + { + type: "song", + text: ["Nicki Minaj", "Starships"], + }, + ], + }, + { + timestamp: 1173, + events: [ + { + type: "shot", + text: ["Laatste shotje als tiener!", "Nog 81 shotjes"], + shotCount: 19, + }, + ], + }, + { + timestamp: 1222, + events: [ + { + type: "song", + text: ["2Unlimited", "Get Ready For This"], + }, + ], + }, + { + timestamp: 1233, + events: [ + { + type: "time", + text: ["Nog 80 minuten!", "Al 19 shotjes achter de rug"], + }, + ], + }, + { + timestamp: 1235, + events: [ + { + type: "shot", + text: ["Adje!", "Nog 80 shotjes"], + shotCount: 20, + }, + ], + }, + { + timestamp: 1275, + events: [ + { + type: "song", + text: ["The Village People", "YMCA"], + }, + ], + }, + { + timestamp: 1288, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 79 shotjes"], + shotCount: 21, + }, + ], + }, + { + timestamp: 1348, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 78 shotjes"], + shotCount: 22, + }, + ], + }, + { + timestamp: 1350, + events: [ + { + type: "song", + text: ["Carly Rae Jepsen ft Owl City", "It's Always A Good Time"], + }, + ], + }, + { + timestamp: 1395, + events: [ + { + type: "song", + text: ["Avicii", "Levels"], + }, + ], + }, + { + timestamp: 1411, + events: [ + { + type: "shot", + text: ["Claxon!", "Nog 77 shotjes"], + shotCount: 23, + }, + ], + }, + { + timestamp: 1456, + events: [ + { + type: "song", + text: ["Flo-Rida feat. T-Pain", "Low"], + }, + ], + }, + { + timestamp: 1471, + events: [ + { + type: "shot", + text: ["En nu even op standje maximaal!", "Nog 76 shotjes"], + shotCount: 24, + }, + ], + }, + { + timestamp: 1486, + events: [ + { + type: "song", + text: ["Taio Cruz", "Hangover"], + }, + ], + }, + { + timestamp: 1522, + events: [ + { + type: "talk", + text: [ + "Dit is nog het rustige stukje!", + "Zet hem maar op de bonk-bonk", + ], + }, + ], + }, + { + timestamp: 1530, + events: [ + { + type: "shot", + text: ["Halve Abraham!", "Nog 75 shotjes"], + shotCount: 25, + }, + ], + }, + { + timestamp: 1545, + events: [ + { + type: "song", + text: ["LMFAO", "Party Rock Anthem"], + }, + ], + }, + { + timestamp: 1594, + events: [ + { + type: "shot", + text: ["Hoch die Hände!", "Nog 74 shotjes"], + shotCount: 26, + }, + { + type: "song", + text: ["Hans Entertainment vs. Finger & Kadel", "Hoch die Hände"], + }, + ], + }, + { + timestamp: 1623, + events: [ + { + type: "song", + text: ["Galantis", "No Money"], + }, + ], + }, + { + timestamp: 1653, + events: [ + { + type: "shot", + text: ["Voel je 'm al?", "Nog 73 shotjes"], + shotCount: 27, + }, + ], + }, + { + timestamp: 1683, + events: [ + { + type: "song", + text: ["Kid Cudi", "Pursuit of Happiness (Steve Aoki remix)"], + }, + ], + }, + { + timestamp: 1712, + events: [ + { + type: "shot", + text: ["Project X!", "Nog 72 shotjes"], + shotCount: 28, + }, + ], + }, + { + timestamp: 1741, + events: [ + { + type: "song", + text: ["Yeah Yeah Yeahs", "Heads Will Roll (A-Trak remix)"], + }, + ], + }, + { + timestamp: 1769, + events: [ + { + type: "shot", + text: ["Pweeeep!", "Nog 71 shotjes"], + shotCount: 29, + }, + ], + }, + { + timestamp: 1814, + events: [ + { + type: "song", + text: ["Michael Calfan", "Resurrection"], + }, + ], + }, + { + timestamp: 1825, + events: [ + { + type: "time", + text: ["Nog 70 minuten!", "Half uurtje zit erop"], + }, + ], + }, + { + timestamp: 1829, + events: [ + { + type: "shot", + text: ["Toet!", "Nog 70 shotjes"], + shotCount: 30, + }, + ], + }, + { + timestamp: 1858, + events: [ + { + type: "song", + text: ["Basto!", "Again and Again"], + }, + ], + }, + { + timestamp: 1887, + events: [ + { + type: "shot", + text: ["Over de dertig!", "Nog 69 (nice) shotjes"], + shotCount: 31, + }, + ], + }, + { + timestamp: 1916, + events: [ + { + type: "song", + text: ["David Guetta feat. Sia", "Titanium"], + }, + ], + }, + { + timestamp: 1945, + events: [ + { + type: "shot", + text: ["Trek een ad!", "Nog 68 shotjes"], + shotCount: 32, + }, + ], + }, + { + timestamp: 1959, + events: [ + { + type: "song", + text: ["Gala", "Freed From Desire"], + }, + ], + }, + { + timestamp: 2004, + events: [ + { + type: "shot", + text: ["Nummertje 33!", "Nog 67 shotjes!"], + shotCount: 33, + }, + ], + }, + { + timestamp: 2034, + events: [ + { + type: "song", + text: ["Wolter Kroes", "Viva Hollandia"], + }, + ], + }, + { + timestamp: 2064, + events: [ + { + type: "shot", + text: ["Voor het vaderland!", "Nog 66 shotjes"], + shotCount: 34, + }, + ], + }, + { + timestamp: 2090, + events: [ + { + type: "song", + text: ["Spongebob Squarepants", "Het Spongebob Squarepants-lied"], + }, + ], + }, + { + timestamp: 2125, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 65 shotjes"], + shotCount: 35, + }, + ], + }, + { + timestamp: 2128, + events: [ + { + type: "song", + text: ["Westlife", "Uptown Girl"], + }, + ], + }, + { + timestamp: 2179, + events: [ + { + type: "song", + text: ["Aqua", "Barbie Girl"], + }, + ], + }, + { + timestamp: 2194, + events: [ + { + type: "shot", + text: ["Pweeeep!", "Nog 64 shotjes"], + shotCount: 36, + }, + ], + }, + { + timestamp: 2225, + events: [ + { + type: "song", + text: ["Guillermo & Tropical Danny", "Toppertje"], + }, + ], + }, + { + timestamp: 2245, + events: [ + { + type: "shot", + text: ["In dat keelgaatje!", "Nog 63 shotjes"], + shotCount: 37, + }, + ], + }, + { + timestamp: 2305, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 62 shotjes"], + shotCount: 38, + }, + { + type: "song", + text: ["The Bloody Beetroots feat. Steve Aoki", "Warp 1.9"], + }, + ], + }, + { + timestamp: 2374, + events: [ + { + type: "shot", + text: ["Toet!", "Nog 61 shotjes"], + shotCount: 39, + }, + { + type: "song", + text: ["David Guetta & Showtek feat. Vassy", "Bad"], + }, + ], + }, + { + timestamp: 2431, + events: [ + { + type: "shot", + text: ["40 alweer!", "Nog 60 shotjes"], + shotCount: 40, + }, + { + type: "song", + text: ["Showtek & Justin Prime", "Cannonball"], + }, + ], + }, + { + timestamp: 2444, + events: [ + { + type: "time", + text: ["Nog 60 minuten!", "Een klein uurtje"], + }, + ], + }, + { + timestamp: 2460, + events: [ + { + type: "song", + text: ["Die Atzen", "Disco Pogo"], + }, + ], + }, + { + timestamp: 2489, + events: [ + { + type: "shot", + text: ["Zuipen!", "Nog 59 shotjes"], + shotCount: 41, + }, + ], + }, + { + timestamp: 2534, + events: [ + { + type: "song", + text: ["Lorenz Büffel", "Johnny Däpp"], + }, + ], + }, + { + timestamp: 2555, + events: [ + { + type: "shot", + text: ["Dab dat glas naar je mond!", "Nog 58 shotjes"], + shotCount: 42, + }, + ], + }, + { + timestamp: 2587, + events: [ + { + type: "song", + text: ["Zware Jongens", "Jodeljump"], + }, + ], + }, + { + timestamp: 2606, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 57 shotjes"], + shotCount: 43, + }, + ], + }, + { + timestamp: 2635, + events: [ + { + type: "song", + text: ["Parla & Pardoux", "Liberté"], + }, + ], + }, + { + timestamp: 2664, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 56 shotjes"], + shotCount: 44, + }, + ], + }, + { + timestamp: 2695, + events: [ + { + type: "song", + text: ["Markus Becker", "Das rote Pferd"], + }, + ], + }, + { + timestamp: 2729, + events: [ + { + type: "shot", + text: ["Pweeeep!", "Nog 55 shotjes"], + shotCount: 45, + }, + ], + }, + { + timestamp: 2743, + events: [ + { + type: "song", + text: ["Olaf Henning", "Cowboy und Indianer"], + }, + ], + }, + { + timestamp: 2784, + events: [ + { + type: "shot", + text: ["Adje!", "Nog 54 shotjes"], + shotCount: 46, + }, + ], + }, + { + timestamp: 2785, + events: [ + { + type: "song", + text: ["Ch!pz", "Cowboy"], + }, + ], + }, + { + timestamp: 2824, + events: [ + { + type: "song", + text: ["Toy-Box", "Tarzan & Jane"], + }, + ], }, { - 'name': 'Totale isolatie', - 'songFile': 'songs/totale_isolatie.m4a', - 'feed': [ - { - 'timestamp': 0, - 'events': [ - { - 'type': 'talk', - 'text': [ - 'Ik heb geen tekst', - 'want het is veel werk' - ] - } - ] - }, - { - 'timestamp': 10, - 'events': [ - { - 'type': 'talk', - 'text': [ - 'Nee echt', - 'niks' - ] - }, - { - 'type': 'song', - 'text': [ - 'Blahblah', - 'blahblahblah' - ] - } - ] - } - ] + timestamp: 2850, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 53 shotjes"], + shotCount: 47, + }, + ], + }, + { + timestamp: 2879, + events: [ + { + type: "song", + text: ["Toy-Box", "Sailor Song"], + }, + ], + }, + { + timestamp: 2919, + events: [ + { + type: "shot", + text: ["Bijna op de helft!", "Nog 52 shotjes"], + shotCount: 48, + }, + ], + }, + { + timestamp: 2922, + events: [ + { + type: "song", + text: ["Vengaboys", "Boom, Boom, Boom, Boom!!"], + }, + ], + }, + { + timestamp: 2975, + events: [ + { + type: "shot", + text: ["Bam!", "Nog 51 shotjes"], + shotCount: 49, + }, + ], + }, + { + timestamp: 2998, + events: [ + { + type: "song", + text: ["Vengaboys", "To Brazil!"], + }, + ], + }, + { + timestamp: 3024, + events: [ + { + type: "time", + text: ["Nog 50 minuten!", "We zijn op de helft!"], + }, + ], + }, + { + timestamp: 3039, + events: [ + { + type: "shot", + text: ["Abraham!", "Nog 50 shotjes"], + shotCount: 50, + }, + ], + }, + { + timestamp: 3070, + events: [ + { + type: "song", + text: ["Snollebollekes", "Bam bam (bam)"], + }, + ], + }, + { + timestamp: 3104, + events: [ + { + type: "shot", + text: ["Tweede helft!", "Nog 49 shotjes"], + shotCount: 51, + }, + ], + }, + { + timestamp: 3120, + events: [ + { + type: "song", + text: ["Def Rhymz", "Schudden"], + }, + ], + }, + { + timestamp: 3160, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 48 shotjes"], + shotCount: 52, + }, + ], + }, + { + timestamp: 3190, + events: [ + { + type: "song", + text: ["Cooldown Café", "Hey baby"], + }, + ], + }, + { + timestamp: 3215, + events: [ + { + type: "shot", + text: ["Pweeeep!", "Nog 47 shotjes"], + shotCount: 53, + }, + ], + }, + { + timestamp: 3232, + events: [ + { + type: "song", + text: ["Gebroeders Ko", "Schatje, mag ik je foto"], + }, + ], + }, + { + timestamp: 3279, + events: [ + { + type: "shot", + text: ["Zuipen!", "Nog 46 shotjes"], + shotCount: 54, + }, + { + type: "song", + text: ["Guus Meeuwis", "Het is een nacht"], + }, + ], + }, + { + timestamp: 3341, + events: [ + { + type: "shot", + text: ["Adje!", "Nog 45 shotjes"], + shotCount: 55, + }, + ], + }, + { + timestamp: 3356, + events: [ + { + type: "song", + text: ["Tom Waes", "Dos cervezas"], + }, + ], + }, + { + timestamp: 3398, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 44 shotjes"], + shotCount: 56, + }, + ], + }, + { + timestamp: 3412, + events: [ + { + type: "song", + text: ["Peter Wackel", "Vollgas"], + }, + ], + }, + { + timestamp: 3439, + events: [ + { + type: "song", + text: ["Peter Wackel", "Scheiß drauf!"], + }, + ], + }, + { + timestamp: 3465, + events: [ + { + type: "shot", + text: ["Hard gaan!", "Nog 43 shotjes"], + shotCount: 57, + }, + ], + }, + { + timestamp: 3467, + events: [ + { + type: "song", + text: ["Ikke Hüftgold", "Dicke titten, kartoffelsalat"], + }, + ], + }, + { + timestamp: 3520, + events: [ + { + type: "shot", + text: ["Hap, slok, weg!", "Nog 42 shotjes"], + shotCount: 58, + }, + ], + }, + { + timestamp: 3521, + events: [ + { + type: "song", + text: ["Tim Toupet", "Fliegerlied (So ein schöner Tag)"], + }, + ], + }, + { + timestamp: 3564, + events: [ + { + type: "song", + text: ["Cooldown Café", "Met z'n allen"], + }, + ], + }, + { + timestamp: 3577, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 41 shotjes"], + shotCount: 59, + }, + ], + }, + { + timestamp: 3636, + events: [ + { + type: "time", + text: ["Nog 40 minuten!", "Uurtje achter de rug"], + }, + ], + }, + { + timestamp: 3643, + events: [ + { + type: "shot", + text: ["Glas 60!", "Nog 40 shotjes"], + shotCount: 60, + }, + ], + }, + { + timestamp: 3659, + events: [ + { + type: "song", + text: [ + "The Partysquad feat. Jayh, Sjaak & Reverse", + "Helemaal naar de klote", + ], + }, + ], + }, + { + timestamp: 3687, + events: [ + { + type: "song", + text: ["K-Liber", "Viben"], + }, + ], + }, + { + timestamp: 3700, + events: [ + { + type: "shot", + text: ["Adje!", "Nog 39 shotjes"], + shotCount: 61, + }, + ], + }, + { + timestamp: 3753, + events: [ + { + type: "shot", + text: ["Pweeeep!", "Nog 38 shotjes"], + shotCount: 62, + }, + ], + }, + { + timestamp: 3755, + events: [ + { + type: "song", + text: [ + "FeestDJRuud & Dirtcaps feat. Sjaak & Kraantje Pappie", + "Weekend", + ], + }, + ], + }, + { + timestamp: 3808, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 37 shotjes"], + shotCount: 63, + }, + { + type: "song", + text: ["Lawineboys", "Joost"], + }, + ], + }, + { + timestamp: 3860, + events: [ + { + type: "song", + text: ["Gebroeders Ko", "Ik heb een toeter op mijn waterscooter"], + }, + ], + }, + { + timestamp: 3874, + events: [ + { + type: "shot", + text: ["Toe-toe-toeter!", "Nog 36 shotjes"], + shotCount: 64, + }, + ], + }, + { + timestamp: 3904, + events: [ + { + type: "song", + text: ["Gebroeders Ko", "Tringeling"], + }, + ], + }, + { + timestamp: 3931, + events: [ + { + type: "shot", + text: ["Tringeling!", "Nog 35 shotjes"], + shotCount: 65, + }, + ], + }, + { + timestamp: 3975, + events: [ + { + type: "song", + text: ["Basshunter", "Boten Anna"], + }, + ], + }, + { + timestamp: 3988, + events: [ + { + type: "shot", + text: ["Zuipen!", "Nog 34 shotjes"], + shotCount: 66, + }, + ], + }, + { + timestamp: 4029, + events: [ + { + type: "song", + text: ["Lawineboys", "Wat zullen we drinken"], + }, + ], + }, + { + timestamp: 4050, + events: [ + { + type: "shot", + text: ["Dorst!", "Nog 33 shotjes"], + shotCount: 67, + }, + ], + }, + { + timestamp: 4081, + events: [ + { + type: "song", + text: ["Lamme Frans", "Wakker met een biertje!"], + }, + ], + }, + { + timestamp: 4113, + events: [ + { + type: "shot", + text: ["Biertje in de hand...", "Nog 32 shotjes"], + shotCount: 68, + }, + ], + }, + { + timestamp: 4124.18, + events: [ + { + type: "song", + text: ["Lawineboys feat. DJ Jerome", "Seks met die kale"], + }, + ], + }, + { + timestamp: 4175, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 31 shotjes"], + shotCount: 69, + }, + ], + }, + { + timestamp: 4177, + events: [ + { + type: "song", + text: ["Zombie Nation", "Kernkraft 400"], + }, + ], + }, + { + timestamp: 4214, + events: [ + { + type: "time", + text: ["Nog 30 minuten!", "Half uurtje nog maar"], + }, + ], + }, + { + timestamp: 4228, + events: [ + { + type: "shot", + text: ["Pweeeep!", "Nog 30 shotjes"], + shotCount: 70, + }, + ], + }, + { + timestamp: 4230, + events: [ + { + type: "song", + text: ["DJ Boozywoozy", "Party Affair"], + }, + ], + }, + { + timestamp: 4280, + events: [ + { + type: "shot", + text: ["Tik maar achterover!", "Nog 29 shotjes"], + shotCount: 71, + }, + ], + }, + { + timestamp: 4289, + events: [ + { + type: "song", + text: ["2Unlimited", "No Limit"], + }, + ], + }, + { + timestamp: 4341, + events: [ + { + type: "shot", + text: ["Alcoholic party!", "Nog 28 shotjes"], + shotCount: 72, + }, + ], + }, + { + timestamp: 4343, + events: [ + { + type: "song", + text: ["DJ Kicken vs. MC-Q", "Ain't No Party"], + }, + ], + }, + { + timestamp: 4408, + events: [ + { + type: "shot", + text: ["Toet!", "Nog 27 shotjes"], + shotCount: 73, + }, + ], + }, + { + timestamp: 4411, + events: [ + { + type: "song", + text: ["Jan Wayne", "Becuase the Night"], + }, + ], + }, + { + timestamp: 4455, + events: [ + { + type: "song", + text: ["Cascada", "Everytime We Touch"], + }, + ], + }, + { + timestamp: 4467, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 26 shotjes"], + shotCount: 74, + }, + ], + }, + { + timestamp: 4510, + events: [ + { + type: "song", + text: ["Gigi D'Agostino", "L'amour toujours"], + }, + ], + }, + { + timestamp: 4521, + events: [ + { + type: "shot", + text: ["Shotje 75!", "Nog 25 shotjes"], + shotCount: 75, + }, + ], + }, + { + timestamp: 4573, + events: [ + { + type: "song", + text: ["Jason Paige", "Gotta Catch 'M All"], + }, + ], + }, + { + timestamp: 4578, + events: [ + { + type: "shot", + text: ["Trek een ad!", "Nog 24 shotjes"], + shotCount: 76, + }, + ], + }, + { + timestamp: 4636, + events: [ + { + type: "song", + text: ["Scooter", "How Much Is The Fish"], + }, + ], + }, + { + timestamp: 4645, + events: [ + { + type: "shot", + text: ["Pweeeep!", "Nog 23 shotjes"], + shotCount: 77, + }, + ], + }, + { + timestamp: 4674, + events: [ + { + type: "song", + text: ["Scooter", "Weekend"], + }, + ], + }, + { + timestamp: 4701, + events: [ + { + type: "shot", + text: ["scToeter!", "Nog 22 shotjes"], + shotCount: 78, + }, + ], + }, + { + timestamp: 4714, + events: [ + { + type: "song", + text: ["Scooter", "One (Always Hardcore)"], + }, + ], + }, + { + timestamp: 4764, + events: [ + { + type: "shot", + text: ["En door!", "Nog 21 shotjes"], + shotCount: 79, + }, + ], + }, + { + timestamp: 4766, + events: [ + { + type: "song", + text: ["Scooter", "Maria (I Like It Loud)"], + }, + ], + }, + { + timestamp: 4815, + events: [ + { + type: "time", + text: ["Nog 20 minuten!", "Geef alles, behalve over"], + }, + ], + }, + { + timestamp: 4818, + events: [ + { + type: "song", + text: ["Scooter", "J'adore Hardcore"], + }, + ], + }, + { + timestamp: 4829, + events: [ + { + type: "shot", + text: ["Al 80 in de mik!", "Nog 20 shotjes"], + shotCount: 80, + }, + ], + }, + { + timestamp: 4860, + events: [ + { + type: "song", + text: ["Wildstylez feat. Niels Geusebroek", "Year of Summer"], + }, + ], + }, + { + timestamp: 4888, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 19 shotjes"], + shotCount: 81, + }, + ], + }, + { + timestamp: 4929, + events: [ + { + type: "song", + text: ["Brennan Heart & Wildstylez", "Lose My Mind"], + }, + ], + }, + { + timestamp: 4953, + events: [ + { + type: "shot", + text: ["Bakken vouwen!", "Nog 18 shotjes"], + shotCount: 82, + }, + ], + }, + { + timestamp: 5004, + events: [ + { + type: "shot", + text: ["Pweeeep!", "Nog 17 shotjes"], + shotCount: 83, + }, + ], + }, + { + timestamp: 5006, + events: [ + { + type: "song", + text: ["Starkoo", "Ik wil je"], + }, + ], + }, + { + timestamp: 5059, + events: [ + { + type: "song", + text: ["Feestteam", "Let It Be / Hey Jude (mix)"], + }, + ], + }, + { + timestamp: 5071, + events: [ + { + type: "shot", + text: ["Let it bier!", "Nog 16 shotjes"], + shotCount: 84, + }, + ], + }, + { + timestamp: 5125, + events: [ + { + type: "shot", + text: ["Adje numero 85!", "Nog 15 shotjes"], + shotCount: 85, + }, + ], + }, + { + timestamp: 5179, + events: [ + { + type: "song", + text: ["DJ Nikolai & DJ Mike van Dijk", "Piano Man"], + }, + ], + }, + { + timestamp: 5188.35, + events: [ + { + type: "shot", + text: ["Toet!", "Nog 14 shotjes"], + shotCount: 86, + }, + ], + }, + { + timestamp: 5190, + events: [ + { + type: "talk", + text: ["Gewoon doorgaan!", "Deze Piano Man telt niet"], + }, + ], + }, + { + timestamp: 5237, + events: [ + { + type: "song", + text: ["Robbie Williams", "Angels"], + }, + ], + }, + { + timestamp: 5243, + events: [ + { + type: "shot", + text: ["Drinken!", "Nog 13 shotjes"], + shotCount: 87, + }, + ], + }, + { + timestamp: 5278, + events: [ + { + type: "song", + text: ["Enrique Iglesias", "Hero"], + }, + ], + }, + { + timestamp: 5309, + events: [ + { + type: "shot", + text: ["I can't be your biero!", "Nog 12 shotjes"], + shotCount: 88, + }, + ], + }, + { + timestamp: 5331, + events: [ + { + type: "song", + text: ["Whitney Houston", "I Will Always Love You"], + }, + ], + }, + { + timestamp: 5374, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 11 shotjes"], + shotCount: 89, + }, + ], + }, + { + timestamp: 5380, + events: [ + { + type: "song", + text: ["Mariah Carey", "All I Want For Christmas"], + }, + ], + }, + { + timestamp: 5431, + events: [ + { + type: "shot", + text: ["90 in de keel, hierna niet veel!", "Nog 10 shotjes"], + shotCount: 90, + }, + ], + }, + { + timestamp: 5441, + events: [ + { + type: "time", + text: ["Nog 10 minuten!", "De laatste loodjes"], + }, + ], + }, + { + timestamp: 5444, + events: [ + { + type: "song", + text: ["Kraantje Pappie", "Feesttent (FeestDJRuud remix)"], + }, + ], + }, + { + timestamp: 5488, + events: [ + { + type: "shot", + text: ["Zuip je uit de dubbele cijfers!", "Nog 9 shotjes"], + shotCount: 91, + }, + ], + }, + { + timestamp: 5490.25, + events: [ + { + type: "song", + text: ["New Kids feat. DJ Paul Elstak", "Turbo"], + }, + ], + }, + { + timestamp: 5556, + events: [ + { + type: "shot", + text: ["Zuipen!", "Nog 8 shotjes"], + shotCount: 92, + }, + ], + }, + { + timestamp: 5558, + events: [ + { + type: "song", + text: ["Lipstick", "I'm a Raver"], + }, + ], + }, + { + timestamp: 5591, + events: [ + { + type: "song", + text: ["Nakatomi", "Children of the Night"], + }, + ], + }, + { + timestamp: 5612, + events: [ + { + type: "shot", + text: ["Pweeeep!", "Nog 7 shotjes"], + shotCount: 93, + }, + ], + }, + { + timestamp: 5614, + events: [ + { + type: "song", + text: ["Charly Lownoise & Mental Theo", "Wonderful Days"], + }, + ], + }, + { + timestamp: 5659, + events: [ + { + type: "song", + text: ["DJ Paul Elstak", "Luv You More"], + }, + ], + }, + { + timestamp: 5667, + events: [ + { + type: "shot", + text: ["Bijna daar!", "Nog 6 shotjes"], + shotCount: 94, + }, + ], + }, + { + timestamp: 5704, + events: [ + { + type: "song", + text: ["DJ Paul Elstak", "Rainbow In The Sky"], + }, + ], + }, + { + timestamp: 5716, + events: [ + { + type: "time", + text: ["Nog 5 minuten!", "Zet de shotjes maar klaar"], + }, + ], + }, + { + timestamp: 5731.46, + events: [ + { + type: "shot", + text: ["Toeter!", "Nog 5 shotjes"], + shotCount: 95, + }, + ], + }, + { + timestamp: 5733, + events: [ + { + type: "song", + text: ["Evil Activities", "Nobody Said It Was Easy"], + }, + ], + }, + { + timestamp: 5783, + events: [ + { + type: "shot", + text: ["Slok 96!", "Nog 4 shotjes"], + shotCount: 96, + }, + ], + }, + { + timestamp: 5827, + events: [ + { + type: "song", + text: ["Melrose", "O"], + }, + ], + }, + { + timestamp: 5846, + events: [ + { + type: "shot", + text: ["Voor de 97e keer!", "Nog 3 shotjes"], + shotCount: 97, + }, + ], + }, + { + timestamp: 5855, + events: [ + { + type: "song", + text: ["Backstreet Boys", "I Want It That Way"], + }, + ], + }, + { + timestamp: 5902, + events: [ + { + type: "shot", + text: ["Nummer 98!", "Nog 2 shotjes"], + shotCount: 98, + }, + ], + }, + { + timestamp: 5933, + events: [ + { + type: "song", + text: ["R. Kelly", "The World's Greatest"], + }, + ], + }, + { + timestamp: 5970, + events: [ + { + type: "shot", + text: ["Nummer 99!", "Nog 1 shotje"], + shotCount: 99, + }, + { + type: "song", + text: ["Céline Dion", "My Heart Will Go On"], + }, + ], }, { + timestamp: 6020, + events: [ + { + type: "shot", + text: ["CENTURION!", "Geen shots meer"], + shotCount: 100, + }, + ], + }, + ], + }, + { 'name': 'Centurion 2.0', 'songFile': 'songs/Centurion2.mp3', 'feed': [ @@ -5892,5 +5250,7 @@ module.exports = { } ] } - ] -} + ], +}; + +export default timelines; diff --git a/backend/src/index.ts b/backend/src/index.ts index e0ec8ba..903cc0f 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,105 +1,133 @@ import express from "express"; -import SocketIO, {Socket} from "socket.io"; +import { Server } from "socket.io"; import path from "path"; -import Service from './Service' +import Service from "./Service"; +import { RoomOptions } from "./Room"; // process.on('SIGINT', () => process.exit()); // process.on('SIGTERM', () => process.exit()); -const HOST = '0.0.0.0'; +const HOST = "0.0.0.0"; const PORT = 3001; const app = express(); -const server = app.listen(PORT, HOST, () => console.log(`Centurion listening on port ${PORT}!`)); -app.use(express.static(path.join(__dirname, '../public'))); +const httpServer = app.listen(PORT, HOST, () => + console.log(`Centurion listening on port ${PORT}!`) +); +app.use(express.static(path.join(__dirname, "../public"))); -const io = SocketIO(server); +const io = new Server(httpServer); const service = new Service(); -io.on('connection', socket => { - socket.on('disconnect', (reason) => { - service.onSocketDisconnect(socket); - }); - - socket.on('ping', () => { - socket.emit('pong'); - }) - - socket.on('time_sync', (requestId: number, clientTime: number) => { - if (!Number.isSafeInteger(requestId)) return; - if (!Number.isSafeInteger(clientTime)) return; - - service.onTimeSync(socket, requestId, clientTime); - }) - - socket.on('room_options', (options) => { - if (!options) return; - if (!options.timelineName || typeof (options.timelineName) !== 'string') return; - if (!Number.isSafeInteger(options.seekTime)) return; - - service.onSetRoomOptions(socket, options); - }); - - socket.on('request_start', (options) => { - service.onRequestStart(socket); - }); - - socket.on('request_join', (roomId: number) => { - if (!Number.isSafeInteger(roomId)) return; - - service.onRequestJoin(socket, roomId); - }); - - socket.on('request_ready', () => { - service.onRequestReady(socket); - }) - - socket.on('request_join_random', () => { - service.onRequestJoinRandom(socket); - }) - - socket.on('call', (id: number, name: string, params: any) => { - if (!Number.isSafeInteger(id)) return; - // noinspection SuspiciousTypeOfGuard - if (!name || typeof (name) !== 'string') return; - // if (!params) return; - - let call = new Call(socket, id, name, params); - - if (name == 'room_exists') { - let roomId = params && params['roomId']; - if (!Number.isSafeInteger(roomId)) { - call.error('Invalid room id'); - return; - } +app.get("/state", (req, res) => { + return res.json(service.rooms.map((r) => r.serialize())); +}); - call.respond(service.hasRoomId(roomId)); - return; - } - // - // if (name == 'request_join') { - // let roomId = params && params['roomId']; - // if (!Number.isSafeInteger(roomId)) { - // call.error('Invalid room id'); - // return; - // } - // if (!service.hasRoomId(roomId)) { - // call.respond(false); - // return; - // } - // if (service.onRequestJoin(socket, roomId)) { - // call.respond(true); - // } else { - // call.respond(false); - // } - // } - }) - - service.onSocketConnect(socket); - - /*socket.on('join_room', (roomId, callback) => { +io.on("connection", (socket) => { + socket.on("disconnect", async () => { + await service.onSocketDisconnect(socket); + }); + + socket.on("ping", () => { + socket.emit("pong"); + }); + + socket.on("time_sync", (requestId: number, clientTime: number) => { + if (!Number.isSafeInteger(requestId)) return; + if (!Number.isSafeInteger(clientTime)) return; + + service.onTimeSync(socket, requestId, clientTime); + }); + + socket.on("room_options", (options: RoomOptions) => { + if (!options) return; + if (!options.timelineName || typeof options.timelineName !== "string") + return; + if (!Number.isSafeInteger(options.seekTime)) return; + + service.onSetRoomOptions(socket, options); + }); + + socket.on("request_start", () => { + service.onRequestStart(socket); + }); + + socket.on( + "request_join", + async (roomId: number, callback: (err?: string, res?: boolean) => void) => { + if (!Number.isSafeInteger(roomId)) { + return callback("Invalid roomId."); + } + + if (!service.hasRoomId(roomId)) { + // cannot join a room that does not exist. + return callback(undefined, false); + } + + try { + const didJoinRoom = await service.onRequestJoin(socket, roomId); + callback(undefined, didJoinRoom); + } catch (e) { + callback(e instanceof Error ? e.message : "Unknown error."); + } + } + ); + + socket.on("request_set_ready", () => { + service.onRequestSetReady(socket); + }); + + socket.on("request_join_random", async () => { + await service.onRequestJoinRandom(socket); + }); + + socket.on( + "submit_ticker_message", + (message?: unknown, callback?: (res?: null, err?: string) => void) => { + if (typeof message !== "string") { + return callback && callback(null, "Invalid message."); + } + + if (message.length > 192) { + // perfect voor het Wilhelmus + return callback && callback(null, "Message too long."); + } + + try { + service.submitTickerMessage(socket, message); + return callback && callback(); + } catch (e) { + console.error(e); + return ( + callback && + callback(null, e instanceof Error ? e.message : "Unknown error") + ); + } + } + ); + + service.onSocketConnect(socket); + + // if (name == 'request_join') { + // let roomId = params && params['roomId']; + // if (!Number.isSafeInteger(roomId)) { + // call.error('Invalid room id'); + // return; + // } + // if (!service.hasRoomId(roomId)) { + // call.respond(false); + // return; + // } + // if (service.onRequestJoin(socket, roomId)) { + // call.respond(true); + // } else { + // call.respond(false); + // } + // } + + /*socket.on('join_room', (roomId, callback) => { if (!callback || typeof callback !== 'function') { console.error("Join: Callback not a function."); return @@ -157,31 +185,3 @@ io.on('connection', socket => { } });*/ }); - -class Call { - private socket: Socket; - private id: number; - private name: string; - private params: any; - - constructor(socket: Socket, id: number, name: string, params: any) { - this.socket = socket; - this.id = id; - this.name = name; - this.params = params; - } - - error(reason: string) { - this.socket.emit('call_response', { - 'id': this.id, - 'error': reason - }) - } - - respond(data: any) { - this.socket.emit('call_response', { - 'id': this.id, - 'response': data - }); - } -} diff --git a/backend/src/timeline.ts b/backend/src/timeline.ts index 9afa7d3..a91a6aa 100644 --- a/backend/src/timeline.ts +++ b/backend/src/timeline.ts @@ -1,62 +1,11 @@ -// @ts-ignore -import timeline from '../data/timelines.js'; - +import timeline from "./data/timelines"; export function getTimelineNames(): string[] { - return timeline.timelines.map((i: any) => i.name) + return timeline.timelines.map((timeline) => timeline.name); } export function getTimeline(name: string) { - let t = timeline.timelines.find((i: any) => i.name == name); - if (!t) return null; - return t; -} - -/** - * - * @param i - * @returns {*} - */ -export function getIndex(i: number): any { - if (i >= timeline.length) { - return; - } - - return timeline[i]; -} - -/** - * @param {number} i - the index. - * @returns {{count: number, timestamp: number}|undefined} - */ -export function getNextShot(i: number) { - for (; i < timeline.length; i++) { - const time = getIndex(i); - - for (let event of time.events) { - if (event.type === 'shot') { - return { - timestamp: time.timestamp, - count: event.shotCount - } - } - } - } - - return undefined; -} - -export function indexForTime(seconds: number): number { - let lastIndex = 0; - for (let i = 0; i < timeline.length; i++) { - const time = timeline[i]; - - if (time.timestamp >= seconds) { - return lastIndex; - } - - lastIndex = i; - } - - return -1; + const t = timeline.timelines.find((t) => t.name == name); + if (!t) return null; + return t; } diff --git a/backend/src/util.ts b/backend/src/util.ts index 157e5bd..67c8b78 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -5,16 +5,14 @@ * @returns {number} */ export function randomInt(min: number, max: number): number { - min = Math.ceil(min); - max = Math.floor(max); - return Math.floor(Math.random() * (max - min)) + min; + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min)) + min; } let _randomTimeOffsetForDebug = randomInt(-10000, 10000); _randomTimeOffsetForDebug = 0; -console.log('random time offset', _randomTimeOffsetForDebug); - export function getCurrentTime() { - return Date.now() + _randomTimeOffsetForDebug; + return Date.now() + _randomTimeOffsetForDebug; } diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 8bb50b5..d6ef2db 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -1,8 +1,12 @@ { "compilerOptions": { + "outDir": "build", "target": "es6", "module": "commonjs", "strict": true, "esModuleInterop": true - } + }, + "include": [ + "src" + ] } diff --git a/backend/yarn.lock b/backend/yarn.lock deleted file mode 100644 index efafd4c..0000000 --- a/backend/yarn.lock +++ /dev/null @@ -1,739 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@types/body-parser@*": - version "1.19.0" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" - integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.33" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" - integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== - dependencies: - "@types/node" "*" - -"@types/express-serve-static-core@*": - version "4.17.5" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.5.tgz#a00ac7dadd746ae82477443e4d480a6a93ea083c" - integrity sha512-578YH5Lt88AKoADy0b2jQGwJtrBxezXtVe/MBqWXKZpqx91SnC0pVkVCcxcytz3lWW+cHBYDi3Ysh0WXc+rAYw== - dependencies: - "@types/node" "*" - "@types/range-parser" "*" - -"@types/express@^4.17.6": - version "4.17.6" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.6.tgz#6bce49e49570507b86ea1b07b806f04697fac45e" - integrity sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "*" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/mime@*": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" - integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw== - -"@types/node@*": - version "13.9.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.2.tgz#ace1880c03594cc3e80206d96847157d8e7fa349" - integrity sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg== - -"@types/qs@*": - version "6.9.1" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.1.tgz#937fab3194766256ee09fcd40b781740758617e7" - integrity sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw== - -"@types/range-parser@*": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" - integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== - -"@types/serve-static@*": - version "1.13.3" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.3.tgz#eb7e1c41c4468272557e897e9171ded5e2ded9d1" - integrity sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g== - dependencies: - "@types/express-serve-static-core" "*" - "@types/mime" "*" - -"@types/socket.io@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@types/socket.io/-/socket.io-2.1.4.tgz#674e7bc193c5ccdadd4433f79f3660d31759e9ac" - integrity sha512-cI98INy7tYnweTsUlp8ocveVdAxENUThO0JsLSCs51cjOP2yV5Mqo5QszMDPckyRRA+PO6+wBgKvGvHUCc23TQ== - dependencies: - "@types/node" "*" - -accepts@~1.3.4, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -after@0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" - integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -arraybuffer.slice@~0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" - integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - -backo2@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" - integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= - -base64-arraybuffer@0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" - integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= - -base64id@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" - integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== - -better-assert@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" - integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= - dependencies: - callsite "1.0.0" - -blob@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" - integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== - -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== - dependencies: - bytes "3.1.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== - -callsite@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" - integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= - -component-bind@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" - integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= - -component-emitter@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= - -component-inherit@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" - integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -debug@~4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -engine.io-client@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.0.tgz#82a642b42862a9b3f7a188f41776b2deab643700" - integrity sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA== - dependencies: - component-emitter "1.2.1" - component-inherit "0.0.3" - debug "~4.1.0" - engine.io-parser "~2.2.0" - has-cors "1.1.0" - indexof "0.0.1" - parseqs "0.0.5" - parseuri "0.0.5" - ws "~6.1.0" - xmlhttprequest-ssl "~1.5.4" - yeast "0.1.2" - -engine.io-parser@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed" - integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w== - dependencies: - after "0.8.2" - arraybuffer.slice "~0.0.7" - base64-arraybuffer "0.1.5" - blob "0.0.5" - has-binary2 "~1.0.2" - -engine.io@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.4.0.tgz#3a962cc4535928c252759a00f98519cb46c53ff3" - integrity sha512-XCyYVWzcHnK5cMz7G4VTu2W7zJS7SM1QkcelghyIk/FmobWBtXE7fwhBusEKvCSqc3bMh8fNFMlUkCKTFRxH2w== - dependencies: - accepts "~1.3.4" - base64id "2.0.0" - cookie "0.3.1" - debug "~4.1.0" - engine.io-parser "~2.2.0" - ws "^7.1.2" - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -express@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" - content-type "~1.0.4" - cookie "0.4.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" - range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -has-binary2@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" - integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== - dependencies: - isarray "2.0.1" - -has-cors@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" - integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= - -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" - integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -inherits@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -isarray@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" - integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -mime-db@1.43.0: - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== - -mime-types@~2.1.24: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== - dependencies: - mime-db "1.43.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -object-component@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" - integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -parseqs@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" - integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= - dependencies: - better-assert "~1.0.0" - -parseuri@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" - integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= - dependencies: - better-assert "~1.0.0" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.1" - -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - -safe-buffer@5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.7.2" - mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - -socket.io-adapter@~1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz#ab3f0d6f66b8fc7fca3959ab5991f82221789be9" - integrity sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g== - -socket.io-client@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4" - integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA== - dependencies: - backo2 "1.0.2" - base64-arraybuffer "0.1.5" - component-bind "1.0.0" - component-emitter "1.2.1" - debug "~4.1.0" - engine.io-client "~3.4.0" - has-binary2 "~1.0.2" - has-cors "1.1.0" - indexof "0.0.1" - object-component "0.0.3" - parseqs "0.0.5" - parseuri "0.0.5" - socket.io-parser "~3.3.0" - to-array "0.1.4" - -socket.io-parser@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f" - integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng== - dependencies: - component-emitter "1.2.1" - debug "~3.1.0" - isarray "2.0.1" - -socket.io-parser@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.4.0.tgz#370bb4a151df2f77ce3345ff55a7072cc6e9565a" - integrity sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ== - dependencies: - component-emitter "1.2.1" - debug "~4.1.0" - isarray "2.0.1" - -socket.io@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.3.0.tgz#cd762ed6a4faeca59bc1f3e243c0969311eb73fb" - integrity sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg== - dependencies: - debug "~4.1.0" - engine.io "~3.4.0" - has-binary2 "~1.0.2" - socket.io-adapter "~1.1.0" - socket.io-client "2.3.0" - socket.io-parser "~3.4.0" - -source-map-support@^0.5.17: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -to-array@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" - integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - -ts-node@^8.8.2: - version "8.9.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.9.0.tgz#d7bf7272dcbecd3a2aa18bd0b96c7d2f270c15d4" - integrity sha512-rwkXfOs9zmoHrV8xE++dmNd6ZIS+nmHHCxcV53ekGJrxFLMbp+pizpPS07ARvhwneCIECPppOwbZHvw9sQtU4w== - dependencies: - arg "^4.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" - yn "3.1.1" - -type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typescript@^3.8.3: - version "3.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" - integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -ws@^7.1.2: - version "7.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" - integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== - -ws@~6.1.0: - version "6.1.4" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" - integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA== - dependencies: - async-limiter "~1.0.0" - -xmlhttprequest-ssl@~1.5.4: - version "1.5.5" - resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" - integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= - -yeast@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" - integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js new file mode 100644 index 0000000..b4408df --- /dev/null +++ b/frontend/.eslintrc.js @@ -0,0 +1,23 @@ +module.exports = { + "ignorePatterns": [".eslintrc.js", "vite.config.ts", "postcss.config.js"], + "settings": { + "react": { + "version": "detect" + } + }, + "parserOptions": { + "tsconfigRootDir": __dirname, + "project": ["./tsconfig.json"] + }, + "extends": [ + "plugin:react/recommended" + ], + "rules": { + // suppress errors for missing 'import React' in files + "react/react-in-jsx-scope": "off", + // At some point these must be set to "error" + "@typescript-eslint/no-unsafe-member-access": "warn", + "@typescript-eslint/no-unsafe-assignment": "warn", + "@typescript-eslint/no-unsafe-argument": "warn" + } +}; diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 9d2ae56..264055a 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,14 +1,16 @@ -FROM node:13-alpine AS build +FROM node:16-alpine AS build WORKDIR /app -COPY package.json yarn.lock config-overrides.js ./ -RUN yarn install +# Install TS manually since it's only included in the parent's package.json +RUN npm install --global typescript@^4.5.2 +COPY package.json package-lock.json vite.config.ts ./ +RUN npm ci --no-progress --no-optional -COPY tsconfig.json ./ +COPY tsconfig.json postcss.config.js index.html ./ COPY public public/ COPY src src/ -RUN yarn build +RUN npm run build FROM nginx:alpine WORKDIR /app diff --git a/frontend/config-overrides.js b/frontend/config-overrides.js deleted file mode 100644 index 4236e05..0000000 --- a/frontend/config-overrides.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = { - webpack: function (config, env) { - return config; - }, - devServer: function (configFunction) { - // Return the replacement function for create-react-app to use to generate the Webpack - // Development Server config. "configFunction" is the function that would normally have - // been used to generate the Webpack Development server config - you can use it to create - // a starting configuration to then modify instead of having to create a config from scratch. - return function (proxy, allowedHost) { - // Create the default config by calling configFunction with the proxy/allowedHost parameters - const config = configFunction(proxy, allowedHost); - - config.proxy = { - "/socket.io": { - target: "http://localhost:3001", - ws: true - } - } - - // Return your customised Webpack Development Server config. - return config; - }; - } -} diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..3993d2f --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,21 @@ + + + + + + + + + + + Centurion + + + +
+ + + diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000..9a2b72c --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,5282 @@ +{ + "name": "centurion-via", + "version": "0.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "centurion-via", + "version": "0.1.0", + "dependencies": { + "antd": "^4.17.2", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-ticker": "^1.3.0", + "react-transition-group": "^4.4.2", + "socket.io-client": "^4.4.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^5.15.1", + "@testing-library/react": "^12.1.2", + "@testing-library/user-event": "^13.5.0", + "@types/jest": "^27.0.3", + "@types/react": "^17.0.37", + "@types/react-dom": "^17.0.11", + "@types/react-transition-group": "^4.4.4", + "@types/socket.io-client": "^1.4.36", + "@vitejs/plugin-react": "^1.1.1", + "autoprefixer": "^10.4.0", + "less": "^4.1.2", + "postcss": "^8.4.4", + "postcss-nested": "^5.0.6", + "vite": "^2.7.1", + "vite-plugin-imp": "^2.0.10", + "vite-plugin-svgr": "^0.6.0" + } + }, + "node_modules/@ant-design/colors": { + "version": "6.0.0", + "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==", + "dependencies": { + "@ctrl/tinycolor": "^3.4.0" + } + }, + "node_modules/@ant-design/icons": { + "version": "4.7.0", + "integrity": "sha512-aoB4Z7JA431rt6d4u+8xcNPPCrdufSRMUOpxa1ab6mz1JCQZOEVolj2WVs/tDFmN62zzK30mNelEsprLYsSF3g==", + "dependencies": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-svg": "^4.2.1", + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-util": "^5.9.4" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/@ant-design/icons-svg": { + "version": "4.2.1", + "integrity": "sha512-EB0iwlKDGpG93hW8f85CTJTs4SvMX7tt5ceupvhALp1IF44SeUFOMhKUOYqpsoYWQKAOuTRDMqn75rEaKDp0Xw==" + }, + "node_modules/@ant-design/react-slick": { + "version": "0.28.4", + "integrity": "sha512-j9eAHTn7GxbXUFNknJoHS2ceAsqrQi2j8XykjZE1IXCD8kJF+t28EvhBLniDpbOsBk/3kjalnhriTfZcjBHNqg==", + "dependencies": { + "@babel/runtime": "^7.10.4", + "classnames": "^2.2.5", + "json2mq": "^0.2.0", + "lodash": "^4.17.21", + "resize-observer-polyfill": "^1.5.0" + }, + "peerDependencies": { + "react": ">=16.9.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.0", + "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.16.4", + "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.16.0", + "integrity": "sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-compilation-targets": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.0", + "@babel/helpers": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.16.0", + "integrity": "sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.16.0", + "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.16.3", + "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.16.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.16.0", + "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.16.0", + "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.16.0", + "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.16.0", + "integrity": "sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.16.0", + "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.16.0", + "integrity": "sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-replace-supers": "^7.16.0", + "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.16.0", + "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.14.5", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.16.0", + "integrity": "sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.16.0", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.16.0", + "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.0", + "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.15.7", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.14.5", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.16.3", + "integrity": "sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.3", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.16.0", + "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.15.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.16.4", + "integrity": "sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.16.0", + "integrity": "sha512-8zv2+xiPHwly31RK4RmnEYY5zziuF3O7W2kIDW+07ewWDh6Oi0dRq8kwvulRkFgt6DB97RlKs5c1y068iPlCUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.16.0", + "integrity": "sha512-rqDgIbukZ44pqq7NIRPGPGNklshPkvlmvqjdx3OZcGPk4zGIenYkxDTvl3LsSL8gqcc3ZzGmXPE6hR/u/voNOw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-jsx": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.16.0", + "integrity": "sha512-qq65iSqBRq0Hr3wq57YG2AmW0H6wgTnIzpffTphrUWUgLCOK+zf1f7G0vuOiXrp7dU1qq+fQBoqZ3wCDAkhFzw==", + "dev": true, + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.16.0", + "integrity": "sha512-97yCFY+2GvniqOThOSjPor8xUoDiQ0STVWAQMl3pjhJoFVe5DuXDLZCRSZxu9clx+oRCbTiXGgKEG/Yoyo6Y+w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.16.0", + "integrity": "sha512-8yvbGGrHOeb/oyPc9tzNoe9/lmIjz3HLa9Nc5dMGDyNpGjfFrk8D2KdEq9NRkftZzeoQEW6yPQ29TMZtrLiUUA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.16.3", + "integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.16.3", + "integrity": "sha512-IAdDC7T0+wEB4y2gbIL0uOXEYpiZEeuFUTVbdGq+UwCcF35T/tS8KrmMomEwEc5wBbyfH3PJVpTSUqrhPDXFcQ==", + "dev": true, + "dependencies": { + "core-js-pure": "^3.19.0", + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.16.0", + "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.16.3", + "integrity": "sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/parser": "^7.16.3", + "@babel/types": "^7.16.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.16.0", + "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.15.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.4.0", + "integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/types": { + "version": "27.4.2", + "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "4.1.1", + "integrity": "sha512-clDjivHqWGXi7u+0d2r2sBi4Ie6VLEAzWMIkvJLnDmxoOhBYOTfzGbOQBA32THHm11/LiJbd01tJUpJsbshSWQ==", + "dev": true, + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.0.0", + "integrity": "sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==" + }, + "node_modules/@testing-library/dom": { + "version": "8.11.1", + "integrity": "sha512-3KQDyx9r0RKYailW2MiYrSSKEfH0GTkI51UGEvJenvcoDoeRYs0PZpi2SXqtnMClQvCqdtTTpOfFETDTVADpAg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^4.2.0", + "aria-query": "^5.0.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.4.4", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.0.0", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@testing-library/dom/node_modules/chalk": { + "version": "4.1.2", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "5.15.1", + "integrity": "sha512-kmj8opVDRE1E4GXyLlESsQthCXK7An28dFWxhiMwD7ZUI7ZxA6sjdJRxLerD9Jd8cHX4BDc1jzXaaZKqzlUkvg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^4.2.2", + "chalk": "^3.0.0", + "css": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=8", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/react": { + "version": "12.1.2", + "integrity": "sha512-ihQiEOklNyHIpo2Y8FREkyD1QAea054U0MVbwH1m8N9TxeFz+KoJ9LkqoKqJlzx2JDm56DVwaJ1r36JYxZM05g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@testing-library/user-event": { + "version": "13.5.0", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@types/aria-query": { + "version": "4.2.2", + "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.3", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "27.0.3", + "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==", + "dev": true, + "dependencies": { + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "node_modules/@types/node": { + "version": "16.11.11", + "integrity": "sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "node_modules/@types/prop-types": { + "version": "15.7.4", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", + "dev": true + }, + "node_modules/@types/react": { + "version": "17.0.37", + "integrity": "sha512-2FS1oTqBGcH/s0E+CjrCCR9+JMpsu9b69RTFO+40ua43ZqP5MmQ4iUde/dMjWR909KxZwmOQIFq6AV6NjEG5xg==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "17.0.11", + "integrity": "sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.4", + "integrity": "sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, + "node_modules/@types/socket.io-client": { + "version": "1.4.36", + "integrity": "sha512-ZJWjtFBeBy1kRSYpVbeGYTElf6BqPQUkXDlHHD4k/42byCN5Rh027f4yARHCink9sKAkbtGZXEAmR0ZCnc2/Ag==", + "dev": true + }, + "node_modules/@types/testing-library__jest-dom": { + "version": "5.14.2", + "integrity": "sha512-vehbtyHUShPxIa9SioxDwCvgxukDMH//icJG90sXQBUm5lJOHLT5kNeU9tnivhnA/TkOFMzGIXN2cTc4hY8/kg==", + "dev": true, + "dependencies": { + "@types/jest": "*" + } + }, + "node_modules/@types/yargs": { + "version": "16.0.4", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "node_modules/@vitejs/plugin-react": { + "version": "1.1.1", + "integrity": "sha512-IJSRD4culdwQ6cRK0D1mstV1vdvYSb2HK1JQ1FDo6Hr7j5ppWJEwBC2v/Gy0h/A1lMmi4AnXACY/d10EgbQNEA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/plugin-transform-react-jsx": "^7.16.0", + "@babel/plugin-transform-react-jsx-development": "^7.16.0", + "@babel/plugin-transform-react-jsx-self": "^7.16.0", + "@babel/plugin-transform-react-jsx-source": "^7.16.0", + "@rollup/pluginutils": "^4.1.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/antd": { + "version": "4.17.2", + "integrity": "sha512-1/xwj72mzg2ly5byvnxsgucEL5JMrinlsaAr4Y+vjobmTBSI9l9zOVkwwOG8kPIrFkhrzC1I42n6GZKnTwfZmg==", + "dependencies": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons": "^4.7.0", + "@ant-design/react-slick": "~0.28.1", + "@babel/runtime": "^7.12.5", + "@ctrl/tinycolor": "^3.4.0", + "array-tree-filter": "^2.1.0", + "classnames": "^2.2.6", + "copy-to-clipboard": "^3.2.0", + "lodash": "^4.17.21", + "memoize-one": "^6.0.0", + "moment": "^2.25.3", + "rc-cascader": "~2.2.0", + "rc-checkbox": "~2.3.0", + "rc-collapse": "~3.1.0", + "rc-dialog": "~8.6.0", + "rc-drawer": "~4.4.2", + "rc-dropdown": "~3.2.0", + "rc-field-form": "~1.21.0", + "rc-image": "~5.2.5", + "rc-input-number": "~7.3.0", + "rc-mentions": "~1.6.1", + "rc-menu": "~9.0.12", + "rc-motion": "^2.4.4", + "rc-notification": "~4.5.7", + "rc-pagination": "~3.1.9", + "rc-picker": "~2.5.17", + "rc-progress": "~3.1.0", + "rc-rate": "~2.9.0", + "rc-resize-observer": "^1.0.0", + "rc-select": "~13.1.0-alpha.0", + "rc-slider": "~9.7.4", + "rc-steps": "~4.1.0", + "rc-switch": "~3.2.0", + "rc-table": "~7.19.0", + "rc-tabs": "~11.10.0", + "rc-textarea": "~0.3.0", + "rc-tooltip": "~5.1.1", + "rc-tree": "~5.3.0", + "rc-tree-select": "~4.7.0", + "rc-trigger": "^5.2.10", + "rc-upload": "~4.3.0", + "rc-util": "^5.14.0", + "scroll-into-view-if-needed": "^2.2.25" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ant-design" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/aria-query": { + "version": "4.2.2", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/array-tree-filter": { + "version": "2.1.0", + "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==" + }, + "node_modules/async-validator": { + "version": "4.0.7", + "integrity": "sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ==" + }, + "node_modules/atob": { + "version": "2.1.2", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.0", + "integrity": "sha512-7FdJ1ONtwzV1G43GDD0kpVMn/qbiNqyOPMFTX5nRffI+7vgWoFEc6DcXOxHJxrWNDXrZh18eDsZjvZGUljSRGA==", + "dev": true, + "dependencies": { + "browserslist": "^4.17.5", + "caniuse-lite": "^1.0.30001272", + "fraction.js": "^4.1.1", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.1.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/backo2": { + "version": "1.0.2", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, + "node_modules/browserslist": { + "version": "4.18.1", + "integrity": "sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001280", + "electron-to-chromium": "^1.3.896", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001284", + "integrity": "sha512-t28SKa7g6kiIQi6NHeOcKrOrGMzCRrXvlasPwWC26TH2QNdglgzQIRUuJ0cR3NeQPH+5jpuveeeSFDLm2zbkEw==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/chalk": { + "version": "3.0.0", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/classnames": { + "version": "2.3.1", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/compute-scroll-into-view": { + "version": "1.0.17", + "integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==" + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/copy-anything": { + "version": "2.0.3", + "integrity": "sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ==", + "dev": true, + "dependencies": { + "is-what": "^3.12.0" + } + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.1", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/core-js-pure": { + "version": "3.19.2", + "integrity": "sha512-5LkcgQEy8pFeVnd/zomkUBSwnmIxuF1C8E9KrMAbOc8f34IBT9RGvTYeNDdp1PnvMJrrVhvk1hg/yVV5h/znlg==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "7.0.1", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/css": { + "version": "3.0.0", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "source-map": "^0.6.1", + "source-map-resolve": "^0.6.0" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "dev": true + }, + "node_modules/cssesc": { + "version": "3.0.0", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.0.10", + "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==" + }, + "node_modules/date-fns": { + "version": "2.27.0", + "integrity": "sha512-sj+J0Mo2p2X1e306MHq282WS4/A8Pz/95GIFcsPNMPMZVI3EUrAdSv90al1k+p74WGLCruMXk23bfEDZa71X9Q==", + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/dayjs": { + "version": "1.10.7", + "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==" + }, + "node_modules/debug": { + "version": "4.3.3", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/diff-sequences": { + "version": "27.4.0", + "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.10", + "integrity": "sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==", + "dev": true + }, + "node_modules/dom-align": { + "version": "1.12.2", + "integrity": "sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==" + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.10", + "integrity": "sha512-tFgA40Iq2oy4k2PnZrLJowbgpij+lD6ZLxkw8Ht1NKTYyN8dvSvC5xlo8X0WW2jqhKSzITrbr5mpB4/AZ/8OUA==", + "dev": true + }, + "node_modules/engine.io-client": { + "version": "6.1.1", + "integrity": "sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==", + "dependencies": { + "@socket.io/component-emitter": "~3.0.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.0", + "has-cors": "1.1.0", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~8.2.3", + "xmlhttprequest-ssl": "~2.0.0", + "yeast": "0.1.2" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.2.3", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-client/node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.0.2", + "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==", + "dependencies": { + "base64-arraybuffer": "~1.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io-parser/node_modules/base64-arraybuffer": { + "version": "1.0.1", + "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/esbuild": { + "version": "0.13.15", + "integrity": "sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "optionalDependencies": { + "esbuild-android-arm64": "0.13.15", + "esbuild-darwin-64": "0.13.15", + "esbuild-darwin-arm64": "0.13.15", + "esbuild-freebsd-64": "0.13.15", + "esbuild-freebsd-arm64": "0.13.15", + "esbuild-linux-32": "0.13.15", + "esbuild-linux-64": "0.13.15", + "esbuild-linux-arm": "0.13.15", + "esbuild-linux-arm64": "0.13.15", + "esbuild-linux-mips64le": "0.13.15", + "esbuild-linux-ppc64le": "0.13.15", + "esbuild-netbsd-64": "0.13.15", + "esbuild-openbsd-64": "0.13.15", + "esbuild-sunos-64": "0.13.15", + "esbuild-windows-32": "0.13.15", + "esbuild-windows-64": "0.13.15", + "esbuild-windows-arm64": "0.13.15" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.13.15", + "integrity": "sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/escalade": { + "version": "3.1.1", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/fraction.js": { + "version": "4.1.2", + "integrity": "sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.8", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true, + "optional": true + }, + "node_modules/has": { + "version": "1.0.3", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-cors": { + "version": "1.1.0", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "dev": true, + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.8.0", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, + "node_modules/jest-diff": { + "version": "27.4.2", + "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-get-type": { + "version": "27.4.0", + "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json2mq": { + "version": "0.2.0", + "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=", + "dependencies": { + "string-convert": "^0.2.0" + } + }, + "node_modules/json5": { + "version": "2.2.0", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less": { + "version": "4.1.2", + "integrity": "sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA==", + "dev": true, + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^2.5.2", + "source-map": "~0.6.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/lodash": { + "version": "4.17.21", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lz-string": { + "version": "1.4.4", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "dev": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "node_modules/mime": { + "version": "1.6.0", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/moment": { + "version": "2.29.1", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nanoid": { + "version": "3.1.30", + "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/needle": { + "version": "2.9.1", + "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", + "dev": true, + "optional": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/debug": { + "version": "3.2.7", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "optional": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-releases": { + "version": "2.0.1", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parseqs": { + "version": "0.0.6", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "node_modules/parseuri": { + "version": "0.0.6", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" + }, + "node_modules/path-parse": { + "version": "1.0.7", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.0", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss": { + "version": "8.4.4", + "integrity": "sha512-joU6fBsN6EIer28Lj6GDFoC/5yOZzLCfn0zHAn/MYXI7aPt4m4hK5KC5ovEZXy+lnCjmYIbQWngvju2ddyEr8Q==", + "dev": true, + "dependencies": { + "nanoid": "^3.1.30", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-nested": { + "version": "5.0.6", + "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.6" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.7", + "integrity": "sha512-U+b/Deoi4I/UmE6KOVPpnhS7I7AYdKbhGcat+qTQ27gycvaACvNEw11ba6RrkwVmDVRW7sigWgLj4/KbbJjeDA==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/pretty-format": { + "version": "27.4.2", + "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/prop-types": { + "version": "15.7.2", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true, + "optional": true + }, + "node_modules/rc-align": { + "version": "4.0.11", + "integrity": "sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "dom-align": "^1.7.0", + "lodash": "^4.17.21", + "rc-util": "^5.3.0", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-cascader": { + "version": "2.2.1", + "integrity": "sha512-4saWcwpmxxh5fhUdaDgOLF2gWL8KNxLwWqELX702HNXEt2yU7AixjfvgEORNsnQZleT2W2AaGMkRDeWrwt8fMw==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "array-tree-filter": "^2.1.0", + "rc-tree-select": "~4.7.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.0.1", + "warning": "^4.0.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-checkbox": { + "version": "2.3.2", + "integrity": "sha512-afVi1FYiGv1U0JlpNH/UaEXdh6WUJjcWokj/nUN2TgG80bfG+MDdbfHKlLcNNba94mbjy2/SXJ1HDgrOkXGAjg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-collapse": { + "version": "3.1.2", + "integrity": "sha512-HujcKq7mghk/gVKeI6EjzTbb8e19XUZpakrYazu1MblEZ3Hu3WBMSN4A3QmvbF6n1g7x6lUlZvsHZ5shABWYOQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.3.4", + "rc-util": "^5.2.1", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-dialog": { + "version": "8.6.0", + "integrity": "sha512-GSbkfqjqxpZC5/zc+8H332+q5l/DKUhpQr0vdX2uDsxo5K0PhvaMEVjyoJUTkZ3+JstEADQji1PVLVb/2bJeOQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-motion": "^2.3.0", + "rc-util": "^5.6.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-drawer": { + "version": "4.4.3", + "integrity": "sha512-FYztwRs3uXnFOIf1hLvFxIQP9MiZJA+0w+Os8dfDh/90X7z/HqP/Yg+noLCIeHEbKln1Tqelv8ymCAN24zPcfQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-util": "^5.7.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-dropdown": { + "version": "3.2.0", + "integrity": "sha512-j1HSw+/QqlhxyTEF6BArVZnTmezw2LnSmRk6I9W7BCqNCKaRwleRmMMs1PHbuaG8dKHVqP6e21RQ7vPBLVnnNw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-trigger": "^5.0.4" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-field-form": { + "version": "1.21.2", + "integrity": "sha512-LR/bURt/Tf5g39mb0wtMtQuWn42d/7kEzpzlC5fNC7yaRVmLTtlPP4sBBlaViETM9uZQKLoaB0Pt9Mubhm9gow==", + "dependencies": { + "@babel/runtime": "^7.8.4", + "async-validator": "^4.0.2", + "rc-util": "^5.8.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">= 16.9.0", + "react-dom": ">= 16.9.0" + } + }, + "node_modules/rc-image": { + "version": "5.2.5", + "integrity": "sha512-qUfZjYIODxO0c8a8P5GeuclYXZjzW4hV/5hyo27XqSFo1DmTCs2HkVeQObkcIk5kNsJtgsj1KoPThVsSc/PXOw==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-dialog": "~8.6.0", + "rc-util": "^5.0.6" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-input-number": { + "version": "7.3.4", + "integrity": "sha512-W9uqSzuvJUnz8H8vsVY4kx+yK51SsAxNTwr8SNH4G3XqQNocLVmKIibKFRjocnYX1RDHMND9FFbgj2h7E7nvGA==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.9.8" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-mentions": { + "version": "1.6.1", + "integrity": "sha512-LDzGI8jJVGnkhpTZxZuYBhMz3avcZZqPGejikchh97xPni/g4ht714Flh7DVvuzHQ+BoKHhIjobHnw1rcP8erg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-menu": "^9.0.0", + "rc-textarea": "^0.3.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.0.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-menu": { + "version": "9.0.14", + "integrity": "sha512-CIox5mZeLDAi32SlHrV7UeSjv7tmJJhwRyxQtZCKt351w3q59XlL4WMFOmtT9gwIfP9h0XoxdBZUMe/xzkp78A==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.4.3", + "rc-overflow": "^1.2.0", + "rc-trigger": "^5.1.2", + "rc-util": "^5.12.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-motion": { + "version": "2.4.4", + "integrity": "sha512-ms7n1+/TZQBS0Ydd2Q5P4+wJTSOrhIrwNxLXCZpR7Fa3/oac7Yi803HDALc2hLAKaCTQtw9LmQeB58zcwOsqlQ==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.2.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-notification": { + "version": "4.5.7", + "integrity": "sha512-zhTGUjBIItbx96SiRu3KVURcLOydLUHZCPpYEn1zvh+re//Tnq/wSxN4FKgp38n4HOgHSVxcLEeSxBMTeBBDdw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.2.0", + "rc-util": "^5.0.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-overflow": { + "version": "1.2.2", + "integrity": "sha512-X5kj9LDU1ue5wHkqvCprJWLKC+ZLs3p4He/oxjZ1Q4NKaqKBaYf5OdSzRSgh3WH8kSdrfU8LjvlbWnHgJOEkNQ==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-pagination": { + "version": "3.1.14", + "integrity": "sha512-tcugvxrtPiVU00Uh0IwC8NIUlxa4KtA9pXcaMNJdSHeO2uQqVkHEwllsULTAWRF3zRV2ozo2weP/DRKIUrX+Zg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-picker": { + "version": "2.5.19", + "integrity": "sha512-u6myoCu/qiQ0vLbNzSzNrzTQhs7mldArCpPHrEI6OUiifs+IPXmbesqSm0zilJjfzrZJLgYeyyOMSznSlh0GKA==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "date-fns": "2.x", + "dayjs": "1.x", + "moment": "^2.24.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.4.0", + "shallowequal": "^1.1.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-progress": { + "version": "3.1.4", + "integrity": "sha512-XBAif08eunHssGeIdxMXOmRQRULdHaDdIFENQ578CMb4dyewahmmfJRyab+hw4KH4XssEzzYOkAInTLS7JJG+Q==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-rate": { + "version": "2.9.1", + "integrity": "sha512-MmIU7FT8W4LYRRHJD1sgG366qKtSaKb67D0/vVvJYR0lrCuRrCiVQ5qhfT5ghVO4wuVIORGpZs7ZKaYu+KMUzA==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.0.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-resize-observer": { + "version": "1.1.1", + "integrity": "sha512-5A3B9ha297ItltzXl812WFE36SyRDTNclfrXE3FL1pEwXkBh7iSEzxjzfwsPeMcF9ahy3ZoxLgLuRksXBGGD6A==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-util": "^5.15.0", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-select": { + "version": "13.1.1", + "integrity": "sha512-Oy4L27x5QgGR8902pw0bJVjrTWFnKPKvdLHzJl5pjiA+jM1hpzDfLGg/bY2ntk5ElxxQKZUwbFKUeqfCQU7SrQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-overflow": "^1.0.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.9.8", + "rc-virtual-list": "^3.2.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-slider": { + "version": "9.7.4", + "integrity": "sha512-pjLKLiDKiaL7/pNywfIBD+lDo5TtVo05KuIBSWEIoqu6FHh6IMWvthCiaODuYaVs3RLeF2nXOP5AjkD2Lt2Rwg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-tooltip": "^5.0.1", + "rc-util": "^5.0.0", + "shallowequal": "^1.1.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-steps": { + "version": "4.1.4", + "integrity": "sha512-qoCqKZWSpkh/b03ASGx1WhpKnuZcRWmvuW+ZUu4mvMdfvFzVxblTwUM+9aBd0mlEUFmt6GW8FXhMpHkK3Uzp3w==", + "dependencies": { + "@babel/runtime": "^7.10.2", + "classnames": "^2.2.3", + "rc-util": "^5.0.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-switch": { + "version": "3.2.2", + "integrity": "sha512-+gUJClsZZzvAHGy1vZfnwySxj+MjLlGRyXKXScrtCTcmiYNPzxDFOxdQ/3pK1Kt/0POvwJ/6ALOR8gwdXGhs+A==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-util": "^5.0.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-table": { + "version": "7.19.2", + "integrity": "sha512-NdpnoM50MK02H5/hGOsObfxCvGFUG5cHB9turE5BKJ81T5Ycbq193w5tLhnpILXe//Oanzr47MdMxkUnVGP+qg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.14.0", + "shallowequal": "^1.1.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tabs": { + "version": "11.10.4", + "integrity": "sha512-FXihSD9DEF7G/C5iIHNon5jzIO66Two0aeB6uHCmSYibasCsnuBFslHXb9Pa4woqs+vVNjiKRgoDZfurwx1rzg==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "classnames": "2.x", + "rc-dropdown": "^3.2.0", + "rc-menu": "^9.0.0", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.5.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-textarea": { + "version": "0.3.5", + "integrity": "sha512-qa+k5vDn9ct65qr+SgD2KwJ9Xz6P84lG2z+TDht/RBr71WnM/K61PqHUAcUyU6YqTJD26IXgjPuuhZR7HMw7eA==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.7.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tooltip": { + "version": "5.1.1", + "integrity": "sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "rc-trigger": "^5.0.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tree": { + "version": "5.3.0", + "integrity": "sha512-A9GpRalG9sCsC+D3Dw9AB3a2gggf7KUT1FoCGGrbmCH1vsBYfTm3Z4RqEUrWtC7793HRccUTxqnENymkKS99lw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-util": "^5.0.0", + "rc-virtual-list": "^3.4.1" + }, + "engines": { + "node": ">=10.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-tree-select": { + "version": "4.7.0", + "integrity": "sha512-xcc2yPpQieTW6BcRkcKbT1dcAYCQ7ARtkoHlS9EsNdd6xgw9LA6rek6PMed8r/VRMfiKtWV4c4xijW5PI6s4Rw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-select": "~13.1.0-alpha.0", + "rc-tree": "~5.3.0", + "rc-util": "^5.7.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-trigger": { + "version": "5.2.10", + "integrity": "sha512-FkUf4H9BOFDaIwu42fvRycXMAvkttph9AlbCZXssZDVzz2L+QZ0ERvfB/4nX3ZFPh1Zd+uVGr1DEDeXxq4J1TA==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-align": "^4.0.0", + "rc-motion": "^2.0.0", + "rc-util": "^5.5.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-upload": { + "version": "4.3.2", + "integrity": "sha512-v0HdwC/19xKAn1OYZ4hTMUSqSs/IA0n1v4p/cioSSnKubHrdpcCXC45N+TFMSOZtBlf4+xMNCFo3KDih31lAMg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-util": { + "version": "5.15.0", + "integrity": "sha512-8RI8sjOCXD3FhD3dzQNBQetpGol6BBd3sHQ/8jSGk9NPT0CH3JGtBfPODnASyE7AdDpCFQMOmgcp9CBs3S/1hg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "react-is": "^16.12.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-virtual-list": { + "version": "3.4.2", + "integrity": "sha512-OyVrrPvvFcHvV0ssz5EDZ+7Rf5qLat/+mmujjchNw5FfbJWNDwkpQ99EcVE6+FtNRmX9wFa1LGNpZLUTvp/4GQ==", + "dependencies": { + "classnames": "^2.2.6", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.0.7" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/react": { + "version": "17.0.2", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "17.0.2", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + }, + "peerDependencies": { + "react": "17.0.2" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-refresh": { + "version": "0.11.0", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-ticker": { + "version": "1.3.0", + "integrity": "sha512-aB+Gk17BkZAMMYSel4aJ74EbDfvEbZ6zIFsvylO6FXV5xWj08NzaXc833uBv8TxP0RQ9kKjN6HgSd+VyH6Bu1w==", + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "prop-types": "^15.5.4", + "react": "^16.7.0", + "react-dom": "^16.7.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.2", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, + "node_modules/resolve": { + "version": "1.20.0", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "optional": true + }, + "node_modules/sax": { + "version": "1.2.4", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true, + "optional": true + }, + "node_modules/scheduler": { + "version": "0.20.2", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/scroll-into-view-if-needed": { + "version": "2.2.28", + "integrity": "sha512-8LuxJSuFVc92+0AdNv4QOxRL4Abeo1DgLnGNkn1XlaujPH/3cCFz3QI60r2VNu4obJJROzgnIUw5TKQkZvZI1w==", + "dependencies": { + "compute-scroll-into-view": "^1.0.17" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "node_modules/socket.io-client": { + "version": "4.4.0", + "integrity": "sha512-g7riSEJXi7qCFImPow98oT8X++MSsHz6MMFRXkWNJ6uEROSHOa3kxdrsYWMq85dO+09CFMkcqlpjvbVXQl4z6g==", + "dependencies": { + "@socket.io/component-emitter": "~3.0.0", + "backo2": "~1.0.2", + "debug": "~4.3.2", + "engine.io-client": "~6.1.1", + "parseuri": "0.0.6", + "socket.io-parser": "~4.1.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.1.1", + "integrity": "sha512-USQVLSkDWE5nbcY760ExdKaJxCE65kcsG/8k5FDGZVVxpD1pA7hABYXYkCUvxUuYYh/+uQw0N/fvBzfT8o07KA==", + "dependencies": { + "@socket.io/component-emitter": "~3.0.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.1", + "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.6.0", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, + "node_modules/string-convert": { + "version": "0.2.1", + "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=" + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" + }, + "node_modules/tslib": { + "version": "2.3.1", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/vite": { + "version": "2.7.1", + "integrity": "sha512-TDXXhcu5lyQ6uosK4ZWaOyB4VzOiizk0biitRzDzaEtgSUi8rVYPc4k1xgOjLSf0OuceDJmojFKXHOX9DB1WuQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.13.12", + "postcss": "^8.3.11", + "resolve": "^1.20.0", + "rollup": "^2.59.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": ">=12.2.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "less": "*", + "sass": "*", + "stylus": "*" + }, + "peerDependenciesMeta": { + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + } + } + }, + "node_modules/vite-plugin-imp": { + "version": "2.0.10", + "integrity": "sha512-fn+g1/K3jedgS+etFHhD9fQzxpX3DI5DXjCw3wkP+dYBzG2sPDGoSiOxxsZS4YRFf5jo94ARqMMam9dbA6mWag==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.10", + "@babel/generator": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/traverse": "^7.12.12", + "chalk": "^4.1.0", + "param-case": "^3.0.4" + }, + "peerDependencies": { + "vite": ">= 2.0.0-beta.5" + } + }, + "node_modules/vite-plugin-imp/node_modules/chalk": { + "version": "4.1.2", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/vite-plugin-svgr": { + "version": "0.6.0", + "integrity": "sha512-+9eiWLzdlLK3ktnO7gzazMmR/KJyXTy7z6GeRbhv5HKEOFjLdNk3eB0qJaSpzJC3dr2pKWml0jAmxH7O6CcQtg==", + "dev": true, + "dependencies": { + "@svgr/core": "^6.0.0-alpha.3" + }, + "peerDependencies": { + "vite": "^2.6.0" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@babel/core": { + "version": "7.16.0", + "integrity": "sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-compilation-targets": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.0", + "@babel/helpers": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "6.0.0", + "integrity": "sha512-MdPdhdWLtQsjd29Wa4pABdhWbaRMACdM1h31BY+c6FghTZqNGT7pEYdBoaGeKtdTOBC/XNFQaKVj+r/Ei2ryWA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "6.0.0", + "integrity": "sha512-aVdtfx9jlaaxc3unA6l+M9YRnKIZjOhQPthLKqmTXC8UVkBLDRGwPKo+r8n3VZN8B34+yVajzPTZ+ptTSuZZCw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "6.0.0", + "integrity": "sha512-Ccj42ApsePD451AZJJf1QzTD1B/BOU392URJTeXFxSK709i0KUsGtbwyiqsKu7vsYxpTM0IA5clAKDyf9RCZyA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "6.0.0", + "integrity": "sha512-88V26WGyt1Sfd1emBYmBJRWMmgarrExpKNVmI9vVozha4kqs6FzQJ/Kp5+EYli1apgX44518/0+t9+NU36lThQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "6.0.0", + "integrity": "sha512-F7YXNLfGze+xv0KMQxrl2vkNbI9kzT9oDK55/kUuymh1ACyXkMV+VZWX1zEhSTfEKh7VkHVZGmVtHg8eTZ6PRg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "6.0.0", + "integrity": "sha512-+rghFXxdIqJNLQK08kwPBD3Z22/0b2tEZ9lKiL/yTfuyj1wW8HUXu4bo/XkogATIYuXSghVQOOCwURXzHGKyZA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "6.0.0", + "integrity": "sha512-VaphyHZ+xIKv5v0K0HCzyfAaLhPGJXSk2HkpYfXIOKb7DjLBv0soHDxNv6X0vr2titsxE7klb++u7iOf7TSrFQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "6.1.0", + "integrity": "sha512-1zacrn08K5RyV2NtXahOZ5Im/+aB1Y0LVh6QpzwgQV05sY7H5Npq+OcW/UqXbfB2Ua/WnHsFossFQqigCjarYg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/babel-preset": { + "version": "6.1.0", + "integrity": "sha512-f9XrTqcwhHLVkjvXBw6QJVxuIfmW22z8iTdGqGvUGGxWoeRV2EzSHstWMBgIVd7t+TmkerqowRvBYiT0OEx3cw==", + "dev": true, + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^6.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^6.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^6.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^6.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "^6.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "^6.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "^6.0.0", + "@svgr/babel-plugin-transform-svg-component": "^6.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/core": { + "version": "6.1.1", + "integrity": "sha512-/NP+24cQmcEdJYptoFWO34SHkNx2x4KOGAMcnTpzOPQifvb1ecupWNEPeHBDY18utd0OMpl2kWf0ZnyN5VsVlg==", + "dev": true, + "dependencies": { + "@svgr/plugin-jsx": "^6.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/hast-util-to-babel-ast": { + "version": "6.0.0", + "integrity": "sha512-S+TxtCdDyRGafH1VG1t/uPZ87aOYOHzWL8kqz4FoSZcIbzWA6rnOmjNViNiDzqmEpzp2PW5o5mZfvC9DiVZhTQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.6", + "entities": "^3.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@svgr/plugin-jsx": { + "version": "6.1.0", + "integrity": "sha512-grAeVnwjr4eyzzscX6d5dK202nQcKGt5STry3BrCNuw8RZkMVFYumjH/qLnInO2ugc0ESSo8eCkb+30vXVxSTg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.15.5", + "@svgr/babel-preset": "^6.1.0", + "@svgr/hast-util-to-babel-ast": "^6.0.0", + "svg-parser": "^2.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "^6.0.0-alpha.0" + } + }, + "node_modules/vite-plugin-svgr/node_modules/camelcase": { + "version": "6.2.1", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vite-plugin-svgr/node_modules/entities": { + "version": "3.0.1", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/vite-plugin-svgr/node_modules/semver": { + "version": "6.3.0", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/vite-plugin-svgr/node_modules/source-map": { + "version": "0.5.7", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vite/node_modules/postcss": { + "version": "8.4.4", + "integrity": "sha512-joU6fBsN6EIer28Lj6GDFoC/5yOZzLCfn0zHAn/MYXI7aPt4m4hK5KC5ovEZXy+lnCjmYIbQWngvju2ddyEr8Q==", + "dev": true, + "dependencies": { + "nanoid": "^3.1.30", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/vite/node_modules/rollup": { + "version": "2.61.0", + "integrity": "sha512-teQ+T1mUYbyvGyUavCodiyA9hD4DxwYZJwr/qehZGhs1Z49vsmzelMVYMxGU4ZhGRKxYPupHuz5yzm/wj7VpWA==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/warning": { + "version": "4.0.3", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/yaml": { + "version": "1.10.2", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yeast": { + "version": "0.1.2", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + } + }, + "dependencies": { + "@ant-design/colors": { + "version": "6.0.0", + "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==", + "requires": { + "@ctrl/tinycolor": "^3.4.0" + } + }, + "@ant-design/icons": { + "version": "4.7.0", + "integrity": "sha512-aoB4Z7JA431rt6d4u+8xcNPPCrdufSRMUOpxa1ab6mz1JCQZOEVolj2WVs/tDFmN62zzK30mNelEsprLYsSF3g==", + "requires": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-svg": "^4.2.1", + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-util": "^5.9.4" + } + }, + "@ant-design/icons-svg": { + "version": "4.2.1", + "integrity": "sha512-EB0iwlKDGpG93hW8f85CTJTs4SvMX7tt5ceupvhALp1IF44SeUFOMhKUOYqpsoYWQKAOuTRDMqn75rEaKDp0Xw==" + }, + "@ant-design/react-slick": { + "version": "0.28.4", + "integrity": "sha512-j9eAHTn7GxbXUFNknJoHS2ceAsqrQi2j8XykjZE1IXCD8kJF+t28EvhBLniDpbOsBk/3kjalnhriTfZcjBHNqg==", + "requires": { + "@babel/runtime": "^7.10.4", + "classnames": "^2.2.5", + "json2mq": "^0.2.0", + "lodash": "^4.17.21", + "resize-observer-polyfill": "^1.5.0" + } + }, + "@babel/code-frame": { + "version": "7.16.0", + "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.0" + } + }, + "@babel/compat-data": { + "version": "7.16.4", + "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", + "dev": true + }, + "@babel/core": { + "version": "7.16.0", + "integrity": "sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-compilation-targets": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.0", + "@babel/helpers": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.16.0", + "integrity": "sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.16.0", + "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.16.3", + "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.16.0", + "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.16.0", + "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.16.0", + "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.16.0", + "integrity": "sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.16.0", + "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.16.0", + "integrity": "sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-replace-supers": "^7.16.0", + "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.16.0", + "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.16.0", + "integrity": "sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.16.0", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.16.0", + "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.16.0", + "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true + }, + "@babel/helpers": { + "version": "7.16.3", + "integrity": "sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w==", + "dev": true, + "requires": { + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.3", + "@babel/types": "^7.16.0" + } + }, + "@babel/highlight": { + "version": "7.16.0", + "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.15.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.16.4", + "integrity": "sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==", + "dev": true + }, + "@babel/plugin-syntax-jsx": { + "version": "7.16.0", + "integrity": "sha512-8zv2+xiPHwly31RK4RmnEYY5zziuF3O7W2kIDW+07ewWDh6Oi0dRq8kwvulRkFgt6DB97RlKs5c1y068iPlCUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.16.0", + "integrity": "sha512-rqDgIbukZ44pqq7NIRPGPGNklshPkvlmvqjdx3OZcGPk4zGIenYkxDTvl3LsSL8gqcc3ZzGmXPE6hR/u/voNOw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-jsx": "^7.16.0", + "@babel/types": "^7.16.0" + } + }, + "@babel/plugin-transform-react-jsx-development": { + "version": "7.16.0", + "integrity": "sha512-qq65iSqBRq0Hr3wq57YG2AmW0H6wgTnIzpffTphrUWUgLCOK+zf1f7G0vuOiXrp7dU1qq+fQBoqZ3wCDAkhFzw==", + "dev": true, + "requires": { + "@babel/plugin-transform-react-jsx": "^7.16.0" + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.16.0", + "integrity": "sha512-97yCFY+2GvniqOThOSjPor8xUoDiQ0STVWAQMl3pjhJoFVe5DuXDLZCRSZxu9clx+oRCbTiXGgKEG/Yoyo6Y+w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.16.0", + "integrity": "sha512-8yvbGGrHOeb/oyPc9tzNoe9/lmIjz3HLa9Nc5dMGDyNpGjfFrk8D2KdEq9NRkftZzeoQEW6yPQ29TMZtrLiUUA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/runtime": { + "version": "7.16.3", + "integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/runtime-corejs3": { + "version": "7.16.3", + "integrity": "sha512-IAdDC7T0+wEB4y2gbIL0uOXEYpiZEeuFUTVbdGq+UwCcF35T/tS8KrmMomEwEc5wBbyfH3PJVpTSUqrhPDXFcQ==", + "dev": true, + "requires": { + "core-js-pure": "^3.19.0", + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.16.0", + "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0" + } + }, + "@babel/traverse": { + "version": "7.16.3", + "integrity": "sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/parser": "^7.16.3", + "@babel/types": "^7.16.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.16.0", + "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.15.7", + "to-fast-properties": "^2.0.0" + } + }, + "@ctrl/tinycolor": { + "version": "3.4.0", + "integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==" + }, + "@jest/types": { + "version": "27.4.2", + "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@rollup/pluginutils": { + "version": "4.1.1", + "integrity": "sha512-clDjivHqWGXi7u+0d2r2sBi4Ie6VLEAzWMIkvJLnDmxoOhBYOTfzGbOQBA32THHm11/LiJbd01tJUpJsbshSWQ==", + "dev": true, + "requires": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + } + }, + "@socket.io/component-emitter": { + "version": "3.0.0", + "integrity": "sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==" + }, + "@testing-library/dom": { + "version": "8.11.1", + "integrity": "sha512-3KQDyx9r0RKYailW2MiYrSSKEfH0GTkI51UGEvJenvcoDoeRYs0PZpi2SXqtnMClQvCqdtTTpOfFETDTVADpAg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^4.2.0", + "aria-query": "^5.0.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.4.4", + "pretty-format": "^27.0.2" + }, + "dependencies": { + "aria-query": { + "version": "5.0.0", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@testing-library/jest-dom": { + "version": "5.15.1", + "integrity": "sha512-kmj8opVDRE1E4GXyLlESsQthCXK7An28dFWxhiMwD7ZUI7ZxA6sjdJRxLerD9Jd8cHX4BDc1jzXaaZKqzlUkvg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^4.2.2", + "chalk": "^3.0.0", + "css": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + } + }, + "@testing-library/react": { + "version": "12.1.2", + "integrity": "sha512-ihQiEOklNyHIpo2Y8FREkyD1QAea054U0MVbwH1m8N9TxeFz+KoJ9LkqoKqJlzx2JDm56DVwaJ1r36JYxZM05g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.0.0" + } + }, + "@testing-library/user-event": { + "version": "13.5.0", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5" + } + }, + "@types/aria-query": { + "version": "4.2.2", + "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", + "dev": true + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "27.0.3", + "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==", + "dev": true, + "requires": { + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "@types/node": { + "version": "16.11.11", + "integrity": "sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw==", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "@types/prop-types": { + "version": "15.7.4", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", + "dev": true + }, + "@types/react": { + "version": "17.0.37", + "integrity": "sha512-2FS1oTqBGcH/s0E+CjrCCR9+JMpsu9b69RTFO+40ua43ZqP5MmQ4iUde/dMjWR909KxZwmOQIFq6AV6NjEG5xg==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "17.0.11", + "integrity": "sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-transition-group": { + "version": "4.4.4", + "integrity": "sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/scheduler": { + "version": "0.16.2", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, + "@types/socket.io-client": { + "version": "1.4.36", + "integrity": "sha512-ZJWjtFBeBy1kRSYpVbeGYTElf6BqPQUkXDlHHD4k/42byCN5Rh027f4yARHCink9sKAkbtGZXEAmR0ZCnc2/Ag==", + "dev": true + }, + "@types/testing-library__jest-dom": { + "version": "5.14.2", + "integrity": "sha512-vehbtyHUShPxIa9SioxDwCvgxukDMH//icJG90sXQBUm5lJOHLT5kNeU9tnivhnA/TkOFMzGIXN2cTc4hY8/kg==", + "dev": true, + "requires": { + "@types/jest": "*" + } + }, + "@types/yargs": { + "version": "16.0.4", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "20.2.1", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "@vitejs/plugin-react": { + "version": "1.1.1", + "integrity": "sha512-IJSRD4culdwQ6cRK0D1mstV1vdvYSb2HK1JQ1FDo6Hr7j5ppWJEwBC2v/Gy0h/A1lMmi4AnXACY/d10EgbQNEA==", + "dev": true, + "requires": { + "@babel/core": "^7.16.0", + "@babel/plugin-transform-react-jsx": "^7.16.0", + "@babel/plugin-transform-react-jsx-development": "^7.16.0", + "@babel/plugin-transform-react-jsx-self": "^7.16.0", + "@babel/plugin-transform-react-jsx-source": "^7.16.0", + "@rollup/pluginutils": "^4.1.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "antd": { + "version": "4.17.2", + "integrity": "sha512-1/xwj72mzg2ly5byvnxsgucEL5JMrinlsaAr4Y+vjobmTBSI9l9zOVkwwOG8kPIrFkhrzC1I42n6GZKnTwfZmg==", + "requires": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons": "^4.7.0", + "@ant-design/react-slick": "~0.28.1", + "@babel/runtime": "^7.12.5", + "@ctrl/tinycolor": "^3.4.0", + "array-tree-filter": "^2.1.0", + "classnames": "^2.2.6", + "copy-to-clipboard": "^3.2.0", + "lodash": "^4.17.21", + "memoize-one": "^6.0.0", + "moment": "^2.25.3", + "rc-cascader": "~2.2.0", + "rc-checkbox": "~2.3.0", + "rc-collapse": "~3.1.0", + "rc-dialog": "~8.6.0", + "rc-drawer": "~4.4.2", + "rc-dropdown": "~3.2.0", + "rc-field-form": "~1.21.0", + "rc-image": "~5.2.5", + "rc-input-number": "~7.3.0", + "rc-mentions": "~1.6.1", + "rc-menu": "~9.0.12", + "rc-motion": "^2.4.4", + "rc-notification": "~4.5.7", + "rc-pagination": "~3.1.9", + "rc-picker": "~2.5.17", + "rc-progress": "~3.1.0", + "rc-rate": "~2.9.0", + "rc-resize-observer": "^1.0.0", + "rc-select": "~13.1.0-alpha.0", + "rc-slider": "~9.7.4", + "rc-steps": "~4.1.0", + "rc-switch": "~3.2.0", + "rc-table": "~7.19.0", + "rc-tabs": "~11.10.0", + "rc-textarea": "~0.3.0", + "rc-tooltip": "~5.1.1", + "rc-tree": "~5.3.0", + "rc-tree-select": "~4.7.0", + "rc-trigger": "^5.2.10", + "rc-upload": "~4.3.0", + "rc-util": "^5.14.0", + "scroll-into-view-if-needed": "^2.2.25" + } + }, + "aria-query": { + "version": "4.2.2", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + } + }, + "array-tree-filter": { + "version": "2.1.0", + "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==" + }, + "async-validator": { + "version": "4.0.7", + "integrity": "sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ==" + }, + "atob": { + "version": "2.1.2", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "autoprefixer": { + "version": "10.4.0", + "integrity": "sha512-7FdJ1ONtwzV1G43GDD0kpVMn/qbiNqyOPMFTX5nRffI+7vgWoFEc6DcXOxHJxrWNDXrZh18eDsZjvZGUljSRGA==", + "dev": true, + "requires": { + "browserslist": "^4.17.5", + "caniuse-lite": "^1.0.30001272", + "fraction.js": "^4.1.1", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.1.0" + } + }, + "backo2": { + "version": "1.0.2", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, + "browserslist": { + "version": "4.18.1", + "integrity": "sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001280", + "electron-to-chromium": "^1.3.896", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001284", + "integrity": "sha512-t28SKa7g6kiIQi6NHeOcKrOrGMzCRrXvlasPwWC26TH2QNdglgzQIRUuJ0cR3NeQPH+5jpuveeeSFDLm2zbkEw==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "classnames": { + "version": "2.3.1", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, + "color-convert": { + "version": "2.0.1", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "compute-scroll-into-view": { + "version": "1.0.17", + "integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==" + }, + "convert-source-map": { + "version": "1.8.0", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-anything": { + "version": "2.0.3", + "integrity": "sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ==", + "dev": true, + "requires": { + "is-what": "^3.12.0" + } + }, + "copy-to-clipboard": { + "version": "3.3.1", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", + "requires": { + "toggle-selection": "^1.0.6" + } + }, + "core-js-pure": { + "version": "3.19.2", + "integrity": "sha512-5LkcgQEy8pFeVnd/zomkUBSwnmIxuF1C8E9KrMAbOc8f34IBT9RGvTYeNDdp1PnvMJrrVhvk1hg/yVV5h/znlg==", + "dev": true + }, + "cosmiconfig": { + "version": "7.0.1", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "css": { + "version": "3.0.0", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "source-map": "^0.6.1", + "source-map-resolve": "^0.6.0" + } + }, + "css.escape": { + "version": "1.5.1", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "csstype": { + "version": "3.0.10", + "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==" + }, + "date-fns": { + "version": "2.27.0", + "integrity": "sha512-sj+J0Mo2p2X1e306MHq282WS4/A8Pz/95GIFcsPNMPMZVI3EUrAdSv90al1k+p74WGLCruMXk23bfEDZa71X9Q==" + }, + "dayjs": { + "version": "1.10.7", + "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==" + }, + "debug": { + "version": "4.3.3", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "diff-sequences": { + "version": "27.4.0", + "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", + "dev": true + }, + "dom-accessibility-api": { + "version": "0.5.10", + "integrity": "sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==", + "dev": true + }, + "dom-align": { + "version": "1.12.2", + "integrity": "sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==" + }, + "dom-helpers": { + "version": "5.2.1", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "dot-case": { + "version": "3.0.4", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "electron-to-chromium": { + "version": "1.4.10", + "integrity": "sha512-tFgA40Iq2oy4k2PnZrLJowbgpij+lD6ZLxkw8Ht1NKTYyN8dvSvC5xlo8X0WW2jqhKSzITrbr5mpB4/AZ/8OUA==", + "dev": true + }, + "engine.io-client": { + "version": "6.1.1", + "integrity": "sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==", + "requires": { + "@socket.io/component-emitter": "~3.0.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.0", + "has-cors": "1.1.0", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~8.2.3", + "xmlhttprequest-ssl": "~2.0.0", + "yeast": "0.1.2" + }, + "dependencies": { + "ws": { + "version": "8.2.3", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "requires": {} + }, + "xmlhttprequest-ssl": { + "version": "2.0.0", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" + } + } + }, + "engine.io-parser": { + "version": "5.0.2", + "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==", + "requires": { + "base64-arraybuffer": "~1.0.1" + }, + "dependencies": { + "base64-arraybuffer": { + "version": "1.0.1", + "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==" + } + } + }, + "errno": { + "version": "0.1.8", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "esbuild": { + "version": "0.13.15", + "integrity": "sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw==", + "dev": true, + "requires": { + "esbuild-android-arm64": "0.13.15", + "esbuild-darwin-64": "0.13.15", + "esbuild-darwin-arm64": "0.13.15", + "esbuild-freebsd-64": "0.13.15", + "esbuild-freebsd-arm64": "0.13.15", + "esbuild-linux-32": "0.13.15", + "esbuild-linux-64": "0.13.15", + "esbuild-linux-arm": "0.13.15", + "esbuild-linux-arm64": "0.13.15", + "esbuild-linux-mips64le": "0.13.15", + "esbuild-linux-ppc64le": "0.13.15", + "esbuild-netbsd-64": "0.13.15", + "esbuild-openbsd-64": "0.13.15", + "esbuild-sunos-64": "0.13.15", + "esbuild-windows-32": "0.13.15", + "esbuild-windows-64": "0.13.15", + "esbuild-windows-arm64": "0.13.15" + } + }, + "esbuild-linux-64": { + "version": "0.13.15", + "integrity": "sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==", + "dev": true, + "optional": true + }, + "escalade": { + "version": "3.1.1", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "estree-walker": { + "version": "2.0.2", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "fraction.js": { + "version": "4.1.2", + "integrity": "sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "globals": { + "version": "11.12.0", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.8", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true, + "optional": true + }, + "has": { + "version": "1.0.3", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-cors": { + "version": "1.1.0", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, + "has-flag": { + "version": "4.0.0", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "image-size": { + "version": "0.5.5", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "dev": true, + "optional": true + }, + "import-fresh": { + "version": "3.3.0", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "indent-string": { + "version": "4.0.0", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inherits": { + "version": "2.0.4", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-core-module": { + "version": "2.8.0", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-what": { + "version": "3.14.1", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, + "jest-diff": { + "version": "27.4.2", + "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-get-type": { + "version": "27.4.0", + "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "jsesc": { + "version": "2.5.2", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json2mq": { + "version": "0.2.0", + "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=", + "requires": { + "string-convert": "^0.2.0" + } + }, + "json5": { + "version": "2.2.0", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "less": { + "version": "4.1.2", + "integrity": "sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA==", + "dev": true, + "requires": { + "copy-anything": "^2.0.1", + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^2.5.2", + "parse-node-version": "^1.0.1", + "source-map": "~0.6.0", + "tslib": "^2.3.0" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "lodash": { + "version": "4.17.21", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "loose-envify": { + "version": "1.4.0", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lower-case": { + "version": "2.0.2", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "lz-string": { + "version": "1.4.4", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "dev": true + }, + "make-dir": { + "version": "2.1.0", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "memoize-one": { + "version": "6.0.0", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "mime": { + "version": "1.6.0", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true + }, + "min-indent": { + "version": "1.0.1", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimist": { + "version": "1.2.5", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "moment": { + "version": "2.29.1", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "ms": { + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nanoid": { + "version": "3.1.30", + "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==", + "dev": true + }, + "needle": { + "version": "2.9.1", + "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "no-case": { + "version": "3.0.4", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-releases": { + "version": "2.0.1", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, + "normalize-range": { + "version": "0.1.2", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "param-case": { + "version": "3.0.4", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "parent-module": { + "version": "1.0.1", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parse-node-version": { + "version": "1.0.1", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true + }, + "parseqs": { + "version": "0.0.6", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "parseuri": { + "version": "0.0.6", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" + }, + "path-parse": { + "version": "1.0.7", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.0", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true + }, + "postcss": { + "version": "8.4.4", + "integrity": "sha512-joU6fBsN6EIer28Lj6GDFoC/5yOZzLCfn0zHAn/MYXI7aPt4m4hK5KC5ovEZXy+lnCjmYIbQWngvju2ddyEr8Q==", + "dev": true, + "requires": { + "nanoid": "^3.1.30", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.1" + } + }, + "postcss-nested": { + "version": "5.0.6", + "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.6" + } + }, + "postcss-selector-parser": { + "version": "6.0.7", + "integrity": "sha512-U+b/Deoi4I/UmE6KOVPpnhS7I7AYdKbhGcat+qTQ27gycvaACvNEw11ba6RrkwVmDVRW7sigWgLj4/KbbJjeDA==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "pretty-format": { + "version": "27.4.2", + "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "react-is": { + "version": "17.0.2", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + } + } + }, + "prop-types": { + "version": "15.7.2", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "prr": { + "version": "1.0.1", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true, + "optional": true + }, + "rc-align": { + "version": "4.0.11", + "integrity": "sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "dom-align": "^1.7.0", + "lodash": "^4.17.21", + "rc-util": "^5.3.0", + "resize-observer-polyfill": "^1.5.1" + } + }, + "rc-cascader": { + "version": "2.2.1", + "integrity": "sha512-4saWcwpmxxh5fhUdaDgOLF2gWL8KNxLwWqELX702HNXEt2yU7AixjfvgEORNsnQZleT2W2AaGMkRDeWrwt8fMw==", + "requires": { + "@babel/runtime": "^7.12.5", + "array-tree-filter": "^2.1.0", + "rc-tree-select": "~4.7.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.0.1", + "warning": "^4.0.1" + } + }, + "rc-checkbox": { + "version": "2.3.2", + "integrity": "sha512-afVi1FYiGv1U0JlpNH/UaEXdh6WUJjcWokj/nUN2TgG80bfG+MDdbfHKlLcNNba94mbjy2/SXJ1HDgrOkXGAjg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1" + } + }, + "rc-collapse": { + "version": "3.1.2", + "integrity": "sha512-HujcKq7mghk/gVKeI6EjzTbb8e19XUZpakrYazu1MblEZ3Hu3WBMSN4A3QmvbF6n1g7x6lUlZvsHZ5shABWYOQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.3.4", + "rc-util": "^5.2.1", + "shallowequal": "^1.1.0" + } + }, + "rc-dialog": { + "version": "8.6.0", + "integrity": "sha512-GSbkfqjqxpZC5/zc+8H332+q5l/DKUhpQr0vdX2uDsxo5K0PhvaMEVjyoJUTkZ3+JstEADQji1PVLVb/2bJeOQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-motion": "^2.3.0", + "rc-util": "^5.6.1" + } + }, + "rc-drawer": { + "version": "4.4.3", + "integrity": "sha512-FYztwRs3uXnFOIf1hLvFxIQP9MiZJA+0w+Os8dfDh/90X7z/HqP/Yg+noLCIeHEbKln1Tqelv8ymCAN24zPcfQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-util": "^5.7.0" + } + }, + "rc-dropdown": { + "version": "3.2.0", + "integrity": "sha512-j1HSw+/QqlhxyTEF6BArVZnTmezw2LnSmRk6I9W7BCqNCKaRwleRmMMs1PHbuaG8dKHVqP6e21RQ7vPBLVnnNw==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-trigger": "^5.0.4" + } + }, + "rc-field-form": { + "version": "1.21.2", + "integrity": "sha512-LR/bURt/Tf5g39mb0wtMtQuWn42d/7kEzpzlC5fNC7yaRVmLTtlPP4sBBlaViETM9uZQKLoaB0Pt9Mubhm9gow==", + "requires": { + "@babel/runtime": "^7.8.4", + "async-validator": "^4.0.2", + "rc-util": "^5.8.0" + } + }, + "rc-image": { + "version": "5.2.5", + "integrity": "sha512-qUfZjYIODxO0c8a8P5GeuclYXZjzW4hV/5hyo27XqSFo1DmTCs2HkVeQObkcIk5kNsJtgsj1KoPThVsSc/PXOw==", + "requires": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-dialog": "~8.6.0", + "rc-util": "^5.0.6" + } + }, + "rc-input-number": { + "version": "7.3.4", + "integrity": "sha512-W9uqSzuvJUnz8H8vsVY4kx+yK51SsAxNTwr8SNH4G3XqQNocLVmKIibKFRjocnYX1RDHMND9FFbgj2h7E7nvGA==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.9.8" + } + }, + "rc-mentions": { + "version": "1.6.1", + "integrity": "sha512-LDzGI8jJVGnkhpTZxZuYBhMz3avcZZqPGejikchh97xPni/g4ht714Flh7DVvuzHQ+BoKHhIjobHnw1rcP8erg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-menu": "^9.0.0", + "rc-textarea": "^0.3.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.0.1" + } + }, + "rc-menu": { + "version": "9.0.14", + "integrity": "sha512-CIox5mZeLDAi32SlHrV7UeSjv7tmJJhwRyxQtZCKt351w3q59XlL4WMFOmtT9gwIfP9h0XoxdBZUMe/xzkp78A==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.4.3", + "rc-overflow": "^1.2.0", + "rc-trigger": "^5.1.2", + "rc-util": "^5.12.0", + "shallowequal": "^1.1.0" + } + }, + "rc-motion": { + "version": "2.4.4", + "integrity": "sha512-ms7n1+/TZQBS0Ydd2Q5P4+wJTSOrhIrwNxLXCZpR7Fa3/oac7Yi803HDALc2hLAKaCTQtw9LmQeB58zcwOsqlQ==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.2.1" + } + }, + "rc-notification": { + "version": "4.5.7", + "integrity": "sha512-zhTGUjBIItbx96SiRu3KVURcLOydLUHZCPpYEn1zvh+re//Tnq/wSxN4FKgp38n4HOgHSVxcLEeSxBMTeBBDdw==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.2.0", + "rc-util": "^5.0.1" + } + }, + "rc-overflow": { + "version": "1.2.2", + "integrity": "sha512-X5kj9LDU1ue5wHkqvCprJWLKC+ZLs3p4He/oxjZ1Q4NKaqKBaYf5OdSzRSgh3WH8kSdrfU8LjvlbWnHgJOEkNQ==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.5.1" + } + }, + "rc-pagination": { + "version": "3.1.14", + "integrity": "sha512-tcugvxrtPiVU00Uh0IwC8NIUlxa4KtA9pXcaMNJdSHeO2uQqVkHEwllsULTAWRF3zRV2ozo2weP/DRKIUrX+Zg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1" + } + }, + "rc-picker": { + "version": "2.5.19", + "integrity": "sha512-u6myoCu/qiQ0vLbNzSzNrzTQhs7mldArCpPHrEI6OUiifs+IPXmbesqSm0zilJjfzrZJLgYeyyOMSznSlh0GKA==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "date-fns": "2.x", + "dayjs": "1.x", + "moment": "^2.24.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.4.0", + "shallowequal": "^1.1.0" + } + }, + "rc-progress": { + "version": "3.1.4", + "integrity": "sha512-XBAif08eunHssGeIdxMXOmRQRULdHaDdIFENQ578CMb4dyewahmmfJRyab+hw4KH4XssEzzYOkAInTLS7JJG+Q==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6" + } + }, + "rc-rate": { + "version": "2.9.1", + "integrity": "sha512-MmIU7FT8W4LYRRHJD1sgG366qKtSaKb67D0/vVvJYR0lrCuRrCiVQ5qhfT5ghVO4wuVIORGpZs7ZKaYu+KMUzA==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.0.1" + } + }, + "rc-resize-observer": { + "version": "1.1.1", + "integrity": "sha512-5A3B9ha297ItltzXl812WFE36SyRDTNclfrXE3FL1pEwXkBh7iSEzxjzfwsPeMcF9ahy3ZoxLgLuRksXBGGD6A==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-util": "^5.15.0", + "resize-observer-polyfill": "^1.5.1" + } + }, + "rc-select": { + "version": "13.1.1", + "integrity": "sha512-Oy4L27x5QgGR8902pw0bJVjrTWFnKPKvdLHzJl5pjiA+jM1hpzDfLGg/bY2ntk5ElxxQKZUwbFKUeqfCQU7SrQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-overflow": "^1.0.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.9.8", + "rc-virtual-list": "^3.2.0" + } + }, + "rc-slider": { + "version": "9.7.4", + "integrity": "sha512-pjLKLiDKiaL7/pNywfIBD+lDo5TtVo05KuIBSWEIoqu6FHh6IMWvthCiaODuYaVs3RLeF2nXOP5AjkD2Lt2Rwg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-tooltip": "^5.0.1", + "rc-util": "^5.0.0", + "shallowequal": "^1.1.0" + } + }, + "rc-steps": { + "version": "4.1.4", + "integrity": "sha512-qoCqKZWSpkh/b03ASGx1WhpKnuZcRWmvuW+ZUu4mvMdfvFzVxblTwUM+9aBd0mlEUFmt6GW8FXhMpHkK3Uzp3w==", + "requires": { + "@babel/runtime": "^7.10.2", + "classnames": "^2.2.3", + "rc-util": "^5.0.1" + } + }, + "rc-switch": { + "version": "3.2.2", + "integrity": "sha512-+gUJClsZZzvAHGy1vZfnwySxj+MjLlGRyXKXScrtCTcmiYNPzxDFOxdQ/3pK1Kt/0POvwJ/6ALOR8gwdXGhs+A==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-util": "^5.0.1" + } + }, + "rc-table": { + "version": "7.19.2", + "integrity": "sha512-NdpnoM50MK02H5/hGOsObfxCvGFUG5cHB9turE5BKJ81T5Ycbq193w5tLhnpILXe//Oanzr47MdMxkUnVGP+qg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.14.0", + "shallowequal": "^1.1.0" + } + }, + "rc-tabs": { + "version": "11.10.4", + "integrity": "sha512-FXihSD9DEF7G/C5iIHNon5jzIO66Two0aeB6uHCmSYibasCsnuBFslHXb9Pa4woqs+vVNjiKRgoDZfurwx1rzg==", + "requires": { + "@babel/runtime": "^7.11.2", + "classnames": "2.x", + "rc-dropdown": "^3.2.0", + "rc-menu": "^9.0.0", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.5.0" + } + }, + "rc-textarea": { + "version": "0.3.5", + "integrity": "sha512-qa+k5vDn9ct65qr+SgD2KwJ9Xz6P84lG2z+TDht/RBr71WnM/K61PqHUAcUyU6YqTJD26IXgjPuuhZR7HMw7eA==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.7.0" + } + }, + "rc-tooltip": { + "version": "5.1.1", + "integrity": "sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==", + "requires": { + "@babel/runtime": "^7.11.2", + "rc-trigger": "^5.0.0" + } + }, + "rc-tree": { + "version": "5.3.0", + "integrity": "sha512-A9GpRalG9sCsC+D3Dw9AB3a2gggf7KUT1FoCGGrbmCH1vsBYfTm3Z4RqEUrWtC7793HRccUTxqnENymkKS99lw==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-util": "^5.0.0", + "rc-virtual-list": "^3.4.1" + } + }, + "rc-tree-select": { + "version": "4.7.0", + "integrity": "sha512-xcc2yPpQieTW6BcRkcKbT1dcAYCQ7ARtkoHlS9EsNdd6xgw9LA6rek6PMed8r/VRMfiKtWV4c4xijW5PI6s4Rw==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-select": "~13.1.0-alpha.0", + "rc-tree": "~5.3.0", + "rc-util": "^5.7.0" + } + }, + "rc-trigger": { + "version": "5.2.10", + "integrity": "sha512-FkUf4H9BOFDaIwu42fvRycXMAvkttph9AlbCZXssZDVzz2L+QZ0ERvfB/4nX3ZFPh1Zd+uVGr1DEDeXxq4J1TA==", + "requires": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-align": "^4.0.0", + "rc-motion": "^2.0.0", + "rc-util": "^5.5.0" + } + }, + "rc-upload": { + "version": "4.3.2", + "integrity": "sha512-v0HdwC/19xKAn1OYZ4hTMUSqSs/IA0n1v4p/cioSSnKubHrdpcCXC45N+TFMSOZtBlf4+xMNCFo3KDih31lAMg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.2.0" + } + }, + "rc-util": { + "version": "5.15.0", + "integrity": "sha512-8RI8sjOCXD3FhD3dzQNBQetpGol6BBd3sHQ/8jSGk9NPT0CH3JGtBfPODnASyE7AdDpCFQMOmgcp9CBs3S/1hg==", + "requires": { + "@babel/runtime": "^7.12.5", + "react-is": "^16.12.0", + "shallowequal": "^1.1.0" + } + }, + "rc-virtual-list": { + "version": "3.4.2", + "integrity": "sha512-OyVrrPvvFcHvV0ssz5EDZ+7Rf5qLat/+mmujjchNw5FfbJWNDwkpQ99EcVE6+FtNRmX9wFa1LGNpZLUTvp/4GQ==", + "requires": { + "classnames": "^2.2.6", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.0.7" + } + }, + "react": { + "version": "17.0.2", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-dom": { + "version": "17.0.2", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + } + }, + "react-is": { + "version": "16.13.1", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-refresh": { + "version": "0.11.0", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "dev": true + }, + "react-ticker": { + "version": "1.3.0", + "integrity": "sha512-aB+Gk17BkZAMMYSel4aJ74EbDfvEbZ6zIFsvylO6FXV5xWj08NzaXc833uBv8TxP0RQ9kKjN6HgSd+VyH6Bu1w==", + "requires": {} + }, + "react-transition-group": { + "version": "4.4.2", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, + "redent": { + "version": "3.0.0", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "regenerator-runtime": { + "version": "0.13.9", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "resize-observer-polyfill": { + "version": "1.5.1", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, + "resolve": { + "version": "1.20.0", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true, + "optional": true + }, + "scheduler": { + "version": "0.20.2", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "scroll-into-view-if-needed": { + "version": "2.2.28", + "integrity": "sha512-8LuxJSuFVc92+0AdNv4QOxRL4Abeo1DgLnGNkn1XlaujPH/3cCFz3QI60r2VNu4obJJROzgnIUw5TKQkZvZI1w==", + "requires": { + "compute-scroll-into-view": "^1.0.17" + } + }, + "semver": { + "version": "5.7.1", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true + }, + "shallowequal": { + "version": "1.1.0", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "socket.io-client": { + "version": "4.4.0", + "integrity": "sha512-g7riSEJXi7qCFImPow98oT8X++MSsHz6MMFRXkWNJ6uEROSHOa3kxdrsYWMq85dO+09CFMkcqlpjvbVXQl4z6g==", + "requires": { + "@socket.io/component-emitter": "~3.0.0", + "backo2": "~1.0.2", + "debug": "~4.3.2", + "engine.io-client": "~6.1.1", + "parseuri": "0.0.6", + "socket.io-parser": "~4.1.1" + } + }, + "socket.io-parser": { + "version": "4.1.1", + "integrity": "sha512-USQVLSkDWE5nbcY760ExdKaJxCE65kcsG/8k5FDGZVVxpD1pA7hABYXYkCUvxUuYYh/+uQw0N/fvBzfT8o07KA==", + "requires": { + "@socket.io/component-emitter": "~3.0.0", + "debug": "~4.3.1" + } + }, + "source-map": { + "version": "0.6.1", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-js": { + "version": "1.0.1", + "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==", + "dev": true + }, + "source-map-resolve": { + "version": "0.6.0", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, + "string-convert": { + "version": "0.2.1", + "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=" + }, + "strip-indent": { + "version": "3.0.0", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "svg-parser": { + "version": "2.0.4", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "toggle-selection": { + "version": "1.0.6", + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" + }, + "tslib": { + "version": "2.3.1", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "vite": { + "version": "2.7.1", + "integrity": "sha512-TDXXhcu5lyQ6uosK4ZWaOyB4VzOiizk0biitRzDzaEtgSUi8rVYPc4k1xgOjLSf0OuceDJmojFKXHOX9DB1WuQ==", + "dev": true, + "requires": { + "esbuild": "^0.13.12", + "fsevents": "~2.3.2", + "postcss": "^8.3.11", + "resolve": "^1.20.0", + "rollup": "^2.59.0" + }, + "dependencies": { + "postcss": { + "version": "8.4.4", + "integrity": "sha512-joU6fBsN6EIer28Lj6GDFoC/5yOZzLCfn0zHAn/MYXI7aPt4m4hK5KC5ovEZXy+lnCjmYIbQWngvju2ddyEr8Q==", + "dev": true, + "requires": { + "nanoid": "^3.1.30", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.1" + } + }, + "rollup": { + "version": "2.61.0", + "integrity": "sha512-teQ+T1mUYbyvGyUavCodiyA9hD4DxwYZJwr/qehZGhs1Z49vsmzelMVYMxGU4ZhGRKxYPupHuz5yzm/wj7VpWA==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + } + } + }, + "vite-plugin-imp": { + "version": "2.0.10", + "integrity": "sha512-fn+g1/K3jedgS+etFHhD9fQzxpX3DI5DXjCw3wkP+dYBzG2sPDGoSiOxxsZS4YRFf5jo94ARqMMam9dbA6mWag==", + "dev": true, + "requires": { + "@babel/core": "^7.12.10", + "@babel/generator": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/traverse": "^7.12.12", + "chalk": "^4.1.0", + "param-case": "^3.0.4" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "vite-plugin-svgr": { + "version": "0.6.0", + "integrity": "sha512-+9eiWLzdlLK3ktnO7gzazMmR/KJyXTy7z6GeRbhv5HKEOFjLdNk3eB0qJaSpzJC3dr2pKWml0jAmxH7O6CcQtg==", + "dev": true, + "requires": { + "@svgr/core": "^6.0.0-alpha.3" + }, + "dependencies": { + "@babel/core": { + "version": "7.16.0", + "integrity": "sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-compilation-targets": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.0", + "@babel/helpers": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + } + }, + "@svgr/babel-plugin-add-jsx-attribute": { + "version": "6.0.0", + "integrity": "sha512-MdPdhdWLtQsjd29Wa4pABdhWbaRMACdM1h31BY+c6FghTZqNGT7pEYdBoaGeKtdTOBC/XNFQaKVj+r/Ei2ryWA==", + "dev": true, + "requires": {} + }, + "@svgr/babel-plugin-remove-jsx-attribute": { + "version": "6.0.0", + "integrity": "sha512-aVdtfx9jlaaxc3unA6l+M9YRnKIZjOhQPthLKqmTXC8UVkBLDRGwPKo+r8n3VZN8B34+yVajzPTZ+ptTSuZZCw==", + "dev": true, + "requires": {} + }, + "@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "6.0.0", + "integrity": "sha512-Ccj42ApsePD451AZJJf1QzTD1B/BOU392URJTeXFxSK709i0KUsGtbwyiqsKu7vsYxpTM0IA5clAKDyf9RCZyA==", + "dev": true, + "requires": {} + }, + "@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "6.0.0", + "integrity": "sha512-88V26WGyt1Sfd1emBYmBJRWMmgarrExpKNVmI9vVozha4kqs6FzQJ/Kp5+EYli1apgX44518/0+t9+NU36lThQ==", + "dev": true, + "requires": {} + }, + "@svgr/babel-plugin-svg-dynamic-title": { + "version": "6.0.0", + "integrity": "sha512-F7YXNLfGze+xv0KMQxrl2vkNbI9kzT9oDK55/kUuymh1ACyXkMV+VZWX1zEhSTfEKh7VkHVZGmVtHg8eTZ6PRg==", + "dev": true, + "requires": {} + }, + "@svgr/babel-plugin-svg-em-dimensions": { + "version": "6.0.0", + "integrity": "sha512-+rghFXxdIqJNLQK08kwPBD3Z22/0b2tEZ9lKiL/yTfuyj1wW8HUXu4bo/XkogATIYuXSghVQOOCwURXzHGKyZA==", + "dev": true, + "requires": {} + }, + "@svgr/babel-plugin-transform-react-native-svg": { + "version": "6.0.0", + "integrity": "sha512-VaphyHZ+xIKv5v0K0HCzyfAaLhPGJXSk2HkpYfXIOKb7DjLBv0soHDxNv6X0vr2titsxE7klb++u7iOf7TSrFQ==", + "dev": true, + "requires": {} + }, + "@svgr/babel-plugin-transform-svg-component": { + "version": "6.1.0", + "integrity": "sha512-1zacrn08K5RyV2NtXahOZ5Im/+aB1Y0LVh6QpzwgQV05sY7H5Npq+OcW/UqXbfB2Ua/WnHsFossFQqigCjarYg==", + "dev": true, + "requires": {} + }, + "@svgr/babel-preset": { + "version": "6.1.0", + "integrity": "sha512-f9XrTqcwhHLVkjvXBw6QJVxuIfmW22z8iTdGqGvUGGxWoeRV2EzSHstWMBgIVd7t+TmkerqowRvBYiT0OEx3cw==", + "dev": true, + "requires": { + "@svgr/babel-plugin-add-jsx-attribute": "^6.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^6.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^6.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^6.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "^6.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "^6.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "^6.0.0", + "@svgr/babel-plugin-transform-svg-component": "^6.1.0" + } + }, + "@svgr/core": { + "version": "6.1.1", + "integrity": "sha512-/NP+24cQmcEdJYptoFWO34SHkNx2x4KOGAMcnTpzOPQifvb1ecupWNEPeHBDY18utd0OMpl2kWf0ZnyN5VsVlg==", + "dev": true, + "requires": { + "@svgr/plugin-jsx": "^6.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.1" + } + }, + "@svgr/hast-util-to-babel-ast": { + "version": "6.0.0", + "integrity": "sha512-S+TxtCdDyRGafH1VG1t/uPZ87aOYOHzWL8kqz4FoSZcIbzWA6rnOmjNViNiDzqmEpzp2PW5o5mZfvC9DiVZhTQ==", + "dev": true, + "requires": { + "@babel/types": "^7.15.6", + "entities": "^3.0.1" + } + }, + "@svgr/plugin-jsx": { + "version": "6.1.0", + "integrity": "sha512-grAeVnwjr4eyzzscX6d5dK202nQcKGt5STry3BrCNuw8RZkMVFYumjH/qLnInO2ugc0ESSo8eCkb+30vXVxSTg==", + "dev": true, + "requires": { + "@babel/core": "^7.15.5", + "@svgr/babel-preset": "^6.1.0", + "@svgr/hast-util-to-babel-ast": "^6.0.0", + "svg-parser": "^2.0.2" + } + }, + "camelcase": { + "version": "6.2.1", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "dev": true + }, + "entities": { + "version": "3.0.1", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "warning": { + "version": "4.0.3", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "yaml": { + "version": "1.10.2", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, + "yeast": { + "version": "0.1.2", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + } + } +} diff --git a/frontend/package.json b/frontend/package.json index 282025b..958df4b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,35 +3,38 @@ "version": "0.1.0", "private": true, "dependencies": { - "@testing-library/jest-dom": "^4.2.4", - "@testing-library/react": "^9.4.0", - "@testing-library/user-event": "^7.2.1", - "@types/jest": "^24.9.1", - "@types/node": "^12.12.27", - "@types/react": "^16.9.19", - "@types/react-dom": "^16.9.5", - "@types/react-transition-group": "^4.2.3", - "antd": "^4.1.4", - "node-sass": "^4.13.1", - "query-string": "^6.12.1", - "react": "^16.12.0", - "react-dom": "^16.12.0", - "react-scripts": "^3.4.0", - "react-transition-group": "^4.3.0", - "socket.io-client": "^2.3.0", - "sscaffold-css": "^0.1.0", - "typescript": "^3.7.5", - "use-query-params": "^0.6.0", - "use-socketio": "^2.0.0" + "antd": "^4.17.2", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-ticker": "^1.3.0", + "react-transition-group": "^4.4.2", + "socket.io-client": "^4.4.0" }, - "scripts": { - "start": "react-app-rewired start", - "build": "react-app-rewired build", - "test": "react-app-rewired test", - "eject": "react-scripts eject" + "devDependencies": { + "@testing-library/jest-dom": "^5.15.1", + "@testing-library/react": "^12.1.2", + "@testing-library/user-event": "^13.5.0", + "@types/jest": "^27.0.3", + "@types/react": "^17.0.37", + "@types/react-dom": "^17.0.11", + "@types/react-transition-group": "^4.4.4", + "@types/socket.io-client": "^1.4.36", + "@vitejs/plugin-react": "^1.1.1", + "autoprefixer": "^10.4.0", + "less": "^4.1.2", + "postcss": "^8.4.4", + "postcss-nested": "^5.0.6", + "vite": "^2.7.1", + "vite-plugin-imp": "^2.0.10", + "vite-plugin-svgr": "^0.6.0" }, - "eslintConfig": { - "extends": "react-app" + "scripts": { + "start": "vite", + "build": "tsc && vite build", + "serve": "vite preview", + "check": "tsc --noEmit", + "lint": "eslint 'src/**/*.{ts,tsx}'", + "fix": "eslint --fix 'src/**/*.{ts,tsx}'" }, "browserslist": { "production": [ @@ -44,12 +47,5 @@ "last 1 firefox version", "last 1 safari version" ] - }, - "devDependencies": { - "@types/socket.io-client": "^1.4.32", - "customize-cra": "^0.9.1", - "eslint-plugin-react-hooks": "^2.3.0", - "react-app-rewired": "^2.1.5", - "workerize-loader": "^1.1.0" } } diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js new file mode 100644 index 0000000..0360ded --- /dev/null +++ b/frontend/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: [ + require('autoprefixer'), + require('postcss-nested'), + ] +} diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico index bcd5dfd..31e6fa2 100644 Binary files a/frontend/public/favicon.ico and b/frontend/public/favicon.ico differ diff --git a/frontend/public/index.html b/frontend/public/index.html deleted file mode 100644 index 463c98f..0000000 --- a/frontend/public/index.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - Centurion - - - -
- - - diff --git a/frontend/public/logo192.png b/frontend/public/logo192.png index fc44b0a..c94bd0f 100644 Binary files a/frontend/public/logo192.png and b/frontend/public/logo192.png differ diff --git a/frontend/public/logo512.png b/frontend/public/logo512.png index a4e47a6..9f8992a 100644 Binary files a/frontend/public/logo512.png and b/frontend/public/logo512.png differ diff --git a/frontend/public/manifest.json b/frontend/public/manifest.json index e17adca..ba14d11 100644 --- a/frontend/public/manifest.json +++ b/frontend/public/manifest.json @@ -1,9 +1,9 @@ { - "short_name": "React App", - "name": "Create React App Sample", + "short_name": "Centurion", + "name": "Centurion: honderd minuten...", "icons": [ { - "src": "harambee.ico", + "src": "favicon.ico", "sizes": "64x64 32x32 24x24 16x16", "type": "image/x-icon" }, @@ -20,6 +20,6 @@ ], "start_url": ".", "display": "standalone", - "theme_color": "#000000", + "theme_color": "#304ba3", "background_color": "#ffffff" } diff --git a/frontend/public/robots.txt b/frontend/public/robots.txt index 01b0f9a..2d1aa03 100644 --- a/frontend/public/robots.txt +++ b/frontend/public/robots.txt @@ -1,2 +1,3 @@ # https://www.robotstxt.org/robotstxt.html User-agent: * +Disallow: / \ No newline at end of file diff --git a/frontend/src/components/App.tsx b/frontend/src/components/App.tsx deleted file mode 100644 index e15f5b5..0000000 --- a/frontend/src/components/App.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; - -import Centurion from "./Centurion"; - -const App = () => { - return ( - - ); -}; - -export default App; diff --git a/frontend/src/components/Centurion.tsx b/frontend/src/components/Centurion.tsx index 29b6d7a..f79486a 100644 --- a/frontend/src/components/Centurion.tsx +++ b/frontend/src/components/Centurion.tsx @@ -1,46 +1,26 @@ -import React from "react"; -import {Row} from "antd"; +import React, { useState } from "react"; -import {useRoomRunningAndReadyChanged} from "../lib/Connection"; -import NextShot from "./NextShot"; +import { useRoomRunningAndReadyChanged } from "../lib/Connection"; import Feed from "./Feed"; -import ShotsTaken from "./ShotsTaken"; import Lobby from "./Lobby"; -import logo from "../img/via-logo.svg"; -import haramlogo from "../img/harambee_logo.png"; -import Player from "./Player"; - const Centurion = () => { - const room = useRoomRunningAndReadyChanged(); - const showFeed = (room?.running && room.readyToParticipate) || false; - - const feedContent = ( - - - - - - - - - ); - - const lobbyContent = ( - - ); + const [currentUserReady, setCurrentUserReady] = useState(false); + const room = useRoomRunningAndReadyChanged(); + const showFeed = (room?.readyToParticipate && currentUserReady) || false; - return ( - <> -
- {showFeed ? feedContent : lobbyContent} -
-
- haramlogo - logo -
- - ); + return ( +
+ {showFeed ? ( + + ) : ( + setCurrentUserReady(b)} + /> + )} +
+ ); }; -export default Centurion; \ No newline at end of file +export default Centurion; diff --git a/frontend/src/components/Feed.tsx b/frontend/src/components/Feed.tsx index 76c60e3..b55cafe 100644 --- a/frontend/src/components/Feed.tsx +++ b/frontend/src/components/Feed.tsx @@ -1,40 +1,220 @@ -import React from 'react'; -import {Col} from "antd" +import React, { useRef, useState } from "react"; +import { Col, Row } from "antd"; -import {TimelineItem} from "../types/types"; +import { + EVENT_PRIORITY, + Timeline, + TimelineItem, + TimestampEvent, +} from "../types/types"; -import FeedItem from "./FeedItem" -import {roomTime, useTimeline} from "../lib/Connection"; -import {useUpdateAfterDelay} from "../util/hooks"; +import FeedItem from "./FeedItem"; +import connection, { + calculateRoomTime, + useRoomRunningAndReadyChanged, + useRoomTime, + useTimeline, +} from "../lib/Connection"; +import { useResize, useUpdateAfterDelay } from "../util/hooks"; import CSSTransition from "react-transition-group/CSSTransition"; import TransitionGroup from "react-transition-group/TransitionGroup"; +import NextShot from "./NextShot"; +import ShotsTaken from "./ShotsTaken"; +import Player from "./Player"; -const Feed = (props: any) => { - const timeline = useTimeline(); +import "../css/feed.css"; +import FeedTicker from "./FeedTicker"; - useUpdateAfterDelay(500) +declare global { + interface Window { + __feedShakeDebug?: boolean; + } +} - let liveFeed: TimelineItem[] = []; +function getNextItemDelay(timeline: Timeline | null, defaultDelay = 500) { + if (!timeline) { + return defaultDelay; + } - if (timeline != null) { - liveFeed = timeline.feed.filter(item => { - return item.timestamp * 1000 <= roomTime() - }); + const time = calculateRoomTime(); + const nextItem = timeline.itemAfterTime(time); + + if (!nextItem) { + return defaultDelay; + } + + const speedFactor = connection.room.get()?.speedFactor || 1; + return (nextItem.timestamp * 1000 - time) / speedFactor; +} + +/** + * This map relates back an event to the index of the item displayed from + * top to bottom. We can use this to calculate opacity. + */ +function calculateKeyToIndexMap(feed: TimelineItem[]) { + const keyToIndex: Map = new Map(); + + let totalEvents = 0; + for (const item of feed) { + totalEvents += item.events.length; + } + + let totalIdx = 0; + for (const item of feed) { + for (let eventIdx = 0; eventIdx < item.events.length; eventIdx++) { + keyToIndex.set(`${item.timestamp}.${eventIdx}`, totalEvents - ++totalIdx); } + } + + return keyToIndex; +} + +/** + * Makes sure 'shot' is always top-most within an timeline item + */ +function sortEvents(events: TimestampEvent[]) { + return events.sort((a, b) => { + return EVENT_PRIORITY.indexOf(b.type) - EVENT_PRIORITY.indexOf(a.type); + }); +} + +const Feed = () => { + const timeline = useTimeline(); + useRoomRunningAndReadyChanged(); + useResize(); + useRoomTime(); - return ( - - - {liveFeed.map((item, i) => - item.events.map((event, j) => - - - - ) - )} - + const feedElement = useRef(null); + const [lastShotId, setLastShotId] = useState(null); + + useUpdateAfterDelay(getNextItemDelay(timeline)); + + if (!timeline) { + throw new TypeError("Feed without timeline."); + } + + const time = calculateRoomTime(); + + const liveFeed = timeline.feed.filter((item) => { + return item.timestamp * 1000 <= time; + }); + + const keyToIndex: Map = calculateKeyToIndexMap(liveFeed); + + const lastEvent = timeline.eventBeforeTime(time, "shot"); + if (lastEvent && lastShotId !== lastEvent?.id) { + setLastShotId(lastEvent.id); + + if (feedElement.current) { + // Let the browser first do the heavy dom stuff to avoid lagging our + // animation. + setTimeout(doSingleShake, 100); + } + } + + function doSingleShake() { + if (!feedElement.current) return; + + if (feedElement.current.getAnimations().length > 0) return; + + if (feedElement.current.classList.contains("feed-shot-shake")) { + feedElement.current.getAnimations().forEach((i) => i.finish()); + feedElement.current.classList.remove("feed-shot-shake"); + setTimeout(doSingleShake, 0); + return; + } + + feedElement.current.classList.add("feed-shot-shake"); + const el = feedElement.current; + const listener = function () { + el.classList.remove("feed-shot-shake"); + el.removeEventListener("animationend", listener); + }; + el.addEventListener("animationend", listener); + } + + function itemOpacity(itemKey: string) { + // This is a bit of a hack but works better than trying to do this in css. + // This fades out the elements the lower the element is on the screen. + + // Ticker is only visible on large screens, the ticker obstructs some of + // the items. If it is not visible we simply take body height, otherwise + // we use the height where the ticker starts. + const tickerHeight = document + .querySelector(".ticker-container") + ?.getBoundingClientRect().y; + const bodyHeight = document.body.clientHeight; + const totalHeight = tickerHeight ? tickerHeight : bodyHeight; + + // Start at top most item, figure out which index is the first + // that is NOT visible. + const items = document.querySelectorAll(".feed-item-container"); + let i = items.length - 1; + for (; i > 0; i--) { + const rect = items[i].getBoundingClientRect(); + // If the bottom of this element is below the screen, we declare it + // not-visible. + if (rect.y + rect.height >= totalHeight) { + break; + } + } + const totalItemsOnScreen = items.length - i; + const index = keyToIndex.get(itemKey) ?? 0; + + let x = index / (totalItemsOnScreen - 1.8); + x = Math.min(0.9, Math.max(0, x)); + return 1 - Math.pow(x, 4); + } + + const debug = true; + if (debug) { + if (!window["__feedShakeDebug"]) { + window["__feedShakeDebug"] = true; + window.document.documentElement.addEventListener("keydown", (e) => { + if (e.keyCode === 67) { + // c + doSingleShake(); + } + }); + } + } + + return ( +
+ + + + + + + + + + + {liveFeed.map((item) => + sortEvents(item.events).map((event, j) => ( + +
+ +
+
+ )) + )} +
- ); +
+ + + +
+ ); }; export default Feed; diff --git a/frontend/src/components/FeedItem.tsx b/frontend/src/components/FeedItem.tsx index bbbc881..ccc0b7c 100644 --- a/frontend/src/components/FeedItem.tsx +++ b/frontend/src/components/FeedItem.tsx @@ -1,33 +1,38 @@ -import React, {PureComponent} from 'react'; +import { Col, Row } from "antd"; -import {TimestampEvent} from "../types/types"; +import type { TimestampEvent } from "../types/types"; -import '../css/feed.sass' +import "../css/feed.css"; import shot from "../img/shot.png"; import song from "../img/song.png"; import talk from "../img/talk.png"; import time from "../img/time.png"; +export interface FeedItemProps { + item: TimestampEvent; +} + const images = { - shot, song, talk, time + shot, + song, + talk, + time, }; -class FeedItem extends PureComponent<{item: TimestampEvent}> { - render() { - return ( -
-
- {this.props.item.text[0]} -
-
- -
-
- {this.props.item.text[1]} -
-
- ); - } -} +const FeedItem = ({ item }: FeedItemProps) => { + return ( + + + {item.text[0]} + + + {item.type} + + + {item.text[1]} + + + ); +}; export default FeedItem; diff --git a/frontend/src/components/FeedTicker.tsx b/frontend/src/components/FeedTicker.tsx new file mode 100644 index 0000000..2cf5d2b --- /dev/null +++ b/frontend/src/components/FeedTicker.tsx @@ -0,0 +1,95 @@ +import React, { MouseEvent, useRef, useState } from "react"; + +import "../css/feed.css"; +import connection, { useRoom } from "../lib/Connection"; +import { Button, Input, Modal } from "antd"; +import Ticker from "react-ticker"; + +const FeedTicker = (props: any) => { + const room = useRoom(); + + const [showTickerMessageModal, setShowTickerMessageModal] = useState(false); + const [tickerMessage, setTickerMessage] = useState(""); + const [blockMessageInput, setBlockMessageInput] = useState(false); + const messageInput = useRef(null); + function handleTickerMessageButton(e: MouseEvent) { + if (blockMessageInput) return; + setShowTickerMessageModal(true); + + setTimeout(function () { + messageInput.current?.focus(); + }, 100); + } + + function cancelTickerMessageModal() { + if (blockMessageInput) return; + setShowTickerMessageModal(false); + setTickerMessage(""); + } + + async function okTickerMessageModal() { + if (blockMessageInput) return; + if (tickerMessage) { + setBlockMessageInput(true); + + try { + await connection.submitTickerMessage(tickerMessage); + setBlockMessageInput(false); + setShowTickerMessageModal(false); + setTickerMessage(""); + if (messageInput.current) { + messageInput.current.input.value = ""; + } + } catch { + setBlockMessageInput(false); + } + } + } + + function getForIndex(index: number) { + return room?.ticker[index % room.ticker.length]; + } + + return ( +
+ + setTickerMessage(e.target.value)} + onKeyPress={(e) => { + e.key === "Enter" && okTickerMessageModal(); + }} + /> + + +
+ + {({ index }) => ( + <> + {room?.ticker && ( + {getForIndex(index)} + )} + + )} + + + +
+
+ ); +}; + +export default FeedTicker; diff --git a/frontend/src/components/Lobby.tsx b/frontend/src/components/Lobby.tsx index 5cbff5e..36bf2a5 100644 --- a/frontend/src/components/Lobby.tsx +++ b/frontend/src/components/Lobby.tsx @@ -1,219 +1,313 @@ -import React, {MouseEvent, useState} from 'react'; -import {Button, Card, Col, Divider, Form, Input, InputNumber, Row, Select} from "antd" -import {red} from '@ant-design/colors'; - -import connection, {useConfig, useIsConnected, useRoom} from "../lib/Connection"; - -import "../css/lobby.sass"; -import beer from "../img/beer.png" -import {RoomOptions} from "../types/types"; - -const {Option} = Select; - -const Lobby = (props: any) => { - // Form/control states. - const [selectedRoomId, setSelectedRoomId] = useState(1); - const [seekTime, setSeekTime] = useState(0); - const [timelineName, setTimelineName] = useState(null); - const [joiningLobby, setJoiningLobby] = useState(false); - const [joinLobbyError, setJoinLobbyError] = useState(false); - - // Room and logic states. - const isConnected = useIsConnected(); - const room = useRoom(); - const config = useConfig(); - - // @ts-ignore - const connectionType = connection.socket.io.engine.transport.name; - - let isLeader = room?.isLeader || false; - let userCount = room?.userCount || 0; - - function handleRequestStartClicked(e: MouseEvent) { - connection.requestStart(seekTime * 1000); - } - - function handleJoin(e: MouseEvent) { - connection.requestReady(); - } - - function applyRoomId(v: number) { - connection.requestJoin(v).then(v => { - setJoiningLobby(false); - setJoinLobbyError(!v); - }) - setJoiningLobby(true) - } +import { useState } from "react"; +import { + Button, + Card, + Col, + Divider, + Form, + Input, + InputNumber, + Row, + Select, + Badge, +} from "antd"; +import { red } from "@ant-design/colors"; + +import connection, { + useConfig, + useIsConnected, + useRoom, + useTimelineSongFileChanged, +} from "../lib/Connection"; + +import "../css/lobby.css"; +import logo from "../img/via-logo.svg"; +import haramlogo from "../img/harambee_logo.png"; +import beer from "../img/beer.png"; +import { RoomOptions } from "../types/types"; + +const { Option } = Select; + +export interface PropType { + currentUserReady: boolean; + onCurrentUserReadyChange?: (ready: boolean) => void; +} + +const Lobby = (props: PropType) => { + // Form/control states. + const [selectedRoomId, setSelectedRoomId] = useState(1); + const [seekTime, setSeekTime] = useState(0); + const [timelineName, setTimelineName] = useState(null); + const [joiningLobby, setJoiningLobby] = useState(false); + const [joinLobbyError, setJoinLobbyError] = useState(false); + const [isPreloading, setIsPreloading] = useState(false); + const timeline = useTimelineSongFileChanged(); + + // Room and logic states. + const isConnected = useIsConnected(); + const room = useRoom(); + const config = useConfig(); + + const isLeader = room?.isLeader || false; + const userCount = room?.userCount || 0; + + async function handleJoin() { + await preloadAudio(); + connection.requestSetReady(); + props.onCurrentUserReadyChange?.(true); + } + + async function applyRoomId(v: number) { + setJoiningLobby(true); + await connection.requestJoin(v); + setJoiningLobby(false); + setJoinLobbyError(!v); + } + + function handleJoinRandomLobby() { + connection.requestJoinRandom(); + setJoinLobbyError(false); + } + + function handleTimelineNameSet(timelineName: any) { + setTimelineName(timelineName); + connection.setRoomOptions( + new RoomOptions( + seekTime * 1000 || 0, + timelineName || room?.timelineName || "" + ) + ); + } + + function handleSetSeekTime(seekTime: number) { + setSeekTime(seekTime); + connection.setRoomOptions( + new RoomOptions( + seekTime * 1000 || 0, + timelineName || room?.timelineName || "" + ) + ); + } - function handleJoinRandomLobby() { - connection.requestJoinRandom() - setJoinLobbyError(false); - } + function preloadAudio(): Promise { + setIsPreloading(true); + const songFile = timeline?.songFile; - function handleTimelineNameSet(timelineName: any) { - setTimelineName(timelineName); - connection.setRoomOptions(new RoomOptions( - seekTime || 0, - timelineName || room?.timelineName || '')) + if (!songFile) { + return Promise.resolve(false); } - function handleSetSeekTime(seekTime: number) { - setSeekTime(seekTime); - connection.setRoomOptions(new RoomOptions( - seekTime * 1000 || 0, - timelineName || room?.timelineName || '')) - } - - let leaderConfig = ( + return new Promise((resolve) => { + const audioElement = new Audio(); + audioElement.addEventListener("canplaythrough", () => { + // 'canplaythrough' means the browser thinks it has buffered enough to play + // until the end. + setIsPreloading(false); + resolve(true); + }); + audioElement.src = songFile; + }); + } + + const leaderConfig = ( + + +
+ + handleSetSeekTime(parseInt(v.target.value) || 0)} + /> + + + + + +
+ + + +
+ ); + + const nonLeaderConfig = ( + + +

+ {room?.running ? "We luisteren naar" : "We gaan luisteren naar"}{" "} + {room && room.timelineName} en + {room?.running && zijn al gestart!} + {!room?.running && ( + starten op {(room?.seekTime || 0) / 1000} seconden + )} +

+ + + +
+ ); + + return ( +
+ + + beer + + + Centurion! + + + beer + + + + +
Honderd minuten...
+
Honderd shots...
+
Kun jij het aan?
+ +
+
+ + {!isConnected && ( - -
- - handleSetSeekTime(parseInt(v.target.value) || 0)}/> - - - - - - -
- - - + +

Verbinden...

+
- ) + )} - let nonLeaderConfig = ( + {isConnected && ( - -

- We gaan luisteren naar {room && room.timelineName} en - {room?.running && zijn al gestart!} - {!room?.running && starten op {(room?.seekTime || 0) / 1000} seconden} -

- - - -
- ) - - // @ts-ignore - return ( -
- - -
- beer -
- Centurion! - beer + loading={joiningLobby} + onClick={async () => { + await applyRoomId(selectedRoomId); + }} + > + Ga naar die lobby + + + {joinLobbyError && ( + + Die lobby bestaat niet + + )} -
- - -
Honderd minuten...
-
Honderd shots...
-
Kun jij het aan?
- -
-
+ - {!isConnected && - - -

Verbinden...

- -
- } - - {isConnected && - - - -

Huidige lobby: {room?.id || 'Geen lobby'}

- - {/*Verbonden met {connectionType}*/} - - {room && - - {userCount === 1 ? -

Er is één gebruiker aanwezig.

- : -

Er zijn {userCount} gebruikers aanwezig.

- } -
- } - {room && - Deel de link met je vrienden om mee te doen! - } -
-
- - {room && (isLeader ? leaderConfig : nonLeaderConfig)} - - - - - - setSelectedRoomId(v || 0)}/> - - - - {joinLobbyError && - Die lobby bestaat niet - } - - - - - of - - - - - - - -
+ + of + + + + + - - } -
- ); + + + + + )} + haramlogo + logo +
+ ); }; export default Lobby; diff --git a/frontend/src/components/NextShot.tsx b/frontend/src/components/NextShot.tsx index 0a13ec3..afbc7a9 100644 --- a/frontend/src/components/NextShot.tsx +++ b/frontend/src/components/NextShot.tsx @@ -1,42 +1,48 @@ -import React from 'react'; -import {Col, Progress} from "antd" -import {roomTime, useTimeline} from "../lib/Connection"; -import {useUpdateAfterDelay} from "../util/hooks"; - +import { Progress } from "antd"; +import { calculateRoomTime, useTimeline } from "../lib/Connection"; +import { useUpdateAfterDelay } from "../util/hooks"; const NextShot = () => { - const timeline = useTimeline() - - useUpdateAfterDelay(1000) - - let remainingTime = 0; - let remainingPercentage = 0; - - if (timeline) { - const time = roomTime(); - const [current, next] = timeline.itemAtTime(time, 'shot'); - - if (current && next) { - let currentTime = time - current.timestamp * 1000 - let nextTime = next.timestamp * 1000 - current.timestamp * 1000; - - remainingTime = Math.round((nextTime - currentTime) / 1000) - remainingPercentage = 100 - (currentTime / (nextTime || 1)) * 100; - } - } - - return ( - -

Tijd tot volgende shot:

- remainingTime + ' sec.'} - strokeColor={"#304ba3"} - strokeWidth={10} - status="normal"/> - - - ); + const timeline = useTimeline(); + + useUpdateAfterDelay(1000); + + if (!timeline) { + throw new TypeError("NextShot without timeline"); + } + + let remainingTime = 0; + let remainingPercentage = 0; + + const currentRoomTime = calculateRoomTime(); + + const nextItem = timeline.itemAfterTime(currentRoomTime, "shot"); + + if (nextItem) { + const prevShotRoomTime = + (timeline.itemBeforeTime(currentRoomTime, "shot")?.timestamp || 0) * 1000; + const nextShotRoomTime = nextItem?.timestamp * 1000; + const totalRoomTimeBetweenShots = nextShotRoomTime - prevShotRoomTime; + const roomTimeSinceLastShot = currentRoomTime - prevShotRoomTime; + + remainingTime = Math.round((nextShotRoomTime - currentRoomTime) / 1000); + remainingPercentage = + 100 - (roomTimeSinceLastShot / totalRoomTimeBetweenShots) * 100; + } + + return ( + <> +

Tijd tot volgende shot:

+ `${remainingTime} sec.`} + strokeColor={"#304ba3"} + strokeWidth={10} + status="normal" + /> + + ); }; export default NextShot; diff --git a/frontend/src/components/Player.tsx b/frontend/src/components/Player.tsx index 60c395a..c36f2bc 100644 --- a/frontend/src/components/Player.tsx +++ b/frontend/src/components/Player.tsx @@ -1,106 +1,211 @@ -import {roomTime, useRoomRunningAndReadyChanged, useRoomTime, useTimelineSongFileChanged} from "../lib/Connection"; -import React, {createRef, SyntheticEvent, useRef, useState} from "react"; +import connection, { + calculateRoomTime, + useRoomRunningAndReadyChanged, + useTimelineSongFileChanged, +} from "../lib/Connection"; +import { SyntheticEvent, useEffect, useRef, useState } from "react"; -import '../css/player.sass' -import {Room} from "../types/types"; -import {parse as parseQueryString} from "query-string"; +import { Button, Slider } from "antd"; +import { SoundFilled, SoundOutlined } from "@ant-design/icons"; + +import "../css/player.css"; +import { Room } from "../types/types"; const Player = () => { - const room = useRoomRunningAndReadyChanged(); - const _ = useRoomTime() - const timeline = useTimelineSongFileChanged(); + const room = useRoomRunningAndReadyChanged(); + const timeline = useTimelineSongFileChanged(); + + const player = useRef(null); + const defaultVolume = parseInt(localStorage.getItem("volume") ?? "100"); + + const [volume, setVolume] = useState(defaultVolume); + const [muted, setMuted] = useState(false); + const [finishedLoading, setFinishedLoading] = useState(false); + + const [timesSeeked, setTimesSeeked] = useState(0); + const [hadError, setHadError] = useState(false); + + // If our time synchronisation algorithm thing thinks the time is off by more + // than this value, we seek the running player to correct it. + const diffSecondsRequiredToSeekRunningPlayer = 0.2; + + // Hard cap we are allowed to seek this player. Some browsers are slow or inaccurate + // and will always be off. To avoid endless skipping of the song this cap stops seeking the + // player. + const maxTimesSeekAllow = 25; + + useEffect(() => { + // Need to use an effect since 'player' will only contain a reference after first render. + + if (!timeline) { + throw new Error("Player without active timeline."); + } + + if (!player.current) { + throw new Error("No player after mount."); + } - let player = useRef(null) + player.current.src = timeline.songFile; + }, [timeline]); - const [timesSeeked, setTimesSeeked] = useState(0); - const [hadError, setHadError] = useState(false); + function handlePlayerOnPlay(e: SyntheticEvent) { + e.preventDefault(); + // For when the user manually started the player for when autoplay is off. + setHadError(false); + } - // If our time synchronisation algorithm thing thinks the time is off by more - // than this value, we seek the running player to correct it. - const diffSecondsRequiredToSeekRunningPlayer = 0.20; + async function handlePlayerPause(e: SyntheticEvent) { + if (!shouldPlay()) { + // We should not be playing, pausing is fine. + console.log("should not play, paused"); + return; + } - // Hard cap we are allowed to seek this player. Some browsers are slow or inaccurate - // and will always be off. To avoid endless skipping of the song this cap stops seeking the - // player. - const maxTimesSeekAllow = 25; + e.preventDefault(); - const query = parseQueryString(window.location.search); - if (query.nosound) { - return null; + if (room) { + setPlayerTime(room, true); } + await player.current?.play(); + } - if (player.current && player.current.dataset.src != timeline!!.songFile) { - player.current.dataset.src = timeline!!.songFile; - player.current.src = timeline!!.songFile; + function handlePlayerCanPlayThrough() { + if (!finishedLoading) { + setFinishedLoading(true); + connection.requestStart(); + } + } + + function shouldPlay() { + return ( + player.current && + timeline && + room && + room.running && + room.readyToParticipate && + !player.current.ended + ); + } + + async function startPlaying(manual: boolean) { + if (!player.current) { + return; } - function handlePlayerOnPlay(e: SyntheticEvent) { - e.preventDefault(); + if (player.current.paused && !hadError) { + setPlayerVolume(volume); - // For when the user manually started the player for when autoplay is off. + try { + await player.current.play(); setHadError(false); - if (shouldPlay()) { - startPlaying(true) - } + } catch (e) { + console.error("Error playing", e); + setHadError(true); + } } - function shouldPlay() { - return player.current && timeline && room && room.running && room.readyToParticipate + if (!hadError && room) { + setPlayerTime(room, manual); } + } - function startPlaying(manual: boolean) { - if (!player.current) return; - - if (player.current.paused && !hadError) { - player.current.play().then(() => { - setHadError(false); - }).catch(e => { - console.error('Error playing', e); - setHadError(true); - }) - } - - if (!hadError) { - setPlayerTime(room!!, manual); - } + function setPlayerTime(room: Room, manualAdjustment: boolean) { + if (!player.current) { + return; } - function setPlayerTime(room: Room, manualAdjustment: boolean) { - if (!player.current) return; - - let targetTime = roomTime() / 1000; - let diff = player.current.currentTime - targetTime; - - if (player.current && Math.abs(diff) > diffSecondsRequiredToSeekRunningPlayer) { - if (room.speedFactor != 1 || manualAdjustment || timesSeeked < maxTimesSeekAllow) { - player.current.currentTime = targetTime; - player.current.playbackRate = Math.max(Math.min(4.0, room.speedFactor), 0.25); - - if (!manualAdjustment) { - setTimesSeeked(timesSeeked + 1); - } - } else { - console.warn('The running player is off, but we\'ve changed the time ' + - 'too often, skipping synchronizing the player.'); - } - } + // Player's currentTime is in seconds, not ms. + const targetTime = calculateRoomTime() / 1000; + const diff = Math.abs(player.current.currentTime - targetTime); + + // console.log('PLAYER DIFF', diff, + // 'min req to seek: ', diffSecondsRequiredToSeekRunningPlayer, + // `(${timesSeeked} / ${maxTimesSeekAllow})`); + + if (diff <= diffSecondsRequiredToSeekRunningPlayer) { + return; } - if (shouldPlay()) { - startPlaying(false) - } else { - if (player.current) { - player.current.pause(); - } + if (timesSeeked >= maxTimesSeekAllow && !manualAdjustment) { + // If we are adjusting manually we always allow a seek. + console.warn( + "The running player is off, but we've changed the time " + + "too often, skipping synchronizing the player." + ); + return; } - function render() { - return ( -