From bc346138dd82a4a1341d3a5d4bc64652effda8f8 Mon Sep 17 00:00:00 2001 From: night0721 Date: Sat, 12 Jun 2021 18:53:51 +0800 Subject: [PATCH] Bot --- .env.example | 16 + .gitignore | 14 + .replit | 2 + Procfile | 1 + cat/Path/fantastic.js | 17 + cat/Path/fight.js | 35 + cat/Path/gae.js | 41 + cat/Path/gg.js | 30 + cat/Path/how.js | 29 + cat/Path/nab.js | 34 + cat/Path/pp.js | 24 + commands/Config/check.js | 32 + commands/Config/choices.js | 127 + commands/Config/cmd-list.js | 25 + commands/Config/create.js | 434 +++ commands/Config/delete.js | 25 + commands/Config/disable.js | 53 + commands/Config/enable.js | 48 + commands/Config/migrate.js | 26 + commands/Config/modmail-category.js | 35 + commands/Config/modmail-role.js | 32 + commands/Config/panel.js | 33 + commands/Config/prefix-reset.js | 41 + commands/Config/prefix.js | 37 + commands/Config/premium.js | 63 + commands/Config/rr-add.js | 50 + commands/Config/rr-rmv.js | 39 + commands/Config/set.js | 34 + commands/Economy/bal.js | 34 + commands/Economy/bet.js | 48 + commands/Economy/blackjack.js | 290 ++ commands/Economy/buy.js | 71 + commands/Economy/daily.js | 51 + commands/Economy/drop.js | 41 + commands/Economy/gift.js | 103 + commands/Economy/give.js | 45 + commands/Economy/inv.js | 51 + commands/Economy/lb.js | 39 + commands/Economy/shop.js | 33 + commands/Economy/slots.js | 92 + commands/Economy/steal.js | 122 + commands/Economy/work.js | 29 + commands/Fun/cat.js | 30 + commands/Fun/coinflip.js | 22 + commands/Fun/connect4.js | 309 ++ commands/Fun/dog.js | 30 + commands/Fun/hangman.js | 92 + commands/Fun/hug.js | 34 + commands/Fun/kiss.js | 34 + commands/Fun/meme.js | 30 + commands/Fun/say.js | 17 + commands/Fun/simprate.js | 31 + commands/Giveaway/end.js | 22 + commands/Giveaway/giveaway.js | 52 + commands/Giveaway/reroll.js | 21 + commands/Moderation/announce.js | 45 + commands/Moderation/ban.js | 59 + commands/Moderation/clear.js | 47 + commands/Moderation/clearWarns.js | 48 + commands/Moderation/kick.js | 52 + commands/Moderation/lock.js | 33 + commands/Moderation/mute.js | 146 + commands/Moderation/nuke.js | 59 + commands/Moderation/removeWarn.js | 58 + commands/Moderation/role.js | 57 + commands/Moderation/slowmode.js | 62 + commands/Moderation/unban.js | 35 + commands/Moderation/unlock.js | 32 + commands/Moderation/unmute.js | 52 + commands/Moderation/warn.js | 64 + commands/Moderation/warns.js | 53 + commands/Music/leave.js | 35 + commands/Music/loop.js | 26 + commands/Music/lyrics.js | 42 + commands/Music/nowplaying.js | 25 + commands/Music/pause.js | 29 + commands/Music/play.js | 204 ++ commands/Music/playlist.js | 201 ++ commands/Music/queue.js | 52 + commands/Music/remove.js | 35 + commands/Music/resume.js | 28 + commands/Music/shuffle.js | 29 + commands/Music/skip.js | 37 + commands/Music/skipto.js | 46 + commands/Music/stop.js | 29 + commands/Music/volume.js | 35 + commands/Owner/accept.js | 43 + commands/Owner/add.js | 20 + commands/Owner/blacklist.js | 31 + commands/Owner/deny.js | 41 + commands/Owner/dm.js | 25 + commands/Owner/encrypt.js | 45 + commands/Owner/eval.js | 47 + commands/Owner/getinvite.js | 50 + commands/Owner/guilds.js | 29 + commands/Owner/premium.js | 22 + commands/Owner/reaction-role.js | 56 + commands/Owner/restart.js | 19 + commands/Owner/rmv.js | 20 + commands/Owner/setBotAvatar.js | 25 + commands/Owner/try.js | 63 + commands/Utilities/8ball.js | 61 + commands/Utilities/afk.js | 31 + commands/Utilities/avatar.js | 54 + commands/Utilities/botinfo.js | 54 + commands/Utilities/choose.js | 20 + commands/Utilities/emoji.js | 26 + commands/Utilities/emojiadd.js | 58 + commands/Utilities/esnipe.js | 162 + commands/Utilities/help.js | 317 ++ commands/Utilities/hexcolor.js | 84 + commands/Utilities/invite.js | 18 + commands/Utilities/modmail.js | 138 + commands/Utilities/permission.js | 110 + commands/Utilities/poll.js | 80 + commands/Utilities/report.js | 85 + commands/Utilities/roleinfo.js | 90 + commands/Utilities/servericon.js | 21 + commands/Utilities/serverinfo.js | 120 + commands/Utilities/snipe.js | 79 + commands/Utilities/support.js | 16 + commands/Utilities/timer.js | 66 + commands/Utilities/userinfo.js | 123 + config.json | 12 + events/afk.js | 39 + events/emoji.js | 56 + events/goodBye.js | 68 + events/guild.js | 46 + events/guildCreate.js | 30 + events/guildDelete.js | 42 + events/level.js | 27 + events/message.js | 265 ++ events/messageUpdate.js | 69 + events/messsageDelete.js | 31 + events/reactionroles.js | 30 + events/ready.js | 31 + events/slash.js | 35 + index.js | 108 + inlinereply.js | 51 + models/custom-commands.js | 11 + models/econ.js | 15 + models/guilds.js | 36 + models/inventory.js | 27 + models/level.js | 11 + models/modmail.js | 11 + models/reaction.js | 10 + models/users.js | 31 + models/warns.js | 12 + package-lock.json | 4696 +++++++++++++++++++++++++++ package.json | 75 + util/Data/giveaways.json | 1 + util/Data/rank.js | 51 + util/Data/triggered.js | 23 + util/command-handler.js | 44 + util/err.js | 207 ++ util/functions/common.js | 767 +++++ util/functions/function.js | 8 + util/functions/mongoose.js | 475 +++ util/item.js | 68 + util/pagify.js | 119 + util/pagination.js | 55 + 161 files changed, 14947 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 .replit create mode 100644 Procfile create mode 100644 cat/Path/fantastic.js create mode 100644 cat/Path/fight.js create mode 100644 cat/Path/gae.js create mode 100644 cat/Path/gg.js create mode 100644 cat/Path/how.js create mode 100644 cat/Path/nab.js create mode 100644 cat/Path/pp.js create mode 100644 commands/Config/check.js create mode 100644 commands/Config/choices.js create mode 100644 commands/Config/cmd-list.js create mode 100644 commands/Config/create.js create mode 100644 commands/Config/delete.js create mode 100644 commands/Config/disable.js create mode 100644 commands/Config/enable.js create mode 100644 commands/Config/migrate.js create mode 100644 commands/Config/modmail-category.js create mode 100644 commands/Config/modmail-role.js create mode 100644 commands/Config/panel.js create mode 100644 commands/Config/prefix-reset.js create mode 100644 commands/Config/prefix.js create mode 100644 commands/Config/premium.js create mode 100644 commands/Config/rr-add.js create mode 100644 commands/Config/rr-rmv.js create mode 100644 commands/Config/set.js create mode 100644 commands/Economy/bal.js create mode 100644 commands/Economy/bet.js create mode 100644 commands/Economy/blackjack.js create mode 100644 commands/Economy/buy.js create mode 100644 commands/Economy/daily.js create mode 100644 commands/Economy/drop.js create mode 100644 commands/Economy/gift.js create mode 100644 commands/Economy/give.js create mode 100644 commands/Economy/inv.js create mode 100644 commands/Economy/lb.js create mode 100644 commands/Economy/shop.js create mode 100644 commands/Economy/slots.js create mode 100644 commands/Economy/steal.js create mode 100644 commands/Economy/work.js create mode 100644 commands/Fun/cat.js create mode 100644 commands/Fun/coinflip.js create mode 100644 commands/Fun/connect4.js create mode 100644 commands/Fun/dog.js create mode 100644 commands/Fun/hangman.js create mode 100644 commands/Fun/hug.js create mode 100644 commands/Fun/kiss.js create mode 100644 commands/Fun/meme.js create mode 100644 commands/Fun/say.js create mode 100644 commands/Fun/simprate.js create mode 100644 commands/Giveaway/end.js create mode 100644 commands/Giveaway/giveaway.js create mode 100644 commands/Giveaway/reroll.js create mode 100644 commands/Moderation/announce.js create mode 100644 commands/Moderation/ban.js create mode 100644 commands/Moderation/clear.js create mode 100644 commands/Moderation/clearWarns.js create mode 100644 commands/Moderation/kick.js create mode 100644 commands/Moderation/lock.js create mode 100644 commands/Moderation/mute.js create mode 100644 commands/Moderation/nuke.js create mode 100644 commands/Moderation/removeWarn.js create mode 100644 commands/Moderation/role.js create mode 100644 commands/Moderation/slowmode.js create mode 100644 commands/Moderation/unban.js create mode 100644 commands/Moderation/unlock.js create mode 100644 commands/Moderation/unmute.js create mode 100644 commands/Moderation/warn.js create mode 100644 commands/Moderation/warns.js create mode 100644 commands/Music/leave.js create mode 100644 commands/Music/loop.js create mode 100644 commands/Music/lyrics.js create mode 100644 commands/Music/nowplaying.js create mode 100644 commands/Music/pause.js create mode 100644 commands/Music/play.js create mode 100644 commands/Music/playlist.js create mode 100644 commands/Music/queue.js create mode 100644 commands/Music/remove.js create mode 100644 commands/Music/resume.js create mode 100644 commands/Music/shuffle.js create mode 100644 commands/Music/skip.js create mode 100644 commands/Music/skipto.js create mode 100644 commands/Music/stop.js create mode 100644 commands/Music/volume.js create mode 100644 commands/Owner/accept.js create mode 100644 commands/Owner/add.js create mode 100644 commands/Owner/blacklist.js create mode 100644 commands/Owner/deny.js create mode 100644 commands/Owner/dm.js create mode 100644 commands/Owner/encrypt.js create mode 100644 commands/Owner/eval.js create mode 100644 commands/Owner/getinvite.js create mode 100644 commands/Owner/guilds.js create mode 100644 commands/Owner/premium.js create mode 100644 commands/Owner/reaction-role.js create mode 100644 commands/Owner/restart.js create mode 100644 commands/Owner/rmv.js create mode 100644 commands/Owner/setBotAvatar.js create mode 100644 commands/Owner/try.js create mode 100644 commands/Utilities/8ball.js create mode 100644 commands/Utilities/afk.js create mode 100644 commands/Utilities/avatar.js create mode 100644 commands/Utilities/botinfo.js create mode 100644 commands/Utilities/choose.js create mode 100644 commands/Utilities/emoji.js create mode 100644 commands/Utilities/emojiadd.js create mode 100644 commands/Utilities/esnipe.js create mode 100644 commands/Utilities/help.js create mode 100644 commands/Utilities/hexcolor.js create mode 100644 commands/Utilities/invite.js create mode 100644 commands/Utilities/modmail.js create mode 100644 commands/Utilities/permission.js create mode 100644 commands/Utilities/poll.js create mode 100644 commands/Utilities/report.js create mode 100644 commands/Utilities/roleinfo.js create mode 100644 commands/Utilities/servericon.js create mode 100644 commands/Utilities/serverinfo.js create mode 100644 commands/Utilities/snipe.js create mode 100644 commands/Utilities/support.js create mode 100644 commands/Utilities/timer.js create mode 100644 commands/Utilities/userinfo.js create mode 100644 config.json create mode 100644 events/afk.js create mode 100644 events/emoji.js create mode 100644 events/goodBye.js create mode 100644 events/guild.js create mode 100644 events/guildCreate.js create mode 100644 events/guildDelete.js create mode 100644 events/level.js create mode 100644 events/message.js create mode 100644 events/messageUpdate.js create mode 100644 events/messsageDelete.js create mode 100644 events/reactionroles.js create mode 100644 events/ready.js create mode 100644 events/slash.js create mode 100644 index.js create mode 100644 inlinereply.js create mode 100644 models/custom-commands.js create mode 100644 models/econ.js create mode 100644 models/guilds.js create mode 100644 models/inventory.js create mode 100644 models/level.js create mode 100644 models/modmail.js create mode 100644 models/reaction.js create mode 100644 models/users.js create mode 100644 models/warns.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 util/Data/giveaways.json create mode 100644 util/Data/rank.js create mode 100644 util/Data/triggered.js create mode 100644 util/command-handler.js create mode 100644 util/err.js create mode 100644 util/functions/common.js create mode 100644 util/functions/function.js create mode 100644 util/functions/mongoose.js create mode 100644 util/item.js create mode 100644 util/pagify.js create mode 100644 util/pagination.js diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..b3d76d3 --- /dev/null +++ b/.env.example @@ -0,0 +1,16 @@ +TOKEN = +MONGO = +CLIENT_SECRET = +CLIENT_ID = +PORT = +REDIRECT = +DMLogID = +DMLogToken = +CMDLogID = +CMDLogToken = +ReadyLogID = +ReadyLogToken = +ErrorLogID = +ErrorLogToken = +ServerLogID = +ServerLogToken = \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..666ed82 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +node_modules/ +/.env +/commands/CODM/ +/dashboard/ +/util/Data/aliases.json +/util/Data/attachments.json +/util/Data/builds.json +/util/Data/data.json +/util/Data/perk.json +/util/Data/skins.json +/util/Data/weapons.json +/util/functions/common.json +/util/bash.sh +/bot.js \ No newline at end of file diff --git a/.replit b/.replit new file mode 100644 index 0000000..0502834 --- /dev/null +++ b/.replit @@ -0,0 +1,2 @@ +"language"="nodejs" +"run"="node ." \ No newline at end of file diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..973094b --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +worker: node index.js \ No newline at end of file diff --git a/cat/Path/fantastic.js b/cat/Path/fantastic.js new file mode 100644 index 0000000..430d863 --- /dev/null +++ b/cat/Path/fantastic.js @@ -0,0 +1,17 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "fantastic", + timeout: 60000, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + message.delete(); + const player = args.join(" "); + message.channel.send( + `${player} is a fantastic CoDM player. Just need to work on communication, map awareness, info scouting, bomb plants, positioning, teamfighting, gun skill , utility usage, rotations and getting kills.` + ); + }, +}; diff --git a/cat/Path/fight.js b/cat/Path/fight.js new file mode 100644 index 0000000..d212c13 --- /dev/null +++ b/cat/Path/fight.js @@ -0,0 +1,35 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "fight", + description: "Gooooooooooooooooooolag!", + timeout: 10000, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const Fight = [ + "`Snow Gae`", + "`Not Gae`", + "`Ultimate Gae`", + "`Gae`", + "`Gae beyond repair`", + "`Akimbo Gae`", + "`Mega Gae`", + "`Super Gae`", + "`Ultra Gae`", + "`Terminal Gae`", + "`Dead`", + "`Path Gae`", + "`Cheez Gae`", + "`Zero Gae`", + "`KDR Gae`", + "`! not Gae`", + ]; + const fightIndex = Fight[Math.floor(Math.random() * Fight.length)]; + message.channel.send( + `**You have taken a chance at redemption in The Gulag, you fight only to find out that you're ${fightIndex}. If you somehow turned out to not be gae, DM an admin to get unmuted early you lucky bastard!!**` + ); + }, +}; diff --git a/cat/Path/gae.js b/cat/Path/gae.js new file mode 100644 index 0000000..4b04293 --- /dev/null +++ b/cat/Path/gae.js @@ -0,0 +1,41 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "gae", + timeout: 15000, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const MEE6 = [ + "u = gae", + "pLeaSe gAE", + "REEEEEEEEEEEEEEEEEEEEEE*GAE*EEEEEEEEEEEEEEEEEEEEEEEEEEE", + "Enough with the gae jokes, U gae", + "Plain ol' gae", + "", + "By the way, Deity bot is my senpai.\nShe is the most beautiful bot I've ever seen <3", + "aight imma gae out", + "*gae with extra steps*", + "**wae r u gae**", + "u gae bro?", + "**100%** gae", + "I bet you do **tiktok**", + "**G.A.E.**", + "The next person to chat is gae", + "Whoever used C.gae, is **gae**", + "*Its ok to be gae*", + "*succ my* **cheez**", + "**gae gae gae gae gae gae**", + "**Be gae**", + "There's no cooldown so y'all get muted for being *gae*", + "Ok stop using this command, really. U gae?", + "What the hell, u gae?", + "**GAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE**", + ]; + const MEE6Index = MEE6[Math.floor(Math.random() * MEE6.length)]; + message.delete(); + message.channel.send(`${MEE6Index}`); + }, +}; diff --git a/cat/Path/gg.js b/cat/Path/gg.js new file mode 100644 index 0000000..ace24fb --- /dev/null +++ b/cat/Path/gg.js @@ -0,0 +1,30 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "gg", + timeout: 15000, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const GG = [ + "**GIT GUD**", + "Git gud kid", + "good game *question mark*", + "gg l0ser", + "delet cod gg", + "*ggwp*", + "I was lagging doe", + "```Stop using this command```", + " ez pz ", + "", + "**GOOD GAME WELL PLAYED**", + " get rektd ", + "", + ]; + const GGIndex = GG[Math.floor(Math.random() * GG.length)]; + message.delete(); + message.channel.send(`${GGIndex}`); + }, +}; diff --git a/cat/Path/how.js b/cat/Path/how.js new file mode 100644 index 0000000..931939a --- /dev/null +++ b/cat/Path/how.js @@ -0,0 +1,29 @@ +const { MessageEmbed } = require("discord.js"); +module.exports = { + name: "howgae", + description: "Check how gae is the user", + usage: "(User)", + Path: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const target = message.mentions.users.first() || message.author; + if (target.id === "366562874039992331") { + message.channel.send( + new MessageEmbed() + .setTitle(`${target.username}'s gae rate`) + .setDescription(`You are 69420% gae`) + ); + } else { + let simp = Math.floor(Math.random() * 100); + message.channel.send( + new MessageEmbed() + .setTitle(`${target.username}'s gae rate`) + .setDescription(`You are ${simp}% gae`) + ); + } + }, +}; diff --git a/cat/Path/nab.js b/cat/Path/nab.js new file mode 100644 index 0000000..cfde741 --- /dev/null +++ b/cat/Path/nab.js @@ -0,0 +1,34 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "nab", + timeout: 15000, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const NAB = [ + "stop being a nab, nab", + "Lmao you a nab", + "Biggest nab of all time", + "You're just a nab", + "Okay calm down nab", + "**Stop** spamming this command you **nab**", + "```I told you to stop spamming this command nab```", + "Get rekt nab XD Jajajajajaja", + "**N.A.B.**", + "Better luck next time nab", + "Ooooh look at me im better than you nab", + "Whoever used C.nab, is a nab", + "Stfu nab", + "**you cant aim**", + "*bonjour* nab", + "u = ", + "Go back to tiktok ", + ]; + const NABIndex = NAB[Math.floor(Math.random() * NAB.length)]; + message.delete(); + message.channel.send(`${NABIndex}`); + }, +}; diff --git a/cat/Path/pp.js b/cat/Path/pp.js new file mode 100644 index 0000000..8168639 --- /dev/null +++ b/cat/Path/pp.js @@ -0,0 +1,24 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "pp", + description: "Check how long is the user", + usage: "(User)", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let user = message.mentions.users.first() || message.author; + let embed = new MessageEmbed() + .addField( + `${user.username}\'s peepee`, + `8${"=".repeat(Math.floor(Math.random() * 20))}D` + ) + .setColor(client.color) + .setTitle("Peepee size machine") + .setTimestamp() + .setFooter(`Made by Cath Team`); + message.inlineReply(embed); + }, +}; diff --git a/commands/Config/check.js b/commands/Config/check.js new file mode 100644 index 0000000..46d379e --- /dev/null +++ b/commands/Config/check.js @@ -0,0 +1,32 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "check", + description: "Check Goodbye/Welcome/Log Channel for the server", + usage: "(goodbye/welcome/log) (Channel)", + UserPerm: "ADMINISTRATOR", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const data = await client.data.getGuild(message.guild.id); + if (!args[0]) return client.err(messgae, "Config", "check", 45); + if (args[0].toLowerCase() === "goodbye") { + const goodbye = data.Goodbye; + if (goodbye === "null") return client.err(messgae, "Config", "check", 10); + else message.channel.send(`The goodbye channel is <#${goodbye}>`); + } else if (args[0].toLowerCase() === "log") { + const log = data.Log; + if (log === "null") return client.err(messgae, "Config", "check", 10); + else message.channel.send(`The log channel is <#${log}>`); + } else if (args[0].toLowerCase() === "welcome") { + const welcome = data.Welcome; + if (welcome === "null") return client.err(messgae, "Config", "check", 10); + else message.channel.send(`The welcome channel is <#${welcome}>`); + } else { + return client.err(messgae, "Config", "check", 45); + } + }, +}; diff --git a/commands/Config/choices.js b/commands/Config/choices.js new file mode 100644 index 0000000..9b37b39 --- /dev/null +++ b/commands/Config/choices.js @@ -0,0 +1,127 @@ +const schema = require("../../models/modmail"); +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "choices", + UserPerm: "ADMINISTRATOR", + description: "Add choices for modmail in a server", + usage: "(add/list/rmv) (Emoji) {Text}", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + schema.findOne({ Guild: message.guild.id }, async (err, data) => { + if (data) return; + else { + new schema({ + Guild: message.guild.id, + }).save(); + } + }); + if (args[0].toLowerCase() === "add") { + if (!args[1]) return client.err(message, "Config", "choices", 11); + if (!args[2]) return client.err(message, "Config", "choices", 12); + if (!args.slice(2).join(" ").length > 100) + return client.err(message, "Config", "choices", 13); + const config = await schema.findOne({ Guild: message.guild.id }); + if ( + !config || + !config.Choices || + !Object.entries(config.Choices).length + ) { + const choices = { + 0: { + emoji: args[1], + text: args.slice(2).join(" "), + }, + }; + schema.findOne({ Guild: message.guild.id }, async (err, data) => { + if (data) { + if (data.Choices) { + data.Choices = choices; + await schema.findOneAndUpdate({ Guild: message.guild.id }, data); + } else if (data.Guild) { + data.Choices = choices; + await schema.findOneAndUpdate({ Guild: message.guild.id }, data); + } else { + new schema({ + Guild: message.guild.id, + Choices: choices, + }).save(); + } + } + }); + return message.channel.send( + `${message.author.tag} has added ${args[1]} as a modmail choice` + ); + } else { + const choices = Object.entries(config.Choices); + if (choices.length >= 5) + return client.err(message, "Config", "choices", 14); + const last = choices[choices.length - 1]; + const parsed = config.Choices; + parsed[(parseInt(last[0]) + 1).toString()] = { + emoji: args[1], + text: args.slice(2).join(" "), + }; + schema.findOne({ Guild: message.guild.id }, async (err, data) => { + if (data) { + data.Choices = parsed; + await schema.findOneAndUpdate({ Guild: message.guild.id }, data); + } else { + new schema({ + Guild: message.guild.id, + Choices: parsed, + }).save(); + } + }); + return message.channel.send( + `${message.author.tag} has added ${args[1]} as a modmail choice` + ); + } + } + if (args[0].toLowerCase() === "list") { + const Data = await schema.findOne({ Guild: message.guild.id }); + if (!Data || !Data.Choices || !Object.entries(Data.Choices).length) + return client.err(message, "Config", "choices", 10); + else + return message.channel.send( + Object.entries(Data.Choices) + .map(value => { + return `${value[1].emoji}: ${value[1].text}`; + }) + .join("\n") + ); + } + if (args[0].toLowerCase() === "rmv") { + if (!args[1]) return client.err(message, "Config", "choices", 11); + schema.findOne({ Guild: message.guild.id }, async (err, data) => { + if (!data || !data.Choices || !Object.entries(data.Choices).length) + return client.err(message, "Config", "choices", 10); + const choices = Object.entries(data.Choices); + const found = choices.find(value => value[1].emoji == args[1]); + if (!found) return client.err(message, "Config", "choices", 15); + const filtered = choices.filter(value => value[1].emoji != args[1]); + const parsed = {}; + filtered.map(value => { + parsed[value[0]] = { + emoji: value[1].emoji, + text: value[1].text, + }; + }); + if (data) { + data.Choices = parsed; + await schema.findOneAndUpdate({ Guild: message.guild.id }, data); + } else { + new schema({ + Guild: message.guild.id, + Choices: parsed, + }).save(); + } + }); + return message.channel.send(`${args[1]} is removed from choices.`); + } + }, +}; diff --git a/commands/Config/cmd-list.js b/commands/Config/cmd-list.js new file mode 100644 index 0000000..ebd11ce --- /dev/null +++ b/commands/Config/cmd-list.js @@ -0,0 +1,25 @@ +const schema = require("../../models/custom-commands"); +const { MessageEmbed } = require("discord.js"); + +module.exports = { + name: "cc-list", + UserPerm: "ADMINISTRATOR", + description: "Check the custom commands in a server", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const data = await schema.find({ Guild: message.guild.id }); + if (!!data === false) return client.err(messgae, "Config", "cmd-list", 10); + message.channel.send( + new MessageEmbed() + .setColor(client.color) + .setDescription( + data.map((cmd, i) => `${i + 1}: ${cmd.Command}`).join("\n") + ) + ); + }, +}; diff --git a/commands/Config/create.js b/commands/Config/create.js new file mode 100644 index 0000000..4377385 --- /dev/null +++ b/commands/Config/create.js @@ -0,0 +1,434 @@ +const Discord = require("discord.js"); +const db = require("../../models/custom-commands"); + +module.exports = { + name: "cc-create", + UserPerm: "ADMINISTRATOR", + description: "Crate custom commands for a server", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + message.delete(); + message.channel.send( + new Discord.MessageEmbed() + .setTitle(`Setup | 1/3`) + .setDescription( + "What is the name of the command?\nYou can cancel the setup at any time by sending `cancel`." + ) + .setColor(client.color) + ); + await startMessageCollectors(client, message, args); + function startMessageCollectors(client, message, args) { + let nameFilter = m => m.author.id === message.author.id; + let nameCollector = new Discord.MessageCollector( + message.channel, + nameFilter, + { max: 999 } + ); + nameCollector.on("collect", async msg => { + let name = msg.content.toLowerCase(); + const data = await db.findOne({ + Guild: message.guild.id, + Command: name, + }); + if (data) { + nameCollector.stop(); + return message.inlineReply("This command has already exist."); + } + if (name === "cancel") { + msg.channel.send("The setup has been cancelled."); + db.findOneAndDelete({ Guild: message.guild.id, Command: name }); + nameCollector.stop(); + return; + } + if (!name) { + await msg.channel.send("You don't specify a name. Cancelled setup."); + nameCollector.stop(); + return; + } else { + const newDB = new db({ + Guild: message.guild.id, + Command: name, + }); + await newDB.save(); + console.log(newDB); + msg.channel.send( + new Discord.MessageEmbed() + .setTitle(`Setup | 2/3`) + .setDescription( + `The command name will be **${name}**.\nWhat is the response for the command? You can have mutliple response by joning them with differnt lines.` + ) + .setColor(client.color) + ); + nameCollector.stop(); + } + let responseFilter = m => m.author.id === message.author.id; + let responseCollector = new Discord.MessageCollector( + message.channel, + responseFilter, + { max: 999 } + ); + responseCollector.on("collect", async msg => { + let response = msg.content.split("\n"); + console.log(`Response: ${response}`); + + if (msg.content.toLowerCase() === "cancel") { + msg.channel.send("The setup has been cancelled."); + responseCollector.stop(); + return; + } + if (!response) { + msg.channel.send(`You didn't specify a response. Setup cancelled.`); + responseCollector.stop(); + } + if (response.length > 1) { + responseCollector.stop(); + await db.findOne( + { Guild: message.guild.id, Command: name }, + async (err, data) => { + if (data) { + data.Response = response; + await db.findOneAndUpdate( + { Guild: message.guild.id, Command: name }, + data + ); + console.log(data); + } + } + ); + msg.channel.send( + new Discord.MessageEmbed() + .setTitle(`Setup | 3/4`) + .setColor(client.color) + .setDescription( + `Ok so there will be ${response.length} responses. Do you want the response be randomized?\n\`Type yes or no\` \nIf you choose no, accumlative responses may let the command can\'t be sent out.` + ) + ); + let randomFilter = m => m.author.id === message.author.id; + let randomCollector = new Discord.MessageCollector( + message.channel, + randomFilter, + { max: 999 } + ); + randomCollector.on("collect", async msg => { + let maybe; + if (msg.content.toLowerCase() === "yes") { + msg.channel.send( + new Discord.MessageEmbed() + .setColor(client.color) + .setTitle(`Setup | 4/4`) + .setDescription( + `The responses will be randomized. Do you want to have delete command usage? \`Type yes or no\`` + ) + ); + randomCollector.stop(); + maybe = true; + await db.findOne( + { + Guild: message.guild.id, + Response: response, + Command: name, + }, + async (err, data) => { + if (data) { + data.Random = maybe; + await db.findOneAndUpdate( + { + Guild: message.guild.id, + Command: name, + Response: response, + }, + data + ); + console.log(data); + } + } + ); + console.log(`Random: ${maybe}`); + let deleteeeFilter = m => m.author.id === message.author.id; + let deleteeeCollector = new Discord.MessageCollector( + message.channel, + deleteeeFilter, + { max: 999 } + ); + deleteeeCollector.on("collect", async msg => { + let idkwor; + if (msg.content.toLowerCase() === "yes") { + deleteeeCollector.stop(); + idkwor = true; + await db.findOne( + { + Guild: message.guild.id, + Command: name, + Response: response, + Random: maybe, + }, + async (err, data) => { + if (data) { + data.Delete = idkwor; + await db.findOneAndUpdate( + { + Guild: message.guild.id, + Command: name, + Response: response, + Random: maybe, + }, + data + ); + console.log(data); + msg.inlineReply( + `Saved **${data.Command}** as a custom command` + ); + } + } + ); + console.log(`Usage Delete: ${idkwor}`); + } + if (msg.content.toLowerCase() === "no") { + deleteeeCollector.stop(); + idkwor = false; + await db.findOne( + { + Guild: message.guild.id, + Command: name, + Response: response, + Random: maybe, + }, + async (err, data) => { + if (data) { + data.Delete = idkwor; + await db.findOneAndUpdate( + { + Guild: message.guild.id, + Command: name, + Response: response, + Random: maybe, + }, + data + ); + console.log(data); + msg.inlineReply( + `Saved **${data.Command}** as a custom command` + ); + } + } + ); + } + if (msg.content.toLowerCase() === "cancel") { + msg.channel.send("The setup has been cancelled."); + deleteeeCollector.stop(); + return; + } + }); + } + if (msg.content.toLowerCase() === "no") { + msg.channel.send( + new Discord.MessageEmbed() + .setColor(client.color) + .setTitle(`Setup | 4/4`) + .setDescription( + `The responses won't be randomized. Do you want to have delete command usage? \`Type yes or no\`` + ) + ); + randomCollector.stop(); + maybe = false; + await db.findOne( + { + Guild: message.guild.id, + Command: name, + Response: response, + }, + async (err, data) => { + if (data) { + data.Random = maybe; + await db.findOneAndUpdate( + { + Guild: message.guild.id, + Command: name, + Response: response, + }, + data + ); + console.log(data); + } + } + ); + let deleteeFilter = m => m.author.id === message.author.id; + let deleteeCollector = new Discord.MessageCollector( + message.channel, + deleteeFilter, + { max: 999 } + ); + deleteeCollector.on("collect", async msg => { + let idkwor; + if (msg.content.toLowerCase() === "yes") { + deleteeCollector.stop(); + idkwor = true; + await db.findOne( + { + Guild: message.guild.id, + Command: name, + Response: response, + }, + async (err, data) => { + if (data) { + data.Delete = idkwor; + await db.findOneAndUpdate( + { + Guild: message.guild.id, + Command: name, + Response: response, + Random: maybe, + }, + data + ); + msg.inlineReply( + `Saved **${data.Command}** as a custom command` + ); + } + } + ); + console.log(`Usage Delete: ${idkwor}`); + } + if (msg.content.toLowerCase() === "no") { + deleteeCollector.stop(); + idkwor = false; + await db.findOne( + { + Guild: message.guild.id, + Command: name, + Response: response, + Random: maybe, + }, + async (err, data) => { + if (data) { + data.Delete = idkwor; + await db.findOneAndUpdate( + { + Guild: message.guild.id, + Command: name, + Response: response, + }, + data + ); + msg.inlineReply( + `Saved **${data.Command}** as a custom command` + ); + } + } + ); + } + if (msg.content.toLowerCase() === "cancel") { + msg.channel.send("The setup has been cancelled."); + deleteeCollector.stop(); + return; + } + }); + } + if (msg.content.toLowerCase() === "cancel") { + msg.channel.send("The setup has been cancelled."); + randomCollector.stop(); + return; + } + }); + } else { + await db.findOne( + { Guild: message.guild.id, Command: name }, + async (err, data) => { + if (data) { + data.Response = response; + await db.findOneAndUpdate( + { Guild: message.guild.id, Command: name }, + data + ); + console.log(data); + } + } + ); + msg.channel.send( + new Discord.MessageEmbed() + .setTitle(`Setup | 3/3`) + .setColor(client.color) + .setDescription( + `The response is \n**${response}**\nDo you to want have delete command usage?` + ) + ); + responseCollector.stop(); + let deleteFilter = m => m.author.id === message.author.id; + let deleteCollector = new Discord.MessageCollector( + message.channel, + deleteFilter, + { max: 999 } + ); + deleteCollector.on("collect", async msg => { + let idkwor; + if (msg.content.toLowerCase() === "yes") { + deleteCollector.stop(); + idkwor = true; + await db.findOne( + { + Guild: message.guild.id, + Command: name, + Response: response, + }, + async (err, data) => { + if (data) { + data.Delete = idkwor; + await db.findOneAndUpdate( + { + Guild: message.guild.id, + Command: name, + Response: response, + }, + data + ); + msg.inlineReply( + `Saved **${data.Command}** as a custom command` + ); + } + } + ); + } + if (msg.content.toLowerCase() === "no") { + deleteCollector.stop(); + idkwor = false; + await db.findOne( + { + Guild: message.guild.id, + Command: name, + Response: response, + }, + async (err, data) => { + if (data) { + data.Delete = idkwor; + await db.findOneAndUpdate( + { + Guild: message.guild.id, + Command: name, + Response: response, + }, + data + ); + msg.inlineReply( + `Saved **${data.Command}** as a custom command` + ); + } + } + ); + } + if (msg.content.toLowerCase() === "cancel") { + msg.channel.send("The setup has been cancelled."); + deleteCollector.stop(); + return; + } + }); + } + }); + }); + } + }, +}; diff --git a/commands/Config/delete.js b/commands/Config/delete.js new file mode 100644 index 0000000..f852ce7 --- /dev/null +++ b/commands/Config/delete.js @@ -0,0 +1,25 @@ +const schema = require("../../models/custom-commands"); + +module.exports = { + name: "cc-delete", + UserPerm: "ADMINISTRATOR", + usage: "(command)", + description: "Delete a custom command for a server", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const name = args[0]; + if (!name) return client.err(message, "Config", "cc-delete", 47); + const data = await schema.findOne({ + Guild: message.guild.id, + Command: name, + }); + if (!data) return client.err(message, "Config", "cc-delete", 404); + await schema.findOneAndDelete({ Guild: message.guild.id, Command: name }); + message.inlineReply(`Removed **${name}** from custom commands.`); + }, +}; diff --git a/commands/Config/disable.js b/commands/Config/disable.js new file mode 100644 index 0000000..c9ba731 --- /dev/null +++ b/commands/Config/disable.js @@ -0,0 +1,53 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const fs = require("fs"); +module.exports = { + name: "disable", + UserPerm: "MANAGE_CHANNELS", + usage: "(Command/Category) (Name)", + description: "Disable a command in a server", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const type = args[0].toLowerCase(); + if (!type) return client.err(message, "Config", "disable", 17); + const name = args[1].toLowerCase(); + if (!name) return client.err(message, "Config", "disable", 17); + const data = await client.data.getGuild(message.guild.id); + if (!type) return client.err(message, "Config", "disable", 17); + if (type === "command") { + if (!!client.commands.get(name) === false) + return client.err(message, "Config", "disable", 404); + if (data.Commands.includes(name)) + return client.err(message, "Config", "disable", 18); + message.channel.send(`This command is disabled now:\n\n\`${name}\``); + await client.data.disable(message.guild.id, "command", name); + } + if (type === "category") { + const category = fs.readdirSync("./commands"); + const names = category.map(e => e.toLowerCase()); + const i = names.indexOf(name); + const up = names[i][0].toUpperCase(); + const others = names[i].substring(1); + if (!names.includes(name)) + return client.err(message, "Config", "disable", 404); + if (data.Category) { + if (data.Category.includes(name)) + return client.err(message, "Config", "disable", 18); + } + if (names.includes(name)) { + await client.data.disable( + message.guild.id, + "category", + `${up}${others}` + ); + message.inlineReply( + `This command is disabled now:\n\n\`${up}${others}\`` + ); + } + } + }, +}; diff --git a/commands/Config/enable.js b/commands/Config/enable.js new file mode 100644 index 0000000..3156ddf --- /dev/null +++ b/commands/Config/enable.js @@ -0,0 +1,48 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const fs = require("fs"); +module.exports = { + name: "enable", + UserPerm: "MANAGE_CHANNELS", + usage: "(Command) {Channel}", + description: "Enable a command in a server", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const type = args[0].toLowerCase(); + const name = args[1].toLowerCase(); + const data = await client.data.getGuild(message.guild.id); + if (!type) return client.err(message, "Config", "enable", 17); + if (!name) return client.err(message, "Config", "enable", 17); + if (type === "command") { + if (!!client.commands.get(name) === false) + return client.err(message, "Config", "enable", 404); + if (data.Commands.includes(name) && !!client.command.get(name) === true) { + await client.data.enable(message.guild.id, "command", name); + message.channel.send(`This command is enabled now:\n\n\`${cmd}\``); + } else return client.err(message, "Config", "enable", 18); + } + if (type === "category") { + const category = fs.readdirSync("./commands"); + const names = category.map(e => e.toLowerCase()); + const i = names.indexOf(name); + const up = names[i][0].toUpperCase(); + const others = names[i].substring(1); + if (!names.includes(name)) + return client.err(message, "Config", "enable", 404); + if (data.Category.includes(`${up}${others}`) && names.includes(name)) { + await client.data.enable( + message.guild.id, + "category", + `${up}${others}` + ); + message.inlineReply( + `This command is enabled now:\n\n\`${up}${others}\`` + ); + } else return client.err(message, "Config", "enable", 18); + } + }, +}; diff --git a/commands/Config/migrate.js b/commands/Config/migrate.js new file mode 100644 index 0000000..5f9ecc0 --- /dev/null +++ b/commands/Config/migrate.js @@ -0,0 +1,26 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "migrate", + usage: "(Server ID)", + description: "Migrate all emojis from a server", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + try { + const oldGuild = args[0]; + if (!oldGuild) return; + old = client.guilds.cache.get(oldGuild); + if (!old) return client.err(message, "Config", "migrate", 404); + await old.emojis.cache.map(async e => { + await message.guild.emojis.create(e.url, e.name); + }); + return message.channel.send(`Created Emotes.`); + } catch (e) { + console.log(e); + } + }, +}; diff --git a/commands/Config/modmail-category.js b/commands/Config/modmail-category.js new file mode 100644 index 0000000..279ec48 --- /dev/null +++ b/commands/Config/modmail-category.js @@ -0,0 +1,35 @@ +const schema = require("../../models/modmail"); +const { Client, Message, MessageEmbed } = require("discord.js"); + +module.exports = { + name: "modmail-category", + UserPerm: "ADMINISTRATOR", + description: "Setup modmail category in a server", + usage: "(Category ID)", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args.length) + return client.err(message, "Config", "modmail-category", 0); + const category = message.guild.channels.cache.find( + ch => (ch.type = "category" && ch.id == args[0]) + ); + if (!category) return client.err(message, "Config", "modmail-category", 1); + schema.findOne({ Guild: message.guild.id }, async (err, data) => { + if (data) { + data.Category = category.id; + await schema.findOneAndUpdate({ Guild: message.guild.id }, data); + } else { + new schema({ + Guild: message.guild.id, + Category: category.id, + }).save(); + } + }); + return message.channel.send(`**Saved category to ${category.name}**`); + }, +}; diff --git a/commands/Config/modmail-role.js b/commands/Config/modmail-role.js new file mode 100644 index 0000000..aad2d70 --- /dev/null +++ b/commands/Config/modmail-role.js @@ -0,0 +1,32 @@ +const schema = require("../../models/modmail"); + +module.exports = { + name: "modmail-role", + UserPerm: "ADMINISTRATOR", + description: "Add role for modmail in a server", + usage: "(Role)", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args.length) return client.err(message, "Config", "modmail-role", 0); + const role = + message.mentions.roles.first() || message.guild.roles.cache.get(args[0]); + if (!role) return client.err(message, "Config", "modmail-role", 404); + schema.findOne({ Guild: message.guild.id }, async (err, data) => { + if (data) { + data.Role = role.id; + await schema.findOneAndUpdate({ Guild: message.guild.id }, data); + } else { + new schema({ + Guild: message.guild.id, + Role: role.id, + }).save(); + } + }); + return message.channel.send(`Updated **${role.name}** as the modmail role`); + }, +}; diff --git a/commands/Config/panel.js b/commands/Config/panel.js new file mode 100644 index 0000000..422c369 --- /dev/null +++ b/commands/Config/panel.js @@ -0,0 +1,33 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const Schema = require("../../models/reaction"); + +module.exports = { + name: "panel", + description: "Reaction-Role Panel", + UserPerm: "ADMINISTRATOR", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const channel = message.mentions.channels.first() || message.channel; + Schema.findOne({ Guild: message.guild.id }, async (err, data) => { + if (!data) return client.err(message, "Config", "panel", 10); + const mapped = Object.keys(data.Roles) + .map((value, index) => { + const role = message.guild.roles.cache.get(data.Roles[value][0]); + return `${index + 1}) ${data.Roles[value][1].raw} - ${role}`; + }) + .join("\n\n"); + channel.send(new MessageEmbed().setDescription(mapped)).then(msg => { + data.Message = msg.id; + data.save(); + + const reactions = Object.values(data.Roles).map(val => val[1].id); // ?? val[1].raw); + reactions.map(emoji => msg.react(emoji)); + }); + }); + }, +}; diff --git a/commands/Config/prefix-reset.js b/commands/Config/prefix-reset.js new file mode 100644 index 0000000..db27202 --- /dev/null +++ b/commands/Config/prefix-reset.js @@ -0,0 +1,41 @@ +const schema = require("../../models/guilds"); +const prefix = require("../../config.json").prefix; +const { confirmation } = require("@reconlx/discord.js"); +module.exports = { + name: "prefix-reset", + aliases: ["pr"], + description: 'Reset the prefix to "C." at the server', + UserPerm: "ADMINISTRATOR", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message) => { + message.channel + .send("**Do you want to reset your prefix?**") + .then(async msg => { + const emoji = await confirmation( + msg, + message.author, + ["✅", "❌"], + 10000 + ); + if (emoji === "✅") { + msg.delete(); + schema.findOne({ Guild: message.guild.id }, async (err, data) => { + if (data) { + data.Prefix = prefix; + await schema.findOneAndUpdate({ Guild: message.guild.id }, data); + } + }); + message.channel.send(`The prefix has been reset to **${prefix}**`); + } + if (emoji === "❌") { + msg.delete(); + message.channel.send("Cancelled."); + } + }); + }, +}; diff --git a/commands/Config/prefix.js b/commands/Config/prefix.js new file mode 100644 index 0000000..789719e --- /dev/null +++ b/commands/Config/prefix.js @@ -0,0 +1,37 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const schema = require("../../models/guilds"); +module.exports = { + name: "prefix", + usage: "(Prefix)", + description: "Set the prefix at the server", + UserPerm: "ADMINISTRATOR", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const res = args.join(" "); + if (!res) return client.err(message, "Config", "prefix", 46); + schema.findOne({ Guild: message.guild.id }, async (err, data) => { + if (err) throw err; + if (data) { + schema.findOne({ Guild: message.guild.id }, async (err, data) => { + data.Prefix = res; + await schema.findOneAndUpdate({ Guild: message.guild.id }, data); + }); + message.channel.send(`Your prefix has been updated to **${res}**`); + } else { + data = new schema({ + Guild: message.guild.id, + Prefix: res, + }); + data.save(); + message.channel.send( + `Custom prefix in this server is now set to **${res}**` + ); + } + }); + }, +}; diff --git a/commands/Config/premium.js b/commands/Config/premium.js new file mode 100644 index 0000000..6026f99 --- /dev/null +++ b/commands/Config/premium.js @@ -0,0 +1,63 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "premiumserveradd", + category: "Config", + timeout: 1000 * 60, + aliases: ["psadd", "psa", "premiumserver"], + description: "Add premium to a server", + Premium: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + try { + const user = await client.data.getUser(message.author.id); + const guild = await client.data.getGuild(message.guild.id); + if (guild.Premium == true) { + return client.err(message, "Config", "premium", 506); + } + if ( + (user.Tier == 1 && user.PremiumServers.length >= 5) || + (user.Tier == 2 && user.PremiumServers.length >= 2) || + (user.Tier == 3 && user.PremiumServers.length >= 0) + ) { + return client.err(message, "Config", "premium", 505); + } + await client.data.setPremium(message.guild.id, "true"); + await client.data.pushGuild(message.author.id, message.guild.id, "push"); + message.channel.send( + new MessageEmbed() + .setTitle("Success!") + .setDescription(`Premium added to **${message.guild.name}**! \n`) + .setFooter("Thank you for supporting Cath!") + .setColor("GREEN") + .setTimestamp() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ) + ); + client.ServerLog.send( + new MessageEmbed() + .setTitle("New Premium Server") + .addField("Server Info", [ + `**>Server Name**: \n${message.guild.name}`, + `**>Server ID**: \n${message.guild.id}`, + `**>Server Member Count**: \n${message.guild.memberCount}`, + ]) + .addField("Owner Info", [ + `**>Owner Tag**: \n${message.guild.owner.user.tag}`, + `**>Owner ID**: \n${message.guild.owner.id}`, + ]) + .setTimestamp() + .setThumbnail(message.guild.iconURL({ dynamic: true })) + .setColor("GREEN") + ); + } catch (e) { + console.log(e); + return client.err(message, "Config", "premium", 999); + } + }, +}; diff --git a/commands/Config/rr-add.js b/commands/Config/rr-add.js new file mode 100644 index 0000000..87e3e72 --- /dev/null +++ b/commands/Config/rr-add.js @@ -0,0 +1,50 @@ +const { Client, Message, MessageEmbed, Util } = require("discord.js"); +const Schema = require("../../models/reaction"); +module.exports = { + name: "rr-add", + UserPerm: "ADMINISTRATOR", + description: "Create reaction role for server", + usage: "(Role) (emoji(Must be in server)", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const role = + message.mentions.roles.first() || + message.guild.roles.cache.get(args[0]) || + message.guild.roles.cache.find(r => r.name == args[0]); + let [, emoji] = args; + if (!emoji) return client.err(message, "Config", "rr-add", 11); + const parsedEmoji = Util.parseEmoji(emoji); + Schema.findOne({ Guild: message.guild.id }, async (err, data) => { + if (data) { + data.Roles[parsedEmoji.name] = [ + role.id, + { + id: parsedEmoji.id, + raw: emoji, + }, + ]; + await Schema.findOneAndUpdate({ Guild: message.guild.id }, data); + } else { + new Schema({ + Guild: message.guild.id, + Message: 0, + Roles: { + [parsedEmoji.name]: [ + role.id, + { + id: parsedEmoji.id, + raw: emoji, + }, + ], + }, + }).save(); + } + message.channel.send(`Added ${role.name}.`); + }); + }, +}; diff --git a/commands/Config/rr-rmv.js b/commands/Config/rr-rmv.js new file mode 100644 index 0000000..e053337 --- /dev/null +++ b/commands/Config/rr-rmv.js @@ -0,0 +1,39 @@ +const { Client, Message } = require("discord.js"); +const Schema = require("../../models/reaction"); +const { confirmation } = require("@reconlx/discord.js"); +module.exports = { + name: "rr-rmv", + UserPerm: "ADMINISTRATOR", + description: "Remove reaction role for server", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + message.channel + .send("**Do you want to remove the reaction roles?**") + .then(async msg => { + Schema.findOne({ Guild: message.guild.id }, async (err, data) => { + if (err) throw err; + if (!data) return client.err(message, "Config", "rr-rmv", 10); + }); + const emoji = await confirmation( + msg, + message.author, + ["✅", "❌"], + 10000 + ); + if (emoji === "✅") { + msg.delete(); + await Schema.findOneAndDelete({ Guild: message.guild.id }); + message.channel.send(`Removed reaction roles for this server.`); + } + if (emoji === "❌") { + msg.delete(); + message.channel.send("Cancelled."); + } + }); + }, +}; diff --git a/commands/Config/set.js b/commands/Config/set.js new file mode 100644 index 0000000..1430444 --- /dev/null +++ b/commands/Config/set.js @@ -0,0 +1,34 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "set", + description: "Set Goodbye/Welcome/Log Channel for the server", + usage: "(goodbye/welcome/log) (#Channel)", + UserPerm: "ADMINISTRATOR", + category: "Config", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args[0]) return client.err(message, "Config", "set", 45); + if (args[0].toLowerCase() === "goodbye") { + const channel = message.mentions.channels.first(); + if (!channel) return client.err(message, "Config", "set", 28); + await client.data.setGoodbye(message.guild.id, channel.id); + message.channel.send(`Saved ${channel} as the goodbye channel.`); + } else if (args[0].toLowerCase() === "log") { + const channel = message.mentions.channels.first(); + if (!channel) return client.err(message, "Config", "set", 28); + await client.data.setLog(message.guild.id, channel.id); + message.channel.send(`Saved ${channel} as the log channel.`); + } else if (args[0].toLowerCase() === "welcome") { + const channel = message.mentions.channels.first(); + if (!channel) return client.err(message, "Config", "set", 28); + await client.data.setWelcome(message.guild.id, channel.id); + message.channel.send(`Saved ${channel} as the welcome channel.`); + } else { + return client.err(message, "Config", "set", 45); + } + }, +}; diff --git a/commands/Economy/bal.js b/commands/Economy/bal.js new file mode 100644 index 0000000..04f11d5 --- /dev/null +++ b/commands/Economy/bal.js @@ -0,0 +1,34 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "balance", + aliases: ["bal"], + usage: "(User)", + category: "Economy", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const user = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]) || + message.guild.members.cache.find( + r => + r.user.username.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.guild.members.cache.find( + r => r.displayName.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.member; + const bal = await client.data.bal(user.id); + let embed = new MessageEmbed() + .addField(`${client.currency} Balance`, `**${bal}**`) + .setColor(client.color) + .setURL(client.web) + .setTitle(`${user.displayName}'s Balance`) + .setTimestamp() + .setFooter(`Requested by ${message.author.tag}`); + message.inlineReply(embed); + }, +}; diff --git a/commands/Economy/bet.js b/commands/Economy/bet.js new file mode 100644 index 0000000..ec95a6c --- /dev/null +++ b/commands/Economy/bet.js @@ -0,0 +1,48 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "gamble", + aliases: ["bet"], + usage: "(Number)", + timeout: 5000, + description: "Win double amount of coins or lose all coins", + category: "Economy", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const max = 1000000; + if (!args[0]) { + return client.err(message, "Economy", "gamble", 5); + } + if (isNaN(args[0])) { + return client.err(message, "Economy", "gamble", 7); + } + const amt = parseInt(args[0]); + if ((await client.data.bal(message.author.id)) < amt) { + return client.err(message, "Economy", "gamble", 20); + } + if (amt > max) { + return client.err(message, "Economy", "gamble", 101); + } + if (client.function.random() === true) { + const winamt = amt * 1; + await client.data.add(message.author.id, winamt); + const abc = new MessageEmbed() + .setColor("GREEN") + .setTimestamp() + .setTitle(`${message.author.username} wins a gamble game`) + .setDescription(`You win\n**${winamt}**${client.currency}`); + message.inlineReply(abc); + } else { + await client.data.rmv(message.author.id, amt); + const cba = new MessageEmbed() + .setColor("RED") + .setTimestamp() + .setTitle(`${message.author.username} loses a gamble game`) + .setDescription(`You lost\n**${amt}**${client.currency}`); + message.inlineReply(cba); + } + }, +}; diff --git a/commands/Economy/blackjack.js b/commands/Economy/blackjack.js new file mode 100644 index 0000000..cc5d4e5 --- /dev/null +++ b/commands/Economy/blackjack.js @@ -0,0 +1,290 @@ +const Discord = require("discord.js"); +module.exports = { + name: "blackjack", + aliases: ["bj"], + usage: "(Number)", + description: "Play a blackjack game to win money", + category: "Economy", + timeout: 10000, + run: async (client, message, args) => { + const money = parseInt(args[0]); + const author = message.author; + if (isNaN(money) || !money) { + return client.err(message, "Economy", "blackjack", 101); + } + if ((await client.data.bal(author.id)) < bet) { + client.err(message, "Economy", "blackjack", 20); + } + var numCardsPulled = 0; + var gameOver = false; + var player = { + cards: [], + score: 0, + }; + var dealer = { + cards: [], + score: 0, + }; + function getCardsValue(a) { + var cardArray = [], + sum = 0, + i = 0, + dk = 10.5, + doubleking = "QQ", + aceCount = 0; + cardArray = a; + for (i; i < cardArray.length; i += 1) { + if ( + cardArray[i].rank === "J" || + cardArray[i].rank === "Q" || + cardArray[i].rank === "K" + ) { + sum += 10; + } else if (cardArray[i].rank === "A") { + sum += 11; + aceCount += 1; + } else if (cardArray[i].rank === doubleking) { + sum += dk; + } else { + sum += cardArray[i].rank; + } + } + while (aceCount > 0 && sum > 21) { + sum -= 10; + aceCount -= 1; + } + return sum; + } + + var deck = { + deckArray: [], + initialize: function () { + var suitArray, rankArray, s, r, n; + suitArray = ["b", "d", "g", "s"]; + rankArray = [2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K", "A"]; + n = 13; + + for (s = 0; s < suitArray.length; s += 1) { + for (r = 0; r < rankArray.length; r += 1) { + this.deckArray[s * n + r] = { + rank: rankArray[r], + suit: suitArray[s], + }; + } + } + }, + shuffle: function () { + var temp, i, rnd; + for (i = 0; i < this.deckArray.length; i += 1) { + rnd = Math.floor(Math.random() * this.deckArray.length); + temp = this.deckArray[i]; + this.deckArray[i] = this.deckArray[rnd]; + this.deckArray[rnd] = temp; + } + }, + }; + deck.initialize(); + deck.shuffle(); + async function bet(outcome) { + if (outcome === "win") { + client.data.add(author.id, money); + //client.ADDbjWin(message.author.id); + } + if (outcome === "lose") { + client.data.rmv(author.id, money); + } + } + + function endMsg(f, msg, cl, dealerC) { + let cardsMsg = ""; + player.cards.forEach(function (card) { + var emAR = ["♥", "♦", "♠", "♣"]; + var t = emAR[Math.floor(Math.random() * emAR.length)]; + cardsMsg += "[`" + t + card.rank.toString(); + if (card.suit == "d1") cardsMsg += "♥"; + if (card.suit == "d2") cardsMsg += "♦"; + if (card.suit == "d3") cardsMsg += "♠"; + if (card.suit == "d4") cardsMsg += "♣"; + cardsMsg += "`](https://cath.gq/) "; + }); + cardsMsg += " > " + player.score.toString(); + + var dealerMsg = ""; + if (!dealerC) { + var emAR = ["♥", "♦", "♠", "♣"]; + var t = emAR[Math.floor(Math.random() * emAR.length)]; + dealerMsg = "[`" + t + dealer.cards[0].rank.toString(); + if (dealer.cards[0].suit == "d1") dealerMsg += "♥"; + if (dealer.cards[0].suit == "d2") dealerMsg += "♦"; + if (dealer.cards[0].suit == "d3") dealerMsg += "♠"; + if (dealer.cards[0].suit == "d4") dealerMsg += "♣"; + dealerMsg += " ? ?`](https://cath.gq/)"; + } else { + dealerMsg = ""; + dealer.cards.forEach(function (card) { + var emAR = ["♥", "♦", "♠", "♣"]; + var t = emAR[Math.floor(Math.random() * emAR.length)]; + dealerMsg += "[`" + t + card.rank.toString(); + if (card.suit == "d1") dealerMsg += "♥"; + if (card.suit == "d2") dealerMsg += "♦"; + if (card.suit == "d3") dealerMsg += "♠"; + if (card.suit == "d4") dealerMsg += "♣"; + dealerMsg += "`](https://cath.gq/) "; + }); + dealerMsg += " > " + dealer.score.toString(); + } + + const gambleEmbed = new Discord.MessageEmbed() + .setColor(cl) + .setTitle(message.author.username + `'s Blackjack game`) + .addField("You", cardsMsg, true) + .addField("cath.exe", dealerMsg, true) + .addField(f, msg); + + message.channel.send(gambleEmbed); + } + + async function endGame() { + if (player.score === 21) { + bet("win"); + gameOver = true; + await endMsg( + `Win! You got 21!`, + `cath.exe had ${dealer.score.toString()}`, + `GREEN` + ); + } + if (player.score > 21) { + bet("lose"); + gameOver = true; + await endMsg( + `Lost! You reached over 21!`, + `cath.exe had ${dealer.score.toString()}`, + `RED` + ); + } + if (dealer.score === 21) { + bet("lose"); + gameOver = true; + await endMsg( + `Lost! The dealer got 21!`, + `cath.exe had ${dealer.score.toString()}`, + `RED` + ); + } + if (dealer.score > 21) { + bet("win"); + gameOver = true; + await endMsg( + `Win! cath.exe reached over 21!`, + `cath.exe had ${dealer.score.toString()}`, + `GREEN` + ); + } + if ( + dealer.score >= 17 && + player.score > dealer.score && + player.score < 21 + ) { + bet("win"); + gameOver = true; + await endMsg( + `Win! You defeated cath.exe!`, + `cath.exe had ${dealer.score.toString()}`, + `GREEN` + ); + } + if ( + dealer.score >= 17 && + player.score < dealer.score && + dealer.score < 21 + ) { + bet("lose"); + gameOver = true; + await endMsg( + `Lost! cath.exe won!`, + `cath.exe had ${dealer.score.toString()}`, + `RED` + ); + } + if ( + dealer.score >= 17 && + player.score === dealer.score && + dealer.score < 21 + ) { + gameOver = true; + await endMsg( + `Tie! UwU`, + `cath.exe had ${dealer.score.toString()}`, + `RED` + ); + } + } + + function dealerDraw() { + dealer.cards.push(deck.deckArray[numCardsPulled]); + dealer.score = getCardsValue(dealer.cards); + numCardsPulled += 1; + } + + function newGame() { + hit(); + hit(); + dealerDraw(); + endGame(); + } + + function hit() { + player.cards.push(deck.deckArray[numCardsPulled]); + player.score = getCardsValue(player.cards); + + numCardsPulled += 1; + if (numCardsPulled > 2) { + endGame(); + } + } + + function stand() { + while (dealer.score < 17) { + dealerDraw(); + } + endGame(); + } + newGame(); + async function loop() { + if (gameOver) return; + + endMsg("To hit type `h`, for stand type `s`", `GoodLuck ;)`, `GRAY`); + + let filter = m => m.author.id === message.author.id; + message.channel + .awaitMessages(filter, { + max: 1, + time: 1200000, + errors: ["time"], + }) + .then(message => { + message = message.first(); + if (message.content === "h" || message.content === "hit") { + hit(); + loop(); + return; + } else if (message.content === "s" || message.content === "stand") { + stand(); + loop(); + return; + } else { + bet("lose"); + endMsg("Invalid response", `You lost ${money}`, "RED"); + return; + } + }) + .catch(_ => { + message.channel.send("Lost!!"); + bet("lose"); + return; + }); + } + await loop(); + }, +}; diff --git a/commands/Economy/buy.js b/commands/Economy/buy.js new file mode 100644 index 0000000..41e6ca8 --- /dev/null +++ b/commands/Economy/buy.js @@ -0,0 +1,71 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const inventory = require("../../models/econ"); +const items = require("../../util/item"); +module.exports = { + name: "purchase", + aliases: ["buy"], + usage: "(Item)", + description: "Buy something from the shop", + category: "Economy", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args[0]) { + return client.err(message, "Economy", "buy", 21); + } + const itemToBuy = args[0]; + const validItem = !!items.find( + item => item.alias.toLowerCase() === itemToBuy + ); + if (!validItem) { + return client.err(message, "Economy", "buy", 22); + } + const itemName = items.find( + item => item.alias.toLowerCase() === itemToBuy + ).item; + const itemPrice = items.find( + item => item.alias.toLowerCase() === itemToBuy + ).price; + if ((await client.data.bal(message.author.id)) < itemPrice) + return client.err(message, "Economy", "buy", 20); + const params = { + User: message.author.id, + }; + inventory.findOne(params, async (err, data) => { + if (data.Inventory) { + const hasItem = Object.keys(data.Inventory).includes(itemName); + if (!hasItem) { + data.Inventory[itemName] = 1; + } else { + data.Inventory[itemName]++; + } + await inventory.findOneAndUpdate(params, data); + } else if (data.CP) { + data.Inventory = { + [itemName]: 1, + }; + await inventory.findOneAndUpdate(params, data); + } else { + new inventory({ + User: message.author.id, + Inventory: { + [itemName]: 1, + }, + }).save(); + } + message.inlineReply( + new MessageEmbed() + .setTimestamp() + .setDescription( + `**${message.author.username}** buys **${itemName}** for **${itemPrice}**${client.currency}` + ) + .setColor("GREEN") + .setURL(client.web) + ); + await client.data.rmv(message.author.id, itemPrice); + }); + }, +}; diff --git a/commands/Economy/daily.js b/commands/Economy/daily.js new file mode 100644 index 0000000..ab240bf --- /dev/null +++ b/commands/Economy/daily.js @@ -0,0 +1,51 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "daily", + description: "Earns daily money", + category: "Economy", + timeout: 1000 * 60 * 60 * 24, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + var money; + const user = await client.data.getUser(message.author.id); + if (user) { + if (user.Premium == true) { + money = 20000; + let pre_embed = new MessageEmbed() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dyanmic: true }) + ) + .setDescription( + `**Here is your daily ${money}${client.currency}!\nThanks for supporting Cath!**` + ) + .setURL(client.web) + .setColor(client.color) + .setFooter(`Made by Cath Team`) + .setTimestamp(); + await client.data.add(message.author.id, money); + return message.inlineReply(pre_embed); + } else { + money = 10000; + let norm_embed = new MessageEmbed() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dyanmic: true }) + ) + .setDescription( + `Here is your daily ${money}${client.currency}!\nBe [premium](https://discord.gg/SbQHChmGcp) user, you can get more coins everyday!` + ) + .setURL(client.web) + .setColor(client.color) + .setFooter(`Made by Cath Team`) + .setTimestamp(); + await client.data.add(message.author.id, money); + return message.inlineReply(norm_embed); + } + } + }, +}; diff --git a/commands/Economy/drop.js b/commands/Economy/drop.js new file mode 100644 index 0000000..0e0c6a7 --- /dev/null +++ b/commands/Economy/drop.js @@ -0,0 +1,41 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +require("../../inlinereply"); +module.exports = { + name: "drop", + usage: "{Channel} (Number)", + description: "Drops money to a channel", + category: "Economy", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const p = await client.prefix(message); + const channel = message.mentions.channels.first() || message.channel; + const coinsAmount = args[0]; + if (!coinsAmount) { + return client.err(message, "Economy", "drop", 5); + } + if ((await client.data.bal(message.author.id)) < coinsAmount) { + return client.err(message, "Economy", "drop", 20); + } + const filter = msg => + msg.guild.id === message.guild.id && msg.content === `${p}claim`; + message.channel.send("The drop has started in " + channel.toString()); + channel.send( + `${message.author.username} has dropped a ${client.currency} bomb! Use ${p}claim to claim ${client.currency}!!` + ); + client.data.rmv(message.author.id, parseInt(coinsAmount)); + channel.awaitMessages(filter, { max: 1, time: 60000 }).then(async msg => { + const id = msg.first().author.id; + const coinsToClaim = parseInt(coinsAmount); + await client.data.add(id, coinsToClaim); + msg + .first() + .inlineReply( + `Congratultions! You have claimed **${coinsToClaim}** ${client.currency}!` + ); + }); + }, +}; diff --git a/commands/Economy/gift.js b/commands/Economy/gift.js new file mode 100644 index 0000000..c152ea6 --- /dev/null +++ b/commands/Economy/gift.js @@ -0,0 +1,103 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const inventory = require("../../models/econ"); +const items = require("../../util/item"); +module.exports = { + name: "gift", + timeout: 5000, + usage: "(User) (Item)", + description: "Gift item to an user", + category: "Economy", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const user = + message.mentions.users.first() || + message.guild.members.cache.find( + r => r.user.username.toLowerCase() === args[0].toLocaleLowerCase() + ) || + message.guild.members.cache.find( + r => r.displayName.toLowerCase() === args[0].toLocaleLowerCase() + ); + if (!user) return client.err(message, "Economy", "gift", 1); + if (user.id === message.author.id) + return client.err(message, "Economy", "gift", 21); + /* + const number = args[1]; + if (!number) + return error( + message, + message.author, + p, + "gift", + "(User) **(Number)** (Item)", + `Missing 'Number' argument` + ); + if (isNaN(number)) + return error( + message, + message.author, + p, + "gift", + "(User) **(Number)** (Item)", + `'Number' argument must be a number` + ); + */ + const itemToGift = args[1]; + if (!itemToGift) return client.err(message, "Economy", "gift", 21); + const validItem = !!items.find( + item => item.alias.toLowerCase() === itemToGift + ); + if (!validItem) return client.err(message, "Economy", "gift", 22); + const itemName = items.find( + item => item.alias.toLowerCase() === itemToGift + ).item; + const params = { + User: message.author.id, + }; + const param = { + User: user.id, + }; + inventory.findOne(params, async (err, data) => { + if (data.Inventory) { + const hasItem = Object.keys(data.Inventory).includes(itemName); + if (hasItem) { + if (data.Inventory[itemName] <= 0) { + return client.err(message, "Economy", "gift", 23); + } else { + data.Inventory[itemName]--; + message.channel.send( + new MessageEmbed() + .setColor(client.color) + .setTimestamp() + .setDescription( + `**${message.author.username}** has given **${user.username}** a **${itemName}**` + ) + ); + await inventory.findOneAndUpdate(params, data); + } + } else return client.err(message, "Economy", "gift", 24); + } else return client.err(message, "Economy", "gift", 24); + }); + inventory.findOne(param, async (err, data) => { + if (data.Inventory) { + const hasItem = Object.keys(data.Inventory).includes(itemName); + if (!hasItem) { + data.Inventory[itemName] = 1; + } else { + data.Inventory[itemName]++; + } + await inventory.findOneAndUpdate(param, data); + } else { + new inventory({ + User: user.id, + Inventory: { + [itemName]: 1, + }, + }).save(); + } + }); + }, +}; diff --git a/commands/Economy/give.js b/commands/Economy/give.js new file mode 100644 index 0000000..4a25ba0 --- /dev/null +++ b/commands/Economy/give.js @@ -0,0 +1,45 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "give", + aliases: ["share"], + timeout: 5000, + usage: "(User) (Number)", + description: "Give money to an user", + category: "Economy", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const user = + message.mentions.users.first() || + message.guild.members.cache.find( + r => r.user.username.toLowerCase() === args[0].toLocaleLowerCase() + ) || + message.guild.members.cache.find( + r => r.displayName.toLowerCase() === args[0].toLocaleLowerCase() + ); + if (!user) return client.err(message, "Economy", "give", 1); + const parsed = parseInt(args[1]); + if (!args[1]) return client.err(message, "Economy", "give", 5); + if (isNaN(parsed)) return client.err(message, "Economy", "give", 7); + if (user.id === message.author.id) + return client.err(message, "Economy", "give", 2); + if (parsed > (await client.data.bal(message.author.id))) { + return client.err(message, "Economy", "give", 20); + } + await client.data.rmv(message.author.id, parsed); + await client.data.add(user.id, parsed); + message.channel.send( + new MessageEmbed() + .setColor(client.color) + .setTimestamp() + .setDescription( + `**${message.author.username}** has given **${ + user.username + }** **${parsed.toLocaleString()}**${client.currrency}` + ) + ); + }, +}; diff --git a/commands/Economy/inv.js b/commands/Economy/inv.js new file mode 100644 index 0000000..e98f84e --- /dev/null +++ b/commands/Economy/inv.js @@ -0,0 +1,51 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const inv = require("../../models/econ"); +const util = require("../../util/pagination"); +module.exports = { + name: "inventory", + aliases: ["inv"], + description: "Check the inventory of an user", + usage: "{User}", + category: "Economy", + timeout: 5000, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const p = await client.prefix(message); + const user = + message.mentions.users.first() || + message.guild.members.cache.get(args[0]) || + message.guild.members.cache.find( + r => + r.user.username.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.guild.members.cache.find( + r => r.displayName.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.member; + inv.findOne({ User: user.id }, async (err, data) => { + if (!data.Inventory) + return client.err(message, "Economy", "inventory", 25); + const mappedData = Object.keys(data.Inventory).map(key => { + return `\n**${key}** — ${data.Inventory[key]}`; + }); + const c = util.chunk(mappedData, 5).map(x => x.join("\n")); + const embed = new MessageEmbed() + .setTimestamp() + .setTitle(`${user.displayName}'s inventory`) + .setColor("client.color") + .setDescription(c[0]) + .setFooter(`Page 1 of ${c.length}`); + try { + const msg = await message.channel.send(embed); + if (mappedData.length > 5) + await util.pagination(msg, message.author, c); + } catch (e) { + console.log(e); + } + }); + }, +}; diff --git a/commands/Economy/lb.js b/commands/Economy/lb.js new file mode 100644 index 0000000..65331f6 --- /dev/null +++ b/commands/Economy/lb.js @@ -0,0 +1,39 @@ +const Levels = require("discord-xp"); +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "leaderboard", + aliases: ["lb"], + timeout: 5000, + usage: "Check the leaderboard of a server", + category: "Economy", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const rawLeaderboard = await Levels.fetchLeaderboard(message.guild.id, 10); + if (rawLeaderboard.length < 1) + return client.err(message, "Economy", "lb", 10); + const leaderboard = await Levels.computeLeaderboard( + client, + rawLeaderboard, + true + ); + const lb = leaderboard.map( + e => + `**${e.position}**. ${e.username}#${e.discriminator} Level: ${ + e.level + } XP: ${e.xp.toLocaleString()}` + ); + const embed = new MessageEmbed() + .setTitle(`**Leaderboard for ${message.guild.name}**`) + .setDescription(`\n${lb.join("\n")}`) + .setFooter( + `Requested by ${message.author.tag}`, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setColor(client.color); + message.inlineReply(embed); + }, +}; diff --git a/commands/Economy/shop.js b/commands/Economy/shop.js new file mode 100644 index 0000000..ec857ad --- /dev/null +++ b/commands/Economy/shop.js @@ -0,0 +1,33 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const util = require("../../util/pagination"); +const items = require("../../util/item"); +module.exports = { + name: "shop", + description: "Check the items from the shop", + category: "Economy", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const list = items.map((value, index) => { + return `**${value.item}** — ${value.price.toLocaleString()}${ + client.currency + }\nID: \`${value.id}\``; + }); + const c = util.chunk(list, 5).map(x => x.join("\n\n")); + const embed = new MessageEmbed() + .setTitle("**cath.exe shop**") + .setTimestamp() + .setDescription(c[0]) + .setColor(client.color) + .setFooter(`Page 1 of ${c.length}`); + try { + const msg = await message.channel.send(embed); + if (list.length > 5) await util.pagination(msg, message.author, c); + } catch (e) { + console.log(e); + } + }, +}; diff --git a/commands/Economy/slots.js b/commands/Economy/slots.js new file mode 100644 index 0000000..765bc55 --- /dev/null +++ b/commands/Economy/slots.js @@ -0,0 +1,92 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "slots", + usage: "(Number)", + timeout: 5000, + description: "Win more coins by slots", + category: "Economy", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const max = 1000000; + const slots = [ + "<:dumbcat:818913965353730068>", + "<:nicecat:740978278055280722>", + "<:wah:836951911729987597>", + "<:startledcat:836619417550061580>", + ]; + const slotOne = slots[Math.floor(Math.random() * slots.length)]; + const slotTwo = slots[Math.floor(Math.random() * slots.length)]; + const slotThree = slots[Math.floor(Math.random() * slots.length)]; + const slotfour = slots[Math.floor(Math.random() * slots.length)]; + const slotfive = slots[Math.floor(Math.random() * slots.length)]; + const slotsix = slots[Math.floor(Math.random() * slots.length)]; + const slotseven = slots[Math.floor(Math.random() * slots.length)]; + const sloteight = slots[Math.floor(Math.random() * slots.length)]; + const slotnine = slots[Math.floor(Math.random() * slots.length)]; + if (!args[0]) return client.err(message, "Economy", "slots", 5); + if (isNaN(args[0])) return client.err(message, "Economy", "slots", 7); + const amt = parseInt(args[0]); + if (amt > max) return client.err(message, "Economy", "slots", 101); + if ((await client.data.bal(message.author.id)) < amt) { + return client.err(message, "Economy", "slots", 20); + } + if ( + (slotOne === slotTwo && slotOne === slotThree) || + (slotfour === slotfive && slotfour === slotsix) || + (slotseven === sloteight && slotseven === slotnine) + ) { + const winamt = Math.floor(Math.random() * 2 * amt); + await client.data.add(message.author.id, winamt); + const won = new MessageEmbed() + .setColor("GREEN") + .addField( + "|-----|-----|----|", + `| ${slotfour} | ${slotfive} | ${slotsix} |` + ) + .addField( + "|-----|-----|----|", + `| ${slotOne} | ${slotTwo} | ${slotThree} |` + ) + .addField( + "|-----|-----|----|", + `| ${slotseven} | ${sloteight} | ${slotnine} |` + ) + .setTitle(`${message.author.username} wins a slots game`) + .setDescription( + `You win\n**${winamt}**${client.currency}\nYou now have **${ + parseInt(await client.data.bal(message.author.id)) - amt + }**${client.currency}` + ); + message.inlineReply(won); + console.log(`Coins: ${await client.data.bal(message.author.id)}`); + } else { + await client.data.rmv(message.author.id, amt); + const lost = new MessageEmbed() + .setColor("RED") + .addField( + "|-----|-----|----|", + `| ${slotfour} | ${slotfive} | ${slotsix} |` + ) + .addField( + "|-----|-----|----|", + `| ${slotOne} | ${slotTwo} | ${slotThree} |` + ) + .addField( + "|-----|-----|----|", + `| ${slotseven} | ${sloteight} | ${slotnine} |` + ) + .setTitle(`${message.author.username} loses a slots game`) + .setDescription( + `You lose\n**${amt}**${client.currency}\nYou now have **${ + parseInt(await client.data.bal(message.author.id)) - amt + }**${client.currency}` + ); + message.inlineReply(lost); + console.log(`Coins: ${await client.data.bal(message.author.id)}`); + } + }, +}; diff --git a/commands/Economy/steal.js b/commands/Economy/steal.js new file mode 100644 index 0000000..3a06cbd --- /dev/null +++ b/commands/Economy/steal.js @@ -0,0 +1,122 @@ +const db = require("../../models/econ"); +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "steal", + description: "Steal money from an user", + usage: "(User)", + aliases: ["rob"], + category: "Economy", + timeout: 120000, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + var tryrob = + message.mentions.users.first() || + message.guild.members.cache.get(args[0]) || + message.guild.members.cache.find( + r => + r.user.username.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.guild.members.cache.find( + r => r.displayName.toLowerCase() === args.join(" ").toLocaleLowerCase() + ); + if (!tryrob || !args[0]) { + return client.err(message, "Economy", "steal", 1); + } + if (tryrob.id === message.author.id) { + return client.err(message, "Economy", "steal", 2); + } + await db.findOne({ User: message.author.id }, async (err, data) => { + if (err) throw err; + if (data) { + if (!data.CP) { + data.CP = 0; + data.save(); + return client.err(message, "Economy", "steal", 20); + } + } + if (!data) { + new db({ + User: message.author.id, + CP: 0, + Inventory: "", + }).save(); + return client.err(message, "Economy", "steal", 20); + } else if (data) { + await db.findOne({ User: tryrob.id }, async (err1, data1) => { + const coins = Math.floor(Math.random() * data.CP) + 1; + const coins1 = Math.floor(Math.random() * data1.CP) + 1; + if (err1) throw err1; + if (!data1) { + new db({ + User: tryrob.id, + CP: 0, + Inventory: "", + }).save(); + return message.inlineReply( + new MessageEmbed() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setColor("RED") + .setDescription( + `They don't have any ${client.currency}. Be kind!` + ) + ); + } else if (data1) { + if (data1.CP <= 0 || !data1.CP) { + return message.inlineReply( + new MessageEmbed() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setColor("RED") + .setDescription( + `They don't have any ${client.currency}. Be kind!` + ) + ); + } + if (client.function.random() === true) { + data.CP += coins1; + data.save(); + data1.CP -= coins1; + data1.save(); + return message.inlineReply( + new MessageEmbed() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setColor("GREEN") + .setDescription( + `You robbed ${tryrob}! And you got \`${coins}\`${client.currency}` + ) + ); + } else { + data.CP -= coins; + data.save(); + data1.CP += coins; + data1.save(); + return message.inlineReply( + new MessageEmbed() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setColor("RED") + .setDescription( + `You failed on robbing ${tryrob}! And you had to pay him/her \`${coins}\`${client.currency}` + ) + ); + } + } + }); + } + }); + }, +}; diff --git a/commands/Economy/work.js b/commands/Economy/work.js new file mode 100644 index 0000000..f6e7de5 --- /dev/null +++ b/commands/Economy/work.js @@ -0,0 +1,29 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +require("../../inlinereply"); +module.exports = { + name: "work", + description: "Work to earn money", + category: "Economy", + timeout: 1000 * 60 * 10, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const job = [ + "Software engineer", + "Programmer", + "Teacher", + "YouTuber", + "Student", + "Desginer", + "Editor", + "Banker", + ]; + const earning = client.function.rndint(5000, 3000); + const jobs = job[Math.floor(Math.random() * job.length)]; + await client.data.add(message.author.id, earning); + return message.inlineReply(`You worked as a ${jobs} and earned ${earning}`); + }, +}; diff --git a/commands/Fun/cat.js b/commands/Fun/cat.js new file mode 100644 index 0000000..afaa658 --- /dev/null +++ b/commands/Fun/cat.js @@ -0,0 +1,30 @@ +const api = require("imageapi.js"); +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "cat", + aliases: ["cats"], + category: "Fun", + description: "A cat command", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const wait = await message.inlineReply("Getting cat picture..."); + let subreddits = ["cat", "cats"]; + let subreddit = subreddits[Math.floor(Math.random() * subreddits.length)]; + const img = await api(subreddit).catch(err => console.log(err)); + const Embed = new MessageEmbed() + .setTitle(`A cat picture from r/${subreddit}`) + .setURL(`https://reddit.com/r/${subreddit}`) + .setColor(client.color) + .setImage(img) + .setTimestamp() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ); + wait.edit("", { embed: Embed }); + }, +}; diff --git a/commands/Fun/coinflip.js b/commands/Fun/coinflip.js new file mode 100644 index 0000000..7655cf6 --- /dev/null +++ b/commands/Fun/coinflip.js @@ -0,0 +1,22 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "coinflip", + aliases: ["cf"], + description: "Flip a coin", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let HT = ["Heads!", "Tails!"]; + let pick = HT[Math.floor(Math.random() * HT.length)]; + let embed = new MessageEmbed() + .setColor(client.color) + .setTitle("CoinFilp Game") + .setTimestamp() + .setFooter(`Made by Cath Team`) + .setDescription(pick); + message.inlineReply(embed); + }, +}; diff --git a/commands/Fun/connect4.js b/commands/Fun/connect4.js new file mode 100644 index 0000000..0d83dec --- /dev/null +++ b/commands/Fun/connect4.js @@ -0,0 +1,309 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "connect4", + aliases: ["c4"], + usage: "(User)", + description: "Play a connect 4 game with a user", + category: "Fun", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const challenger = message.member; + const oppenent = message.mentions.members.first(); + + if (!oppenent) return client.err(message, "Fun", "connect4", 1); + + const question = await message.channel.send( + `${oppenent}, would you like to play connect 4 against ${challenger}?` + ); + + ["✅", "❌"].forEach(async el => await question.react(el)); + + const filter = (reaction, user) => + ["✅", "❌"].includes(reaction.emoji.name) && user.id === oppenent.id; + + const response = await question.awaitReactions(filter, { max: 1 }); + + const reaction = response.first(); + + if (reaction.emoji.name === "❌") + return question.edit("Looks like they didn't want to play"); + else { + await message.delete(); + await question.delete(); + + const board = [ + ["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"], + ["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"], + ["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"], + ["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"], + ["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"], + ["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"], + ]; + + const renderBoard = board => { + let tempString = ""; + for (const boardSection of board) { + tempString += `${boardSection.join("")}\n`; + } + + tempString = tempString.concat("1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣"); + + return tempString; + }; + + const initialState = renderBoard(board); + + const initial = new MessageEmbed().setDescription(initialState); + + const gameMessage = await message.channel.send(initial); + + ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣"].forEach(async el => + gameMessage.react(el) + ); + + const gameFilter = (reaction, user) => + ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣"].includes( + reaction.emoji.name + ) && + (user.id === oppenent.id || user.id === challenger.id); + + const gameCollector = gameMessage.createReactionCollector(gameFilter); + + const gameData = [ + { member: challenger, playerColor: "🔴" }, + { member: oppenent, playerColor: "🟡" }, + ]; + + let player = 0; + + const checkFour = (a, b, c, d) => + a === b && b === c && c === d && a !== "⚪"; + + const horizontalCheck = () => { + for (let i = 0; i < 6; i++) { + for (let j = 0; j < 4; j++) { + if ( + checkFour( + board[i][j], + board[i][j + 1], + board[i][j + 2], + board[i][j + 3] + ) + ) + return [ + board[i][j], + board[i][j + 1], + board[i][j + 2], + board[i][j + 3], + ]; + } + } + }; + + const verticalCheck = () => { + for (let j = 0; j < 7; j++) { + for (let i = 0; i < 3; i++) { + if ( + checkFour( + board[i][j], + board[i + 1][j], + board[i + 2][j], + board[i + 3][j] + ) + ) + return [ + board[i][j], + board[i + 1][j], + board[i + 2][j], + board[i + 3][j], + ]; + } + } + }; + + const diagonal1 = () => { + for (let col = 0; col < 4; col++) { + for (let row = 0; row < 3; row++) { + if ( + checkFour( + board[row][col], + board[row + 1][col + 1], + board[row + 2][col + 2], + board[row + 3][col + 3] + ) + ) + return [ + board[row][col], + board[row + 1][col + 1], + board[row + 2], + board[col + 2], + board[row + 3][col + 3], + ]; + } + } + }; + + const diagonal2 = () => { + for (let col = 0; col < 4; col++) { + for (let row = 5; row > 2; row--) { + if ( + checkFour( + board[row][col], + board[row - 1][col + 1], + board[row - 2][col + 2], + board[row - 3][col + 3] + ) + ) + return [ + board[row][col], + board[row - 1][col + 1], + board[row - 2][col + 2], + board[row - 3][col + 3], + ]; + } + } + }; + + const tieCheck = () => { + let count = 0; + for (const el of board) { + for (const string of el) { + if (string !== "⚪") count++; + } + } + if (count === 42) return true; + else return false; + }; + + const checks = [horizontalCheck, verticalCheck, diagonal1, diagonal2]; + + gameCollector.on("collect", (reaction, user) => { + if (user.id === gameData[player].member.id) { + const openSpaces = []; + + switch (reaction.emoji.name) { + case "1️⃣": + for (let i = 5; i > -1; i--) { + if (board[i][0] === "⚪") openSpaces.push({ i, j: 0 }); + } + if (openSpaces.length === 0) + return message.channel.send( + `${gameData[player].member}, that column is already full. Choose a differnt one.` + ); + else + board[openSpaces[0].i][openSpaces[0].j] = + gameData[player].playerColor; + + break; + case "2️⃣": + for (let i = 5; i > -1; i--) { + if (board[i][1] === "⚪") openSpaces.push({ i, j: 1 }); + } + if (openSpaces.length === 0) + return message.channel.send( + `${gameData[player].member}, that column is already full. Choose a differnt one.` + ); + else + board[openSpaces[0].i][openSpaces[0].j] = + gameData[player].playerColor; + + break; + case "3️⃣": + for (let i = 5; i > -1; i--) { + if (board[i][2] === "⚪") openSpaces.push({ i, j: 2 }); + } + if (openSpaces.length === 0) + return message.channel.send( + `${gameData[player].member}, that column is already full. Choose a differnt one.` + ); + else + board[openSpaces[0].i][openSpaces[0].j] = + gameData[player].playerColor; + break; + case "4️⃣": + for (let i = 5; i > -1; i--) { + if (board[i][3] === "⚪") openSpaces.push({ i, j: 3 }); + } + if (openSpaces.length === 0) + return message.channel.send( + `${gameData[player].member}, that column is already full. Choose a differnt one.` + ); + else + board[openSpaces[0].i][openSpaces[0].j] = + gameData[player].playerColor; + break; + case "5️⃣": + for (let i = 5; i > -1; i--) { + if (board[i][4] === "⚪") openSpaces.push({ i, j: 4 }); + } + if (openSpaces.length === 0) + return message.channel.send( + `${gameData[player].member}, that column is already full. Choose a differnt one.` + ); + else + board[openSpaces[0].i][openSpaces[0].j] = + gameData[player].playerColor; + break; + case "6️⃣": + for (let i = 5; i > -1; i--) { + if (board[i][5] === "⚪") openSpaces.push({ i, j: 5 }); + } + if (openSpaces.length === 0) + return message.channel.send( + `${gameData[player].member}, that column is already full. Choose a differnt one.` + ); + else + board[openSpaces[0].i][openSpaces[0].j] = + gameData[player].playerColor; + break; + case "7️⃣": + for (let i = 5; i > -1; i--) { + if (board[i][6] === "⚪") openSpaces.push({ i, j: 6 }); + } + if (openSpaces.length === 0) + return message.channel.send( + `${gameData[player].member}, that column is already full. Choose a differnt one.` + ); + else + board[openSpaces[0].i][openSpaces[0].j] = + gameData[player].playerColor; + break; + } + + if (tieCheck()) { + const TieEmbed = new MessageEmbed().setDescription( + renderBoard(board) + ); + gameCollector.stop("Tie Game"); + return gameMessage.edit(`It was a tie game!`, { embed: TieEmbed }); + } + + for (const func of checks) { + const data = func(); + if (data) { + const WinEmbed = new MessageEmbed().setDescription( + renderBoard(board) + ); + gameCollector.stop(`${gameData[player].member.id} won`); + return gameMessage.edit( + `${gameData[player].member} has won the game!`, + { embed: WinEmbed } + ); + } + } + + player = (player + 1) % 2; + + const newEmbed = new MessageEmbed().setDescription( + renderBoard(board) + ); + gameMessage.edit("", { embed: newEmbed }); + } + }); + } + }, +}; diff --git a/commands/Fun/dog.js b/commands/Fun/dog.js new file mode 100644 index 0000000..bf3df65 --- /dev/null +++ b/commands/Fun/dog.js @@ -0,0 +1,30 @@ +const api = require("imageapi.js"); +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "dog", + aliases: ["dogs"], + category: "Fun", + description: "A dog command", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const wait = await message.inlineReply("Getting dog picture..."); + let subreddits = ["dog", "dogs"]; + let subreddit = subreddits[Math.floor(Math.random() * subreddits.length)]; + const img = await api(subreddit).catch(err => console.log(err)); + const Embed = new MessageEmbed() + .setTitle(`A dog picture from r/${subreddit}`) + .setURL(`https://reddit.com/r/${subreddit}`) + .setColor(client.color) + .setImage(img) + .setTimestamp() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ); + wait.edit("", { embed: Embed }); + }, +}; diff --git a/commands/Fun/hangman.js b/commands/Fun/hangman.js new file mode 100644 index 0000000..9d14f3b --- /dev/null +++ b/commands/Fun/hangman.js @@ -0,0 +1,92 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const { stripIndents } = require("common-tags"); +const { get } = require("node-superfetch"); +const playing = new Set(); +module.exports = { + name: "hangman", + description: "Play a hangman game", + category: "Fun", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (playing.has(message.channel.id)) + return message.reply("Only one game may be occurring per channel."); + playing.add(message.channel.id); + try { + const { body } = await get("https://emilia-api.xyz/api/hangman").set( + "Authorization", + `Bearer MzU2MDA1NzA4MTQ5NTU1MjAy.5r4BVOkZX8L1ial8chloqopkphU0w19us0UbqgxOQOo` + ); + const word = body.word; + let points = 0; + let displayText = null; + let guessed = false; + const confirmation = []; + const incorrect = []; + const display = new Array(word.length).fill("◯"); + while (word.length !== confirmation.length && points < 6) { + const embed = new MessageEmbed() + .setColor(client.color) + .setTitle("Hangman game").setDescription(stripIndents` + ${displayText === null ? "Here we go!" : displayText ? "Good job!" : "Nope!"} + \`${display.join(" ")}\`. Which letter do you choose? + Incorrect Tries: ${incorrect.join(", ") || "None"} + \`\`\` + . ┌─────┐ + . ┃ ┋ + . ┃ ${points > 0 ? "O" : ""} + . ┃ ${points > 2 ? "/" : " "}${points > 1 ? "|" : ""}${ + points > 3 ? "\\" : "" + } + . ┃ ${points > 4 ? "/" : ""}${points > 5 ? "\\" : ""} + ============= + \`\`\` + `); + let m = await message.channel.send(embed); + const filter = res => { + const choice = res.content.toLowerCase(); + return ( + res.author.id === message.author.id && + !confirmation.includes(choice) && + !incorrect.includes(choice) + ); + }; + const guess = await message.channel.awaitMessages(filter, { + max: 1, + time: 30000, + }); + //m.delete(); + if (!guess.size) { + await message.reply("Sorry, time is up!"); + break; + } + const choice = guess.first().content.toLowerCase(); + if (choice === "end") break; + if (choice.length > 1 && choice === word) { + guessed = true; + break; + } else if (word.includes(choice)) { + displayText = true; + for (let i = 0; i < word.length; i++) { + if (word.charAt(i) !== choice) continue; // eslint-disable-line max-depth + confirmation.push(word.charAt(i)); + display[i] = word.charAt(i); + } + } else { + displayText = false; + if (choice.length === 1) incorrect.push(choice); + points++; + } + } + playing.delete(message.channel.id); + if (word.length === confirmation.length || guessed) + return message.channel.send(`You won. The word is **${word}**!`); + return message.channel.send(`You lost. The word is **${word}**.`); + } catch (err) { + playing.delete(message.channel.id); + } + }, +}; diff --git a/commands/Fun/hug.js b/commands/Fun/hug.js new file mode 100644 index 0000000..d66f389 --- /dev/null +++ b/commands/Fun/hug.js @@ -0,0 +1,34 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "hug", + usage: "(User)", + description: "Hug someone", + category: "Fun", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const words = args.slice(1).join(" "); + const user = + message.mentions.users.first() || + message.guild.members.cache.get(args[0]); + if (!user) { + return client.err(message, "Fun", "hug", 1); + } + if (user.id === message.author.id) { + return client.err(message, "Fun", "hug", 33); + } + const embed = new MessageEmbed(); + embed.setDescription(`${message.author} **hugs** ${user}`); + if (words) { + embed.addField("Words:", reason); + } + embed.setImage( + `https://media.tenor.com/images/ca88f916b116711c60bb23b8eb608694/tenor.gif` + ); + embed.setColor(client.color); + message.inlineReply(embed).then(msg => msg.react("💕")); + }, +}; diff --git a/commands/Fun/kiss.js b/commands/Fun/kiss.js new file mode 100644 index 0000000..753fbb7 --- /dev/null +++ b/commands/Fun/kiss.js @@ -0,0 +1,34 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "kiss", + usage: "(User)", + description: "Kiss someone", + category: "Fun", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const words = args.slice(1).join(" "); + const user = + message.mentions.users.first() || + message.guild.members.cache.get(args[0]); + if (!user) { + return client.err(message, "Fun", "kiss", 1); + } + if (user.id === message.author.id) { + return client.err(message, "Fun", "kiss", 33); + } + const embed = new MessageEmbed(); + embed.setDescription(`${message.author} **kisses** ${user}`); + if (words) { + embed.addField("Words: ", words); + } + embed.setImage( + `https://media.discordapp.net/attachments/814310468906123274/817656819416825896/image0.gif` + ); + embed.setColor(client.color); + message.inlineReply(embed).then(msg => msg.react("💕")); + }, +}; diff --git a/commands/Fun/meme.js b/commands/Fun/meme.js new file mode 100644 index 0000000..919bc65 --- /dev/null +++ b/commands/Fun/meme.js @@ -0,0 +1,30 @@ +const api = require("imageapi.js"); +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "meme", + aliases: ["memes"], + category: "Fun", + description: "A meme command", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const wait = await message.inlineReply("Getting meme..."); + let subreddits = ["comedyheaven", "dank", "meme", "memes"]; + let subreddit = subreddits[Math.floor(Math.random() * subreddits.length)]; + const img = await api(subreddit).catch(err => console.log(err)); + const Embed = new MessageEmbed() + .setTitle(`A meme from r/${subreddit}`) + .setURL(`https://reddit.com/r/${subreddit}`) + .setColor(client.color) + .setImage(img) + .setTimestamp() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ); + wait.edit("", { embed: Embed }); + }, +}; diff --git a/commands/Fun/say.js b/commands/Fun/say.js new file mode 100644 index 0000000..1ba09a0 --- /dev/null +++ b/commands/Fun/say.js @@ -0,0 +1,17 @@ +const { Client, Message, Util } = require("discord.js"); +module.exports = { + name: "say", + description: "Pretend a bot to say", + usage: "(Words)", + category: "Fun", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args.length) return; + message.delete(); + return message.channel.send(Util.cleanContent(args.join(" "), message)); + }, +}; diff --git a/commands/Fun/simprate.js b/commands/Fun/simprate.js new file mode 100644 index 0000000..7f52d93 --- /dev/null +++ b/commands/Fun/simprate.js @@ -0,0 +1,31 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "simprate", + aliases: ["simp"], + description: "Check how simp is the user", + usage: "(@User)", + category: "Fun", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let simp = Math.floor(Math.random() * 100); + if (message.mentions.users.first()) { + let target = message.mentions.users.first(); + message.inlineReply( + new MessageEmbed() + .setTitle(`${target.username}'s simp rate`) + .setDescription(`${target.username} is a ${simp}% simp`) + ); + } else { + const target = message.author; + message.inlineReply( + new MessageEmbed() + .setTitle(`${target.username}'s simp rate`) + .setDescription(`You are a ${simp}% simp`) + ); + } + }, +}; diff --git a/commands/Giveaway/end.js b/commands/Giveaway/end.js new file mode 100644 index 0000000..20cfad1 --- /dev/null +++ b/commands/Giveaway/end.js @@ -0,0 +1,22 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "gend", + UserPerm: "MANAGE_MESSAGES", + usage: "(Message ID)", + description: "End a giveaway", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args[0]) return client.err(message, "Giveaway", "end", 27); + const giveaway = client.giveaways.giveaways.find( + g => g.messageID === args.join(" ") + ); + if (!giveaway) return client.err(message, "Giveaway", "end", 26); + client.giveaways.edit(giveaway.messageID, { + setEndTimestamp: Date.now(), + }); + }, +}; diff --git a/commands/Giveaway/giveaway.js b/commands/Giveaway/giveaway.js new file mode 100644 index 0000000..437bcb7 --- /dev/null +++ b/commands/Giveaway/giveaway.js @@ -0,0 +1,52 @@ +const ms = require("ms"); +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "giveaway", + aliases: ["gstart"], + description: "Start a giveaway", + usage: "(Channel) (Time) (Winners(Number)) (Prize)", + UserPerm: "MANAGE_MESSAGES", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const channel = message.mentions.channels.first(); + if (!channel) return client.err(message, "Giveaway", "giveaway", 28); + const duration = args[1]; + if (!duration) return client.err(message, "Giveaway", "giveaway", 29); + const winners = parseInt(args[2]); + if (!winners) return client.err(message, "Giveaway", "giveaway", 30); + if (isNaN(winners)) return client.err(message, "Giveaway", "giveaway", 31); + const prize = args.slice(3).join(" "); + if (!prize) return client.err(message, "Giveaway", "giveaway", 32); + client.giveaways.start(channel, { + time: ms(duration), + prize: prize, + winnerCount: winners, + hostedBy: message.author, + messages: { + giveaway: "🎉🎉 **GIVEAWAY** 🎉🎉", + giveawayEnded: "🎉🎉 **GIVEAWAY ENDED** 🎉🎉", + timeRemaining: "Time Remaining **{duration}**!", + inviteToParticipate: "React with 🎉 to enter!", + winMessage: `Congratulations {winners}! You won the **${prize}**!`, + noWinner: "Could not determine a winner!", + embedFooter: "Made by Ń1ght", + hostedBy: "Hosted by: {user}", + winners: "Winner(s)", + messageURL: "", + endedAt: "Ends at", + units: { + seconds: "seconds", + minutes: "minutes", + hours: "hours", + days: "days", + pluralS: false, + }, + }, + }); + message.inlineReply(`Giveaway is started in ${channel}`); + }, +}; diff --git a/commands/Giveaway/reroll.js b/commands/Giveaway/reroll.js new file mode 100644 index 0000000..013a223 --- /dev/null +++ b/commands/Giveaway/reroll.js @@ -0,0 +1,21 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "reroll", + aliases: ["greroll"], + usage: "(Message ID)", + description: "Reroll a giveaway", + UserPerm: "MANAGE_MESSAGES", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args[0]) return client.err(message, "Giveaway", "reroll", 27); + const giveaway = client.giveaways.giveaways.find( + g => g.messageID === args[0] + ); + if (!giveaway) return client.err(message, "Giveaway", "reroll", 26); + client.giveaways.reroll(giveaway.messageID); + }, +}; diff --git a/commands/Moderation/announce.js b/commands/Moderation/announce.js new file mode 100644 index 0000000..8dc43b5 --- /dev/null +++ b/commands/Moderation/announce.js @@ -0,0 +1,45 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "announce", + UserPerm: "MANAGE_MESSAGES", + BotPerm: "MANAGE_MESSAGES", + usage: "{Channel} (Message)", + description: "Announce a message to a channel.", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const channel = message.mentions.channels.first() || message.channel; + if (!args[0]) return client.err(message, "Moderation", "announce", 4); + try { + message.delete(); + channel.send( + new MessageEmbed() + .setAuthor( + `Sent by ${message.member.displayName}`, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setDescription(args.slice(0).join(" ")) + .setTimestamp() + .setColor(client.color) + ); + message.inlineReply( + new MessageEmbed() + .setTitle(`Message Announced`) + .addField("**Moderator**", message.author.tag, true) + .setTimestamp() + .setFooter( + message.member.displayName, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setColor(client.color) + ); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "announce", 999); + } + }, +}; diff --git a/commands/Moderation/ban.js b/commands/Moderation/ban.js new file mode 100644 index 0000000..c5419ee --- /dev/null +++ b/commands/Moderation/ban.js @@ -0,0 +1,59 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "ban", + description: "Ban an user", + BotPerm: "BAN_MEMBERS", + UserPerm: "BAN_MEMBERS", + usage: "(User) {Reason}", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let target = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]); + let reason = args.slice(1).join(" ") || "No reason provided"; + if (!target) { + try { + target = await client.users.fetch(args[0]); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "ban", 1); + } + } else { + if (target.id === message.author.id) + return client.err(message, "Moderation", "ban", 2); + if (message.member.roles.highest.position < target.roles.highest.position) + return client.err(message, "Moderation", "ban", 8); + if ( + message.guild.me.roles.highest.position < target.roles.highest.position + ) + return client.err(message, "Moderation", "ban", 9); + } + if (reason.length > 1024) reason = reason.slice(0, 1021) + "..."; + try { + const embed = new MessageEmbed() + .setTitle("User Banned") + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", target.user.tag, true) + .addField("**Reason**", reason, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + await message.guild.members.ban(target.id, { + reason: reason, + }); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "ban", 999); + } + }, +}; diff --git a/commands/Moderation/clear.js b/commands/Moderation/clear.js new file mode 100644 index 0000000..32e5a60 --- /dev/null +++ b/commands/Moderation/clear.js @@ -0,0 +1,47 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const ms = require("ms"); +module.exports = { + name: "purge", + aliases: ["clear", "c"], + UserPerm: "MANAGE_MESSAGES", + BotPerm: "MANAGE_MESSAGES", + description: "Clear/Purge 1-100 messages in the channel", + usage: "(Number)", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if ( + !args[0] || + isNaN(args[0]) || + parseInt(args[0]) > 100 || + parseInt(args[0] < 0) + ) + return client.err(message, "Moderation", "clear", 7); + const messages = await message.channel.messages.fetch({ + limit: parseInt(args[0]), + }); + const usable = messages.filter( + m => m.createdTimestamp - Date.now() < ms("14d") && !m.pinned + ); + await message.delete(); + await message.channel.bulkDelete(usable).then(() => + message.channel + .send( + new MessageEmbed() + .setTitle(`Message Cleared`) + .addField("**Moderator**", message.author.tag, true) + .setTimestamp() + .setFooter( + message.member.displayName, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setColor(client.color) + ) + .then(m => m.delete({ timeout: 10000 })) + ); + }, +}; diff --git a/commands/Moderation/clearWarns.js b/commands/Moderation/clearWarns.js new file mode 100644 index 0000000..ccbf530 --- /dev/null +++ b/commands/Moderation/clearWarns.js @@ -0,0 +1,48 @@ +const db = require("../../models/warns"); +module.exports = { + name: "clear-warns", + aliases: ["cw"], + usage: "(User)", + description: "Clear an user's warns", + UserPerm: "MANAGE_MESSAGES", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const user = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]) || + message.author; + if (!user) { + return client.err(message, "Moderation", "clearWarns", 1); + } + db.findOne( + { Guild: message.guild.id, User: user.id }, + async (err, data) => { + if (data) { + await db.findOneAndDelete({ + Guild: message.guild.id, + User: user.id, + }); + return message.inlineReply( + new MessageEmbed() + .setTitle(`Warns Cleared`) + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", user.tag, true) + .setTimestamp() + .setFooter( + message.member.displayName, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setColor(client.color) + ); + } else { + return client.err(message, "Moderation", "clearWarns", 10); + } + } + ); + }, +}; diff --git a/commands/Moderation/kick.js b/commands/Moderation/kick.js new file mode 100644 index 0000000..7947257 --- /dev/null +++ b/commands/Moderation/kick.js @@ -0,0 +1,52 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "kick", + description: "Kick an user", + UserPerm: "KICK_MEMBERS", + BotPem: "KICK_MEMBERS", + usage: "(User) {Reason}", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let target = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]); + let reason = args.slice(1).join(" ") || "No reason provided"; + if (!target) { + return client.err(message, "Moderation", "kick", 1); + } else { + if (target.id === message.author.id) + return client.err(message, "Moderation", "kick", 2); + if (message.member.roles.highest.position < target.roles.highest.position) + return client.err(message, "Moderation", "kick", 8); + if ( + message.guild.me.roles.highest.position < target.roles.highest.position + ) + return client.err(message, "Moderation", "kick", 9); + } + if (reason.length > 1024) reason = reason.slice(0, 1021) + "..."; + try { + const embed = new MessageEmbed() + .setTitle("User Kicked") + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", target.user.tag, true) + .addField("**Reason**", reason, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + await target.kick(reason); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "kick", 999); + } + }, +}; diff --git a/commands/Moderation/lock.js b/commands/Moderation/lock.js new file mode 100644 index 0000000..6529673 --- /dev/null +++ b/commands/Moderation/lock.js @@ -0,0 +1,33 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); + +module.exports = { + name: "lockdown", + aliases: ["lock"], + description: "Lock a channel", + UserPerm: "MANAGE_CHANNELS", + BotPerm: "MANAGE_CHANNELS", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + message.channel + .createOverwrite(message.guild.id, { SEND_MESSAGES: false }) + .then(() => { + const embed = new MessageEmbed() + .setTitle("Channel Locked") + .addField("**Moderator**", message.author.tag, true) + .addField("**Channel**", `<#${message.channel.id}>`, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + }); + }, +}; diff --git a/commands/Moderation/mute.js b/commands/Moderation/mute.js new file mode 100644 index 0000000..f3b6cb8 --- /dev/null +++ b/commands/Moderation/mute.js @@ -0,0 +1,146 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const ms = require("ms"); +module.exports = { + name: "mute", + description: "Mute an user.", + usage: "(User) (Time) {Reason}", + UserPerm: "MANAGE_MESSAGES", + BotPerm: "MANAGE_ROLES", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let Member = message.mentions.members.first(); + const time = args[1]; + if (!Member) return client.err(message, "Moderation", "mute", 1); + if (!time) { + let reason = "No reason provided"; + const role = message.guild.roles.cache.find(x => x.name === "Muted"); + if (!role) { + try { + let muterole = await message.guild.roles.create({ + data: { + name: "Muted", + permissions: [], + }, + }); + message.guild.channels.cache + .filter(c => c.type === "text") + .forEach(async (channel, id) => { + await channel.createOverwrite(muterole, { + SEND_MESSAGES: false, + ADD_REACTIONS: false, + }); + }); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "mute", 999); + } + } + let role2 = message.guild.roles.cache.find(x => x.name === "Muted"); + await Member.roles.add(role2); + const embed = new MessageEmbed() + .setTitle("User Muted") + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", Member.user.tag, true) + .addField("**Reason**", reason, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + } + if (!ms(time)) { + let reason = args.slice(1).join(" ") || "No reason provided"; + const role = message.guild.roles.cache.find(x => x.name === "Muted"); + if (!role) { + try { + let muterole = await message.guild.roles.create({ + data: { + name: "Muted", + permissions: [], + }, + }); + message.guild.channels.cache + .filter(c => c.type === "text") + .forEach(async (channel, id) => { + await channel.createOverwrite(muterole, { + SEND_MESSAGES: false, + ADD_REACTIONS: false, + }); + }); + } catch (e) { + console.log(err); + return client.err(message, "Moderation", "mute", 999); + } + } + let role2 = message.guild.roles.cache.find(x => x.name === "Muted"); + await Member.roles.add(role2); + const embed = new MessageEmbed() + .setTitle("User Muted") + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", Member.user.tag, true) + .addField("**Reason**", reason, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + setTimeout(async () => { + await Member.roles.remove(role2); + }, ms(time)); + } else { + let reason = args.slice(2).join(" ") || "No reason provided"; + const role = message.guild.roles.cache.find(x => x.name === "Muted"); + if (!role) { + try { + let muterole = await message.guild.roles.create({ + data: { + name: "Muted", + permissions: [], + }, + }); + message.guild.channels.cache + .filter(c => c.type === "text") + .forEach(async (channel, id) => { + await channel.createOverwrite(muterole, { + SEND_MESSAGES: false, + ADD_REACTIONS: false, + }); + }); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "mute", 999); + } + } + let role2 = message.guild.roles.cache.find(x => x.name === "Muted"); + await Member.roles.add(role2); + const embed = new MessageEmbed() + .setTitle("User Muted") + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", Member.user.tag, true) + .addField("**Time**", ms(ms(time), { long: true }), true) + .addField("**Reason**", reason, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + setTimeout(async () => { + await Member.roles.remove(role2); + }, ms(time)); + } + }, +}; diff --git a/commands/Moderation/nuke.js b/commands/Moderation/nuke.js new file mode 100644 index 0000000..fbdb996 --- /dev/null +++ b/commands/Moderation/nuke.js @@ -0,0 +1,59 @@ +const { Client, Message } = require("discord.js"); +module.exports = { + name: "nuke", + description: "Destroy a channel and create a new one", + usage: "{Channel}", + UserPerm: "MANAGE_CHANNELS", + BotPerm: "MANAGE_CHANNELS", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + try { + let filter = m => m.author.id === message.author.id; + message.channel.send("Do you want to nuke this channel? (Yes/No)"); + message.channel + .awaitMessages(filter, { + max: 1, + time: 99999, + errors: ["time"], + }) + .then(msg => { + message = msg.first(); + if ( + message.content.toLowerCase() == "yes" || + message.content.toLowerCase() == "y" + ) { + let channel = client.channels.cache.get(message.channel.id); + channel.clone().then(ch => { + if (channel.parent) { + ch.setParent(channel.parent.id); + } else; + ch.setPosition(channel.position); + channel.delete(); + ch.send( + "https://i.pinimg.com/originals/06/c3/92/06c392b847166a9a671bfcd590d8fff7.gif \nFriendly nuke has been launched." + ); + }); + } else if ( + message.content.toLowerCase() == "no" || + message.content.toLowerCase() == "n" + ) { + message.delete(); + return message.channel.send("The process has been cancelled"); + } else { + message.delete(); + return message.channel.send( + `The process has been cancelled due to invalid response` + ); + } + }); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "nuke", 999); + } + }, +}; diff --git a/commands/Moderation/removeWarn.js b/commands/Moderation/removeWarn.js new file mode 100644 index 0000000..e06f688 --- /dev/null +++ b/commands/Moderation/removeWarn.js @@ -0,0 +1,58 @@ +const db = require("../../models/warns"); +module.exports = { + name: "remove-warn", + aliases: ["rw"], + UserPerm: "MANAGE_MESSAGES", + description: "Remove a latest warn for an user", + usage: "(User)", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + try { + const user = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]) || + message.guild.members.cache.find( + r => + r.user.username.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.guild.members.cache.find( + r => + r.displayName.toLowerCase() === args.join(" ").toLocaleLowerCase() + ); + if (!user) return client.err(message, "Moderation", "removeWarn", 1); + db.findOne( + { guildid: message.guild.id, user: user.user.id }, + async (err, data) => { + if (err) throw err; + if (data) { + let number = parseInt(args[1]) - 1; + data.Warns.splice(number, 1); + const embed = new MessageEmbed() + .setTitle("Warn Removed") + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", user.user.tag, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + data.save(); + } else { + return client.err(message, "Moderation", "removeWarn", 10); + } + } + ); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "removeWarn", 999); + } + }, +}; diff --git a/commands/Moderation/role.js b/commands/Moderation/role.js new file mode 100644 index 0000000..bcd6ee8 --- /dev/null +++ b/commands/Moderation/role.js @@ -0,0 +1,57 @@ +const { MessageEmbed } = require("discord.js"); +module.exports = { + name: "role", + UserPerm: "MANAGE_ROLES", + BotPerm: "MANAGE_ROLES", + usage: "(Role) (User)", + description: "Add/Remove a role for an user", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + try { + const target = + message.mentions.members.first() || + message.guild.members.cache.get(args[1]); + if (!target) return client.err(message, "Moderation", "role", 1); + const role = + message.mentions.roles.first() || + message.guild.roles.cache.get(args[0]) || + message.guild.roles.cache.find(r => r.name == args[0]); + if (!role) return client.err(message, "Moderation", "role", 3); + if (target.roles.cache.has(role.id)) { + const embed = new MessageEmbed() + .setTitle("Role Removed") + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", target.user.tag, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed).then(await target.roles.remove(role)); + } else { + const embed = new MessageEmbed() + .setTitle("Role Added") + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", target.user.tag, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed).then(await target.roles.add(role)); + } + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "role", 999); + } + }, +}; diff --git a/commands/Moderation/slowmode.js b/commands/Moderation/slowmode.js new file mode 100644 index 0000000..feb805a --- /dev/null +++ b/commands/Moderation/slowmode.js @@ -0,0 +1,62 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const ms = require("ms"); +module.exports = { + name: "slowmode", + UserPerm: "MANAGE_CHANNELS", + description: "Set slowmode at a specific channel", + BotPerm: "MANAGE_CHANNELS", + usage: "(Time)", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + try { + if (!args[0]) { + message.channel.setRateLimitPerUser(0); + const embed = new MessageEmbed() + .setTitle("Slowmode Removed") + .addField("**Moderator**", message.author.tag, true) + .addField("**Channel**", `<#${message.channel.id}>`, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + } + const milliseconds = ms(args[0]); + if (isNaN(milliseconds)) + return client.err(message, "Moderation", "slowmode", 101); + if (milliseconds < 1000) + return client.err(message, "Moderation", "slowmode", 16); + message.channel.setRateLimitPerUser(milliseconds / 1000); + const embed = new MessageEmbed() + .setTitle("Slowmode Added") + .addField("**Moderator**", message.author.tag, true) + .addField("**Channel**", `<#${message.channel.id}>`, true) + .addField( + "**Rate**", + ms(milliseconds, { + long: true, + }), + true + ) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "slowmode", 999); + } + }, +}; diff --git a/commands/Moderation/unban.js b/commands/Moderation/unban.js new file mode 100644 index 0000000..51e1908 --- /dev/null +++ b/commands/Moderation/unban.js @@ -0,0 +1,35 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "unban", + description: "Unban an user", + UserPerm: "BAN_MEMBERS", + BotPerm: "BAN_MEMBERS", + usage: "(User)", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + try { + if (!args[0]) return client.err(message, "Moderation", "unban", 1); + const user = await message.guild.members.unban(args[0]); + const embed = new MessageEmbed() + .setTitle("User Unbanned") + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", user.user.tag, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "unban", 999); + } + }, +}; diff --git a/commands/Moderation/unlock.js b/commands/Moderation/unlock.js new file mode 100644 index 0000000..a95fa56 --- /dev/null +++ b/commands/Moderation/unlock.js @@ -0,0 +1,32 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); + +module.exports = { + name: "unlock", + description: "Lock a channel", + UserPerm: "MANAGE_CHANNELS", + BotPerm: "MANAGE_CHANNELS", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + message.channel + .createOverwrite(message.guild.id, { SEND_MESSAGES: true }) + .then(() => { + const embed = new MessageEmbed() + .setTitle("Channel Unlocked") + .addField("**Moderator**", message.author.tag, true) + .addField("**Channel**", `<#${message.channel.id}>`, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + }); + }, +}; diff --git a/commands/Moderation/unmute.js b/commands/Moderation/unmute.js new file mode 100644 index 0000000..1f53a00 --- /dev/null +++ b/commands/Moderation/unmute.js @@ -0,0 +1,52 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "unmute", + UserPerm: "MANAGE_MESSAGES", + BotPerm: "MANAGE_ROLES", + usage: "(User)", + description: "Unmute an user", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + try { + const user = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]); + if (!user) return client.err(message, "Moderation", "unmute", 1); + const role = message.guild.roles.cache.find(r => r.name === "Muted"); + if (!role) { + try { + await message.guild.roles.create({ + data: { + name: "Muted", + permissions: [], + }, + }); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "unmute", 999); + } + } + await user.roles.remove(role); + const embed = new MessageEmbed() + .setTitle("User Unmuted") + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", user.user.tag, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "unmute", 999); + } + }, +}; diff --git a/commands/Moderation/warn.js b/commands/Moderation/warn.js new file mode 100644 index 0000000..c385ddc --- /dev/null +++ b/commands/Moderation/warn.js @@ -0,0 +1,64 @@ +const db = require("../../models/warns"); +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "warn", + UserPerm: "MANAGE_MESSAGES", + usage: "(User) {Reason}", + description: "Warn a user", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + try { + const user = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]); + if (!user) return client.err(message, "Moderation", "warn", 1); + const reason = args.slice(1).join(" ") || "No reason provided"; + db.findOne( + { Guild: message.guild.id, User: user.id }, + async (err, data) => { + if (!data) { + data = new db({ + Guild: message.guild.id, + User: user.id, + Warns: [ + { + Reason: reason, + }, + ], + }); + } else { + const obj = { + Reason: reason, + }; + data.Warns.push(obj); + } + data.save(); + } + ); + user.send( + `You have been warned in **${message.guild.name}** for **${reason}**` + ); + const embed = new MessageEmbed() + .setTitle("User Warned") + .addField("**Moderator**", message.author.tag, true) + .addField("**User**", user.user.tag, true) + .addField("**Reason**", reason, true) + .setFooter( + message.member.displayName || message.author.username, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(client.color) + .setTimestamp(); + message.inlineReply(embed); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "warn", 1); + } + }, +}; diff --git a/commands/Moderation/warns.js b/commands/Moderation/warns.js new file mode 100644 index 0000000..f423dde --- /dev/null +++ b/commands/Moderation/warns.js @@ -0,0 +1,53 @@ +const db = require("../../models/warns"); +const { Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "warns", + UserPerm: "MANAGE_MESSAGES", + description: "Check the warns of an user", + usage: "{User}", + category: "Moderation", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + try { + const user = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]) || + message.guild.members.cache.find( + r => + r.user.username.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.guild.members.cache.find( + r => + r.displayName.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.author; + db.findOne( + { Guild: message.guild.id, User: user.id }, + async (err, data) => { + if (data) { + message.channel.send( + new MessageEmbed() + .setTitle(`${user.user.tag}'s warns`) + .setDescription( + data.Warns.map( + (w, i) => `\`${i + 1}\` | Reason : ${w.Reason}` + ) + ) + .setTimestamp() + .setColor("client.color") + ); + } else { + return client.err(message, "Moderation", "warns", 10); + } + } + ); + } catch (e) { + console.log(e); + return client.err(message, "Moderation", "warns", 999); + } + }, +}; diff --git a/commands/Music/leave.js b/commands/Music/leave.js new file mode 100644 index 0000000..8715503 --- /dev/null +++ b/commands/Music/leave.js @@ -0,0 +1,35 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "disconnect", + aliases: ["dc"], + description: "Leave The Voice Channel", + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let channel = message.member.voice.channel; + if (!channel) return client.err(message, "Music", "disconnect", 35); + if (!message.guild.me.voice.channel) + return client.err(message, "Music", "disconnect", 41); + try { + await message.guild.me.voice.channel.leave(); + } catch (error) { + await message.guild.me.voice.kick(message.guild.me.id); + } + + const Embed = new MessageEmbed() + .setAuthor("Left Voice Channel", client.user.displayAvatarURL()) + .setColor("GREEN") + .setTitle( + `By user: ${message.author.tag}`, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setDescription("🎶 Left The Voice Channel.") + .setTimestamp(); + + return message.channel.send(Embed); + }, +}; diff --git a/commands/Music/loop.js b/commands/Music/loop.js new file mode 100644 index 0000000..36cedaf --- /dev/null +++ b/commands/Music/loop.js @@ -0,0 +1,26 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "loop", + description: "Music loop", + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const serverQueue = message.client.queue.get(message.guild.id); + if (serverQueue) { + serverQueue.loop = !serverQueue.loop; + return message.channel.send({ + embed: { + color: "GREEN", + description: `🔁 **|** Loop is ${ + serverQueue.loop === true ? "enabled" : "disabled" + }`, + }, + }); + } + return client.err(message, "Music", "loop", 34); + }, +}; diff --git a/commands/Music/lyrics.js b/commands/Music/lyrics.js new file mode 100644 index 0000000..16f315d --- /dev/null +++ b/commands/Music/lyrics.js @@ -0,0 +1,42 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const lyricsFinder = require("lyrics-finder"); +const splitlyrics = require("../../util/pagination"); + +module.exports = { + name: "lyrics", + description: "Get lyrics for the currently playing song", + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const queue = message.client.queue.get(message.guild.id); + if (!queue) return client.err(message, "Music", "lyrics", 34); + let lyrics = null; + try { + lyrics = await lyricsFinder(queue.songs[0].title, ""); + if (!lyrics) + lyrics = `**No lyrics are found for ${queue.songs[0].title}.**`; + } catch (error) { + lyrics = `**No lyrics are found for ${queue.songs[0].title}.**`; + } + const splittedLyrics = splitlyrics.chunk(lyrics, 1024); + + let lyricsEmbed = new MessageEmbed() + .setAuthor( + `${queue.songs[0].title} — Lyrics`, + "https://i.imgur.com/qHPXWxN.gif" + ) + .setThumbnail(queue.songs[0].img) + .setColor("YELLOW") + .setDescription(splittedLyrics[0]) + .setFooter(`Page 1 of ${splittedLyrics.length}.`) + .setTimestamp(); + + const lyricsMsg = await message.channel.send(lyricsEmbed); + if (splittedLyrics.length > 1) + await splitlyrics.pagination(lyricsMsg, message.author, splittedLyrics); + }, +}; diff --git a/commands/Music/nowplaying.js b/commands/Music/nowplaying.js new file mode 100644 index 0000000..e78de68 --- /dev/null +++ b/commands/Music/nowplaying.js @@ -0,0 +1,25 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "nowplaying", + description: "To show the music which is currently playing in this server", + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const serverQueue = message.client.queue.get(message.guild.id); + if (!serverQueue) return client.err(message, "Music", "nowplaying", 34); + let song = serverQueue.songs[0]; + let thing = new MessageEmbed() + .setAuthor("Now Playing", "https://i.imgur.com/qHPXWxN.gif") + .setThumbnail(song.img) + .setColor("client.color") + .addField("Name:", `**${song.title}**`, true) + .addField("Duration:", `**${song.duration}**`, true) + .addField("Requested by:", `**${song.req.tag}**`, true) + .setFooter(`Views:${song.views} | ${song.ago}`); + return message.channel.send(thing); + }, +}; diff --git a/commands/Music/pause.js b/commands/Music/pause.js new file mode 100644 index 0000000..8e5a64f --- /dev/null +++ b/commands/Music/pause.js @@ -0,0 +1,29 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "pause", + description: "To pause the current music in the server", + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const serverQueue = message.client.queue.get(message.guild.id); + if (serverQueue && serverQueue.playing) { + serverQueue.playing = false; + try { + serverQueue.connection.dispatcher.pause(); + } catch (error) { + message.client.queue.delete(message.guild.id); + return client.err(message, "Music", "pause", 36); + } + let xd = new MessageEmbed() + .setDescription(`⏸ Paused the music for ${message.author.username}`) + .setColor("YELLOW") + .setTitle("Music has been paused."); + return message.channel.send(xd); + } + return client.err(message, "Music", "pause", 34); + }, +}; diff --git a/commands/Music/play.js b/commands/Music/play.js new file mode 100644 index 0000000..6a35794 --- /dev/null +++ b/commands/Music/play.js @@ -0,0 +1,204 @@ +const { Client, Message, MessageEmbed, Util } = require("discord.js"); +const ytdl = require("ytdl-core"); +const ytdlDiscord = require("discord-ytdl-core"); +const yts = require("yt-search"); +const scdl = require("soundcloud-downloader").default; +const config = require("../../config.json"); +module.exports = { + name: "play", + description: "Play songs", + usage: "(YouTube_URL)/(Song Name)", + aliases: ["p"], + category: "Music", + BotPerm: ["CONNECT", "SPEAK"], + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let channel = message.member.voice.channel; + if (!channel) return client.err(message, "Music", "play", 35); + var searchString = args.join(" "); + if (!searchString) return client.err(message, "Music", "play", 0); + const url = args[0] ? args[0].replace(/<(.+)>/g, "$1") : ""; + var serverQueue = message.client.queue.get(message.guild.id); + + let songInfo; + let song; + if ( + url.match(/^(https?:\/\/)?(www\.)?(m\.)?(youtube\.com|youtu\.?be)\/.+$/gi) + ) { + try { + songInfo = await ytdl.getInfo(url); + if (!songInfo) return client.err(message, "Music", "play", 42); + song = { + id: songInfo.videoDetails.videoId, + title: songInfo.videoDetails.title, + url: songInfo.videoDetails.video_url, + img: songInfo.player_response.videoDetails.thumbnail.thumbnails[0] + .url, + duration: songInfo.videoDetails.lengthSeconds, + ago: songInfo.videoDetails.publishDate, + views: String(songInfo.videoDetails.viewCount).padStart(10, " "), + req: message.author, + }; + } catch (error) { + console.log(e); + return client.err(message, "Music", "play", 999); + } + } else if (url.match(/^https?:\/\/(soundcloud\.com)\/(.*)$/gi)) { + try { + songInfo = await scdl.getInfo(url); + if (!songInfo) return client.err(message, "Music", "play", 43); + song = { + id: songInfo.permalink, + title: songInfo.title, + url: songInfo.permalink_url, + img: songInfo.artwork_url, + ago: songInfo.last_modified, + views: String(songInfo.playback_count).padStart(10, " "), + duration: Math.ceil(songInfo.duration / 1000), + req: message.author, + }; + } catch (e) { + console.error(e); + return client.err(message, "Music", "play", 999); + } + } else { + try { + var searched = await yts.search(searchString); + if (searched.videos.length === 0) + return client.err(message, "Music", "play", 44); + songInfo = searched.videos[0]; + song = { + id: songInfo.videoId, + title: Util.escapeMarkdown(songInfo.title), + views: String(songInfo.views).padStart(10, " "), + url: songInfo.url, + ago: songInfo.ago, + duration: songInfo.duration.toString(), + img: songInfo.image, + req: message.author, + }; + } catch (e) { + console.error(e); + return client.err(message, "Music", "play", 999); + } + } + + if (serverQueue) { + serverQueue.songs.push(song); + let thing = new MessageEmbed() + .setAuthor( + "Song has been added to queue", + "https://i.imgur.com/qHPXWxN.gif" + ) + .setThumbnail(song.img) + .setColor("YELLOW") + .addField("Name:", `**${song.title}**`, true) + .addField("Duration:", `**${song.duration}**`, true) + .addField("Requested by:", `**${song.req.tag}**`, true) + .setFooter(`Views:${song.views} | ${song.ago}`); + return message.channel.send(thing); + } + + const queueConstruct = { + textChannel: message.channel, + voiceChannel: channel, + connection: null, + songs: [], + volume: 80, + playing: true, + loop: false, + }; + message.client.queue.set(message.guild.id, queueConstruct); + queueConstruct.songs.push(song); + + const play = async song => { + const queue = message.client.queue.get(message.guild.id); + if (!song) { + message.guild.me.voice.channel.leave(); //If you want your bot stay in vc 24/7 remove this line :D + message.client.queue.delete(message.guild.id); + return client.err(message, "Music", "play", 40); + } + let stream; + let streamType; + + try { + if (song.url.includes("soundcloud.com")) { + try { + stream = await scdl.downloadFormat( + song.url, + scdl.FORMATS.OPUS, + config.soundcloud + ); + } catch (error) { + stream = await scdl.downloadFormat( + song.url, + scdl.FORMATS.MP3, + config.soundcloud + ); + streamType = "unknown"; + } + } else if (song.url.includes("youtube.com")) { + stream = await ytdlDiscord(song.url, { + filter: "audioonly", + quality: "highestaudio", + highWaterMark: 1 << 25, + opusEncoded: true, + }); + streamType = "opus"; + stream.on("error", function (er) { + if (er) { + if (queue) { + queue.songs.shift(); + play(queue.songs[0]); + return client.err(message, "Music", "play", 999); + } + } + }); + } + } catch (error) { + if (queue) { + queue.songs.shift(); + play(queue.songs[0]); + } + } + queue.connection.on("disconnect", () => + message.client.queue.delete(message.guild.id) + ); + const dispatcher = queue.connection + .play(stream, { type: streamType }) + .on("finish", () => { + const shiffed = queue.songs.shift(); + if (queue.loop === true) { + queue.songs.push(shiffed); + } + play(queue.songs[0]); + }); + + dispatcher.setVolumeLogarithmic(queue.volume / 100); + let thing = new MessageEmbed() + .setAuthor(`Playing song`, "https://i.imgur.com/qHPXWxN.gif") + .setThumbnail(song.img) + .setColor("client.color") + .addField("Name:", `**${song.title}**`, true) + .addField("Duration:", `**${song.duration}**`, true) + .addField("Requested by:", `**${song.req.tag}**`, true) + .setFooter(`Views:${song.views} | ${song.ago}`); + queue.textChannel.send(thing); + }; + + try { + const connection = await channel.join(); + queueConstruct.connection = connection; + play(queueConstruct.songs[0]); + } catch (error) { + console.log(e); + message.client.queue.delete(message.guild.id); + await channel.leave(); + return client.err(message, "Music", "play", 39); + } + }, +}; diff --git a/commands/Music/playlist.js b/commands/Music/playlist.js new file mode 100644 index 0000000..a356a3a --- /dev/null +++ b/commands/Music/playlist.js @@ -0,0 +1,201 @@ +const { Client, Message, MessageEmbed, Util } = require("discord.js"); +const yts = require("yt-search"); +const ytdlDiscord = require("discord-ytdl-core"); +var ytpl = require("ytpl"); +const scdl = require("soundcloud-downloader").default; +const config = require("../../config.json"); +module.exports = { + name: "playlist", + description: "Play songs", + usage: "(YouTube Playlist URL)/(Playlist Name)", + category: "Music", + BotPerm: ["CONNECT", "SPEAK"], + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const channel = message.member.voice.channel; + if (!channel) return client.err(message, "Music", "playlist", 35); + const url = args[0] ? args[0].replace(/<(.+)>/g, "$1") : ""; + var searchString = args.join(" "); + if (!searchString || !url) + return client.err(message, "Music", "playlist", 0); + if (url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)) { + try { + const playlist = await ytpl(url.split("list=")[1]); + if (!playlist) return client.err(messgae, "Music", "playlist", 404); + const videos = await playlist.items; + for (const video of videos) { + await handleVideo(video, message, channel, true); + } + return message.channel.send({ + embed: { + color: "GREEN", + description: `✅ **|** Playlist: **\`${videos[0].title}\`** has been added to the queue`, + }, + }); + } catch (e) { + console.error(e); + return client.err(message, "Music", "playlist", 999); + } + } else { + try { + var searched = await yts.search(searchString); + if (searched.playlists.length === 0) + return client.err(message, "Music", "playlist", 38); + var songInfo = searched.playlists[0]; + let listurl = songInfo.listId; + const playlist = await ytpl(listurl); + const videos = await playlist.items; + for (const video of videos) { + // eslint-disable-line no-await-in-loop + await handleVideo(video, message, channel, true); // eslint-disable-line no-await-in-loop + } + let thing = new MessageEmbed() + .setAuthor( + "Playlist has been added to queue", + "https://i.imgur.com/qHPXWxN.gif" + ) + .setThumbnail(songInfo.thumbnail) + .setColor("GREEN") + .setDescription( + `✅ **|** Playlist: **\`${songInfo.title}\`** has been added \`${songInfo.videoCount}\` video to the queue.` + ); + return message.channel.send(thing); + } catch (e) { + console.log(e); + return client.err(message, "Music", "playlist", 999); + } + } + async function handleVideo(video, message, channel, playlist = false) { + const serverQueue = message.client.queue.get(message.guild.id); + const song = { + id: video.id, + title: Util.escapeMarkdown(video.title), + views: video.views ? video.views : "-", + ago: video.ago ? video.ago : "-", + duration: video.duration, + url: `https://www.youtube.com/watch?v=${video.id}`, + img: video.thumbnail, + req: message.author, + }; + if (!serverQueue) { + const queueConstruct = { + textChannel: message.channel, + voiceChannel: channel, + connection: null, + songs: [], + volume: 80, + playing: true, + loop: false, + }; + message.client.queue.set(message.guild.id, queueConstruct); + queueConstruct.songs.push(song); + + try { + var connection = await channel.join(); + queueConstruct.connection = connection; + play(message.guild, queueConstruct.songs[0]); + } catch (e) { + console.log(e); + message.client.queue.delete(message.guild.id); + return client.err(message, "Music", "playlist", 39); + } + } else { + serverQueue.songs.push(song); + if (playlist) return; + let thing = new MessageEmbed() + .setAuthor( + "Song has been added to queue", + "https://i.imgur.com/qHPXWxN.gif" + ) + .setThumbnail(song.img) + .setColor("YELLOW") + .addField("Name:", `**${song.title}**`, true) + .addField("Duration:", `**${song.duration}**`, true) + .addField("Requested by:", `**${song.req.tag}**`, true) + .setFooter(`Views:${song.views} | ${song.ago}`); + return message.channel.send(thing); + } + return; + } + + async function play(guild, song) { + const serverQueue = message.client.queue.get(message.guild.id); + if (!song) { + message.guild.me.voice.channel.leave(); + message.client.queue.delete(message.guild.id); + return client.err(message, "Music", "playlist", 40); + } + let stream; + let streamType; + + try { + if (song.url.includes("soundcloud.com")) { + try { + stream = await scdl.downloadFormat( + song.url, + scdl.FORMATS.OPUS, + config.soundcloud + ); + } catch (error) { + stream = await scdl.downloadFormat( + song.url, + scdl.FORMATS.MP3, + config.soundcloud + ); + streamType = "unknown"; + } + } else if (song.url.includes("youtube.com")) { + stream = await ytdlDiscord(song.url, { + filter: "audioonly", + quality: "highestaudio", + highWaterMark: 1 << 25, + opusEncoded: true, + }); + streamType = "opus"; + stream.on("error", function (er) { + if (er) { + if (serverQueue) { + serverQueue.songs.shift(); + play(serverQueue.songs[0]); + return client.err(message, "Music", "playlist", 999); + } + } + }); + } + } catch (error) { + if (serverQueue) { + console.log(error); + serverQueue.songs.shift(); + play(serverQueue.songs[0]); + } + } + serverQueue.connection.on("disconnect", () => + message.client.queue.delete(message.guild.id) + ); + const dispatcher = serverQueue.connection + .play(stream, { type: streamType }) + .on("finish", () => { + const shiffed = serverQueue.songs.shift(); + if (serverQueue.loop === true) { + serverQueue.songs.push(shiffed); + } + play(guild, serverQueue.songs[0]); + }); + + dispatcher.setVolume(serverQueue.volume / 100); + let thing = new MessageEmbed() + .setAuthor("Playing music", "https://i.imgur.com/qHPXWxN.gif") + .setThumbnail(song.img) + .setColor("BLUE") + .addField("Name:", `**${song.title}**`, true) + .addField("Duration:", `**${song.duration}**`, true) + .addField("Requested by:", `**${song.req.tag}**`, true) + .setFooter(`Views:${song.views} | ${song.ago}`); + serverQueue.textChannel.send(thing); + } + }, +}; diff --git a/commands/Music/queue.js b/commands/Music/queue.js new file mode 100644 index 0000000..68a04c0 --- /dev/null +++ b/commands/Music/queue.js @@ -0,0 +1,52 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const util = require("../../util/pagination"); +module.exports = { + name: "queue", + description: "To show the songs queue", + aliases: ["q"], + category: "Music", + BotPerm: ["MANAGE_MESSAGES", "ADD_REACTIONS"], + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const queue = message.client.queue.get(message.guild.id); + if (!queue) return client.err(message, "Music", "queue", 34); + const que = queue.songs.map( + (t, i) => `\`${++i}.\` | [\`${t.title}\`](${t.url}) - [<@${t.req.id}>]` + ); + const chunked = util.chunk(que, 10).map(x => x.join("\n")); + const embed = new MessageEmbed() + .setAuthor("Songs Queue", "https://i.imgur.com/qHPXWxN.gif") + .setThumbnail(message.guild.iconURL()) + .setColor("client.color") + .setDescription(chunked[0]) + .addField( + "Now Playing", + `[${queue.songs[0].title}](${queue.songs[0].url})`, + true + ) + .addField("Text Channel", queue.textChannel, true) + .addField("Voice Channel", queue.voiceChannel, true) + .setFooter( + `Currently Server Volume is ${queue.volume} | Page 1 of ${chunked.length}.` + ); + if (queue.songs.length === 1) + embed.setDescription( + `**No songs to play next. Add songs by \`\`${await client.prefix( + message + )}play \`\`**` + ); + + try { + const queueMsg = await message.channel.send(embed); + if (chunked.length > 1) + await util.pagination(queueMsg, message.author, chunked); + } catch (e) { + console.log(e); + return client.err(message, "Music", "queue", 999); + } + }, +}; diff --git a/commands/Music/remove.js b/commands/Music/remove.js new file mode 100644 index 0000000..6ef452a --- /dev/null +++ b/commands/Music/remove.js @@ -0,0 +1,35 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "remove", + description: "Remove song from the queue", + usage: "(Number)", + aliases: ["rm"], + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const queue = message.client.queue.get(message.guild.id); + if (!queue) return client.err(message, "Music", "remove", 37); + if (!args.length) return client.err(message, "Music", "remove", 101); + if (isNaN(args[0])) return client.err(message, "Music", "remove", 7); + if (queue.songs.length == 1) + return client.err(message, "Music", "remove", 37); + if (args[0] > queue.songs.length) + return client.err(message, "Music", "remove", 101); + try { + const embed = new MessageEmbed() + .setColor(client.color) + .setDescription(`❌ **|** Removed: **${song[0].title}** from the queue`) + .setTimestamp("Made by Cath Team"); + const song = queue.songs.splice(args[0] - 1, 1); + message.inlineReply(embed); + message.react("✅"); + } catch (e) { + console.log(e); + return client.err(message, "Music", "remove", 999); + } + }, +}; diff --git a/commands/Music/resume.js b/commands/Music/resume.js new file mode 100644 index 0000000..9f67090 --- /dev/null +++ b/commands/Music/resume.js @@ -0,0 +1,28 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "resume", + description: "To resume the paused music", + aliases: ["continue"], + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const serverQueue = message.client.queue.get(message.guild.id); + if (serverQueue && !serverQueue.playing) { + serverQueue.playing = true; + serverQueue.connection.dispatcher.resume(); + let xd = new MessageEmbed() + .setDescription(`▶ Resumed the music for ${message.author.username}`) + .setColor("YELLOW") + .setAuthor( + "Music has been resumed.", + "https://i.imgur.com/qHPXWxN.gif" + ); + return message.channel.send(xd); + } + return client.err(message, "Music", "resume", 34); + }, +}; diff --git a/commands/Music/shuffle.js b/commands/Music/shuffle.js new file mode 100644 index 0000000..ce169eb --- /dev/null +++ b/commands/Music/shuffle.js @@ -0,0 +1,29 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "shuffle", + description: "Shuffle queue", + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const serverQueue = message.client.queue.get(message.guild.id); + if (!serverQueue) return client.err(message, "Music", "shuffle", 37); + try { + let songs = serverQueue.songs; + for (let i = songs.length - 1; i > 1; i--) { + let j = 1 + Math.floor(Math.random() * i); + [songs[i], songs[j]] = [songs[j], songs[i]]; + } + serverQueue.songs = songs; + message.client.queue.set(message.guild.id, serverQueue); + message.react("✅"); + } catch (error) { + message.guild.me.voice.channel.leave(); + message.client.queue.delete(message.guild.id); + return client.err(message, "Music", "shuffle", 36); + } + }, +}; diff --git a/commands/Music/skip.js b/commands/Music/skip.js new file mode 100644 index 0000000..12112b1 --- /dev/null +++ b/commands/Music/skip.js @@ -0,0 +1,37 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "skip", + description: "To skip the current music", + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const channel = message.member.voice.channel; + if (!channel) return client.err(message, "Music", "skip", 35); + const serverQueue = message.client.queue.get(message.guild.id); + if (!serverQueue) return client.err(message, "Music", "skip", 34); + if (!serverQueue.connection) return; + if (!serverQueue.connection.dispatcher) return; + if (serverQueue && !serverQueue.playing) { + serverQueue.playing = true; + serverQueue.connection.dispatcher.resume(); + let xd = new MessageEmbed() + .setDescription(`▶ Skipped the music for ${message.author.username}`) + .setColor("YELLOW") + .setTitle("Music has been skipped"); + return message.channel.send(xd).catch(err => console.log(err)); + } + + try { + serverQueue.connection.dispatcher.end(); + } catch (error) { + serverQueue.voiceChannel.leave(); + message.client.queue.delete(message.guild.id); + return client.err(message, "Music", "skip", 36); + } + message.react("✅"); + }, +}; diff --git a/commands/Music/skipto.js b/commands/Music/skipto.js new file mode 100644 index 0000000..0fd46cf --- /dev/null +++ b/commands/Music/skipto.js @@ -0,0 +1,46 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "skipto", + description: "Skip to the selected queue number", + usage: "(Number)", + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args.length || isNaN(args[0])) + return client.err(message, "Music", "skipto", 101); + const queue = message.client.queue.get(message.guild.id); + if (!queue) return client.err(message, "Music", "skipto", 37); + if (args[0] > queue.songs.length) + return client.err(message, "Music", "skipto", 101); + queue.playing = true; + + if (queue.loop) { + for (let i = 0; i < args[0] - 2; i++) { + queue.songs.push(queue.songs.shift()); + } + } else { + queue.songs = queue.songs.slice(args[0] - 2); + } + try { + queue.connection.dispatcher.end(); + } catch (error) { + queue.voiceChannel.leave(); + message.client.queue.delete(message.guild.id); + return client.err(message, "Music", "skipto", 36); + } + + queue.textChannel + .send({ + embed: { + color: "GREEN", + description: `${message.author} ⏭ skipped ${args[0] - 1} songs`, + }, + }) + .catch(console.error); + message.react("✅"); + }, +}; diff --git a/commands/Music/stop.js b/commands/Music/stop.js new file mode 100644 index 0000000..91124e4 --- /dev/null +++ b/commands/Music/stop.js @@ -0,0 +1,29 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "stop", + description: "To stop the music and clear the queue", + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const channel = message.member.voice.channel; + if (!channel) return client.err(message, "Music", "stop", 35); + const serverQueue = message.client.queue.get(message.guild.id); + if (!serverQueue) return client.err(message, "Music", "stop", 34); + if (!serverQueue.connection) return; + if (!serverQueue.connection.dispatcher) return; + try { + serverQueue.connection.dispatcher.end(); + } catch (error) { + message.guild.me.voice.channel.leave(); + message.client.queue.delete(message.guild.id); + return client.err(message, "Music", "stop", 36); + } + message.client.queue.delete(message.guild.id); + serverQueue.songs = []; + message.react("✅"); + }, +}; diff --git a/commands/Music/volume.js b/commands/Music/volume.js new file mode 100644 index 0000000..022c04f --- /dev/null +++ b/commands/Music/volume.js @@ -0,0 +1,35 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "volume", + description: "To change the server song queue volume", + usage: "(Number)", + aliases: ["vol"], + category: "Music", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const channel = message.member.voice.channel; + if (!channel) return client.err(message, "Music", "volume", 35); + const serverQueue = message.client.queue.get(message.guild.id); + if (!serverQueue) return client.err(message, "Music", "volume", 34); + if (!serverQueue.connection) + return client.err(message, "Music", "volume", 34); + if (!args[0]) + return message.channel.send( + `The current volume is: **${serverQueue.volume}**` + ); + if (isNaN(args[0])) return client.err(message, "Music", "volume", 101); + if (parseInt(args[0]) > 150 || args[0] < 0) + return client.err(message, "Music", "volume", 101); + serverQueue.volume = args[0]; + serverQueue.connection.dispatcher.setVolumeLogarithmic(args[0] / 100); + let xd = new MessageEmbed() + .setDescription(`Tuned the volume to: **${args[0] / 1}/100**`) + .setAuthor("Server Volume Manager", "https://i.imgur.com/qHPXWxN.gif") + .setColor("client.color"); + return message.channel.send(xd); + }, +}; diff --git a/commands/Owner/accept.js b/commands/Owner/accept.js new file mode 100644 index 0000000..416584e --- /dev/null +++ b/commands/Owner/accept.js @@ -0,0 +1,43 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const { Suggestion } = require("../../config.json"); +module.exports = { + name: "accept", + category: "Owner", + usage: "(Message)", + description: "Accept a suggestion", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const MessageID = args[0]; + const acceptQuery = + args.slice(1).join(" ") || `Night doesn't leave any message.`; + + if (!MessageID) return message.reply("Please specify a valid ID"); + try { + const suggestionChannel = message.guild.channels.cache.get(Suggestion); + const suggestEmbed = await suggestionChannel.messages.fetch(MessageID); + console.log(suggestEmbed); + const data = suggestEmbed.embeds[0]; + const acceptEmbed = new MessageEmbed() + .setAuthor(data.author.name, data.author.iconURL) + .setDescription(data.description) + .setColor("GREEN") + .addField("**Status(ACCEPTED)**", acceptQuery); + + suggestEmbed.edit(acceptEmbed); + + const user = await client.users.cache.find( + u => u.tag === data.author.name + ); + message.channel.send("Suggestion accepted."); + user.send(acceptEmbed); + } catch (err) { + message.channel.send("That suggestion doesn't exist"); + console.log(err); + } + }, +}; diff --git a/commands/Owner/add.js b/commands/Owner/add.js new file mode 100644 index 0000000..f60f64f --- /dev/null +++ b/commands/Owner/add.js @@ -0,0 +1,20 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "add", + category: "Owner", + usage: "(Number)", + description: "Add coins from someone", + Owner: true, + /** + * @param {Client}client + * @param {Message}message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args[0] || isNaN(args[0])) + return message.channel.send("Number of coins?"); + const user = message.mentions.members.first() || message.author; + client.data.add(user.id, parseInt(args[0])); + message.react(""); + }, +}; diff --git a/commands/Owner/blacklist.js b/commands/Owner/blacklist.js new file mode 100644 index 0000000..f7e3129 --- /dev/null +++ b/commands/Owner/blacklist.js @@ -0,0 +1,31 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "bk", + category: "Owner", + usage: "(User) (Toggle) (Reason)", + description: "Blacklist someone from the bot", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let user = args[0]; + toggle = args[1]; + reason = args.slice(2).join(" "); + if (toggle === "true") { + await client.data.BK(user, toggle, reason); + message.inlineReply( + `**Blacklisted** ${message.guild.members.cache.get( + user + )}.\n**Reason: **${reason}` + ); + } else { + await client.data.BK(user, toggle, reason); + message.inlineReply( + `Removed blacklist from ${message.guild.members.cache.get(user)}` + ); + } + }, +}; diff --git a/commands/Owner/deny.js b/commands/Owner/deny.js new file mode 100644 index 0000000..47ceef7 --- /dev/null +++ b/commands/Owner/deny.js @@ -0,0 +1,41 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const { Suggestion } = require("../../config.json"); +module.exports = { + name: "deny", + category: "Owner", + usage: "(Message)", + description: "Deny a suggestion", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const MessageID = args[0]; + const denyQuery = + args.slice(1).join(" ") || `Night doesn't leave any message.`; + + if (!MessageID) return message.reply("Please specify a valid ID"); + try { + const suggestionChannel = message.guild.channels.cache.get(Suggestion); + const suggestEmbed = await suggestionChannel.messages.fetch(MessageID); + console.log(suggestEmbed); + const data = suggestEmbed.embeds[0]; + const denyEmbed = new MessageEmbed() + .setAuthor(data.author.name, data.author.iconURL) + .setDescription(data.description) + .setColor("RED") + .addField("**Status(DENIED)**", denyQuery); + suggestEmbed.edit(denyEmbed); + const user = await client.users.cache.find( + u => u.tag === data.author.name + ); + message.channel.send("Suggestion denied."); + user.send(denyEmbed); + } catch (err) { + message.channel.send("That suggestion doesn't exist"); + console.log(err); + } + }, +}; diff --git a/commands/Owner/dm.js b/commands/Owner/dm.js new file mode 100644 index 0000000..4a72f98 --- /dev/null +++ b/commands/Owner/dm.js @@ -0,0 +1,25 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "dm", + category: "Owner", + usage: "(User) (Message)", + description: "DM a user", + Owner: true, + /** + * @param {Client}client + * @param {Message}message + * @param {String[]} args + */ + run: async (client, message, args) => { + const user = client.users.cache.get(id); + if (!user) return message.inlineReply("User?"); + if (!args.slice(1).join(" ")) return message.inlineReply("Message?"); + try { + await user + .send(args.slice(1).join(" ")) + .then(() => message.channel.send(`Sent message.`)); + } catch (err) { + message.author.send("That user can't be dmed"); + } + }, +}; diff --git a/commands/Owner/encrypt.js b/commands/Owner/encrypt.js new file mode 100644 index 0000000..3544327 --- /dev/null +++ b/commands/Owner/encrypt.js @@ -0,0 +1,45 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); + +module.exports = { + name: "code", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const encrypted = encrypt(args.slice(0).join(" ")); + message.channel.send(`\`\`\`${encrypted}\`\`\``); + message.channel.send(`\`\`\`${decrypt(encrypted)}\`\`\``); + function encrypt(inp) { + var str = inp.split(""), + out = ""; + str.forEach((c, i) => { + if (c == " ") { + out += " "; + } else if (i % 3 == 0) { + out += String.fromCharCode(c.charCodeAt(0) + 3); + } else { + out += String.fromCharCode(c.charCodeAt(0) - 2); + } + }); + return out; + } + + function decrypt(inp) { + var str = inp.split(""), + out = ""; + str.forEach((c, i) => { + if (c == " ") { + out += " "; + } else if (i % 3 == 0) { + out += String.fromCharCode(c.charCodeAt(0) - 3); + } else { + out += String.fromCharCode(c.charCodeAt(0) + 2); + } + }); + return out; + } + }, +}; diff --git a/commands/Owner/eval.js b/commands/Owner/eval.js new file mode 100644 index 0000000..deb5fb2 --- /dev/null +++ b/commands/Owner/eval.js @@ -0,0 +1,47 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const util = require("util"); +module.exports = { + name: "eval", + category: "Owner", + aliases: ["e"], + usage: "(Code)", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let code = args.join(" "); + const embed = new MessageEmbed(); + if (!code) { + return client.err(message, "Owner", "eval", "Missing 'Code' argument"); + } + try { + let evaled = await eval(code), + output; + if (evaled.constructor.name === `Promise`) { + output = `📤 Output (Promise)`; + } else { + output = `📤 Output`; + } + if (evaled.length > 800) { + evaled = evaled.substring(0, 800) + `...`; + } + embed + .addField(`📥 Input`, `\`\`\`\n${code}\n\`\`\``) + .addField(output, `\`\`\`js\n${evaled}\n\`\`\``) + .setColor(client.color) + .addField(`Status`, `\`\`\`diff\n+ Success\`\`\``); + return message.channel.send(embed); + } catch (e) { + console.log(e.stack); + embed + .addField(`📥 Input`, `\`\`\`\n${code}\n\`\`\``) + .addField(`📤 Output`, `\`\`\`js\n${e}\n\`\`\``) + .addField(`Status`, `\`\`\`diff\n- Failed\`\`\``) + .setColor(client.color); + return message.channel.send(embed); + } + }, +}; diff --git a/commands/Owner/getinvite.js b/commands/Owner/getinvite.js new file mode 100644 index 0000000..8425cfc --- /dev/null +++ b/commands/Owner/getinvite.js @@ -0,0 +1,50 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "getinvite", + category: "Owner", + usage: "(Guild)", + description: "Generates an invitation to the server", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let guild = null; + if (!args[0]) return client.err(message, "Owner", "getinvite", 0); + if (args[0]) { + let fetched = client.guilds.cache.find(g => g.name === args.join(" ")); + let found = client.guilds.cache.get(args[0]); + if (!found) { + if (fetched) { + guild = fetched; + } + } else { + guild = found; + } + } else { + return message.inlineReply("Invalid Name/ID!"); + } + if (guild) { + let tChannel = guild.channels.cache.find( + ch => + ch.type == "text" && + ch.permissionsFor(ch.guild.me).has("CREATE_INSTANT_INVITE") + ); + if (!tChannel) { + return client.err(message, "Owner", "getinvite", 6); + } + let invite = await tChannel + .createInvite({ temporary: false, maxAge: 0 }) + .catch(err => { + return message.inlineReply(`${err} has occured!`); + }); + message.inlineReply(invite.url); + } else { + return message.inlineReply( + `\`${args.join(" ")}\` - Bot is Not in this server` + ); + } + }, +}; diff --git a/commands/Owner/guilds.js b/commands/Owner/guilds.js new file mode 100644 index 0000000..0a34113 --- /dev/null +++ b/commands/Owner/guilds.js @@ -0,0 +1,29 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "guilds", + category: "Owner", + description: "Check top 10 guilds of the bot", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const guilds = client.guilds.cache + .sort((a, b) => b.memberCount - a.memberCount) + .first(10); + const description = guilds + .map((guild, index) => { + return `${index + 1}) ${guild.name} -> ${guild.memberCount}members`; + }) + .join("\n"); + let embed = new MessageEmbed() + .setTitle("Guilds") + .setDescription(description) + .setColor(client.color) + .setFooter(`Made by Cath Team`) + .setTimestamp(); + message.channel.send(embed); + }, +}; diff --git a/commands/Owner/premium.js b/commands/Owner/premium.js new file mode 100644 index 0000000..6a5cbe2 --- /dev/null +++ b/commands/Owner/premium.js @@ -0,0 +1,22 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "setpremium", + category: "Owner", + usage: "(User) (Toggle) (Tier)", + description: "Set someone into Premium with tiers", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const member = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]); + client.data.Premium(member.id, "true", args[1]); + message.inlineReply( + `**${member.user.username}**'s premium status:\nTier **${args[1]}**` + ); + }, +}; diff --git a/commands/Owner/reaction-role.js b/commands/Owner/reaction-role.js new file mode 100644 index 0000000..8249bb1 --- /dev/null +++ b/commands/Owner/reaction-role.js @@ -0,0 +1,56 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "test", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const embed = new MessageEmbed() + .setAuthor( + "Ń1ght and Cath Nation", + "https://images-ext-2.discordapp.net/external/JyjN4pXpaLIaSOSszAR9dyp03Hf3ouzjUb8kRa0OFiE/%3Fsize%3D2048/https/cdn.discordapp.com/icons/718762019586572341/c35c387563c7527f056276f2a16f526b.webp" + ) + .setColor(client.color) + .setDescription( + "*Welcome to Ń1ght and Cath Nation*.\n**Please get a role below by reacting!**\n**[Invite](https://discord.com/api/oauth2/authorize?client_id=800966959268364288&permissions=4231314550&scope=bot%20applications.commands) | [Support](https://discord.gg/SbQHChmGcp) | [YouTube](https://youtube.com/c/Kirito01) | [Website](https://www.cath.gq)**" + ) + .addFields( + { + name: "Gold<:gold:841194046419370024>", + value: "<@&841200768706543636>", + inline: true, + }, + { + name: "Platinum<:platinum:841194040165924865>", + value: "<@&840536973126270976>", + inline: true, + }, + { + name: "Updates<:Update:841196992385253408>", + value: "<@&841200845885538325>", + inline: true, + }, + { + name: "Announcements<:announce_dark:841195615458951168>", + value: "<@&841026716181069824>", + inline: false, + }, + { + name: "YouTube<:YouTube:841186450497339412>", + value: "<@&765928569397575750>", + inline: true, + } + ) + .setThumbnail(client.user.displayAvatarURL()) + .setURL(client.web) + .setFooter( + "Ń1ght#0001", + "https://images-ext-2.discordapp.net/external/JyjN4pXpaLIaSOSszAR9dyp03Hf3ouzjUb8kRa0OFiE/%3Fsize%3D2048/https/cdn.discordapp.com/icons/718762019586572341/c35c387563c7527f056276f2a16f526b.webp" + ) + .setTimestamp(); + message.channel.send(embed); + }, +}; diff --git a/commands/Owner/restart.js b/commands/Owner/restart.js new file mode 100644 index 0000000..b5a8015 --- /dev/null +++ b/commands/Owner/restart.js @@ -0,0 +1,19 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "restart", + category: "Owner", + description: "Restart the bot", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + message.channel + .send("Restarting...") + .then(message => client.destroy()) + .then(() => client.login(process.env.TOKEN)); + message.channel.send("Restarted"); + }, +}; diff --git a/commands/Owner/rmv.js b/commands/Owner/rmv.js new file mode 100644 index 0000000..1be65e7 --- /dev/null +++ b/commands/Owner/rmv.js @@ -0,0 +1,20 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "rmv", + category: "Owner", + usage: "(Number)", + description: "Remove coins from someone", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args[0] || isNaN(args[0])) + return message.channel.send("Number of coins?"); + const user = message.mentions.members.first() || message.author; + client.data.rmv(user.id, parseInt(args[0])); + message.react(""); + }, +}; diff --git a/commands/Owner/setBotAvatar.js b/commands/Owner/setBotAvatar.js new file mode 100644 index 0000000..3f5b019 --- /dev/null +++ b/commands/Owner/setBotAvatar.js @@ -0,0 +1,25 @@ +const { MessageEmbed } = require("discord.js"); +module.exports = { + name: "setavatar", + category: "Owner", + usage: "(Link)", + description: "Set bot avatar from a link", + Owner: true, + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (message.deletable) { + message.delete(); + } + if (!args || args.length < 1) { + return client.err(message, "Owner", "setBotAvatar", 404); + } + client.user.setAvatar(args.join(" ")); + message.channel + .send("Profile picture has been changed.") + .then(m => m.delete({ timeout: 10000 })); + }, +}; diff --git a/commands/Owner/try.js b/commands/Owner/try.js new file mode 100644 index 0000000..aaf4847 --- /dev/null +++ b/commands/Owner/try.js @@ -0,0 +1,63 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "auth", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const random = client.function.rndint(100000, 999999); + let ed; + const questions = [ + `Please enter the following code to authenicate\n\n\`${random}\``, + ]; + let collectCounter = 0; + let endCounter = 0; + const filter = m => m.author.id === message.author.id; + message.inlineReply("Please check your DM."); + try { + const appStart = await message.author.send( + new MessageEmbed() + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setTitle("One-Time Password") + .setDescription(questions[collectCounter++]) + .setColor(client.color) + .setFooter(`Made by Cath Team`) + .setTimestamp() + ); + const channel = appStart.channel; + const collector = channel.createMessageCollector(filter); + collector.on("collect", () => { + collector.stop("fulfilled"); + }); + + const chan = client.channels.cache.get(Suggestion); + collector.on("end", (collected, reason) => { + if (reason === "fulfilled") { + const msss = collected.map(msg => { + if (msg.content === `${random}`) { + message.author.send( + new MessageEmbed() + .setDescription(`Success`) + .setTimestamp() + .setColor("GREEN") + .setFooter(`Made by Cath Team`) + ); + } else { + message.author.send( + new MessageEmbed() + .setDescription(`Failed\nPlease try again.`) + .setTimestamp() + .setColor("RED") + .setFooter(`Made by Cath Team`) + ); + } + }); + } + }); + } catch (err) { + message.channel.send(`Please enable your DM allowance`); + } + }, +}; diff --git a/commands/Utilities/8ball.js b/commands/Utilities/8ball.js new file mode 100644 index 0000000..2776925 --- /dev/null +++ b/commands/Utilities/8ball.js @@ -0,0 +1,61 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); + +const answers = [ + "Maybe.", + "Certainly not.", + "I hope so.", + "Not in your wildest dreams.", + "There is a good chance.", + "Quite likely.", + "I think so.", + "I hope not.", + "I hope so.", + "Never!", + "Fuhgeddaboudit.", + "Ahaha! Really?!?", + "Pfft.", + "Sorry, bucko.", + "Hell, yes.", + "Hell to the no.", + "The future is bleak.", + "The future is uncertain.", + "I would rather not say.", + "Who cares?", + "Possibly.", + "Never, ever, ever.", + "There is a small chance.", + "Yes!", +]; + +module.exports = { + name: "8ball", + usage: "(Question)", + description: "8ball an answer", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args.join(" ").endsWith("?")) + return client.err(message, "Utilities", "8ball", 101); + else { + const embed = new MessageEmbed() + .setAuthor( + `🎱 ${message.member.displayName} asks`, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setDescription( + `**🎱Question:** \n${args.join(" ")} \n**🎱Answer:** \n ${ + answers[Math.floor(Math.random() * answers.length)] + }` + ) + .setColor(client.color) + .setTimestamp() + .setURL(client.web) + .setFooter("Made by Cath Team"); + message.inlineReply(embed); + } + }, +}; diff --git a/commands/Utilities/afk.js b/commands/Utilities/afk.js new file mode 100644 index 0000000..9f37d97 --- /dev/null +++ b/commands/Utilities/afk.js @@ -0,0 +1,31 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "afk", + description: "Tell someone you are AFK.", + usage: "{Status}", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let uuser = message.guild.members.cache.get(message.author.id); + const content = args.join(" ") || "No status provided."; + uuser.setNickname(`[AFK]${message.author.username}`); + await client.data.AFK(message.author.id, content); + const embed = new MessageEmbed() + .setDescription( + `${message.author.username} is set into AFK.\nStatus : ${content}` + ) + .setTimestamp() + .setFooter(`Made by Cath Team`) + .setColor(client.color) + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setURL(client.web); + message.channel.send(embed); + }, +}; diff --git a/commands/Utilities/avatar.js b/commands/Utilities/avatar.js new file mode 100644 index 0000000..d43c48a --- /dev/null +++ b/commands/Utilities/avatar.js @@ -0,0 +1,54 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "avatar", + description: "Show user's avatar in different formats", + aliases: ["av"], + usage: "{User}", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const member = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]) || + message.guild.members.cache.find( + r => + r.user.username.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.guild.members.cache.find( + r => r.displayName.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.member; + const embed = new MessageEmbed() + .setAuthor( + member.user.tag, + member.user.displayAvatarURL({ dynamic: true, size: 1024 }) + ) + .setColor(client.color) + .setTitle(`**Avatar**`) + .setDescription( + `\`Links:\` **[png](${member.user.displayAvatarURL({ + format: "png", + size: 1024, + })}) | [jpg](${member.user.displayAvatarURL({ + format: "jpg", + size: 1024, + })}) | [gif](${member.user.displayAvatarURL({ + format: "gif", + size: 1024, + dynamic: true, + })}) | [webp](${member.user.displayAvatarURL({ + format: "webp", + size: 1024, + })})**` + ) + .setImage(member.user.displayAvatarURL({ dynamic: true, size: 1024 })) + .setFooter("Made by Cath Team") + .setURL(client.web) + .setTimestamp(); + return message.inlineReply(embed); + }, +}; diff --git a/commands/Utilities/botinfo.js b/commands/Utilities/botinfo.js new file mode 100644 index 0000000..c2764eb --- /dev/null +++ b/commands/Utilities/botinfo.js @@ -0,0 +1,54 @@ +const { + Client, + Message, + MessageEmbed, + version: djsversion, +} = require("discord.js"); +const version = require("../../package.json").version; +const { utc } = require("moment"); +const os = require("os"); +const ms = require("ms"); +module.exports = { + name: "botinfo", + description: "Check the info of the bot", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const core = os.cpus()[0]; + const embed = new MessageEmbed() + .setURL(client.web) + .setThumbnail(client.user.displayAvatarURL()) + .setColor(message.guild.me.displayHexColor || client.color) + .addField("General", [ + `**❯ Client:** ${client.user.tag} (${client.user.id})`, + `**❯ Commands:** ${client.commands.size}`, + `**❯ Servers:** ${client.guilds.cache.size.toLocaleString()} `, + `**❯ Users:** ${client.guilds.cache + .reduce((a, b) => a + b.memberCount, 0) + .toLocaleString()}`, + `**❯ Channels:** ${client.channels.cache.size.toLocaleString()}`, + `**❯ Creation Date:** ${utc(client.user.createdTimestamp).format( + "Do MMMM YYYY HH:mm:ss" + )}`, + `**❯ Node.js:** ${process.version}`, + `**❯ Version:** v${version}`, + `**❯ Discord.js:** v${djsversion}`, + "\u200b", + ]) + .setColor(client.color) + .addField("System", [ + `**❯ Platform:** ${process.platform}`, + `**❯ Uptime:** ${ms(os.uptime() * 1000, { long: true })}`, + `**❯ CPU:**`, + `\u3000 Cores: ${os.cpus().length}`, + `\u3000 Model: ${core.model}`, + `\u3000 Speed: ${core.speed}MHz`, + ]) + .setTimestamp(); + message.inlineReply(embed); + }, +}; diff --git a/commands/Utilities/choose.js b/commands/Utilities/choose.js new file mode 100644 index 0000000..f7711bc --- /dev/null +++ b/commands/Utilities/choose.js @@ -0,0 +1,20 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +module.exports = { + name: "choose", + aliases: ["random", "8ball"], + description: "Choose random things", + usage: "(Choices)", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const split = args.join(" ").split(" "); + if (!split) return client.err(message, "Utilities", "choose", 0); + if (!split[1]) return client.err(message, "Utilities", "choose", 101); + let choices = split[Math.floor(Math.random() * split.length)]; + message.channel.send(`I will choose - \`${choices}\``); + }, +}; diff --git a/commands/Utilities/emoji.js b/commands/Utilities/emoji.js new file mode 100644 index 0000000..1b02cfe --- /dev/null +++ b/commands/Utilities/emoji.js @@ -0,0 +1,26 @@ +const { Client, Message, MessageEmbed, Util } = require("discord.js"); +module.exports = { + name: "emoji", + aliases: ["se", "stealemoji"], + usage: "(Emoji)", + description: "Show an emoji URL", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args.length) return client.err(message, "Utilities", "emoji", 11); + for (const rawEmoji of args) { + const parsedEmoji = Util.parseEmoji(rawEmoji); + if (parsedEmoji.id) { + const extension = parsedEmoji.animated ? ".gif" : ".png"; + const url = `https://cdn.discordapp.com/emojis/${ + parsedEmoji.id + extension + }`; + message.channel.send(`Emoji URL:\n${url}`); + } + } + }, +}; diff --git a/commands/Utilities/emojiadd.js b/commands/Utilities/emojiadd.js new file mode 100644 index 0000000..7e4cd76 --- /dev/null +++ b/commands/Utilities/emojiadd.js @@ -0,0 +1,58 @@ +const { Client, Message, MessageEmbed, Util } = require("discord.js"); +module.exports = { + name: "emojiadd", + usage: "(Link/Photo)", + aliases: ["addemoji"], + description: "Show an emoji URL or add the emoji to the server", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args.length) return client.err(message, "Utilities", "emojiadd", 0); + if (message.attachments) { + message.attachments.map(m => { + if ( + m.name.endsWith(".png") || + m.name.endsWith(".jpeg") || + m.name.endsWith(".jpeg") || + m.name.endsWith(".gif") || + m.name.endsWith(".webp") + ) { + try { + if (message.attachments.map(u => u.size) > 256000) + return client.err(message, "Utilities", "emojiadd", 19); + + if (args[0].length < 2 || args[0].match(/\W/)) + return client.err(message, "Utilities", "emojiadd", 49); + message.attachments.map(u => { + try { + message.guild.emojis.create(u.url, args[0]); + message.inlineReply(`Added :${args[0]}: to the server`); + } catch (e) { + console.log(e); + return client.err(message, "Utilities", "emojiadd", 999); + } + }); + } catch (e) { + console.log(e); + return client.err(message, "Utilities", "emojiadd", 999); + } + } else return client.err(message, "Utilities", "emojiadd", 48); + }); + } + if (args[0].includes("https")) { + try { + if (args[0].length < 2 || args[0].match(/\W/)) + return client.err(message, "Utilities", "emojiadd", 49); + message.guild.emojis.create(args[0], args[1]); + message.inlineReply(`Added :${args[1]}: to the server`); + } catch (e) { + console.log(e); + return client.err(message, "Utilities", "emojiadd", 999); + } + } else return client.err(message, "Utilities", "emojiadd", 101); + }, +}; diff --git a/commands/Utilities/esnipe.js b/commands/Utilities/esnipe.js new file mode 100644 index 0000000..14235e4 --- /dev/null +++ b/commands/Utilities/esnipe.js @@ -0,0 +1,162 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const moment = require("moment"); +module.exports = { + name: "editsnipe", + category: "Utilities", + aliases: ["esnipe"], + usage: "{Channel}", + description: "Snipe an edited message", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + let channel = + message.mentions.channels.first() || + message.guild.channels.cache.get(args[0]) || + message.channel, + snipes = client.esnipes.get(channel.id), + page = 0, + reactions = ["◀️", "⏪", "⏩", "▶️"]; + if (!snipes) + return message.reply( + `No snipes have been found for the channel \`${channel.name}\`` + ); + + let users = await Promise.all( + snipes.map(snipe => + client.users.fetch( + snipe.author === "No author found??" ? client.user.id : snipe.author + ) + ) + ); + if (args[0] === "--history") { + let embed = new MessageEmbed() + .addField("Channel:", `${channel} (${channel.name})`) + .addField( + "History", + `${ + snipes.length > 20 + ? `${snipes + .map( + (snipe, c) => + `${users[c].tag} | ${moment + .utc(snipe.date) + .fromNow()} | snipe **${c + 1}**` + ) + .slice(0, 20) + .join("\n")}\n ${snipes.length - 20} more...` + : `${snipes + .map( + (snipe, c) => + `${users[c].tag} | ${moment + .utc(snipe.date) + .fromNow()} | snipe **${c + 1}**` + ) + .slice(0, 20) + .join("\n")}` + }` + ); + let msg = await message.channel.send(embed); + + await Promise.all(reactions.map(r => msg.react(r))); + const backwardsFilter = (reaction, user) => + user.id === message.author.id && + reactions.includes(reaction.emoji.name); + const backwards = msg.createReactionCollector(backwardsFilter); + backwards.on("collect", r => { + switch (r.emoji.name) { + case "⏪": + page = 0; + break; + case "⏩": + page = snipes.length; + break; + case "◀️": + page === 1 + ? (page = 0) + : page === 0 + ? (page = snipes.length) + : page--; + break; + case "▶️": + page === snipes.length ? (page = 1) : page++; + break; + } + if (page === 0) { + let embed = new MessageEmbed() + .addField("Channel:", `${channel} (${channel.name})`) + .addField( + "History", + `${snipes.length + .map( + (snipe, c) => + `${users[c].tag} | ${moment + .utc(snipe.date) + .fromNow()} | snipe **${c + 1}**` + ) + .slice(0, 20) + .join("\n")}` + ); + msg.edit(embed); + } else { + let newembed = new MessageEmbed() + .setAuthor( + `${client.users.cache.get(snipes[page - 1].author).tag}`, + `${client.users.cache + .get(snipes[page - 1].author) + .displayAvatarURL({ format: "png", dynamic: true })}` + ) + .addField("Channel:", `${channel} (${channel.name})`) + .addField("When:", `${moment.utc(snipes[page - 1].date).fromNow()}`) + .addField( + "Content:", + snipes[page - 1].content || "No content could be found" + ) + .addField( + "New content:", + snipes[page - 1].newContent || "No new content could be found" + ) + .setFooter(`${page}/${snipes.length}`); + snipes[page - 1].image !== null + ? newembed.setImage(snipes[page - 1].image) + : ""; + msg.edit(newembed); + } + }); + } else { + let num = isNaN(args[0]) + ? 0 + : !args[0] + ? 0 + : args[0] < snipes.length && args[0] > 0 + ? args[0] + : 0; + let embed = new MessageEmbed() + .setAuthor( + `${ + client.users.cache.get(snipes[num].author) + ? client.users.cache.get(snipes[num].author).tag + : "no" + }`, + `${client.users.cache + .get(snipes[num].author) + .displayAvatarURL({ format: "png", dynamic: true })}` + ) + .addField("Channel:", `${channel} (${channel.name})`) + .addField("When:", `${moment.utc(snipes[num].date).fromNow()}`) + .addField( + "Content:", + snipes[num].content || "No content could be found" + ) + .addField( + "New content:", + snipes[num].newContent || "No new content could be found" + ) + .setFooter(`Showing snipe ${parseInt(num) + 1}`); + snipes[0].image !== null ? embed.setImage(snipes[num].image) : ""; + await message.channel.send(embed); + } + }, +}; diff --git a/commands/Utilities/help.js b/commands/Utilities/help.js new file mode 100644 index 0000000..3169865 --- /dev/null +++ b/commands/Utilities/help.js @@ -0,0 +1,317 @@ +const { MessageEmbed } = require("discord.js"); +const { readdirSync } = require("fs"); +const { ca } = require("../../config.json"); +const ms = require("ms"); +require("../../inlinereply"); + +module.exports = { + name: "help", + aliases: ["h"], + usage: "(Command/Category)", + description: "Shows all available bot commands", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const p = await client.prefix(message); + const emoji = { + CODM: "", + Config: "<:staff:829718501224480788>", + Economy: client.currency, + Fun: "", + Moderation: ":tools:", + Utilities: ":gear:", + Music: "", + Giveaway: "", + }; + if (!args[0]) { + let categories = []; + readdirSync("./commands/").forEach(dir => { + const category = ["Owner"]; + if (category.includes(dir)) return; + const edited = `${emoji[dir]} ${dir}`; + let data = new Object(); + data = { + name: edited, + value: `\`${p}help ${dir.toLowerCase()}\``, + inline: true, + }; + categories.push(data); + }); + const embed = new MessageEmbed() + .setTitle("**cath.exe commands**") + .addFields(categories) + .setDescription(`Links:${ca}`) + .setURL(client.web) + .setFooter( + `Requested by ${message.author.tag}`, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setTimestamp() + .setColor(client.color); + return message.channel.send(embed); + } else if (args[0] === "moderation") { + const commandList = []; + readdirSync(`./commands/Moderation`).forEach(file => { + const pull = require(`../../commands/Moderation/${file}`); + const name = `\`${pull.name}\``; + commandList.push(name); + }); + return message.inlineReply( + new MessageEmbed() + .setDescription(commandList.map(data => `${data}`).join(", ")) + .setTimestamp() + .setURL(client.web) + .setColor(client.color) + .setTitle(":tools:**Moderation Commands**:tools:") + ); + } else if (args[0] === "utilities") { + const commandList = []; + readdirSync(`./commands/Utilities`).forEach(file => { + const pull = require(`../../commands/Utilities/${file}`); + const name = `\`${pull.name}\``; + commandList.push(name); + }); + return message.inlineReply( + new MessageEmbed() + .setDescription(commandList.map(data => `${data}`).join(", ")) + .setTimestamp() + .setURL(client.web) + .setColor(client.color) + .setTitle(":gear:**Utiltiies Commands**:gear:") + ); + } else if (args[0] === "codm") { + const commandList = []; + readdirSync(`./commands/CODM`).forEach(file => { + const command = readdirSync(`./commands/CODM`); + const pull = require(`../../commands/CODM/${file}`); + const name = `\`${pull.name}\``; + commandList.push(name); + }); + return message.inlineReply( + new MessageEmbed() + .setDescription(commandList.map(data => `${data}`).join(", ")) + .setTimestamp() + .setURL(client.web) + .setColor(client.color) + .setTitle( + "**CODM Commands**" + ) + ); + } else if (args[0] === "config") { + const commandList = []; + readdirSync(`./commands/Config`).forEach(file => { + const pull = require(`../../commands/Config/${file}`); + const name = `\`${pull.name}\``; + commandList.push(name); + }); + return message.inlineReply( + new MessageEmbed() + .setDescription(commandList.map(data => `${data}`).join(", ")) + .setTimestamp() + .setURL(client.web) + .setColor(client.color) + .setTitle( + "<:staff:829718501224480788>**Config Commands**<:staff:829718501224480788>" + ) + ); + } else if (args[0] === "economy") { + const commandList = []; + readdirSync(`./commands/Economy`).forEach(file => { + const pull = require(`../../commands/Economy/${file}`); + const name = `\`${pull.name}\``; + commandList.push(name); + }); + return message.inlineReply( + new MessageEmbed() + .setDescription(commandList.map(data => `${data}`).join(", ")) + .setTimestamp() + .setURL(client.web) + .setColor(client.color) + .setTitle( + "**Economy Commands**" + ) + ); + } else if (args[0] === "fun") { + const commandList = []; + readdirSync(`./commands/Fun`).forEach(file => { + const pull = require(`../../commands/Fun/${file}`); + if (pull.hidden) return; + const name = `\`${pull.name}\``; + commandList.push(name); + }); + return message.inlineReply( + new MessageEmbed() + .setDescription(commandList.map(data => `${data}`).join(", ")) + .setTimestamp() + .setURL(client.web) + .setColor(client.color) + .setTitle( + "**Fun Commands**" + ) + ); + } else if (args[0] === "music") { + const commandList = []; + readdirSync(`./commands/Music`).forEach(file => { + const pull = require(`../../commands/Music/${file}`); + if (pull.hidden) return; + const name = `\`${pull.name}\``; + commandList.push(name); + }); + return message.inlineReply( + new MessageEmbed() + .setDescription(commandList.map(data => `${data}`).join(", ")) + .setTimestamp() + .setURL(client.web) + .setColor(client.color) + .setTitle( + "**Music Commands**" + ) + ); + } else if (args[0] === "giveaway") { + const commandList = []; + readdirSync(`./commands/Giveaway`).forEach(file => { + const pull = require(`../../commands/Giveaway/${file}`); + if (pull.hidden) return; + const name = `\`${pull.name}\``; + commandList.push(name); + }); + return message.inlineReply( + new MessageEmbed() + .setDescription(commandList.map(data => `${data}`).join(", ")) + .setTimestamp() + .setURL(client.web) + .setColor(client.color) + .setTitle( + "**Giveaway Commands**" + ) + ); + } else { + const command = + client.commands.get(args[0].toLowerCase()) || + client.commands.find( + c => c.aliases && c.aliases.includes(args[0].toLowerCase()) + ); + if (!command) { + message.channel.send( + `There isn't any command or category named "${args[0]}"` + ); + } else { + let BotPerm; + let UserPerm; + const UserPermissions = [command.UserPerm ? command.UserPerm : ""]; + const BotPermissions = [command.BotPerm ? command.BotPerm : ""]; + BotPermissions.forEach(perm => { + if (BotPermissions.includes(command.BotPerm)) + BotPerm = `${perm + .replace("CREATE_INSTANT_INVITE", "Create Invite") + .replace("KICK_MEMBERS", "Kick Members") + .replace("BAN_MEMBERS", "Ban Members") + .replace("ADMINISTRATOR", "Administrator") + .replace("MANAGE_CHANNELS", "Manage Channels") + .replace("MANAGE_GUILD", "Manage Guild") + .replace("ADD_REACTIONS", "Add Reactions") + .replace("VIEW_AUDIT_LOG", "View Audit Log") + .replace("PRIORITY_SPEAKER", "Priority Speaker") + .replace("STREAM", "Stream") + .replace("VIEW_CHANNEL", "View Channel") + .replace("SEND_MESSAGES", "Send Messages") + .replace("SEND_TTS_MESSAGES", "Send TTS Messages") + .replace("MANAGE_MESSAGES", "Manage Messages") + .replace("EMBED_LINKS", "Embed Links") + .replace("ATTACH_FILES", "Attach Files") + .replace("READ_MESSAGE_HISTORY", "Read Message History") + .replace("MENTION_EVERYONE", "Mention Everyone") + .replace("USE_EXTERNAL_EMOJIS", "Use External Emojis") + .replace("VIEW_GUILD_INSIGHTS", "View Guild Insights") + .replace("CONNECT", "Connect") + .replace("SPEAK", "Speak") + .replace("MUTE_MEMBERS", "Mute Members") + .replace("DEAFEN_MEMBERS", "Defean Members") + .replace("MOVE_MEMBERS", "Move Members") + .replace("USE_VAD", "Use VAD") + .replace("CHANGE_NICKNAME", "Change Nickname") + .replace("MANAGE_NICKNAMES", "Manage Nicknames") + .replace("MANAGE_ROLES", "Manage Roles") + .replace("MANAGE_WEBHOOKS", "Manage Webhooks") + .replace("MANAGE_EMOJIS", "Manage Emojis")}\n`; + }); + UserPermissions.forEach(perm => { + if (UserPermissions.includes(command.UserPerm)) + UserPerm = `${perm + .replace("CREATE_INSTANT_INVITE", "Create Invite") + .replace("KICK_MEMBERS", "Kick Members") + .replace("BAN_MEMBERS", "Ban Members") + .replace("ADMINISTRATOR", "Administrator") + .replace("MANAGE_CHANNELS", "Manage Channels") + .replace("MANAGE_GUILD", "Manage Guild") + .replace("ADD_REACTIONS", "Add Reactions") + .replace("VIEW_AUDIT_LOG", "View Audit Log") + .replace("PRIORITY_SPEAKER", "Priority Speaker") + .replace("STREAM", "Stream") + .replace("VIEW_CHANNEL", "View Channel") + .replace("SEND_MESSAGES", "Send Messages") + .replace("SEND_TTS_MESSAGES", "Send TTS Messages") + .replace("MANAGE_MESSAGES", "Manage Messages") + .replace("EMBED_LINKS", "Embed Links") + .replace("ATTACH_FILES", "Attach Files") + .replace("READ_MESSAGE_HISTORY", "Read Message History") + .replace("MENTION_EVERYONE", "Mention Everyone") + .replace("USE_EXTERNAL_EMOJIS", "Use External Emojis") + .replace("VIEW_GUILD_INSIGHTS", "View Guild Insights") + .replace("CONNECT", "Connect") + .replace("SPEAK", "Speak") + .replace("MUTE_MEMBERS", "Mute Members") + .replace("DEAFEN_MEMBERS", "Defean Members") + .replace("MOVE_MEMBERS", "Move Members") + .replace("USE_VAD", "Use VAD") + .replace("CHANGE_NICKNAME", "Change Nickname") + .replace("MANAGE_NICKNAMES", "Manage Nicknames") + .replace("MANAGE_ROLES", "Manage Roles") + .replace("MANAGE_WEBHOOKS", "Manage Webhooks") + .replace("MANAGE_EMOJIS", "Manage Emojis")}\n`; + }); + const embed = new MessageEmbed() + .setTitle(`"${command.name}" command details`) + .addField( + "**Command**:", + command.name ? `\`${command.name}\`` : "N/A" + ) + .addField( + "**Aliases**:", + command.aliases ? `\`${command.aliases.join(", ")}\`` : "N/A" + ) + .addField( + "**Usage**:", + command.usage + ? `\`${p}${command.name} ${command.usage}\`` + : `\`${p}${command.name}\`` + ) + .addField( + "**Description**:", + command.description ? command.description : "N/A" + ) + .addField( + "**Cooldown**:", + command.timeout ? ms(command.timeout, { long: true }) : "N/A" + ) + .addField( + "**Required User Permission**:", + UserPerm ? UserPerm : "N/A" + ) + .addField("**Required Bot Permission**:", BotPerm ? BotPerm : "N/A") + .setFooter( + `Requested by ${message.author.tag}`, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setTimestamp() + .setURL(client.web) + .setColor(client.color); + message.inlineReply(embed); + } + } + }, +}; diff --git a/commands/Utilities/hexcolor.js b/commands/Utilities/hexcolor.js new file mode 100644 index 0000000..6abd6d9 --- /dev/null +++ b/commands/Utilities/hexcolor.js @@ -0,0 +1,84 @@ +const Canvas = require("canvas"); +const { + Client, + Message, + MessageEmbed, + MessageAttachment, +} = require("discord.js"); +const axios = require("axios"); + +module.exports = { + name: "hexcolor", + usage: "(Hex Color Code)", + description: "Get Hex and RGB info of a color", + aliases: ["hex"], + category: "Utilities", + run: async (client, message, args) => { + let color; + if (args[0]) { + if (/(#|0x)([0-9A-F]{6})/i.test(args[0])) { + color = args[0].match(/(#|0x)([0-9A-F]{6})/i)[2]; + } else { + return client.err(message, "Utilities", "hexcolor", 101); + } + } else { + color = message.member.displayHexColor; + } + try { + message.channel.startTyping(); + const aa = color.replace("#", "", "0x", ""); + const colour = await axios.get( + `https://www.thecolorapi.com/scheme?hex=${aa}` + ); + const canvas = Canvas.createCanvas(200, 200); + const ctx = canvas.getContext("2d"); + ctx.beginPath(); + ctx.rect(0, 0, 200, 200); + ctx.fillStyle = `${colour.data.seed.hex.value}`; + ctx.fill(); + const rightpic = new MessageAttachment(canvas.toBuffer(), "wea.jpg"); + const canvasx = Canvas.createCanvas(500, 100); + const ctxt = canvasx.getContext("2d"); + let y = canvasx.height / 2; + ctxt.font = "12px Roboto"; + ctxt.textAlign = "center"; + let addup = 0; + for (let i = 0; i < 5; i++) { + ctxt.beginPath(); + ctxt.rect(addup, 0, 100, 100); + ctxt.fillStyle = `${colour.data.colors[i].hex.value}`; + ctxt.fill(); + addup = addup + 100; + ctxt.beginPath(); + ctxt.rect(addup - 80, y - 15, 60, 30); + ctxt.fillStyle = `black`; + ctxt.fill(); + ctxt.fillStyle = `white`; + ctxt.fillText( + `${colour.data.colors[i].hex.value}`, + addup - 51, + y + 4.3 + ); + } + const attachment = new MessageAttachment(canvasx.toBuffer(), "color.jpg"); + const embed = new MessageEmbed() + .setColor(`0x${colour.data.seed.hex.value}`) + .setDescription( + `\`HEX: ${colour.data.seed.hex.value} RGB: ${colour.data.seed.rgb.value}\`\n🔽Color Scheme🔽` + ) + .setTitle("Color Information (Click here for more info)") + .setURL(`https://www.colorhexa.com/${colour.data.seed.hex.clean}`) + .attachFiles(attachment) + .setURL(client.web) + .setImage("attachment://color.jpg") + .attachFiles(rightpic) + .setThumbnail("attachment://wea.jpg"); + message.channel.send(embed); + } catch (e) { + console.log(e); + return client.err(message, "Utilities", "hexcolor", 999); + } finally { + message.channel.stopTyping(); + } + }, +}; diff --git a/commands/Utilities/invite.js b/commands/Utilities/invite.js new file mode 100644 index 0000000..ef2e901 --- /dev/null +++ b/commands/Utilities/invite.js @@ -0,0 +1,18 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); + +module.exports = { + name: "invite", + description: "Get bot invite link", + aliases: ["bot"], + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + message.inlineReply( + `https://discord.com/api/oauth2/authorize?client_id=${client.user.id}&permissions=4231314550&scope=bot%20applications.commands` + ); + }, +}; diff --git a/commands/Utilities/modmail.js b/commands/Utilities/modmail.js new file mode 100644 index 0000000..a806a9a --- /dev/null +++ b/commands/Utilities/modmail.js @@ -0,0 +1,138 @@ +const schema = require("../../models/modmail"); +const { MessageEmbed, MessageAttachment } = require("discord.js"); +const fs = require("fs"); +module.exports = { + name: "modmail", + BotPerm: "MANAGE_CHANNELS", + description: "Create a modmail thread with moderators in a server", + usage: "(Emoji) (Text)", + category: "Utilities", + run: async (client, message, args) => { + const data = await schema.findOne({ Guild: message.guild.id }); + if ( + !data || + !data.Role || + !data.Category || + !data.Choices || + !Object.entries(data.Choices).length || + !message.guild.roles.cache.has(data.Role) || + !message.guild.channels.cache.find( + value => value.type == "category" && value.id === data.Category + ) + ) + return message.channel.send( + `This server isn't setup properly. Please find an administrator or a moderator to specify a category, role and choices for users to create thread. The issue may be caused by invalid role/category.` + ); + const embed = new MessageEmbed(); + const choices = Object.entries(data.Choices); + embed.setDescription( + choices.map(value => `${value[1].emoji} - ${value[1].text}`).join("\n") + ); + try { + const msg = await message.author.send(embed); + choices.map(async value => { + await msg.react(value[1].emoji); + }); + const reactionCollector = await msg.createReactionCollector( + async (reaction, user) => + choices.map(value => value[1].emoji).includes(reaction.emoji.name) && + user.id == message.author.id, + { time: 30000 } + ); + let type; + reactionCollector.on("collect", async reaction => { + type = choices.find(value => value[1].emoji == reaction.emoji.name); + await msg.delete(); + reactionCollector.stop("done"); + }); + reactionCollector.on("end", async (collected, reason) => { + if (reason.toLowerCase() == "time") { + return ( + message.channel.send( + "You didn't provide a reaction in-time. Cancelled." + ), + message.author.send( + "You didn't provide a reaction in-time. Cancelled" + ) + ); + } else { + const channel = await message.guild.channels.create( + `${message.author.username}-${message.author.discriminator}`, + { + reason: "Modmail thread", + parent: data.Category, + topic: `${type[1].text}`, + type: "text", + } + ); + const transcript = []; + channel.createOverwrite(data.Role, { + VIEW_CHANNEL: true, + SEND_MESSAGES: true, + }); + channel.createOverwrite(message.guild.id, { + VIEW_CHANNEL: false, + }); + channel.send( + `A modmail thread has been started by ${message.author.tag} with type: ${type[1].text}\nUse \`close\` to close the thread.` + ); + message.author.send( + "Thread created. Use `close` to close the thread." + ); + const channelCollector = channel.createMessageCollector( + m => !m.author.bot + ); + const dmCollector = message.author.dmChannel.createMessageCollector( + m => !m.author.bot + ); + channelCollector.on("collect", async m => { + if (m.content.toLowerCase().startsWith("close")) { + message.author.send("Closing.."); + channel.send("Closing.."); + dmCollector.stop("done"); + channelCollector.stop("done"); + fs.writeFileSync( + `./transcript.${message.author.id}.txt`, + transcript.join("\n") + ); + const attachment = new MessageAttachment( + fs.createReadStream(`./transcript.${message.author.id}.txt`) + ); + await channel.send(attachment); + fs.unlinkSync(`./transcript.${message.author.id}.txt`); + setTimeout(() => { + channel.delete(); + }, 1000 * 10); + } + message.author.send(`**Admin**: ${m.content}`); + transcript.push(`**Admin**: ${m.content}`); + }); + dmCollector.on("collect", async m => { + if (m.content.toLowerCase().startsWith("close")) { + message.author.send("Closing.."); + channel.send("Closing.."); + dmCollector.stop("done"); + channelCollector.stop("done"); + fs.writeFileSync( + `./transcript.${message.author.id}.txt`, + transcript.join("\n") + ); + const attachment = new MessageAttachment( + fs.createReadStream(`./transcript.${message.author.id}.txt`) + ); + await channel.send(attachment); + fs.unlinkSync(`./transcript.${message.author.id}.txt`); + setTimeout(() => { + channel.delete(); + }, 1000 * 10); + } + channel.send(`**${message.author.tag}**: ${m.content}`); + transcript.push(`**${message.author.tag}**: ${m.content}`); + }); + } + }); + } catch { + return message.reply("please let me send DM to you."); + } + }, +}; diff --git a/commands/Utilities/permission.js b/commands/Utilities/permission.js new file mode 100644 index 0000000..202929c --- /dev/null +++ b/commands/Utilities/permission.js @@ -0,0 +1,110 @@ +const Discord = require("discord.js"); +module.exports = { + name: "permission", + aliases: ["perms", "permsfor"], + usage: "(User)", + description: "Show user's permission in server/channel", + category: "Utilities", + /** + * @param {Client}client + * @param {Message}message + * @param {String[]args} + */ + run: async (client, message, args) => { + const yes = "✔️"; + const no = "❌"; + const x = "```"; + const s = "📛"; + const c = "♨️"; + + const permissions = [ + "CREATE_INSTANT_INVITE", + "KICK_MEMBERS", + "BAN_MEMBERS", + "ADMINISTRATOR", + "MANAGE_CHANNELS", + "MANAGE_GUILD", + "ADD_REACTIONS", + "VIEW_AUDIT_LOG", + "PRIORITY_SPEAKER", + "STREAM", + "VIEW_CHANNEL", + "SEND_MESSAGES", + "SEND_TTS_MESSAGES", + "MANAGE_MESSAGES", + "EMBED_LINKS", + "ATTACH_FILES", + "READ_MESSAGE_HISTORY", + "MENTION_EVERYONE", + "USE_EXTERNAL_EMOJIS", + "VIEW_GUILD_INSIGHTS", + "CONNECT", + "SPEAK", + "MUTE_MEMBERS", + "DEAFEN_MEMBERS", + "MOVE_MEMBERS", + "USE_VAD", + "CHANGE_NICKNAME", + "MANAGE_NICKNAMES", + "MANAGE_ROLES", + "MANAGE_WEBHOOKS", + "MANAGE_EMOJIS", + ]; + + let user = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]) || + message.guild.members.cache.find( + r => + r.user.username.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.guild.members.cache.find( + r => r.displayName.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.member; + let userId = user.user.id; + let description = `Server - ${s}\nCurrent channel - ${c}\n\n${s} | ${c}\n`; + let embed = new Discord.MessageEmbed() + .setTitle(`${user.user.username} Permissions`) + .setColor(user.displayColor) + .setURL(client.web); + permissions.forEach(perm => { + description += `${user.permissions.has(perm) ? yes : no} | ${ + message.channel.permissionsFor(userId).has(perm) ? yes : no + } - ${perm + .replace("CREATE_INSTANT_INVITE", "Create Invite") + .replace("KICK_MEMBERS", "Kick Members") + .replace("BAN_MEMBERS", "Ban Members") + .replace("ADMINISTRATOR", "Administrator") + .replace("MANAGE_CHANNELS", "Manage Channels") + .replace("MANAGE_GUILD", "Manage Guild") + .replace("ADD_REACTIONS", "Add Reactions") + .replace("VIEW_AUDIT_LOG", "View Audit Log") + .replace("PRIORITY_SPEAKER", "Priority Speaker") + .replace("STREAM", "Stream") + .replace("VIEW_CHANNEL", "View Channel") + .replace("SEND_MESSAGES", "Send Messages") + .replace("SEND_TTS_MESSAGES", "Send TTS Messages") + .replace("MANAGE_MESSAGES", "Manage Messages") + .replace("EMBED_LINKS", "Embed Links") + .replace("ATTACH_FILES", "Attach Files") + .replace("READ_MESSAGE_HISTORY", "Read Message History") + .replace("MENTION_EVERYONE", "Mention Everyone") + .replace("USE_EXTERNAL_EMOJIS", "Use External Emojis") + .replace("VIEW_GUILD_INSIGHTS", "View Guild Insights") + .replace("CONNECT", "Connect") + .replace("SPEAK", "Speak") + .replace("MUTE_MEMBERS", "Mute Members") + .replace("DEAFEN_MEMBERS", "Defean Members") + .replace("MOVE_MEMBERS", "Move Members") + .replace("USE_VAD", "Use VAD") + .replace("CHANGE_NICKNAME", "Change Nickname") + .replace("MANAGE_NICKNAMES", "Manage Nicknames") + .replace("MANAGE_ROLES", "Manage Roles") + .replace("MANAGE_WEBHOOKS", "Manage Webhooks") + .replace("MANAGE_EMOJIS", "Manage Emojis")}\n`; + }); + embed.setDescription(x + description + x); + message.channel.send(embed); + }, +}; diff --git a/commands/Utilities/poll.js b/commands/Utilities/poll.js new file mode 100644 index 0000000..7c218f2 --- /dev/null +++ b/commands/Utilities/poll.js @@ -0,0 +1,80 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const { Suggestion } = require("../../config.json"); +module.exports = { + name: "poll", + description: "Join a poll for develop of this bot", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const questions = [ + "Which statistic of gun you want to see?", + //"question 2" + ]; + let collectCounter = 0; + let endCounter = 0; + const filter = m => m.author.id === message.author.id; + message.reply("check your dm."); + const appStart = await message.author.send( + new MessageEmbed() + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setDescription(questions[collectCounter++]) + .setFooter(client.user.username) + .setTimestamp() + ); + const channel = appStart.channel; + + const collector = channel.createMessageCollector(filter); + + collector.on("collect", () => { + if (collectCounter < questions.length) { + channel.send( + new MessageEmbed() + .setAuthor( + message.author.username, + message.author.displayAvatarURL() + ) + .setDescription(questions[collectCounter++]) + .setFooter(client.user.username) + .setTimestamp() + ); + } else { + channel.send( + new MessageEmbed() + .setTitle("SUCCESS!") + .setDescription("You have joined the poll.") + .setColor("GREEN") + ); + collector.stop("fulfilled"); + } + }); + + const appsChannel = client.channels.cache.get(Suggestion); + collector.on("end", (collected, reason) => { + if (reason === "fulfilled") { + let index = 1; + const mapedResponses = collected + .map(msg => { + return `${questions[endCounter++]}**\n->** ${msg.content}`; + }) + .join("\n\n"); + + appsChannel.send( + new MessageEmbed() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setTitle("New Apllication") + + .setDescription(mapedResponses) + .setColor("ORANGE") + .setTimestamp() + ); + } + }); + }, +}; diff --git a/commands/Utilities/report.js b/commands/Utilities/report.js new file mode 100644 index 0000000..145038a --- /dev/null +++ b/commands/Utilities/report.js @@ -0,0 +1,85 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +require("../../inlinereply"); + +module.exports = { + name: "report", + description: "Report a bug of the bot", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const questions = [ + "Describe the bug", + //"question 2" + ]; + + let collectCounter = 0; + let endCounter = 0; + + const filter = m => m.author.id === message.author.id; + message.inlineReply("Check your dm."); + const appStart = await message.author.send( + new MessageEmbed() + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setDescription(questions[collectCounter++]) + .setFooter(client.user.username) + .setTimestamp() + ); + const channel = appStart.channel; + + const collector = channel.createMessageCollector(filter); + + collector.on("collect", () => { + if (collectCounter < questions.length) { + channel.send( + new MessageEmbed() + .setAuthor( + message.author.username, + message.author.displayAvatarURL() + ) + .setDescription(questions[collectCounter++]) + .setFooter(client.user.username) + .setTimestamp() + ); + } else { + channel.send( + new MessageEmbed() + .setTitle("SUCCESS!") + .setDescription( + "You have reported the bug.\nPlease wait for Night to solve it" + ) + .setColor("GREEN") + ); + collector.stop("fulfilled"); + } + }); + + const appsChannel = client.channels.cache.get("808200253261611018"); + collector.on("end", (collected, reason) => { + if (reason === "fulfilled") { + let index = 1; + const mapedResponses = collected + .map(msg => { + return `${questions[endCounter++]}**\n->** ${msg.content}`; + }) + .join("\n\n"); + + appsChannel.send( + new MessageEmbed() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setTitle("New Apllication") + + .setDescription(mapedResponses) + .setColor("ORANGE") + .setTimestamp() + ); + } + }); + }, +}; diff --git a/commands/Utilities/roleinfo.js b/commands/Utilities/roleinfo.js new file mode 100644 index 0000000..7410ebf --- /dev/null +++ b/commands/Utilities/roleinfo.js @@ -0,0 +1,90 @@ +const moment = require("moment"); +const { MessageEmbed } = require("discord.js"); +module.exports = { + name: "roleinfo", + aliases: ["role"], + category: "Utilities", + run: async (client, message, args) => { + const role = + message.mentions.roles.first() || + message.guild.roles.cache.get(args[0]) || + message.guild.roles.cache.find(r => r.name == args[0]) || + message.member.roles.cache.highest; + const permissions = { + ADMINISTRATOR: "Administrator", + VIEW_AUDIT_LOG: "View Audit Log", + VIEW_GUILD_INSIGHTS: "View Server Insights", + MANAGE_GUILD: "Manage Server", + MANAGE_ROLES: "Manage Roles", + MANAGE_CHANNELS: "Manage Channels", + KICK_MEMBERS: "Kick Members", + BAN_MEMBERS: "Ban Members", + CREATE_INSTANT_INVITE: "Create Invite", + CHANGE_NICKNAME: "Change Nickname", + MANAGE_NICKNAMES: "Manage Nicknames", + MANAGE_EMOJIS: "Manage Emojis", + MANAGE_WEBHOOKS: "Manage Webhooks", + VIEW_CHANNEL: "Read Text Channels & See Voice Channels", + SEND_MESSAGES: "Send Messages", + SEND_TTS_MESSAGES: "Send TTS Messages", + MANAGE_MESSAGES: "Manage Messages", + EMBED_LINKS: "Embed Links", + ATTACH_FILES: "Attach Files", + READ_MESSAGE_HISTORY: "Read Message History", + MENTION_EVERYONE: "Mention @everyone, @here, and All Roles", + USE_EXTERNAL_EMOJIS: "Use External Emojis", + ADD_REACTIONS: "Add Reactions", + CONNECT: "Connect", + SPEAK: "Speak", + STREAM: "Video", + MUTE_MEMBERS: "Mute Members", + DEAFEN_MEMBERS: "Deafen Members", + MOVE_MEMBERS: "Move Members", + USE_VAD: "Use Voice Activity", + PRIORITY_SPEAKER: "Priority Speaker", + }; + const yesno = { + true: "`Yes", + false: "`No`", + }; + if (!role) return client.err(message, "Utilities", "roleinfo", 3); + const rolePermissions = role.permissions.toArray(); + const finalPermissions = []; + for (const permission in permissions) { + if (rolePermissions.includes(permission)) + finalPermissions.push(`✔️ ${permissions[permission]}`); + else finalPermissions.push(`❌ ${permissions[permission]}`); + } + + const position = `\`${message.guild.roles.cache.size - role.position}\`/\`${ + message.guild.roles.cache.size + }\``; + + const embed = new MessageEmbed() + .setURL(client.web) + .setColor(client.color) + .setTimestamp() + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setTitle(`Role Info`) + .addField("Name", role, true) + .addField("ID", `\`${role.id}\``, true) + .addField("Position", position, true) + .addField("Mentionable", yesno[role.mentionable], true) + .addField("Bot Role", yesno[role.managed], true) + .addField("Visible", yesno[role.hoist], true) + .addField("Color", `\`${role.hexColor.toUpperCase()}\``, true) + .addField( + "Creation Date", + `\`${moment(role.createdAt).format("DD/MMM/YYYY")}\``, + true + ) + .addField( + "Permissions", + `\`\`\`diff\n${finalPermissions.join("\n")}\`\`\`` + ); + message.inlineReply(embed); + }, +}; diff --git a/commands/Utilities/servericon.js b/commands/Utilities/servericon.js new file mode 100644 index 0000000..3106112 --- /dev/null +++ b/commands/Utilities/servericon.js @@ -0,0 +1,21 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); + +module.exports = { + name: "servericon", + description: "View the icon of the server", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const Embed = new MessageEmbed() + .setTitle(`Icon of ${message.guild.name}`) + .setURL(client.web) + .setTimestamp() + .setFooter(`Requested by ${message.authpr.tag}`) + .setImage(message.guild.iconURL({ dynamic: true, size: 2048 })); + message.inlineReply(Embed); + }, +}; diff --git a/commands/Utilities/serverinfo.js b/commands/Utilities/serverinfo.js new file mode 100644 index 0000000..59409a5 --- /dev/null +++ b/commands/Utilities/serverinfo.js @@ -0,0 +1,120 @@ +const { MessageEmbed } = require("discord.js"); +const moment = require("moment"); + +const filterLevels = { + DISABLED: "Off", + MEMBERS_WITHOUT_ROLES: "No Role", + ALL_MEMBERS: "Everyone", +}; + +const verificationLevels = { + NONE: "None", + LOW: "Low", + MEDIUM: "Medium", + HIGH: "High", + VERY_HIGH: "Very High", +}; + +const regions = { + brazil: "Brazil", + europe: "Europe", + hongkong: "Hong Kong", + india: "India", + japan: "Japan", + russia: "Russia", + singapore: "Singapore", + southafrica: "South Africa", + sydeny: "Sydeny", + "us-central": "US Central", + "us-east": "US East", + "us-west": "US West", + "us-south": "US South", +}; + +module.exports = { + name: "serverinfo", + description: "Check the info of the server", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const roles = message.guild.roles.cache + .sort((a, b) => b.position - a.position) + .map(role => role.toString()) + .slice(0, -1); + const members = message.guild.members.cache; + const channels = message.guild.channels.cache; + const emojis = message.guild.emojis.cache; + + const embed = new MessageEmbed() + .setDescription(`**Guild information for __${message.guild.name}__**`) + .setColor(client.color) + .setThumbnail(message.guild.iconURL({ dynamic: true })) + .addField("General", [ + `**❯ Name:** ${message.guild.name}`, + `**❯ ID:** ${message.guild.id}`, + `**❯ Owner:** ${message.guild.owner.user.tag} (${message.guild.ownerID})`, + `**❯ Region:** ${regions[message.guild.region]}`, + `**❯ Boost Tier:** ${ + message.guild.premiumTier + ? `Tier ${message.guild.premiumTier}` + : "None" + }`, + `**❯ Explicit Filter:** ${ + filterLevels[message.guild.explicitContentFilter] + }`, + `**❯ Verification Level:** ${ + verificationLevels[message.guild.verificationLevel] + }`, + `**❯ Time Created:** ${moment(message.guild.createdTimestamp).format( + "LT" + )} ${moment(message.guild.createdTimestamp).format("LL")} ${moment( + message.guild.createdTimestamp + ).fromNow()}`, + "\u200b", + ]) + .addField("Statistics", [ + `**❯ Role Count:** ${roles.length}`, + `**❯ Emoji Count:** ${emojis.size}`, + `**❯ Regular Emoji Count:** ${ + emojis.filter(emoji => !emoji.animated).size + }`, + `**❯ Animated Emoji Count:** ${ + emojis.filter(emoji => emoji.animated).size + }`, + `**❯ Member Count:** ${message.guild.memberCount}`, + `**❯ Humans:** ${members.filter(member => !member.user.bot).size}`, + `**❯ Bots:** ${members.filter(member => member.user.bot).size}`, + `**❯ Text Channels:** ${ + channels.filter(channel => channel.type === "text").size + }`, + `**❯ Voice Channels:** ${ + channels.filter(channel => channel.type === "voice").size + }`, + `**❯ Boost Count:** ${message.guild.premiumSubscriptionCount || "0"}`, + "\u200b", + ]) + .addField("Presence", [ + `**❯ Online:** ${ + members.filter(member => member.presence.status === "online").size + }`, + `**❯ Idle:** ${ + members.filter(member => member.presence.status === "idle").size + }`, + `**❯ Do Not Disturb:** ${ + members.filter(member => member.presence.status === "dnd").size + }`, + `**❯ Offline:** ${ + members.filter(member => member.presence.status === "offline").size + }`, + "\u200b", + ]) + .setURL(client.web) + //.addField(`Roles [${roles.length - 1}]`, roles.length < 10 ? roles.join(' **|** ') : roles.length > 10 ? roles.join(' **|** ') : 'None') + .setTimestamp(); + message.channel.send(embed); + }, +}; diff --git a/commands/Utilities/snipe.js b/commands/Utilities/snipe.js new file mode 100644 index 0000000..3ab20de --- /dev/null +++ b/commands/Utilities/snipe.js @@ -0,0 +1,79 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const moment = require("moment"); +module.exports = { + name: "snipe", + description: "Snipes a deleted message.", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + var i = 0; + var description = ""; + const embed = new MessageEmbed() + .setAuthor( + `Sniped by ${message.author.tag}`, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setColor(client.color) + .setFooter("Made by Cath Team") + .setURL(client.web); + client.snipes.reverse().forEach(msg => { + if (msg.channel.id != message.channel.id) return; + if (i >= 5) return; + if (msg.attachment) { + if (msg.attachment.length == 1) { + console.log("one"); + description = + description + + `\n\n**Author:** ${msg.author.username}#${ + msg.author.discriminator + } (Deleted ${moment(msg.date).fromNow()})\n**ID:** ${ + msg.author.id + }\n**Content:** ${ + msg.content + }\n**Attachment URL:** [Click to view](${msg.attachment})`; + i++; + } else if (msg.attachment.length > 1) { + const map = msg.attachment.map( + (s, i) => `**${i + 1}:** [Click to view](${s})` + ); + description = + description + + `\n\n**Author:** ${msg.author.username}#${ + msg.author.discriminator + } (Deleted ${moment(msg.date).fromNow()})\n**ID:** ${ + msg.author.id + }\n**Content:** ${msg.content}\n**Attachment URLs:** \n${map.join( + "\n" + )}`; + i++; + } else { + description = + description + + `\n\n**Author:** ${msg.author.username}#${ + msg.author.discriminator + } (Deleted ${moment(msg.date).fromNow()})\n**ID:** ${ + msg.author.id + }\n**Content:** ${msg.content}`; + i++; + } + } else { + description = + description + + `\n\n**Author:** ${msg.author.username}#${ + msg.author.discriminator + } (Deleted ${moment(msg.date).fromNow()})\n**ID:** ${ + msg.author.id + }\n**Content:** ${msg.content}`; + i++; + } + }); + if (i == 0) return client.err(message, "Utilities", "snipe", 10); + embed.setDescription(description); + embed.setTimestamp(); + return message.inlineReply(embed); + }, +}; diff --git a/commands/Utilities/support.js b/commands/Utilities/support.js new file mode 100644 index 0000000..d843906 --- /dev/null +++ b/commands/Utilities/support.js @@ -0,0 +1,16 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); + +module.exports = { + name: "support", + description: "Get support server invite link", + aliases: ["server"], + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + message.inlineReply(`https://discord.gg/SbQHChmGcp`); + }, +}; diff --git a/commands/Utilities/timer.js b/commands/Utilities/timer.js new file mode 100644 index 0000000..a198555 --- /dev/null +++ b/commands/Utilities/timer.js @@ -0,0 +1,66 @@ +const ms = require("ms"); +const { MessageEmbed } = require("discord.js"); +module.exports = { + name: "timer", + description: "Set a timer for yourself", + usage: "(Time)", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + if (!args[0]) { + return client.err(message, "Utilities", "timer", 19); + } + if (!args[0].endsWith("d")) { + if (!args[0].endsWith("h")) { + if (!args[0].endsWith("m")) { + if (!args[0].endsWith("s")) { + return client.err(message, "Utilities", "timer", 101); + } + } + } + } + if (isNaN(args[0][0])) { + return client.err(message, "Utilities", "timer", 101); + } + client.Timers.set(message.author.id + " G " + message.guild.name, { + Guild: message.guild.name, + Author: { + Tag: message.author.tag, + ID: message.author.id, + }, + Time: ms(args[0]), + }); + message.channel.send( + `${message.author} you have set a timer for ${ms(ms(args[0]), { + long: true, + })}.` + ); + setTimeout(() => { + let Embed = new MessageEmbed() + .setTitle(`Timer finished in ${message.guild.name}.`) + .setDescription( + `Your timer for ${ms(ms(args[0]), { + long: true, + })} has finished.` + ) + .setURL(client.web) + .setColor(`GREEN`); + let embe = new MessageEmbed() + .setTitle(`Timer finished.`) + .setDescription( + `Your timer for ${ms(ms(args[0]), { + long: true, + })} has finished.` + ) + .setURL(client.web) + .setColor(`GREEN`); + message.channel.send(`${message.author}`, embe); + message.author.send(Embed); + client.Timers.delete(message.author.id + " G " + message.guild.name); + }, ms(args[0])); + }, +}; diff --git a/commands/Utilities/userinfo.js b/commands/Utilities/userinfo.js new file mode 100644 index 0000000..ef003c3 --- /dev/null +++ b/commands/Utilities/userinfo.js @@ -0,0 +1,123 @@ +const { MessageEmbed } = require("discord.js"); +const moment = require("moment"); +module.exports = { + name: "userinfo", + aliases: ["whois"], + description: "Check the info of a user", + usage: "{User}", + category: "Utilities", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async (client, message, args) => { + const member = + message.mentions.members.first() || + message.guild.members.cache.get(args[0]) || + message.guild.members.cache.find( + r => + r.user.username.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.guild.members.cache.find( + r => r.displayName.toLowerCase() === args.join(" ").toLocaleLowerCase() + ) || + message.member; + const flags = { + DISCORD_EMPLOYEE: "Discord Staff<:staff:829718501224480788>", + DISCORD_PARTNER: "Partnered Server Owner<:partner:829718449436622858>", + BUGHUNTER_LEVEL_1: "Discord Bug Hunter<:bughunter:829718598343196672>", + BUGHUNTER_LEVEL_2: "Discord Bug Hunter<:bughunterlv2:829718545298358313>", + HYPESQUAD_EVENTS: "HypeSquad Events<:HypeSquad:829718113913405440>", + HOUSE_BRAVERY: "HypeSquad Bravery<:bravery:829718178527182869>", + HOUSE_BRILLIANCE: "HypeSquad Brilliance<:brilliance:829718391727456311>", + HOUSE_BALANCE: "HypeSquad Balance<:balance:829718333204856854>", + EARLY_SUPPORTER: "Early Supporter<:earlysupporter:829717947052195880>", + TEAM_USER: "Team User", + SYSTEM: "System", + VERIFIED_BOT: "Verified Bot<:VerifiedBot:822497433933709343>", + VERIFIED_DEVELOPER: + "Early Verified Bot Developer<:discord_bot_dev:829717061802131466>", + }; + let status; + switch (member.user.presence.status) { + case "online": + status = "<:online:829714260199997482>Online"; + break; + case "dnd": + status = "<:do_not_disturb:829714335952535632>Do Not Disturb"; + break; + case "idle": + status = "<:idle:829714296211505182>Idle"; + break; + case "offline": + status = "<:offline:829714364511682582>Offline"; + break; + } + let x = Date.now() - member.user.createdAt; + let y = Date.now() - message.guild.members.cache.get(member.id).joinedAt; + let created = Math.floor(x / 86400000); + let joined = Math.floor(y / 86400000); + const members = message.guild.member(member); + let nickname = + members.nickname !== undefined && members.nickname !== null + ? members.nickname + : "None"; + const roles = member.roles.cache + .sort((a, b) => b.position - a.position) + .map(role => role.toString()) + .slice(0, -1); + const userFlags = member.user.flags.toArray(); + let createdate = moment + .utc(member.user.createdAt) + .format("dddd, MMMM Do YYYY, HH:mm:ss"); + let joindate = moment + .utc(member.joinedAt) + .format("dddd, MMMM Do YYYY, HH:mm:ss"); + + const infoembed = new MessageEmbed() + .setAuthor( + member.user.tag, + member.user.displayAvatarURL({ dynamic: true, size: 2048 }) + ) + .setTimestamp() + .setColor(client.color) + .setThumbnail(member.user.displayAvatarURL({ dynamic: true, size: 512 })) + .setColor(member.displayHexColor || "BLUE") + .addField("User", [ + `**❯ Username:** ${member.user.username}`, + `**❯ Discriminator:** ${member.user.discriminator}`, + `**❯ Nickname:** ${nickname}`, + `**❯ ID:** ${member.id}`, + `**❯ Flags:** ${ + userFlags.length + ? userFlags.map(flag => flags[flag]).join(" **|** ") + : "None" + }`, + `**❯ Avatar:** [Link to avatar](${member.user.displayAvatarURL({ + dynamic: true, + size: 2048, + })})`, + `**❯ Time Created:** ${createdate} \nsince ${created} day(s) ago`, + `**❯ Status:** ${status}`, + `**❯ Game:** ${ + member.presence.activities[0] + ? member.presence.activities[0].name + : "None" + }`, + `\u200b`, + ]) + .addField("Member", [ + `**❯ Highest Role:** ${ + member.roles.highest.id === message.guild.id + ? "None" + : member.roles.highest.name + }`, + `**❯ Server Join Date:** ${joindate} \nsince ${joined} day(s) ago`, + //`**❯ Roles [${roles.length}]:** ${roles.length < 10 ? roles.join(" **|** ") : roles.length > 10 ? roles.join(" **|** ") : "None"}`, + + `\u200b`, + ]); + message.inlineReply(infoembed); + }, +}; diff --git a/config.json b/config.json new file mode 100644 index 0000000..7f3e9b2 --- /dev/null +++ b/config.json @@ -0,0 +1,12 @@ +{ + "prefix": "C.", + "mongo": "mongodb://127.0.0.1:27017", + "URL": "https://cath.gq/", + "color": "02023a", + "soundcloud": "dmDh7QSlmGpzH9qQoH1YExYCGcyYeYYC", + "ca": "**[Invite](https://discord.com/api/oauth2/authorize?client_id=800966959268364288&permissions=4231314550&scope=bot%20applications.commands) | [Support](https://discord.gg/SbQHChmGcp) | [YouTube](https://youtube.com/Kirito01) | [Website](https://www.cath.gq)**", + "cat": "**[Invite](https://discord.com/api/oauth2/authorize?client_id=800966959268364288&permissions=4231314550&scope=bot%20applications.commands) | [Support](https://discord.gg/SbQHChmGcp) | [YouTube](https://youtube.com/Kirito01) | [Website](https://www.cath.gq)**\n\n", + "Suggestion": "837870173376741387", + "Report": "837870173376741387", + "Welcome": "837913442228371456" +} diff --git a/events/afk.js b/events/afk.js new file mode 100644 index 0000000..80b9e70 --- /dev/null +++ b/events/afk.js @@ -0,0 +1,39 @@ +const client = require("../index"); +const moment = require("moment"); +require("../inlinereply"); +client.on("message", async (message) => { + if (message.author.bot) return; + if (!message.guild) return; + const dataa = await client.data.getUser(message.author.id); + if (dataa) { + if (dataa.AFK != null) { + message.inlineReply( + `Welcome back <@${dataa.User}>! I have removed your AFK status.` + ); + const nothahaa = message.guild.members.cache.get(message.author.id); + nothahaa.setNickname(`${message.author.username}`); + await client.data.DelAFK(message.author.id); + } else return; + } else { + return; + } + if (message.mentions.members.first()) { + const data1 = await client.data.getUser( + message.mentions.members.first().id + ); + if (data1) { + if (data1.AFK !== null) { + message.inlineReply( + message.mentions.members.first().user.tag + + ` is in afk (${data1.AFK})` + ); + } else { + return; + } + } else { + return; + } + } else { + return; + } +}); diff --git a/events/emoji.js b/events/emoji.js new file mode 100644 index 0000000..9782d2d --- /dev/null +++ b/events/emoji.js @@ -0,0 +1,56 @@ +const client = require("../index"); +client.on("message", async message => { + function Check(str) { + if ( + client.emojis.cache.find(emoji => emoji.name === str) || + message.guild.emojis.cache.find(emoji => emoji.name === str) + ) { + return true; + } else { + return false; + } + } + if (message.content.startsWith(":") && message.content.endsWith(":")) { + let EmojiName = message.content.slice(1, -1); + + if (Check(EmojiName) === true) { + console.log("cmeoji"); + const channel = client.channels.cache.get(message.channel.id); + try { + if (message.author.bot) return; + let webhooks = await channel.fetchWebhooks(); + let webhook = webhooks.first(); + if (webhook === undefined || null || !webhook) { + channel + .createWebhook(client.user.username, { + avatar: client.user.displayAvatarURL(), + }) + .then(async webhook => { + const emoji = + client.emojis.cache.find(e => e.name == EmojiName).id || + message.guild.emojis.cache.find(e => e.name === EmojiName).id; + + await webhook.send(`${client.emojis.cache.get(emoji)}`, { + username: message.member.displayName + ? message.member.displayName + : message.author.username, + avatarURL: message.author.displayAvatarURL({ dynamic: true }), + }); + message.delete(); + }); + } + const emoji = + client.emojis.cache.find(e => e.name == EmojiName).id || + message.guild.emojis.cache.find(e => e.name === EmojiName).id; + + await webhook.send(`${client.emojis.cache.get(emoji)}`, { + username: message.author.username, + avatarURL: message.author.displayAvatarURL({ dynamic: true }), + }); + message.delete(); + } catch (error) { + console.log(`Error :\n${error}`); + } + } else return; + } else return; +}); diff --git a/events/goodBye.js b/events/goodBye.js new file mode 100644 index 0000000..6cc151e --- /dev/null +++ b/events/goodBye.js @@ -0,0 +1,68 @@ +const { MessageAttachment } = require("discord.js"); +const client = require("../index"); +const schema = require("../models/guilds"); +const canvas = require("discord-canvas"); + +client.on("guildMemberAdd", async member => { + schema.findOne({ Guild: member.guild.id }, async (e, data) => { + if (!data) return; + const user = member.user; + const image = await new canvas.Welcome() + .setUsername(user.username) + .setDiscriminator(user.discriminator) + .setMemberCount(member.guild.memberCount) + .setGuildName(member.guild.name) + .setAvatar(user.displayAvatarURL({ dynamic: false, format: "png" })) + .setColor("border", client.color) + .setColor("username-box", client.color) + .setColor("discriminator-box", client.color) + .setColor("message-box", client.color) + .setColor("title", "#89FB23") + .setColor("avatar", client.color) + .setBackground( + "https://cdn.discordapp.com/attachments/815622126526005268/819116213925052436/image0.png" + ) + .toAttachment(); + + const attachment = new MessageAttachment( + image.toBuffer(), + "goodbye-image.png" + ); + + const channel = member.guild.channels.cache.get(data.WelcomeChannel); + if (!channel) return; + channel.send(attachment); + }); +}); + +client.on("guildMemberRemove", async member => { + schema.findOne({ Guild: member.guild.id }, async (e, data) => { + if (!data) return; + const user = member.user; + const image = await new canvas.Goodbye() + .setUsername(user.username) + .setDiscriminator(user.discriminator) + .setMemberCount(member.guild.memberCount) + .setGuildName(member.guild.name) + .setAvatar(user.displayAvatarURL({ dynamic: false, format: "png" })) + .setColor("border", client.color) + .setColor("username-box", client.color) + .setColor("discriminator-box", client.color) + .setColor("message-box", client.color) + .setColor("title", "#89FB23") + .setColor("avatar", client.color) + .setBackground( + "https://cdn.discordapp.com/attachments/815622126526005268/819116213925052436/image0.png" + ) + .toAttachment(); + + const attachment = new MessageAttachment( + image.toBuffer(), + "goodbye-image.png" + ); + + const channel = member.guild.channels.cache.get(data.GoodbyeChannel); + if (!channel) return; + channel.send(attachment); + }); +}); diff --git a/events/guild.js b/events/guild.js new file mode 100644 index 0000000..b03096a --- /dev/null +++ b/events/guild.js @@ -0,0 +1,46 @@ +const client = require("../index"); +const { MessageEmbed } = require("discord.js"); +const { Welcome } = require("../config.json"); +client.on("guildMemberAdd", async member => { + const channel = member.guild.channels.cache.find( + channel => channel.id === Welcome + ); + if (!channel) return; + const embed = new MessageEmbed() + .setTitle( + `<:YouTube:841186450497339412> ${member},welcome to Night\'s official Discord server! <:YouTube:841186450497339412>` + ) + .setThumbnail(member.guild.iconURL({ dynamic: true })) + .addField( + "Read the rules at <#799074874513555496> channel, and enjoy your stay~", + `We now have ${member.guild.memberCount} members!` + ) + .setFooter( + `${member.user.tag} joined the server!`, + member.user.displayAvatarURL({ dynamic: true }) + ) + .setColor(client.color) + .setTimestamp(); + + channel.send(embed); +}); +client.on("guildMemberRemove", async member => { + const channel = member.guild.channels.cache.find( + channel => channel.id === Welcome + ); + if (!channel) return; + const embed = new MessageEmbed() + .setTitle( + `<:YouTube:841186450497339412> ${member} can\'t handle being cool! <:YouTube:841186450497339412>` + ) + .setThumbnail(member.guild.iconURL({ dynamic: true })) + .setDescription(`We now only have ${member.guild.memberCount} members`) + .setFooter( + `${member.user.tag} leaved the server!`, + member.user.displayAvatarURL({ dynamic: true }) + ) + .setColor(client.color) + .setTimestamp(); + + channel.send(embed); +}); diff --git a/events/guildCreate.js b/events/guildCreate.js new file mode 100644 index 0000000..75ad937 --- /dev/null +++ b/events/guildCreate.js @@ -0,0 +1,30 @@ +const client = require("../index"); +const { MessageEmbed } = require("discord.js"); +const db = require("../models/guilds"); +const config = require("../config.json"); +client.on("guildCreate", guild => { + client.ServerLog.send( + new MessageEmbed() + .setTitle("New Server") + .addField("Server Info", [ + `**>Server Name**: \n${guild.name}`, + `**>Server ID**: \n${guild.id}`, + `**>Server Member Count**: \n${guild.memberCount}`, + ]) + .addField("Owner Info", [ + `**>Owner Tag**: \n${guild.owner.user.tag}`, + `**>Owner ID**: \n${guild.owner.id}`, + ]) + .setFooter( + `${client.user.username} Currently in ${client.guilds.cache.size} servers` + ) + .setTimestamp() + .setThumbnail(guild.iconURL({ dynamic: true })) + .setColor("GREEN") + ); + const newdb = new db({ + Guild: guild.id, + Prefix: config.prefix, + }); + newdb.save(); +}); diff --git a/events/guildDelete.js b/events/guildDelete.js new file mode 100644 index 0000000..612b3cb --- /dev/null +++ b/events/guildDelete.js @@ -0,0 +1,42 @@ +const client = require("../index"); +const db = require("../models/guilds"); +const { prefix, Log } = require("../config.json"); +const { MessageEmbed } = require("discord.js"); + +client.on("guildDelete", async guild => { + client.data.DelGuild(guild.id).then(() => console.log("Deleted Data")); + client.ServerLog.send( + new MessageEmbed() + .setTitle("Deleted from server") + .addField("Server Info", [ + `**>**Server Name: ${guild.name}`, + `**>**Server ID: ${guild.id}`, + `**>**Server Member Count: ${guild.memberCount}`, + ]) + .addField("Owner Info", [ + `Owner Tag: ${guild.owner.user.tag}`, + `Owner ID: ${guild.owner.id}`, + ]) + .setFooter(`Currently in ${client.guilds.cache.size} servers`) + .setTimestamp() + .setThumbnail(guild.iconURL({ dynamic: true })) + .setColor("RED") + ); +}); + +/** + * @param {Client} client + */ +client.prefix = async function (message) { + let custom; + if (!message.guild) return; + const data = await db + .findOne({ Guild: message.guild.id }) + .catch(err => console.log(err)); + if (data) { + custom = data.Prefix; + } else { + custom = prefix; + } + return custom; +}; diff --git a/events/level.js b/events/level.js new file mode 100644 index 0000000..fee599d --- /dev/null +++ b/events/level.js @@ -0,0 +1,27 @@ +const Levels = require("discord-xp"); +const client = require("../index"); +const users = require("../models/users"); +Levels.setURL(require("../config.json").mongo); +client.on("message", async message => { + if (!message.guild) return; + if (message.author.bot) return; + const user = await client.data.getUser(message.author.id); + var max = 30; + if (user) { + if (user.Tier) { + if (user.Tier == 1) max = 120; + if (user.Tier == 2) max = 90; + if (user.Tier == 3) max = 60; + } + } + const randomAmountOfXp = client.function.rndint(10, max); + if (client.xp.includes(message.guild.id)) return; + const hasLeveledUp = await Levels.appendXp( + message.author.id, + message.guild.id, + randomAmountOfXp + ); + if (hasLeveledUp) { + const user = await Levels.fetch(message.author.id, message.guild.id); + } +}); diff --git a/events/message.js b/events/message.js new file mode 100644 index 0000000..1d40ca0 --- /dev/null +++ b/events/message.js @@ -0,0 +1,265 @@ +const client = require("../index"); +const leven = require("leven"); +const { Collection, MessageEmbed } = require("discord.js"); +const { prefix } = require("../config.json"); +const guilds = require("../models/guilds"); +const ms = require("ms"); +const schema = require("../models/custom-commands"); +const Timeout = new Collection(); +const Timeout2 = new Collection(); +client.on("message", async message => { + const p = await client.prefix(message); + if (message.author.bot) return; + if (message.content.match(new RegExp(`^<@!?${client.user.id}>( |)$`))) { + const _ = new MessageEmbed() + .setTitle("cath.exe") + .addField("Links:", client.cat) + .addField( + "Prefix/Usage", + `My prefix in **${message.guild.name}** is **${p}**\n\nRun \`${p}help\` to start using the bot` + ) + + .setThumbnail(client.user.displayAvatarURL()) + .setURL(client.web) + .setFooter("Made by Cath Team") + .setTimestamp() + .setColor(client.color); + return message.inlineReply(_).then(m => m.delete({ timeout: 10000 })); + } + if (!message.content.startsWith(p)) return; + if (!message.guild) return; + if (!message.member) { + message.member = await message.guild.fetchMember(message); + } + + let guildDB = await client.data.getGuild(message.guild.id); + if (!guildDB) return; + let userDB = await client.data.getUser(message.author.id); + if (!userDB) return; + const data = {}; + data.Guild = guildDB; + data.User = userDB; + if (!guildDB) { + client.data.CreateGuild(message.guild.id); + } + if (data.User) { + if (data.User.Blacklist) { + return; + } + } + guilds.findOne({ Guild: message.guild.id }, async (err, data) => { + if (data) { + if (!data.Prefix || data.Prefix === null) { + (data.Prefix = prefix), + await guilds.findOneAndUpdate({ Guild: message.guild.id }, data); + } + } + if (!data) { + new guilds({ + Guild: message.guild.id, + Prefix: prefix, + }).save(); + } + }); + const args = message.content.slice(p.length).trim().split(/ +/g); + const cmd = args.shift().toLowerCase(); + if (cmd.length == 0) return; + const cmddata = await schema.findOne({ + Guild: message.guild.id, + Command: cmd, + }); + if (!cmddata) { + let command = + client.commands.get(cmd) || client.commands.get(client.aliases.get(cmd)); + if (!command) { + const best = [ + ...client.commands.map(cmd => cmd.name), + ...client.aliases.keys(), + ].filter(c => leven(cmd.toLowerCase(), c.toLowerCase()) < c.length * 0.4); + const dym = + best.length == 0 + ? "" + : best.length == 1 + ? `Do you mean this?\n**${best[0]}**` + : `Do you mean one of these?\n${best + .slice(0, 3) + .map(value => `**${value}**`) + .join("\n")}`; + if (dym === "") return; + return message + .inlineReply( + new MessageEmbed() + .setDescription(`Couldn't find that command.\n${dym}`) + .setTimestamp() + .setColor(client.color) + ) + .then(msg => msg.delete({ timeout: 10000 })); + } + if (command) { + if (command.Premium == true) { + if (data.User.Premium == false) { + return message.inlineReply( + new MessageEmbed() + .setURL(client.web) + .setAuthor( + message.author.tag, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setColor(client.color) + .setDescription( + `You aren't a premium user. Please join [this](https://discord.gg/SbQHChmGcp) server and know more` + ) + .setTimestamp() + .setFooter(`Made by Cath Team`) + ); + } + } + if (!message.member.permissions.has(command.UserPerm)) return; + if (!message.guild.me.permissions.has(command.BotPerm)) + return message.inlineReply( + `You can't use this command. I need to have ${command.BotPerm} permission to use this command.` + ); + client.CMDLog.send( + `\`${message.author.tag}(${message.author.id})\`\n has used \n**${command.name}**\n command in \n\`${message.guild.name}(${message.guild.id})\`` + ); + const category = command.category; + if (data.Guild) { + if (data.Guild.Category) { + if (data.Guild.Category.includes(category)) return; + } + if (data.Guild.Commands) { + if (data.Guild.Commands.includes(command.name)) return; + } + } + const check = await guilds.findOne({ + Guild: message.guild.id, + }); + if (check) { + if (!check.Prefix) { + check.Prefix = prefix; + } else; + } + if (command.timeout) { + const slow = [ + "Keep it slow...", + "Calm down", + "Stop it get some help", + "Too fast", + ]; + const slowed = slow[Math.floor(Math.random() * slow.length)]; + if (Timeout.has(`${command.name}${message.author.id}`)) + return message.channel.send( + new MessageEmbed() + .setColor(client.color) + .setTimestamp() + .setTitle(slowed) + .setDescription( + `You are on a \`${ms( + Timeout.get(`${command.name}${message.author.id}`) - + Date.now(), + { long: true } + )}\` cooldown.` + ) + ); + command.run(client, message, args); + Timeout.set( + `${command.name}${message.author.id}`, + Date.now() + command.timeout + ); + setTimeout(() => { + Timeout.delete(`${command.name}${message.author.id}`); + }, command.timeout); + } else command.run(client, message, args); + } + } else { + if (cmddata.Delete === true && cmddata.Random === false) { + message.delete().then(() => message.channel.send(cmddata.Response)); + } else if (cmddata.Random === true && cmddata.Delete === true) { + const randomed = + cmddata.Response[Math.floor(Math.random() * cmddata.Response.length)]; + message.delete().then(() => message.channel.send(randomed)); + } else if (cmddata.Random === true && cmddata.Delete === false) { + const randomed = + cmddata.Response[Math.floor(Math.random() * cmddata.Response.length)]; + message.channel.send(randomed); + } else { + message.channel.send(cmddata.Response); + } + } +}); +client.on("message", async message => { + const p = await client.prefix(message); + if (message.author.bot) return; + if (!message.content.startsWith(p)) return; + if (!message.guild) return; + if (!message.member) { + message.member = await message.guild.fetchMember(message); + } + const args = message.content.slice(p.length).trim().split(/ +/g); + const cmd = args.shift().toLowerCase(); + if (cmd.length == 0) return; + let path = client.hide.get(cmd); + if (path) { + if (!client.path.includes(message.guild.id)) return; + client.CMDLog.send( + `\`${message.author.tag}(${message.author.id})\`\n has used \n**${path.name}**\n command in \n\`${message.guild.name}(${message.guild.id})\`` + ); + if (path.timeout) { + const slow = [ + "Keep it slow...", + "Calm down", + "Stop it get some help", + "Too fast", + ]; + const slowed = slow[Math.floor(Math.random() * slow.length)]; + if (Timeout2.has(`${path.name}${message.author.id}`)) + return message.channel.send( + new MessageEmbed() + .setColor(client.color) + .setTimestamp() + .setTitle(slowed) + .setDescription( + `You are on a \`${ms( + Timeout2.get(`${path.name}${message.author.id}`) - Date.now(), + { long: true } + )}\` cooldown.` + ) + ); + path.run(client, message, args); + Timeout2.set( + `${path.name}${message.author.id}`, + Date.now() + path.timeout + ); + setTimeout(() => { + Timeout2.delete(`${path.name}${message.author.id}`); + }, path.timeout); + } else path.run(client, message, args); + } +}); +client.on("message", async message => { + const p = await client.prefix(message); + if ( + message.channel.type === "dm" && + !message.content.startsWith(p) && + !message.author.bot + ) { + var attachment = message.attachments.array(); + client.DMLog.send( + `\`${message.author.tag}(${message.author.id})\`: ` + message.content + ); + if (attachment[0]) client.DMLog.send(attachment); + } +}); +/* +client.on("message", async (message) => { + if (message.author.bot) return; + let wordArray = message.content.split(" "); + let filterWords = ["bruh", "Bruh"]; + for (var i = 0; i < filterWords.length; i++) { + if (wordArray.includes(filterWords[i])) { + message.react(""); + break; + } + } +}); +*/ diff --git a/events/messageUpdate.js b/events/messageUpdate.js new file mode 100644 index 0000000..d6c868a --- /dev/null +++ b/events/messageUpdate.js @@ -0,0 +1,69 @@ +const client = require("../index"); +client.on("messageUpdate", (message, newMessage) => { + function getAllTextFromEmbed(embed) { + let text = ""; + function getTime(now) { + const date = new Date(now); + const escape = value => `0${value}`.slice(-2); + const ampm = date.getHours() >= 12 ? "PM" : "AM"; + + return `${date.getMonth()}/${date.getDate()}/${date.getFullYear()} at ${escape( + date.getHours() + )}:${escape(date.getMinutes())}:${escape(date.getSeconds())}${ampm}`; + } + + if (embed.title) + text += `**${embed.title + .replace(/(https?:\/\/)?discord\.gg\/(\w+)/g, "Invite") + .replace(/\[(.*)\]\((.*)\)/g, "Hyper link")}**`; + if (embed.description) + text += `\n${embed.description + .replace(/(https?:\/\/)?discord\.gg\/(\w+)/g, "Invite") + .replace(/\[(.*)\]\((.*)\)/g, "Hyper link")}`; + if (embed.fields) { + text += "\n"; + for (const field of embed.fields) + text += `\n**${field.name + .replace(/(https?:\/\/)?discord\.gg\/(\w+)/g, "Invite") + .replace(/\[(.*)\]\((.*)\)/g, "Hyper link")}**\n ${field.value + .replace(/(https?:\/\/)?discord\.gg\/(\w+)/g, "Invite") + .replace(/\[(.*)\]\((.*)\)/g, "Hyper link")}`; + } + if (embed.footer) { + let field = `\n\n**${embed.footer.text + .replace(/(https?:\/\/)?discord\.gg\/(\w+)/g, "Invite") + .replace(/\[(.*)\]\((.*)\)/g, "Hyper link")}`; + + if (embed.timestamp) { + const time = + embed.timestamp instanceof Date + ? getTime(embed.timestamp.getTime()) + : embed.timestamp; + field += `at ${time}`; + } + + text += `${field}**`; + } + + return text; + } + let snipes = client.esnipes.get(message.channel.id) || []; + snipes.unshift({ + content: + message.embeds.length > 0 + ? getAllTextFromEmbed(message.embeds[0]) + : message.content, + newContent: + newMessage.embeds.length > 0 + ? getAllTextFromEmbed(newMessage.embeds[0]) + : newMessage.content, + author: message.author ? message.author.id : "No author found??", + image: message.attachments.first() + ? message.attachments.first().proxyURL + : message.embeds.length > 0 && message.embeds[0].image + ? message.embeds[0].image.url + : "", + date: Date.now(), + }); + client.esnipes.set(message.channel.id, snipes); +}); diff --git a/events/messsageDelete.js b/events/messsageDelete.js new file mode 100644 index 0000000..7788616 --- /dev/null +++ b/events/messsageDelete.js @@ -0,0 +1,31 @@ +const client = require("../index.js"); +client.on("messageDelete", async message => { + let all = []; + if (message.attachments) { + const mapped = message.attachments.map(a => { + if ( + a.name.endsWith(".png") || + a.name.endsWith(".jpg") || + a.name.endsWith(".jpeg") || + a.name.endsWith(".gif") || + a.name.endsWith(".webp") + ) + return message.attachments.first().proxyURL; + else return message.attachments.first().url; + }); + if (mapped.length == 1) { + all.push(mapped); + } else if (mapped.length > 1) { + message.attachments.map(b => { + all.push(mapped); + }); + } + } + client.snipes.push({ + channel: message.channel, + content: message.content ? message.content : "None", + author: message.author, + attachment: all ? all : null, + date: new Date(), + }); +}); diff --git a/events/reactionroles.js b/events/reactionroles.js new file mode 100644 index 0000000..0577190 --- /dev/null +++ b/events/reactionroles.js @@ -0,0 +1,30 @@ +const client = require("../index"); +const Schema = require("../models/reaction"); + +client.on("messageReactionAdd", async (reaction, user) => { + if (reaction.message.partial) await reaction.message.fetch(); + if (reaction.partial) await reaction.fetch(); + if (user.bot) return; + if (!reaction.message.guild) return; + Schema.findOne({ Message: reaction.message.id }, async (err, data) => { + if (!data) return; + if (!Object.keys(data.Roles).includes(reaction.emoji.name)) return; + const [roleid] = data.Roles[reaction.emoji.name]; + reaction.message.guild.members.cache.get(user.id).roles.add(roleid); + user.send(`A role has been added`); + }); +}); +client.on("messageReactionRemove", async (reaction, user) => { + if (reaction.message.partial) await reaction.message.fetch(); + if (reaction.partial) await reaction.fetch(); + if (user.bot) return; + if (!reaction.message.guild) return; + Schema.findOne({ Message: reaction.message.id }, async (err, data) => { + if (!data) return; + if (!Object.keys(data.Roles).includes(reaction.emoji.name)) return; + + const [roleid] = data.Roles[reaction.emoji.name]; + reaction.message.guild.members.cache.get(user.id).roles.remove(roleid); + user.send(`A role has been removed`); + }); +}); diff --git a/events/ready.js b/events/ready.js new file mode 100644 index 0000000..76b1560 --- /dev/null +++ b/events/ready.js @@ -0,0 +1,31 @@ +const client = require("../index"); +const config = require("../config.json"); +const prefix = config.prefix; +const version = require("../package.json").version; +const { MessageEmbed } = require("discord.js"); +client.on("ready", () => { + var users = client.guilds.cache + .reduce((a, b) => a + b.memberCount, 0) + .toLocaleString(); + var playing = [ + `v${version} | ${prefix}help`, + client.web, + `with ${users} users`, + ]; + var interval = setInterval(function () { + var game = Math.floor(Math.random() * playing.length + 0); + client.user.setActivity({ + name: playing[game], + type: "STREAMING", + url: "https://www.twitch.tv/thekiritosgaming", + }); + }, 5000); + console.log(`${client.user.username} ✅\nVersion: v${version}`); + var embed = new MessageEmbed() + .setColor(client.color) + .setTitle(`${client.user.tag} is online`) + .setDescription(`${client.user.username} ✅\nVersion: v${version}`) + .setTimestamp() + .setFooter(`${client.user.username}`); + client.ReadyLog.send(embed); +}); diff --git a/events/slash.js b/events/slash.js new file mode 100644 index 0000000..17e1788 --- /dev/null +++ b/events/slash.js @@ -0,0 +1,35 @@ +const { Client, Message, MessageEmbed } = require("discord.js"); +const client = require("../index"); +async function createApiMessage(interaction, content) { + const apiMessage = await APIMessage.create( + client.channels.resolve(interaction.channel_id), + content + ) + .resolveData() + .resolveFiles(); + return { ...apiMessage.data, files: apiMessage.files }; +} +client.on("ready", async () => { + const a = client.api.applications(client.user.id); + a.commands.post({ + data: { + name: "help", + description: "Get some support!", + }, + }); +}); +client.ws.on("INTERACTION_CREATE", async (interaction) => { + let command = interaction.data.name.toLowerCase(); + let args = interaction.data.options; + if (command === "help") { + client.api.interactions(interaction.id, interaction.token).callback.post({ + data: { + type: 4, + data: { + content: + "Website: https://cath.gq/\n Support: https://discord.gg/SbQHChmGcp", + }, + }, + }); + } +}); diff --git a/index.js b/index.js new file mode 100644 index 0000000..98d3299 --- /dev/null +++ b/index.js @@ -0,0 +1,108 @@ +const { + Client, + Collection, + WebhookClient, + MessageEmbed, +} = require("discord.js"); +const { GiveawaysManager } = require("discord-giveaways"); +const fs = require("fs"); +const config = require("./config.json"); +require("dotenv").config(); +const client = new Client({ + disableEveryone: true, + disableMentions: "everyone", + restTimeOffset: 0, + partials: ["MESSAGE", "CHANNEL", "REACTION", "GUILD_MEMBER"], + intents: ["GUILDS", "GUILD_MESSAGES", "GUILD_MEMBERS", "GUILD_PRESENCES"], +}); +module.exports = client; +client.color = config.color; +client.author = "Cath Team"; +client.web = config.URL; +client.DMLog = new WebhookClient(process.env.DMLogID, process.env.DMLogToken); +client.CMDLog = new WebhookClient( + process.env.CMDLogID, + process.env.CMDLogToken +); +client.ReadyLog = new WebhookClient( + process.env.ReadyLogID, + process.env.ReadyLogToken +); +client.ServerLog = new WebhookClient( + process.env.ServerLogID, + process.env.ServerLogToken +); +client.ErrorLog = new WebhookClient( + process.env.ErrorLogID, + process.env.ErrorLogToken +); +process.on("unhandledRejection", async err => { + if (client.user) { + if (client.user.id === client.user.id) { + const embed = new MessageEmbed() + .setTitle("UnhandledRejection Error") + .setDescription(`\`\`\`ini\n${err.stack}\`\`\``) + .setTimestamp() + .setColor(client.color) + .setFooter(client.user.username); + client.ErrorLog.send(embed); + } + } + return console.log(err); +}); +client.SuggestionLog = config.Suggestion; +client.commands = new Collection(); +client.aliases = new Collection(); +client.events = new Collection(); +client.snipes = []; +client.esnipes = new Collection(); +client.hide = new Collection(); +client.queue = new Map(); +client.Timers = new Map(); +client.cat = config.ca; +client.function = require("./util/functions/function"); +client.data = require("./util/functions/mongoose"); +client.err = require("./util/err"); +client.data + .connect(config.mongo) + .then(() => console.log("Connected to MongoDB!")) + .catch(e => console.log(e)); +client.owners = [ + "452076196419600394", + "749692825402212494", + "766645910087139338", + "755476040029306952", +]; +client.currency = "<:cp:836630372661329990>"; +client.path = [ + "614423108388126731", + "767173194943168542", + "783633408738721834", + "718762019586572341", + "784052348561522730", + "840225563193114624", + "800396461229080619" +]; +client.xp = [ + "749135655350697986", + "801677847730585620", + "796316316880732160", + "755074176431423609", + "712255334298943569", + "639498286297907230", +]; +client.giveaways = new GiveawaysManager(client, { + storage: "./util/Data/giveaways.json", + updateCountdownEvery: 1000, + default: { + botsCanWin: false, + embedColor: client.color, + reaction: "🎉", + }, +}); +client.categories = fs.readdirSync("./commands/"); +client.paths = fs.readdirSync("./cat/"); +["command"].forEach(handler => { + require(`./util/command-handler`)(client); +}); +client.login(process.env.TOKEN); diff --git a/inlinereply.js b/inlinereply.js new file mode 100644 index 0000000..eba1f6d --- /dev/null +++ b/inlinereply.js @@ -0,0 +1,51 @@ +const { APIMessage, Structures } = require("discord.js"); + +class Message extends Structures.get("Message") { + async inlineReply(content, options) { + const mentionRepliedUser = + typeof ((options || content || {}).allowedMentions || {}).repliedUser === + "undefined" + ? true + : (options || content).allowedMentions.repliedUser; + delete ((options || content || {}).allowedMentions || {}).repliedUser; + + const apiMessage = + content instanceof APIMessage + ? content.resolveData() + : APIMessage.create(this.channel, content, options).resolveData(); + Object.assign(apiMessage.data, { + message_reference: { message_id: this.id }, + }); + + if ( + !apiMessage.data.allowed_mentions || + Object.keys(apiMessage.data.allowed_mentions).length === 0 + ) + apiMessage.data.allowed_mentions = { + parse: ["users", "roles", "everyone"], + }; + if (typeof apiMessage.data.allowed_mentions.replied_user === "undefined") + Object.assign(apiMessage.data.allowed_mentions, { + replied_user: mentionRepliedUser, + }); + + if (Array.isArray(apiMessage.data.content)) { + return Promise.all( + apiMessage + .split() + .map(x => { + x.data.allowed_mentions = apiMessage.data.allowed_mentions; + return x; + }) + .map(this.inlineReply.bind(this)) + ); + } + + const { data, files } = await apiMessage.resolveFiles(); + return this.client.api.channels[this.channel.id].messages + .post({ data, files }) + .then(d => this.client.actions.MessageCreate.handle(d).message); + } +} + +Structures.extend("Message", () => Message); diff --git a/models/custom-commands.js b/models/custom-commands.js new file mode 100644 index 0000000..28931b8 --- /dev/null +++ b/models/custom-commands.js @@ -0,0 +1,11 @@ +const mongoose = require("mongoose"); +module.exports = mongoose.model( + "custom-commands", + new mongoose.Schema({ + Guild: String, + Command: String, + Response: Array, + Delete: Boolean, + Random: Boolean, + }) +); diff --git a/models/econ.js b/models/econ.js new file mode 100644 index 0000000..44f65a5 --- /dev/null +++ b/models/econ.js @@ -0,0 +1,15 @@ +const { Schema, model } = require("mongoose"); +module.exports = model( + "economy", + new Schema({ + User: { + type: String, + required: true, + }, + CP: { + type: Number, + required: true, + }, + Inventory: Object, + }) +); diff --git a/models/guilds.js b/models/guilds.js new file mode 100644 index 0000000..0e286aa --- /dev/null +++ b/models/guilds.js @@ -0,0 +1,36 @@ +const mongoose = require("mongoose"); +const prefix = require("../config.json").prefix; +module.exports = mongoose.model( + "guild", + new mongoose.Schema({ + Guild: String, + Prefix: { + type: String, + default: prefix, + }, + Welcome: { + type: String, + default: "null", + }, + Goodbye: { + type: String, + default: "null", + }, + Log: { + type: String, + default: "null", + }, + Premium: { + type: Boolean, + default: false, + }, + Category: { + type: Array, + default: [], + }, + Commands: { + type: Array, + default: [], + }, + }) +); diff --git a/models/inventory.js b/models/inventory.js new file mode 100644 index 0000000..a1e4d82 --- /dev/null +++ b/models/inventory.js @@ -0,0 +1,27 @@ +const mongoose = require("mongoose"); + +const inventorySchema = mongoose.Schema({ + userId: { + type: String, + required: true, + }, + items: { + itemID: { + type: Number, + }, + itemName: { + type: String, + }, + itemWeapon: { + type: String, + }, + itemRarity: { + type: String, + }, + itemIMG: { + type: String, + }, + }, +}); + +module.exports = mongoose.model("inventory", inventorySchema); diff --git a/models/level.js b/models/level.js new file mode 100644 index 0000000..3a04862 --- /dev/null +++ b/models/level.js @@ -0,0 +1,11 @@ +const mongoose = require("mongoose"); +module.exports = mongoose.model( + "level", + new mongoose.Schema({ + xp: Number, + level: Number, + lastUpdate: Date, + userID: String, + guildID: String, + }) +); diff --git a/models/modmail.js b/models/modmail.js new file mode 100644 index 0000000..90eaf33 --- /dev/null +++ b/models/modmail.js @@ -0,0 +1,11 @@ +const mongoose = require("mongoose"); + +module.exports = mongoose.model( + "modmail", + new mongoose.Schema({ + Guild: String, + Category: String, + Choices: Object, + Role: String, + }) +); diff --git a/models/reaction.js b/models/reaction.js new file mode 100644 index 0000000..9aaf365 --- /dev/null +++ b/models/reaction.js @@ -0,0 +1,10 @@ +const mongoose = require("mongoose"); + +module.exports = mongoose.model( + "reaction-roles", + new mongoose.Schema({ + Guild: String, + Message: String, + Roles: Object, + }) +); diff --git a/models/users.js b/models/users.js new file mode 100644 index 0000000..713b69c --- /dev/null +++ b/models/users.js @@ -0,0 +1,31 @@ +const mongoose = require("mongoose"); +module.exports = mongoose.model( + "user", + new mongoose.Schema({ + User: String, + AFK: { + type: String, + default: null, + }, + Tier: { + type: Number, + default: 0, + }, + Premium: { + type: Boolean, + default: false, + }, + Blacklist: { + type: Boolean, + default: false, + }, + Blacklist_Reason: { + type: String, + default: "null", + }, + PremiumServers: { + type: Array, + default: [], + }, + }) +); diff --git a/models/warns.js b/models/warns.js new file mode 100644 index 0000000..a3a3c23 --- /dev/null +++ b/models/warns.js @@ -0,0 +1,12 @@ +const mongoose = require("mongoose"); +module.exports = mongoose.model( + "warn", + new mongoose.Schema({ + Guild: String, + User: String, + Warns: { + type: Array, + default: [], + }, + }) +); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..8175798 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4696 @@ +{ + "name": "cath.exe", + "version": "1.6.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" + }, + "@babel/parser": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==" + }, + "@babel/runtime": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", + "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + }, + "@canvacord/assets": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@canvacord/assets/-/assets-1.0.2.tgz", + "integrity": "sha512-76uLD27UDlfTxtgA7armbt6G9/X1NDqm/qjs9gxbWFVfcJxVdT3r3LlwaLp0NlRa5yMylCFf3WcOHufVjk60vw==" + }, + "@canvacord/emoji-parser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@canvacord/emoji-parser/-/emoji-parser-1.0.1.tgz", + "integrity": "sha512-Lb3xatdd91MR9tU4sicgrxxKg+/rVD1zKTOh55bmVF2Ri5X8vHTV+jNHTvRzkomGpyepGM+7qA4xMvG8ZqtO8g==", + "requires": { + "twemoji-parser": "^13.0.0" + } + }, + "@derhuerst/http-basic": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@derhuerst/http-basic/-/http-basic-8.2.1.tgz", + "integrity": "sha512-Rmn7qQQulw2sxJ8qGfZ7OuqMWuhz8V+L5xnYKMF5cXVcYqmgWqlVEAme90pF7Ya8OVhxVxLmhh0rI2k6t7ITWw==", + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "@discordjs/collection": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", + "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ==" + }, + "@discordjs/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "@discordjs/opus": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@discordjs/opus/-/opus-0.5.0.tgz", + "integrity": "sha512-s3XUJ7dYV+UvYUiqkgs7sq8JKWMhQrHcwDECP2SKdxtL9h9qGa4mr0IR6XnZw+G/Sogx8c+HRS7+wEspkqk3zA==", + "requires": { + "@discordjs/node-pre-gyp": "^0.3.2", + "node-addon-api": "^3.1.0" + }, + "dependencies": { + "@discordjs/node-pre-gyp": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@discordjs/node-pre-gyp/-/node-pre-gyp-0.3.2.tgz", + "integrity": "sha512-NqRvPz0X+/3h+6ClElrSfvsD5XEG9ljYzXhzyo81DslVkVKzmmxX9FLs3MUr9qI7p53DG1eYru633qosrOqMyA==", + "requires": { + "detect-libc": "^1.0.3", + "http-proxy-agent": "^4.0.1", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.1", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "rimraf": "^3.0.2", + "semver": "^7.3.4", + "tar": "^6.1.0" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "requires": { + "abbrev": "1" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "@kensingtontech/recacheman": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@kensingtontech/recacheman/-/recacheman-2.2.8.tgz", + "integrity": "sha512-rbh85Pse/iqT+doCauVZWxqaXCJpnjjJKOh3hFE5b7J1SoHp/S4IY94CZ8E8uV/eHUQlPF5YfTuCYjSaMTX9eQ==", + "requires": { + "@kensingtontech/recacheman-redis": "^2.1.6", + "ms": "^2.1.3", + "recacheman-file": "^0.2.5", + "recacheman-memory": "^1.1.0" + } + }, + "@kensingtontech/recacheman-redis": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@kensingtontech/recacheman-redis/-/recacheman-redis-2.1.6.tgz", + "integrity": "sha512-hTB0i3yxjciMF0zjr5U4ui/Qv4OVb/ld2PHKvE4NTpiGUz0kzye1d0verKwBWmenvFnScKTX9KXc7/HE59CdRA==", + "requires": { + "each": "1.2.1", + "parse-redis-url": "0.0.2", + "redis": "^3.0.2" + } + }, + "@mapbox/node-pre-gyp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", + "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", + "requires": { + "detect-libc": "^1.0.3", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.1", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "rimraf": "^3.0.2", + "semver": "^7.3.4", + "tar": "^6.1.0" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "requires": { + "abbrev": "1" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "@reconlx/discord.js": { + "version": "1.1.101", + "resolved": "https://registry.npmjs.org/@reconlx/discord.js/-/discord.js-1.1.101.tgz", + "integrity": "sha512-YKXJ74zra1tUwtx0p2U1nZWhnBTe2WhZioTMT5+W89QQrheyYus1MUWdJceAsN0eIs0p4zqhrNqWMWNY7B3xyQ==" + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "@types/bson": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz", + "integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==", + "requires": { + "@types/node": "*" + } + }, + "@types/mongodb": { + "version": "3.6.16", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.16.tgz", + "integrity": "sha512-D3tM0iRUet3TiIMAdvovxAIRG9gYqFd4j7visGwmPNdQj8Fq/uFFfRxyGCgEwVXAs0NnJPMI/QGVTADxDwhmSQ==", + "requires": { + "@types/bson": "*", + "@types/node": "*" + } + }, + "@types/node": { + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz", + "integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==" + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.2.tgz", + "integrity": "sha512-VrMS8kxT0e7J1EX0p6rI/E0FbfOVcvBpbIqHThFv+f8YrZIlMfVotYcXKVPmTvPW8sW5miJzfUFrrvthUZg8VQ==" + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + } + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "assert-never": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, + "async.parallellimit": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.parallellimit/-/async.parallellimit-0.5.2.tgz", + "integrity": "sha1-v9y/Lwgy8f/0wLM1S09jIGY91R8=", + "requires": { + "async.util.eachoflimit": "0.5.2", + "async.util.parallel": "0.5.2" + } + }, + "async.util.eachoflimit": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.eachoflimit/-/async.util.eachoflimit-0.5.2.tgz", + "integrity": "sha1-i4y4z7AniqXOtQqPgAwcJmjbV+8=", + "requires": { + "async.util.keyiterator": "0.5.2", + "async.util.noop": "0.5.2", + "async.util.once": "0.5.2", + "async.util.onlyonce": "0.5.2" + } + }, + "async.util.isarray": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.isarray/-/async.util.isarray-0.5.2.tgz", + "integrity": "sha1-5i2sjyY29lh13PdSHC0k0N+yu98=" + }, + "async.util.isarraylike": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.isarraylike/-/async.util.isarraylike-0.5.2.tgz", + "integrity": "sha1-jn+H2pFB8vCZboBAR30NTv4/UPg=", + "requires": { + "async.util.isarray": "0.5.2" + } + }, + "async.util.keyiterator": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.keyiterator/-/async.util.keyiterator-0.5.2.tgz", + "integrity": "sha1-M55s6PidAAQz+3gU4ico8/F1CQ0=", + "requires": { + "async.util.isarraylike": "0.5.2", + "async.util.keys": "0.5.2" + } + }, + "async.util.keys": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.keys/-/async.util.keys-0.5.2.tgz", + "integrity": "sha1-XDTd2KPtt6eIPJtf4hJngbIJivY=" + }, + "async.util.noop": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.noop/-/async.util.noop-0.5.2.tgz", + "integrity": "sha1-vdYrl8sKo/YLWGrRSEaGmJdeWLk=" + }, + "async.util.once": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.once/-/async.util.once-0.5.2.tgz", + "integrity": "sha1-FFPLdATK0IImlPq6vEepblyqchY=" + }, + "async.util.onlyonce": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz", + "integrity": "sha1-uOb8AErckjFk154y8oE+5GXCT/I=" + }, + "async.util.parallel": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.parallel/-/async.util.parallel-0.5.2.tgz", + "integrity": "sha1-IzUk49b6/9XplddUdrjZJPloCM0=", + "requires": { + "async.util.isarraylike": "0.5.2", + "async.util.noop": "0.5.2", + "async.util.restparam": "0.5.2" + } + }, + "async.util.restparam": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.restparam/-/async.util.restparam-0.5.2.tgz", + "integrity": "sha1-A+/r88Ane5ciDlJaunUPXgT8gM0=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "requires": { + "@babel/types": "^7.9.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + } + } + }, + "better-sqlite3": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.1.2.tgz", + "integrity": "sha512-8FWYnJ6Bx94MBX03J5Ka7sTRlvXXMEm4FW2Op7nM8ErQZeyALYLmSlbMBnfr4cMpS0tj0aYZv0a+26G2YJuIjg==", + "requires": { + "bindings": "^1.5.0", + "prebuild-install": "^5.3.3", + "tar": "^6.0.5" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", + "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "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=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + } + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "boolstring": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/boolstring/-/boolstring-1.0.2.tgz", + "integrity": "sha512-0JLNSmZUv1m/O8sVayFm2t0naiOXwQ9O2Gq9u1eoIkhvu6U5NQER/e3k4BGpjZ33G775lWMT7TzJ7r5VtmEnbQ==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "bson": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", + "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==" + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "canvacord": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/canvacord/-/canvacord-5.2.0.tgz", + "integrity": "sha512-Cr+ZM/N2Dhjbvkhm0Tu0Kg3oCx67J/koBFHoSKIrLzOvsiaiFFPAXIRpaJiTXeRVXk8adZa+g1812dwcjmPq6g==", + "requires": { + "@canvacord/assets": "^1.0.2", + "@canvacord/emoji-parser": "^1.0.1", + "canvas": "^2.7.0", + "gifencoder": "^2.0.1", + "moment": "^2.29.1", + "moment-duration-format": "^2.3.2" + }, + "dependencies": { + "canvas": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.7.0.tgz", + "integrity": "sha512-pzCxtkHb+5su5MQjTtepMDlIOtaXo277x0C0u3nMOxtkhTyQ+h2yNKhlROAaDllWgRyePAUitC08sXw26Eb6aw==", + "requires": { + "nan": "^2.14.0", + "node-pre-gyp": "^0.15.0", + "simple-get": "^3.0.3" + } + }, + "node-pre-gyp": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", + "integrity": "sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==", + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.3", + "needle": "^2.5.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + } + } + }, + "canvas": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.8.0.tgz", + "integrity": "sha512-gLTi17X8WY9Cf5GZ2Yns8T5lfBOcGgFehDFb+JQwDqdOoBOcECS9ZWMEAqMSVcMYwXD659J8NyzjRY/2aE+C2Q==", + "requires": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.14.0", + "simple-get": "^3.0.3" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "cath": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cath/-/cath-1.0.7.tgz", + "integrity": "sha512-P6kdi3KiE80eMK957AvQacDPD6z8ZupcoiGD6GpeLbOvSOzQSXIaUtiNutIlnDfqQ9D90PV4Imu2KwplIjLOAA==", + "requires": { + "discord.js": "^12.5.1" + }, + "dependencies": { + "discord.js": { + "version": "12.5.3", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.3.tgz", + "integrity": "sha512-D3nkOa/pCkNyn6jLZnAiJApw2N9XrIsXUAdThf01i7yrEuqUmDGc7/CexVWwEcgbQR97XQ+mcnqJpmJ/92B4Aw==", + "requires": { + "@discordjs/collection": "^0.1.6", + "@discordjs/form-data": "^3.0.1", + "abort-controller": "^3.0.0", + "node-fetch": "^2.6.1", + "prism-media": "^1.2.9", + "setimmediate": "^1.0.5", + "tweetnacl": "^1.0.3", + "ws": "^7.4.4" + } + } + } + }, + "centra": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/centra/-/centra-2.4.2.tgz", + "integrity": "sha512-f1RaP0V1HqVNEXfLfjNBthB2yy3KnSGnPCnOPCFLUk9e/Z4rNJ8nBaJNnghflnp88mi1IT8mfmW+HlMS1/H+bg==" + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "requires": { + "is-regex": "^1.0.3" + } + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + }, + "cheerio": { + "version": "1.0.0-rc.6", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.6.tgz", + "integrity": "sha512-hjx1XE1M/D5pAtMgvWwE21QClmAEeGHOIDfycgmndisdNgI6PE1cGRQkMGBcsbUbmEQyWu5PJLUcAOjtQS8DWw==", + "requires": { + "cheerio-select": "^1.3.0", + "dom-serializer": "^1.3.1", + "domhandler": "^4.1.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1" + } + }, + "cheerio-select": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.4.0.tgz", + "integrity": "sha512-sobR3Yqz27L553Qa7cK6rtJlMDbiKPdNywtR95Sj/YgfpLfy0u6CGJuaBKe5YE/vTc23SCRKxWSdlon/w6I/Ew==", + "requires": { + "css-select": "^4.1.2", + "css-what": "^5.0.0", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "cli-color": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-1.2.0.tgz", + "integrity": "sha1-OlrnT9drYmevZm5p4q+70B3vNNE=", + "requires": { + "ansi-regex": "^2.1.1", + "d": "1", + "es5-ext": "^0.10.12", + "es6-iterator": "2", + "memoizee": "^0.4.3", + "timers-ext": "0.1" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "connect-mongo": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-4.4.1.tgz", + "integrity": "sha512-I1QUE2tSGPtIBDAL2sFqUEPspDeJOR0u4g+N41ARJZk958pncu2PBG48Ev++fnldljobpIfdafak7hSlPYarvA==", + "requires": { + "debug": "^4.3.1", + "kruptein": "^3.0.0", + "mongodb": "3.6.5" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "mongodb": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.5.tgz", + "integrity": "sha512-mQlYKw1iGbvJJejcPuyTaytq0xxlYbIoVDm2FODR+OHxyEiMR021vc32bTvamgBjCswsD54XIRwhg3yBaWqJjg==", + "requires": { + "bl": "^2.2.1", + "bson": "^1.1.4", + "denque": "^1.4.1", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "requires": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "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.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cross-fetch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "requires": { + "node-fetch": "2.6.1" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" + }, + "css-select": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.2.tgz", + "integrity": "sha512-nu5ye2Hg/4ISq4XqdLY2bEatAcLIdt3OYGFc9Tm9n7VSlFBcfRv0gBNksHRgSdUDQGtN3XrZ94ztW+NfzkFSUw==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^5.0.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0", + "nth-check": "^2.0.0" + } + }, + "css-what": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.0.tgz", + "integrity": "sha512-qxyKHQvgKwzwDWC/rGbT821eJalfupxYW2qbSJSAtdSTimsr/MlaGONoNLllaUPZWf8QnbcKM/kPVYUQuEKAFA==" + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } + } + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "dasu": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/dasu/-/dasu-0.4.2.tgz", + "integrity": "sha512-3iZKDAKqv0APFwpqP40gpro5msM+pwhQN7IhB42mjbL1W4M2V6A+MJy7RhA8y6lUM+1mQoLls3OePidmzVbncQ==" + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" + }, + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "requires": { + "mimic-response": "^2.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "denque": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", + "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==" + }, + "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=" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "disco-oauth": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/disco-oauth/-/disco-oauth-5.1.0.tgz", + "integrity": "sha512-36yAW1h6h3k3QTMAmY21/vJiu1xgkfqk//F9VyMBlR3g6ELYa3fgRWmSGfjycC+hi+/zOH6Ti/lx4r+U7EgAcw==", + "requires": { + "jsonwebtoken": "^8.5.1", + "phin": "^3.5.0", + "uid": "^1.0.0" + } + }, + "discord-buttons": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/discord-buttons/-/discord-buttons-1.0.4.tgz", + "integrity": "sha512-oLYUDaL4IQmEAnnIkWDPZHsxQA4+DpGJy9jszsx9vOmODnWsPdFJKtMvG39TfeZ/eTwpcNT2WWtPX8m/xAfyRA==", + "requires": { + "discord.js": "^12.5.3" + }, + "dependencies": { + "discord.js": { + "version": "12.5.3", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.3.tgz", + "integrity": "sha512-D3nkOa/pCkNyn6jLZnAiJApw2N9XrIsXUAdThf01i7yrEuqUmDGc7/CexVWwEcgbQR97XQ+mcnqJpmJ/92B4Aw==", + "requires": { + "@discordjs/collection": "^0.1.6", + "@discordjs/form-data": "^3.0.1", + "abort-controller": "^3.0.0", + "node-fetch": "^2.6.1", + "prism-media": "^1.2.9", + "setimmediate": "^1.0.5", + "tweetnacl": "^1.0.3", + "ws": "^7.4.4" + } + } + } + }, + "discord-canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/discord-canvas/-/discord-canvas-1.4.1.tgz", + "integrity": "sha512-0Ee1mvmalw1Nz60MwU6SxUdFNUDrJwx8II4JxaDFqw/2nEPav7PB8giQxDPaCgcyFOAvReQJFSQ66FCr+m1O8g==", + "requires": { + "canvas": "^2.6.1", + "fortnite": "^4.3.2", + "fortnite-9812": "^1.0.4", + "fs": "^0.0.1-security" + } + }, + "discord-giveaways": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/discord-giveaways/-/discord-giveaways-4.5.1.tgz", + "integrity": "sha512-aSOD7IiCqfJ2sU1GbdH0EP/xwuXZW/h7+8RH6LzgfZaYy2V89O0qKwbe52Dy2ToymAexPhEGpDKZHrm6Vd0Jqw==", + "requires": { + "deepmerge": "^4.2.2", + "serialize-javascript": "^5.0.1" + } + }, + "discord-player": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/discord-player/-/discord-player-3.4.0.tgz", + "integrity": "sha512-r7RCxIBq2n79+rdz6NtquR3DmJ2+8TMnPcCYhqCVfM5eqMiYlGcN/eEiSF4VGD2wJ8QGjQNsvV29J2GWG77D1Q==", + "requires": { + "chalk": "^4.1.0", + "discord-ytdl-core": "^5.0.1", + "jsdom": "^16.4.0", + "merge-options": "^3.0.4", + "node-fetch": "^2.6.0", + "parse-ms": "^2.1.0", + "reverbnation-scraper": "^2.0.0", + "soundcloud-scraper": "^4.0.3", + "spotify-url-info": "^2.2.0", + "youtube-sr": "^4.0.2", + "ytdl-core": "^4.5.0" + } + }, + "discord-rpc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/discord-rpc/-/discord-rpc-3.2.0.tgz", + "integrity": "sha512-KJv0EVbGMlr04HoG6f5b3wD7X9kSHzQ2Ed2qfHSDvYJ1MkE8RbCQmMcQQrSvAxpfsqZgUjB/bsfi/mjyicCH+A==", + "requires": { + "node-fetch": "^2.6.1", + "ws": "^7.3.1" + } + }, + "discord-xp": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/discord-xp/-/discord-xp-1.1.14.tgz", + "integrity": "sha512-SYZTi/xVn0sJJn7wW49OekdTIdi3d4/ftII4Yl1wteOfa49/0uEpCRqf6I5KZffuz1kCCD5p8EVAIg291rzyvg==", + "requires": { + "mongoose": "^5.11.11" + } + }, + "discord-ytdl-core": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/discord-ytdl-core/-/discord-ytdl-core-5.0.3.tgz", + "integrity": "sha512-q4GOEFiV19l0OcPezXnkDWualf+n96LcbTEWReceiDHdx4xxn5CXZX9PR4iDTXQR3Kv2VUkwB8RO8dI50d88vQ==", + "requires": { + "prism-media": "^1.2.9" + } + }, + "discord.js": { + "version": "github:reconlx/discord.js#17c7eb62f3748518900f69b23be87aeb13683007", + "from": "github:reconlx/discord.js", + "requires": { + "@discordjs/collection": "^0.1.6", + "@discordjs/form-data": "^3.0.1", + "abort-controller": "^3.0.0", + "node-fetch": "^2.6.1", + "prism-media": "^1.2.2", + "setimmediate": "^1.0.5", + "tweetnacl": "^1.0.3", + "ws": "^7.3.1" + } + }, + "doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" + }, + "dom-serializer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.1.tgz", + "integrity": "sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + } + } + }, + "domhandler": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.6.0.tgz", + "integrity": "sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + }, + "each": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/each/-/each-1.2.1.tgz", + "integrity": "sha512-POUbnWaseHgI8I+icHo3jAMrCqoLgVWaI7yqcQ0nat4q2f2BFUVGAndMOvr2UZoHAGAnQqotaM9RI4kZcjtAcg==" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "requires": { + "jake": "^10.6.1" + } + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "requires": { + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "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=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + } + } + }, + "express-session": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", + "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", + "requires": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "dependencies": { + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, + "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" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", + "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "ffmpeg": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/ffmpeg/-/ffmpeg-0.0.4.tgz", + "integrity": "sha1-HEYN+OfaUSf2LO70v6BsWciWMMs=", + "requires": { + "when": ">= 0.0.1" + } + }, + "ffmpeg-static": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-4.3.0.tgz", + "integrity": "sha512-w/tXYGlOSeAkPHjypjzylaChLrG5wRzHFyB47KFRDsGyBxUJJWiq9I/39/e6r9Y4aY1gzpejTLg5Aa0aqb0XXA==", + "requires": { + "@derhuerst/http-basic": "^8.2.0", + "env-paths": "^2.2.0", + "https-proxy-agent": "^5.0.0", + "progress": "^2.0.3" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "filelist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "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=" + } + } + }, + "follow-redirects": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", + "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "fortnite": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/fortnite/-/fortnite-4.3.2.tgz", + "integrity": "sha512-6BReElBAwP/3Gq6zEBn9gdQzrzWpMlumY9IF0suZgDshbzsS8dCDuV8JszDl1l1PVJwtzm2uexfUo9YtUqUV6Q==", + "requires": { + "node-fetch": "^2.3.0" + } + }, + "fortnite-9812": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fortnite-9812/-/fortnite-9812-1.0.4.tgz", + "integrity": "sha512-TkdbPT1oTQ/GncnC5Sf4dVo6CLo4NJAtiU17rOUetcZ59nLAgNhceNkSqgMCYdYx6gCEB1A/9pYzm/JKOmgRcA==", + "requires": { + "node-fetch": "^2.3.0" + } + }, + "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=" + }, + "fs": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", + "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=" + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-extra": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "gifencoder": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gifencoder/-/gifencoder-2.0.1.tgz", + "integrity": "sha512-x19DcyWY10SkshBpokqFOo/HBht9GB75evRYvaLMbez9p+yB/o+kt0fK9AwW59nFiAMs2UUQsjv1lX/hvu9Ong==", + "requires": { + "canvas": "^2.2.0" + } + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "goosecache": { + "version": "9.0.14", + "resolved": "https://registry.npmjs.org/goosecache/-/goosecache-9.0.14.tgz", + "integrity": "sha512-EWUYpaUnRBVFabApU/tKqFTq2VPdXqU75UeCUcv6cYgPtNxErVkYyBpguwOQtvI8FLELhraK/AU6E7nyeFIqpw==", + "requires": { + "@kensingtontech/recacheman": "^2.2.8", + "loglevel": "^1.7.1", + "sha1": "^1.1.1" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "himalaya": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/himalaya/-/himalaya-1.1.0.tgz", + "integrity": "sha512-LLase1dHCRMel68/HZTFft0N0wti0epHr3nNY7ynpLbyZpmrKMQ8YIpiOV77TM97cNpC8Wb2n6f66IRggwdWPw==" + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-to-text": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-5.1.1.tgz", + "integrity": "sha512-Bci6bD/JIfZSvG4s0gW/9mMKwBRoe/1RWLxUME/d6WUSZCdY7T60bssf/jFf7EYXRyqU4P5xdClVqiYU0/ypdA==", + "requires": { + "he": "^1.2.0", + "htmlparser2": "^3.10.1", + "lodash": "^4.17.11", + "minimist": "^1.2.0" + }, + "dependencies": { + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", + "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==" + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + } + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.59", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.59.tgz", + "integrity": "sha512-7Uc8IRrL8yZz5ti45RaFxpbU8TxlzdC3HvxV+hOWo1EyLsuKv/w7y0n+TwZzwL3vdx3oZ2k3ubxPq131hNtXyg==" + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "human-time": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/human-time/-/human-time-0.0.2.tgz", + "integrity": "sha512-sbYI90YhYmstslPTb70BLGjy6mdESa0lxL7uDR4fIVAx9Iobz8fLEqi7FqF4Q/6vblrzZALg//MsYJlIPBU8SA==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "imageapi.js": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/imageapi.js/-/imageapi.js-1.7.0.tgz", + "integrity": "sha512-0OCfIWDQxCwqP5XjiumobcNbmv0rwatIOrhkQTikkJ8VjgohvaUh4yBHSKTlGHLyvPuKKNVfz4epR6Mm0xrHWQ==", + "requires": { + "node-fetch": "^2.6.1" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-core-module": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", + "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "requires": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + } + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "iso8601-duration": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/iso8601-duration/-/iso8601-duration-1.3.0.tgz", + "integrity": "sha512-K4CiUBzo3YeWk76FuET/dQPH03WE04R94feo5TSKQCXpoXQt9E4yx2CnY737QZnSAI3PI4WlKo/zfqizGx52QQ==" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "requires": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==" + }, + "js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsdom": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.3.tgz", + "integrity": "sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA==", + "requires": { + "abab": "^2.0.5", + "acorn": "^8.1.0", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.9", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.4", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" + } + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonpath-plus": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-5.0.7.tgz", + "integrity": "sha512-7TS6wsiw1s2UMK/A6nA4n0aUJuirCVhJ87nWX5je5MPOl0z5VTr2qs7nMP8NZ2ed3rlt6kePTqddgVPE9F0i0w==" + }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "requires": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "kareem": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", + "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" + }, + "keypress": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz", + "integrity": "sha1-HoBFQlABjbrUw/6USX1uZ7YmnHc=" + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "kruptein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/kruptein/-/kruptein-3.0.0.tgz", + "integrity": "sha512-Fh5sIb+3XI9L12GsgeBQqXVRPLB1HVViKSUkqPPOcqTEX4NwoF8Z3pEfMSl3Psd1j+QlloV8Uxxwp4gk3aFBGA==", + "requires": { + "asn1.js": "^5.4.1" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=" + }, + "lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + }, + "lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=" + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=" + }, + "loglevel": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", + "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", + "requires": { + "es5-ext": "~0.10.2" + } + }, + "lyrics-finder": { + "version": "21.7.0", + "resolved": "https://registry.npmjs.org/lyrics-finder/-/lyrics-finder-21.7.0.tgz", + "integrity": "sha512-AMaJ+MdbdemYOWM1Kxd/vzn23OD66/fdemaJWN9dU0qsxK6d09rODSphygAvaGka6mgfHaFlHN+ETHv/d60ftw==", + "requires": { + "encoding": "^0.1.13", + "html-to-text": "^5.1.1", + "node-fetch": "^2.6.0" + } + }, + "m3u8stream": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.8.3.tgz", + "integrity": "sha512-0nAcdrF8YJKUkb6PzWdvGftTPyCVWgoiot1AkNVbPKTeIGsWs6DrOjifrJ0Zi8WQfQmD2SuVCjkYIOip12igng==", + "requires": { + "miniget": "^4.0.0", + "sax": "^1.2.4" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + }, + "dependencies": { + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + } + } + }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "requires": { + "is-plain-obj": "^2.1.0" + } + }, + "method-override": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", + "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", + "requires": { + "debug": "3.1.0", + "methods": "~1.1.2", + "parseurl": "~1.3.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", + "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==" + }, + "mime-types": { + "version": "2.1.28", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", + "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "requires": { + "mime-db": "1.45.0" + } + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" + }, + "miniget": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/miniget/-/miniget-4.1.0.tgz", + "integrity": "sha512-kzhrNv5L7LlomwGmPGQsLQ2PnT1LeJJWfB0wNFGyv426gEM1gsfziBQmfkr6XOBA8EusZg9nowlNT5CbuKTjZg==" + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "moment-duration-format": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/moment-duration-format/-/moment-duration-format-2.3.2.tgz", + "integrity": "sha512-cBMXjSW+fjOb4tyaVHuaVE/A5TqkukDWiOfxxAjY+PEqmmBQlLwn+8OzwPiG3brouXKY5Un4pBjAeB6UToXHaQ==" + }, + "moment-timezone": { + "version": "0.5.33", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", + "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", + "requires": { + "moment": ">= 2.9.0" + } + }, + "mongodb": { + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.8.tgz", + "integrity": "sha512-sDjJvI73WjON1vapcbyBD3Ao9/VN3TKYY8/QX9EPbs22KaCSrQ5rXo5ZZd44tWJ3wl3FlnrFZ+KyUtNH6+1ZPQ==", + "requires": { + "bl": "^2.2.1", + "bson": "^1.1.4", + "denque": "^1.4.1", + "optional-require": "^1.0.3", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + } + }, + "mongoose": { + "version": "5.12.11", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.11.tgz", + "integrity": "sha512-16TVqYhHQdZNR8RTis/8iiTPy+nJPq0UhKyBFTucLLU3PWcDLY2gAGv6aOk0LygTNhEfgNnENgUUHhjVqTuh8w==", + "requires": { + "@types/mongodb": "^3.5.27", + "bson": "^1.1.4", + "kareem": "2.3.2", + "mongodb": "3.6.8", + "mongoose-legacy-pluralize": "1.0.2", + "mpath": "0.8.3", + "mquery": "3.2.5", + "ms": "2.1.2", + "regexp-clone": "1.0.0", + "safe-buffer": "5.2.1", + "sift": "13.5.2", + "sliced": "1.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "mongoose-legacy-pluralize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", + "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" + }, + "mpath": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.3.tgz", + "integrity": "sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA==" + }, + "mquery": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.5.tgz", + "integrity": "sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A==", + "requires": { + "bluebird": "3.5.1", + "debug": "3.1.0", + "regexp-clone": "^1.0.0", + "safe-buffer": "5.1.2", + "sliced": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, + "needle": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", + "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "node-abi": { + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.19.3.tgz", + "integrity": "sha512-9xZrlyfvKhWme2EXFKQhZRp1yNWT/uI1luYPr3sFl+H4keYY4xR+1jO7mvTTijIsHf1M+QDe9uWuKeEpLInIlg==", + "requires": { + "semver": "^5.4.1" + } + }, + "node-addon-api": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz", + "integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==" + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "node-fzf": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/node-fzf/-/node-fzf-0.5.3.tgz", + "integrity": "sha512-crN8rRfApu/GUrtKq+zJ6LueUyNAOJpFHxoT2Ru1Q+OYRa/F/H7CXvzcMrFc7D964yakYZEZ9XR3YbdSHXgyCw==", + "requires": { + "cli-color": "~1.2.0", + "keypress": "~0.2.1", + "minimist": "~1.2.0", + "redstar": "0.0.2", + "string-width": "~2.1.1", + "ttys": "0.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "node-superfetch": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/node-superfetch/-/node-superfetch-0.1.11.tgz", + "integrity": "sha512-984lO43EvDtjBOpVXDqnR2L5+pVt+qWfqIE6H7Sl21BoIz26OwSKxBnO9ZmJkYXAimR64MUPiz6tn5hySy1d0Q==", + "requires": { + "form-data": "^3.0.0", + "node-fetch": "^2.6.0" + } + }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", + "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", + "requires": { + "boolbase": "^1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + }, + "oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "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" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "optional-require": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", + "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==" + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "opusscript": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.8.tgz", + "integrity": "sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==" + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=" + }, + "parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==" + }, + "parse-redis-url": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/parse-redis-url/-/parse-redis-url-0.0.2.tgz", + "integrity": "sha1-E8kqCrvm8lEgBqjEnebLe43Usnc=" + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "requires": { + "parse5": "^6.0.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "passport": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + } + }, + "passport-discord": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/passport-discord/-/passport-discord-0.1.4.tgz", + "integrity": "sha512-VJWPYqSOmh7SaCLw/C+k1ZqCzJnn2frrmQRx1YrcPJ3MQ+Oa31XclbbmqFICSvl8xv3Fqd6YWQ4H4p1MpIN9rA==", + "requires": { + "passport-oauth2": "^1.5.0" + } + }, + "passport-oauth2": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz", + "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==", + "requires": { + "base64url": "3.x.x", + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "uid2": "0.0.x", + "utils-merge": "1.x.x" + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" + }, + "path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", + "requires": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "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=" + }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "phin": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/phin/-/phin-3.5.1.tgz", + "integrity": "sha512-jgFO28IaiWAl0xk+zmqVx7neKVokWKU8YTQC5QlB45SZnEE53LH2saqJIcyIV557VX3Gk+TdR4rwWTc3P83DSA==", + "requires": { + "centra": "^2.4.2" + } + }, + "prebuild-install": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", + "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "prism-media": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.9.tgz", + "integrity": "sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q==" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "pug": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", + "requires": { + "pug-code-gen": "^3.0.2", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "requires": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "pug-code-gen": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", + "requires": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "pug-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" + }, + "pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "requires": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "requires": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "requires": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "requires": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "requires": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" + }, + "pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "requires": { + "pug-error": "^2.0.0" + } + }, + "pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "quick.db": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/quick.db/-/quick.db-7.1.3.tgz", + "integrity": "sha512-0S1fVb9OAZGhkI4ZIc5Oe4yWMwhz20xSsziwd6+yGWKKMsPt+XOfj/gD5CesGxd2WdqBkZFBiP8ZqWDu55HLHA==", + "requires": { + "better-sqlite3": "^7.1.1", + "lodash": "^4.17.20" + } + }, + "quickchart-js": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/quickchart-js/-/quickchart-js-1.0.7.tgz", + "integrity": "sha512-ck+0VgrYDqU1YZ3q39rPhr9DmxoPByUhV3YMwDedYNX5admxjSlbQM9BLjavYpKQEdbTwG9tbkCUakbSf0ke1Q==", + "requires": { + "axios": "^0.21.1", + "javascript-stringify": "^2.0.1" + } + }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "recacheman-file": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/recacheman-file/-/recacheman-file-0.2.5.tgz", + "integrity": "sha512-wG3NrjR/+QTGVjV+omK8n81LPHNzhfHNiMGx25upFUX3FBmGBbtPZCLFlwc2wUDt4HIReKQ3sIjOQVBUE8/T5Q==", + "requires": { + "fs-extra": "~0.26.2", + "sanitize-filename": "^1.5.3" + } + }, + "recacheman-memory": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/recacheman-memory/-/recacheman-memory-1.1.2.tgz", + "integrity": "sha512-FqaAJ0Rn0yZaGPPKI6aAb6z5PbPLKGhlZnCWRB2vYzBtPOx3c/PhCT3B1jt1zjkVjDNLs06+NGRoK3GY/A0qsw==", + "requires": { + "lru-cache": "~4.1.x" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } + }, + "reconlx": { + "version": "1.2.41", + "resolved": "https://registry.npmjs.org/reconlx/-/reconlx-1.2.41.tgz", + "integrity": "sha512-wewcAeqwqyFHvyQG4zDYc61IbJySwEKU50XSXEMBl6KCUhcNvmeI4A0nJ+dKaS6W3ElQkWhe+3Nk2x2fJ5Mi1g==", + "requires": { + "discord.js": "^12.5.1", + "jsdom": "^16.4.0", + "mongoose": "^5.10.15", + "ms": "^2.1.2" + }, + "dependencies": { + "discord.js": { + "version": "12.5.3", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.3.tgz", + "integrity": "sha512-D3nkOa/pCkNyn6jLZnAiJApw2N9XrIsXUAdThf01i7yrEuqUmDGc7/CexVWwEcgbQR97XQ+mcnqJpmJ/92B4Aw==", + "requires": { + "@discordjs/collection": "^0.1.6", + "@discordjs/form-data": "^3.0.1", + "abort-controller": "^3.0.0", + "node-fetch": "^2.6.1", + "prism-media": "^1.2.9", + "setimmediate": "^1.0.5", + "tweetnacl": "^1.0.3", + "ws": "^7.4.4" + } + }, + "prism-media": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.9.tgz", + "integrity": "sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q==" + }, + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" + } + } + }, + "redis": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz", + "integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==", + "requires": { + "denque": "^1.5.0", + "redis-commands": "^1.7.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0" + } + }, + "redis-commands": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", + "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==" + }, + "redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=" + }, + "redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", + "requires": { + "redis-errors": "^1.0.0" + } + }, + "redstar": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/redstar/-/redstar-0.0.2.tgz", + "integrity": "sha1-nVammAY4yYUaEAsMs799PrkCBcs=", + "requires": { + "minimatch": "~3.0.4" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + }, + "regexp-clone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", + "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "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.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "requires": { + "lodash": "^4.17.19" + } + }, + "request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "reverbnation-scraper": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reverbnation-scraper/-/reverbnation-scraper-2.0.0.tgz", + "integrity": "sha512-t1Mew5QC9QEVEry5DXyagvci2O+TgXTGoMHbNoW5NRz6LTOzK/DLHUpnrQwloX8CVX5z1a802vwHM3YgUVOvKg==", + "requires": { + "node-fetch": "^2.6.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "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==" + }, + "sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "requires": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "requires": { + "xmlchars": "^2.2.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "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" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "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==" + } + } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sha1": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", + "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=", + "requires": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + } + }, + "sift": { + "version": "13.5.2", + "resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz", + "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + }, + "simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "simple-youtube-api": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/simple-youtube-api/-/simple-youtube-api-5.2.1.tgz", + "integrity": "sha512-vmndP9Bkh35tifn2OwY+th2imSsfYtmDqczgdOW5yEARFzvSoR8VSQFsivJnctfV5QHQUL6VrOpNdbmDRLh9Bg==", + "requires": { + "iso8601-duration": "^1.2.0", + "node-fetch": "^2.6.0" + } + }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, + "soundcloud-downloader": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/soundcloud-downloader/-/soundcloud-downloader-0.2.4.tgz", + "integrity": "sha512-ncXi9AC3Crs8azBBUw0u5n6RyJpuV3QhBPDkI8dik3e9r7l6L6mmmrdGgKITsOwEuj3rxoTdFvSAP4pv2VorRw==", + "requires": { + "@babel/runtime": "^7.10.3", + "axios": "^0.21.0", + "dotenv": "^8.2.0", + "m3u8stream": "^0.8.0", + "soundcloud-key-fetch": "^1.0.10" + } + }, + "soundcloud-key-fetch": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/soundcloud-key-fetch/-/soundcloud-key-fetch-1.0.11.tgz", + "integrity": "sha512-ofnXB3yeHGVKnFKEMBP/kIJzGu1SduQzJc+zmkPbKgelvYNsEU/aTGD0PlhmyZquaCkTGByF8CEPRrAnt7ki4g==" + }, + "soundcloud-scraper": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/soundcloud-scraper/-/soundcloud-scraper-4.0.3.tgz", + "integrity": "sha512-A0a6sVJ2wkkWIX8Ft3L63sfHBlFDRAaPFif+SWi07KCNLh8YTcylw45pts76pndxlupKwV2NgOTIYeF/F9tg8w==", + "requires": { + "cheerio": "^1.0.0-rc.3", + "m3u8stream": "^0.8.0", + "node-fetch": "^2.6.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, + "spotify-uri": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spotify-uri/-/spotify-uri-2.2.0.tgz", + "integrity": "sha512-uUybj02bfyfCoZ0MJ80MkqbKxtIVRJfbRGk05KJFq1li3zb7yNfN1f+TAw4wcXgp7jLWExeiw2wyPQXZ8PHtfg==" + }, + "spotify-url-info": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spotify-url-info/-/spotify-url-info-2.2.0.tgz", + "integrity": "sha512-GEMoMf2RF+CSPsSGstY/9c7dgViKOKJ09bFZTwrU4KzQ+JpLq+0Ho4eMCeeGmES94yjBz+GHMtBfTcp+4DxEbA==", + "requires": { + "cross-fetch": "^3.0.5", + "himalaya": "^1.1.0", + "spotify-uri": "^2.1.0" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "bl": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", + "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "requires": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=" + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "requires": { + "punycode": "^2.1.1" + } + }, + "truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "requires": { + "utf8-byte-length": "^1.0.1" + } + }, + "ttys": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/ttys/-/ttys-0.0.3.tgz", + "integrity": "sha1-FbrN54MQIN5fLyjwGxcy7wNlH00=" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "twemoji-parser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-13.0.0.tgz", + "integrity": "sha512-zMaGdskpH8yKjT2RSE/HwE340R4Fm+fbie4AaqjDa4H/l07YUmAvxkSfNl6awVWNRRQ0zdzLQ8SAJZuY5MgstQ==" + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "uid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uid/-/uid-1.0.0.tgz", + "integrity": "sha512-DYp36HDIRECMW0xmeyGSDSheURMbL7gy4DqINDUW5OSw7cot0pNRNvEtEji9nk1XVDZN/0lJ7myxacoTeU9oow==" + }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, + "uid2": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=" + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=" + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" + }, + "weky": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/weky/-/weky-1.4.2.tgz", + "integrity": "sha512-sIu8KJgtoZ1k+r8VOLLm9GGd+mE63RU74pFoaI8Tep4aueGe9uWp61IWB3dgMWYMcU/v2Lh1WDdRduwMcWd/Lw==", + "requires": { + "ms": "^2.1.3", + "node-fetch": "^2.6.1" + } + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz", + "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==", + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^6.1.0" + } + }, + "when": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", + "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=" + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "requires": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "youtube-sr": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/youtube-sr/-/youtube-sr-4.0.6.tgz", + "integrity": "sha512-nRrqgWl0xYfMhwLTqjF7G6s+36IHIdOMtZaSrz0Cpk4uSIqoeKEJgLiAZrYIGWGNYtS8/mzZYRzYxaIA/gW1Ig==", + "requires": { + "node-fetch": "^2.6.1", + "simple-youtube-api": "^5.2.1" + } + }, + "yt-search": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yt-search/-/yt-search-2.8.0.tgz", + "integrity": "sha512-tpRiSF42vW0T5aa0ebGqsoI3lq0/QpJXQ4JFTSIyknZIxCq3h0Pvjcctdmp8Huplq90/1Ma9/rxeAhpCFPe5tw==", + "requires": { + "async.parallellimit": "~0.5.2", + "boolstring": "~1.0.2", + "cheerio": "~0.22.0", + "dasu": "~0.4.2", + "human-time": "0.0.2", + "jsonpath-plus": "~5.0.2", + "minimist": "~1.2.5", + "node-fzf": "~0.5.1" + }, + "dependencies": { + "cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "ytdl-core": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.8.0.tgz", + "integrity": "sha512-LFhhwqFojReoaME17VpsFeiamygM0W/YNG8O02mrmS2O6Em5LjCPiJYdq7Af3CmJtBEOCdptSZ3Ql+3LGWDGvg==", + "requires": { + "m3u8stream": "^0.8.3", + "miniget": "^4.0.0", + "sax": "^1.1.3" + } + }, + "ytdl-core-discord": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ytdl-core-discord/-/ytdl-core-discord-1.3.0.tgz", + "integrity": "sha512-AdyhfsegYyFGM6vaNWz/VOjknJ5sY9D2729tTp1uelQW0+yhHSycEC+gzjU0YY18cwwyaepQsHA0zQAvaI6pmw==", + "requires": { + "@types/node": "^14.14.35", + "prism-media": "^1.2.8", + "ytdl-core": "^4.5.0" + }, + "dependencies": { + "@types/node": { + "version": "14.14.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz", + "integrity": "sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==" + }, + "prism-media": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.9.tgz", + "integrity": "sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q==" + } + } + }, + "ytpl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ytpl/-/ytpl-2.2.1.tgz", + "integrity": "sha512-sxty58s4JTNCDkiaiTkcaXfWCOW5sfHOPwDQtWIkoU4C+Kht2qat8yaLVbWZIclUSZo+naANyaI7LGjhhrErGA==", + "requires": { + "miniget": "^4.2.0" + }, + "dependencies": { + "miniget": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/miniget/-/miniget-4.2.0.tgz", + "integrity": "sha512-IzTOaNgBw/qEpzkPTE7X2cUVXQfSKbG8w52Emi93zb+Zya2ZFrbmavpixzebuDJD9Ku4ecbaFlC7Y1cEESzQtQ==" + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..ce4a053 --- /dev/null +++ b/package.json @@ -0,0 +1,75 @@ +{ + "name": "cath.exe", + "version": "2.0.0", + "description": "cath.exe bot created by Night", + "engines": { + "node": "14.17", + "npm": "*" + }, + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "dev": "nodemon index.js", + "start": "node index.js", + "dashboard": "cd dashboard && npm run dev" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/night0721/cath.git" + }, + "keywords": [], + "author": "Ń1ght#0001", + "license": "ISC", + "bugs": { + "url": "https://github.com/night0721/cath/issues" + }, + "homepage": "https://github.com/night0721/cath#readme", + "dependencies": { + "@discordjs/opus": "^0.5.0", + "@reconlx/discord.js": "^1.1.101", + "axios": "^0.21.1", + "canvacord": "^5.2.0", + "canvas": "^2.8.0", + "cath": "^1.0.7", + "common-tags": "^1.8.0", + "connect-mongo": "^4.4.1", + "disco-oauth": "^5.1.0", + "discord-buttons": "^1.0.4", + "discord-canvas": "^1.4.1", + "discord-giveaways": "^4.5.1", + "discord-player": "^3.4.0", + "discord-rpc": "^3.2.0", + "discord-xp": "^1.1.14", + "discord-ytdl-core": "^5.0.3", + "discord.js": "github:reconlx/discord.js", + "ejs": "^3.1.6", + "express": "^4.17.1", + "express-session": "^1.17.2", + "ffmpeg": "0.0.4", + "ffmpeg-static": "^4.3.0", + "goosecache": "^9.0.14", + "imageapi.js": "^1.7.0", + "leven": "^3.1.0", + "lyrics-finder": "^21.7.0", + "method-override": "^3.0.0", + "moment": "^2.29.1", + "moment-timezone": "^0.5.33", + "mongoose": "^5.12.11", + "ms": "^2.1.3", + "node-superfetch": "^0.1.11", + "opusscript": "0.0.8", + "passport": "^0.4.1", + "passport-discord": "^0.1.4", + "path": "^0.12.7", + "pug": "^3.0.2", + "quick.db": "^7.1.3", + "quickchart-js": "^1.0.7", + "reconlx": "^1.2.41", + "soundcloud-downloader": "^0.2.4", + "weky": "^1.4.2", + "yt-search": "^2.8.0", + "ytdl-core": "^4.8.0", + "ytdl-core-discord": "^1.3.0", + "ytpl": "^2.2.1" + } +} diff --git a/util/Data/giveaways.json b/util/Data/giveaways.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/util/Data/giveaways.json @@ -0,0 +1 @@ +[] diff --git a/util/Data/rank.js b/util/Data/rank.js new file mode 100644 index 0000000..6dbd072 --- /dev/null +++ b/util/Data/rank.js @@ -0,0 +1,51 @@ +const { MessageAttachment } = require("discord.js"); +const Levels = require("discord-xp"); +const canvacord = require("canvacord"); +const error = require("../util/err"); +require("../inlinereply"); +module.exports = { + name: "rank", + description: "Shows the current level and rank of the user!", + usage: "{@User/User ID}", + timeout: 5000, + run: async (client, message, args) => { + const p = await client.prefix(message); + if (!message.guild) return; + if (message.author.bot) return; + const target = + message.mentions.users.first() || + message.guild.members.cache.find( + r => r.user.username.toLowerCase() === args[0].toLocaleLowerCase() + ) || + message.guild.members.cache.find( + r => r.displayName.toLowerCase() === args[0].toLocaleLowerCase() + ) || + message.guild.members.cache.get(args[0]) || + message.author; + const user = await Levels.fetch(target.id, message.guild.id, true); + if (!user) + return error( + message, + message.author, + p, + "rank", + "**{@User/User ID}**", + `'User' doesn't have any XP` + ); + const neededXp = Levels.xpFor(parseInt(user.level) + 1); + const Rank = new canvacord.Rank() + .setAvatar(target.displayAvatarURL({ dynamic: false, format: "png" })) + .setCurrentXP(user.xp) + .setRank(parseInt(user.position)) + .setLevel(user.level) + .setRequiredXP(neededXp) + .setStatus(target.presence.status) + .setProgressBar("BLACK", "COLOR") + .setUsername(target.username) + .setDiscriminator(target.discriminator); + Rank.build().then(data => { + const attachment = new MessageAttachment(data, "RankCard.png"); + message.inlineReply(attachment); + }); + }, +}; diff --git a/util/Data/triggered.js b/util/Data/triggered.js new file mode 100644 index 0000000..45a75d6 --- /dev/null +++ b/util/Data/triggered.js @@ -0,0 +1,23 @@ +const { Canvas } = require('canvacord') +const { Client, Message, MessageAttachment } = require('discord.js') +module.exports = { + name: 'trigger', + aliases: ['triggered'], + usage: '(?@User/ User ID)', + description: "Have a trigger effect on a user's avatar", + /** + * @param {Client} client + * @param {Message} message + * @param {String[]} args + */ + run: async(client, message, args) => { + const user = message.mentions.users.first() || message.guild.members.cache.get(args[0]) || message.author + const ava = user.displayAvatarURL({ format: 'png' }) + + const imga = await Canvas.trigger(ava) + + message.channel.send( + new MessageAttachment(imga, 'imgae.gif') + ) + } +} \ No newline at end of file diff --git a/util/command-handler.js b/util/command-handler.js new file mode 100644 index 0000000..e4a09ab --- /dev/null +++ b/util/command-handler.js @@ -0,0 +1,44 @@ +const { readdirSync } = require("fs"); +module.exports = client => { + readdirSync("./commands/").forEach(dir => { + const commands = readdirSync(`./commands/${dir}/`).filter(file => + file.endsWith(".js") + ); + for (let file of commands) { + let pull = require(`../commands/${dir}/${file}`); + if (pull.name) { + client.commands.set(pull.name, pull); + } else { + continue; + } + if (pull.aliases && Array.isArray(pull.aliases)) + pull.aliases.forEach(alias => client.aliases.set(alias, pull.name)); + } + }); + readdirSync("./cat/").forEach(dir => { + const commands = readdirSync(`./cat/${dir}/`).filter(file => + file.endsWith(".js") + ); + for (let file of commands) { + let pull = require(`../cat/${dir}/${file}`); + if (pull.name) { + client.hide.set(pull.name, pull); + } else { + continue; + } + } + }); + readdirSync("./events/").forEach(file => { + const events = readdirSync("./events/").filter(file => + file.endsWith(".js") + ); + for (let file of events) { + let pull = require(`../events/${file}`); + if (pull) { + client.events.set(file, file); + } else { + continue; + } + } + }); +}; diff --git a/util/err.js b/util/err.js new file mode 100644 index 0000000..5471936 --- /dev/null +++ b/util/err.js @@ -0,0 +1,207 @@ +const { MessageEmbed } = require("discord.js"); +const client = require("../index"); +require("../inlinereply.js"); +/** + * @param {String} message + * @param {String} dir + * @param {String} file + * @param {String} err + */ +module.exports = async (message, dir, file, err) => { + switch (err) { + case 101: + err = "Invalid argument"; + break; + case 0: + err = "Missing argument"; + break; + case 1: + err = "Missing 'User' argument"; + break; + case 2: + err = "'User' argument can't be author"; + break; + case 3: + err = "Missing 'Role' argument"; + break; + case 4: + err = "Missing 'Message' argument"; + break; + case 5: + err = "Missing 'Number' argument"; + break; + case 6: + err = "Missing permission"; + break; + case 7: + err = "Invalid number"; + break; + case 8: + err = "User doesn't have enough hierarchy"; + break; + case 9: + err = "Bot doesn't have enough hierarchy"; + break; + case 10: + err = "There isn't any data"; + break; + case 11: + err = "Missing 'Emoji' argument"; + break; + case 12: + err = "Missing 'Text' argument"; + break; + case 13: + err = "'Text' argument must be less than or equal to 100"; + break; + case 14: + err = "The maximum of modmail choices is 5"; + break; + case 15: + err = "Emoji can't be found"; + break; + case 16: + err = "'Time' argument must be larger than 1 second"; + break; + case 17: + err = "Missing 'Command'/'Category' argument"; + break; + case 18: + err = "'Command'/'Category' is already disabled"; + break; + case 19: + err = "Missing 'Time' argument"; + break; + case 20: + err = "Insufficient balance"; + break; + case 21: + err = "Missing 'Item' argument"; + break; + case 22: + err = "Invalid Item"; + break; + case 23: + err = "You didn't have enough item to gift"; + break; + case 24: + err = "Item invalid or you don't have that item"; + break; + case 25: + err = "Inventory is empty"; + break; + case 26: + err = "Giveaway not found"; + break; + case 27: + err = "Missing 'Message ID' argument"; + break; + case 28: + err = "Missing 'Channel' argument"; + break; + case 29: + err = "'Time' argument is invalid"; + break; + case 30: + err = "Missing 'Winners' argument"; + break; + case 31: + err = "'Winner' argument must be a number"; + break; + case 32: + err = "Missing 'Prize' argument"; + break; + case 33: + err = "You cannot hug yourself"; + break; + case 34: + err = "There isn't any song playing in the server currently"; + break; + case 35: + err = "You must be in a voice channel"; + break; + case 36: + err = "The player has stopped and the queue has been cleared"; + break; + case 37: + err = "There is no queue"; + break; + case 38: + err = "Can't find the playlist at YouTube"; + break; + case 39: + err = "Can't join the voice channel"; + break; + case 40: + err = "Left the voice channel since there is no song at the queue"; + break; + case 41: + err = "I am not in a voice channel"; + break; + case 42: + err = "I can't find this song/video"; + break; + case 43: + err = "I can't find the song at SoundCloud"; + break; + case 44: + err = "I can't find the song at YouTube"; + break; + case 45: + err = "Invalid selection"; + break; + case 46: + err = "Missing 'Prefix' argument"; + break; + case 47: + err = "Missing 'Command' argument"; + break; + case 48: + err = "The attachment must be an image"; + break; + case 49: + err = "'Emoji' name must be more than 2 characters"; + break; + case 50: + err = + "The error maybe the link isn't a image, or the image size is too big"; + break; + case 404: + err = "Error 404 - Not Found"; + break; + case 505: + err = "You have reached the maximum number of premium servers"; + break; + case 506: + err = "This server is already premium"; + break; + case 999: + err = "An unexpected error occured. Please try again."; + break; + default: + "Missing argument"; + break; + } + const pull = require(`../commands/${dir}/${file}`); + let pre = await client.prefix(message); + let embed = new MessageEmbed() + .setAuthor( + `Error from ${message.author.tag}`, + message.author.displayAvatarURL({ dynamic: true }) + ) + .setColor("RED") + .setDescription( + `${require("../config.json").ca}\nUse \`${pre}help ${ + pull.name + }\` to get help\n \n ` + ) + .addField( + `**>Usage**: ${pre}${pull.name} ${pull.usage ? pull.usage : ""}`, + `\`${err}\`` + ) + .setTimestamp() + .setThumbnail(client.user.displayAvatarURL({ dynamic: false })) + .setURL(client.web) + .setFooter(`Made by ${client.author}`); + message.inlineReply(embed).then(msg => msg.delete({ timeout: 10000 })); +}; diff --git a/util/functions/common.js b/util/functions/common.js new file mode 100644 index 0000000..082fa17 --- /dev/null +++ b/util/functions/common.js @@ -0,0 +1,767 @@ +const data = require("../Data/data.json"); +const guns = data.cguns; +const QuickChart = require("quickchart-js"); +const nmDt = require("../Data/aliases.json"); +var weaponActualName = nmDt.weaponActualName; +var weaponAlliasName = nmDt.weaponAlliasName; +Object.defineProperty(String.prototype, "Simplify", { + value: function Simplify() { + return this.toLowerCase().replace(/[^0-9a-z]/g, ""); + }, + writable: true, + configurable: true, +}); + +Object.defineProperty(Number.prototype, "IsPositive", { + value: function IsPositive() { + if (this > 0) { + return true; + } + return false; + }, + writable: true, + configurable: true, +}); + +Object.defineProperty(Number.prototype, "IsNegative", { + value: function IsNegative() { + if (this < 0) { + return true; + } + return false; + }, + writable: true, + configurable: true, +}); + +Object.defineProperty(Number.prototype, "ToBool", { + value: function ToBool() { + if (this == 1) { + return true; + } + return false; + }, + writable: true, + configurable: true, +}); + +Object.defineProperty(Number.prototype, "PlusHL", { + value: function PlusHL() { + if (this.toString()[0] == "-") { + return parseFloat(this.toFixed(2)).toString(); + } + return "+" + parseFloat(this.toFixed(2)).toString(); + }, + writable: true, + configurable: true, +}); + +function weaponIdentifier(inpmsg) { + var inpWeaponName = isolator(inpmsg)[0]; + if (inpWeaponName.length < 2) { + return inpmsg + ? "The name `" + inpmsg + "` is too short." + : "Empty weapon name"; + } + var probableWeapons = []; + for (let i = 0; i < guns.length; i++) { + if (inpWeaponName.Simplify() == guns[i].gunname.Simplify()) { + return guns[i]; + } else if (guns[i].gunname.Simplify().includes(inpWeaponName.Simplify())) { + probableWeapons.push(i); + } + } + + if (probableWeapons.length == 1) { + return guns[probableWeapons[0]]; + } + + for (let i = 0; i < weaponAlliasName.length; i++) { + for (let j = 0; j < weaponAlliasName[i].length; j++) { + /*if (weaponAlliasName[i][j].Simplify().includes(inpWeaponName.Simplify())) { + for (let i2 = 0; i2 < guns.length; i2++) { + if (weaponActualName[i].Simplify() == guns[i2].gunname.Simplify()) { + probableWeapons.push(i2); + } + } + }*/ + if (weaponAlliasName[i][j].Simplify() == inpWeaponName.Simplify()) { + for (let i2 = 0; i2 < guns.length; i2++) { + if (weaponActualName[i].Simplify() == guns[i2].gunname.Simplify()) { + return guns[i2]; + } + } + } + } + } + probableWeapons = [...new Set(probableWeapons)]; + if (probableWeapons.length == 1) { + return guns[probableWeapons[0]]; + } + if (probableWeapons.length > 1) { + return ( + "Did you mean `" + + probableWeapons + .map(x => guns[x].gunname) + .reduce((out, x, i) => + [out, x].join(i === probableWeapons.length - 1 ? "` or `" : "`, `") + ) + + "`?" + ); + } + return "Couldn't identify the weapon: `" + '"' + inpWeaponName + '"`'; +} + +function isolator(inpmsg) { + if (inpmsg.includes(" + ")) { + var out = inpmsg + .split(" + ") + .map(x => x.split("+")) + .flat(); + return [out.shift(), out.join(", ")]; + } + return inpmsg.split(" with "); +} + +function hasAttachments(inpmsg) { + if ( + inpmsg.split(" with ").filter(x => x.Simplify()).length > 1 || + inpmsg.split(" + ").filter(x => x.Simplify()).length > 1 + ) { + return true; + } + return false; +} + +function attachmentsIdentifier(inpmsg, attachmentsData) { + var inpmsg1 = inpmsg, + inpmsg3 = inpmsg.split(" ").filter(x => x), + inpmsg2 = inpmsg3.shift().toLowerCase(), + inpmsg5 = inpmsg3.join(" "); + inpmsg = + inpmsg2 == "akim" || inpmsg2 == "akimbo" + ? inpmsg5 + (hasAttachments(inpmsg) ? " + " : ", ") + "akimbo" + : inpmsg; + /*var replacer = [ + 'Stopping Power', + 'Laser' + ].map(x => x.Simplify()); + + var replacee = [ + ['SP'], + ['Lazer'] + ].map(x => x.Simplify()); + replacee.map(x => x.filter(y => inpmsg.includes(y)));*/ + //console.log(inpmsg); + /*console.log(JSON.stringify(inpmsg)); + var g1 = []; + g1 = inpmsg.split(/ with | + /); + console.log(JSON.stringify(g1)); + var givenAttachmentsNames = g1.split(/ & | , /);*/ + + if (!hasAttachments(inpmsg)) { + return []; + } + + var inputAttachmentsNames = isolator(inpmsg)[1] + .split(/ & |, |,| and /) + .filter(x => x); + var tooSmall = inputAttachmentsNames.filter(x => x.length < 3); + inputAttachmentsNames = inputAttachmentsNames.filter(x => !(x.length < 3)); + var errorMsgs = "", + errors = [], + unidentifined = []; + + if (inputAttachmentsNames.length == 00) { + errorMsgs += "\nAttachments are missing!\n"; + } + if (inputAttachmentsNames.length >= 10) { + return "Cocaineeeeee"; + } + + var splitAttachmentsDataName = [], + outAttachments = []; + + for (let i = 0; i < attachmentsData.length; i++) { + splitAttachmentsDataName.push([ + ...new Set( + attachmentsData[i].name + .split(" ") + .filter(x => x) + .map(x => x.trim()) + ), + ]); + if (Math.max(...splitAttachmentsDataName.map(x => x.length)) > 6) { + return "Cocaineeeeee"; + } + for (let j = 0; j < splitAttachmentsDataName[i].length; j++) { + splitAttachmentsDataName[i][j] = + splitAttachmentsDataName[i][j].Simplify(); + } + } + + for (let i = 0; i < inputAttachmentsNames.length; i++) { + var probables = []; + var splitInputAttachmentsName = inputAttachmentsNames[i].split(" "); + + for (let j = 0; j < splitAttachmentsDataName.length; j++) { + for (let i2 = 0; i2 < splitAttachmentsDataName[j].length; i2++) { + for (let i3 = 0; i3 < splitInputAttachmentsName.length; i3++) { + if ( + splitAttachmentsDataName[j][i2].includes( + splitInputAttachmentsName[i3].Simplify() + ) + ) { + var probablePushed = false; + for (let i4 = 0; i4 < probables.length; i4++) { + if (!probables[i4].includes(j)) { + probables[i4].push(j); + probablePushed = true; + break; + } + } + if (!probablePushed) { + probables.push([j]); + } + } + } + } + } + if (probables.length == 0) { + unidentifined.push(inputAttachmentsNames[i]); + continue; + } + + var curr = probables[probables.length - 1]; + var temp1 = probables[probables.length - 1].filter( + x => + attachmentsData[x].name.Simplify() == + inputAttachmentsNames[i].Simplify() + ); + var temp2 = probables[probables.length - 1].filter( + x => + splitAttachmentsDataName[x].length == splitInputAttachmentsName.length + ); + if (temp1.length === 1 && temp2.length !== 1) { + probables.push([temp1]); + } + if (temp1.length !== 1 && temp2.length === 1) { + probables.push([temp2]); + } + if (temp1.length === 1 && temp2.length === 1 && temp1[0] == temp2[0]) { + probables.push([temp1]); + } + //console.log(probables[probables.length - 1].length); + if ( + probables[probables.length - 1].length != 1 || + probables.length < splitInputAttachmentsName.length + ) { + //errors.push(probables[probables.length - 1]); + errors.push( + "`" + + curr + .map(x => attachmentsData[x].name) + .reduce((out, x, i) => + [out, x].join(i === curr.length - 1 ? "` or `" : "`, `") + ) + + '` by `"' + + inputAttachmentsNames[i] + + '"`' + ); + } + outAttachments.push(attachmentsData[probables[probables.length - 1][0]]); + } + //console.log(JSON.stringify(errors)); + /*if (errors.length && unidentifined.length) { + return "Couldn't identify the attachment" + (unidentifined.length === 1 ? "" : "s") + ': `"' + unidentifined.join('"`, `"') + '"`\n\nDid you mean `' + errors.map((p, j) => p.map(x => attachmentsData[x].name).reduce((out, x, i) => [out, x].join(i === p.length - 1 ? '` or `' : '`, `')) + '` by `"' + inputAttachmentsNames[j + unidentifined.length] + '"`').join(";\n`") + "?"; + } + if (errors.length) { + //return "Did you mean " + errors.map((p, j) => p.map(x => attachmentsData[x].name).reduce((out, x, i) => [out, x].join(i === p.length - 1 ? '` or `' : '`, `')) + '` by `"' + inputAttachmentsNames[j] + '"`').join(";\n") + "?"; + return "\nDid you mean " + errors.join(";\n") + "?\n"; + } + if (unidentifined.length) { + return "\nCouldn't identify the attachment" + (unidentifined.length === 1 ? "" : "s") + ': `"' + unidentifined.join('"`, `"') + '"`\n'; + }*/ + + /*var sameAttachments = outAttachments.filter((x,i,a)=> a.indexOf(x)!==i); + if (sameAttachments.length) { + sameAttachments = [...sameAttachments, ...new Set(sameAttachments.map((x, i) => outAttachments.indexOf(x)))]; + } + inputAttachmentsNames.filter();*/ + + var t1 = outAttachments.map(x => x.effects[35]); + var t2 = outAttachments.map(x => x.effects[36] + x.effects[32]); + + errorMsgs += + t1.indexOf(1) !== -1 + ? "Can't equip Muzzle with `" + + '"' + + outAttachments[t1.indexOf(1)].name + + '"`' + : ""; + errorMsgs += + t2.indexOf(1) !== -1 + ? "Can't equip Optics with `" + + '"' + + outAttachments[t2.indexOf(1)].name + + '"`' + : ""; + errorMsgs += errors.length + ? "\nDid you mean " + errors.join(";\n") + "?\n" + : ""; + errorMsgs += unidentifined.length + ? "\nCouldn't identify the attachment" + + (unidentifined.length === 1 ? "" : "s") + + ': `"' + + unidentifined.join('"`, `"') + + '"`\n' + : ""; + errorMsgs += + outAttachments.length > 5 ? "\nCan't equip more than 5 attachments!\n" : ""; + errorMsgs += outAttachments.filter((x, i, a) => a.indexOf(x) !== i).length + ? "\nMultiple of same attachments found!\n" + : ""; + errorMsgs += outAttachments + .map(x => x.type) + .filter((x, i, a) => a.indexOf(x) !== i).length + ? "\nMultiple of attachments the same type found!\n" + : ""; + errorMsgs += tooSmall.length + ? "\nThe name" + + (tooSmall.length === 1 ? "" : "s") + + ': `"' + + tooSmall.reduce((out, x, i) => + [out, x].join(i === curr.length - 1 ? '"` and `"' : '"`, `"') + ) + + '"` ' + + (tooSmall.length === 1 ? "is" : "are") + + " too short\n" + : ""; + + return errorMsgs ? errorMsgs.trim() : outAttachments; +} +//console.log(attachmentsIdentifier("ak with mag, red sight, red dot, ll", data.cguns[0].aments));// makeError(); +//console.log(attachmentsIdentifier("ak with mdfgt, skjs", data.cguns[0].aments)); makeError(); +//console.log(attachmentsIdentifier("117 + 40 round mag", data.cguns[0].aments)); makeError(); +//console.log(attachmentsIdentifier("117 + rtc muzzle brake, rubberized griptape, tac lazer sight, 40 round mag, no stock", data.cguns[1].aments)); makeError(); + +function damageHandler( + currDmgs, + currRngs, + damageMulti, + hp, + tbs, + tbb, + bib, + pellets +) { + //console.log([currDmgs, currRngs, damageMulti, hp, tbs, tbb, bib, pellets]); + //tbs = timeBetweenShots + //tbb = timeBetweenBurst + //bib = bulletsInBurst + + currRngs = currRngs.filter(x => x < 100).map(x => Math.round(x)); + currDmgs.length = currRngs.length + 1; + currDmgs = currDmgs.map(x => Math.round(x * damageMulti)); + var currSTKs = currDmgs.map(x => stk(x)), + currTTKs = currDmgs.map(x => ttk(x)), + currPDmg = null, + n = Math.max(...currTTKs.map(x => x.toString().length)); + n = n < 3 ? 3 : n; + //console.log() + function worker1(inp) { + return inp.map(x => x.toString().padStart(n)).join(" -- ") + "\n"; + } + function worker2(inp) { + return ( + "".padStart(n + 1) + + inp.map(x => x.toString().padStart(2)).join("".padStart(n + 2)) + + "\n" + ); + } + function stk(dmg) { + var out; + if (!pellets) { + out = Math.ceil(hp / dmg); + } else { + out = Math.ceil(hp / (dmg * pellets)); + } + out = out == Infinity ? "∞" : out; + return out; + } + function ttk(dmg) { + var stkVal = stk(dmg); + if (stkVal == "∞") { + return stkVal; + } + if (!bib) { + return Math.round((stkVal - 1) * tbs); + } + var out = 0; + if (dmg > 0) { + if (stkVal % bib == 0) { + for (var i = 0; i < Math.floor(stkVal / bib) - 1; i++) { + out += tbs * (bib - 1) + tbb; + } + out = out + tbs * (bib - 1); + } else if (stkVal % bib != 0) { + for (var i = 0; i <= Math.floor(stkVal / bib) - 1; i++) { + out += tbs * (bib - 1) + tbb; + } + for (var i = 0; i < (stkVal % bib) - 1; i++) { + out += tbs; + } + } + out = Math.round(out); + if (out == Infinity) { + return "∞"; + } + } else { + out = "No"; + } + return out; + } + if (pellets) { + currPDmg = currDmgs.map(x => x + " x" + pellets); + n = Math.max(...currPDmg.map(x => x.toString().length)); + } + return ( + "```Damage : " + + worker1(currPDmg || currDmgs) + + (pellets ? "Total : " + worker1(currDmgs.map(x => x * pellets)) : "") + + "STK : " + + worker1(currSTKs) + + "TTK : " + + worker1(currTTKs) + + "Range : " + + (currRngs.length ? worker2(currRngs) : worker1(["∞"])) + + "```" + ); +} +//console.log(damageHandler([30, 25, 20], [10, 20], 1, 100, 60000 / 720, 0, 0)); makeError(); +//console.log(damageHandler([ 33, 23 ], [ 39 ], 1, 100, 109.0909090909091, 0, 0 )); makeError(); + +function recoilHandler( + xRecoil, + yRecoil, + xMultiplier, + yMultiplier, + bulletCount +) { + if (xRecoil.length != yRecoil.length) { + return "err"; + } + var recoilLength = xRecoil.length; + if (recoilLength == 0) { + return "none"; + } + var recoilPattern = [ + { + x: 0, + y: 0, + }, + ]; + var recoilObj; + for (let i = 0; i < bulletCount; i++) { + var xContinuationVal = + xRecoil[recoilLength - 1] - xRecoil[recoilLength - 2]; + var yContinuationVal = + yRecoil[recoilLength - 1] - yRecoil[recoilLength - 2]; + if (i < recoilLength) { + recoilObj = { + x: xRecoil[i] * (1 + xMultiplier / 100), + y: yRecoil[i] * (1 + yMultiplier / 100), + }; + } else { + recoilObj = { + x: + (recoilPattern[recoilPattern.length - 1].x + xContinuationVal) * + xMultiplier, + y: + (recoilPattern[recoilPattern.length - 1].y + yContinuationVal) * + yMultiplier, + }; + } + recoilPattern.push(recoilObj); + } + var chart = new QuickChart(); + chart + .setConfig({ + type: "scatter", + data: { + datasets: [ + { + data: recoilPattern, + showLine: true, + fill: false, + borderColor: "rgba(0, 200, 0, 1)", + }, + ], + }, + options: { + /*plugins: { + backgroundImageUrl: 'https://www.codmdatabase.ml/display.png' + },*/ + legend: { + display: false, + }, + scales: { + yAxes: [ + { + ticks: { + display: false, + min: 0, + max: 5050, + }, + }, + ], + xAxes: [ + { + ticks: { + display: false, + min: -4495, + max: 4495, + }, + }, + ], + }, + }, + }) + .setWidth(1780) + .setHeight(1000); + + return chart; +} + +function updateStatswithEffects(inpEffects, inpStats) { + //console.log(inpStats.toString()); + var l = inpStats[18] / inpStats[17]; + var outStats = inpStats; + /*if (inpEffects[09] != 0) { inpStats[25] += inpEffects[09]; } + if (inpEffects[29] != 0) { inpStats[00] += inpEffects[29]; } + inpStats[17] += inpEffects[27];*/ + var inpStatsarr = [01, 02, 05, 10, 11, 14, 15, 20, 21, 22, 26, 27, 31]; + var inpEfecsarr = [17, 18, 16, 04, 19, 01, 10, 14, 14, 14, 06, 07, 42]; //Efecs is short for Effects + for (let i = 0; i < inpEffects.length; i++) { + if (inpEffects[inpEfecsarr[i]] != 0) { + outStats[inpStatsarr[i]] *= (inpEffects[inpEfecsarr[i]] + 100) / 100; + } + } + var inpStatsarr = [03, 04, 16, 28, 29, 30]; + var inpEfecsarr = [20, 38, 00, 39, 40, 41]; //Efecs is short for Effects + for (let i = 0; i < inpEffects.length; i++) { + if (inpEffects[inpEfecsarr[i]] != 0) { + outStats[inpStatsarr[i]] = inpEffects[inpEfecsarr[i]]; + } + } + var inpStatsarr = [00, 17, 25]; + var inpEfecsarr = [29, 27, 09]; //Efecs is short for Effects + for (let i = 0; i < inpEffects.length; i++) { + if (inpEffects[inpEfecsarr[i]] != 0) { + outStats[inpStatsarr[i]] += inpEffects[inpEfecsarr[i]]; + } + } + + if (inpEffects[43] != 0 && inpStats[08] != -1) { + outStats[08] *= (inpEffects[43] + 100) / 100; + } + if (inpEffects[16] != 0) { + outStats[07] *= inpEffects[16] / -100 + 1; + } + outStats[18] = inpStats[17] * l; + + outStats[25] = (inpStats[26] * inpStats[25]) / 100; //must occur after inpStats[26] + //no 06, 09, 12, 13, 19, 23, 24 + return outStats; +} + +function attachmentHandler(currEffects, currStats) { + //console.log(JSON.stringify(currEffects)); + var pos = [], + neg = []; + if (currEffects[0] > currStats[16]) { + pos.push( + currEffects[0] + + "% zoom (+" + + (currEffects[0] - currStats[16]) + + "% zoom)" + ); + } else if (currEffects[0] != 0 && currEffects[0] != currStats[16]) { + neg.push( + currEffects[0] + + "% zoom (-" + + (currStats[16] - currEffects[0]) + + "% zoom)" + ); + } + if (currEffects[0] != 0 && currStats[16] <= 110) { + pos.push("Easier to Aim"); + } + negGood1(01, "ADS time"); + negGood1(02, "Vertical Recoil"); + negGood1(03, "Horizontal Recoil"); + negGood1(04, "Bullet Spread"); + negGood1(05, "Moving Bullet Spread"); + posGood1(06, "Mobility"); + posGood1(07, "ADS Mobility"); + negGood1(08, "Recoil when Crouched or Prone"); + posGood1(09, "Sprint Mobility"); + negGood1(10, "Sprint to Fire Time"); + negGood1(11, "Flinch"); + negGood1(12, "Hipfire Spread"); + posGood1(13, "Damage Range"); + negGood1(14, "Reload Time"); + posGood1(15, "Headshot Damage"); + posGood1(16, "Rate of Fire"); + posGood1(17, "Detonation Range"); + posGood1(18, "Explosion Radius"); + negGood1(19, "Idle Sway"); + if (currEffects[20] > currStats[3]) { + pos.push( + currEffects[20].ToString().Replace(".", " ~ ") + " Explosion Damage" + ); + } else if (currEffects[20] != 0 && currEffects[20] != currStats[3]) { + neg.push( + currEffects[20].ToString().Replace(".", " ~ ") + " Explosion Damage" + ); + } + negGood3(21, "+Visible Laser when not ADS-ed"); + negGood3(22, "+Visible Laser when ADS-ed"); + negGood3(23, "+Visible Laser"); + posGood3(24, "+Silenced Gunfire"); + posGood3(25, "-Muzzle Flash"); + posGood3(26, "Reworked Damage"); + posGood2(27, "Rounds/Mag"); + posGood2(28, "Rounds/Tube"); + posGood2(29, "Pellets per Shot"); + posGood2(30, "Damage Over Time"); + posGood3(31, "Damage per Shot"); + posGood3(32, "Reworked ADS"); + posGood3(33, "-Melee QTE Time"); + if (currEffects[34] == 1) { + pos.push("+Damage per Pellet"); + } else if (currEffects[34] == -1) { + neg.push("-Damage per Pellet"); + } + negGood3(35, "Can Not use Muzzle"); + negGood3(36, "Can Not ADS"); + if (currEffects[37] != 0) { + pos.push("New Leathality Profile"); + } + if (currEffects[38] != 0 && currEffects[38] < currStats[4]) { + pos.push( + "Turns to " + + ["Full Auto", "Burst", "Semi Auto", "Pump Action", "Bolt Action"][ + currEffects[38] - 1 + ] + ); + } else if (currEffects[38] != 0 && currEffects[38] != currStats[4]) { + neg.push( + "Turns to " + + ["Full Auto", "Burst", "Semi Auto", "Pump Action", "Bolt Action"][ + currEffects[38] - 1 + ] + ); + } + posGood2(39, "Tick Damage"); + posGood2(40, "Ticks"); + negGood2(41, "ms Tick Interval"); + posGood2(42, "Breath Holding Time"); + posGood1(43, "Bullet Speed"); + if (currEffects[44] == 1) { + pos.push("+Penetraion Damage"); + } else if (currEffects[44] == -1) { + neg.push("-Penetraion Damage"); + } + posGood2(45, "Round" + (currEffects[45] - 1 ? "s" : "") + " in Reserve"); + + function posGood1(i, ext) { + if (currEffects[i].IsPositive()) { + pos.push(currEffects[i].PlusHL() + "% " + ext); + } else if (currEffects[i].IsNegative()) { + neg.push(currEffects[i].PlusHL() + "% " + ext); + } + } + + function negGood1(i, ext) { + if (currEffects[i].IsNegative()) { + pos.push(currEffects[i].PlusHL() + "% " + ext); + } else if (currEffects[i].IsPositive()) { + neg.push(currEffects[i].PlusHL() + "% " + ext); + } + } + + function posGood2(i, ext) { + if (currEffects[i].IsPositive()) { + pos.push(currEffects[i].PlusHL() + " " + ext); + } else if (currEffects[i].IsNegative()) { + neg.push(currEffects[i].PlusHL() + " " + ext); + } + } + + function negGood2(i, ext) { + if (currEffects[i].IsNegative()) { + pos.push(currEffects[i].PlusHL() + " " + ext); + } else if (currEffects[i].IsPositive()) { + neg.push(currEffects[i].PlusHL() + " " + ext); + } + } + + function posGood3(i, ext) { + if (currEffects[i].ToBool()) { + pos.push(ext); + } + } + + function negGood3(i, ext) { + if (currEffects[i].ToBool()) { + neg.push(ext); + } + } + return ( + "\nPositives :\n```ini\n[" + + pos.join("]\n[") + + "]```\nNegatives :\n```css\n[" + + neg.join("]\n[") + + "]\n```" + ); +} +/* +console.log("Full directory : " + __filename); +console.log("Current file : " + __filename.split("/").pop()); +console.log("Without extenstion : " + __filename.split("/").pop().split(".")[0]); +*/ + +function interpretioner(inpAttachments) { + return inpAttachments.length + ? " with " + inpAttachments.map(x => x.name).join(", ") + : ""; +} + +function totaler(inpAttachments) { + var totalEffects = inpAttachments[0].effects; + for (let j = 1; j < inpAttachments.length; j++) { + for (let i2 = 0; i2 < totalEffects.length; i2++) { + totalEffects[i2] += inpAttachments[j].effects[i2]; + } + } + return totalEffects; +} + +function makeError() { + var m; + m.split("L"); +} + +module.exports = { + weaponIdentifier, + attachmentsIdentifier, + recoilHandler, + attachmentHandler, + updateStatswithEffects, + makeError, + interpretioner, + damageHandler, + isolator, + totaler, +}; diff --git a/util/functions/function.js b/util/functions/function.js new file mode 100644 index 0000000..48eadbe --- /dev/null +++ b/util/functions/function.js @@ -0,0 +1,8 @@ +function rndint(max, min) { + return Math.floor(Math.random() * (max - (min ? min : 0))) + (min ? min : 0); +} +function random() { + const num = Math.floor(Math.random() * 2); + return num === 1; +} +module.exports = { rndint, random }; diff --git a/util/functions/mongoose.js b/util/functions/mongoose.js new file mode 100644 index 0000000..98c9237 --- /dev/null +++ b/util/functions/mongoose.js @@ -0,0 +1,475 @@ +const mongoose = require("mongoose"); +const { GooseCache } = require("goosecache"); +const cachegoose = new GooseCache(mongoose, { + engine: "memory", +}); +mongoose.set("useFindAndModify", false); +const u = require("../../models/users"); +const g = require("../../models/guilds"); +const Econ = require("../../models/econ"); +module.exports = { + /** + * @param {String} URI - Mongo Connection URI + */ + async connect(URI) { + if (!URI) throw new Error("Please provide a Mongoose URI"); + return mongoose.connect(URI, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + }, + /** + * @param {String} ID - Guild ID + */ + async getGuild(ID) { + if (!ID) throw new Error("Guild ID?"); + const guild = await g.findOne({ Guild: ID }).lean().cache(120); + if (!guild) { + const gg = new g({ Guild: ID }); + const { + Guild, + Prefix, + Welcome, + Goodbye, + Log, + Premium, + Category, + Commands, + } = gg; + await gg.save().catch(error => console.log(error)); + return { + Guild, + Prefix, + Welcome, + Goodbye, + Log, + Premium, + Category, + Commands, + }; + } else { + const Guild = guild.Guild; + const Prefix = guild.Prefix; + const Welcome = guild.Welcome; + const Goodbye = guild.Goodbye; + const Log = guild.Log; + const Premium = guild.Premium; + const Category = guild.Category; + const Commands = guild.Commands; + return { + Guild, + Prefix, + Welcome, + Goodbye, + Log, + Premium, + Category, + Commands, + }; + } + }, + /** + * @param {String} ID - User ID + */ + async getUser(ID) { + if (!ID) throw new Error("User ID?"); + const user = await u.findOne({ User: ID }).lean().cache(120); + if (!user) { + const ss = new u({ User: ID }); + const { + User, + AFK, + AFKDate, + Tier, + Premium, + Blacklist, + Blacklist_Reason, + PremiumServers, + } = ss; + await ss.save().catch(error => console.log(error)); + return { + User, + AFK, + AFKDate, + Tier, + Premium, + Blacklist, + Blacklist_Reason, + PremiumServers, + }; + } else { + const User = user.User; + const AFK = user.AFK; + const AFKDate = user.AFKDate; + const Tier = user.Tier; + const Premium = user.Premium; + const Blacklist = user.Blacklist; + const Blacklist_Reason = user.Blacklist_Reason; + const PremiumServers = user.PremiumServers; + return { + User, + AFK, + AFKDate, + Tier, + Premium, + Blacklist, + Blacklist_Reason, + PremiumServers, + }; + } + }, + /** + * @param {String} ID - User ID + * @param {String} Reason - AFK Reason + */ + async AFK(ID, Reason) { + if (!ID) throw new Error("User ID?"); + if (!Reason) throw new Error("AFK Reason?"); + const user = await u.findOne({ User: ID }); + if (!user) { + const sss = new u({ User: ID }); + await sss.save().catch(error => console.log(error)); + return { Reason, Time }; + } else { + user.User = ID; + user.AFK = Reason; + await user.save().catch(error => console.log(error)); + cachegoose.clearCache(); + return { Reason }; + } + }, + /** + * @param {String} ID - User ID + */ + async DelAFK(ID) { + if (!ID) throw new Error("User ID?"); + const user = await u.findOne({ User: ID }); + if (!user) { + const sssss = new u({ User: ID }); + await sssss.save().catch(error => console.log(error)); + return { ID }; + } else { + user.AFK = null; + user.AFKDate = null; + await user.save().catch(error => console.log(error)); + cachegoose.clearCache(); + return { ID }; + } + }, + /** + * @param {String} ID - ID of the User + * @param {String} Toggle - Blacklist Toggle(true/false) + * @param {String} Reason - Blacklist Reason + */ + async BK(ID, Toggle, Reason) { + if (!ID) throw new Error("User ID?"); + if (!Toggle) throw new Error("Blacklist Toggle?"); + if (!Reason) throw new Error("Blacklist Feason?"); + const user = await u.findOne({ User: ID }); + if (!user) { + const sus = new u({ User: ID }); + if (Toggle == "true") { + user.Blacklist = true; + user.Blacklist_Reason = Reason; + } else { + user.Blacklist = false; + user.Blacklist_Reason = null; + } + await sus.save().catch(error => console.log(error)); + cachegoose.clearCache(); + return { Reason }; + } else { + if (Toggle == "true") { + user.Blacklist = true; + user.Blacklist_Reason = Reason; + } else { + user.Blacklist = false; + user.Blacklist_Reason = null; + } + await user.save().catch(error => console.log(error)); + cachegoose.clearCache(); + return { Reason }; + } + }, + /** + * @param {String} ID - ID of the User + * @param {Boolean} Toggle - Premium Toggle(true/false) + * @param {Number} Tier - Tier + */ + async Premium(ID, Toggle, Tier) { + if (!ID) throw new Error("User ID?"); + if (!Toggle) throw new Error("Premium Toggle?"); + if (!Tier) throw new Error("Premium Feason?"); + const user = await u.findOne({ User: ID }); + if (!user) { + const sus = new u({ User: ID }); + if (Toggle == "true") { + user.Premium = true; + user.Tier = Tier; + } else { + user.Premium = false; + user.Tier = 0; + } + await sus.save().catch(error => console.log(error)); + cachegoose.clearCache(); + return { Tier }; + } else { + if (Toggle == "true") { + user.Premium = true; + user.Tier = Tier; + } else { + user.Premium = false; + user.Tier = 0; + } + await user.save().catch(error => console.log(error)); + cachegoose.clearCache(); + return { Tier }; + } + }, + /** + * @param {String} ID + */ + async CreateGuild(ID) { + await new g({ Guild: ID }); + return; + }, + /** + * @param {String} ID - Guild ID + */ + async DelGuild(ID) { + await g.deleteMany({ Guild: ID }); + return; + }, + /** + * @param {String} ID - User ID + * @param {String} Prefix - Guild Prefix + */ + async setPrefix(ID, Prefix) { + if (!ID) throw new Error("Guild ID?"); + if (!Prefix) throw new Error("Prefix?"); + const guild = await g.findOne({ Guild: ID }); + if (!guild) { + const newU = new g({ Guild: ID }); + await newU.save().catch(error => console.log(error)); + return { Prefix }; + } + guild.Prefix = Prefix; + await guild.save().catch(error => console.log(error)); + cachegoose.clearCache(); + return { Prefix }; + }, + /** + * @param {String} ID - Guild ID + * @param {String} Channel - Welcome Channel + */ + async setWelcome(ID, Channel) { + if (!ID) throw new Error("Guild ID?"); + if (!Channel) throw new Error("Channel?"); + const guild = await g.findOne({ Guild: ID }); + if (!guild) { + const newU = new g({ Guild: ID }); + await newU.save().catch(error => console.log(error)); + return { Channel }; + } + guild.Welcome = Channel; + await guild.save().catch(error => console.log(error)); + cachegoose.clearCache(); + return { Channel }; + }, + /** + * @param {String} ID - Guild ID + * @param {String} Channel - Goodbye Channel + */ + async setGoodbye(ID, Channel) { + if (!ID) throw new Error("Guild ID?"); + if (!Channel) throw new Error("Channel?"); + const guild = await g.findOne({ Guild: ID }); + if (!guild) { + const newU = new g({ Guild: ID }); + await newU.save().catch(error => console.log(error)); + return { Channel }; + } + guild.Goodbye = Channel; + await guild.save().catch(error => console.log(error)); + cachegoose.clearCache(); + return { Channel }; + }, + /** + * @param {String} ID - Guild ID + * @param {String} Channel - Log Channel + */ + async setLog(ID, Channel) { + if (!ID) throw new Error("Guild ID?"); + if (!Channel) throw new Error("Channel?"); + const guild = await g.findOne({ Guild: ID }); + if (!guild) { + const newU = new g({ Guild: ID }); + await newU.save().catch(error => console.log(error)); + return { Channel }; + } + guild.Log = Channel; + await guild.save().catch(error => console.log(error)); + cachegoose.clearCache(); + return { Channel }; + }, + /** + * @param {String} ID - Guild ID + * @param {String} Toggle - premium Toggle + */ + async setPremium(ID, Toggle) { + if (!ID) throw new Error("Please Provide a Guild ID"); + if (!Toggle) throw new Error("Please Provide a Toggle!"); + const guild = await g.findOne({ Guild: ID }); + if (!guild) { + const newU = new g({ Guild: ID }); + if (Toggle == "true") { + guild.Premium = true; + } else { + guild.Premium = false; + } + await newU.save().catch(error => console.log(error)); + return; + } else { + if (Toggle == "true") { + guild.Premium = true; + } else { + guild.Premium = false; + } + } + await guild.save().catch(error => console.log(error)); + cachegoose.clearCache(); + return; + }, + /** + * @param {String} User - User ID + * @param {String} ID - Guild ID + * @param {String} Method - Method + */ + async pushGuild(User, ID, method) { + if (!method) return new Error("Method?"); + u.findOne({ User: User }, async (err, data) => { + if (err) throw err; + if (!data) return new Error("User not found"); + if (method === "push") { + await data.PremiumServers.push(ID); + await data.save().catch(error => console.log(error)); + data.save(); + } + if (method === "splice") { + const index = data.PremiumServers.indexOf(ID); + data.PremiumServers.splice(index, 1); + data.save(); + } + cachegoose.clearCache(); + return { User }; + }); + }, + /** + * @param {String} ID - Guild ID + * @param {String} Type - Type + * @param {String} Name - Name + */ + async disable(ID, Type, Name) { + if (!Name) throw new Error("Name?"); + if (!Type) throw new Error("Type?"); + if (!ID) throw new Error("Guild ID?"); + if (Type === "category") { + const db = await g.findOne({ Guild: ID }); + if (!db) { + const newdoc = await new g({ Guild: ID }); + await newdoc.save().catch(error => console.log(error)); + } + await db.Category.push(Name); + await db.save().catch(e => console.log(e)); + } + if (Type === "command") { + const db = await g.findOne({ Guild: ID }); + if (!db) { + const newdoc = await new g({ Guild: ID }); + await newdoc.save().catch(error => console.log(error)); + } + await db.Commands.push(Name); + await db.save().catch(e => console.log(e)); + } + cachegoose.clearCache(); + return { Name }; + }, + /** + * @param {String} ID - Guild ID + * @param {String} Type - Type + * @param {String} Name - Name + */ + async enable(ID, Type, Name) { + if (!ID) throw new Error("Guild ID?"); + if (!Name) throw new Error("Name?"); + if (!Type) throw new Error("Type?"); + if (Type === "category") { + const db = await g.findOne({ Guild: ID }); + if (!db) { + return false; + } + const index = db.Category.indexOf(Name.toLowerCase()); + await db.Category.splice(index, 1); + await db.save().catch(e => console.log(e)); + } + if (Type === "command") { + const db = await g.findOne({ Guild: ID }); + if (!db) { + return false; + } + const index = db.Commands.indexOf(Name); + await db.Commands.splice(index, 1); + await db.save().catch(e => console.log(e)); + } + cachegoose.clearCache(); + return true; + }, + // /** + // * @param {String} ID - User ID + // */ + // async bal(ID) { + // new Promise(async ful => { + // const data = await Econ.findOne({ User: ID }); + // if (!data) return ful(0); + // ful(data.CP); + // }); + // }, + /** + * @param {String} ID - User ID + */ + async bal(ID) { + const data = await Econ.findOne({ User: ID }); + if (!data) return 0; + else return data.CP; + }, + /** + * @param {String} ID - User ID + * @param {Number} CP - Number + */ + async add(ID, CP) { + Econ.findOne({ User: ID }, async (err, data) => { + if (err) throw err; + if (data) { + data.CP += CP; + } else { + data = new Econ({ User: ID, CP }); + } + await data.save(); + }); + }, + /** + * @param {String} ID - User ID + * @param {Number} CP - Number + */ + async rmv(ID, CP) { + Econ.findOne({ User: ID }, async (err, data) => { + if (err) throw err; + if (data) { + data.CP -= CP; + } else { + data = new Econ({ User: ID, CP: -CP }); + } + await data.save(); + }); + }, +}; diff --git a/util/item.js b/util/item.js new file mode 100644 index 0000000..1d4a093 --- /dev/null +++ b/util/item.js @@ -0,0 +1,68 @@ +module.exports = [ + { + item: "<:na45:829965262739996672> NA-45", + alias: "na45", + id: "na45", + price: 10000, + }, + { + item: "<:50gs:829965044703559690> Akimbo .50 GS", + alias: ".50gs", + id: ".50gs", + price: 10000, + }, + { + item: "<:mantaray:815149866489610281> Manta Ray", + alias: "mantaray", + id: "mantaray", + price: 50000, + }, + { + item: "<:zer0:827143771329921034> Zero", + alias: "zero", + id: "zero", + price: 50000, + }, + { + item: "<:artery:827143979727978496> Artery", + alias: "artery", + id: "artery", + price: 50000, + }, + { + item: "<:alias:827143908084547626> Alias", + alias: "alias", + id: "alias", + price: 50000, + }, + { + item: "<:urban:827143838258692097> Urban Tracker", + alias: "urban", + id: "urban", + price: 50000, + }, + { + item: "<:scylla:838676436402700331> Scylla", + alias: "scylla", + id: "scylla", + price: 50000, + }, + { + item: "<:parkk:838677177024905216> Park", + alias: "park", + id: "park", + price: 50000, + }, + { + item: "<:mara:838676389120442398> Mara", + alias: "mara", + id: "mara", + price: 50000, + }, + { + item: "<:outrider:838676881720475658> Outrider", + alias: "outrider", + id: "outrider", + price: 50000, + }, +]; diff --git a/util/pagify.js b/util/pagify.js new file mode 100644 index 0000000..7a3daf8 --- /dev/null +++ b/util/pagify.js @@ -0,0 +1,119 @@ +const Discord = require('discord.js') + +async function pagify(client, message, options = {}) { + + if (!(message instanceof Discord.Message)) + throw new TypeError( + "First parameter must be a type of .Message" + ); + options = { + page: options.page, + type: ["message", "embed"].includes( + options.type && options.type.toString().toLowerCase() + ) + ? options.type + : "message", + messages: Array.isArray(options.messages) ? options.messages : [], + pages: options.pages || true + }; + if (!options.messages.length) + throw new TypeError("'options.messages' must have at least one element"); + if ( + options.type === "embed" && + !options.messages.every(m => m instanceof Discord.MessageEmbed) + ) + throw new TypeError( + "'options.type' were chosen as 'embed' but not every element of 'options.messages' were an instance of .MessageEmbed" + ); + let pages = 0, + reactions = + options.messages.length > 1 + ? ["⏪", "◀️", "#️⃣", "▶️", "⏩", "⏹️"] + : ["⏹️"], + mainMessage = await message.channel.send( + `${options.messages.length > 1 && options.pages === true + ? `[${pages + 1}/${options.messages.length}] ${"○" + .repeat(options.messages.length) + .replaceAt(pages, "●")}` + : "" + }`, + options.messages[pages] + ); + await Promise.all(reactions.map(r => mainMessage.react(r))); + let collector = mainMessage.createReactionCollector( + (reaction, user) => + reactions.some(r => r === reaction.emoji.name) && + user.id === message.author.id, + { + time: options.time + } + ); + collector.on("collect", async (reaction, user) => { + switch (reaction.emoji.name) { + case "⏪": + if (pages === 0) return; + pages = 0; + break; + case "◀️": + if (pages === 0) { + pages = options.messages.length - 1; + } else { + pages -= 1; + } + break; + case "⏹️": + for (let reaction of mainMessage.reactions.cache + .filter(r => r.users.cache.has(clinet.user.id)) + .array()) { + await reaction.users.remove(client.user.id); + } + return collector.stop(); + break; + case "▶️": + if (pages === options.messages.length - 1) { + pages = 0; + } else { + pages += 1; + } + break; + case "⏩": + if (pages === options.messages.length - 1) return; + pages = options.messages.length - 1; + break; + case "#️⃣": + let m = await message.channel.send("What page do you wish to go to?"); + let collected = await m.channel.awaitMessages( + response => message.content, + { + max: 1, + errors: ["time"] + } + ); + try { + m.delete(); + let content = parseInt(collected.first().content); + if (content && content > 0 && content <= options.messages.length) + pages = content - 1; + } catch (err) { + console.log(err.message); + m.delete(); + } + + break; + } + await mainMessage.edit( + `${options.messages.length > 1 && options.pages === true + ? `[${pages + 1}/${options.messages.length}] ${"○" + .repeat(options.messages.length) + .replaceAt(pages, "●")}` + : "" + }`, + options.type === "message" + ? options.messages[pages] + : { + embed: options.messages[pages] + } + ); + }) +} +module.exports = pagify \ No newline at end of file diff --git a/util/pagination.js b/util/pagination.js new file mode 100644 index 0000000..c4d4001 --- /dev/null +++ b/util/pagination.js @@ -0,0 +1,55 @@ +const { MessageEmbed, Permissions } = require("discord.js"); + +module.exports = class Util { + static chunk(arr, size) { + const temp = []; + for (let i = 0; i < arr.length; i += size) { + temp.push(arr.slice(i, i + size)); + } + return temp; + } + + static get paginationEmojis() { + return ["◀", "⛔", "▶"]; + } + + static async pagination(msg, author, contents, init = true, currPage = 0) { + if (init) for (const emoji of this.paginationEmojis) await msg.react(emoji); + + const collector = msg.createReactionCollector( + (reaction, user) => { + return ( + this.paginationEmojis.includes(reaction.emoji.name) && + user.id === author.id + ); + }, + { + max: 1, + time: 90000, + } + ); + + collector + .on("collect", reaction => { + reaction.users.remove(author); + + const emoji = reaction.emoji.name; + if (emoji === this.paginationEmojis[0]) currPage--; + if (emoji === this.paginationEmojis[1]) return collector.stop(); + if (emoji === this.paginationEmojis[2]) currPage++; + currPage = + ((currPage % contents.length) + contents.length) % contents.length; + + const embed = msg.embeds[0] + .setDescription(contents[currPage]) + .setFooter(`Page ${currPage + 1} of ${contents.length}.`); + + msg.edit(embed); + + this.pagination(msg, author, contents, false, currPage); + }) + .on("end", (_, reason) => { + if (["time", "user"].includes(reason)) msg.reactions.removeAll(); + }); + } +};