Compare commits

..

12 Commits

Author SHA1 Message Date
Akiru eaff7c0772 README.md aktualisiert 2024-01-26 13:13:31 +00:00
Akiru 9f75621c70 bot/mod.ts aktualisiert
- Comment logging in "handleWebhook" function
- Handle Errors when setting the Bot commands so that the entire bot doesn't fail when they can't be set due to a temporary error
- Set default configuration for the bot (Job Limit)
2024-01-26 12:54:05 +00:00
Akiru b7a551afc7 api/mod.ts aktualisiert 2024-01-26 07:42:44 +00:00
Akiru c19f8c8f71 bot/mod.ts aktualisiert 2024-01-26 07:40:32 +00:00
Akiru a7e41b63df api/mod.ts aktualisiert
Create "async function handleWebhook"
2024-01-26 07:30:42 +00:00
Akiru 04b0f9bdf5 bot/mod.ts aktualisiert 2024-01-25 09:08:16 +00:00
Akiru 29161fa58a main.ts aktualisiert 2024-01-25 09:01:23 +00:00
Akiru 128c4312d4 ui/StatsPage.tsx aktualisiert
Make the counters update faster to make it look more snappy.
2024-01-25 08:53:35 +00:00
Akiru 85bd9b5861 bot/mod.ts aktualisiert 2024-01-25 08:51:39 +00:00
Akiru aefbc63a46 monitoring/sleepy.sh hinzugefügt 2024-01-25 08:38:14 +00:00
Akiru ffff9c87ef monitoring/monitoring.sh hinzugefügt 2024-01-25 08:35:11 +00:00
Akiru d9ff25e04e monitoring/Readme.md hinzugefügt 2024-01-25 08:31:43 +00:00
12 changed files with 576 additions and 53 deletions

1
.gitignore vendored
View File

@ -1,4 +1,3 @@
.env
*.db
*.db-*
deno.lock

View File

@ -1,17 +1,12 @@
# Eris the Bot
[![Website](https://img.shields.io/website?url=https%3A%2F%2Feris.lisq.eu%2F)](https://eris.lisq.eu/)
![Unique users](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Feris.lisq.eu%2Fapi%2Fstats&query=%24.userCount&label=unique%20users)
![Generated images](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Feris.lisq.eu%2Fapi%2Fstats&query=%24.imageCount&label=images%20generated)
![Processed steps](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Feris.lisq.eu%2Fapi%2Fstats&query=%24.stepCount&label=steps%20processed)
![Painted pixels](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Feris.lisq.eu%2Fapi%2Fstats&query=%24.pixelCount&label=pixels%20painted)
# Nyx the Bot
Fork of Eris the Bot https://eris.lisq.eu
Telegram bot for generating images from text.
## Requirements
- [Deno](https://deno.land/)
- [Stable Diffusion WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui/)
- [Deno](https://deno.land/) (for the bot server)
- [Stable Diffusion WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui/) (for the worker that generates images)
## Options
@ -20,17 +15,23 @@ You can put these in `.env` file or pass them as environment variables.
- `TG_BOT_TOKEN` - Telegram bot token. Get yours from [@BotFather](https://t.me/BotFather).
Required.
- `DENO_KV_PATH` - [Deno KV](https://deno.land/api?s=Deno.openKv&unstable) database file path. A
temporary file is used by default.
temporary file is used by default. Example: /opt/data/botdata.kv
- `LOG_LEVEL` - [Log level](https://deno.land/std@0.201.0/log/mod.ts?s=LogLevels). Default: `INFO`.
## Running
1. Start Eris: `deno task start`
2. Visit [Eris WebUI](http://localhost:5999/) and login via Telegram.
2. Visit [Eris WebUI](http://localhost:8443/) and login via Telegram.
3. Promote yourself to admin in the Eris WebUI.
4. Start Stable Diffusion WebUI: `./webui.sh --api` (in SD WebUI directory)
5. Add a new worker in the Eris WebUI.
## This fork requires the use of webhooks.
1. You need a reverse Proxy and HTTPS certificate set up that proxies all requests from a domain on port 443 (e.g. nyx.akiru.de) to the backend of this bot (:8443).
2. Change the Webhook URL to your own one in /mod/bot.ts - There are also console log statements you can uncomment for troubleshooting.
3. Make sure the DNS and firewall are set up for the webhook to be reachable, because otherwise the bot fails to start.
## Codegen
The Stable Diffusion API types are auto-generated. To regenerate them, first start your SD WebUI
@ -38,8 +39,8 @@ with `--nowebui --api`, and then run `deno task generate`
## Project structure
- `/api` - Eris API served at `http://localhost:5999/api/`.
- `/api` - Eris API served at `http://localhost:8443/api/`.
- `/app` - Queue handling and other core processes.
- `/bot` - Handling bot commands and other updates from Telegram API.
- `/ui` - Eris WebUI frontend files served at `http://localhost:5999/`.
- `/ui` - Eris WebUI frontend files served at `http://localhost:8443/`.
- `/util` - Utility functions shared by other parts.

View File

@ -2,11 +2,15 @@ import { route } from "reroute";
import { serveSpa } from "serve_spa";
import { api } from "./serveApi.ts";
import { fromFileUrl } from "std/path/mod.ts";
// New function that handles the webhook
import { handleWebhook } from "../bot/mod.ts";
export async function serveUi() {
const server = Deno.serve({ port: 5999 }, (request) =>
const server = Deno.serve({ port: 8443 }, (request) =>
route(request, {
"/api/*": (request) => api.fetch(request),
"/webhook": handleWebhook, // Create the webhook route handle
"/*": (request) =>
serveSpa(request, {
fsRoot: fromFileUrl(new URL("../ui/", import.meta.url)),

View File

@ -4,7 +4,7 @@ import { JobData, Queue, Worker } from "kvmq";
import createOpenApiClient from "openapi_fetch";
import { delay } from "std/async/delay.ts";
import { decode, encode } from "std/encoding/base64.ts";
import { debug, error, info } from "std/log/mod.ts";
import { debug, error, info, warning } from "std/log/mod.ts";
import { ulid } from "ulid";
import { bot } from "../bot/mod.ts";
import { PngInfo } from "../bot/parsePngInfo.ts";
@ -46,7 +46,7 @@ export const activeGenerationWorkers = new Map<string, Worker<GenerationJob>>();
/**
* Initializes queue workers for each SD instance when they become online.
*/
export async function processGenerationQueue(): Promise<never> {
export async function processGenerationQueue() {
while (true) {
for await (const workerInstance of workerInstanceStore.listAll()) {
const activeWorker = activeGenerationWorkers.get(workerInstance.id);
@ -142,6 +142,15 @@ async function processGenerationJob(
debug(`Generation started for ${formatUserChat(state)}`);
await updateJob({ state: state });
// check if bot can post messages in this chat
const chat = await bot.api.getChat(state.chat.id);
if (
(chat.type === "group" || chat.type === "supergroup") &&
(!chat.permissions?.can_send_messages || !chat.permissions?.can_send_photos)
) {
throw new Error("Bot doesn't have permissions to send photos in this chat");
}
// edit the existing status message
await bot.api.editMessageText(
state.replyMessage.chat.id,
@ -303,25 +312,34 @@ async function processGenerationJob(
/**
* Handles queue updates and updates the status message.
*/
export async function updateGenerationQueue(): Promise<never> {
export async function updateGenerationQueue() {
while (true) {
const jobs = await generationQueue.getAllJobs();
await Promise.all(jobs.map(async (job) => {
const editedMessages = await Promise.all(jobs.map(async (job) => {
if (job.status === "processing") {
// if the job is processing, the worker will update its status message
return;
}
// spread the updates in time randomly
await delay(Math.random() * 3_000);
return await bot.api.editMessageText(
job.state.replyMessage.chat.id,
job.state.replyMessage.message_id,
`You are ${formatOrdinal(job.place)} in queue.`,
{ maxAttempts: 1 },
).catch(() => {});
).then(() => true).catch(() => false);
}));
// delay between updates based on the number of jobs
await delay(Math.min(15_000, Math.max(3_000, jobs.length * 100)));
const erroredMessages = editedMessages.filter((ok) => !ok);
if (erroredMessages.length > 0) {
warning(
`Updating queue status failed for ${erroredMessages.length} / ${editedMessages.length} jobs`,
);
}
await delay(10_000);
}
}

View File

@ -1,7 +1,7 @@
import { Api, Bot, Context, RawApi, session, SessionFlavor } from "grammy";
import { FileFlavor, hydrateFiles } from "grammy_files";
import { hydrateReply, ParseModeFlavor } from "grammy_parse_mode";
import { run, sequentialize } from "grammy_runner";
import { sequentialize } from "grammy_runner";
import { error, info, warning } from "std/log/mod.ts";
import { sessions } from "../api/sessionsRoute.ts";
import { formatUserChat } from "../utils/formatUserChat.ts";
@ -12,6 +12,16 @@ import { img2imgCommand, img2imgQuestion } from "./img2imgCommand.ts";
import { pnginfoCommand, pnginfoQuestion } from "./pnginfoCommand.ts";
import { queueCommand } from "./queueCommand.ts";
import { txt2imgCommand, txt2imgQuestion } from "./txt2imgCommand.ts";
import { setConfig, getConfig } from "../app/config.ts";
// Set the new configuration
await setConfig({ maxUserJobs: 1, maxJobs: 500 });
// Fetch the updated configuration
const updatedConfig = await getConfig();
// Log the updated configuration to the console
console.log("Updated Configuration:", updatedConfig);
interface SessionData {
chat: ErisChatData;
@ -107,18 +117,38 @@ bot.use(async (ctx, next) => {
}
});
bot.api.setMyShortDescription("I can generate furry images from text");
bot.api.setMyDescription(
"I can generate furry images from text. " +
"Send /txt2img to generate an image.",
);
bot.api.setMyCommands([
{ command: "txt2img", description: "Generate image from text" },
{ command: "img2img", description: "Generate image from image" },
{ command: "pnginfo", description: "Try to extract prompt from raw file" },
{ command: "queue", description: "Show the current queue" },
{ command: "cancel", description: "Cancel all your requests" },
]);
// Wrap the calls in try-catch for error handling
async function setupBotCommands() {
try {
await bot.api.setMyShortDescription("Generate furry images in '704x704', '576x832', '832x576'. https://ko-fi.com/nyxthebot https://nyx.akiru.de/");
} catch (err) {
error(`Failed to set short description: ${err.message}`);
}
try {
await bot.api.setMyDescription(
"I can generate furry images from text. If you want a different size, use 'Size: 576x832' for example." +
"Send /txt2img to generate an image.",
);
} catch (err) {
error(`Failed to set description: ${err.message}`);
}
try {
await bot.api.setMyCommands([
{ command: "txt2img", description: "Generate image from text" },
{ command: "img2img", description: "Generate image from image" },
{ command: "pnginfo", description: "Try to extract prompt from raw file" },
{ command: "queue", description: "Show the current queue" },
{ command: "cancel", description: "Cancel all your requests" },
]);
} catch (err) {
error(`Failed to set commands: ${err.message}`);
}
}
// Call the setup function
setupBotCommands();
bot.command("start", async (ctx) => {
if (ctx.match) {
@ -173,7 +203,26 @@ bot.command("crash", () => {
throw new Error("Crash command used");
});
export async function runBot() {
const runner = run(bot, { runner: { silent: true } });
await runner.task();
// Set up the webhook in the telegram API and initialize the bot
await bot.api.setWebhook('https://nyx.akiru.de/webhook');
await bot.init();
// Function to handle incoming webhook requests
export async function handleWebhook(req: Request): Promise<Response> {
try {
const body = await req.json();
// console.log("Received webhook data:", JSON.stringify(body, null, 2));
// Log before processing update
// console.log("Processing update through handleUpdate...");
await bot.handleUpdate(body); // Process the update
// Log after processing update
// console.log("Update processed successfully.");
return new Response(JSON.stringify({ status: 'ok' }), { headers: { 'Content-Type': 'application/json' } });
} catch (error) {
// Detailed error logging
console.error("Error in handleWebhook:", error);
return new Response("Error", { status: 500 });
}
}

View File

@ -55,9 +55,9 @@
}
},
"tasks": {
"check": "deno check --unstable-kv main.ts && deno check --unstable-kv ui/main.tsx",
"check": "deno check --unstable main.ts && deno check --unstable ui/main.tsx",
"generate": "deno run npm:openapi-typescript http://localhost:7861/openapi.json -o app/sdApi.ts",
"start": "deno run --unstable-kv --allow-env --allow-read=. --allow-write=db --allow-net main.ts",
"test": "deno test"
"start": "deno run --unstable --allow-env --allow-read --allow-write --allow-net main.ts",
"test": "deno test --unstable"
}
}

389
deno.lock Normal file
View File

@ -0,0 +1,389 @@
{
"version": "3",
"packages": {
"specifiers": {
"npm:@types/node": "npm:@types/node@18.16.19"
},
"npm": {
"@types/node@18.16.19": {
"integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==",
"dependencies": {}
}
}
},
"redirects": {
"https://cdn.skypack.dev/-/@date-fns/utc@v1.1.0-EKCmNY9452DyFBJfVVmZ/dist=es2019,mode=types/date.d.ts": "https://cdn.skypack.dev/-/@date-fns/utc@v1.1.0-EKCmNY9452DyFBJfVVmZ/dist=es2019,mode=types/date/index.d.ts",
"https://esm.sh/@grammyjs/types@2": "https://esm.sh/@grammyjs/types@2.12.1",
"https://esm.sh/@grammyjs/types@v2": "https://esm.sh/@grammyjs/types@2.0.0",
"https://esm.sh/@swc/core@1.2.212/types.d.ts": "https://esm.sh/v133/@swc/core@1.2.212/types.d.ts",
"https://esm.sh/telegram-format@2": "https://esm.sh/telegram-format@2.1.0",
"https://esm.sh/v128/@types/react@~18.2/index.d.ts": "https://esm.sh/v128/@types/react@18.2.25/index.d.ts",
"https://esm.sh/v133/@types/png-chunk-text@~1.0/index.d.ts": "https://esm.sh/v133/@types/png-chunk-text@1.0.2/index.d.ts",
"https://esm.sh/v133/@types/png-chunks-extract@~1.0/index.d.ts": "https://esm.sh/v133/@types/png-chunks-extract@1.0.1/index.d.ts",
"https://esm.sh/v133/@types/react-dom@~18.2/X-ZS9yZWFjdA/client~.d.ts": "https://esm.sh/v133/@types/react-dom@18.2.14/X-ZS9yZWFjdA/client~.d.ts",
"https://lib.deno.dev/x/grammy@1/mod.ts": "https://deno.land/x/grammy@v1.19.2/mod.ts",
"https://lib.deno.dev/x/grammy@^1.0/mod.ts": "https://deno.land/x/grammy@v1.19.2/mod.ts",
"https://lib.deno.dev/x/grammy@v1/mod.ts": "https://deno.land/x/grammy@v1.19.2/mod.ts",
"https://lib.deno.dev/x/grammy@v1/types.ts": "https://deno.land/x/grammy@v1.19.2/types.ts",
"https://lib.deno.dev/x/grammy_files@1/mod.ts": "https://deno.land/x/grammy_files@v1.0.4/mod.ts",
"https://lib.deno.dev/x/grammy_parse_mode@1/mod.ts": "https://deno.land/x/grammy_parse_mode@1.8.1/mod.ts",
"https://lib.deno.dev/x/grammy_runner@2/mod.ts": "https://deno.land/x/grammy_runner@v2.0.3/mod.ts",
"https://lib.deno.dev/x/grammy_stateless_question_alpha@3/mod.ts": "https://deno.land/x/grammy_stateless_question_alpha@v3.0.5/mod.ts",
"https://lib.deno.dev/x/grammy_types@3/mod.ts": "https://deno.land/x/grammy_types@v3.3.0/mod.ts"
},
"remote": {
"https://cdn.skypack.dev/-/@date-fns/utc@v1.1.0-EKCmNY9452DyFBJfVVmZ/dist=es2019,mode=imports/optimized/@date-fns/utc.js": "f3566d499010a4872640fc2c5f539e98d490d794f43e597a2da9aadf03b2c050",
"https://cdn.skypack.dev/-/@date-fns/utc@v1.1.0-EKCmNY9452DyFBJfVVmZ/dist=es2019,mode=imports/optimized/@date-fns/utc/date.js": "bd4ef50c3a846971a4b001bfdbfee22e9b523a4faaaa776c1001b5c8b450a025",
"https://cdn.skypack.dev/-/@date-fns/utc@v1.1.0-EKCmNY9452DyFBJfVVmZ/dist=es2019,mode=imports/optimized/@date-fns/utc/date/mini.js": "2d7a4c546f921006542c2f83b76a5d1a94c670f9c885382d998054f627aadd5a",
"https://cdn.skypack.dev/-/date-fns@v2.30.0-E7SpvwCL3wRUK0Q9mmOa/dist=es2019,mode=imports/optimized/date-fns.js": "9e81dde88a23d207bf9c40c8350525c9115eeede74000c9f94fcd4a65ce64865",
"https://cdn.skypack.dev/-/debug@v4.3.4-o4liVvMlOnQWbLSYZMXw/dist=es2019,mode=imports/optimized/debug.js": "671100993996e39b501301a87000607916d4d2d9f8fc8e9c5200ae5ba64a1389",
"https://cdn.skypack.dev/-/ms@v2.1.2-giBDZ1IA5lmQ3ZXaa87V/dist=es2019,mode=imports/optimized/ms.js": "fd88e2d51900437011f1ad232f3393ce97db1b87a7844b3c58dd6d65562c1276",
"https://cdn.skypack.dev/@date-fns/utc@1.1.0?dts": "9fafa18de74e61386a79482ca58b766c0be1f8fd10bdc931ef26bd4b8cdac91e",
"https://cdn.skypack.dev/date-fns@2.30.0?dts": "9cf78eb65f86f7b699e241a1e0ff94f3878d693e517e21ddc7fe727e3b479058",
"https://cdn.skypack.dev/debug@4.3.4": "7b1d010cc930f71b940ba5941da055bc181115229e29de7214bdb4425c68ea76",
"https://deno.land/std@0.135.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74",
"https://deno.land/std@0.135.0/_util/os.ts": "49b92edea1e82ba295ec946de8ffd956ed123e2948d9bd1d3e901b04e4307617",
"https://deno.land/std@0.135.0/bytes/bytes_list.ts": "67eb118e0b7891d2f389dad4add35856f4ad5faab46318ff99653456c23b025d",
"https://deno.land/std@0.135.0/bytes/equals.ts": "a60ef9f01fb6e06a4e0343fc44d53d39d12dd66bc3f09ac8e6eb9cc1a6335e48",
"https://deno.land/std@0.135.0/bytes/mod.ts": "4cef6fe8f0de217b9babbcbb0a566402b667f18a8e6d094a45e5fb3fc1afff70",
"https://deno.land/std@0.135.0/fmt/colors.ts": "30455035d6d728394781c10755351742dd731e3db6771b1843f9b9e490104d37",
"https://deno.land/std@0.135.0/io/buffer.ts": "bd0c4bf53db4b4be916ca5963e454bddfd3fcd45039041ea161dbf826817822b",
"https://deno.land/std@0.135.0/io/files.ts": "d199ef64e918a256320ba8d8d44ae91de87c9077df8f8d6cca013f1b9fbbe285",
"https://deno.land/std@0.135.0/io/mod.ts": "1a4e8d19d42745fb2ff68d6ffa801657a4a15713bf7e7173df2da4737f5c5450",
"https://deno.land/std@0.135.0/io/readers.ts": "15062a8863e6df8503ac6629924d04c5e65cf3da15997470525e705831a810c8",
"https://deno.land/std@0.135.0/io/streams.ts": "988a19155b52161f0035ce539e2f1d12edbc4c389fa7633da832a64e6edbe1a0",
"https://deno.land/std@0.135.0/io/util.ts": "078da53bba767bec0d45f7da44411f6dbf269e51ef7fcfea5e3714e04681c674",
"https://deno.land/std@0.135.0/io/writers.ts": "5db9995d2afc7ed391c88c6b441457df6fad6a0b09653e54c1dcd0387ab947fd",
"https://deno.land/std@0.135.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3",
"https://deno.land/std@0.135.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09",
"https://deno.land/std@0.135.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b",
"https://deno.land/std@0.135.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633",
"https://deno.land/std@0.135.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee",
"https://deno.land/std@0.135.0/path/mod.ts": "4275129bb766f0e475ecc5246aa35689eeade419d72a48355203f31802640be7",
"https://deno.land/std@0.135.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44",
"https://deno.land/std@0.135.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9",
"https://deno.land/std@0.135.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757",
"https://deno.land/std@0.135.0/streams/conversion.ts": "712585bfa0172a97fb68dd46e784ae8ad59d11b88079d6a4ab098ff42e697d21",
"https://deno.land/std@0.135.0/testing/_diff.ts": "9d849cd6877694152e01775b2d93f9d6b7aef7e24bfe3bfafc4d7a1ac8e9f392",
"https://deno.land/std@0.135.0/testing/asserts.ts": "b0ef969032882b1f7eb1c7571e313214baa1485f7b61cf35807b2434e254365c",
"https://deno.land/std@0.186.0/async/deferred.ts": "42790112f36a75a57db4a96d33974a936deb7b04d25c6084a9fa8a49f135def8",
"https://deno.land/std@0.201.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee",
"https://deno.land/std@0.201.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56",
"https://deno.land/std@0.201.0/async/abortable.ts": "fd682fa46f3b7b16b4606a5ab52a7ce309434b76f820d3221bdfb862719a15d7",
"https://deno.land/std@0.201.0/async/deadline.ts": "58f72a3cc0fcb731b2cc055ba046f4b5be3349ff6bf98f2e793c3b969354aab2",
"https://deno.land/std@0.201.0/async/debounce.ts": "adab11d04ca38d699444ac8a9d9856b4155e8dda2afd07ce78276c01ea5a4332",
"https://deno.land/std@0.201.0/async/deferred.ts": "42790112f36a75a57db4a96d33974a936deb7b04d25c6084a9fa8a49f135def8",
"https://deno.land/std@0.201.0/async/delay.ts": "a6142eb44cdd856b645086af2b811b1fcce08ec06bb7d50969e6a872ee9b8659",
"https://deno.land/std@0.201.0/async/mod.ts": "f04344fa21738e5ad6bea37a6bfffd57c617c2d372bb9f9dcfd118a1b622e576",
"https://deno.land/std@0.201.0/async/mux_async_iterator.ts": "70c7f2ee4e9466161350473ad61cac0b9f115cff4c552eaa7ef9d50c4cbb4cc9",
"https://deno.land/std@0.201.0/async/pool.ts": "47c1841cfa9c036144943d11747ddd44064f5baf8cb7ece25473ba873c6aceb0",
"https://deno.land/std@0.201.0/async/retry.ts": "296fb9c323e1325a69bee14ba947e7da7409a8dd9dd646d70cb51ea0d301f24e",
"https://deno.land/std@0.201.0/async/tee.ts": "47e42d35f622650b02234d43803d0383a89eb4387e1b83b5a40106d18ae36757",
"https://deno.land/std@0.201.0/bytes/copy.ts": "939d89e302a9761dcf1d9c937c7711174ed74c59eef40a1e4569a05c9de88219",
"https://deno.land/std@0.201.0/dotenv/load.ts": "0636983549b98f29ab75c9a22a42d9723f0a389ece5498fe971e7bb2556a12e2",
"https://deno.land/std@0.201.0/dotenv/mod.ts": "1da8c6d0e7f7d8a5c2b19400b763bc11739df24acec235dda7ea2cfd3d300057",
"https://deno.land/std@0.201.0/fmt/colors.ts": "87544aa2bc91087bb37f9c077970c85bfb041b48e4c37356129d7b450a415b6f",
"https://deno.land/std@0.201.0/fs/exists.ts": "cb59a853d84871d87acab0e7936a4dac11282957f8e195102c5a7acb42546bb8",
"https://deno.land/std@0.201.0/io/buf_writer.ts": "48c33c8f00b61dcbc7958706741cec8e59810bd307bc6a326cbd474fe8346dfd",
"https://deno.land/std@0.201.0/log/handlers.ts": "3a0883f65567f59a9a88e44c972b24b924621bc28ead91af11d7a6da93c4a64c",
"https://deno.land/std@0.201.0/log/levels.ts": "6309147664e9e008cd6671610f2505c4c95f181f6bae4816a84b33e0aec66859",
"https://deno.land/std@0.201.0/log/logger.ts": "180c50a07c43a556dc5794e913c82946399e89d683201d01c8f0091e1e4ae3fc",
"https://deno.land/std@0.201.0/log/mod.ts": "a274d2129c8d08d4c96e0fb165a595e6c730b5130b437a9ce04364156bfe955a",
"https://deno.land/std@0.202.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee",
"https://deno.land/std@0.202.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56",
"https://deno.land/std@0.202.0/bytes/bytes_list.ts": "ecf5098c230b793970f43c06e8f30d70b937c031658365aeb3de9a8ae4d406a3",
"https://deno.land/std@0.202.0/bytes/concat.ts": "d26d6f3d7922e6d663dacfcd357563b7bf4a380ce5b9c2bbe0c8586662f25ce2",
"https://deno.land/std@0.202.0/bytes/copy.ts": "939d89e302a9761dcf1d9c937c7711174ed74c59eef40a1e4569a05c9de88219",
"https://deno.land/std@0.202.0/bytes/ends_with.ts": "4228811ebc71615d27f065c54b5e815ec1972538772b0f413c0efe05245b472e",
"https://deno.land/std@0.202.0/bytes/equals.ts": "fc190cce412b2136979181b163ec7e05f7e7a947e39102eee4b8c0d62519ddf9",
"https://deno.land/std@0.202.0/bytes/includes_needle.ts": "76a8163126fb2f8bf86fd7f22192c3bb04bf6a20b987a095127c2ca08adf3ba6",
"https://deno.land/std@0.202.0/bytes/index_of_needle.ts": "9c06610e9611b5647ac25952e71a22e09227c9f1b8cbeeb33399bf8bf8a7f649",
"https://deno.land/std@0.202.0/bytes/last_index_of_needle.ts": "f1602f221c3b678bc4f1e1c88a70a15ab7da32c21751dbbc6c957c956951d784",
"https://deno.land/std@0.202.0/bytes/mod.ts": "e869bba1e7a2e3a9cc6c2d55471888429a544e70a840c087672e656e7ba21815",
"https://deno.land/std@0.202.0/bytes/repeat.ts": "6f5e490d8d72bcbf8d84a6bb04690b9b3eb5822c5a11687bca73a2318a842294",
"https://deno.land/std@0.202.0/bytes/starts_with.ts": "3e607a70c9c09f5140b7a7f17a695221abcc7244d20af3eb47ccbb63f5885135",
"https://deno.land/std@0.202.0/collections/_utils.ts": "5114abc026ddef71207a79609b984614e66a63a4bda17d819d56b0e72c51527e",
"https://deno.land/std@0.202.0/collections/deep_merge.ts": "9db788ba56cb05b65c77166b789e58e125dff159b7f41bf4d19dc1cba19ecb8b",
"https://deno.land/std@0.202.0/collections/distinct_by.ts": "3afe11d81eafb30c7c9dbf568d94357f3d88153292c00671b72cd695deae6602",
"https://deno.land/std@0.202.0/collections/max_by.ts": "9d5940986aac51b2e4feaebef9cd8bf6e1eceeee5edcf3303e334b737f99520d",
"https://deno.land/std@0.202.0/collections/sort_by.ts": "1207755af756a5da04bebff39146c93cbe54f7870a5d67cf6922e871d96a01d5",
"https://deno.land/std@0.202.0/encoding/base64.ts": "144ae6234c1fbe5b68666c711dc15b1e9ee2aef6d42b3b4345bf9a6c91d70d0d",
"https://deno.land/std@0.202.0/flags/mod.ts": "0948466fc437f017f00c0b972a422b3dc3317a790bcf326429d23182977eaf9f",
"https://deno.land/std@0.202.0/fmt/bytes.ts": "f29cf69e0791d375f9f5d94ae1f0641e5a03b975f32ddf86d70f70fdf37e7b6a",
"https://deno.land/std@0.202.0/fmt/colors.ts": "c51c4642678eb690dcf5ffee5918b675bf01a33fba82acf303701ae1a4f8c8d9",
"https://deno.land/std@0.202.0/fmt/duration.ts": "7e73e2e7aa82013ea5885efd65e331c6b99506b3977bb9edcd2b6745ce3212e0",
"https://deno.land/std@0.202.0/http/etag.ts": "807382795850cde5c437c74bcc09392bc0fc56de348fc1271f383f4b28935b9f",
"https://deno.land/std@0.202.0/http/file_server.ts": "6f5c4a28c36995f31544abb49b86bee6e7a2d34664cac3936ff08ccad1682d85",
"https://deno.land/std@0.202.0/http/http_status.ts": "8a7bcfe3ac025199ad804075385e57f63d055b2aed539d943ccc277616d6f932",
"https://deno.land/std@0.202.0/http/util.ts": "4cf044067febaa26d0830e356b0f3a5f76d701a60d7ff7a516fad7b192f4c3a7",
"https://deno.land/std@0.202.0/media_types/_db.ts": "7606d83e31f23ce1a7968cbaee852810c2cf477903a095696cdc62eaab7ce570",
"https://deno.land/std@0.202.0/media_types/_util.ts": "0879b04cc810ff18d3dcd97d361e03c9dfb29f67d7fc4a9c6c9d387282ef5fe8",
"https://deno.land/std@0.202.0/media_types/content_type.ts": "ad98a5aa2d95f5965b2796072284258710a25e520952376ed432b0937ce743bc",
"https://deno.land/std@0.202.0/media_types/format_media_type.ts": "f5e1073c05526a6f5a516ac5c5587a1abd043bf1039c71cde1166aa4328c8baf",
"https://deno.land/std@0.202.0/media_types/get_charset.ts": "18b88274796fda5d353806bf409eb1d2ddb3f004eb4bd311662c4cdd8ac173db",
"https://deno.land/std@0.202.0/media_types/parse_media_type.ts": "31ccf2388ffab31b49500bb89fa0f5de189c8897e2ee6c9954f207637d488211",
"https://deno.land/std@0.202.0/media_types/type_by_extension.ts": "8c210d4e28ea426414dd8c61146eefbcc7e091a89ccde54bbbe883a154856afd",
"https://deno.land/std@0.202.0/media_types/vendor/mime-db.v1.52.0.ts": "6925bbcae81ca37241e3f55908d0505724358cda3384eaea707773b2c7e99586",
"https://deno.land/std@0.202.0/path/_basename.ts": "057d420c9049821f983f784fd87fa73ac471901fb628920b67972b0f44319343",
"https://deno.land/std@0.202.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
"https://deno.land/std@0.202.0/path/_extname.ts": "eaaa5aae1acf1f03254d681bd6a8ce42a9cb5b7ff2213a9d4740e8ab31283664",
"https://deno.land/std@0.202.0/path/_join.ts": "815f5e85b042285175b1492dd5781240ce126c23bd97bad6b8211fe7129c538e",
"https://deno.land/std@0.202.0/path/_normalize.ts": "a19ec8706b2707f9dd974662a5cd89fad438e62ab1857e08b314a8eb49a34d81",
"https://deno.land/std@0.202.0/path/_os.ts": "30b0c2875f360c9296dbe6b7f2d528f0f9c741cecad2e97f803f5219e91b40a2",
"https://deno.land/std@0.202.0/path/_relative.ts": "27bdeffb5311a47d85be26d37ad1969979359f7636c5cd9fcf05dcd0d5099dc5",
"https://deno.land/std@0.202.0/path/_resolve.ts": "7a3616f1093735ed327e758313b79c3c04ea921808ca5f19ddf240cb68d0adf6",
"https://deno.land/std@0.202.0/path/_util.ts": "4e191b1bac6b3bf0c31aab42e5ca2e01a86ab5a0d2e08b75acf8585047a86221",
"https://deno.land/std@0.202.0/path/basename.ts": "bdfa5a624c6a45564dc6758ef2077f2822978a6dbe77b0a3514f7d1f81362930",
"https://deno.land/std@0.202.0/path/extname.ts": "62c4b376300795342fe1e4746c0de518b4dc9c4b0b4617bfee62a2973a9555cf",
"https://deno.land/std@0.202.0/path/join.ts": "31c5419f23d91655b08ec7aec403f4e4cd1a63d39e28f6e42642ea207c2734f8",
"https://deno.land/std@0.202.0/path/relative.ts": "8bedac226afd360afc45d451a6c29fabceaf32978526bcb38e0c852661f66c61",
"https://deno.land/std@0.202.0/path/resolve.ts": "133161e4949fc97f9ca67988d51376b0f5eef8968a6372325ab84d39d30b80dc",
"https://deno.land/std@0.202.0/path/separator.ts": "40a3e9a4ad10bef23bc2cd6c610291b6c502a06237c2c4cd034a15ca78dedc1f",
"https://deno.land/std@0.202.0/streams/_common.ts": "3b2c1f0287ce2ad51fff4091a7d0f48375c85b0ec341468e76d5ac13bb0014dd",
"https://deno.land/std@0.202.0/streams/byte_slice_stream.ts": "c46d7c74836fc8c1a9acd9fe211cbe1bbaaee1b36087c834fb03af4991135c3a",
"https://deno.land/std@0.202.0/streams/iterate_reader.ts": "3b42d3056c8ccade561f1c7ac22d5e671e745933d9f9168fd3b5913588d911c3",
"https://deno.land/std@0.202.0/version.ts": "a39aa19f482555b66c041c6317bd8ce849401a3b580bd12e80fe0adf647b0ad1",
"https://deno.land/std@0.203.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee",
"https://deno.land/std@0.203.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56",
"https://deno.land/std@0.203.0/flags/mod.ts": "0948466fc437f017f00c0b972a422b3dc3317a790bcf326429d23182977eaf9f",
"https://deno.land/std@0.203.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
"https://deno.land/std@0.203.0/path/_extname.ts": "eaaa5aae1acf1f03254d681bd6a8ce42a9cb5b7ff2213a9d4740e8ab31283664",
"https://deno.land/std@0.203.0/path/_join.ts": "815f5e85b042285175b1492dd5781240ce126c23bd97bad6b8211fe7129c538e",
"https://deno.land/std@0.203.0/path/_normalize.ts": "a19ec8706b2707f9dd974662a5cd89fad438e62ab1857e08b314a8eb49a34d81",
"https://deno.land/std@0.203.0/path/_os.ts": "30b0c2875f360c9296dbe6b7f2d528f0f9c741cecad2e97f803f5219e91b40a2",
"https://deno.land/std@0.203.0/path/_util.ts": "4e191b1bac6b3bf0c31aab42e5ca2e01a86ab5a0d2e08b75acf8585047a86221",
"https://deno.land/std@0.203.0/path/extname.ts": "62c4b376300795342fe1e4746c0de518b4dc9c4b0b4617bfee62a2973a9555cf",
"https://deno.land/std@0.203.0/path/join.ts": "31c5419f23d91655b08ec7aec403f4e4cd1a63d39e28f6e42642ea207c2734f8",
"https://deno.land/std@0.204.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee",
"https://deno.land/std@0.204.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56",
"https://deno.land/std@0.204.0/path/_common/assert_path.ts": "061e4d093d4ba5aebceb2c4da3318bfe3289e868570e9d3a8e327d91c2958946",
"https://deno.land/std@0.204.0/path/_common/basename.ts": "0d978ff818f339cd3b1d09dc914881f4d15617432ae519c1b8fdc09ff8d3789a",
"https://deno.land/std@0.204.0/path/_common/common.ts": "9e4233b2eeb50f8b2ae10ecc2108f58583aea6fd3e8907827020282dc2b76143",
"https://deno.land/std@0.204.0/path/_common/constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
"https://deno.land/std@0.204.0/path/_common/dirname.ts": "2ba7fb4cc9fafb0f38028f434179579ce61d4d9e51296fad22b701c3d3cd7397",
"https://deno.land/std@0.204.0/path/_common/format.ts": "11aa62e316dfbf22c126917f5e03ea5fe2ee707386555a8f513d27ad5756cf96",
"https://deno.land/std@0.204.0/path/_common/from_file_url.ts": "ef1bf3197d2efbf0297a2bdbf3a61d804b18f2bcce45548ae112313ec5be3c22",
"https://deno.land/std@0.204.0/path/_common/glob_to_reg_exp.ts": "5c3c2b79fc2294ec803d102bd9855c451c150021f452046312819fbb6d4dc156",
"https://deno.land/std@0.204.0/path/_common/is_glob.ts": "567dce5c6656bdedfc6b3ee6c0833e1e4db2b8dff6e62148e94a917f289c06ad",
"https://deno.land/std@0.204.0/path/_common/normalize.ts": "2ba7fb4cc9fafb0f38028f434179579ce61d4d9e51296fad22b701c3d3cd7397",
"https://deno.land/std@0.204.0/path/_common/normalize_string.ts": "88c472f28ae49525f9fe82de8c8816d93442d46a30d6bb5063b07ff8a89ff589",
"https://deno.land/std@0.204.0/path/_common/relative.ts": "1af19d787a2a84b8c534cc487424fe101f614982ae4851382c978ab2216186b4",
"https://deno.land/std@0.204.0/path/_common/strip_trailing_separators.ts": "7ffc7c287e97bdeeee31b155828686967f222cd73f9e5780bfe7dfb1b58c6c65",
"https://deno.land/std@0.204.0/path/_common/to_file_url.ts": "a8cdd1633bc9175b7eebd3613266d7c0b6ae0fb0cff24120b6092ac31662f9ae",
"https://deno.land/std@0.204.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
"https://deno.land/std@0.204.0/path/_os.ts": "30b0c2875f360c9296dbe6b7f2d528f0f9c741cecad2e97f803f5219e91b40a2",
"https://deno.land/std@0.204.0/path/basename.ts": "04bb5ef3e86bba8a35603b8f3b69537112cdd19ce64b77f2522006da2977a5f3",
"https://deno.land/std@0.204.0/path/common.ts": "f4d061c7d0b95a65c2a1a52439edec393e906b40f1caf4604c389fae7caa80f5",
"https://deno.land/std@0.204.0/path/dirname.ts": "88a0a71c21debafc4da7a4cd44fd32e899462df458fbca152390887d41c40361",
"https://deno.land/std@0.204.0/path/extname.ts": "2da4e2490f3b48b7121d19fb4c91681a5e11bd6bd99df4f6f47d7a71bb6ecdf2",
"https://deno.land/std@0.204.0/path/format.ts": "3457530cc85d1b4bab175f9ae73998b34fd456c830d01883169af0681b8894fb",
"https://deno.land/std@0.204.0/path/from_file_url.ts": "e7fa233ea1dff9641e8d566153a24d95010110185a6f418dd2e32320926043f8",
"https://deno.land/std@0.204.0/path/glob.ts": "9c77cf47db1d786e2ebf66670824d03fd84ecc7c807cac24441eb9d5cb6a2986",
"https://deno.land/std@0.204.0/path/is_absolute.ts": "67232b41b860571c5b7537f4954c88d86ae2ba45e883ee37d3dec27b74909d13",
"https://deno.land/std@0.204.0/path/join.ts": "98d3d76c819af4a11a81d5ba2dbb319f1ce9d63fc2b615597d4bcfddd4a89a09",
"https://deno.land/std@0.204.0/path/mod.ts": "2d62a0a8b78a60e8e6f485d881bac6b61d58573b11cf585fb7c8fc50d9b20d80",
"https://deno.land/std@0.204.0/path/normalize.ts": "aa95be9a92c7bd4f9dc0ba51e942a1973e2b93d266cd74f5ca751c136d520b66",
"https://deno.land/std@0.204.0/path/parse.ts": "d87ff0deef3fb495bc0d862278ff96da5a06acf0625ca27769fc52ac0d3d6ece",
"https://deno.land/std@0.204.0/path/posix/_util.ts": "ecf49560fedd7dd376c6156cc5565cad97c1abe9824f4417adebc7acc36c93e5",
"https://deno.land/std@0.204.0/path/posix/basename.ts": "a630aeb8fd8e27356b1823b9dedd505e30085015407caa3396332752f6b8406a",
"https://deno.land/std@0.204.0/path/posix/common.ts": "e781d395dc76f6282e3f7dd8de13194abb8b04a82d109593141abc6e95755c8b",
"https://deno.land/std@0.204.0/path/posix/dirname.ts": "f48c9c42cc670803b505478b7ef162c7cfa9d8e751b59d278b2ec59470531472",
"https://deno.land/std@0.204.0/path/posix/extname.ts": "ee7f6571a9c0a37f9218fbf510c440d1685a7c13082c348d701396cc795e0be0",
"https://deno.land/std@0.204.0/path/posix/format.ts": "b94876f77e61bfe1f147d5ccb46a920636cd3cef8be43df330f0052b03875968",
"https://deno.land/std@0.204.0/path/posix/from_file_url.ts": "b97287a83e6407ac27bdf3ab621db3fccbf1c27df0a1b1f20e1e1b5acf38a379",
"https://deno.land/std@0.204.0/path/posix/glob.ts": "86c3f06d1c98303613c74650961c3e24bdb871cde2a97c3ae7f0f6d4abbef445",
"https://deno.land/std@0.204.0/path/posix/is_absolute.ts": "159900a3422d11069d48395568217eb7fc105ceda2683d03d9b7c0f0769e01b8",
"https://deno.land/std@0.204.0/path/posix/join.ts": "0c0d84bdc344876930126640011ec1b888e6facf74153ffad9ef26813aa2a076",
"https://deno.land/std@0.204.0/path/posix/mod.ts": "6bfa8a42d85345b12dbe8571028ca2c62d460b6ef968125e498602b43b6cf6b6",
"https://deno.land/std@0.204.0/path/posix/normalize.ts": "11de90a94ab7148cc46e5a288f7d732aade1d616bc8c862f5560fa18ff987b4b",
"https://deno.land/std@0.204.0/path/posix/parse.ts": "199208f373dd93a792e9c585352bfc73a6293411bed6da6d3bc4f4ef90b04c8e",
"https://deno.land/std@0.204.0/path/posix/relative.ts": "e2f230608b0f083e6deaa06e063943e5accb3320c28aef8d87528fbb7fe6504c",
"https://deno.land/std@0.204.0/path/posix/resolve.ts": "51579d83159d5c719518c9ae50812a63959bbcb7561d79acbdb2c3682236e285",
"https://deno.land/std@0.204.0/path/posix/separator.ts": "0b6573b5f3269a3164d8edc9cefc33a02dd51003731c561008c8bb60220ebac1",
"https://deno.land/std@0.204.0/path/posix/to_file_url.ts": "08d43ea839ee75e9b8b1538376cfe95911070a655cd312bc9a00f88ef14967b6",
"https://deno.land/std@0.204.0/path/posix/to_namespaced_path.ts": "c9228a0e74fd37e76622cd7b142b8416663a9b87db643302fa0926b5a5c83bdc",
"https://deno.land/std@0.204.0/path/relative.ts": "23d45ede8b7ac464a8299663a43488aad6b561414e7cbbe4790775590db6349c",
"https://deno.land/std@0.204.0/path/resolve.ts": "5b184efc87155a0af9fa305ff68a109e28de9aee81fc3e77cd01380f19daf867",
"https://deno.land/std@0.204.0/path/separator.ts": "40a3e9a4ad10bef23bc2cd6c610291b6c502a06237c2c4cd034a15ca78dedc1f",
"https://deno.land/std@0.204.0/path/to_file_url.ts": "edaafa089e0bce386e1b2d47afe7c72e379ff93b28a5829a5885e4b6c626d864",
"https://deno.land/std@0.204.0/path/to_namespaced_path.ts": "cf8734848aac3c7527d1689d2adf82132b1618eff3cc523a775068847416b22a",
"https://deno.land/std@0.204.0/path/windows/_util.ts": "f32b9444554c8863b9b4814025c700492a2b57ff2369d015360970a1b1099d54",
"https://deno.land/std@0.204.0/path/windows/basename.ts": "8a9dbf7353d50afbc5b221af36c02a72c2d1b2b5b9f7c65bf6a5a2a0baf88ad3",
"https://deno.land/std@0.204.0/path/windows/common.ts": "e781d395dc76f6282e3f7dd8de13194abb8b04a82d109593141abc6e95755c8b",
"https://deno.land/std@0.204.0/path/windows/dirname.ts": "5c2aa541384bf0bd9aca821275d2a8690e8238fa846198ef5c7515ce31a01a94",
"https://deno.land/std@0.204.0/path/windows/extname.ts": "07f4fa1b40d06a827446b3e3bcc8d619c5546b079b8ed0c77040bbef716c7614",
"https://deno.land/std@0.204.0/path/windows/format.ts": "343019130d78f172a5c49fdc7e64686a7faf41553268961e7b6c92a6d6548edf",
"https://deno.land/std@0.204.0/path/windows/from_file_url.ts": "d53335c12b0725893d768be3ac6bf0112cc5b639d2deb0171b35988493b46199",
"https://deno.land/std@0.204.0/path/windows/glob.ts": "0286fb89ecd21db5cbf3b6c79e2b87c889b03f1311e66fb769e6b905d4142332",
"https://deno.land/std@0.204.0/path/windows/is_absolute.ts": "245b56b5f355ede8664bd7f080c910a97e2169972d23075554ae14d73722c53c",
"https://deno.land/std@0.204.0/path/windows/join.ts": "e6600bf88edeeef4e2276e155b8de1d5dec0435fd526ba2dc4d37986b2882f16",
"https://deno.land/std@0.204.0/path/windows/mod.ts": "c3d1a36fbf9f6db1320bcb4fbda8de011d25461be3497105e15cbea1e3726198",
"https://deno.land/std@0.204.0/path/windows/normalize.ts": "9deebbf40c81ef540b7b945d4ccd7a6a2c5a5992f791e6d3377043031e164e69",
"https://deno.land/std@0.204.0/path/windows/parse.ts": "120faf778fe1f22056f33ded069b68e12447668fcfa19540c0129561428d3ae5",
"https://deno.land/std@0.204.0/path/windows/relative.ts": "026855cd2c36c8f28f1df3c6fbd8f2449a2aa21f48797a74700c5d872b86d649",
"https://deno.land/std@0.204.0/path/windows/resolve.ts": "5ff441ab18a2346abadf778121128ee71bda4d0898513d4639a6ca04edca366b",
"https://deno.land/std@0.204.0/path/windows/separator.ts": "ae21f27015f10510ed1ac4a0ba9c4c9c967cbdd9d9e776a3e4967553c397bd5d",
"https://deno.land/std@0.204.0/path/windows/to_file_url.ts": "8e9ea9e1ff364aa06fa72999204229952d0a279dbb876b7b838b2b2fea55cce3",
"https://deno.land/std@0.204.0/path/windows/to_namespaced_path.ts": "e0f4d4a5e77f28a5708c1a33ff24360f35637ba6d8f103d19661255ef7bfd50d",
"https://deno.land/x/async@v2.0.2/barrier.ts": "e5d35a8c565be07b5bd02ea8861745f57cd707fe72ba54eca34948ffe28495d7",
"https://deno.land/x/async@v2.0.2/lock.ts": "fd7dc5b54c72d0093072adddb1691e1ae4a801c55b2015589454ea60f1c59adb",
"https://deno.land/x/async@v2.0.2/mod.ts": "0671efa8602fe6a6c73caa84d4619b797c1fe0572e31cd78905045ee58c2a6ee",
"https://deno.land/x/async@v2.0.2/mutex.ts": "312dcad7468c82f84fd018be157df451361ed19bdc12fd59af8d12b2e6c3ae28",
"https://deno.land/x/async@v2.0.2/notify.ts": "3127ab5835c97527fdf978a5ec5844d71a2fd62a75988db6f175aac6f61259d0",
"https://deno.land/x/async@v2.0.2/queue.ts": "4df05fbaf376d37379224b68b2b8506a45be835f799139437e7bfc143db5127f",
"https://deno.land/x/async@v2.0.2/rw_lock.ts": "ea7a8cf2ee87c21d3fcbb44f2d654f28a06bf71d5ba7a930f04e5619cc4c82fb",
"https://deno.land/x/async@v2.0.2/semaphore.ts": "16aca813bc0f9ffed4eb15134271fb677407a6245d1f803294219a607940d636",
"https://deno.land/x/async@v2.0.2/stack.ts": "e24ebcbdcab032783e6b278b938475c221fbfb86f8eb71d3752679fcdf132d42",
"https://deno.land/x/async@v2.0.2/state.ts": "a71692b72371239120b196d0c6a249631bab867dd499e85c422c2e5ec9695999",
"https://deno.land/x/async@v2.0.2/testutil.ts": "c4b4092066ad6f24cf84012781831ff188e656a1e81abf31b0f712d2e1ad07b7",
"https://deno.land/x/grammy@v1.19.2/bot.ts": "8d13cd72f1512e3f76d685131c7d0db5ba51f2c877db5ac2c0aa4b0f6f876aa8",
"https://deno.land/x/grammy@v1.19.2/composer.ts": "8660f86990f4ef2afc4854a1f2610bb8d60f88116f3a57c8e5515a77b277f82d",
"https://deno.land/x/grammy@v1.19.2/context.ts": "4cf51ed7538750edb4379f757f6b8b3c1f3987242d58393160b463c9ca13c997",
"https://deno.land/x/grammy@v1.19.2/convenience/constants.ts": "3be0f6393ab2b2995fad6bcd4c9cf8a1a615ae4543fc864c107ba0dd38f123f6",
"https://deno.land/x/grammy@v1.19.2/convenience/frameworks.ts": "77e2f9fc841ab92d4310b556126447a42f131ad976a6adfff454c016f339b28e",
"https://deno.land/x/grammy@v1.19.2/convenience/inline_query.ts": "409d1940c7670708064efa495003bcbfdf6763a756b2e6303c464489fd3394ff",
"https://deno.land/x/grammy@v1.19.2/convenience/input_media.ts": "7af72a5fdb1af0417e31b1327003f536ddfdf64e06ab8bc7f5da6b574de38658",
"https://deno.land/x/grammy@v1.19.2/convenience/keyboard.ts": "21220dc2321c40203c699fa4eb7b07ed8217956ea0477c241a551224a58a278d",
"https://deno.land/x/grammy@v1.19.2/convenience/session.ts": "f92d57b6b2b61920912cf5c44d4db2f6ca999fe4f9adef170c321889d49667c2",
"https://deno.land/x/grammy@v1.19.2/convenience/webhook.ts": "f1da7d6426171fb7b5d5f6b59633f91d3bab9a474eea821f714932650965eb9e",
"https://deno.land/x/grammy@v1.19.2/core/api.ts": "7d4d8df3567e322ab3b793360ee48da09f46ad531ef994a87b3e6aef4ec23bf2",
"https://deno.land/x/grammy@v1.19.2/core/client.ts": "39639e4f5fc3a3f9d528c6906d7e3cdc268cf5d33929eeab801bb39642a59103",
"https://deno.land/x/grammy@v1.19.2/core/error.ts": "4638b2127ebe60249c78b83011d468f5e1e1a87748d32fe11a8200d9f824ad13",
"https://deno.land/x/grammy@v1.19.2/core/payload.ts": "420e17c3c2830b5576ea187cfce77578fe09f1204b25c25ea2f220ca7c86e73b",
"https://deno.land/x/grammy@v1.19.2/filter.ts": "201ddac882ab6cd46cae2d18eb8097460dfe7cedadaab2ba16959c5286d5a5f1",
"https://deno.land/x/grammy@v1.19.2/mod.ts": "b81cccf69779667b36bef5d0373d1567684917a3b9827873f3de7a7e6af1926f",
"https://deno.land/x/grammy@v1.19.2/platform.deno.ts": "84735643c8dde2cf8af5ac2e6b8eb0768452260878da93238d673cb1b4ccea55",
"https://deno.land/x/grammy@v1.19.2/types.deno.ts": "0f47eacde6d3d65f107f2abf16ecfe726298d30263367cc82e977c801b766229",
"https://deno.land/x/grammy@v1.19.2/types.ts": "729415590dfa188dbe924dea614dff4e976babdbabb28a307b869fc25777cdf0",
"https://deno.land/x/grammy_files@v1.0.4/deps.deno.ts": "ec398579e7a7f69788fc3c3ef90202bc9e031e13bfbd90ee37c88a655b6742ef",
"https://deno.land/x/grammy_files@v1.0.4/files.ts": "c69a4cfdcf5b75f32b9de97c36e2b197fe9d60feb360b71e89dff5ae22ba1114",
"https://deno.land/x/grammy_files@v1.0.4/mod.ts": "379c5f64594cd879653cdce715c318b3eed29ab26e071f356b9b61f9e3943bc3",
"https://deno.land/x/grammy_files@v1.0.4/plugin.ts": "a804b76d4ceaae727b874bb6c88bd7a7b16d086992aae04e23f24e0e4fccd3ab",
"https://deno.land/x/grammy_parse_mode@1.8.1/deps.deno.ts": "5297e947875ce8ea523e237bbbfa1eb7c709ed8d76dbeeb8d1a5128182a6753b",
"https://deno.land/x/grammy_parse_mode@1.8.1/format.ts": "570be2b4ba5d4122d4c69f6fae3d507f5a2aa4f6177501d8769f3bbc5e6c77ff",
"https://deno.land/x/grammy_parse_mode@1.8.1/hydrate.ts": "58e6887ede8319b6f4001bc3e007130c09ba40ca7eaada1387c77a510c9e6b6c",
"https://deno.land/x/grammy_parse_mode@1.8.1/mod.ts": "58b539ea91fa72c1fd66dd5415b6c4b63104301b07d9daf860bd66343db7062c",
"https://deno.land/x/grammy_parse_mode@1.8.1/transformer.ts": "794d49c27e62b024d3733759aaafab9043fcdacd4fe53a8d7d4703b39f4f049e",
"https://deno.land/x/grammy_runner@v2.0.3/deps.deno.ts": "bbbaffd1020e0c91acacf02fbc43cdaee04f1d63446cb6a42255d36a0c0e86d4",
"https://deno.land/x/grammy_runner@v2.0.3/distribute.ts": "318ed928c437ce0a09956abfa40c0b937bb507dc276bc3db5d571e15a4d1ede1",
"https://deno.land/x/grammy_runner@v2.0.3/mod.ts": "53c08b39527b0b47ffdf4c5996bc3cfbac802ab37074a7b900b2a63d3db273d3",
"https://deno.land/x/grammy_runner@v2.0.3/platform.deno.ts": "5990d453979176708af79baea54ba2bc4bdc662079f088ce7668b9f4d1962b8c",
"https://deno.land/x/grammy_runner@v2.0.3/queue.ts": "d715f98096405c558c2657ef245b5acd1b5de916eed39dbad1399db18e57e0f7",
"https://deno.land/x/grammy_runner@v2.0.3/runner.ts": "2600b9bd39e724d5c629c94e541f497868dfde6cf55be7745dc1d777c8a8b180",
"https://deno.land/x/grammy_runner@v2.0.3/sequentialize.ts": "137764a109ff3fe4bc8809b6d1d8865ed5c2ad8b649e7553b10302d70bf2e7fb",
"https://deno.land/x/grammy_runner@v2.0.3/sink.ts": "4c0acb814dee97ffffaea145413b53ccf64c0b00f105b0993383f25111ed8702",
"https://deno.land/x/grammy_runner@v2.0.3/source.ts": "68ce5aefa92205db4710c8ac313e0c8e8c2577dd1b88f350b32ee33549188d01",
"https://deno.land/x/grammy_runner@v2.0.3/worker.ts": "b6f88b9fde15a8dd892c8d4781e8010ef37b80faf04d6ad18db4a43e4faa42ad",
"https://deno.land/x/grammy_stateless_question_alpha@v3.0.5/mod.ts": "2c634ee172fa86da8581ccee02eb43a1af5f377837ee78668dd6dbea446038ab",
"https://deno.land/x/grammy_stateless_question_alpha@v3.0.5/source/deps.ts": "05a3cae17af42ec058729e14cc544f22eae8bde4792dab652f7a452a00e91301",
"https://deno.land/x/grammy_stateless_question_alpha@v3.0.5/source/identifier.ts": "162971fdfa5d48484c4db6ce664d60af27affb5e0bfdab41c065200332b30226",
"https://deno.land/x/grammy_stateless_question_alpha@v3.0.5/source/index.ts": "b3272436230d7f19f1e9ee515c52e03bbd20ff6963da9b4076d4d3e6935d969d",
"https://deno.land/x/grammy_types@v3.3.0/api.ts": "efc90a31eb6f59ae5e7a4cf5838f46529e2fa6fa7e97a51a82dbd28afad21592",
"https://deno.land/x/grammy_types@v3.3.0/inline.ts": "b5669d79f8c0c6f7d6ca856d548c1ac7d490efd54ee785d18a7c4fc12abfd73b",
"https://deno.land/x/grammy_types@v3.3.0/manage.ts": "e39ec87e74469f70f35aa51dc520b02136ea5e75f9d7a7e0e513846a00b63fd2",
"https://deno.land/x/grammy_types@v3.3.0/markup.ts": "7b547b79130a112f98fbd3f0f754c8bb926f7cab3040d244b5f597aea0e1ce09",
"https://deno.land/x/grammy_types@v3.3.0/message.ts": "e78a7797174c537bb8de80597e265121615fa36a531dd88ac5af27aa68779172",
"https://deno.land/x/grammy_types@v3.3.0/methods.ts": "7547cedfec2c2727b30b8fa38050aee6642c56673b21cfd0ac56b0e531f02795",
"https://deno.land/x/grammy_types@v3.3.0/mod.ts": "7b5f421b4fbb1761f7f0d68328eaddd515f3222ce3f3cdfbedd8d5a4781e91a7",
"https://deno.land/x/grammy_types@v3.3.0/passport.ts": "e3fb63aec96510bcc317ef48fd25b435444b8f407502d7568c00fce15f2958fd",
"https://deno.land/x/grammy_types@v3.3.0/payment.ts": "d23e9038c5b479b606e620dd84e3e67b6642ada110a962f2d5b5286e99ec7de5",
"https://deno.land/x/grammy_types@v3.3.0/settings.ts": "5e989f5bd6c587d55673bd8052293869aa2f372e9223dd7f6e28632bfe021b6e",
"https://deno.land/x/grammy_types@v3.3.0/update.ts": "6d5ec6d1f6d2acf021f807f6bbf7d541487f30672cfab4700e7f935a490c3b78",
"https://deno.land/x/indexed_kv@v0.6.1/mod.ts": "6acc28873c392c69eea7be8c70978f1973919dec5ca6c04d91d2221bbaa767f8",
"https://deno.land/x/kvfs@v0.1.0/mod.ts": "ceb4c28a6ed850f2fe40bf2349fc8564406811349c7dd6be615db3f098b0790e",
"https://deno.land/x/kvmq@v0.3.0/mod.ts": "ce39abbef6a8f0c25a9141dcac82ef165d4ad74a78289eace7bb168bbc645806",
"https://deno.land/x/lz4@v0.1.2/mod.ts": "4decfc1a3569d03fd1813bd39128b71c8f082850fe98ecfdde20025772916582",
"https://deno.land/x/lz4@v0.1.2/wasm.js": "b9c65605327ba273f0c76a6dc596ec534d4cda0f0225d7a94ebc606782319e46",
"https://deno.land/x/reroute@v0.1.0/mod.ts": "2cce7958e13efc2ef1be800dffe6c7043b96d3e514f35dee9cbf60d05d09d2fd",
"https://deno.land/x/serve_spa@v0.2.0/mod.ts": "3ddf85357324b2dd75721b3614accfa01af9a87c292a85e2ed17a9387665f400",
"https://deno.land/x/swc@0.2.1/lib/deno_swc.generated.js": "a112eb5a4871bcbd5b660d3fd9d7afdd5cf2bb9e135eb9b04aceaa24d16481a0",
"https://deno.land/x/swc@0.2.1/mod.ts": "9e03f5daf4c2a25208e34e19ce3e997d2e23a5a11ee8c8ed58023b0e3626073f",
"https://deno.land/x/ulid@v0.3.0/mod.ts": "f7ff065b66abd485051fc68af23becef6ccc7e81f7774d7fcfd894a4b2da1984",
"https://esm.sh/@elysiajs/eden@0.7.4?external=elysia&dev": "28d477942e36cdeb3e57791a3acc1f52dd16378b1e639693897b21e98d7295e3",
"https://esm.sh/@elysiajs/swagger@0.7.4?dev": "78520881a756f6c3a69ccc1f306bc32e258c6e0e27f971f68231763fbafd303e",
"https://esm.sh/@elysiajs/swagger@0.7.4?external=elysia&dev": "9732dabca93af3dee2ed1781edb740f6e6bdbe88167cc6a03fa42bef3aadd315",
"https://esm.sh/@grammyjs/types@2.0.0": "5e5d1ae9f014cb64f0af36fb91f9d35414d670049b77367818a70cd62092b2ac",
"https://esm.sh/@grammyjs/types@2.12.1": "eebe448d3bf3d4fdaeacee50e31b9e3947ce965d2591f1036e5c0273cb7aec36",
"https://esm.sh/@twind/core@1.1.3": "bf3e64c13de95b061a721831bf2aed322f6e7335848b06d805168c3212686c1d",
"https://esm.sh/@twind/preset-tailwind@1.1.4": "29f5e4774c344ff08d2636e3d86382060a8b40d6bce1c158b803df1823c2804c",
"https://esm.sh/elysia@0.7.21?dev": "6e954350858d5f2fd6c8e61dadf8d9989186f436ccdeb850606359d5e163298c",
"https://esm.sh/exifreader@4.14.1": "d0f21973393b0d1a6ed329dac8fcfb2f87ce47fe40b8172e205e7d6d85790bb6",
"https://esm.sh/file-type@18.5.0": "f01f6eddb05d365925545e26bd449f934dc042bead882b2795c35c4f48d690a3",
"https://esm.sh/openapi-fetch@0.7.6": "43eff6df93e773801cb6ade02b0f47c05d0bfe2fb044adbf2b94fa74ff30d35b",
"https://esm.sh/react-dom@18.2.0/client?external=react&dev": "2eb39c339720d727591fd55fb44ffcb6f14b06812af0a71e7a2268185b5b6e73",
"https://esm.sh/react-flip-move@3.0.5?external=react&dev": "4390c0777a0bec583d3e6cb5e4b33831ac937d670d894a20e4f192ce8cd21bae",
"https://esm.sh/react-intl@6.4.7?external=react&dev": "60e68890e2c5ef3c02d37a89c53e056b1bbd1c8467a7aae62f0b634abc7a8a5f",
"https://esm.sh/react-router-dom@6.16.0?external=react&dev": "16046eba15c1ae1ce912e5ab6fdd1f6ce24ea8ac3970d5bdcdb1ebb0e40458c2",
"https://esm.sh/react@18.2.0?dev": "1fe185734f3d77826efb78a22779899d143bb1160baaf5bbf01edee9f4eaa9d5",
"https://esm.sh/stable/react@18.2.0/denonext/react.development.mjs": "88729b33eccbea2c09894f07459f32911777721a3b50fd32151182e82c4351e2",
"https://esm.sh/swr@2.2.4?external=react&dev": "e96c7c09e01c12fca1d871935973c7264353d8a1a1630fdf38ca1b364936ca66",
"https://esm.sh/telegram-format@2.1.0": "f7302f17a2fbd4ef793b7c065116a2994861904520d54126926bb910836a44b9",
"https://esm.sh/ty-rest@0.4.0/client": "66481393ac52b435a8b6e28d75ac2aaf95460d98a54308b718fe35c8d23e5e84",
"https://esm.sh/ty-rest@0.4.0/server": "14dc9ef120306504751b0faa1e436cd29fb231dae0c2518e1cf564326982c48c",
"https://esm.sh/ty-rest@0.4.1/client": "bb9bf7c41c824920272aeefb9fa62c4a180ef2d56217c02eb16000f928d85013",
"https://esm.sh/ty-rest@0.4.1/server": "9335b9acf42dd3d3e3ffacc6f420eda4805c606d409e6e0a2b724fcddeea8b72",
"https://esm.sh/use-local-storage@3.0.0?external=react&dev": "4cf7fce754a9488940daa76051389421c6341420cae5b8c7d2401158ffe79ec0",
"https://esm.sh/v132/@twind/core@1.1.3/denonext/core.mjs": "c2618087a5d5cc406c7dc1079015f4d7cc874bee167f74e9945694896d907b6d",
"https://esm.sh/v132/@twind/preset-tailwind@1.1.4/denonext/preset-tailwind.mjs": "3cb9f5cde89e11cd2adad54ff264f62f5000ccb1694cd88874b1856eb2d8d7f7",
"https://esm.sh/v133/@elysiajs/swagger@0.7.4/denonext/swagger.development.mjs": "63cc67eee29123918283027744da23009fc3767088c513f8bfbfef945b7170d1",
"https://esm.sh/v133/@formatjs/ecma402-abstract@1.17.2/X-ZS9yZWFjdA/denonext/ecma402-abstract.development.mjs": "178a303e29d73369b4c7c1da5a18393c2baa8742a0e8a45be85f506c17f763d9",
"https://esm.sh/v133/@formatjs/fast-memoize@2.2.0/X-ZS9yZWFjdA/denonext/fast-memoize.development.mjs": "4c027b3308490b65dc899f683b1ff9be8da4b7a2e1e32433ef03bcb8f0fdf821",
"https://esm.sh/v133/@formatjs/icu-messageformat-parser@2.6.2/X-ZS9yZWFjdA/denonext/icu-messageformat-parser.development.mjs": "68c7a9be44aaa3e35bfe18668e17a2d4a465e11f59f3a1e025ee83fe1bd0b971",
"https://esm.sh/v133/@formatjs/icu-skeleton-parser@1.6.2/X-ZS9yZWFjdA/denonext/icu-skeleton-parser.development.mjs": "278cf26f11f5c4027a0bbd503832b162be979d0f4732e3b716760fc5543ecfac",
"https://esm.sh/v133/@formatjs/intl-localematcher@0.4.2/X-ZS9yZWFjdA/denonext/intl-localematcher.development.mjs": "26325e3fc4b1728583a863c46332b6878c377bbb918a39896eb0d9f39eb41357",
"https://esm.sh/v133/@formatjs/intl@2.9.3/X-ZS9yZWFjdA/denonext/intl.development.mjs": "42e7cf0cc4f4c3bca21956caefbd17b64fcb01ac07cb4a36d8a301188dcf1fce",
"https://esm.sh/v133/@grammyjs/types@2.0.0/denonext/types.mjs": "7ee61bd0c55a152ea1ffaf3fbe63fce6c103ae836265b23290284d6ba0e3bc5b",
"https://esm.sh/v133/@grammyjs/types@2.12.1/denonext/types.mjs": "3636f7a1ca7fef89fa735d832b72193a834bc7f5250b6bf182544be53a6ab218",
"https://esm.sh/v133/@remix-run/router@1.9.0/X-ZS9yZWFjdA/denonext/router.development.mjs": "97f96f031a7298b0afbbadb23177559ee9b915314d7adf0b9c6a8d7f452c70e7",
"https://esm.sh/v133/@sinclair/typebox@0.31.22/denonext/compiler.development.js": "94129b8b2f26f79bd1ec51f479776e7cdebe521f60bd2eae695634765959f7b9",
"https://esm.sh/v133/@sinclair/typebox@0.31.22/denonext/system.development.js": "e2c96ea22f15b9e79e8021b65ae62bfd1b4fd94176dd9c8fc1042fa014c64e9e",
"https://esm.sh/v133/@sinclair/typebox@0.31.22/denonext/typebox.development.mjs": "d5776065180eea03471f3f2c992a0cf8289219881c40b68270f543536f5ee029",
"https://esm.sh/v133/@sinclair/typebox@0.31.22/denonext/value.development.js": "41db30d8ba66c836ad5faf931f7ce38d15f943339847b8a7491014f8fe2be451",
"https://esm.sh/v133/client-only@0.0.1/X-ZS9yZWFjdA/denonext/client-only.development.mjs": "b7efaef2653f7f628d084e24a4d5a857c9cd1a5e5060d1d9957e185ee98c8a28",
"https://esm.sh/v133/cookie@0.5.0/denonext/cookie.development.mjs": "04344caac1f8341ced6ec11d15b95a36dbda70a8ebb6a809b20b5912a5de2b8b",
"https://esm.sh/v133/crc-32@0.3.0/denonext/crc-32.mjs": "92bbd96cd5a92e45267cf4b3d3928b9355d16963da1ba740637fb10f1daca590",
"https://esm.sh/v133/elysia@0.7.21/denonext/elysia.development.mjs": "4bf283f62b935737d33ab4e3e59195ba9cb0ea2fc2bac90c8e9fa00a44b5e575",
"https://esm.sh/v133/eventemitter3@5.0.1/denonext/eventemitter3.development.mjs": "e19a3e8d30d7564ce7b394636fc66ef273c6394bb6c5820b9a9bfba7ec4ac2dd",
"https://esm.sh/v133/exifreader@4.14.1/denonext/exifreader.mjs": "691e1c1d1337ccaf092bf39115fdac56bf69e93259d04bb03985e918202317ab",
"https://esm.sh/v133/fast-decode-uri-component@1.0.1/denonext/fast-decode-uri-component.development.mjs": "004912e1f391fccf376cf58ff1ab06d6d4ed241cab9c7bed23756091bedbdc36",
"https://esm.sh/v133/fast-querystring@1.1.2/denonext/fast-querystring.development.mjs": "da06ef49d7e834dbac2b3b189de02c80e71cd5942b339de0011ab84aae0de0ff",
"https://esm.sh/v133/file-type@18.5.0/denonext/file-type.mjs": "785cac1bc363448647871e1b310422e01c9cfb7b817a68690710b786d3598311",
"https://esm.sh/v133/hoist-non-react-statics@3.3.2/X-ZS9yZWFjdA/denonext/hoist-non-react-statics.development.mjs": "fcafac9e3c33810f18ecb43dfc32ce80efc88adc63d3f49fd7ada0665d2146c6",
"https://esm.sh/v133/ieee754@1.2.1/denonext/ieee754.mjs": "9ec2806065f50afcd4cf3f3f2f38d93e777a92a5954dda00d219f57d4b24832f",
"https://esm.sh/v133/inherits@2.0.4/denonext/inherits.mjs": "8095f3d6aea060c904fb24ae50f2882779c0acbe5d56814514c8b5153f3b4b3b",
"https://esm.sh/v133/intl-messageformat@10.5.3/X-ZS9yZWFjdA/denonext/intl-messageformat.development.mjs": "d6b701c562c51ec4b4e1deb641c6623986abe304290bbb291e6404cb6a31dc41",
"https://esm.sh/v133/lodash.clonedeep@4.5.0/denonext/lodash.clonedeep.development.mjs": "f44c863cb41bcd2714103a36d97e8eb8268f56070b5cd56dcfae26c556e6622e",
"https://esm.sh/v133/memoirist@0.1.4/denonext/memoirist.development.mjs": "e19f8379a684345ebcab9a688b0b188f29120f4bf1122588b779113cd1ec0e4e",
"https://esm.sh/v133/openapi-fetch@0.7.6/denonext/openapi-fetch.mjs": "1ec8ed23c9141c7f4e58de06f84525e310fe7dda1aeaf675c8edafb3d8292cfc",
"https://esm.sh/v133/peek-readable@5.0.0/denonext/peek-readable.mjs": "5e799ea86e9c501873f687eda9c891a75ed55ba666b5dd822eaa3d28a8a5f2b1",
"https://esm.sh/v133/png-chunk-text@1.0.0/denonext/png-chunk-text.mjs": "e8bb89595ceab2603531693319da08a9dd90d51169437de47a73cf8bac7baa11",
"https://esm.sh/v133/png-chunks-extract@1.0.0/denonext/png-chunks-extract.mjs": "2a9b62c9478e2bb79f7ccc9725be3b79afa473089ac978d8fd14a8b0cba7c040",
"https://esm.sh/v133/react-dom@18.2.0/X-ZS9yZWFjdA/denonext/client.development.js": "ebaa7a1fce9f40b8abdae0daab06348b7bbdf5a90e1e60d2116b45d3577f8fa4",
"https://esm.sh/v133/react-dom@18.2.0/X-ZS9yZWFjdA/denonext/react-dom.development.mjs": "b7e7937e4f3446bb2b6db5f73ae20d2b18a4116330486680c6c6f610f7d85f27",
"https://esm.sh/v133/react-flip-move@3.0.5/X-ZS9yZWFjdA/denonext/react-flip-move.development.mjs": "4644ea8644c7d6ccb3563fec092d05b82c647da4981e878b64fd06ab58d6cfc5",
"https://esm.sh/v133/react-intl@6.4.7/X-ZS9yZWFjdA/denonext/react-intl.development.mjs": "866e2105594ecf772144262d215ffd3245f09e8f1b14e97b5f13b4df8d52c419",
"https://esm.sh/v133/react-is@16.13.1/X-ZS9yZWFjdA/denonext/react-is.development.mjs": "9e2c3272e256b176f71660a52bf0f8a079babbd01e680de070d47ed51a9319bd",
"https://esm.sh/v133/react-router-dom@6.16.0/X-ZS9yZWFjdA/denonext/react-router-dom.development.mjs": "0b2d33abc84446dcf3430a42a1a7935b9a49f81192cba22b1263a884c6edf22d",
"https://esm.sh/v133/react-router@6.16.0/X-ZS9yZWFjdA/denonext/react-router.development.mjs": "e539a1882ef472de5bd8e4325a54e0f0d36a45a0bf53d4ffed09353225a2cf95",
"https://esm.sh/v133/readable-stream@3.6.2/denonext/readable-stream.mjs": "4d368fe1058f90ecfb37581103cae1646123180b8fc4aa77157fd733aed24e4a",
"https://esm.sh/v133/readable-web-to-node-stream@3.0.2/denonext/readable-web-to-node-stream.mjs": "8e7f8b7139f71b1cf94cb4d4772239755e996d88bcefb462f03fd6a0b8b4cd83",
"https://esm.sh/v133/scheduler@0.23.0/X-ZS9yZWFjdA/denonext/scheduler.development.mjs": "b6c8f513ecc4afb69b0c5c78a7674bb1c78f7e003946c6c8c655778d81d775db",
"https://esm.sh/v133/strtok3@7.0.0/denonext/core.js": "4934052fd9086facbb9436e905dfdee19ee27a43d0b0a8fca39648e833324577",
"https://esm.sh/v133/swr@2.2.4/X-ZS9yZWFjdA/denonext/_internal.development.js": "e64b6b30de0ddca08078301c3129c608ab8f2cc6279c704c462ebe3022e81275",
"https://esm.sh/v133/swr@2.2.4/X-ZS9yZWFjdA/denonext/swr.development.mjs": "d6be45253b10e1f6c2bd35f035530d5ac0e7c34c716508db131a143fb9818a82",
"https://esm.sh/v133/telegram-format@2.1.0/denonext/telegram-format.mjs": "f5b6a6df788e9b462ce3e0d3db8fb3446bfa5252440b9878a91496ca6fb2d693",
"https://esm.sh/v133/token-types@5.0.1/denonext/token-types.mjs": "eb8ef626bdfc077ae8f9b6c0842e3bdae25b4867dd9d38b7b1b5f003819a06d3",
"https://esm.sh/v133/tslib@2.6.2/X-ZS9yZWFjdA/denonext/tslib.development.mjs": "40dea6e88a1261c5c96a641d73276ffecae3f2d23b9a93d1c5294125f4474cdb",
"https://esm.sh/v133/ty-rest@0.4.0/denonext/client.js": "dd2a1f04d17c87b395d7a39789e41477e854afcfb66559be08348ad76625615b",
"https://esm.sh/v133/ty-rest@0.4.0/denonext/server.js": "98f33c86c304659703f3a1294ae93e78920d8de303dc0f4e360edd717a7bc667",
"https://esm.sh/v133/ty-rest@0.4.1/denonext/client.js": "466aeedd7bb139c85fb3051f0b7cecaf3e3afac98b4825b98a480f8a127692ed",
"https://esm.sh/v133/ty-rest@0.4.1/denonext/server.js": "00be1165ac96313b077629556a1587d4662f4e23bb0e815b945cc95cd3582370",
"https://esm.sh/v133/use-local-storage@3.0.0/X-ZS9yZWFjdA/denonext/use-local-storage.development.mjs": "1fdc00893fe7dac56e95e2817e05d413b674f5cb5a1c6afd8994e25c9e2a56c8",
"https://esm.sh/v133/use-sync-external-store@1.2.0/X-ZS9yZWFjdA/denonext/shim.development.js": "5388baf48494f5abe76f8a4a30810c48e828b52f1298826aa9a3f3378e2b533f",
"https://esm.sh/v133/util-deprecate@1.0.2/denonext/util-deprecate.mjs": "f69f67cf655c38428b0934e0f7c865c055834a87cc3866b629d6b2beb21005e9",
"https://esm.sh/v134/@elysiajs/eden@0.7.4/X-ZS9lbHlzaWE/denonext/eden.development.mjs": "c79c9f105d2b2062b882240272faa81cab1cbdde1113290d2d56c15ed9479986",
"https://esm.sh/v134/@elysiajs/swagger@0.7.4/X-ZS9lbHlzaWE/denonext/swagger.development.mjs": "4aa74e7b8108e9bacd7830c374ef24ee1b4100d65eef045bf6802ceaa3635554",
"https://esm.sh/v134/@sinclair/typebox@0.31.26/X-ZS9lbHlzaWE/denonext/typebox.development.mjs": "5f24db9ca594ccb61f2ae58df80a1f7690d21e117772e7b00babdb290c0747df",
"https://esm.sh/v134/lodash.clonedeep@4.5.0/X-ZS9lbHlzaWE/denonext/lodash.clonedeep.development.mjs": "f44c863cb41bcd2714103a36d97e8eb8268f56070b5cd56dcfae26c556e6622e"
}
}

View File

@ -4,7 +4,9 @@ import { ConsoleHandler } from "std/log/handlers.ts";
import { LevelName, setup } from "std/log/mod.ts";
import { serveUi } from "./api/mod.ts";
import { runAllTasks } from "./app/mod.ts";
import { runBot } from "./bot/mod.ts";
// runbot shouldn't be needed for webhooks?
// import { runBot } from "./bot/mod.ts";
import "./bot/mod.ts";
const logLevel = Deno.env.get("LOG_LEVEL")?.toUpperCase() as LevelName ?? "INFO";
@ -20,7 +22,8 @@ setup({
// run parts of the app
await Promise.all([
runBot(),
// runbot shouldn't be needed for webhooks?
// runBot(),
runAllTasks(),
serveUi(),
]);

1
monitoring/Readme.md Normal file
View File

@ -0,0 +1 @@
These scripts exist to automatically restart the bot in case of errors and connectivity issues. They should either be run as systemd services or cronjobs.

29
monitoring/monitoring.sh Normal file
View File

@ -0,0 +1,29 @@
#!/bin/bash
# This script has to be run as systemd service. It checks journalctl output for errors and restarts the bot automatically when they occur too often.
# Define the regex pattern to search for occurrences of "GrammyError" and "sendMediaGroup"
ERROR_PATTERN="GrammyError.*sendMediaGroup"
# Initialize the counter for consecutive occurrences
error_count=0
# Monitor the journalctl output
journalctl -xe -f | while read line; do
# Check if the line contains the pattern
if echo "$line" | grep -qE "$ERROR_PATTERN"; then
# Increment the error counter
((error_count++))
# Check if the error has occurred 4 times in a row
if [ $error_count -eq 4 ]; then
# Restart the bot service
systemctl restart nyxthebot
# Reset the error counter
error_count=0
fi
else
# Reset the error counter if the line does not contain the error
error_count=0
fi
done

30
monitoring/sleepy.sh Normal file
View File

@ -0,0 +1,30 @@
#!/bin/bash
# When the bot gets eepy sleepy, this script will restart it. It happens, when no jobs come in for multiple minutes.
# The script interfaces with the REST API of the bot and checks if the image count has changed.
# Run this script as cronjob all 4-5 minutes.
# Define the URL and the stats file path
URL="https://YOUR_URL/api/stats"
STATS_FILE="YOUR_FILE_PATH/stats.txt"
# Fetch the data and extract imageCount
imageCount=$(curl -s "$URL" | jq '.imageCount')
# Check if stats file exists and read the last value
if [ -f "$STATS_FILE" ]; then
lastValue=$(tail -n 1 "$STATS_FILE")
else
lastValue=""
fi
# Save the new value to the file
echo "$imageCount" >> "$STATS_FILE"
# Keep only the last 2 values in the file
tail -n 2 "$STATS_FILE" > "$STATS_FILE.tmp" && mv "$STATS_FILE.tmp" "$STATS_FILE"
# Compare the two values and restart the service if they are the same
if [ "$lastValue" == "$imageCount" ]; then
systemctl restart nyxthebot
fi

View File

@ -7,7 +7,7 @@ export function StatsPage() {
const getGlobalStats = useSWR(
["/stats", {}] as const,
(args) => fetchApi(...args).then(handleResponse),
{ refreshInterval: 2_000 },
{ refreshInterval: 1_00 },
);
return (
@ -18,13 +18,13 @@ export function StatsPage() {
className="font-bold text-zinc-700 dark:text-zinc-300"
value={getGlobalStats.data?.pixelStepCount ?? 0}
digits={15}
transitionDurationMs={3_000}
transitionDurationMs={1_00}
/>
<Counter
className="text-base"
value={(getGlobalStats.data?.pixelStepsPerMinute ?? 0) / 60}
digits={9}
transitionDurationMs={2_000}
transitionDurationMs={1_00}
postfix="/s"
/>
</p>
@ -34,13 +34,13 @@ export function StatsPage() {
className="font-bold text-zinc-700 dark:text-zinc-300"
value={getGlobalStats.data?.pixelCount ?? 0}
digits={15}
transitionDurationMs={3_000}
transitionDurationMs={1_00}
/>
<Counter
className="text-base"
value={(getGlobalStats.data?.pixelsPerMinute ?? 0) / 60}
digits={9}
transitionDurationMs={2_000}
transitionDurationMs={1_00}
postfix="/s"
/>
</p>
@ -51,14 +51,14 @@ export function StatsPage() {
className="font-bold text-zinc-700 dark:text-zinc-300"
value={getGlobalStats.data?.stepCount ?? 0}
digits={9}
transitionDurationMs={3_000}
transitionDurationMs={1_00}
/>
<Counter
className="text-base"
value={(getGlobalStats.data?.stepsPerMinute ?? 0) / 60}
digits={3}
fractionDigits={3}
transitionDurationMs={2_000}
transitionDurationMs={1_00}
postfix="/s"
/>
</p>
@ -68,14 +68,14 @@ export function StatsPage() {
className="font-bold text-zinc-700 dark:text-zinc-300"
value={getGlobalStats.data?.imageCount ?? 0}
digits={9}
transitionDurationMs={3_000}
transitionDurationMs={1_00}
/>
<Counter
className="text-base"
value={(getGlobalStats.data?.imagesPerMinute ?? 0) / 60}
digits={3}
fractionDigits={3}
transitionDurationMs={2_000}
transitionDurationMs={1_00}
postfix="/s"
/>
</p>
@ -86,7 +86,7 @@ export function StatsPage() {
className="font-bold text-zinc-700 dark:text-zinc-300"
value={getGlobalStats.data?.userCount ?? 0}
digits={6}
transitionDurationMs={1_500}
transitionDurationMs={1_00}
/>
</p>
</div>