Added optimization to many image commands, updated packages

This commit is contained in:
TheEssem 2020-01-10 13:40:25 -06:00
parent 51d5f5e5b9
commit a534e7c4cf
19 changed files with 42 additions and 50 deletions

View File

@ -8,7 +8,7 @@ exports.run = async (message) => {
const image = await require("../utils/imagedetect.js")(message); const image = await require("../utils/imagedetect.js")(message);
if (image === undefined) return `${message.author.mention}, you need to provide an image to add a 9GAG watermark!`; if (image === undefined) return `${message.author.mention}, you need to provide an image to add a 9GAG watermark!`;
const watermark = "./assets/images/9gag.png"; const watermark = "./assets/images/9gag.png";
const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("East").out("-layers", "composite"); const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("East").out("-layers", "composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(data); const resultBuffer = await gmToBuffer(data);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -10,7 +10,7 @@ exports.run = async (message) => {
const watermark = "./assets/images/bandicam.png"; const watermark = "./assets/images/bandicam.png";
gm(image.data).size(async (error, size) => { gm(image.data).size(async (error, size) => {
if (error) throw error; if (error) throw error;
const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("North").resize(null, size.height).out("-layers", "composite"); const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("North").resize(null, size.height).out("-layers", "composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(data); const resultBuffer = await gmToBuffer(data);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -19,7 +19,7 @@ exports.run = async (message, args) => {
if (error) throw error; if (error) throw error;
gm(output).gravity("Center").trim().out("+repage").extent(size.width, size2.height + (size.width / 10)).stream(async (error, output2) => { gm(output).gravity("Center").trim().out("+repage").extent(size.width, size2.height + (size.width / 10)).stream(async (error, output2) => {
if (error) throw error; if (error) throw error;
const command3 = gm(output2).out("-alpha", "set").background("none").out("(").out(path).out("-coalesce").out(")").out("-set", "page", "%[fx:u.w]x%[fx:u.h+v.h]+%[fx:t?(u.w-v.w)/2:0]+%[fx:t?u.h:0]").out("-coalesce").out("null:").out("-insert", 1).out("-layers", "composite").out("-loop", "0"); const command3 = gm(output2).out("-alpha", "set").background("none").out("(").out(path).out("-coalesce").out(")").out("-set", "page", "%[fx:u.w]x%[fx:u.h+v.h]+%[fx:t?(u.w-v.w)/2:0]+%[fx:t?u.h:0]").out("-coalesce").out("null:").out("-insert", 1).out("-layers", "composite").out("-layers", "optimize");
const outputFinal = await gmToBuffer(command3, image.type); const outputFinal = await gmToBuffer(command3, image.type);
await processMessage.delete(); await processMessage.delete();
return message.channel.createMessage("", { return message.channel.createMessage("", {

View File

@ -10,7 +10,7 @@ exports.run = async (message) => {
const watermark = "./assets/images/deviantart.png"; const watermark = "./assets/images/deviantart.png";
gm(image.data).size(async (error, size) => { gm(image.data).size(async (error, size) => {
if (error) throw error; if (error) throw error;
const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("Center").resize(null, size.height).out("-layers", "composite"); const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("Center").resize(null, size.height).out("-layers", "composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(data); const resultBuffer = await gmToBuffer(data);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -10,7 +10,7 @@ exports.run = async (message) => {
const watermark = "./assets/images/funky.png"; const watermark = "./assets/images/funky.png";
gm(image.data).size(async (error, size) => { gm(image.data).size(async (error, size) => {
if (error) throw error; if (error) throw error;
const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("NorthEast").resize(null, size.height).out("-layers", "composite"); const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("NorthEast").resize(null, size.height).out("-layers", "composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(data); const resultBuffer = await gmToBuffer(data);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -11,7 +11,7 @@ exports.run = async (message) => {
const template = "./assets/images/gamexplain.png"; const template = "./assets/images/gamexplain.png";
const path = `/tmp/${Math.random().toString(36).substring(2, 15)}.${image.type}`; const path = `/tmp/${Math.random().toString(36).substring(2, 15)}.${image.type}`;
require("util").promisify(fs.writeFile)(path, image.data); require("util").promisify(fs.writeFile)(path, image.data);
const command = gm(template).background("white").out("null:").out("(").out(path).out("-virtual-pixel", "transparent").resize("1181x571!").coalesce().out(")").compose("over").gravity("Center").out("-geometry", "+0+40").out("-layers", "composite"); const command = gm(template).background("white").out("null:").out("(").out(path).out("-virtual-pixel", "transparent").resize("1181x571!").coalesce().out(")").compose("over").gravity("Center").out("-geometry", "+0+40").out("-layers", "composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(command, image.type); const resultBuffer = await gmToBuffer(command, image.type);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -17,7 +17,7 @@ exports.run = async (message) => {
if (error) throw error; if (error) throw error;
gm(data2).flop().write(data, async (error) => { gm(data2).flop().write(data, async (error) => {
if (error) throw error; if (error) throw error;
const command = gm(data2).out("-repage", `${size.width}x${size.height}`).coalesce().out("null:").out("(").out(data).coalesce().out(")").geometry(`+${size.width / 2}+0`).out("-layers", "Composite"); const command = gm(data2).out("-repage", `${size.width}x${size.height}`).coalesce().out("null:").out("(").out(data).coalesce().out(")").geometry(`+${size.width / 2}+0`).out("-layers", "Composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(command); const resultBuffer = await gmToBuffer(command);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -17,7 +17,7 @@ exports.run = async (message) => {
if (error) throw error; if (error) throw error;
gm(data2).flip().write(data, async (error) => { gm(data2).flip().write(data, async (error) => {
if (error) throw error; if (error) throw error;
const command = gm(data).out("-repage", `${size.width}x${size.height}`).coalesce().out("null:").out("(").out(data2).coalesce().out(")").geometry(`+0+${size.height / 2}`).out("-layers", "Composite"); const command = gm(data).out("-repage", `${size.width}x${size.height}`).coalesce().out("null:").out("(").out(data2).coalesce().out(")").geometry(`+0+${size.height / 2}`).out("-layers", "Composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(command); const resultBuffer = await gmToBuffer(command);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -10,7 +10,7 @@ exports.run = async (message) => {
const watermark = "./assets/images/hypercam.png"; const watermark = "./assets/images/hypercam.png";
gm(image.data).size(async (error, size) => { gm(image.data).size(async (error, size) => {
if (error) throw error; if (error) throw error;
const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("NorthWest").resize(null, size.height).out("-layers", "composite"); const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("NorthWest").resize(null, size.height).out("-layers", "composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(data); const resultBuffer = await gmToBuffer(data);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -10,7 +10,7 @@ exports.run = async (message) => {
const watermark = "./assets/images/ifunny.png"; const watermark = "./assets/images/ifunny.png";
gm(image.data).size(async (error, size) => { gm(image.data).size(async (error, size) => {
if (error) throw error; if (error) throw error;
const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("South").resize(size.width, null).out("-layers", "composite"); const data = gm(image.data).coalesce().out("null:").out(watermark).gravity("South").resize(size.width, null).out("-layers", "composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(data); const resultBuffer = await gmToBuffer(data);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -11,7 +11,7 @@ exports.run = async (message) => {
let resultBuffer; let resultBuffer;
gm(image.data).size(async (error, size) => { gm(image.data).size(async (error, size) => {
if (error) throw error; if (error) throw error;
const command = gm(image.data).coalesce().background("white").extent(size.width, size.height + 15).out("null:").out(watermark).gravity("SouthEast").compose("over").out("-layers", "composite"); const command = gm(image.data).coalesce().background("white").extent(size.width, size.height + 15).out("null:").out(watermark).gravity("SouthEast").compose("over").out("-layers", "composite").out("-layers", "optimize");
const output = await gmToBuffer(command, image.type); const output = await gmToBuffer(command, image.type);
gm(output).size(async (error, size2) => { gm(output).size(async (error, size2) => {
if (error) throw error; if (error) throw error;

View File

@ -11,7 +11,7 @@ exports.run = async (message) => {
const template = "./assets/images/scott.png"; const template = "./assets/images/scott.png";
const path = `/tmp/${Math.random().toString(36).substring(2, 15)}.${image.type}`; const path = `/tmp/${Math.random().toString(36).substring(2, 15)}.${image.type}`;
require("util").promisify(fs.writeFile)(path, image.data); require("util").promisify(fs.writeFile)(path, image.data);
const command = gm(template).out("null:").out("(").out(path).out("-virtual-pixel", "transparent").resize("415x234!").coalesce().out("+distort", "Perspective", "0,0 129,187 415,0 517,182 415,234 517,465 0,234 132,418").out(")").compose("over").gravity("Center").geometry("-238-98").out("-layers", "composite"); const command = gm(template).out("null:").out("(").out(path).out("-virtual-pixel", "transparent").resize("415x234!").coalesce().out("+distort", "Perspective", "0,0 129,187 415,0 517,182 415,234 517,465 0,234 132,418").out(")").compose("over").gravity("Center").geometry("-238-98").out("-layers", "composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(command, image.type); const resultBuffer = await gmToBuffer(command, image.type);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -10,7 +10,7 @@ exports.run = async (message) => {
const watermark = "./assets/images/shutterstock.png"; const watermark = "./assets/images/shutterstock.png";
gm(image.data).size(async (error, size) => { gm(image.data).size(async (error, size) => {
if (error) throw error; if (error) throw error;
const command = gm(image.data).coalesce().out("null:").out(watermark).gravity("Center").resize(null, size.height).out("-layers", "composite"); const command = gm(image.data).coalesce().out("null:").out(watermark).gravity("Center").resize(null, size.height).out("-layers", "composite").out("-layers", "optimize");
const output = await gmToBuffer(command); const output = await gmToBuffer(command);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: output, file: output,

View File

@ -11,7 +11,7 @@ exports.run = async (message) => {
const template = "./assets/images/trump.png"; const template = "./assets/images/trump.png";
const path = `/tmp/${Math.random().toString(36).substring(2, 15)}.${image.type}`; const path = `/tmp/${Math.random().toString(36).substring(2, 15)}.${image.type}`;
require("util").promisify(fs.writeFile)(path, image.data); require("util").promisify(fs.writeFile)(path, image.data);
const command = gm(template).background("white").out("null:").out("(").out(path).out("-virtual-pixel", "transparent").resize("365x179!").coalesce().out("+distort", "Perspective", "0,0 207,268 365,0 548,271 365,179 558,450 0,179 193,450").out(")").compose("over").gravity("Center").geometry("-217-135").out("-layers", "composite"); const command = gm(template).background("white").out("null:").out("(").out(path).out("-virtual-pixel", "transparent").resize("365x179!").coalesce().out("+distort", "Perspective", "0,0 207,268 365,0 548,271 365,179 558,450 0,179 193,450").out(")").compose("over").gravity("Center").geometry("-217-135").out("-layers", "composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(command, image.type); const resultBuffer = await gmToBuffer(command, image.type);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -17,7 +17,7 @@ exports.run = async (message) => {
if (error) throw error; if (error) throw error;
gm(data2).flop().write(data, async (error) => { gm(data2).flop().write(data, async (error) => {
if (error) throw error; if (error) throw error;
const command = gm(data).out("-repage", `${size.width}x${size.height}`).coalesce().out("null:").out("(").out(data2).coalesce().out(")").geometry(`+${size.width / 2}+0`).out("-layers", "Composite"); const command = gm(data).out("-repage", `${size.width}x${size.height}`).coalesce().out("null:").out("(").out(data2).coalesce().out(")").geometry(`+${size.width / 2}+0`).out("-layers", "Composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(command); const resultBuffer = await gmToBuffer(command);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -11,7 +11,7 @@ exports.run = async (message) => {
const template = "./assets/images/whodidthis.png"; const template = "./assets/images/whodidthis.png";
const path = `/tmp/${Math.random().toString(36).substring(2, 15)}.${image.type}`; const path = `/tmp/${Math.random().toString(36).substring(2, 15)}.${image.type}`;
require("util").promisify(fs.writeFile)(path, image.data); require("util").promisify(fs.writeFile)(path, image.data);
const command = gm(template).coalesce().out("null:").out(path).gravity("Center").resize("374x374>").out("-layers", "composite"); const command = gm(template).coalesce().out("null:").out(path).gravity("Center").resize("374x374>").out("-layers", "composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(command, image.type); const resultBuffer = await gmToBuffer(command, image.type);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

View File

@ -17,7 +17,7 @@ exports.run = async (message) => {
if (error) throw error; if (error) throw error;
gm(data2).flip().write(data, async (error) => { gm(data2).flip().write(data, async (error) => {
if (error) throw error; if (error) throw error;
const command = gm(data2).out("-repage", `${size.width}x${size.height}`).coalesce().out("null:").out("(").out(data).coalesce().out(")").geometry(`+0+${size.height / 2}`).out("-layers", "Composite"); const command = gm(data2).out("-repage", `${size.width}x${size.height}`).coalesce().out("null:").out("(").out(data).coalesce().out(")").geometry(`+0+${size.height / 2}`).out("-layers", "Composite").out("-layers", "optimize");
const resultBuffer = await gmToBuffer(command); const resultBuffer = await gmToBuffer(command);
return message.channel.createMessage("", { return message.channel.createMessage("", {
file: resultBuffer, file: resultBuffer,

54
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "esmbot", "name": "esmbot",
"version": "1.0.0", "version": "1.1.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -25,9 +25,9 @@
} }
}, },
"@types/node": { "@types/node": {
"version": "12.12.14", "version": "13.1.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.6.tgz",
"integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==" "integrity": "sha512-Jg1F+bmxcpENHP23sVKkNuU3uaxPnsBMW0cLjleiikFKomJQbsn0Cqk2yDvQArqzZN6ABfBkZ0To7pQ8sLdWDg=="
}, },
"acorn": { "acorn": {
"version": "6.1.1", "version": "6.1.1",
@ -160,11 +160,6 @@
"lodash": "^4.17.11" "lodash": "^4.17.11"
} }
}, },
"async-limiter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
},
"asynckit": { "asynckit": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@ -710,13 +705,13 @@
"integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==" "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA=="
}, },
"eris": { "eris": {
"version": "0.11.1", "version": "0.11.2",
"resolved": "https://registry.npmjs.org/eris/-/eris-0.11.1.tgz", "resolved": "https://registry.npmjs.org/eris/-/eris-0.11.2.tgz",
"integrity": "sha512-Ct32iXjESOnmklxZCEA281BQsTlAsS9xzQkbGlnvzXshCjBptWJ5h8Oxbu67ui1DirsYs0WipB8EBC9ITQ5ZQA==", "integrity": "sha512-OhccRcxrPiNUylTamrjIbZM6itKMLjNrwLIXGvNwQZj4CRVOOz9eUVIqOJULB713x1ezw7HoC8AEsnsMNUneDA==",
"requires": { "requires": {
"opusscript": "^0.0.4", "opusscript": "^0.0.7",
"tweetnacl": "^1.0.0", "tweetnacl": "^1.0.1",
"ws": "^7.1.2" "ws": "^7.2.1"
} }
}, },
"erlpack": { "erlpack": {
@ -1538,9 +1533,9 @@
"integrity": "sha512-cBMXjSW+fjOb4tyaVHuaVE/A5TqkukDWiOfxxAjY+PEqmmBQlLwn+8OzwPiG3brouXKY5Un4pBjAeB6UToXHaQ==" "integrity": "sha512-cBMXjSW+fjOb4tyaVHuaVE/A5TqkukDWiOfxxAjY+PEqmmBQlLwn+8OzwPiG3brouXKY5Un4pBjAeB6UToXHaQ=="
}, },
"mongodb": { "mongodb": {
"version": "3.3.5", "version": "3.4.1",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.3.5.tgz", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.4.1.tgz",
"integrity": "sha512-6NAv5gTFdwRyVfCz+O+KDszvjpyxmZw+VlmqmqKR2GmpkeKrKFRv/ZslgTtZba2dc9JYixIf99T5Gih7TIWv7Q==", "integrity": "sha512-juqt5/Z42J4DcE7tG7UdVaTKmUC6zinF4yioPfpeOSNBieWSK6qCY+0tfGQcHLKrauWPDdMZVROHJOa8q2pWsA==",
"requires": { "requires": {
"bson": "^1.1.1", "bson": "^1.1.1",
"require_optional": "^1.0.1", "require_optional": "^1.0.1",
@ -1549,13 +1544,13 @@
} }
}, },
"mongoose": { "mongoose": {
"version": "5.7.13", "version": "5.8.6",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.7.13.tgz", "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.8.6.tgz",
"integrity": "sha512-MoTCETTIfXU1PqIYc+YAkhSB3uzK5xseh6ysAUnoOowkqS66OjBJtsL/bcgAKi6XfMYkFU6M1abKyuL7k//xeg==", "integrity": "sha512-DbmcaD5skOojIlUrd78fXTI3FsF711CX8jaLdKGtL/7/N0rbPpjwyLXIYiHkq146DGkIDeBDLEPlcl6zfkjM6A==",
"requires": { "requires": {
"bson": "~1.1.1", "bson": "~1.1.1",
"kareem": "2.3.1", "kareem": "2.3.1",
"mongodb": "3.3.5", "mongodb": "3.4.1",
"mongoose-legacy-pluralize": "1.0.2", "mongoose-legacy-pluralize": "1.0.2",
"mpath": "0.6.0", "mpath": "0.6.0",
"mquery": "3.2.2", "mquery": "3.2.2",
@ -1798,9 +1793,9 @@
} }
}, },
"opusscript": { "opusscript": {
"version": "0.0.4", "version": "0.0.7",
"resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.4.tgz", "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.7.tgz",
"integrity": "sha512-bEPZFE2lhUJYQD5yfTFO4RhbRZ937x6hRwBC1YoGacT35bwDVwKFP1+amU8NYfZL/v4EU7ZTU3INTqzYAnuP7Q==", "integrity": "sha512-DcBadTdYTUuH9zQtepsLjQn4Ll6rs3dmeFvN+SD0ThPnxRBRm/WC1zXWPg+wgAJimB784gdZvUMA57gDP7FdVg==",
"optional": true "optional": true
}, },
"os-homedir": { "os-homedir": {
@ -2826,12 +2821,9 @@
} }
}, },
"ws": { "ws": {
"version": "7.2.0", "version": "7.2.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.2.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz",
"integrity": "sha512-+SqNqFbwTm/0DC18KYzIsMTnEWpLwJsiasW/O17la4iDRRIO9uaHbvKiAS3AHgTiuuWerK/brj4O6MYZkei9xg==", "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A=="
"requires": {
"async-limiter": "^1.0.0"
}
}, },
"xtend": { "xtend": {
"version": "4.0.1", "version": "4.0.1",

View File

@ -17,13 +17,13 @@
"dblapi.js": "^2.3.0", "dblapi.js": "^2.3.0",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"eris": "^0.11.1", "eris": "^0.11.2",
"file-type": "^10.9.0", "file-type": "^10.9.0",
"gm": "^1.23.1", "gm": "^1.23.1",
"jsqr": "^1.2.0", "jsqr": "^1.2.0",
"moment": "^2.24.0", "moment": "^2.24.0",
"moment-duration-format": "^2.3.2", "moment-duration-format": "^2.3.2",
"mongoose": "^5.7.13", "mongoose": "^5.8.6",
"node-fetch": "^2.6.0", "node-fetch": "^2.6.0",
"qrcode": "^1.4.4", "qrcode": "^1.4.4",
"retrotext": "github:TheEssem/retrotext", "retrotext": "github:TheEssem/retrotext",