This commit is contained in:
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
.env
|
20
.gitea/workflows/deploy.yml
Normal file
20
.gitea/workflows/deploy.yml
Normal file
@ -0,0 +1,20 @@
|
||||
name: Deploy bot
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
env:
|
||||
TOKEN: ${{ secrets.TOKEN }}
|
||||
PREFIX: ${{ secrets.PREFIX }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Deploy with Docker Compose
|
||||
run: |
|
||||
docker compose down
|
||||
docker compose up -d --build
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
config.json
|
||||
node_modules/
|
3
api/.dockerignore
Normal file
3
api/.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
.env
|
16
api/Dockerfile
Normal file
16
api/Dockerfile
Normal file
@ -0,0 +1,16 @@
|
||||
ARG NODE_VERSION=23.0.0
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Install dependencies
|
||||
COPY package*.json ./
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY --chown=node:node . .
|
||||
|
||||
USER node
|
||||
|
||||
CMD ["node", "index.js"]
|
9
api/index.js
Normal file
9
api/index.js
Normal file
@ -0,0 +1,9 @@
|
||||
import express from "express";
|
||||
import { router } from "express-file-routing";
|
||||
const PORT = process.env.PORT || 2000;
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use("/", await router());
|
||||
|
||||
app.listen(PORT, () => console.log("API listening on port " + PORT + "."));
|
835
api/package-lock.json
generated
Normal file
835
api/package-lock.json
generated
Normal file
@ -0,0 +1,835 @@
|
||||
{
|
||||
"name": "api",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "api",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"express": "^5.1.0",
|
||||
"express-file-routing": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
||||
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-types": "^3.0.0",
|
||||
"negotiator": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
|
||||
"integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bytes": "^3.1.2",
|
||||
"content-type": "^1.0.5",
|
||||
"debug": "^4.4.0",
|
||||
"http-errors": "^2.0.0",
|
||||
"iconv-lite": "^0.6.3",
|
||||
"on-finished": "^2.4.1",
|
||||
"qs": "^6.14.0",
|
||||
"raw-body": "^3.0.0",
|
||||
"type-is": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bound": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
||||
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"get-intrinsic": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/content-disposition": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
|
||||
"integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "5.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/content-type": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
||||
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-signature": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
|
||||
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
||||
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/encodeurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
|
||||
"integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"accepts": "^2.0.0",
|
||||
"body-parser": "^2.2.0",
|
||||
"content-disposition": "^1.0.0",
|
||||
"content-type": "^1.0.5",
|
||||
"cookie": "^0.7.1",
|
||||
"cookie-signature": "^1.2.1",
|
||||
"debug": "^4.4.0",
|
||||
"encodeurl": "^2.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"etag": "^1.8.1",
|
||||
"finalhandler": "^2.1.0",
|
||||
"fresh": "^2.0.0",
|
||||
"http-errors": "^2.0.0",
|
||||
"merge-descriptors": "^2.0.0",
|
||||
"mime-types": "^3.0.0",
|
||||
"on-finished": "^2.4.1",
|
||||
"once": "^1.4.0",
|
||||
"parseurl": "^1.3.3",
|
||||
"proxy-addr": "^2.0.7",
|
||||
"qs": "^6.14.0",
|
||||
"range-parser": "^1.2.1",
|
||||
"router": "^2.2.0",
|
||||
"send": "^1.1.0",
|
||||
"serve-static": "^2.2.0",
|
||||
"statuses": "^2.0.1",
|
||||
"type-is": "^2.0.1",
|
||||
"vary": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/express-file-routing": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/express-file-routing/-/express-file-routing-3.1.0.tgz",
|
||||
"integrity": "sha512-FXZM6akwXKcNK+ZFdubcElyWSOPOTDKmkjBaetB6LMLKRjnRI2oKLi/tXd6sJCE7pmDh5zqaBNS8QYQfpvmwIQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"express": ">4.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
|
||||
"integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.4.0",
|
||||
"encodeurl": "^2.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"on-finished": "^2.4.1",
|
||||
"parseurl": "^1.3.3",
|
||||
"statuses": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/fresh": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
|
||||
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"depd": "2.0.0",
|
||||
"inherits": "2.0.4",
|
||||
"setprototypeof": "1.2.0",
|
||||
"statuses": "2.0.1",
|
||||
"toidentifier": "1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/http-errors/node_modules/statuses": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/is-promise": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
||||
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/media-typer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
|
||||
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/merge-descriptors": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
|
||||
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.54.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
|
||||
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
|
||||
"integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "^1.54.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
|
||||
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.13.4",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/on-finished": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ee-first": "1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
|
||||
"integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"forwarded": "0.2.0",
|
||||
"ipaddr.js": "1.9.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
|
||||
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-body": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
|
||||
"integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.6.3",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/router": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
|
||||
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.4.0",
|
||||
"depd": "^2.0.0",
|
||||
"is-promise": "^4.0.0",
|
||||
"parseurl": "^1.3.3",
|
||||
"path-to-regexp": "^8.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/send": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
|
||||
"integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.5",
|
||||
"encodeurl": "^2.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"etag": "^1.8.1",
|
||||
"fresh": "^2.0.0",
|
||||
"http-errors": "^2.0.0",
|
||||
"mime-types": "^3.0.1",
|
||||
"ms": "^2.1.3",
|
||||
"on-finished": "^2.4.1",
|
||||
"range-parser": "^1.2.1",
|
||||
"statuses": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/serve-static": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
|
||||
"integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"encodeurl": "^2.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"parseurl": "^1.3.3",
|
||||
"send": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/setprototypeof": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/side-channel": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
||||
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"object-inspect": "^1.13.3",
|
||||
"side-channel-list": "^1.0.0",
|
||||
"side-channel-map": "^1.0.1",
|
||||
"side-channel-weakmap": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel-list": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
|
||||
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"object-inspect": "^1.13.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel-map": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
||||
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.2",
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.5",
|
||||
"object-inspect": "^1.13.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel-weakmap": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
||||
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.2",
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.5",
|
||||
"object-inspect": "^1.13.3",
|
||||
"side-channel-map": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/statuses": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/type-is": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
||||
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"content-type": "^1.0.5",
|
||||
"media-typer": "^1.1.0",
|
||||
"mime-types": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
}
|
11
api/package.json
Normal file
11
api/package.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "api",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"express": "^5.1.0",
|
||||
"express-file-routing": "^3.1.0"
|
||||
}
|
||||
}
|
190
api/routes/estimate.js
Normal file
190
api/routes/estimate.js
Normal file
@ -0,0 +1,190 @@
|
||||
const priceTable = [
|
||||
{
|
||||
regex: /\b(?:thp|summoner|summ|thp armor|summoner armor|summ armor)\b/i,
|
||||
returnKeyWord: "summoner piece",
|
||||
prices: [
|
||||
"1000;10",
|
||||
"1050;12",
|
||||
"1100;15",
|
||||
"1150;25",
|
||||
"1200;30",
|
||||
"1250;100",
|
||||
"1300;500",
|
||||
],
|
||||
},
|
||||
{
|
||||
regex: /\b(?:dps|ab2|dps armor|ab2 armor)\b/i,
|
||||
returnKeyWord: "dps/ab2 piece",
|
||||
prices: [
|
||||
"1400;20",
|
||||
"1450;35",
|
||||
"1500;50",
|
||||
"1550;75",
|
||||
"1600;150",
|
||||
"1650;500",
|
||||
"1700;1000",
|
||||
"1750;2000",
|
||||
"1800;5000",
|
||||
],
|
||||
},
|
||||
{
|
||||
regex: /\b(?:tb|ab1)\b/i,
|
||||
returnKeyWord: "tb/ab1 piece",
|
||||
prices: ["980;5", "1050;15", "1100;40", "1150;70", "1200;500"],
|
||||
},
|
||||
{
|
||||
regex: /\b(?:app builder armor|apprentice builder piece|app builder piece|apprentice builder armor|app piece|apprentice piece)\b/i,
|
||||
returnKeyWord: "apprentice builder piece",
|
||||
prices: [
|
||||
"2000;25",
|
||||
"2050;35",
|
||||
"2100;50",
|
||||
"2150;80",
|
||||
"2200;150",
|
||||
"2250;220",
|
||||
"2300;500",
|
||||
"2350;1000",
|
||||
"2400;2000",
|
||||
],
|
||||
},
|
||||
{
|
||||
regex: /\b(?:app builder staff|apprentice builder staff|app staff|apprentice staff)\b/i,
|
||||
returnKeyWord: "apprentice builder staff",
|
||||
prices: [
|
||||
"2200;5",
|
||||
"2250;15",
|
||||
"2300;25",
|
||||
"2350;35",
|
||||
"2400;45",
|
||||
"2450;70",
|
||||
"2500;100",
|
||||
"2550;175",
|
||||
"2600;250",
|
||||
"2700;400",
|
||||
"2800;500",
|
||||
"2900;2000",
|
||||
],
|
||||
},
|
||||
{
|
||||
regex: /\b(?:aura|trange)\b/i,
|
||||
returnKeyWord: "aura/trange piece",
|
||||
prices: ["980;5", "1050;15", "1100;40", "1150;70", "1200;500"],
|
||||
},
|
||||
];
|
||||
|
||||
function constructPriceSubTable(idx) {
|
||||
const orig = priceTable[idx];
|
||||
const priceSubTable = [];
|
||||
orig.prices.forEach((price) => {
|
||||
const splitPrice = price.split(";");
|
||||
const obj = {
|
||||
number: parseInt(splitPrice[0]),
|
||||
val: parseInt(splitPrice[1]),
|
||||
};
|
||||
priceSubTable.push(obj);
|
||||
});
|
||||
return priceSubTable;
|
||||
}
|
||||
|
||||
function findClosestPrice(subtable, gameValue) {
|
||||
let closestIdx = 0;
|
||||
let closest = subtable[closestIdx];
|
||||
let smallestDiff = Math.abs(subtable[0].number - gameValue);
|
||||
|
||||
for (let i = 1; i < subtable.length; i++) {
|
||||
const diff = Math.abs(subtable[i].number - gameValue);
|
||||
if (diff < smallestDiff) {
|
||||
smallestDiff = diff;
|
||||
closest = subtable[i];
|
||||
closestIdx = i;
|
||||
}
|
||||
}
|
||||
|
||||
return { val: closest.val, diff: smallestDiff, idx: closestIdx };
|
||||
}
|
||||
|
||||
function weightedInterpolatePrice(pricesArr, inputNum, p = 2) {
|
||||
let lower = null;
|
||||
let upper = null;
|
||||
|
||||
for (let i = 0; i < pricesArr.length; i++) {
|
||||
if (pricesArr[i].number === inputNum) return pricesArr[i].val;
|
||||
if (pricesArr[i].number < inputNum) lower = pricesArr[i];
|
||||
if (pricesArr[i].number > inputNum) {
|
||||
upper = pricesArr[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lower) return upper.val;
|
||||
if (!upper) return lower.val;
|
||||
|
||||
const fraction = (inputNum - lower.number) / (upper.number - lower.number);
|
||||
const weight =
|
||||
Math.pow(fraction, p) /
|
||||
(Math.pow(fraction, p) + Math.pow(1 - fraction, p));
|
||||
|
||||
return lower.val + weight * (upper.val - lower.val);
|
||||
}
|
||||
|
||||
export const get = async (req, res) => {
|
||||
if (req.query.getPriceTable) {
|
||||
let tbl = [];
|
||||
priceTable.forEach((p) => {
|
||||
tbl.push(p.returnKeyWord);
|
||||
});
|
||||
return res.json(tbl);
|
||||
}
|
||||
|
||||
const combined = req.query.q;
|
||||
if (!combined || combined.replace(" ", "").length == 0)
|
||||
return res.status(400).json({ error: "Missing query." });
|
||||
|
||||
let entryFound = false;
|
||||
let estimatedPrice = 0;
|
||||
let subtable, closestInTable;
|
||||
let gameValue = 0;
|
||||
let returnKeyWord = "";
|
||||
|
||||
combined.split(" ").forEach((arg) => {
|
||||
if (!isNaN(parseInt(arg)) && !gameValue) {
|
||||
gameValue = parseInt(arg);
|
||||
}
|
||||
});
|
||||
|
||||
priceTable.forEach((price, idx) => {
|
||||
if (price.regex.test(combined) && !entryFound) {
|
||||
entryFound = true;
|
||||
returnKeyWord = price.returnKeyWord;
|
||||
subtable = constructPriceSubTable(idx);
|
||||
closestInTable = findClosestPrice(subtable, gameValue);
|
||||
estimatedPrice = Math.round(
|
||||
weightedInterpolatePrice(subtable, gameValue)
|
||||
);
|
||||
if (closestInTable.idx == 0 && closestInTable.diff > 100) {
|
||||
estimatedPrice = 0;
|
||||
}
|
||||
if (estimatedPrice > 100000) {
|
||||
estimatedPrice = 100000;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (entryFound) {
|
||||
if (req.query.showTable && req.query.showTable != "false") {
|
||||
return res.json({
|
||||
returnKeyWord,
|
||||
subtable,
|
||||
});
|
||||
} else {
|
||||
return res.json({
|
||||
gameValue,
|
||||
estimatedPrice,
|
||||
returnKeyWord,
|
||||
closestInTable,
|
||||
});
|
||||
}
|
||||
} else
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: "Query could not be matched with anything." });
|
||||
};
|
112
api/routes/resistances.js
Normal file
112
api/routes/resistances.js
Normal file
@ -0,0 +1,112 @@
|
||||
export const get = async (req, res) => {
|
||||
let mainStat = Number(req.query.mainStat);
|
||||
let upgrades = Number(req.query.upgrades);
|
||||
let subStat = Number(req.query.subStat);
|
||||
|
||||
if (isNaN(mainStat) || isNaN(upgrades) || isNaN(subStat)) {
|
||||
return res.status(400).json({
|
||||
error: "mainStat, upgrades, and subStat must be numbers",
|
||||
});
|
||||
}
|
||||
|
||||
let resistances;
|
||||
try {
|
||||
resistances = JSON.parse(req.query.resistances);
|
||||
} catch (err) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: "resistances must be a valid JSON array" });
|
||||
}
|
||||
|
||||
if (!Array.isArray(resistances) || resistances.length !== 4) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: "resistances must be an array of 4 elements" });
|
||||
}
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (typeof resistances[i] !== "number") {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: `resistances[${i}] must be a number` });
|
||||
}
|
||||
}
|
||||
if (resistances[3] !== null && typeof resistances[3] !== "number") {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: "resistances[3] must be a number or null" });
|
||||
}
|
||||
upgrades = upgrades - 1;
|
||||
let resUpgrades = 0;
|
||||
resistances.forEach((res) => {
|
||||
if (res == null) return;
|
||||
if (res > 29)
|
||||
return message.channel.send(
|
||||
"Please provide a number less than 29 for resistances."
|
||||
);
|
||||
if (res < 29) {
|
||||
if (res < 0) {
|
||||
let underzero = Math.abs(res);
|
||||
if (underzero < 13) {
|
||||
resUpgrades += 23 + Math.abs(res);
|
||||
} else {
|
||||
if (underzero == 13 || underzero == 14) {
|
||||
resUpgrades += 23 + 13;
|
||||
}
|
||||
if (underzero == 15 || underzero == 16) {
|
||||
resUpgrades += 23 + 13 + 1;
|
||||
}
|
||||
if (underzero == 17 || underzero == 18) {
|
||||
resUpgrades += 23 + 13 + 2;
|
||||
}
|
||||
if (underzero == 19 || underzero == 20 || underzero == 22) {
|
||||
resUpgrades += 23 + 13 + 3;
|
||||
}
|
||||
if (underzero == 21 || underzero == 23) {
|
||||
resUpgrades += 23 + 13 + 4;
|
||||
}
|
||||
if (underzero > 23) {
|
||||
resUpgrades += 29 - underzero;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (res < 14) {
|
||||
let am = 14 - res;
|
||||
resUpgrades += am + 4 + 6;
|
||||
} else {
|
||||
if (res == 14) {
|
||||
resUpgrades += 4 + 6;
|
||||
}
|
||||
if (res == 15 || res == 16) {
|
||||
resUpgrades += 3 + 6;
|
||||
}
|
||||
if (res == 17 || res == 18) {
|
||||
resUpgrades += 2 + 6;
|
||||
}
|
||||
if (res == 19 || res == 20 || res == 22) {
|
||||
resUpgrades += 1 + 6;
|
||||
}
|
||||
if (res == 21 || res == 23) {
|
||||
resUpgrades += 6;
|
||||
}
|
||||
if (res > 23) {
|
||||
resUpgrades += 29 - res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
upgrades -= resUpgrades;
|
||||
mainStat += upgrades;
|
||||
if (mainStat > 999) {
|
||||
let over = mainStat - 999;
|
||||
mainStat -= over;
|
||||
subStat += over;
|
||||
}
|
||||
res.json({
|
||||
resUpgrades,
|
||||
mainStat,
|
||||
subStat,
|
||||
bonus: Math.ceil(mainStat * 1.4 + subStat * 1.4),
|
||||
});
|
||||
};
|
3
bot/.dockerignore
Normal file
3
bot/.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
.env
|
16
bot/Dockerfile
Normal file
16
bot/Dockerfile
Normal file
@ -0,0 +1,16 @@
|
||||
ARG NODE_VERSION=23.0.0
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Install dependencies
|
||||
COPY package*.json ./
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY --chown=node:node . .
|
||||
|
||||
USER node
|
||||
|
||||
CMD ["node", "index.js"]
|
39
bot/commands/bonus.js
Normal file
39
bot/commands/bonus.js
Normal file
@ -0,0 +1,39 @@
|
||||
exports.name = "bonus";
|
||||
exports.description =
|
||||
":star: Sums and calculates bonus for player stat numbers.";
|
||||
exports.usage =
|
||||
"CLIENT_PREFIX:bonus <number> <number> [inf optional extra numbers]";
|
||||
exports.example = "CLIENT_PREFIX:bonus 100 100";
|
||||
exports.hidden = false;
|
||||
exports.run = (client, message, args) => {
|
||||
let is1nan = false;
|
||||
if (!args[0])
|
||||
return message.channel.send(
|
||||
"Not enough arguments, consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
args.forEach((arg) => {
|
||||
if (isNaN(parseInt(arg))) {
|
||||
is1nan = true;
|
||||
}
|
||||
arg = parseInt(arg);
|
||||
});
|
||||
if (is1nan)
|
||||
return message.channel.send(
|
||||
"You have provided invalid arguments to this command, please consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
let sum = 0;
|
||||
args.forEach((arg) => {
|
||||
if (arg > 2000) arg = 2000; // just dont bother for anything higher than 2000
|
||||
sum += parseInt(arg);
|
||||
});
|
||||
sum--;
|
||||
message.channel.send(
|
||||
`Will reach ${sum}, ${Math.ceil(sum * 1.4)} with bonus.`
|
||||
);
|
||||
};
|
31
bot/commands/cat.js
Normal file
31
bot/commands/cat.js
Normal file
@ -0,0 +1,31 @@
|
||||
exports.name = "cat";
|
||||
exports.description = ":cat: Calculates boost for cat.";
|
||||
exports.usage = "CLIENT_PREFIX:cat <boost> <levels>";
|
||||
exports.example = "CLIENT_PREFIX:cat 80 120";
|
||||
exports.hidden = false;
|
||||
exports.run = (client, message, args) => {
|
||||
if (!args[0] || !args[1])
|
||||
return message.channel.send(
|
||||
"Not enough arguments, consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
let boost = parseInt(args[0]);
|
||||
let levels = parseInt(args[1]);
|
||||
if (isNaN(boost) || isNaN(levels))
|
||||
return message.channel.send(
|
||||
"Boost or levels is not a number. Consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
let extraboost = Math.floor(levels / 3 - 3);
|
||||
let players = Math.floor(levels / 29) + 1;
|
||||
if (players > 4) players = 4;
|
||||
message.channel.send(
|
||||
`Your cat's boost should be atleast **${
|
||||
boost + extraboost
|
||||
}**. It will boost atleast **${players}** players.`
|
||||
);
|
||||
};
|
32
bot/commands/cb.js
Normal file
32
bot/commands/cb.js
Normal file
@ -0,0 +1,32 @@
|
||||
const log = require("../log");
|
||||
exports.name = "cb";
|
||||
exports.description =
|
||||
":crossed_swords: Calculate calamity blade damage taking in to account projectile speed.";
|
||||
exports.usage = "CLIENT_PREFIX:cb <damage> <ups> [projectile speed]";
|
||||
exports.example = "CLIENT_PREFIX:cb 10000 250 10000";
|
||||
exports.hidden = false;
|
||||
exports.run = (client, message, args) => {
|
||||
if (!args[0] || !args[1])
|
||||
return message.channel.send(
|
||||
"Not enough arguments, consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
let cb = parseInt(args[0]);
|
||||
let ups = parseInt(args[1]);
|
||||
if (isNaN(cb) || isNaN(ups))
|
||||
return message.channel.send("Damage or ups should be a number.");
|
||||
let initialspeed = null;
|
||||
if (args[2]) {
|
||||
initialspeed = parseInt(args[2]);
|
||||
if (isNaN(initialspeed))
|
||||
return message.channel.send("Projectile speed should be a number.");
|
||||
initialspeed = 30000 - initialspeed;
|
||||
let t = Math.ceil(initialspeed / 1200);
|
||||
log.info(t);
|
||||
ups = ups - t;
|
||||
}
|
||||
let resnum = cb + ups * 192;
|
||||
message.channel.send(`Your Calamity Blade will hit **${resnum}** damage.`);
|
||||
};
|
69
bot/commands/estimate.js
Normal file
69
bot/commands/estimate.js
Normal file
@ -0,0 +1,69 @@
|
||||
const log = require("../log");
|
||||
exports.name = "estimate";
|
||||
exports.description =
|
||||
":money_with_wings: Give an estimated price of certain items in cv.";
|
||||
exports.usage =
|
||||
"CLIENT_PREFIX:estimate [summary of item you want the price of]";
|
||||
exports.example =
|
||||
"CLIENT_PREFIX:estimate 1600 ab2\nCLIENT_PREFIX:estimate 1100 thp\nCLIENT_PREFIX:estimate 2400 app builder staff\n(you can also include `showtable` anywhere to show raw price data)\n(always put number first, do not put conflicting data to avoid confusion)";
|
||||
exports.hidden = false;
|
||||
exports.run = async (client, message, args) => {
|
||||
if (!args[0]) {
|
||||
return fetch(client.sharedEndpoint + "estimate" + "?getPriceTable=true")
|
||||
.then((d) => d.json())
|
||||
.then((tbl) => {
|
||||
return message.channel.send(
|
||||
`Available items in pricing table:\n\`\`\`\n${tbl.join(
|
||||
"\n"
|
||||
)}\`\`\`\nFor usage, consult \`CLIENT_PREFIX:help estimate\`
|
||||
`.replaceAll("CLIENT_PREFIX:", client.prefix)
|
||||
);
|
||||
});
|
||||
}
|
||||
const combined = args.join(" ");
|
||||
let showtable = combined.includes("showtable");
|
||||
fetch(
|
||||
client.sharedEndpoint +
|
||||
"estimate" +
|
||||
`?q=${combined}&showTable=` +
|
||||
showtable
|
||||
)
|
||||
.then((d) => d.json())
|
||||
.then((data) => {
|
||||
if (data.error) {
|
||||
return message.channel.send(data.error);
|
||||
} else {
|
||||
if (showtable) {
|
||||
const { returnKeyWord, subtable } = data;
|
||||
let res = "";
|
||||
subtable.forEach((entry) => {
|
||||
res +=
|
||||
String(entry.number).padEnd(14, " ") +
|
||||
entry.val +
|
||||
"\n";
|
||||
});
|
||||
message.channel.send(
|
||||
`Displaying data price table for \`${returnKeyWord}\`.\n\`\`\`\nGame Value\tPrice\n${res}\`\`\``
|
||||
);
|
||||
} else {
|
||||
const {
|
||||
gameValue,
|
||||
estimatedPrice,
|
||||
returnKeyWord,
|
||||
closestInTable,
|
||||
} = data;
|
||||
let stringprice;
|
||||
if (estimatedPrice > 499) {
|
||||
stringprice = `**__${estimatedPrice}__** (atleast 1 cheater, worth auctioning)`;
|
||||
} else if (estimatedPrice == 0) {
|
||||
stringprice = "**0** (<:TavKeep:1179145911180480563>)";
|
||||
} else {
|
||||
stringprice = `**${estimatedPrice}**`;
|
||||
}
|
||||
message.channel.send(
|
||||
`Hmm... I estimate your **${gameValue} ${returnKeyWord}** to be worth approximately ${stringprice} cv.\n*Estimation is provided through looking at past trades/price checks/sheets in DDRNG.*\n*Closest price in table: **${closestInTable.val}** cv, diff: **${closestInTable.diff}***.`
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
113
bot/commands/ev.js
Normal file
113
bot/commands/ev.js
Normal file
@ -0,0 +1,113 @@
|
||||
const BASEDMG = 1e9; // absurdly high to avoid base damage bottleneck
|
||||
|
||||
function getHeroDamageScaling(statVal) {
|
||||
return (
|
||||
1.0 +
|
||||
0.33 *
|
||||
(Math.pow(4.0, 0.1 * 1.1) -
|
||||
1.0 +
|
||||
0.68 * (Math.pow(statVal + 1, 0.375 * 1.1) - 1.0))
|
||||
);
|
||||
}
|
||||
|
||||
function getAb2Scaling(statVal) {
|
||||
return (
|
||||
1.0 +
|
||||
0.66 * (Math.pow(4.0, 0.0825) - 1.0) +
|
||||
0.75 * (Math.pow(statVal + 1, 0.3375) - 1.0)
|
||||
);
|
||||
}
|
||||
|
||||
function getTotalDamage(hdmgStat, baseDamage) {
|
||||
return Math.max(
|
||||
Math.max(32.0, Math.max(1.0, baseDamage)) *
|
||||
getHeroDamageScaling(hdmgStat) *
|
||||
(1.2 * 0.8 * 0.155),
|
||||
1.0
|
||||
);
|
||||
}
|
||||
|
||||
function getBeamDamage(hdmg, ab2) {
|
||||
return (
|
||||
getTotalDamage(hdmg, BASEDMG) * 0.6 * Math.pow(getAb2Scaling(ab2), 0.93)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find optimal split of totalStats between hdmg and ab2
|
||||
* using a binary/golden section search.
|
||||
*/
|
||||
function findOptimalDistribution(totalStats) {
|
||||
let left = 0;
|
||||
let right = totalStats;
|
||||
const phi = (Math.sqrt(5) - 1) / 2; // golden ratio for faster convergence
|
||||
let x1 = right - phi * (right - left);
|
||||
let x2 = left + phi * (right - left);
|
||||
|
||||
while (Math.abs(right - left) > 1e-3) {
|
||||
const f1 = getBeamDamage(x1, totalStats - x1);
|
||||
const f2 = getBeamDamage(x2, totalStats - x2);
|
||||
|
||||
if (f1 < f2) {
|
||||
left = x1;
|
||||
x1 = x2;
|
||||
x2 = left + phi * (right - left);
|
||||
} else {
|
||||
right = x2;
|
||||
x2 = x1;
|
||||
x1 = right - phi * (right - left);
|
||||
}
|
||||
}
|
||||
|
||||
const hdmg = (left + right) / 2;
|
||||
const ab2 = totalStats - hdmg;
|
||||
return {
|
||||
hdmg: hdmg,
|
||||
ab2: ab2,
|
||||
};
|
||||
}
|
||||
|
||||
exports.name = "ev";
|
||||
exports.description =
|
||||
":robot: Calculate how much hero damage/ab2 you should aim for.";
|
||||
exports.usage =
|
||||
"CLIENT_PREFIX:ev <hdmg> <ab2> OR CLIENT_PREFIX:ev <total stats>";
|
||||
exports.example = "CLIENT_PREFIX:ev 6000 5000\nCLIENT_PREFIX:ev 10000";
|
||||
exports.hidden = false;
|
||||
exports.run = (client, message, args) => {
|
||||
if (!args[0])
|
||||
return message.channel.send(
|
||||
"Not enough arguments, consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
let total = parseInt(args[0]);
|
||||
if (isNaN(total))
|
||||
return message.channel.send(
|
||||
"One of the arguments is not a number. Consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
if (args[1]) {
|
||||
if (isNaN(parseInt(args[1]))) {
|
||||
return message.channel.send(
|
||||
"One of the arguments is not a number. Consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
} else total += parseInt(args[1]);
|
||||
}
|
||||
|
||||
const distribution = findOptimalDistribution(total);
|
||||
|
||||
message.channel.send(
|
||||
`You should aim for **${
|
||||
Math.round(distribution.hdmg) - 3
|
||||
}** hero damage and **${
|
||||
Math.round(distribution.ab2) + 3
|
||||
}** ab2. *(approximately)*`
|
||||
);
|
||||
};
|
55
bot/commands/hb.js
Normal file
55
bot/commands/hb.js
Normal file
@ -0,0 +1,55 @@
|
||||
const STAT_MULT_INITIAL_AB2 = 0.66;
|
||||
const STAT_MULT_FULL_AB2 = 0.75;
|
||||
|
||||
const STAT_EXP_INITIAL_AB2 = 0.0825;
|
||||
const STAT_EXP_FULL_AB2 = 0.3375;
|
||||
|
||||
const ADDITIONAL_DAMAGE_MULTIPLIER = 0.25;
|
||||
const ADDITIONAL_DAMAGE_EXPONENT = 0.95;
|
||||
|
||||
// Functions
|
||||
function get_ab2_scaling(stat_val) {
|
||||
return (
|
||||
1.0 +
|
||||
STAT_MULT_INITIAL_AB2 *
|
||||
(Math.min(stat_val + 1.0, 4.0) ** STAT_EXP_INITIAL_AB2 - 1.0) +
|
||||
STAT_MULT_FULL_AB2 * ((stat_val + 1.0) ** STAT_EXP_FULL_AB2 - 1.0)
|
||||
);
|
||||
}
|
||||
|
||||
function get_damage_multiplier(stat_val) {
|
||||
return (
|
||||
1.0 +
|
||||
ADDITIONAL_DAMAGE_MULTIPLIER *
|
||||
get_ab2_scaling(Math.max(stat_val, 1)) ** ADDITIONAL_DAMAGE_EXPONENT
|
||||
);
|
||||
}
|
||||
|
||||
exports.name = "hb";
|
||||
exports.description = ":muscle: Calculate hero boost's damage multiplier.";
|
||||
exports.usage = "CLIENT_PREFIX:hb <points>";
|
||||
exports.example = "CLIENT_PREFIX:hb 5000";
|
||||
exports.hidden = false;
|
||||
exports.run = (client, message, args) => {
|
||||
if (!args[0])
|
||||
return message.channel.send(
|
||||
"Not enough arguments, consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
let hbPoints = parseInt(args[0]);
|
||||
if (isNaN(hbPoints))
|
||||
return message.channel.send(
|
||||
"Given argument is not a number. Consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
|
||||
message.channel.send(
|
||||
`With **${hbPoints}** points in your hero boost, you will boost with a **${get_damage_multiplier(
|
||||
hbPoints
|
||||
).toFixed(4)}** damage multiplier.`
|
||||
);
|
||||
};
|
49
bot/commands/help.js
Normal file
49
bot/commands/help.js
Normal file
@ -0,0 +1,49 @@
|
||||
const { EmbedBuilder } = require("discord.js");
|
||||
exports.name = "help";
|
||||
exports.description =
|
||||
":scroll: Shows this message and provides insight into other commands.";
|
||||
exports.usage = "CLIENT_PREFIX:help [optional other command]";
|
||||
exports.example = "CLIENT_PREFIX:help res";
|
||||
exports.hidden = false;
|
||||
exports.run = (client, message, args) => {
|
||||
let embed = new EmbedBuilder();
|
||||
embed.setTitle("Commands Helper");
|
||||
if (args[0]) {
|
||||
const cmd = client.commands.get(args[0]);
|
||||
if (!cmd)
|
||||
return message.channel.send(
|
||||
"Command not found, try `CLIENT_PREFIX:help` first.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
if (cmd.hidden && message.author.id != client.ownerID) return;
|
||||
embed.setTitle(`Help for \`${cmd.name}\` command`);
|
||||
embed.setDescription(cmd.description);
|
||||
embed.addFields(
|
||||
{
|
||||
name: "Usage",
|
||||
value: cmd.usage.replaceAll("CLIENT_PREFIX:", client.prefix),
|
||||
},
|
||||
{
|
||||
name: "Example",
|
||||
value: cmd.example.replaceAll("CLIENT_PREFIX:", client.prefix),
|
||||
}
|
||||
);
|
||||
} else {
|
||||
[...client.commands.values()]
|
||||
.sort((a, b) => (a.name > b.name ? 1 : -1))
|
||||
.forEach((cmd) => {
|
||||
if (cmd.hidden && message.author.id != client.ownerID) return;
|
||||
embed.addFields({
|
||||
name: cmd.name,
|
||||
value: cmd.description.replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
),
|
||||
});
|
||||
});
|
||||
}
|
||||
embed.setColor(0x00ff00);
|
||||
message.channel.send({ embeds: [embed] });
|
||||
};
|
33
bot/commands/ms.js
Normal file
33
bot/commands/ms.js
Normal file
@ -0,0 +1,33 @@
|
||||
const log = require("../log");
|
||||
exports.name = "ms";
|
||||
exports.description =
|
||||
":tada: Calculate moon staff damage taking in to account projectile speed.";
|
||||
exports.usage = "CLIENT_PREFIX:ms <elemental damage> <ups> [projectile speed]";
|
||||
exports.example = "CLIENT_PREFIX:ms 10000 250 10000";
|
||||
exports.hidden = false;
|
||||
exports.run = (client, message, args) => {
|
||||
if (!args[0] || !args[1])
|
||||
return message.channel.send(
|
||||
"Not enough arguments, consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
let moonstaff = parseInt(args[0]);
|
||||
let ups = parseInt(args[1]);
|
||||
if (isNaN(moonstaff) || isNaN(ups))
|
||||
return message.channel.send("Damage or ups should be a number.");
|
||||
let initialspeed = null;
|
||||
if (args[2]) {
|
||||
initialspeed = parseInt(args[2]);
|
||||
if (isNaN(initialspeed))
|
||||
return message.channel.send("Projectile speed should be a number.");
|
||||
initialspeed = 30000 - initialspeed;
|
||||
let t = Math.ceil(initialspeed / 1200);
|
||||
log.info(t);
|
||||
ups = ups - t;
|
||||
}
|
||||
message.channel.send(
|
||||
`Your Moon Staff will hit ${moonstaff + ups * 99} damage.`
|
||||
);
|
||||
};
|
27
bot/commands/ping.js
Normal file
27
bot/commands/ping.js
Normal file
@ -0,0 +1,27 @@
|
||||
function format(seconds) {
|
||||
function pad(s) {
|
||||
return (s < 10 ? "0" : "") + s;
|
||||
}
|
||||
var hours = Math.floor(seconds / (60 * 60));
|
||||
var minutes = Math.floor((seconds % (60 * 60)) / 60);
|
||||
var seconds = Math.floor(seconds % 60);
|
||||
|
||||
return pad(hours) + "h " + pad(minutes) + "m " + pad(seconds) + "s.";
|
||||
}
|
||||
|
||||
exports.name = "ping";
|
||||
exports.description = ":ping_pong: View service statistics.";
|
||||
exports.usage = "CLIENT_PREFIX:ping";
|
||||
exports.example = "CLIENT_PREFIX:ping";
|
||||
exports.hidden = true;
|
||||
exports.run = async (client, message, args) => {
|
||||
message.channel.send("Fetching data...").then((m) => {
|
||||
m.edit(
|
||||
`🏓 Latency is **${
|
||||
m.createdTimestamp - message.createdTimestamp
|
||||
}ms**.\nAPI Latency is **${Math.round(
|
||||
client.ws.ping
|
||||
)}ms**.\nClient uptime is **${format(process.uptime())}**`
|
||||
);
|
||||
});
|
||||
};
|
25
bot/commands/refetch.js
Normal file
25
bot/commands/refetch.js
Normal file
@ -0,0 +1,25 @@
|
||||
exports.name = "refetch";
|
||||
exports.description = ":ninja: Refetch user react data.";
|
||||
exports.usage = "CLIENT_PREFIX:refetch";
|
||||
exports.example = "CLIENT_PREFIX:refetch";
|
||||
exports.hidden = true;
|
||||
exports.run = async (client, message, args) => {
|
||||
if (message.author.id != client.ownerID) return;
|
||||
try {
|
||||
const url = "https://drive.overflow.fun/public/react.json";
|
||||
client.usersToReactTo = [];
|
||||
const res = await fetch(url);
|
||||
const data = await res.json();
|
||||
|
||||
client.usersToReactTo = data.map((entry) => {
|
||||
const [userId, emoji] = entry.split("|");
|
||||
return { userId, emoji };
|
||||
});
|
||||
|
||||
message.channel.send(
|
||||
"Refetched react data. " + JSON.stringify(client.usersToReactTo)
|
||||
);
|
||||
} catch (e) {
|
||||
message.channel.send("copyparty instance unreachable/offline...");
|
||||
}
|
||||
};
|
49
bot/commands/res.js
Normal file
49
bot/commands/res.js
Normal file
@ -0,0 +1,49 @@
|
||||
const logger = require("../log");
|
||||
exports.name = "res";
|
||||
exports.description =
|
||||
":shield: Calculates how much upgrades you need to max your resistances. For Ult pieces and better. (slightly inaccurate but this is hard to calculate)";
|
||||
exports.usage =
|
||||
"CLIENT_PREFIX:res <res> <res> <res> [res] | <hero stat> <levels> [second hero stat]";
|
||||
exports.example = "CLIENT_PREFIX:res -3 1 -16 14 | 406 440";
|
||||
exports.hidden = false;
|
||||
exports.run = async (client, message, args) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] == "|") continue;
|
||||
args[i] = parseInt(args[i]);
|
||||
if (isNaN(args[i]))
|
||||
message.channel.send(
|
||||
"Unable to parse argument `" +
|
||||
i +
|
||||
1 +
|
||||
"` as number, try again or report this issue."
|
||||
);
|
||||
}
|
||||
let type;
|
||||
if (args[4] == "|") type = 4;
|
||||
else if (args[3] == "|") type = 3;
|
||||
else return message.channel.send("Please provide 3 or 4 resistances.");
|
||||
let resistances = [args[0], args[1], args[2], type == 4 ? args[3] : null];
|
||||
let mainStat1 = type == 4 ? args[5] : args[4];
|
||||
let upgrades = type == 4 ? args[6] : args[5];
|
||||
let substat = type == 4 ? args[7] : args[6];
|
||||
if (!mainStat1 || !upgrades)
|
||||
return message.channel.send("Please provide atleast 2 stats.");
|
||||
if (!substat) substat = 0;
|
||||
fetch(
|
||||
client.sharedEndpoint +
|
||||
"resistances" +
|
||||
`?mainStat=${mainStat1}&upgrades=${upgrades}&subStat=${substat}&resistances=${JSON.stringify(
|
||||
resistances
|
||||
)}`
|
||||
)
|
||||
.then((d) => d.json())
|
||||
.then((data) => {
|
||||
const { resUpgrades, mainStat, subStat, bonus } = data;
|
||||
logger.info(resUpgrades, mainStat, subStat, bonus);
|
||||
message.channel.send(
|
||||
`With ${resUpgrades} upgrades spent in resistances, your piece will reach ${
|
||||
mainStat + subStat
|
||||
}, or ${bonus} with set bonus!`
|
||||
);
|
||||
});
|
||||
};
|
56
bot/commands/tb.js
Normal file
56
bot/commands/tb.js
Normal file
@ -0,0 +1,56 @@
|
||||
const STAT_MULT_INITIAL_AB2 = 0.66;
|
||||
const STAT_MULT_FULL_AB2 = 0.75;
|
||||
|
||||
const STAT_EXP_INITIAL_AB2 = 0.0825;
|
||||
const STAT_EXP_FULL_AB2 = 0.3375;
|
||||
|
||||
// only this changed for tower boosting
|
||||
const ADDITIONAL_DAMAGE_MULTIPLIER = 0.1;
|
||||
const ADDITIONAL_DAMAGE_EXPONENT = 1.25;
|
||||
|
||||
// Functions
|
||||
function get_ab2_scaling(stat_val) {
|
||||
return (
|
||||
1.0 +
|
||||
STAT_MULT_INITIAL_AB2 *
|
||||
(Math.min(stat_val + 1.0, 4.0) ** STAT_EXP_INITIAL_AB2 - 1.0) +
|
||||
STAT_MULT_FULL_AB2 * ((stat_val + 1.0) ** STAT_EXP_FULL_AB2 - 1.0)
|
||||
);
|
||||
}
|
||||
|
||||
function get_damage_multiplier(stat_val) {
|
||||
return (
|
||||
1.0 +
|
||||
ADDITIONAL_DAMAGE_MULTIPLIER *
|
||||
get_ab2_scaling(Math.max(stat_val, 1)) ** ADDITIONAL_DAMAGE_EXPONENT
|
||||
);
|
||||
}
|
||||
|
||||
exports.name = "tb";
|
||||
exports.description = ":fire: Calculate tower boost's damage multiplier.";
|
||||
exports.usage = "CLIENT_PREFIX:tb <points>";
|
||||
exports.example = "CLIENT_PREFIX:tb 5000";
|
||||
exports.hidden = false;
|
||||
exports.run = (client, message, args) => {
|
||||
if (!args[0])
|
||||
return message.channel.send(
|
||||
"Not enough arguments, consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
let tbPoints = parseInt(args[0]);
|
||||
if (isNaN(tbPoints))
|
||||
return message.channel.send(
|
||||
"Given argument is not a number. Consult CLIENT_PREFIX:help.".replaceAll(
|
||||
"CLIENT_PREFIX:",
|
||||
client.prefix
|
||||
)
|
||||
);
|
||||
|
||||
message.channel.send(
|
||||
`With **${tbPoints}** points in your tower boost, you will boost towers with a **${get_damage_multiplier(
|
||||
tbPoints
|
||||
).toFixed(4)}** multiplier.`
|
||||
);
|
||||
};
|
91
bot/index.js
Normal file
91
bot/index.js
Normal file
@ -0,0 +1,91 @@
|
||||
const { Client, Events, GatewayIntentBits, Collection } = require("discord.js");
|
||||
const fs = require("fs");
|
||||
const log = require("./log");
|
||||
let cfg = {};
|
||||
try {
|
||||
cfg = require("./config.json");
|
||||
} catch (e) {
|
||||
console.warn(
|
||||
"config.json not found or invalid. Falling back to environment variables."
|
||||
);
|
||||
}
|
||||
const token = process.env.TOKEN || cfg.TOKEN;
|
||||
const prefix = process.env.PREFIX || cfg.PREFIX;
|
||||
const client = new Client({
|
||||
intents: [
|
||||
GatewayIntentBits.Guilds,
|
||||
GatewayIntentBits.GuildMessages,
|
||||
GatewayIntentBits.MessageContent,
|
||||
],
|
||||
});
|
||||
client.commands = new Collection();
|
||||
client.ownerID = 263247134147608578;
|
||||
client.prefix = prefix;
|
||||
client.sharedEndpoint = process.env.SHARED_ENDPOINT;
|
||||
if (!client.sharedEndpoint)
|
||||
return log.error("client.sharedEndpoint is undefined.");
|
||||
|
||||
fs.readdir("./commands/", (err, files) => {
|
||||
if (err) return console.error(err);
|
||||
files.forEach((file) => {
|
||||
if (!file.endsWith(".js")) return;
|
||||
let props = require(`./commands/${file}`);
|
||||
let commandName = file.split(".")[0];
|
||||
log.info("Loaded command " + commandName);
|
||||
client.commands.set(commandName, props);
|
||||
});
|
||||
});
|
||||
|
||||
const url = "https://drive.overflow.fun/public/react.json";
|
||||
client.usersToReactTo = [];
|
||||
client.once(Events.ClientReady, async (readyClient) => {
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
const data = await res.json();
|
||||
|
||||
client.usersToReactTo = data.map((entry) => {
|
||||
const [userId, emoji] = entry.split("|");
|
||||
return { userId, emoji };
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn("copyparty is offline, wont work.");
|
||||
}
|
||||
log.info(`Ready! Logged in as ${readyClient.user.tag}`);
|
||||
});
|
||||
|
||||
client.on(Events.MessageCreate, async (message) => {
|
||||
if (message.author.bot) return;
|
||||
|
||||
client.usersToReactTo.forEach(async (item) => {
|
||||
if (
|
||||
message.mentions.users.find((u) => u.id == item.userId) &&
|
||||
!message.reference
|
||||
) {
|
||||
try {
|
||||
await message.react(item.emoji);
|
||||
} catch (err) {
|
||||
message.channel.send("FAILED TO REACT TO MESSAGE! " + err);
|
||||
console.error("Failed to react to message:", err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (message.content.indexOf(prefix) !== 0) return;
|
||||
|
||||
const args = message.content.slice(prefix.length).trim().split(/ +/g);
|
||||
const command = args.shift().toLowerCase();
|
||||
|
||||
const cmd = client.commands.get(command);
|
||||
|
||||
if (!cmd) return;
|
||||
try {
|
||||
await cmd.run(client, message, args);
|
||||
} catch (e) {
|
||||
message.channel.send(
|
||||
"Command " + cmd.name + " exited with an exception: " + e
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Log in to Discord with your client's token
|
||||
client.login(token);
|
14
bot/log.js
Normal file
14
bot/log.js
Normal file
@ -0,0 +1,14 @@
|
||||
// logger.js
|
||||
function log(level, message, ...args) {
|
||||
const now = new Date().toISOString();
|
||||
const levelLabel = `[${level.toUpperCase()}]`.padEnd(8);
|
||||
|
||||
console.log(`${now} ${levelLabel} ${message}`, ...args);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
info: (msg, ...args) => log("info", msg, ...args),
|
||||
warn: (msg, ...args) => log("warn", msg, ...args),
|
||||
error: (msg, ...args) => log("error", msg, ...args),
|
||||
debug: (msg, ...args) => log("debug", msg, ...args),
|
||||
};
|
299
bot/package-lock.json
generated
Normal file
299
bot/package-lock.json
generated
Normal file
@ -0,0 +1,299 @@
|
||||
{
|
||||
"name": "shirocalc",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "shirocalc",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"discord.js": "^14.14.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/builders": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz",
|
||||
"integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/formatters": "^0.3.3",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@sapphire/shapeshift": "^3.9.3",
|
||||
"discord-api-types": "0.37.61",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"ts-mixer": "^6.0.3",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/collection": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz",
|
||||
"integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/formatters": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz",
|
||||
"integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"discord-api-types": "0.37.61"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz",
|
||||
"integrity": "sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^2.0.0",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@sapphire/async-queue": "^1.5.0",
|
||||
"@sapphire/snowflake": "^3.5.1",
|
||||
"@vladfrangu/async_event_emitter": "^2.2.2",
|
||||
"discord-api-types": "0.37.61",
|
||||
"magic-bytes.js": "^1.5.0",
|
||||
"tslib": "^2.6.2",
|
||||
"undici": "5.27.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest/node_modules/@discordjs/collection": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
|
||||
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/util": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz",
|
||||
"integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz",
|
||||
"integrity": "sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^2.0.0",
|
||||
"@discordjs/rest": "^2.1.0",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@sapphire/async-queue": "^1.5.0",
|
||||
"@types/ws": "^8.5.9",
|
||||
"@vladfrangu/async_event_emitter": "^2.2.2",
|
||||
"discord-api-types": "0.37.61",
|
||||
"tslib": "^2.6.2",
|
||||
"ws": "^8.14.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws/node_modules/@discordjs/collection": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
|
||||
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz",
|
||||
"integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/async-queue": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz",
|
||||
"integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/shapeshift": {
|
||||
"version": "3.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.3.tgz",
|
||||
"integrity": "sha512-WzKJSwDYloSkHoBbE8rkRW8UNKJiSRJ/P8NqJ5iVq7U2Yr/kriIBx2hW+wj2Z5e5EnXL1hgYomgaFsdK6b+zqQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/snowflake": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz",
|
||||
"integrity": "sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz",
|
||||
"integrity": "sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz",
|
||||
"integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@vladfrangu/async_event_emitter": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz",
|
||||
"integrity": "sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/discord-api-types": {
|
||||
"version": "0.37.61",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz",
|
||||
"integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/discord.js": {
|
||||
"version": "14.14.1",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz",
|
||||
"integrity": "sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^1.7.0",
|
||||
"@discordjs/collection": "1.5.3",
|
||||
"@discordjs/formatters": "^0.3.3",
|
||||
"@discordjs/rest": "^2.1.0",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@discordjs/ws": "^1.0.2",
|
||||
"@sapphire/snowflake": "3.5.1",
|
||||
"@types/ws": "8.5.9",
|
||||
"discord-api-types": "0.37.61",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"lodash.snakecase": "4.1.1",
|
||||
"tslib": "2.6.2",
|
||||
"undici": "5.27.2",
|
||||
"ws": "8.14.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.snakecase": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
|
||||
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/magic-bytes.js": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.5.0.tgz",
|
||||
"integrity": "sha512-wJkXvutRbNWcc37tt5j1HyOK1nosspdh3dj6LUYYAvF6JYNqs53IfRvK9oEpcwiDA1NdoIi64yAMfdivPeVAyw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ts-mixer": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz",
|
||||
"integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "5.27.2",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz",
|
||||
"integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.14.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
|
||||
"integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
|
||||
"license": "MIT",
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
bot/package.json
Normal file
9
bot/package.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "bot",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"discord.js": "^14.14.1"
|
||||
}
|
||||
}
|
182
bot/yarn.lock
Normal file
182
bot/yarn.lock
Normal file
@ -0,0 +1,182 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@discordjs/builders@^1.7.0":
|
||||
version "1.7.0"
|
||||
resolved "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz"
|
||||
integrity sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==
|
||||
dependencies:
|
||||
"@discordjs/formatters" "^0.3.3"
|
||||
"@discordjs/util" "^1.0.2"
|
||||
"@sapphire/shapeshift" "^3.9.3"
|
||||
discord-api-types "0.37.61"
|
||||
fast-deep-equal "^3.1.3"
|
||||
ts-mixer "^6.0.3"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@discordjs/collection@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz"
|
||||
integrity sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==
|
||||
|
||||
"@discordjs/collection@1.5.3":
|
||||
version "1.5.3"
|
||||
resolved "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz"
|
||||
integrity sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==
|
||||
|
||||
"@discordjs/formatters@^0.3.3":
|
||||
version "0.3.3"
|
||||
resolved "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz"
|
||||
integrity sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==
|
||||
dependencies:
|
||||
discord-api-types "0.37.61"
|
||||
|
||||
"@discordjs/rest@^2.1.0":
|
||||
version "2.2.0"
|
||||
resolved "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz"
|
||||
integrity sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==
|
||||
dependencies:
|
||||
"@discordjs/collection" "^2.0.0"
|
||||
"@discordjs/util" "^1.0.2"
|
||||
"@sapphire/async-queue" "^1.5.0"
|
||||
"@sapphire/snowflake" "^3.5.1"
|
||||
"@vladfrangu/async_event_emitter" "^2.2.2"
|
||||
discord-api-types "0.37.61"
|
||||
magic-bytes.js "^1.5.0"
|
||||
tslib "^2.6.2"
|
||||
undici "5.27.2"
|
||||
|
||||
"@discordjs/util@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz"
|
||||
integrity sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==
|
||||
|
||||
"@discordjs/ws@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz"
|
||||
integrity sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==
|
||||
dependencies:
|
||||
"@discordjs/collection" "^2.0.0"
|
||||
"@discordjs/rest" "^2.1.0"
|
||||
"@discordjs/util" "^1.0.2"
|
||||
"@sapphire/async-queue" "^1.5.0"
|
||||
"@types/ws" "^8.5.9"
|
||||
"@vladfrangu/async_event_emitter" "^2.2.2"
|
||||
discord-api-types "0.37.61"
|
||||
tslib "^2.6.2"
|
||||
ws "^8.14.2"
|
||||
|
||||
"@fastify/busboy@^2.0.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz"
|
||||
integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==
|
||||
|
||||
"@sapphire/async-queue@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz"
|
||||
integrity sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==
|
||||
|
||||
"@sapphire/shapeshift@^3.9.3":
|
||||
version "3.9.3"
|
||||
resolved "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.3.tgz"
|
||||
integrity sha512-WzKJSwDYloSkHoBbE8rkRW8UNKJiSRJ/P8NqJ5iVq7U2Yr/kriIBx2hW+wj2Z5e5EnXL1hgYomgaFsdK6b+zqQ==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.3"
|
||||
lodash "^4.17.21"
|
||||
|
||||
"@sapphire/snowflake@^3.5.1", "@sapphire/snowflake@3.5.1":
|
||||
version "3.5.1"
|
||||
resolved "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz"
|
||||
integrity sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==
|
||||
|
||||
"@types/node@*":
|
||||
version "20.10.0"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz"
|
||||
integrity sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==
|
||||
dependencies:
|
||||
undici-types "~5.26.4"
|
||||
|
||||
"@types/ws@^8.5.9", "@types/ws@8.5.9":
|
||||
version "8.5.9"
|
||||
resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz"
|
||||
integrity sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@vladfrangu/async_event_emitter@^2.2.2":
|
||||
version "2.2.2"
|
||||
resolved "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz"
|
||||
integrity sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ==
|
||||
|
||||
discord-api-types@0.37.61:
|
||||
version "0.37.61"
|
||||
resolved "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz"
|
||||
integrity sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==
|
||||
|
||||
discord.js@^14.14.1:
|
||||
version "14.14.1"
|
||||
resolved "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz"
|
||||
integrity sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==
|
||||
dependencies:
|
||||
"@discordjs/builders" "^1.7.0"
|
||||
"@discordjs/collection" "1.5.3"
|
||||
"@discordjs/formatters" "^0.3.3"
|
||||
"@discordjs/rest" "^2.1.0"
|
||||
"@discordjs/util" "^1.0.2"
|
||||
"@discordjs/ws" "^1.0.2"
|
||||
"@sapphire/snowflake" "3.5.1"
|
||||
"@types/ws" "8.5.9"
|
||||
discord-api-types "0.37.61"
|
||||
fast-deep-equal "3.1.3"
|
||||
lodash.snakecase "4.1.1"
|
||||
tslib "2.6.2"
|
||||
undici "5.27.2"
|
||||
ws "8.14.2"
|
||||
|
||||
fast-deep-equal@^3.1.3, fast-deep-equal@3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
lodash.snakecase@4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz"
|
||||
integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==
|
||||
|
||||
lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
magic-bytes.js@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.5.0.tgz"
|
||||
integrity sha512-wJkXvutRbNWcc37tt5j1HyOK1nosspdh3dj6LUYYAvF6JYNqs53IfRvK9oEpcwiDA1NdoIi64yAMfdivPeVAyw==
|
||||
|
||||
ts-mixer@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz"
|
||||
integrity sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==
|
||||
|
||||
tslib@^2.6.2, tslib@2.6.2:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz"
|
||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||
|
||||
undici-types@~5.26.4:
|
||||
version "5.26.5"
|
||||
resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz"
|
||||
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
||||
|
||||
undici@5.27.2:
|
||||
version "5.27.2"
|
||||
resolved "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz"
|
||||
integrity sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==
|
||||
dependencies:
|
||||
"@fastify/busboy" "^2.0.0"
|
||||
|
||||
ws@^8.14.2, ws@8.14.2:
|
||||
version "8.14.2"
|
||||
resolved "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz"
|
||||
integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==
|
38
docker-compose.yml
Normal file
38
docker-compose.yml
Normal file
@ -0,0 +1,38 @@
|
||||
name: dd-multitool
|
||||
services:
|
||||
api:
|
||||
restart: unless-stopped
|
||||
build:
|
||||
context: ./api
|
||||
dockerfile: Dockerfile
|
||||
networks:
|
||||
- dundef-tool
|
||||
environment:
|
||||
- PORT=2000
|
||||
web:
|
||||
restart: unless-stopped
|
||||
build:
|
||||
context: ./web
|
||||
dockerfile: Dockerfile
|
||||
networks:
|
||||
- dundef-tool
|
||||
depends_on:
|
||||
- api
|
||||
ports:
|
||||
- "8080:80"
|
||||
bot:
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- TOKEN=${TOKEN}
|
||||
- PREFIX=${PREFIX}
|
||||
- SHARED_ENDPOINT=http://api:2000/
|
||||
build:
|
||||
context: ./bot
|
||||
dockerfile: Dockerfile
|
||||
networks:
|
||||
- dundef-tool
|
||||
depends_on:
|
||||
- api
|
||||
|
||||
networks:
|
||||
dundef-tool:
|
3
web/.dockerignore
Normal file
3
web/.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
.env
|
24
web/.gitignore
vendored
Normal file
24
web/.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
32
web/Dockerfile
Normal file
32
web/Dockerfile
Normal file
@ -0,0 +1,32 @@
|
||||
# Stage 1: Build the Vite app
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package.json and package-lock.json (or pnpm-lock.yaml / yarn.lock)
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm install
|
||||
|
||||
# Copy the rest of the app
|
||||
COPY . .
|
||||
|
||||
# Build the app
|
||||
RUN npm run build
|
||||
|
||||
# Stage 2: Serve the app with a lightweight server
|
||||
FROM nginx:alpine
|
||||
|
||||
# Copy built assets from builder
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
# Copy custom nginx config if needed (optional)
|
||||
# COPY nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Start nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
12
web/index.html
Normal file
12
web/index.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/icon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>DD Multitool</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
1044
web/package-lock.json
generated
Normal file
1044
web/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
web/package.json
Normal file
15
web/package.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "web",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "~5.8.3",
|
||||
"vite": "^7.1.2"
|
||||
}
|
||||
}
|
BIN
web/public/icon.png
Normal file
BIN
web/public/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
96
web/src/style.css
Normal file
96
web/src/style.css
Normal file
@ -0,0 +1,96 @@
|
||||
:root {
|
||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: filter 300ms;
|
||||
}
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
.logo.vanilla:hover {
|
||||
filter: drop-shadow(0 0 2em #3178c6aa);
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.read-the-docs {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
1
web/src/vite-env.d.ts
vendored
Normal file
1
web/src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
23
web/tsconfig.json
Normal file
23
web/tsconfig.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"noImplicitAny": false,
|
||||
"esModuleInterop": true,
|
||||
"strict": false,
|
||||
"allowJs": true,
|
||||
"checkJs": false
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "build"]
|
||||
}
|
Reference in New Issue
Block a user