aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.fonts/NotoEmoji-Regular.ttfbin418804 -> 0 bytes
-rw-r--r--.gitignore3
-rw-r--r--.glitch-assets18
-rw-r--r--Aptfile3
-rw-r--r--Procfile2
-rw-r--r--assets/fonts/NotoSans-Regular.ttfbin0 -> 313144 bytes
-rw-r--r--assets/templates/classic/CrabRaveBackground.pngbin0 -> 581439 bytes
-rw-r--r--assets/templates/classic/CrabRaveQuieter.mp4bin0 -> 4421506 bytes
-rw-r--r--assets/templates/garfield/CrabRaveGarfield.mp4bin0 -> 1427547 bytes
-rw-r--r--assets/templates/garfield/CrabRaveGarfieldBackground.pngbin0 -> 270046 bytes
-rw-r--r--assets/templates/otamatone/CrabRaveOtamatone.mp4bin0 -> 2062062 bytes
-rw-r--r--assets/templates/otamatone/CrabRaveOtamatoneBackground.pngbin0 -> 261975 bytes
-rw-r--r--bot.js225
-rw-r--r--bot.py194
-rw-r--r--package-lock.json483
-rw-r--r--package.json25
-rw-r--r--requirements.txt5
-rw-r--r--shrinkwrap.yaml1557
-rw-r--r--templates/index.html36
19 files changed, 241 insertions, 2310 deletions
diff --git a/.fonts/NotoEmoji-Regular.ttf b/.fonts/NotoEmoji-Regular.ttf
deleted file mode 100644
index 19b7bad..0000000
--- a/.fonts/NotoEmoji-Regular.ttf
+++ /dev/null
Binary files differ
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3240065
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+/venv
+/.idea
+/.env
diff --git a/.glitch-assets b/.glitch-assets
deleted file mode 100644
index 8f9ff69..0000000
--- a/.glitch-assets
+++ /dev/null
@@ -1,18 +0,0 @@
-{"name":"drag-in-files.svg","date":"2016-10-22T16:17:49.954Z","url":"https://cdn.hyperdev.com/drag-in-files.svg","type":"image/svg","size":7646,"imageWidth":276,"imageHeight":276,"thumbnail":"https://cdn.hyperdev.com/drag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(102, 153, 205)","uuid":"adSBq97hhhpFNUna"}
-{"name":"click-me.svg","date":"2016-10-23T16:17:49.954Z","url":"https://cdn.hyperdev.com/click-me.svg","type":"image/svg","size":7116,"imageWidth":276,"imageHeight":276,"thumbnail":"https://cdn.hyperdev.com/click-me.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(243, 185, 186)","uuid":"adSBq97hhhpFNUnb"}
-{"name":"paste-me.svg","date":"2016-10-24T16:17:49.954Z","url":"https://cdn.hyperdev.com/paste-me.svg","type":"image/svg","size":7242,"imageWidth":276,"imageHeight":276,"thumbnail":"https://cdn.hyperdev.com/paste-me.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(42, 179, 185)","uuid":"adSBq97hhhpFNUnc"}
-{"uuid":"adSBq97hhhpFNUna","deleted":true}
-{"uuid":"adSBq97hhhpFNUnb","deleted":true}
-{"name":"CrabRave.mp4","date":"2018-12-06T22:23:10.216Z","url":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRave.mp4","type":"video/mp4","size":47021772,"thumbnail":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2Fthumbnails%2FCrabRave.mp4","thumbnailWidth":210,"thumbnailHeight":210,"dominantColor":"rgba(225, 229, 112, 0.60)","uuid":"ctdYh37a0OjsLvm7"}
-{"uuid":"ctdYh37a0OjsLvm7","deleted":true}
-{"name":"CrabRave.mp4","date":"2018-12-06T22:47:29.808Z","url":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRave.mp4","type":"video/mp4","size":4648850,"thumbnail":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2Fthumbnails%2FCrabRave.mp4","thumbnailWidth":210,"thumbnailHeight":210,"dominantColor":"rgba(13, 247, 4, 0.60)","uuid":"oeXMbnr7ddvY8zWv"}
-{"name":"image.png","date":"2019-01-23T06:02:02.649Z","url":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2Fimage.png","type":"image/png","size":19013,"imageWidth":1550,"imageHeight":82,"thumbnail":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2Fthumbnails%2Fimage.png","thumbnailWidth":330,"thumbnailHeight":18,"dominantColor":"rgb(244,239,240)","uuid":"XVWYPkPWXpZsK2Y8"}
-{"uuid":"XVWYPkPWXpZsK2Y8","deleted":true}
-{"name":"CrabRaveQuieter.mp4","date":"2019-01-23T06:06:21.701Z","url":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveQuieter.mp4","type":"video/mp4","size":4421506,"thumbnail":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2Fthumbnails%2FCrabRaveQuieter.mp4","thumbnailWidth":210,"thumbnailHeight":210,"dominantColor":"rgba(249, 159, 162, 0.60)","uuid":"awSLPgRYPuQ60udO"}
-{"name":"CrabRaveBackground.png","date":"2019-08-21T01:19:32.048Z","url":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveBackground.png","type":"image/png","size":581439,"imageWidth":848,"imageHeight":480,"thumbnail":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2Fthumbnails%2FCrabRaveBackground.png","thumbnailWidth":330,"thumbnailHeight":187,"uuid":"jR9kUIvcVDj58WlS"}
-{"name":"CrabRaveOtamatone.mp4","date":"2019-08-21T02:23:59.409Z","url":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveOtamatone.mp4","type":"video/mp4","size":2062062,"thumbnail":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2Fthumbnails%2FCrabRaveOtamatone.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"7pXA3BONrrQfAk43"}
-{"uuid":"adSBq97hhhpFNUnc","deleted":true}
-{"uuid":"oeXMbnr7ddvY8zWv","deleted":true}
-{"name":"CrabRaveOtamatoneBackground.png","date":"2019-08-21T02:31:42.285Z","url":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveOtamatoneBackground.png","type":"image/png","size":261975,"imageWidth":848,"imageHeight":480,"thumbnail":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2Fthumbnails%2FCrabRaveOtamatoneBackground.png","thumbnailWidth":330,"thumbnailHeight":187,"uuid":"ZylMJsdmY8Kp9wF5"}
-{"name":"CrabRaveGarfield.mp4","date":"2019-11-30T19:49:34.116Z","url":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveGarfield.mp4","type":"video/mp4","size":1427547,"thumbnail":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2Fthumbnails%2FCrabRaveGarfield.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"B5cjk7koYwboSsnw"}
-{"name":"CrabRaveGarfieldBackground.png","date":"2019-11-30T19:50:34.563Z","url":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveGarfieldBackground.png","type":"image/png","size":270046,"imageWidth":848,"imageHeight":480,"thumbnail":"https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2Fthumbnails%2FCrabRaveGarfieldBackground.png","thumbnailWidth":330,"thumbnailHeight":187,"uuid":"E59nv9dhCqeq5937"}
diff --git a/Aptfile b/Aptfile
index 36afc06..0f1d3cc 100644
--- a/Aptfile
+++ b/Aptfile
@@ -1 +1,2 @@
-librsvg2-bin
+gunicorn
+ffmpeg
diff --git a/Procfile b/Procfile
index bef48f6..053b14c 100644
--- a/Procfile
+++ b/Procfile
@@ -1 +1 @@
-web: micro-bot -p $PORT
+web: gunicorn bot:app --log-file -
diff --git a/assets/fonts/NotoSans-Regular.ttf b/assets/fonts/NotoSans-Regular.ttf
new file mode 100644
index 0000000..0a01a06
--- /dev/null
+++ b/assets/fonts/NotoSans-Regular.ttf
Binary files differ
diff --git a/assets/templates/classic/CrabRaveBackground.png b/assets/templates/classic/CrabRaveBackground.png
new file mode 100644
index 0000000..a4c81f6
--- /dev/null
+++ b/assets/templates/classic/CrabRaveBackground.png
Binary files differ
diff --git a/assets/templates/classic/CrabRaveQuieter.mp4 b/assets/templates/classic/CrabRaveQuieter.mp4
new file mode 100644
index 0000000..1970656
--- /dev/null
+++ b/assets/templates/classic/CrabRaveQuieter.mp4
Binary files differ
diff --git a/assets/templates/garfield/CrabRaveGarfield.mp4 b/assets/templates/garfield/CrabRaveGarfield.mp4
new file mode 100644
index 0000000..2b1917c
--- /dev/null
+++ b/assets/templates/garfield/CrabRaveGarfield.mp4
Binary files differ
diff --git a/assets/templates/garfield/CrabRaveGarfieldBackground.png b/assets/templates/garfield/CrabRaveGarfieldBackground.png
new file mode 100644
index 0000000..aba0d3b
--- /dev/null
+++ b/assets/templates/garfield/CrabRaveGarfieldBackground.png
Binary files differ
diff --git a/assets/templates/otamatone/CrabRaveOtamatone.mp4 b/assets/templates/otamatone/CrabRaveOtamatone.mp4
new file mode 100644
index 0000000..5ef1d58
--- /dev/null
+++ b/assets/templates/otamatone/CrabRaveOtamatone.mp4
Binary files differ
diff --git a/assets/templates/otamatone/CrabRaveOtamatoneBackground.png b/assets/templates/otamatone/CrabRaveOtamatoneBackground.png
new file mode 100644
index 0000000..b7a229f
--- /dev/null
+++ b/assets/templates/otamatone/CrabRaveOtamatoneBackground.png
Binary files differ
diff --git a/bot.js b/bot.js
deleted file mode 100644
index 51f59eb..0000000
--- a/bot.js
+++ /dev/null
@@ -1,225 +0,0 @@
-var Libhoney = require("libhoney");
-var hny = new Libhoney({
- writeKey: process.env.HONEYCOMB_KEY,
- dataset: "crabravebot"
-})
-const { Composer } = require('micro-bot');
-const child_process = require('child_process');
-const fs = require('fs');
-const url = require('url');
-const { JSDOM } = require("jsdom");
-
-// the bot
-const bot = new Composer();
-
-// start command
-bot.command('/start', async ({ from, replyWithMarkdown, botInfo }) =>
- replyWithMarkdown(`Hi *${from.first_name || from.username}*!
-To shitpost, type @${botInfo.username} and type the text you want to overlay over crab rave.
-This was originally made by @boringcactus in one afternoon when she was bored.
-This bot isn't super reliable but the source is at https://github.com/boringcactus/crabravebot,
-and you can use this bot from the Web at https://crabravebot.herokuapp.com/`));
-
-// styles
-const STYLES = {
- 'classic': {
- 'video': 'https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveQuieter.mp4?v=1548223581701',
- 'thumb': 'https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveBackground.png?v=1566350372048',
- },
- 'otamatone': {
- 'video': 'https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveOtamatone.mp4?v=1566354239409',
- 'thumb': 'https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveOtamatoneBackground.png?v=1566354702285',
- },
- 'garfield': {
- 'video': 'https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveGarfield.mp4?v=1575143374116',
- 'thumb': 'https://cdn.glitch.com/70ea37b5-d264-46e5-a1db-29c786c86515%2FCrabRaveGarfieldBackground.png?v=1575143434563',
- },
-}
-
-// inline query
-bot.on('inline_query', async ({ inlineQuery, answerInlineQuery }) => {
- const query = inlineQuery.query || '';
- console.log('Got query', query);
- if (query.length > 1) {
- const result = [
- {
- type: "video",
- id: "classic",
- video_url: "https://crabravebot.herokuapp.com/video/" + encodeURIComponent(query) + ".mp4?v1",
- mime_type: "video/mp4",
- thumb_url: "https://crabravebot.herokuapp.com/video/" + encodeURIComponent(query) + ".png?v1",
- title: 'Classic'
- },
- {
- type: "video",
- id: "otamatone",
- video_url: "https://crabravebot.herokuapp.com/video/" + encodeURIComponent(query) + ".mp4?v1&style=otamatone",
- mime_type: "video/mp4",
- thumb_url: "https://crabravebot.herokuapp.com/video/" + encodeURIComponent(query) + ".png?v1&style=otamatone",
- title: 'Otamatone (original by TheRealSullyG)'
- },
- {
- type: "video",
- id: "garfield",
- video_url: "https://crabravebot.herokuapp.com/video/" + encodeURIComponent(query) + ".mp4?v1&style=garfield",
- mime_type: "video/mp4",
- thumb_url: "https://crabravebot.herokuapp.com/video/" + encodeURIComponent(query) + ".png?v1&style=garfield",
- title: 'Garfield (original by @jondancesto)'
- },
- ];
- return answerInlineQuery(result);
- }
-});
-
-function fixPaths() {
- for (let style of Object.keys(STYLES)) {
- try {
- let path = require('path').join('/tmp', style, 'video');
- fs.mkdirSync(path, {recursive: true});
- } catch (e) {
- console.log(e);
- }
- }
-}
-
-module.exports = {
- bot,
- server(req, res) {
- if (req.url === '/') {
- res.end(`
- <html>
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>Crab Rave Bot</title>
- </head>
- <body>
- <main>
- <h1>it's a tool for adding things to crab rave</h1>
- <form action="/add-text" method="GET">
- <textarea id="text" name="text" rows="6" cols="25"></textarea>
- <p>
- Style:
- <input type="radio" id="classic" name="style" value="classic" checked><label for="classic">Classic</label>
- <input type="radio" id="otamatone" name="style" value="otamatone"><label for="otamatone">Otamatone</label> (<a href="https://youtu.be/VI5I3MuKJlo">original</a> by TheRealSullyG)
- <input type="radio" id="garfield" name="style" value="garfield"><label for="garfield">Garfield</label> (<a href="https://twitter.com/jondancesto/status/1199796307218427904">original</a> by @jondancesto)
- </p>
- <input type="submit" value="Overlay!">
- </form>
- <p><a href="https://t.me/crabravebot">also available as a Telegram bot</a></p>
- <p>brought to you by <a href="https://www.boringcactus.com">boringcactus</a></p>
- </main>
- <img id="preview" style="max-width: 100%;" src="https://crabravebot.herokuapp.com/video/.png">
- <script type="text/javascript">
- const img = document.getElementById('preview'),
- text = document.getElementById('text'),
- classic = document.getElementById('classic');
- setInterval(() => {
- let style = document.querySelector('input[name="style"]:checked').value;
- img.src = "https://crabravebot.herokuapp.com/video/" + encodeURIComponent(text.value) + '.png?style=' + style;
- }, 1000);
- </script>
- </body>
- </html>
- `);
- } else if (req.url.startsWith('/add-text')) {
- const parsed = url.parse(req.url, true);
- const data = parsed.query.text;
- const style = parsed.query.style;
- res.writeHead(303, {
- 'Location': "https://crabravebot.herokuapp.com/video/" + encodeURIComponent(data) + ".mp4?style=" + style
- });
- res.end();
- } else if (req.url.startsWith('/video/')) {
- fixPaths();
- if (!fs.existsSync('/tmp/classic/video')) {
- console.log('what???');
- child_process.spawnSync('ls', ['/tmp', '/tmp/classic', '/tmp/classic/video']);
- }
- const parsed = url.parse(req.url, true);
- const match = /^\/video\/(.*)\.(mp4|png)/.exec(parsed.pathname);
- if (match === null) {
- console.error('Bad URL: ' + match);
- res.writeHead(400);
- res.end();
- return;
- }
- const text = decodeURIComponent(match[1]);
- console.log('Match:', text);
- const type = match[2];
- if (type === 'mp4') {
- const ev = hny.newEvent();
- ev.addField('type', 'bake');
- ev.addField('text', text);
- ev.send();
- }
- const style = parsed.query.style || 'classic';
- if (!Object.keys(STYLES).includes(style)) {
- console.error("Bad style");
- res.writeHead(400);
- res.end();
- return;
- }
- const path = require('path').join('/tmp', style, encodeURIComponent(match[1]) + '.' + match[2]);
- if (type === 'mp4') {
- res.setHeader('Content-Type', 'video/mp4');
- } else {
- res.setHeader('Content-Type', 'image/png');
- }
- console.log('Name:', path);
- // TODO don't do this dumb thing
- if (!fs.existsSync(path)) {
- if (!fs.existsSync(path + '.png')) {
- const dom = new JSDOM(`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg version="1.1" viewBox="0 0 848 480">
-</svg>`, {contentType: 'image/svg+xml'});
- const document = dom.window.document;
- const lines = text.split('\n');
- let y = 300 - (75 * lines.length) / 2;
- for (let line of lines) {
- const lineNode = document.createElement('text');
- lineNode.setAttribute('x', 424);
- lineNode.setAttribute('y', y);
- y += 75;
- lineNode.setAttribute('style', "text-anchor:middle;alignment-baseline:middle;font-family:'DejaVu Sans',sans-serif;font-weight:bold;font-size:48pt;fill:white;stroke:black;stroke-width:1px;");
- lineNode.textContent = line;
- document.querySelector('svg').append(lineNode);
- }
- const svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' + dom.serialize();
- fs.writeFileSync(path + '.svg', svg);
- child_process.spawnSync('rsvg-convert', ['--format=png', '--output=' + path + '.png', path + '.svg'], {stdio: ['inherit', 'inherit', 'inherit']});
- }
- if (type === 'mp4') {
- let background = STYLES[style].video;
- let args = [
- '-hide_banner',
- '-i', background,
- '-i', path + '.png',
- '-filter_complex', 'overlay=x=0:y=0',
- '-c:v', 'libx264', '-preset', 'superfast', '-crf', '27', '-f', 'mp4', '-c:a', 'copy',
- '-y', path
- ];
- console.log('ffmpeg', ...args);
- let child = child_process.spawnSync(
- 'ffmpeg',
- args,
- {
- stdio: ['inherit', 'inherit', 'inherit']
- }
- );
- } else {
- let background_url = STYLES[style].thumb;
- let background = '/tmp/' + style + '.png';
- if (!fs.existsSync(background)) {
- child_process.spawnSync('curl', ['-o', background, background_url]);
- }
- child_process.spawnSync('composite', [path + '.png', background, path]);
- }
- }
- if (fs.existsSync(path)) {
- fs.createReadStream(path).pipe(res);
- } else {
- console.log('what the fuck', path);
- }
- }
- },
-};
diff --git a/bot.py b/bot.py
new file mode 100644
index 0000000..5b77632
--- /dev/null
+++ b/bot.py
@@ -0,0 +1,194 @@
+import logging
+import os
+from io import BytesIO
+from dataclasses import dataclass
+from pathlib import Path
+from urllib.parse import quote_plus as url_quote
+import subprocess
+import tempfile
+from queue import Queue
+from threading import Thread
+
+import telegram
+from telegram.ext import Dispatcher, MessageHandler, CommandHandler, InlineQueryHandler, Filters, CallbackContext
+from dotenv import load_dotenv, find_dotenv
+from PIL import Image, ImageDraw, ImageFont
+import libhoney
+from flask import Flask, render_template, request, make_response
+app = Flask(__name__)
+
+load_dotenv(find_dotenv())
+
+libhoney.init(writekey=os.environ.get('HONEYCOMB_KEY'), dataset="crabravebot", debug=True)
+
+font = ImageFont.truetype("assets/fonts/NotoSans-Regular.ttf", 48)
+
+logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
+ level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+
+@dataclass
+class Style:
+ """Crab rave style"""
+ id: str
+ name: str
+ desc: str
+ image: Path
+ video: Path
+
+
+def get_styles():
+ templates = Path('assets/templates')
+ result = []
+ for folder in templates.iterdir():
+ s_id = folder.name
+ name = s_id
+ desc = s_id
+ image = list(folder.glob('*.png'))[0]
+ video = list(folder.glob('*.mp4'))[0]
+ result.append(Style(s_id, name, desc, image, video))
+ return result
+
+
+STYLES = get_styles()
+
+
+def render_text(text: str, base: Image):
+ if base.mode == 'RGB':
+ white = (255, 255, 255)
+ black = (0, 0, 0)
+ elif base.mode == 'RGBA':
+ white = (255, 255, 255, 255)
+ black = (0, 0, 0, 255)
+ else:
+ raise ValueError('Base image {}, not RGB/RGBA'.format(base.mode))
+
+ draw = ImageDraw.Draw(base)
+ text_width, text_height = draw.multiline_textsize(text, font=font)
+ center_x = base.width // 2
+ center_y = base.height // 2
+ draw.multiline_text((center_x - text_width / 2, center_y - text_height / 2), text, font=font,
+ fill=white, stroke_width=1, stroke_fill=black)
+
+
+def make_image(text: str, style_id: str):
+ outfile = BytesIO()
+ style = [s for s in STYLES if s.id == style_id][0]
+ with Image.open(style.image) as base:
+ render_text(text, base)
+ base.save(outfile, 'PNG')
+ return outfile.getvalue()
+
+
+def make_video(text: str, style_id: str):
+ ev = libhoney.Event()
+ ev.add_field('type', 'bake')
+ ev.add_field('text', text)
+ ev.add_field('style', style_id)
+ ev.send()
+ style = [s for s in STYLES if s.id == style_id][0]
+ with Image.open(style.image) as image:
+ size = image.size
+ overlay = Image.new('RGBA', size, (0, 0, 0, 0))
+ render_text(text, overlay)
+ with tempfile.TemporaryDirectory() as tmp:
+ overlay_file = Path(tmp) / 'overlay.png'
+ overlay.save(overlay_file)
+ result_file = Path(tmp) / 'result.mp4'
+ subprocess.run([
+ 'ffmpeg',
+ '-hide_banner',
+ '-v', 'warning',
+ '-i', str(style.video),
+ '-i', str(overlay_file),
+ '-filter_complex', 'overlay=x=0:y=0',
+ '-c:v', 'libx264', '-preset', 'superfast', '-crf', '27', '-f', 'mp4', '-c:a', 'copy',
+ '-y', str(result_file)
+ ]).check_returncode()
+ return result_file.read_bytes()
+
+
+def start(update: telegram.Update, context: CallbackContext):
+ template = r"""Hi {you}!
+To shitpost, type @{me} and type the text you want to overlay over crab rave.
+This was originally made by @boringcactus in one afternoon when ze was bored.
+This bot isn't super reliable but the source is at https://github.com/boringcactus/crabravebot,
+and you can use this bot from the Web at https://crabravebot.herokuapp.com/"""
+ you = update.effective_user.first_name
+ if you is None or len(you) == 0:
+ you = update.effective_user.username
+ text = template.format(you=you, me=context.bot.username)
+ context.bot.send_message(chat_id=update.effective_chat.id, text=text)
+
+
+def inline_query(update: telegram.Update, context: CallbackContext):
+ query = update.inline_query
+ text = query.query
+
+ logger.info('Got query %s', text)
+
+ def make_result(style: Style):
+ base = "https://crabravebot.herokuapp.com/render?v=1&style=" + style.id + "&text=" + url_quote(text, safe='')
+ return telegram.InlineQueryResultVideo(
+ id=style.id,
+ video_url=base + '&ext=mp4',
+ mime_type="video/mp4",
+ thumb_url=base + '&ext=png',
+ title=style.name,
+ )
+
+ query.answer([make_result(s) for s in STYLES])
+
+
+def message(update: telegram.Update, context: CallbackContext):
+ text = update.effective_message.text
+
+ logger.info('Got query %s', text)
+
+ update.effective_message.reply_video(BytesIO(make_video(text, STYLES[0].id)))
+
+
+@app.route('/')
+def index():
+ return render_template('index.html')
+
+
+@app.route('/render')
+def serve_render():
+ style = request.args['style']
+ ext = request.args['ext']
+ text = request.args['text']
+ if sum(1 for x in STYLES if x.id == style) == 0:
+ raise ValueError('bad style')
+ if ext == 'png':
+ response = make_image(text, style)
+ content_type = 'image/png'
+ elif ext == 'mp4':
+ response = make_video(text, style)
+ content_type = 'video/mp4'
+ else:
+ raise ValueError('bad extension')
+ return response, {'Content-Type': content_type}
+
+
+TOKEN = os.environ.get('TG_BOT_TOKEN')
+WEBHOOK = '/webhook/' + TOKEN
+
+
+@app.route(WEBHOOK, methods=['POST'])
+def webhook():
+ update_queue.put(telegram.Update.de_json(request.get_json(), bot))
+
+
+bot = telegram.Bot(token=TOKEN)
+bot.set_webhook('https://crabravebot.herokuapp.com' + WEBHOOK)
+update_queue = Queue()
+dp = Dispatcher(bot, update_queue, use_context=True)
+# Add handlers
+dp.add_handler(CommandHandler('start', start))
+dp.add_handler(InlineQueryHandler(inline_query))
+dp.add_handler(MessageHandler(Filters.all, message))
+
+thread = Thread(target=dp.start, name='dispatcher')
+thread.start()
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index 67f9ae7..0000000
--- a/package-lock.json
+++ /dev/null
@@ -1,483 +0,0 @@
-{
- "name": "glitch-telegram-bot",
- "version": "0.0.1",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
- "@types/node": {
- "version": "10.12.12",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.12.tgz",
- "integrity": "sha512-Pr+6JRiKkfsFvmU/LK68oBRCQeEg36TyAbPhc2xpez24OOZZCuoIhWGTd39VZy6nGafSbxzGouFPTFD/rR1A0A=="
- },
- "accepts": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
- "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
- "requires": {
- "mime-types": "~2.1.18",
- "negotiator": "0.6.1"
- }
- },
- "array-flatten": {
- "version": "1.1.1",
- "resolved": "http://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
- },
- "body-parser": {
- "version": "1.18.3",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
- "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
- "requires": {
- "bytes": "3.0.0",
- "content-type": "~1.0.4",
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "http-errors": "~1.6.3",
- "iconv-lite": "0.4.23",
- "on-finished": "~2.3.0",
- "qs": "6.5.2",
- "raw-body": "2.3.3",
- "type-is": "~1.6.16"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- }
- }
- },
- "bytes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
- },
- "content-disposition": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
- "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
- },
- "content-type": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
- },
- "cookie": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
- "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
- },
- "cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
- },
- "debug": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
- "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "depd": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
- "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
- },
- "destroy": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
- "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
- },
- "dotenv": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz",
- "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w=="
- },
- "ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
- },
- "encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
- },
- "escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
- },
- "etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
- },
- "express": {
- "version": "4.16.4",
- "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
- "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
- "requires": {
- "accepts": "~1.3.5",
- "array-flatten": "1.1.1",
- "body-parser": "1.18.3",
- "content-disposition": "0.5.2",
- "content-type": "~1.0.4",
- "cookie": "0.3.1",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "1.1.1",
- "fresh": "0.5.2",
- "merge-descriptors": "1.0.1",
- "methods": "~1.1.2",
- "on-finished": "~2.3.0",
- "parseurl": "~1.3.2",
- "path-to-regexp": "0.1.7",
- "proxy-addr": "~2.0.4",
- "qs": "6.5.2",
- "range-parser": "~1.2.0",
- "safe-buffer": "5.1.2",
- "send": "0.16.2",
- "serve-static": "1.13.2",
- "setprototypeof": "1.1.0",
- "statuses": "~1.4.0",
- "type-is": "~1.6.16",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- }
- }
- },
- "finalhandler": {
- "version": "1.1.1",
- "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
- "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
- "requires": {
- "debug": "2.6.9",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "on-finished": "~2.3.0",
- "parseurl": "~1.3.2",
- "statuses": "~1.4.0",
- "unpipe": "~1.0.0"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- }
- }
- },
- "forwarded": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
- "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
- },
- "fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
- },
- "http-errors": {
- "version": "1.6.3",
- "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
- "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
- "requires": {
- "depd": "~1.1.2",
- "inherits": "2.0.3",
- "setprototypeof": "1.1.0",
- "statuses": ">= 1.4.0 < 2"
- }
- },
- "iconv-lite": {
- "version": "0.4.23",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
- "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
- },
- "ipaddr.js": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
- "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4="
- },
- "media-typer": {
- "version": "0.3.0",
- "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
- "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
- },
- "merge-descriptors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
- "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
- },
- "methods": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
- "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
- },
- "micro-bot": {
- "version": "2.5.3",
- "resolved": "https://registry.npmjs.org/micro-bot/-/micro-bot-2.5.3.tgz",
- "integrity": "sha512-64sh5hw3AOgWJ4DYgpSGuyhH/TDVm0S3rLxGMB+rFPyPL/urGloMDXr+KM2+TfAUnnXncnD297vBselwLXCXtw==",
- "requires": {
- "dotenv": "^6.0.0",
- "minimist": "^1.2.0",
- "telegraf": "^3.25.4"
- }
- },
- "mime": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
- "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
- },
- "mime-db": {
- "version": "1.37.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
- "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg=="
- },
- "mime-types": {
- "version": "2.1.21",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
- "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
- "requires": {
- "mime-db": "~1.37.0"
- }
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
- },
- "ms": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
- "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
- },
- "negotiator": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
- "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
- },
- "node-fetch": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz",
- "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA=="
- },
- "on-finished": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
- "requires": {
- "ee-first": "1.1.1"
- }
- },
- "os-tmpdir": {
- "version": "1.0.2",
- "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
- },
- "parseurl": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
- "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
- },
- "path-to-regexp": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
- "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
- },
- "proxy-addr": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
- "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
- "requires": {
- "forwarded": "~0.1.2",
- "ipaddr.js": "1.8.0"
- }
- },
- "qs": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
- "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
- },
- "range-parser": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
- "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
- },
- "raw-body": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
- "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
- "requires": {
- "bytes": "3.0.0",
- "http-errors": "1.6.3",
- "iconv-lite": "0.4.23",
- "unpipe": "1.0.0"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- },
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "sandwich-stream": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/sandwich-stream/-/sandwich-stream-2.0.2.tgz",
- "integrity": "sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ=="
- },
- "send": {
- "version": "0.16.2",
- "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
- "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
- "requires": {
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "destroy": "~1.0.4",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "fresh": "0.5.2",
- "http-errors": "~1.6.2",
- "mime": "1.4.1",
- "ms": "2.0.0",
- "on-finished": "~2.3.0",
- "range-parser": "~1.2.0",
- "statuses": "~1.4.0"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- }
- }
- },
- "serve-static": {
- "version": "1.13.2",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
- "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
- "requires": {
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.2",
- "send": "0.16.2"
- }
- },
- "setprototypeof": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
- "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
- },
- "statuses": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
- "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
- },
- "telegraf": {
- "version": "3.25.5",
- "resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.25.5.tgz",
- "integrity": "sha512-gGyyAl5b+jVwR8L2YXxUYCgDqF3LUlXIlt2+sWozdKiVuWliPgATmdk/dp9I0Rw+fIePJVX/lQfgd8MfuSSwRA==",
- "requires": {
- "@types/node": "^10.1.2",
- "debug": "^4.0.1",
- "node-fetch": "^2.2.0",
- "sandwich-stream": "^2.0.1",
- "telegram-typings": "^3.6.0"
- }
- },
- "telegram-typings": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/telegram-typings/-/telegram-typings-3.6.1.tgz",
- "integrity": "sha512-njVv1EAhIZnmQVLocZEADYUyqA1WIXuVcDYlsp+mXua/XB0pxx+PKtMSPeZ/EE4wPWTw9h/hA9ASTT6yQelkiw=="
- },
- "tmp": {
- "version": "0.0.33",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
- "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
- "requires": {
- "os-tmpdir": "~1.0.2"
- }
- },
- "type-is": {
- "version": "1.6.16",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
- "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
- "requires": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.18"
- }
- },
- "unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
- },
- "utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
- },
- "vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
- }
- }
-}
diff --git a/package.json b/package.json
deleted file mode 100644
index 4a80a80..0000000
--- a/package.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "name": "glitch-telegram-bot",
- "version": "0.0.1",
- "description": "Supreme bot",
- "main": "bot.js",
- "scripts": {
- "start": "micro-bot -d ${PROJECT_DOMAIN}.glitch.me"
- },
- "dependencies": {
- "micro-bot": "^2.5.3",
- "express": "^4.16.4",
- "tmp": "^0.1.0",
- "jsdom": "^15.1.1",
- "libhoney": "^1.2.2"
- },
- "engines": {
- "node": "10.x"
- },
- "license": "MIT",
- "keywords": [
- "node",
- "glitch",
- "telegram"
- ]
-} \ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..00f9b5a
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,5 @@
+python-telegram-bot
+python-dotenv
+Pillow
+libhoney
+Flask
diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml
deleted file mode 100644
index 2774dde..0000000
--- a/shrinkwrap.yaml
+++ /dev/null
@@ -1,1557 +0,0 @@
-dependencies:
- express: 4.16.4
- jsdom: 15.1.1
- libhoney: 1.3.0
- micro-bot: 2.5.3
- tmp: 0.1.0
-packages:
- /@types/node/11.13.6:
- dev: false
- resolution:
- integrity: sha512-Xoo/EBzEe8HxTSwaZNLZjaW6M6tA/+GmD3/DZ6uo8qSaolE/9Oarko0oV1fVfrLqOz0tx0nXJB4rdD5c+vixLw==
- /@types/node/8.10.50:
- dev: false
- resolution:
- integrity: sha512-+ZbcUwJdaBgOZpwXeT0v+gHC/jQbEfzoc9s4d0rN0JIKeQbuTrT+A2n1aQY6LpZjrLXJT7avVUqiCecCJeeZxA==
- /abab/2.0.0:
- dev: false
- resolution:
- integrity: sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==
- /accepts/1.3.5:
- dependencies:
- mime-types: 2.1.24
- negotiator: 0.6.1
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-63d99gEXI6OxTopywIBcjoZ0a9I=
- /acorn-globals/4.3.2:
- dependencies:
- acorn: 6.2.0
- acorn-walk: 6.2.0
- dev: false
- resolution:
- integrity: sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==
- /acorn-walk/6.2.0:
- dev: false
- engines:
- node: '>=0.4.0'
- resolution:
- integrity: sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
- /acorn/6.2.0:
- dev: false
- engines:
- node: '>=0.4.0'
- hasBin: true
- resolution:
- integrity: sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw==
- /agent-base/4.2.1:
- dependencies:
- es6-promisify: 5.0.0
- dev: false
- engines:
- node: '>= 4.0.0'
- resolution:
- integrity: sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==
- /agent-base/4.3.0:
- dependencies:
- es6-promisify: 5.0.0
- dev: false
- engines:
- node: '>= 4.0.0'
- resolution:
- integrity: sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
- /ajv/6.10.1:
- dependencies:
- fast-deep-equal: 2.0.1
- fast-json-stable-stringify: 2.0.0
- json-schema-traverse: 0.4.1
- uri-js: 4.2.2
- dev: false
- resolution:
- integrity: sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ==
- /array-equal/1.0.0:
- dev: false
- resolution:
- integrity: sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
- /array-flatten/1.1.1:
- dev: false
- resolution:
- integrity: sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
- /asn1/0.2.4:
- dependencies:
- safer-buffer: 2.1.2
- dev: false
- resolution:
- integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
- /assert-plus/1.0.0:
- dev: false
- engines:
- node: '>=0.8'
- resolution:
- integrity: sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
- /ast-types/0.13.2:
- dev: false
- engines:
- node: '>=4'
- resolution:
- integrity: sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA==
- /async-limiter/1.0.0:
- dev: false
- resolution:
- integrity: sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==
- /asynckit/0.4.0:
- dev: false
- resolution:
- integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=
- /aws-sign2/0.7.0:
- dev: false
- resolution:
- integrity: sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
- /aws4/1.8.0:
- dev: false
- resolution:
- integrity: sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
- /balanced-match/1.0.0:
- dev: false
- resolution:
- integrity: sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
- /bcrypt-pbkdf/1.0.2:
- dependencies:
- tweetnacl: 0.14.5
- dev: false
- resolution:
- integrity: sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
- /body-parser/1.18.3:
- dependencies:
- bytes: 3.0.0
- content-type: 1.0.4
- debug: 2.6.9
- depd: 1.1.2
- http-errors: 1.6.3
- iconv-lite: 0.4.23
- on-finished: 2.3.0
- qs: 6.5.2
- raw-body: 2.3.3
- type-is: 1.6.16
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=
- /brace-expansion/1.1.11:
- dependencies:
- balanced-match: 1.0.0
- concat-map: 0.0.1
- dev: false
- resolution:
- integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
- /browser-process-hrtime/0.1.3:
- dev: false
- resolution:
- integrity: sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==
- /bytes/3.0.0:
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
- /bytes/3.1.0:
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
- /caseless/0.12.0:
- dev: false
- resolution:
- integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
- /co/4.6.0:
- dev: false
- engines:
- iojs: '>= 1.0.0'
- node: '>= 0.12.0'
- resolution:
- integrity: sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
- /combined-stream/1.0.8:
- dependencies:
- delayed-stream: 1.0.0
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
- /component-emitter/1.3.0:
- dev: false
- resolution:
- integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
- /concat-map/0.0.1:
- dev: false
- resolution:
- integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
- /content-disposition/0.5.2:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-DPaLud318r55YcOoUXjLhdunjLQ=
- /content-type/1.0.4:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
- /cookie-signature/1.0.6:
- dev: false
- resolution:
- integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
- /cookie/0.3.1:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
- /cookiejar/2.1.2:
- dev: false
- resolution:
- integrity: sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==
- /core-util-is/1.0.2:
- dev: false
- resolution:
- integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
- /cssom/0.3.8:
- dev: false
- resolution:
- integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
- /cssstyle/1.3.0:
- dependencies:
- cssom: 0.3.8
- dev: false
- engines:
- node: '>=8'
- resolution:
- integrity: sha512-wXsoRfsRfsLVNaVzoKdqvEmK/5PFaEXNspVT22Ots6K/cnJdpoDKuQFw+qlMiXnmaif1OgeC466X1zISgAOcGg==
- /dashdash/1.14.1:
- dependencies:
- assert-plus: 1.0.0
- dev: false
- engines:
- node: '>=0.10'
- resolution:
- integrity: sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
- /data-uri-to-buffer/2.0.1:
- dependencies:
- '@types/node': 8.10.50
- dev: false
- resolution:
- integrity: sha512-OkVVLrerfAKZlW2ZZ3Ve2y65jgiWqBKsTfUIAFbn8nVbPcCZg6l6gikKlEYv0kXcmzqGm6mFq/Jf2vriuEkv8A==
- /data-urls/1.1.0:
- dependencies:
- abab: 2.0.0
- whatwg-mimetype: 2.3.0
- whatwg-url: 7.0.0
- dev: false
- resolution:
- integrity: sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==
- /debug/2.6.9:
- dependencies:
- ms: 2.0.0
- dev: false
- resolution:
- integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
- /debug/3.1.0:
- dependencies:
- ms: 2.0.0
- dev: false
- resolution:
- integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
- /debug/3.2.6:
- dependencies:
- ms: 2.1.2
- dev: false
- resolution:
- integrity: sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
- /debug/4.1.1:
- dependencies:
- ms: 2.1.1
- dev: false
- resolution:
- integrity: sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
- /deep-is/0.1.3:
- dev: false
- resolution:
- integrity: sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
- /degenerator/1.0.4:
- dependencies:
- ast-types: 0.13.2
- escodegen: 1.11.1
- esprima: 3.1.3
- dev: false
- resolution:
- integrity: sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=
- /delayed-stream/1.0.0:
- dev: false
- engines:
- node: '>=0.4.0'
- resolution:
- integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
- /depd/1.1.2:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
- /destroy/1.0.4:
- dev: false
- resolution:
- integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
- /domexception/1.0.1:
- dependencies:
- webidl-conversions: 4.0.2
- dev: false
- resolution:
- integrity: sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==
- /dotenv/6.2.0:
- dev: false
- engines:
- node: '>=6'
- resolution:
- integrity: sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==
- /ecc-jsbn/0.1.2:
- dependencies:
- jsbn: 0.1.1
- safer-buffer: 2.1.2
- dev: false
- resolution:
- integrity: sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
- /ee-first/1.1.1:
- dev: false
- resolution:
- integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
- /encodeurl/1.0.2:
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
- /es6-promise/4.2.8:
- dev: false
- resolution:
- integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
- /es6-promisify/5.0.0:
- dependencies:
- es6-promise: 4.2.8
- dev: false
- resolution:
- integrity: sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
- /escape-html/1.0.3:
- dev: false
- resolution:
- integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
- /escodegen/1.11.1:
- dependencies:
- esprima: 3.1.3
- estraverse: 4.2.0
- esutils: 2.0.2
- optionator: 0.8.2
- dev: false
- engines:
- node: '>=4.0'
- hasBin: true
- optionalDependencies:
- source-map: 0.6.1
- resolution:
- integrity: sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==
- /esprima/3.1.3:
- dev: false
- engines:
- node: '>=4'
- hasBin: true
- resolution:
- integrity: sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
- /estraverse/4.2.0:
- dev: false
- engines:
- node: '>=0.10.0'
- resolution:
- integrity: sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=
- /esutils/2.0.2:
- dev: false
- engines:
- node: '>=0.10.0'
- resolution:
- integrity: sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=
- /etag/1.8.1:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
- /express/4.16.4:
- dependencies:
- accepts: 1.3.5
- array-flatten: 1.1.1
- body-parser: 1.18.3
- content-disposition: 0.5.2
- content-type: 1.0.4
- cookie: 0.3.1
- cookie-signature: 1.0.6
- debug: 2.6.9
- depd: 1.1.2
- encodeurl: 1.0.2
- escape-html: 1.0.3
- etag: 1.8.1
- finalhandler: 1.1.1
- fresh: 0.5.2
- merge-descriptors: 1.0.1
- methods: 1.1.2
- on-finished: 2.3.0
- parseurl: 1.3.3
- path-to-regexp: 0.1.7
- proxy-addr: 2.0.5
- qs: 6.5.2
- range-parser: 1.2.0
- safe-buffer: 5.1.2
- send: 0.16.2
- serve-static: 1.13.2
- setprototypeof: 1.1.0
- statuses: 1.4.0
- type-is: 1.6.16
- utils-merge: 1.0.1
- vary: 1.1.2
- dev: false
- engines:
- node: '>= 0.10.0'
- resolution:
- integrity: sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==
- /extend/2.0.2:
- dev: false
- resolution:
- integrity: sha512-AgFD4VU+lVLP6vjnlNfF7OeInLTyeyckCNPEsuxz1vi786UuK/nk6ynPuhn/h+Ju9++TQyr5EpLRI14fc1QtTQ==
- /extend/3.0.2:
- dev: false
- resolution:
- integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
- /extsprintf/1.3.0:
- dev: false
- engines:
- '0': node >=0.6.0
- resolution:
- integrity: sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
- /extsprintf/1.4.0:
- dev: false
- engines:
- '0': node >=0.6.0
- resolution:
- integrity: sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
- /fast-deep-equal/2.0.1:
- dev: false
- resolution:
- integrity: sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
- /fast-json-stable-stringify/2.0.0:
- dev: false
- resolution:
- integrity: sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
- /fast-levenshtein/2.0.6:
- dev: false
- resolution:
- integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
- /file-uri-to-path/1.0.0:
- dev: false
- resolution:
- integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
- /finalhandler/1.1.1:
- dependencies:
- debug: 2.6.9
- encodeurl: 1.0.2
- escape-html: 1.0.3
- on-finished: 2.3.0
- parseurl: 1.3.3
- statuses: 1.4.0
- unpipe: 1.0.0
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==
- /forever-agent/0.6.1:
- dev: false
- resolution:
- integrity: sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
- /form-data/2.3.3:
- dependencies:
- asynckit: 0.4.0
- combined-stream: 1.0.8
- mime-types: 2.1.24
- dev: false
- engines:
- node: '>= 0.12'
- resolution:
- integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
- /form-data/2.5.0:
- dependencies:
- asynckit: 0.4.0
- combined-stream: 1.0.8
- mime-types: 2.1.24
- dev: false
- engines:
- node: '>= 0.12'
- resolution:
- integrity: sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA==
- /formidable/1.2.1:
- dev: false
- resolution:
- integrity: sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==
- /forwarded/0.1.2:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
- /fresh/0.5.2:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
- /fs.realpath/1.0.0:
- dev: false
- resolution:
- integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
- /ftp/0.3.10:
- dependencies:
- readable-stream: 1.1.14
- xregexp: 2.0.0
- dev: false
- engines:
- node: '>=0.8.0'
- resolution:
- integrity: sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=
- /get-uri/2.0.3:
- dependencies:
- data-uri-to-buffer: 2.0.1
- debug: 4.1.1
- extend: 3.0.2
- file-uri-to-path: 1.0.0
- ftp: 0.3.10
- readable-stream: 3.4.0
- dev: false
- resolution:
- integrity: sha512-x5j6Ks7FOgLD/GlvjKwgu7wdmMR55iuRHhn8hj/+gA+eSbxQvZ+AEomq+3MgVEZj1vpi738QahGbCCSIDtXtkw==
- /getpass/0.1.7:
- dependencies:
- assert-plus: 1.0.0
- dev: false
- resolution:
- integrity: sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
- /glob/7.1.3:
- dependencies:
- fs.realpath: 1.0.0
- inflight: 1.0.6
- inherits: 2.0.3
- minimatch: 3.0.4
- once: 1.4.0
- path-is-absolute: 1.0.1
- dev: false
- resolution:
- integrity: sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
- /har-schema/2.0.0:
- dev: false
- engines:
- node: '>=4'
- resolution:
- integrity: sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
- /har-validator/5.1.3:
- dependencies:
- ajv: 6.10.1
- har-schema: 2.0.0
- dev: false
- engines:
- node: '>=6'
- resolution:
- integrity: sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
- /html-encoding-sniffer/1.0.2:
- dependencies:
- whatwg-encoding: 1.0.5
- dev: false
- resolution:
- integrity: sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==
- /http-errors/1.6.3:
- dependencies:
- depd: 1.1.2
- inherits: 2.0.3
- setprototypeof: 1.1.0
- statuses: 1.5.0
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=
- /http-errors/1.7.3:
- dependencies:
- depd: 1.1.2
- inherits: 2.0.4
- setprototypeof: 1.1.1
- statuses: 1.5.0
- toidentifier: 1.0.0
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
- /http-proxy-agent/2.1.0:
- dependencies:
- agent-base: 4.3.0
- debug: 3.1.0
- dev: false
- engines:
- node: '>= 4.5.0'
- resolution:
- integrity: sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==
- /http-signature/1.2.0:
- dependencies:
- assert-plus: 1.0.0
- jsprim: 1.4.1
- sshpk: 1.16.1
- dev: false
- engines:
- node: '>=0.8'
- npm: '>=1.3.7'
- resolution:
- integrity: sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
- /https-proxy-agent/2.2.2:
- dependencies:
- agent-base: 4.3.0
- debug: 3.2.6
- dev: false
- engines:
- node: '>= 4.5.0'
- resolution:
- integrity: sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==
- /iconv-lite/0.4.23:
- dependencies:
- safer-buffer: 2.1.2
- dev: false
- engines:
- node: '>=0.10.0'
- resolution:
- integrity: sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==
- /iconv-lite/0.4.24:
- dependencies:
- safer-buffer: 2.1.2
- dev: false
- engines:
- node: '>=0.10.0'
- resolution:
- integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
- /inflight/1.0.6:
- dependencies:
- once: 1.4.0
- wrappy: 1.0.2
- dev: false
- resolution:
- integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
- /inherits/2.0.3:
- dev: false
- resolution:
- integrity: sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
- /inherits/2.0.4:
- dev: false
- resolution:
- integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
- /ip-regex/2.1.0:
- dev: false
- engines:
- node: '>=4'
- resolution:
- integrity: sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
- /ip/1.1.5:
- dev: false
- resolution:
- integrity: sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
- /ipaddr.js/1.9.0:
- dev: false
- engines:
- node: '>= 0.10'
- resolution:
- integrity: sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==
- /is-typedarray/1.0.0:
- dev: false
- resolution:
- integrity: sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
- /isarray/0.0.1:
- dev: false
- resolution:
- integrity: sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
- /isarray/1.0.0:
- dev: false
- resolution:
- integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
- /isstream/0.1.2:
- dev: false
- resolution:
- integrity: sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
- /jsbn/0.1.1:
- dev: false
- resolution:
- integrity: sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
- /jsdom/15.1.1:
- dependencies:
- abab: 2.0.0
- acorn: 6.2.0
- acorn-globals: 4.3.2
- array-equal: 1.0.0
- cssom: 0.3.8
- cssstyle: 1.3.0
- data-urls: 1.1.0
- domexception: 1.0.1
- escodegen: 1.11.1
- html-encoding-sniffer: 1.0.2
- nwsapi: 2.1.4
- parse5: 5.1.0
- pn: 1.1.0
- request: 2.88.0
- request-promise-native: /request-promise-native/1.0.7/request@2.88.0
- saxes: 3.1.11
- symbol-tree: 3.2.4
- tough-cookie: 3.0.1
- w3c-hr-time: 1.0.1
- w3c-xmlserializer: 1.1.2
- webidl-conversions: 4.0.2
- whatwg-encoding: 1.0.5
- whatwg-mimetype: 2.3.0
- whatwg-url: 7.0.0
- ws: 7.1.0
- xml-name-validator: 3.0.0
- dev: false
- engines:
- node: '>=8'
- resolution:
- integrity: sha512-cQZRBB33arrDAeCrAEWn1U3SvrvC8XysBua9Oqg1yWrsY/gYcusloJC3RZJXuY5eehSCmws8f2YeliCqGSkrtQ==
- /json-schema-traverse/0.4.1:
- dev: false
- resolution:
- integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
- /json-schema/0.2.3:
- dev: false
- resolution:
- integrity: sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
- /json-stringify-safe/5.0.1:
- dev: false
- resolution:
- integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
- /jsprim/1.4.1:
- dependencies:
- assert-plus: 1.0.0
- extsprintf: 1.3.0
- json-schema: 0.2.3
- verror: 1.10.0
- dev: false
- engines:
- '0': node >=0.6.0
- resolution:
- integrity: sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
- /levn/0.3.0:
- dependencies:
- prelude-ls: 1.1.2
- type-check: 0.3.2
- dev: false
- engines:
- node: '>= 0.8.0'
- resolution:
- integrity: sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=
- /libhoney/1.3.0:
- dependencies:
- superagent: 3.8.3
- superagent-proxy: /superagent-proxy/2.0.0/superagent@3.8.3
- urljoin: 0.1.5
- dev: false
- engines:
- node: 6.* || 8.* || >= 10.*
- resolution:
- integrity: sha512-xGq5sGm5ljbO06zsCcA6g76VMiEqsI4/v7BtUdIvglHBWH0WryfSD9UVvwu7lVYDYVt7HzmeUXZOBbxeMMUpww==
- /lodash.sortby/4.7.0:
- dev: false
- resolution:
- integrity: sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
- /lodash/4.17.14:
- dev: false
- resolution:
- integrity: sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==
- /lru-cache/4.1.5:
- dependencies:
- pseudomap: 1.0.2
- yallist: 2.1.2
- dev: false
- resolution:
- integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
- /media-typer/0.3.0:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
- /merge-descriptors/1.0.1:
- dev: false
- resolution:
- integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
- /methods/1.1.2:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
- /micro-bot/2.5.3:
- dependencies:
- dotenv: 6.2.0
- minimist: 1.2.0
- telegraf: 3.29.0
- dev: false
- engines:
- node: '>=8.1'
- hasBin: true
- resolution:
- integrity: sha512-64sh5hw3AOgWJ4DYgpSGuyhH/TDVm0S3rLxGMB+rFPyPL/urGloMDXr+KM2+TfAUnnXncnD297vBselwLXCXtw==
- /mime-db/1.40.0:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
- /mime-types/2.1.24:
- dependencies:
- mime-db: 1.40.0
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
- /mime/1.4.1:
- dev: false
- hasBin: true
- resolution:
- integrity: sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==
- /mime/1.6.0:
- dev: false
- engines:
- node: '>=4'
- hasBin: true
- resolution:
- integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
- /minimatch/3.0.4:
- dependencies:
- brace-expansion: 1.1.11
- dev: false
- resolution:
- integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
- /minimist/1.2.0:
- dev: false
- resolution:
- integrity: sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
- /ms/2.0.0:
- dev: false
- resolution:
- integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
- /ms/2.1.1:
- dev: false
- resolution:
- integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
- /ms/2.1.2:
- dev: false
- resolution:
- integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
- /negotiator/0.6.1:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=
- /netmask/1.0.6:
- dev: false
- engines:
- node: '>= 0.4.0'
- resolution:
- integrity: sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=
- /node-fetch/2.3.0:
- dev: false
- engines:
- node: 4.x || >=6.0.0
- resolution:
- integrity: sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==
- /nwsapi/2.1.4:
- dev: false
- resolution:
- integrity: sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==
- /oauth-sign/0.9.0:
- dev: false
- resolution:
- integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
- /on-finished/2.3.0:
- dependencies:
- ee-first: 1.1.1
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
- /once/1.4.0:
- dependencies:
- wrappy: 1.0.2
- dev: false
- resolution:
- integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
- /optionator/0.8.2:
- dependencies:
- deep-is: 0.1.3
- fast-levenshtein: 2.0.6
- levn: 0.3.0
- prelude-ls: 1.1.2
- type-check: 0.3.2
- wordwrap: 1.0.0
- dev: false
- engines:
- node: '>= 0.8.0'
- resolution:
- integrity: sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=
- /pac-proxy-agent/3.0.0:
- dependencies:
- agent-base: 4.3.0
- debug: 3.2.6
- get-uri: 2.0.3
- http-proxy-agent: 2.1.0
- https-proxy-agent: 2.2.2
- pac-resolver: 3.0.0
- raw-body: 2.4.1
- socks-proxy-agent: 4.0.2
- dev: false
- resolution:
- integrity: sha512-AOUX9jES/EkQX2zRz0AW7lSx9jD//hQS8wFXBvcnd/J2Py9KaMJMqV/LPqJssj1tgGufotb2mmopGPR15ODv1Q==
- /pac-resolver/3.0.0:
- dependencies:
- co: 4.6.0
- degenerator: 1.0.4
- ip: 1.1.5
- netmask: 1.0.6
- thunkify: 2.1.2
- dev: false
- resolution:
- integrity: sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==
- /parse5/5.1.0:
- dev: false
- resolution:
- integrity: sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==
- /parseurl/1.3.3:
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
- /path-is-absolute/1.0.1:
- dev: false
- engines:
- node: '>=0.10.0'
- resolution:
- integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
- /path-to-regexp/0.1.7:
- dev: false
- resolution:
- integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
- /performance-now/2.1.0:
- dev: false
- resolution:
- integrity: sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
- /pn/1.1.0:
- dev: false
- resolution:
- integrity: sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==
- /prelude-ls/1.1.2:
- dev: false
- engines:
- node: '>= 0.8.0'
- resolution:
- integrity: sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
- /process-nextick-args/2.0.1:
- dev: false
- resolution:
- integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
- /proxy-addr/2.0.5:
- dependencies:
- forwarded: 0.1.2
- ipaddr.js: 1.9.0
- dev: false
- engines:
- node: '>= 0.10'
- resolution:
- integrity: sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==
- /proxy-agent/3.1.0:
- dependencies:
- agent-base: 4.3.0
- debug: 3.2.6
- http-proxy-agent: 2.1.0
- https-proxy-agent: 2.2.2
- lru-cache: 4.1.5
- pac-proxy-agent: 3.0.0
- proxy-from-env: 1.0.0
- socks-proxy-agent: 4.0.2
- dev: false
- engines:
- node: '>=6'
- resolution:
- integrity: sha512-IkbZL4ClW3wwBL/ABFD2zJ8iP84CY0uKMvBPk/OceQe/cEjrxzN1pMHsLwhbzUoRhG9QbSxYC+Z7LBkTiBNvrA==
- /proxy-from-env/1.0.0:
- dev: false
- resolution:
- integrity: sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=
- /pseudomap/1.0.2:
- dev: false
- resolution:
- integrity: sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
- /psl/1.2.0:
- dev: false
- resolution:
- integrity: sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==
- /punycode/1.4.1:
- dev: false
- resolution:
- integrity: sha1-wNWmOycYgArY4esPpSachN1BhF4=
- /punycode/2.1.1:
- dev: false
- engines:
- node: '>=6'
- resolution:
- integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
- /qs/6.5.2:
- dev: false
- engines:
- node: '>=0.6'
- resolution:
- integrity: sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
- /qs/6.7.0:
- dev: false
- engines:
- node: '>=0.6'
- resolution:
- integrity: sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
- /range-parser/1.2.0:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=
- /raw-body/2.3.3:
- dependencies:
- bytes: 3.0.0
- http-errors: 1.6.3
- iconv-lite: 0.4.23
- unpipe: 1.0.0
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==
- /raw-body/2.4.1:
- dependencies:
- bytes: 3.1.0
- http-errors: 1.7.3
- iconv-lite: 0.4.24
- unpipe: 1.0.0
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==
- /readable-stream/1.1.14:
- dependencies:
- core-util-is: 1.0.2
- inherits: 2.0.4
- isarray: 0.0.1
- string_decoder: 0.10.31
- dev: false
- resolution:
- integrity: sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
- /readable-stream/2.3.6:
- dependencies:
- core-util-is: 1.0.2
- inherits: 2.0.4
- isarray: 1.0.0
- process-nextick-args: 2.0.1
- safe-buffer: 5.1.2
- string_decoder: 1.1.1
- util-deprecate: 1.0.2
- dev: false
- resolution:
- integrity: sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
- /readable-stream/3.4.0:
- dependencies:
- inherits: 2.0.4
- string_decoder: 1.2.0
- util-deprecate: 1.0.2
- dev: false
- engines:
- node: '>= 6'
- resolution:
- integrity: sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==
- /request-promise-core/1.1.2/request@2.88.0:
- dependencies:
- lodash: 4.17.14
- request: 2.88.0
- dev: false
- engines:
- node: '>=0.10.0'
- id: registry.npmjs.org/request-promise-core/1.1.2
- peerDependencies:
- request: ^2.34
- resolution:
- integrity: sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==
- /request-promise-native/1.0.7/request@2.88.0:
- dependencies:
- request: 2.88.0
- request-promise-core: /request-promise-core/1.1.2/request@2.88.0
- stealthy-require: 1.1.1
- tough-cookie: 2.5.0
- dev: false
- engines:
- node: '>=0.12.0'
- id: registry.npmjs.org/request-promise-native/1.0.7
- peerDependencies:
- request: ^2.34
- resolution:
- integrity: sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==
- /request/2.88.0:
- dependencies:
- aws-sign2: 0.7.0
- aws4: 1.8.0
- caseless: 0.12.0
- combined-stream: 1.0.8
- extend: 3.0.2
- forever-agent: 0.6.1
- form-data: 2.3.3
- har-validator: 5.1.3
- http-signature: 1.2.0
- is-typedarray: 1.0.0
- isstream: 0.1.2
- json-stringify-safe: 5.0.1
- mime-types: 2.1.24
- oauth-sign: 0.9.0
- performance-now: 2.1.0
- qs: 6.5.2
- safe-buffer: 5.2.0
- tough-cookie: 2.4.3
- tunnel-agent: 0.6.0
- uuid: 3.3.2
- dev: false
- engines:
- node: '>= 4'
- resolution:
- integrity: sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
- /rimraf/2.6.3:
- dependencies:
- glob: 7.1.3
- dev: false
- hasBin: true
- resolution:
- integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
- /safe-buffer/5.1.2:
- dev: false
- resolution:
- integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
- /safe-buffer/5.2.0:
- dev: false
- resolution:
- integrity: sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
- /safer-buffer/2.1.2:
- dev: false
- resolution:
- integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
- /sandwich-stream/2.0.2:
- dev: false
- engines:
- node: '>= 0.10'
- resolution:
- integrity: sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ==
- /saxes/3.1.11:
- dependencies:
- xmlchars: 2.1.1
- dev: false
- engines:
- node: '>=8'
- resolution:
- integrity: sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==
- /send/0.16.2:
- dependencies:
- debug: 2.6.9
- depd: 1.1.2
- destroy: 1.0.4
- encodeurl: 1.0.2
- escape-html: 1.0.3
- etag: 1.8.1
- fresh: 0.5.2
- http-errors: 1.6.3
- mime: 1.4.1
- ms: 2.0.0
- on-finished: 2.3.0
- range-parser: 1.2.0
- statuses: 1.4.0
- dev: false
- engines:
- node: '>= 0.8.0'
- resolution:
- integrity: sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==
- /serve-static/1.13.2:
- dependencies:
- encodeurl: 1.0.2
- escape-html: 1.0.3
- parseurl: 1.3.3
- send: 0.16.2
- dev: false
- engines:
- node: '>= 0.8.0'
- resolution:
- integrity: sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==
- /setprototypeof/1.1.0:
- dev: false
- resolution:
- integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
- /setprototypeof/1.1.1:
- dev: false
- resolution:
- integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
- /smart-buffer/4.0.2:
- dev: false
- engines:
- node: '>= 4.0.0'
- npm: '>= 3.0.0'
- resolution:
- integrity: sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==
- /socks-proxy-agent/4.0.2:
- dependencies:
- agent-base: 4.2.1
- socks: 2.3.2
- dev: false
- engines:
- node: '>= 6'
- resolution:
- integrity: sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==
- /socks/2.3.2:
- dependencies:
- ip: 1.1.5
- smart-buffer: 4.0.2
- dev: false
- engines:
- node: '>= 6.0.0'
- npm: '>= 3.0.0'
- resolution:
- integrity: sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ==
- /source-map/0.6.1:
- dev: false
- engines:
- node: '>=0.10.0'
- optional: true
- resolution:
- integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
- /sshpk/1.16.1:
- dependencies:
- asn1: 0.2.4
- assert-plus: 1.0.0
- bcrypt-pbkdf: 1.0.2
- dashdash: 1.14.1
- ecc-jsbn: 0.1.2
- getpass: 0.1.7
- jsbn: 0.1.1
- safer-buffer: 2.1.2
- tweetnacl: 0.14.5
- dev: false
- engines:
- node: '>=0.10.0'
- hasBin: true
- resolution:
- integrity: sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
- /statuses/1.4.0:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==
- /statuses/1.5.0:
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
- /stealthy-require/1.1.1:
- dev: false
- engines:
- node: '>=0.10.0'
- resolution:
- integrity: sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
- /string_decoder/0.10.31:
- dev: false
- resolution:
- integrity: sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
- /string_decoder/1.1.1:
- dependencies:
- safe-buffer: 5.1.2
- dev: false
- resolution:
- integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
- /string_decoder/1.2.0:
- dependencies:
- safe-buffer: 5.1.2
- dev: false
- resolution:
- integrity: sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==
- /superagent-proxy/2.0.0/superagent@3.8.3:
- dependencies:
- debug: 3.2.6
- proxy-agent: 3.1.0
- superagent: 3.8.3
- dev: false
- engines:
- node: '>=6'
- id: registry.npmjs.org/superagent-proxy/2.0.0
- peerDependencies:
- superagent: '>= 0.15.4 || 1 || 2 || 3'
- resolution:
- integrity: sha512-TktJma5jPdiH1BNN+reF/RMW3b8aBTCV7KlLFV0uYcREgNf3pvo7Rdt564OcFHwkGb3mYEhHuWPBhSbOwiNaYw==
- /superagent/3.8.3:
- dependencies:
- component-emitter: 1.3.0
- cookiejar: 2.1.2
- debug: 3.2.6
- extend: 3.0.2
- form-data: 2.5.0
- formidable: 1.2.1
- methods: 1.1.2
- mime: 1.6.0
- qs: 6.7.0
- readable-stream: 2.3.6
- deprecated: 'Please note that v5.0.1+ of superagent removes User-Agent header by default, therefore you may need to add it yourself (e.g. GitHub blocks requests without a User-Agent header). This notice will go away with v5.0.2+ once it is released.'
- dev: false
- engines:
- node: '>= 4.0'
- resolution:
- integrity: sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==
- /symbol-tree/3.2.4:
- dev: false
- resolution:
- integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
- /telegraf/3.29.0:
- dependencies:
- '@types/node': 11.13.6
- debug: 4.1.1
- node-fetch: 2.3.0
- sandwich-stream: 2.0.2
- telegram-typings: 3.6.1
- dev: false
- engines:
- node: '>=6.2.0'
- resolution:
- integrity: sha512-zvlY2Wnls7D/sJDTD21tORR9S1Exe6NThUCvYhdhCoKx7+OOZlplSd4yhSZbRI4bViuFdyhxCE+IuWS/ZmAElg==
- /telegram-typings/3.6.1:
- dev: false
- resolution:
- integrity: sha512-njVv1EAhIZnmQVLocZEADYUyqA1WIXuVcDYlsp+mXua/XB0pxx+PKtMSPeZ/EE4wPWTw9h/hA9ASTT6yQelkiw==
- /thunkify/2.1.2:
- dev: false
- resolution:
- integrity: sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=
- /tmp/0.1.0:
- dependencies:
- rimraf: 2.6.3
- dev: false
- engines:
- node: '>=6'
- resolution:
- integrity: sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==
- /toidentifier/1.0.0:
- dev: false
- engines:
- node: '>=0.6'
- resolution:
- integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
- /tough-cookie/2.4.3:
- dependencies:
- psl: 1.2.0
- punycode: 1.4.1
- dev: false
- engines:
- node: '>=0.8'
- resolution:
- integrity: sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
- /tough-cookie/2.5.0:
- dependencies:
- psl: 1.2.0
- punycode: 2.1.1
- dev: false
- engines:
- node: '>=0.8'
- resolution:
- integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
- /tough-cookie/3.0.1:
- dependencies:
- ip-regex: 2.1.0
- psl: 1.2.0
- punycode: 2.1.1
- dev: false
- engines:
- node: '>=6'
- resolution:
- integrity: sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==
- /tr46/1.0.1:
- dependencies:
- punycode: 2.1.1
- dev: false
- resolution:
- integrity: sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=
- /tunnel-agent/0.6.0:
- dependencies:
- safe-buffer: 5.2.0
- dev: false
- resolution:
- integrity: sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
- /tweetnacl/0.14.5:
- dev: false
- resolution:
- integrity: sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
- /type-check/0.3.2:
- dependencies:
- prelude-ls: 1.1.2
- dev: false
- engines:
- node: '>= 0.8.0'
- resolution:
- integrity: sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=
- /type-is/1.6.16:
- dependencies:
- media-typer: 0.3.0
- mime-types: 2.1.24
- dev: false
- engines:
- node: '>= 0.6'
- resolution:
- integrity: sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==
- /unpipe/1.0.0:
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
- /uri-js/4.2.2:
- dependencies:
- punycode: 2.1.1
- dev: false
- resolution:
- integrity: sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
- /urljoin/0.1.5:
- dependencies:
- extend: 2.0.2
- dev: false
- resolution:
- integrity: sha1-sl0sYRLFWsnVAJakmg8ft/T1OSE=
- /util-deprecate/1.0.2:
- dev: false
- resolution:
- integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
- /utils-merge/1.0.1:
- dev: false
- engines:
- node: '>= 0.4.0'
- resolution:
- integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
- /uuid/3.3.2:
- dev: false
- hasBin: true
- resolution:
- integrity: sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
- /vary/1.1.2:
- dev: false
- engines:
- node: '>= 0.8'
- resolution:
- integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
- /verror/1.10.0:
- dependencies:
- assert-plus: 1.0.0
- core-util-is: 1.0.2
- extsprintf: 1.4.0
- dev: false
- engines:
- '0': node >=0.6.0
- resolution:
- integrity: sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
- /w3c-hr-time/1.0.1:
- dependencies:
- browser-process-hrtime: 0.1.3
- dev: false
- resolution:
- integrity: sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=
- /w3c-xmlserializer/1.1.2:
- dependencies:
- domexception: 1.0.1
- webidl-conversions: 4.0.2
- xml-name-validator: 3.0.0
- dev: false
- resolution:
- integrity: sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==
- /webidl-conversions/4.0.2:
- dev: false
- resolution:
- integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
- /whatwg-encoding/1.0.5:
- dependencies:
- iconv-lite: 0.4.24
- dev: false
- resolution:
- integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
- /whatwg-mimetype/2.3.0:
- dev: false
- resolution:
- integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
- /whatwg-url/7.0.0:
- dependencies:
- lodash.sortby: 4.7.0
- tr46: 1.0.1
- webidl-conversions: 4.0.2
- dev: false
- resolution:
- integrity: sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==
- /wordwrap/1.0.0:
- dev: false
- resolution:
- integrity: sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
- /wrappy/1.0.2:
- dev: false
- resolution:
- integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
- /ws/7.1.0:
- dependencies:
- async-limiter: 1.0.0
- dev: false
- resolution:
- integrity: sha512-Swie2C4fs7CkwlHu1glMePLYJJsWjzhl1vm3ZaLplD0h7OMkZyZ6kLTB/OagiU923bZrPFXuDTeEqaEN4NWG4g==
- /xml-name-validator/3.0.0:
- dev: false
- resolution:
- integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
- /xmlchars/2.1.1:
- dev: false
- resolution:
- integrity: sha512-7hew1RPJ1iIuje/Y01bGD/mXokXxegAgVS+e+E0wSi2ILHQkYAH1+JXARwTjZSM4Z4Z+c73aKspEcqj+zPPL/w==
- /xregexp/2.0.0:
- dev: false
- resolution:
- integrity: sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=
- /yallist/2.1.2:
- dev: false
- resolution:
- integrity: sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
-registry: 'https://registry.npmjs.org/'
-shrinkwrapMinorVersion: 9
-shrinkwrapVersion: 3
-specifiers:
- express: ^4.16.4
- jsdom: ^15.1.1
- libhoney: ^1.2.2
- micro-bot: ^2.5.3
- tmp: ^0.1.0
diff --git a/templates/index.html b/templates/index.html
new file mode 100644
index 0000000..fa7bdd6
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,36 @@
+<html lang="en">
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Crab Rave Bot</title>
+</head>
+<body>
+<main>
+ <h1>it's a tool for adding things to crab rave</h1>
+ <form action="/render" method="GET">
+ <textarea id="text" name="text" rows="6" cols="25"></textarea>
+ <input type="hidden" name="ext" value="mp4">
+ <p>
+ Style:
+ <input type="radio" id="classic" name="style" value="classic" checked><label for="classic">Classic</label>
+ <input type="radio" id="otamatone" name="style" value="otamatone"><label for="otamatone">Otamatone</label> (<a
+ href="https://youtu.be/VI5I3MuKJlo">original</a> by TheRealSullyG)
+ <input type="radio" id="garfield" name="style" value="garfield"><label for="garfield">Garfield</label> (<a
+ href="https://twitter.com/jondancesto/status/1199796307218427904">original</a> by @jondancesto)
+ </p>
+ <input type="submit" value="Overlay!">
+ </form>
+ <p><a href="https://t.me/crabravebot">also available as a Telegram bot</a></p>
+ <p>brought to you by <a href="https://www.boringcactus.com">boringcactus</a></p>
+</main>
+<img id="preview" style="max-width: 100%;" src="/render?style=classic&ext=png&text=">
+<script type="text/javascript">
+ const img = document.getElementById('preview'),
+ text = document.getElementById('text'),
+ classic = document.getElementById('classic');
+ setInterval(() => {
+ let style = document.querySelector('input[name="style"]:checked').value;
+ img.src = "/render?style=" + encodeURIComponent(style) + '&ext=png&text=' + encodeURIComponent(text.value);
+ }, 1000);
+</script>
+</body>
+</html>