diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..525c1ac --- /dev/null +++ b/.eslintignore @@ -0,0 +1,7 @@ +example/ +node_modules/ +dist/ +.github/ +docs/ + +*.d.ts \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..d752175 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,22 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "env": { + "node": true + }, + "plugins": [ + "@typescript-eslint" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-unused-vars": "error", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/ban-ts-comment": "error", + "semi": "error", + "no-console": "error" + } +} \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index b3b7d41..d211114 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,7 +1,6 @@ --- name: Bug report about: Create a bug report to help us improve -title: "" labels: bug assignees: '' diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index df05d6f..4be6790 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,6 @@ --- name: Feature request about: Suggest an idea for this project -title: "" labels: enhancement assignees: '' diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index f93b328..d7f46be 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,7 +1,6 @@ --- name: Question about: Some questions related to this lib -title: "" labels: question assignees: '' diff --git a/.gitignore b/.gitignore index 7033b56..e8e1662 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,15 @@ # Node node_modules package-lock.json - -# Tests -test +yarn.lock # Compiled files -lib +dist # Yarn logs yarn*.log -# Demo -demo +# example +example/test +example/music-bot/node_modules +example/music-bot/package-lock.json \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..517826d --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npm run format && npm run lint:fix \ No newline at end of file diff --git a/.prettierrc b/.prettierrc index ed8e0ee..46a28f7 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,7 @@ { - "printWidth": 400, + "printWidth": 200, "trailingComma": "none", - "singleQuote": true, - "tabWidth": 4 + "singleQuote": false, + "tabWidth": 4, + "semi": true } \ No newline at end of file diff --git a/README.md b/README.md index 7357eb1..511d425 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ Complete framework to facilitate music commands using **[discord.js](https://dis [![downloadsBadge](https://img.shields.io/npm/dt/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) [![versionBadge](https://img.shields.io/npm/v/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) [![discordBadge](https://img.shields.io/discord/558328638911545423?style=for-the-badge&color=7289da)](https://androz2091.fr/discord) +[![wakatime](https://wakatime.com/badge/github/Androz2091/discord-player.svg)](https://wakatime.com/badge/github/Androz2091/discord-player) +[![CodeFactor](https://www.codefactor.io/repository/github/androz2091/discord-player/badge/v5)](https://www.codefactor.io/repository/github/androz2091/discord-player/overview/v5) ## Installation @@ -40,46 +42,96 @@ $ npm install --save @discordjs/opus ## Getting Started -Here is the code you will need to get started with discord-player. Then, you will be able to use `client.player` everywhere in your code! +First of all, you will need to register slash commands: ```js -const Discord = require("discord.js"), -client = new Discord.Client, -settings = { - prefix: "!", - token: "Your Discord Token" -}; +const { REST } = require("@discordjs/rest"); +const { Routes } = require("discord-api-types/v9"); +const commands = [{ + name: "play", + description: "Plays a song!", + options: [ + { + name: "query", + type: "STRING", + description: "The song you want to play", + required: true + } + ] +}]; + +const rest = new REST({ version: "9" }).setToken(process.env.DISCORD_TOKEN); + +(async () => { + try { + console.log("Started refreshing application [/] commands."); + + await rest.put( + Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID), + { body: commands }, + ); + + console.log("Successfully reloaded application [/] commands."); + } catch (error) { + console.error(error); + } +})(); +``` + +Now you can implement your bot's logic: + +```js +const { Client, Intents } = require("discord.js"); +const client = new Discord.Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_VOICE_STATES] }); const { Player } = require("discord-player"); // Create a new Player (you don't need any API Key) const player = new Player(client); -// To easily access the player -client.player = player; - // add the trackStart event so when a song will be played this message will be sent -client.player.on("trackStart", (message, track) => message.channel.send(`Now playing ${track.title}...`)) +player.on("trackStart", (queue, track) => queue.metadata.channel.send(`🎶 | Now playing **${track.title}**!`)) client.once("ready", () => { console.log("I'm ready !"); }); -client.on("message", async (message) => { +client.on("interactionCreate", async (interaction) => { + if (!interaction.isCommand()) return; - const args = message.content.slice(settings.prefix.length).trim().split(/ +/g); - const command = args.shift().toLowerCase(); - - // !play Despacito + // /play Despacito // will play "Despacito" in the voice channel - if(command === "play"){ - client.player.play(message, args[0]); - // as we registered the event above, no need to send a success message here - } + if (interaction.commandName === "play") { + if (!interaction.member.voice.channelId) return await interaction.reply({ content: "You are not in a voice channel!", empheral: true }); + if (interaction.guild.me.voice.channelId && interaction.member.voice.channelId !== interaction.guild.me.voice.channelId) return await interaction.reply({ content: "You are not in my voice channel!", empheral: true }); + const query = interaction.options.get("query").value; + const queue = player.createQueue(message.guild, { + metadata: { + channel: interaction.channel + } + }); + + // verify vc connection + try { + if (!queue.connection) await queue.connect(interaction.member.voice.channel); + } catch { + queue.destroy(); + return await interaction.reply({ content: "Could not join your voice channel!", empheral: true }); + } + await interaction.defer(); + const track = await player.search(query, { + requestedBy: message.author + }).then(x => x.tracks[1]); + if (!track) return await interaction.followUp({ content: `❌ | Track **${query}** not found!` }); + + queue.play(track); + + return await interaction.followUp({ content: `⏱️ | Loading track **${track.title}**!` }); + } }); -client.login(settings.token); +client.login(process.env.DISCORD_TOKEN); ``` ## Supported websites @@ -113,7 +165,7 @@ These bots are made by the community, they can help you build your own! ```js const player = new Player(client, { - ytdlDownloadOptions: { + ytdlOptions: { requestOptions: { headers: { cookie: "YOUR_YOUTUBE_COOKIE" @@ -133,7 +185,7 @@ const proxy = "http://user:pass@111.111.111.111:8080"; const agent = HttpsProxyAgent(proxy); const player = new Player(client, { - ytdlDownloadOptions: { + ytdlOptions: { requestOptions: { agent } } }); diff --git a/docs/extractors/extractor.md b/docs/extractors/extractor.md index 9510969..dff289b 100644 --- a/docs/extractors/extractor.md +++ b/docs/extractors/extractor.md @@ -32,9 +32,6 @@ Your extractor should have 2 methods (required): url: "Some Link" } ``` - - `important: boolean` - - You can mark your Extractor as `important` by adding `important: true` to your extractor object. Doing this will disable rest of the extractors that comes after your extractor and use your extractor to get data. By default, it is set to `false`. - `version: string` diff --git a/docs/faq/custom_filters.md b/docs/faq/custom_filters.md index fd3cfa9..98a2ef5 100644 --- a/docs/faq/custom_filters.md +++ b/docs/faq/custom_filters.md @@ -8,5 +8,5 @@ const { AudioFilters } = require("discord-player"); AudioFilters.define("3D", "apulsator=hz=0.128"); // later, it can be used like this -player.setFilters(message, { "3D": true }); +queue.setFilters({ "3D": true }); ``` \ No newline at end of file diff --git a/docs/faq/live_video.md b/docs/faq/live_video.md deleted file mode 100644 index 40eb4be..0000000 --- a/docs/faq/live_video.md +++ /dev/null @@ -1,11 +0,0 @@ -# How to play live videos? - -You cannot play live videos by default. If you need to play the live video, just add this option: - -```js -const player = new Player(client, { - enableLive: true // enables livestream -}); -``` - -However, you cannot use audio filters with livestreams using this library! \ No newline at end of file diff --git a/docs/faq/pause_resume.md b/docs/faq/pause_resume.md deleted file mode 100644 index d0cbc54..0000000 --- a/docs/faq/pause_resume.md +++ /dev/null @@ -1,15 +0,0 @@ -# Pause and Resume is not working properly - -This is a bug in **[discord.js#5300](https://github.com/discordjs/discord.js/issues/5300)**. - -# Fix - -You have to update your command something like this: - -```diff -- client.player.resume(message); - -+ client.player.resume(message); -+ client.player.pause(message); -+ client.player.resume(message); -``` \ No newline at end of file diff --git a/docs/faq/slash_commands.md b/docs/faq/slash_commands.md new file mode 100644 index 0000000..0321af5 --- /dev/null +++ b/docs/faq/slash_commands.md @@ -0,0 +1,3 @@ +# Slash Commands Example + +You can use Discord Player with slash commands. **[Here](https://github.com/Androz2091/discord-player/tree/v5/example/music-bot)** is an example on how to use this framework with slash commands. \ No newline at end of file diff --git a/docs/general/welcome.md b/docs/general/welcome.md deleted file mode 100644 index 2075526..0000000 --- a/docs/general/welcome.md +++ /dev/null @@ -1,139 +0,0 @@ -# Discord Player -Complete framework to facilitate music commands using **[discord.js](https://discord.js.org)**. - -[![downloadsBadge](https://img.shields.io/npm/dt/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) -[![versionBadge](https://img.shields.io/npm/v/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) - -## Installation - -### Install **[discord-player](https://npmjs.com/package/discord-player)** - -```sh -$ npm install --save discord-player -``` - -### Install **[@discordjs/opus](https://npmjs.com/package/@discordjs/opus)** - -```sh -$ npm install --save @discordjs/opus -``` - -### Install FFmpeg or Avconv -- Official FFMPEG Website: **[https://www.ffmpeg.org/download.html](https://www.ffmpeg.org/download.html)** - -- Node Module (FFMPEG): **[https://npmjs.com/package/ffmpeg-static](https://npmjs.com/package/ffmpeg-static)** - -- Avconv: **[https://libav.org/download](https://libav.org/download)** - -# Features -- Simple & easy to use 🤘 -- Beginner friendly 😱 -- Audio filters 🎸 -- Lightweight 🛬 -- Custom extractors support 🌌 -- Lyrics 📃 -- Multiple sources support ✌ -- Play in multiple servers at the same time 🚗 - -## [Documentation](https://discord-player.js.org) - -## Getting Started - -Here is the code you will need to get started with discord-player. Then, you will be able to use `client.player` everywhere in your code! - -```js -const Discord = require("discord.js"), -client = new Discord.Client, -settings = { - prefix: "!", - token: "Your Discord Token" -}; - -const { Player } = require("discord-player"); - -// Create a new Player (you don't need any API Key) -const player = new Player(client); - -// To easily access the player -client.player = player; - -// add the trackStart event so when a song will be played this message will be sent -client.player.on("trackStart", (message, track) => message.channel.send(`Now playing ${track.title}...`)) - -client.once("ready", () => { - console.log("I'm ready !"); -}); - -client.on("message", async (message) => { - - const args = message.content.slice(settings.prefix.length).trim().split(/ +/g); - const command = args.shift().toLowerCase(); - - // !play Despacito - // will play the song "Despacito" in the voice channel - if(command === "play"){ - client.player.play(message, args[0]); - // as we registered the event above, no need to send a success message here - } - -}); - -client.login(settings.token); -``` - -## Supported websites - -By default, discord-player supports **YouTube**, **Spotify** and **SoundCloud** streams only. - -### Optional dependencies - -Discord Player provides an **Extractor API** that enables you to use your custom stream extractor with it. Some packages have been made by the community to add new features using this API. - -#### [@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors) (optional) - -Optional package that adds support for `vimeo`, `reverbnation`, `facebook`, `attachment links` and `lyrics`. -You just need to install it using `npm i --save @discord-player/extractor` (discord-player will automatically detect and use it). - -#### [@discord-player/downloader](https://github.com/DevSnowflake/discord-player-downloader) (optional) - -`@discord-player/downloader` is an optional package that brings support for +700 websites. The documentation is available [here](https://github.com/DevSnowflake/discord-player-downloader). - -## Examples of bots made with Discord Player - -These bots are made by the community, they can help you build your own! - -* [AtlantaBot](https://github.com/Androz2091/AtlantaBot) by [Androz2091](https://github.com/Androz2091) -* [Discord-Music](https://github.com/inhydrox/discord-music) by [inhydrox](https://github.com/inhydrox) -* [Music-bot](https://github.com/ZerioDev/Music-bot) by [ZerioDev](https://github.com/ZerioDev) - -## FAQ - -### How to use cookies - -```js -const player = new Player(client, { - ytdlDownloadOptions: { - requestOptions: { - headers: { - cookie: "YOUR_YOUTUBE_COOKIE" - } - } - } -}); -``` - -### How to use custom proxies - -```js -const HttpsProxyAgent = require("https-proxy-agent"); - -// Remove "user:pass@" if you don't need to authenticate to your proxy. -const proxy = "http://user:pass@111.111.111.111:8080"; -const agent = HttpsProxyAgent(proxy); - -const player = new Player(client, { - ytdlDownloadOptions: { - requestOptions: { agent } - } -}); -``` diff --git a/docs/index.yml b/docs/index.yml index 3ab6cd4..551affa 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -1,7 +1,12 @@ - name: General files: - name: Welcome - path: welcome.md + id: welcome + path: ../../README.md +- name: Migrating + files: + - name: Migrating to v5 + path: migrating.md - name: Extractors files: - name: Extractors API @@ -10,13 +15,11 @@ files: - name: Custom Filters path: custom_filters.md - - name: Livestreams - path: live_video.md - - name: Pause & Resume - path: pause_resume.md + - name: Slash Commands + path: slash_commands.md - name: YouTube files: - name: Using Cookies path: cookies.md - name: Using Proxy - path: proxy.md \ No newline at end of file + path: proxy.md diff --git a/docs/migrating/migrating.md b/docs/migrating/migrating.md new file mode 100644 index 0000000..9860d13 --- /dev/null +++ b/docs/migrating/migrating.md @@ -0,0 +1,59 @@ +# Migrating to Discord Player v5 + +We have introduced some breaking changes in Discord Player v5. Which means, your old code will no longer work with v5. +The new update brings new features as well as better management of different things. This also uses the new **[@discordjs/voice](https://github.com/discordjs/voice)** library! + +## Basic Example + +```diff +- player.play(message, query); ++ const queue = player.createQueue(message.guild); ++ const song = await player.search(query, { ++ requestedBy: message.author +}); ++ ++ try { ++ await queue.connect(message.member.voice.channel); ++ } catch { ++ message.reply("Could not join your voice channel"); ++ } ++ ++ queue.addTrack(song.tracks[0]); ++ queue.play(); +``` + +> Everything related to music player is moved to `Queue`. + +## How do I reply to the event like v4? + +Since we got rid of `message` parameter in every method of the Discord Player, you no longer have access to the `message` object in events. +Instead, we have added `.metadata` prop as an alternative. This `metadata` can be anything, declared while creating queue: + +```js +const queue = player.createQueue(message.guild, { + metadata: message +}); +``` + +The metadata `message` will always be available in every events emitted for that specific `Queue`. You can access it via `queue.metadata`: + +```js +player.on("trackStart", (queue, track) => { + const channel = queue.metadata.channel; // queue.metadata is your "message" object + channel.send(`🎶 | Started playing **${track.title}**`); +}); +``` + +## How do I stop the player + +You have to use `.destroy()` to destroy the queue. It will also stop the player. + +```js +const queue = player.getQueue(message.guild.id); +if (queue) queue.destroy(); +``` + +## Updating filters + +Discord Player v5.x has new option `bufferingTimeout` in queue init options which allows you to set stream buffering timeout before playing. +This might be useful if you want to have smooth filters update. By default, it is set to 3 seconds. diff --git a/docs/youtube/cookies.md b/docs/youtube/cookies.md index 2405dcf..e448857 100644 --- a/docs/youtube/cookies.md +++ b/docs/youtube/cookies.md @@ -4,7 +4,7 @@ const { Player } = require("discord-player"); const player = new Player(client, { - ytdlDownloadOptions: { + ytdlOptions: { requestOptions: { headers: { cookie: "YOUR_YOUTUBE_COOKIE" diff --git a/docs/youtube/proxy.md b/docs/youtube/proxy.md index 3dc8ba5..35fe5a8 100644 --- a/docs/youtube/proxy.md +++ b/docs/youtube/proxy.md @@ -9,7 +9,7 @@ const proxy = "http://user:pass@111.111.111.111:8080"; const agent = HttpsProxyAgent(proxy); const player = new Player(client, { - ytdlDownloadOptions: { + ytdlOptions: { requestOptions: { agent } } }); diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..602c11c --- /dev/null +++ b/example/README.md @@ -0,0 +1,2 @@ +# Discord Player Examples +This section contains example bot(s) made with Discord Player. \ No newline at end of file diff --git a/example/music-bot/README.md b/example/music-bot/README.md new file mode 100644 index 0000000..520b8e5 --- /dev/null +++ b/example/music-bot/README.md @@ -0,0 +1,2 @@ +# Music Bot +Slash commands music bot backed by **[Discord Player](https://discord-player.js.org)**. \ No newline at end of file diff --git a/example/music-bot/config.js b/example/music-bot/config.js new file mode 100644 index 0000000..e9ad43e --- /dev/null +++ b/example/music-bot/config.js @@ -0,0 +1,3 @@ +module.exports = { + token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +}; diff --git a/example/music-bot/index.js b/example/music-bot/index.js new file mode 100644 index 0000000..5a85701 --- /dev/null +++ b/example/music-bot/index.js @@ -0,0 +1,301 @@ +const { Client, GuildMember } = require("discord.js"); +const config = require("./config"); +const { Player, QueryType, QueueRepeatMode } = require("discord-player"); + +const client = new Client({ + intents: ["GUILD_VOICE_STATES", "GUILD_MESSAGES", "GUILDS"] +}); + +client.on("ready", () => { + console.log("Bot is online!"); + client.user.setActivity({ + name: "🎶 | Music Time", + type: "LISTENING" + }); +}); +client.on("error", console.error); +client.on("warn", console.warn); + +// instantiate the player +const player = new Player(client); + +player.on("error", (queue, error) => { + console.log(`[${queue.guild.name}] Error emitted from the queue: ${error.message}`); +}); +player.on("connectionError", (queue, error) => { + console.log(`[${queue.guild.name}] Error emitted from the connection: ${error.message}`); +}); + +player.on("trackStart", (queue, track) => { + queue.metadata.send(`🎶 | Started playing: **${track.title}** in **${queue.connection.channel.name}**!`); +}); + +player.on("trackAdd", (queue, track) => { + queue.metadata.send(`🎶 | Track **${track.title}** queued!`); +}); + +player.on("botDisconnect", (queue) => { + queue.metadata.send("❌ | I was manually disconnected from the voice channel, clearing queue!"); +}); + +player.on("channelEmpty", (queue) => { + queue.metadata.send("❌ | Nobody is in the voice channel, leaving..."); +}); + +player.on("queueEnd", (queue) => { + queue.metadata.send("✅ | Queue finished!"); +}); + +client.on("messageCreate", async (message) => { + if (message.author.bot || !message.guild) return; + if (!client.application?.owner) await client.application?.fetch(); + + if (message.content === "!deploy" && message.author.id === client.application?.owner?.id) { + await message.guild.commands.set([ + { + name: "play", + description: "Plays a song from youtube", + options: [ + { + name: "query", + type: "STRING", + description: "The song you want to play", + required: true + } + ] + }, + { + name: "soundcloud", + description: "Plays a song from soundcloud", + options: [ + { + name: "query", + type: "STRING", + description: "The song you want to play", + required: true + } + ] + }, + { + name: "volume", + description: "Sets music volume", + options: [ + { + name: "amount", + type: "INTEGER", + description: "The volume amount to set (0-100)", + required: false + } + ] + }, + { + name: "loop", + description: "Sets loop mode", + options: [ + { + name: "mode", + type: "INTEGER", + description: "Loop type", + required: true, + choices: [ + { + name: "Off", + value: QueueRepeatMode.OFF + }, + { + name: "Track", + value: QueueRepeatMode.TRACK + }, + { + name: "Queue", + value: QueueRepeatMode.QUEUE + }, + { + name: "Autoplay", + value: QueueRepeatMode.AUTOPLAY + } + ] + } + ] + }, + { + name: "skip", + description: "Skip to the current song" + }, + { + name: "queue", + description: "See the queue" + }, + { + name: "pause", + description: "Pause the current song" + }, + { + name: "resume", + description: "Resume the current song" + }, + { + name: "stop", + description: "Stop the player" + }, + { + name: "np", + description: "Now Playing" + }, + { + name: "bassboost", + description: "Toggles bassboost filter" + } + ]); + + await message.reply("Deployed!"); + } +}); + +client.on("interactionCreate", async (interaction) => { + if (!interaction.isCommand() || !interaction.guildId) return; + + if (!(interaction.member instanceof GuildMember) || !interaction.member.voice.channel) { + return void interaction.reply({ content: "You are not in a voice channel!", ephemeral: true }); + } + + if (interaction.guild.me.voice.channelId && interaction.member.voice.channelId !== interaction.guild.me.voice.channelId) { + return void interaction.reply({ content: "You are not in my voice channel!", ephemeral: true }); + } + + if (interaction.commandName === "play" || interaction.commandName === "soundcloud") { + await interaction.deferReply(); + + const query = interaction.options.get("query").value; + const searchResult = await player + .search(query, { + requestedBy: interaction.user, + searchEngine: interaction.commandName === "soundcloud" ? QueryType.SOUNDCLOUD_SEARCH : QueryType.AUTO + }) + .catch(() => {}); + if (!searchResult || !searchResult.tracks.length) return void interaction.followUp({ content: "No results were found!" }); + + const queue = await player.createQueue(interaction.guild, { + metadata: interaction.channel + }); + + try { + if (!queue.connection) await queue.connect(interaction.member.voice.channel); + } catch { + void player.deleteQueue(interaction.guildId); + return void interaction.followUp({ content: "Could not join your voice channel!" }); + } + + await interaction.followUp({ content: `⏱ | Loading your ${searchResult.playlist ? "playlist" : "track"}...` }); + searchResult.playlist ? queue.addTracks(searchResult.tracks) : queue.addTrack(searchResult.tracks[0]); + if (!queue.playing) await queue.play(); + } else if (interaction.commandName === "volume") { + await interaction.deferReply(); + const queue = player.getQueue(interaction.guildId); + if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" }); + const vol = interaction.options.get("amount"); + if (!vol) return void interaction.followUp({ content: `🎧 | Current volume is **${queue.volume}**%!` }); + if ((vol.value) < 0 || (vol.value) > 100) return void interaction.followUp({ content: "❌ | Volume range must be 0-100" }); + const success = queue.setVolume(vol.value); + return void interaction.followUp({ + content: success ? `✅ | Volume set to **${vol.value}%**!` : "❌ | Something went wrong!" + }); + } else if (interaction.commandName === "skip") { + await interaction.deferReply(); + const queue = player.getQueue(interaction.guildId); + if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" }); + const currentTrack = queue.current; + const success = queue.skip(); + return void interaction.followUp({ + content: success ? `✅ | Skipped **${currentTrack}**!` : "❌ | Something went wrong!" + }); + } else if (interaction.commandName === "queue") { + await interaction.deferReply(); + const queue = player.getQueue(interaction.guildId); + if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" }); + const currentTrack = queue.current; + const tracks = queue.tracks.slice(0, 10).map((m, i) => { + return `${i + 1}. **${m.title}** ([link](${m.url}))`; + }); + + return void interaction.followUp({ + embeds: [ + { + title: "Server Queue", + description: `${tracks.join("\n")}${ + queue.tracks.length > tracks.length + ? `\n...${queue.tracks.length - tracks.length === 1 ? `${queue.tracks.length - tracks.length} more track` : `${queue.tracks.length - tracks.length} more tracks`}` + : "" + }`, + color: 0xff0000, + fields: [{ name: "Now Playing", value: `🎶 | **${currentTrack.title}** ([link](${currentTrack.url}))` }] + } + ] + }); + } else if (interaction.commandName === "pause") { + await interaction.deferReply(); + const queue = player.getQueue(interaction.guildId); + if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" }); + const success = queue.setPaused(true); + return void interaction.followUp({ content: success ? "⏸ | Paused!" : "❌ | Something went wrong!" }); + } else if (interaction.commandName === "resume") { + await interaction.deferReply(); + const queue = player.getQueue(interaction.guildId); + if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" }); + const success = queue.setPaused(false); + return void interaction.followUp({ content: success ? "▶ | Resumed!" : "❌ | Something went wrong!" }); + } else if (interaction.commandName === "stop") { + await interaction.deferReply(); + const queue = player.getQueue(interaction.guildId); + if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" }); + queue.destroy(); + return void interaction.followUp({ content: "🛑 | Stopped the player!" }); + } else if (interaction.commandName === "np") { + await interaction.deferReply(); + const queue = player.getQueue(interaction.guildId); + if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" }); + const progress = queue.createProgressBar(); + const perc = queue.getPlayerTimestamp(); + + return void interaction.followUp({ + embeds: [ + { + title: "Now Playing", + description: `🎶 | **${queue.current.title}**! (\`${perc.progress}%\`)`, + fields: [ + { + name: "\u200b", + value: progress + } + ], + color: 0xffffff + } + ] + }); + } else if (interaction.commandName === "loop") { + await interaction.deferReply(); + const queue = player.getQueue(interaction.guildId); + if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" }); + const loopMode = interaction.options.get("mode").value; + const success = queue.setRepeatMode(loopMode); + const mode = loopMode === QueueRepeatMode.TRACK ? "🔂" : loopMode === QueueRepeatMode.QUEUE ? "🔁" : "▶"; + return void interaction.followUp({ content: success ? `${mode} | Updated loop mode!` : "❌ | Could not update loop mode!" }); + } else if (interaction.commandName === "bassboost") { + await interaction.deferReply(); + const queue = player.getQueue(interaction.guildId); + if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" }); + await queue.setFilters({ + bassboost: !queue.getFiltersEnabled().includes("bassboost"), + normalizer2: !queue.getFiltersEnabled().includes("bassboost") // because we need to toggle it with bass + }); + + return void interaction.followUp({ content: `🎵 | Bassboost ${queue.getFiltersEnabled().includes("bassboost") ? "Enabled" : "Disabled"}!` }); + } else { + interaction.reply({ + content: "Unknown command!", + ephemeral: true + }); + } +}); + +client.login(config.token); diff --git a/example/music-bot/package.json b/example/music-bot/package.json new file mode 100644 index 0000000..8eab638 --- /dev/null +++ b/example/music-bot/package.json @@ -0,0 +1,16 @@ +{ + "name": "music-bot", + "version": "1.0.0", + "description": "Simple music bot created with discord-player", + "main": "index.js", + "scripts": { + "start": "node index.js" + }, + "author": "Snowflake107", + "license": "MIT", + "dependencies": { + "@discordjs/opus": "^0.5.3", + "discord-player": "^5.0.0-dev.39f503a.1625470163", + "discord.js": "^13.0.1" + } +} diff --git a/package.json b/package.json index ea00c9e..d58bf95 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,28 @@ { "name": "discord-player", - "version": "4.1.4", + "version": "5.0.0-dev", "description": "Complete framework to facilitate music commands using discord.js", - "main": "lib/index.js", - "types": "lib/index.d.ts", + "main": "dist/index.js", + "types": "dist/index.d.ts", "files": [ - "lib/" + "dist/" ], + "module": "dist/index.mjs", + "exports": { + "require": "./dist/index.js", + "import": "./dist/index.mjs" + }, "scripts": { - "test": "yarn build && cd test && node index.js", - "build": "tsc", - "format": "prettier --write \"src/**/*.ts\"", - "lint": "tslint -p tsconfig.json", - "docs": "docgen --jsdoc jsdoc.json --verbose --source src/*.ts src/**/*.ts --custom docs/index.yml --output docs/docs.json", - "docs:test": "docgen --jsdoc jsdoc.json --verbose --source src/*.ts src/**/*.ts --custom docs/index.yml" + "dev": "cd example/test && ts-node index.ts", + "build": "rimraf dist && tsc && npm run build:esm", + "build:check": "tsc --noEmit --incremental false", + "prepublishOnly": "rollup-type-bundler -e stream", + "build:esm": "gen-esm-wrapper ./dist/index.js ./dist/index.mjs", + "format": "prettier --write \"src/**/*.ts\" \"example/**/*.ts\"", + "docs": "docgen --jsdoc jsdoc.json --source src/*.ts src/**/*.ts --custom docs/index.yml --output docs/docs.json", + "docs:test": "docgen --jsdoc jsdoc.json --source src/*.ts src/**/*.ts --custom docs/index.yml", + "lint": "eslint src --ext .ts", + "lint:fix": "eslint src --ext .ts --fix" }, "funding": "https://github.com/Androz2091/discord-player?sponsor=1", "contributors": [ @@ -50,27 +59,37 @@ }, "homepage": "https://discord-player.js.org", "dependencies": { + "@discordjs/voice": "^0.5.5", "discord-ytdl-core": "^5.0.4", - "soundcloud-scraper": "^5.0.0", + "libsodium-wrappers": "^0.7.9", + "soundcloud-scraper": "^5.0.1", "spotify-url-info": "^2.2.3", - "youtube-sr": "^4.1.5", - "ytdl-core": "^4.8.3" + "tiny-typed-emitter": "^2.1.0", + "youtube-sr": "^4.1.7", + "ytdl-core": "^4.9.1" }, "devDependencies": { - "@babel/cli": "^7.13.16", - "@babel/core": "^7.13.16", - "@babel/preset-env": "^7.13.15", - "@babel/preset-typescript": "^7.13.0", - "@discord-player/extractor": "^3.0.0", - "@discordjs/opus": "^0.5.0", - "@types/node": "^15.6.1", - "@types/ws": "^7.4.1", - "discord.js": "^12.5.3", - "discord.js-docgen": "discordjs/docgen#ts-patch", + "@babel/cli": "^7.14.8", + "@babel/core": "^7.15.0", + "@babel/preset-env": "^7.15.0", + "@babel/preset-typescript": "^7.15.0", + "@devsnowflake/docgen": "devsnowflake/docgen#ts-patch", + "@discord-player/extractor": "^3.0.2", + "@discordjs/opus": "github:discordjs/opus", + "@favware/rollup-type-bundler": "^1.0.3", + "@types/node": "^16.4.13", + "@types/ws": "^7.4.7", + "@typescript-eslint/eslint-plugin": "^4.29.0", + "@typescript-eslint/parser": "^4.29.0", + "discord-api-types": "^0.22.0", + "discord.js": "^13.0.1", + "eslint": "^7.32.0", + "gen-esm-wrapper": "^1.1.2", + "husky": "^7.0.1", "jsdoc-babel": "^0.5.0", - "prettier": "^2.2.1", - "tslint": "^6.1.3", - "tslint-config-prettier": "^1.18.0", - "typescript": "^4.2.3" + "prettier": "^2.3.2", + "rimraf": "^3.0.2", + "ts-node": "^10.1.0", + "typescript": "^4.3.5" } } diff --git a/src/Player.ts b/src/Player.ts index 4b638f7..a635613 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,1581 +1,507 @@ -import { EventEmitter } from 'events'; -import { Client, Collection, Snowflake, Collector, Message, VoiceChannel, VoiceState } from 'discord.js'; -import { LyricsData, PlayerOptions as PlayerOptionsType, PlayerProgressbarOptions, PlayerStats, QueueFilters } from './types/types'; -import Util from './utils/Util'; -import AudioFilters from './utils/AudioFilters'; -import { Queue } from './Structures/Queue'; -import { Track } from './Structures/Track'; -import { PlayerErrorEventCodes, PlayerEvents, PlayerOptions } from './utils/Constants'; -import PlayerError from './utils/PlayerError'; -import ytdl from 'discord-ytdl-core'; -import { ExtractorModel } from './Structures/ExtractorModel'; -import os from 'os'; - +import { Client, Collection, GuildResolvable, Snowflake, User, VoiceState } from "discord.js"; +import { TypedEmitter as EventEmitter } from "tiny-typed-emitter"; +import { Queue } from "./Structures/Queue"; +import { VoiceUtils } from "./VoiceInterface/VoiceUtils"; +import { PlayerEvents, PlayerOptions, QueryType, SearchOptions, PlayerInitOptions } from "./types/types"; +import Track from "./Structures/Track"; +import { QueryResolver } from "./utils/QueryResolver"; +import YouTube from "youtube-sr"; +import { Util } from "./utils/Util"; +import Spotify from "spotify-url-info"; +import { PlayerError, ErrorStatusCode } from "./Structures/PlayerError"; +// eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore -import spotify from 'spotify-url-info'; -// @ts-ignore -import { Client as SoundCloudClient } from 'soundcloud-scraper'; -import YouTube from 'youtube-sr'; +import { Client as SoundCloud } from "soundcloud-scraper"; +import { Playlist } from "./Structures/Playlist"; +import { ExtractorModel } from "./Structures/ExtractorModel"; +import { generateDependencyReport } from "@discordjs/voice"; -const SoundCloud = new SoundCloudClient(); +const soundcloud = new SoundCloud(); -/** - * The Player class - * @extends {EventEmitter} - */ -export class Player extends EventEmitter { - public client: Client; - public options: PlayerOptionsType; - public filters: typeof AudioFilters; +class Player extends EventEmitter { + public readonly client: Client; + public readonly options: PlayerInitOptions = { + autoRegisterExtractor: true, + ytdlOptions: { + highWaterMark: 1 << 25 + }, + connectionTimeout: 20000 + }; + public readonly queues = new Collection(); + public readonly voiceUtils = new VoiceUtils(); + public readonly extractors = new Collection(); /** - * The collection of queues in this player - * @type {DiscordCollection} + * Creates new Discord Player + * @param {Client} client The Discord Client + * @param {PlayerInitOptions} [options={}] The player init options */ - public queues = new Collection(); - - /** - * Collection of results collectors - * @type {DiscordCollection>} - * @private - */ - private _resultsCollectors = new Collection>(); - - /** - * Collection of cooldowns timeout - * @type {DiscordCollection} - * @private - */ - private _cooldownsTimeout = new Collection(); - - /** - * The extractor model collection - * @type {DiscordCollection} - */ - public Extractors = new Collection(); - - /** - * Creates new Player instance - * @param {DiscordClient} client The discord.js client - * @param {PlayerOptions} options Player options - */ - constructor(client: Client, options?: PlayerOptionsType) { + constructor(client: Client, options: PlayerInitOptions = {}) { super(); /** - * The discord client that instantiated this player - * @name Player#client - * @type {DiscordClient} - * @readonly + * The discord.js client + * @type {Client} */ - Object.defineProperty(this, 'client', { - value: client, - enumerable: false - }); + this.client = client; /** - * The player options - * @type {PlayerOptions} + * The extractors collection + * @type {ExtractorModel} */ - this.options = Object.assign({}, PlayerOptions, options ?? {}); + this.options = Object.assign(this.options, options); - // check FFmpeg - void Util.alertFFmpeg(); + this.client.on("voiceStateUpdate", this._handleVoiceState.bind(this)); - /** - * Audio filters - * @type {Object} - */ - this.filters = AudioFilters; + if (this.options?.autoRegisterExtractor) { + let nv: any; // eslint-disable-line @typescript-eslint/no-explicit-any - this.client.on('voiceStateUpdate', this._handleVoiceStateUpdate.bind(this)); - - // auto detect @discord-player/extractor - if (!this.options.disableAutoRegister) { - let nv: any; - - // tslint:disable:no-conditional-assignment - if ((nv = Util.require('@discord-player/extractor'))) { - ['Attachment', 'Facebook', 'Reverbnation', 'Vimeo'].forEach((ext) => void this.use(ext, nv[ext])); - } - } - } - - static get AudioFilters(): typeof AudioFilters { - return AudioFilters; - } - - /** - * Define custom extractor in this player - * @param {String} extractorName The extractor name - * @param {any} extractor The extractor itself - * @returns {Player} - */ - use(extractorName: string, extractor: any): Player { - if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); - - const methods = ['validate', 'getInfo']; - - for (const method of methods) { - if (typeof extractor[method] !== 'function') throw new PlayerError('Invalid extractor supplied!', 'PlayerExtractorError'); - } - - this.Extractors.set(extractorName, new ExtractorModel(extractorName, extractor)); - - return this; - } - - /** - * Remove existing extractor from this player - * @param {String} extractorName The extractor name - * @returns {Boolean} - */ - unuse(extractorName: string): boolean { - if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); - - return this.Extractors.delete(extractorName); - } - - /** - * Internal method to search tracks - * @param {DiscordMessage} message The message - * @param {string} query The query - * @param {boolean} [firstResult=false] If it should return the first result - * @param {number} [startFromIndex=0] Prioritise playing the track with following index (Only works with playlist) - * @returns {Promise} - * @private - */ - private _searchTracks(message: Message, query: string, firstResult?: boolean, startFromIndex = 0): Promise { - return new Promise(async (resolve) => { - let tracks: Track[] = []; - const queryType = Util.getQueryType(query); - - switch (queryType) { - case 'soundcloud_track': - { - const data = await SoundCloud.getSongInfo(query).catch(() => {}); - if (data) { - const track = new Track(this, { - title: data.title, - url: data.url, - duration: Util.buildTimeCode(Util.parseMS(data.duration)), - description: data.description, - thumbnail: data.thumbnail, - views: data.playCount, - author: data.author.name, - requestedBy: message.author, - fromPlaylist: false, - source: 'soundcloud', - engine: data - }); - - tracks.push(track); - } - } - break; - case 'spotify_song': - { - const matchSpotifyURL = query.match(/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/); - if (matchSpotifyURL) { - const spotifyData = await spotify.getData(query).catch(() => {}); - if (spotifyData) { - const spotifyTrack = new Track(this, { - title: spotifyData.name, - description: spotifyData.description ?? '', - author: spotifyData.artists[0]?.name ?? 'Unknown Artist', - url: spotifyData.external_urls?.spotify ?? query, - thumbnail: spotifyData.album?.images[0]?.url ?? spotifyData.preview_url?.length ? `https://i.scdn.co/image/${spotifyData.preview_url?.split('?cid=')[1]}` : 'https://www.scdn.co/i/_global/twitter_card-default.jpg', - duration: Util.buildTimeCode(Util.parseMS(spotifyData.duration_ms)), - views: 0, - requestedBy: message.author, - fromPlaylist: false, - source: 'spotify' - }); - - if (this.options.fetchBeforeQueued) { - const searchQueryString = this.options.disableArtistSearch ? spotifyTrack.title : `${spotifyTrack.title}${' - ' + spotifyTrack.author}`; - const ytv = await YouTube.search(searchQueryString, { - limit: 1, - type: 'video' - }).catch((e) => {}); - - if (ytv && ytv[0]) - Util.define({ - target: spotifyTrack, - prop: 'backupLink', - value: ytv[0].url - }); - } - - tracks = [spotifyTrack]; - } - } - } - break; - - case 'spotify_album': - case 'spotify_playlist': { - this.emit(PlayerEvents.PLAYLIST_PARSE_START, null, message); - const playlist = await spotify.getData(query); - if (!playlist) return void this.emit(PlayerEvents.NO_RESULTS, message, query); - - // tslint:disable-next-line:no-shadowed-variable - let tracks: Track[] = []; - - if (playlist.type !== 'playlist') - tracks = await Promise.all( - playlist.tracks.items.map(async (m: any) => { - const data = new Track(this, { - title: m.name ?? '', - description: m.description ?? '', - author: m.artists[0]?.name ?? 'Unknown Artist', - url: m.external_urls?.spotify ?? query, - thumbnail: playlist.images[0]?.url ?? 'https://www.scdn.co/i/_global/twitter_card-default.jpg', - duration: Util.buildTimeCode(Util.parseMS(m.duration_ms)), - views: 0, - requestedBy: message.author, - fromPlaylist: true, - source: 'spotify' - }); - - if (this.options.fetchBeforeQueued) { - const searchQueryString = this.options.disableArtistSearch ? data.title : `${data.title}${' - ' + data.author}`; - const ytv = await YouTube.search(searchQueryString, { - limit: 1, - type: 'video' - }).catch((e) => {}); - - if (ytv && ytv[0]) - Util.define({ - target: data, - prop: 'backupLink', - value: ytv[0].url - }); - } - - return data; - }) - ); - else { - tracks = await Promise.all( - playlist.tracks.items.map(async (m: any) => { - const data = new Track(this, { - title: m.track.name ?? '', - description: m.track.description ?? '', - author: m.track.artists[0]?.name ?? 'Unknown Artist', - url: m.track.external_urls?.spotify ?? query, - thumbnail: m.track.album?.images[0]?.url ?? 'https://www.scdn.co/i/_global/twitter_card-default.jpg', - duration: Util.buildTimeCode(Util.parseMS(m.track.duration_ms)), - views: 0, - requestedBy: message.author, - fromPlaylist: true, - source: 'spotify' - }); - - if (this.options.fetchBeforeQueued) { - const searchQueryString = this.options.disableArtistSearch ? data.title : `${data.title}${' - ' + data.author}`; - const ytv = await YouTube.search(searchQueryString, { - limit: 1, - type: 'video' - }).catch((e) => {}); - - if (ytv && ytv[0]) - Util.define({ - target: data, - prop: 'backupLink', - value: ytv[0].url - }); - } - - return data; - }) - ); - } - - if (!tracks.length) return void this.emit(PlayerEvents.NO_RESULTS, message, query); - - const pl = { - ...playlist, - tracks, - duration: tracks?.reduce((a, c) => a + (c?.durationMS ?? 0), 0) ?? 0, - thumbnail: playlist.images[0]?.url ?? tracks[0].thumbnail, - title: playlist.title ?? playlist.name ?? '' - }; - - this.emit(PlayerEvents.PLAYLIST_PARSE_END, pl, message); - if (startFromIndex < 0) startFromIndex = 0; - if (startFromIndex > tracks.length - 1) startFromIndex = tracks.length - 1; - - if (this.isPlaying(message)) { - const prioritisedTrack = tracks.splice(startFromIndex, 1); - tracks.unshift(prioritisedTrack); - const queue = this._addTracksToQueue(message, tracks); - this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, pl); - } else { - const track = tracks[startFromIndex]; - const queue = (await this._createQueue(message, track).catch((e) => void this.emit(PlayerEvents.ERROR, e, message))) as Queue; - this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, pl); - tracks.splice(startFromIndex, 1); - this._addTracksToQueue(message, tracks); - this.emit(PlayerEvents.TRACK_START, message, track, queue); - } - - return; - } - case 'youtube_playlist': { - this.emit(PlayerEvents.PLAYLIST_PARSE_START, null, message); - const playlist = await YouTube.getPlaylist(query); - if (!playlist) return void this.emit(PlayerEvents.NO_RESULTS, message, query); - - // @ts-ignore - playlist.videos = playlist.videos.map( - (data) => - new Track(this, { - title: data.title, - url: data.url, - duration: Util.buildTimeCode(Util.parseMS(data.duration)), - description: data.description, - thumbnail: data.thumbnail?.displayThumbnailURL(), - views: data.views, - author: data.channel.name, - requestedBy: message.author, - fromPlaylist: true, - source: 'youtube' - }) - ); - - // @ts-ignore - playlist.duration = playlist.videos.reduce((a, c) => a + c.durationMS, 0); - - // @ts-ignore - playlist.thumbnail = playlist.thumbnail?.url ?? playlist.videos[0].thumbnail; - - // @ts-ignore - playlist.requestedBy = message.author; - - Object.defineProperty(playlist, 'tracks', { - get: () => playlist.videos ?? [] - }); - - this.emit(PlayerEvents.PLAYLIST_PARSE_END, playlist, message); - - // @ts-ignore - // tslint:disable-next-line:no-shadowed-variable - const tracks = playlist.videos as Track[]; - if (startFromIndex < 0) startFromIndex = 0; - if (startFromIndex > tracks.length - 1) startFromIndex = tracks.length - 1; - - if (this.isPlaying(message)) { - const prioritisedTrack = tracks.splice(startFromIndex, 1); - tracks.unshift(prioritisedTrack); - const queue = this._addTracksToQueue(message, tracks); - this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, playlist); - } else { - const track = tracks[startFromIndex]; - const queue = (await this._createQueue(message, track).catch((e) => void this.emit(PlayerEvents.ERROR, e, message))) as Queue; - this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, pl); - tracks.splice(startFromIndex, 1); - this._addTracksToQueue(message, tracks); - this.emit(PlayerEvents.TRACK_START, message, track, queue); - } - - return; - } - case 'soundcloud_playlist': { - this.emit(PlayerEvents.PLAYLIST_PARSE_START, null, message); - - const data = await SoundCloud.getPlaylist(query).catch(() => {}); - if (!data) return void this.emit(PlayerEvents.NO_RESULTS, message, query); - - const res = { - id: data.id, - title: data.title, - tracks: [] as Track[], - author: data.author, - duration: 0, - thumbnail: data.thumbnail, - requestedBy: message.author - }; - - for (const song of data.tracks) { - const r = new Track(this, { - title: song.title, - url: song.url, - duration: Util.buildTimeCode(Util.parseMS(song.duration)), - description: song.description, - thumbnail: song.thumbnail ?? 'https://soundcloud.com/pwa-icon-192.png', - views: song.playCount ?? 0, - author: song.author ?? data.author, - requestedBy: message.author, - fromPlaylist: true, - source: 'soundcloud', - engine: song - }); - - res.tracks.push(r); - } - - if (!res.tracks.length) return this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.PARSE_ERROR, message); - res.duration = res.tracks.reduce((a, c) => a + c.durationMS, 0); - - this.emit(PlayerEvents.PLAYLIST_PARSE_END, res, message); - if (startFromIndex < 0) res.startFromIndex = 0; - if (startFromIndex > tracks.length - 1) startFromIndex = res.tracks.length - 1; - - if (this.isPlaying(message)) { - const prioritisedTrack = res.tracks.splice(startFromIndex, 1); - res.tracks.unshift(prioritisedTrack); - this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, res); - } else { - const track = res.tracks[startFromIndex]; - const queue = (await this._createQueue(message, track).catch((e) => void this.emit(PlayerEvents.ERROR, e, message))) as Queue; - this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, res); - res.tracks.splice(startFromIndex, 1); - this._addTracksToQueue(message, res.tracks); - this.emit(PlayerEvents.TRACK_START, message, track, queue); - } - - return; - } - default: - tracks = await Util.ytSearch(query, { user: message.author, player: this }); - } - - if (tracks.length < 1) return void this.emit(PlayerEvents.NO_RESULTS, message, query); - if (firstResult || tracks.length === 1) return resolve(tracks[0]); - - const collectorString = `${message.author.id}-${message.channel.id}`; - const currentCollector = this._resultsCollectors.get(collectorString); - if (currentCollector) currentCollector.stop(); - - const collector = message.channel.createMessageCollector((m) => m.author.id === message.author.id, { - time: 60000 - }); - - this._resultsCollectors.set(collectorString, collector); - - this.emit(PlayerEvents.SEARCH_RESULTS, message, query, tracks, collector); - - collector.on('collect', ({ content }) => { - if (content === 'cancel') { - collector.stop(); - return this.emit(PlayerEvents.SEARCH_CANCEL, message, query, tracks); - } - - if (!isNaN(content) && parseInt(content) >= 1 && parseInt(content) <= tracks.length) { - const index = parseInt(content, 10); - const track = tracks[index - 1]; - collector.stop(); - resolve(track); - } else { - this.emit(PlayerEvents.SEARCH_INVALID_RESPONSE, message, query, tracks, content, collector); - } - }); - collector.on('end', (_, reason) => { - if (reason === 'time') { - this.emit(PlayerEvents.SEARCH_CANCEL, message, query, tracks); - } - }); - }); - } - - /** - * Play a song - * @param {DiscordMessage} message The discord.js message object - * @param {string|Track} query Search query, can be `Player.Track` instance - * @param {Boolean} [firstResult=false] If it should play the first result - * @param {number} [startFromIndex=0] Prioritise playing the track with following index (Only works with playlist) - * @example await player.play(message, "never gonna give you up", true) - * @returns {Promise} - */ - async play(message: Message, query: string | Track, firstResult?: boolean, startFromIndex = 0): Promise { - if (!message) throw new PlayerError('Play function needs message'); - if (!query) throw new PlayerError('Play function needs search query as a string or Player.Track object'); - - if (this._cooldownsTimeout.has(`end_${message.guild.id}`)) { - clearTimeout(this._cooldownsTimeout.get(`end_${message.guild.id}`)); - this._cooldownsTimeout.delete(`end_${message.guild.id}`); - } - - if (typeof query === 'string') query = query.replace(/<(.+)>/g, '$1'); - let track; - - if (query instanceof Track) track = query; - else { - if (ytdl.validateURL(query)) { - const info = await YouTube.getVideo(query).catch(() => {}); - if (!info) return void this.emit(PlayerEvents.NO_RESULTS, message, query); - if (info.live && !this.options.enableLive) return void this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.LIVE_VIDEO, message, new PlayerError('Live video is not enabled!')); - const lastThumbnail = typeof info.thumbnail === "string" ? info.thumbnail : info.thumbnail.url; - - track = new Track(this, { - title: info.title, - description: info.description || "", - author: info.channel.name, - url: info.url, - thumbnail: lastThumbnail, - duration: Util.buildTimeCode(Util.parseMS(info.duration * 1000)), - views: parseInt(info.views as unknown as string), - requestedBy: message.author, - fromPlaylist: false, - source: 'youtube', - live: Boolean(info.live) - }); - } else { - for (const [_, extractor] of this.Extractors) { - if (extractor.validate(query)) { - const data = await extractor.handle(query); - if (data) { - track = new Track(this, { - title: data.title, - description: data.description, - duration: Util.buildTimeCode(Util.parseMS(data.duration)), - thumbnail: data.thumbnail, - author: data.author, - views: data.views, - engine: data.engine, - source: data.source ?? 'arbitrary', - fromPlaylist: false, - requestedBy: message.author, - url: data.url - }); - - if (extractor.important) break; - } - } - } - - if (!track) track = await this._searchTracks(message, query, firstResult, startFromIndex); - } - } - - if (track) { - if (this.isPlaying(message)) { - const queue = this._addTrackToQueue(message, track); - this.emit(PlayerEvents.TRACK_ADD, message, queue, queue.tracks[queue.tracks.length - 1]); - } else { - const queue = await this._createQueue(message, track); - if (queue) this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue); + if ((nv = Util.require("@discord-player/extractor"))) { + ["Attachment", "Facebook", "Reverbnation", "Vimeo"].forEach((ext) => void this.use(ext, nv[ext])); } } } /** - * Checks if this player is playing in a server - * @param {DiscordMessage} message The message object - * @returns {Boolean} - */ - isPlaying(message: Message): boolean { - return this.queues.some((g) => g.guildID === message.guild.id); - } - - /** - * Returns guild queue object - * @param {DiscordMessage} message The message object - * @returns {Queue} - */ - getQueue(message: Message): Queue { - return this.queues.find((g) => g.guildID === message.guild.id); - } - - /** - * Sets audio filters in this player - * @param {DiscordMessage} message The message object - * @param {QueueFilters} newFilters Audio filters object - * @returns {Promise} - */ - setFilters(message: Message, newFilters: QueueFilters): Promise { - return new Promise((resolve) => { - const queue = this.queues.find((g) => g.guildID === message.guild.id); - if (!queue) this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message, new PlayerError('Not playing')); - - if (queue.playing.raw.live) return void this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.LIVE_VIDEO, message, new PlayerError('Cannot use setFilters on livestream')); - - Object.keys(newFilters).forEach((filterName) => { - // @ts-ignore - queue.filters[filterName] = newFilters[filterName]; - }); - - this._playStream(queue, true).then(() => { - resolve(); - }); - }); - } - - /** - * Sets track position - * @param {DiscordMessage} message The message object - * @param {Number} time Time in ms to set - * @returns {Promise} - */ - setPosition(message: Message, time: number): Promise { - return new Promise((resolve) => { - const queue = this.queues.find((g) => g.guildID === message.guild.id); - if (!queue) return this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - - if (typeof time !== 'number' && !isNaN(time)) time = parseInt(time); - if (queue.playing.durationMS <= time) return this.skip(message); - if (queue.voiceConnection.dispatcher.streamTime === time || queue.voiceConnection.dispatcher.streamTime + queue.additionalStreamTime === time) return resolve(); - if (time < 0) this._playStream(queue, false).then(() => resolve()); - - this._playStream(queue, false, time).then(() => resolve()); - }); - } - - /** - * Sets track position - * @param {DiscordMessage} message The message object - * @param {Number} time Time in ms to set - * @returns {Promise} - */ - seek(message: Message, time: number): Promise { - return this.setPosition(message, time); - } - - /** - * Skips current track - * @param {DiscordMessage} message The message object - * @returns {Boolean} - */ - skip(message: Message): boolean { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return false; - } - if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); - return false; - } - - queue.voiceConnection.dispatcher.end(); - queue.lastSkipped = true; - - return true; - } - - /** - * Moves to a new voice channel - * @param {DiscordMessage} message The message object - * @param {DiscordVoiceChannel} channel New voice channel to move to - * @returns {Boolean} - */ - moveTo(message: Message, channel?: VoiceChannel): boolean { - if (!channel || channel.type !== 'voice') return; - const queue = this.queues.find((g) => g.guildID === message.guild.id); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return false; - } - if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); - return false; - } - if (queue.voiceConnection.channel.id === channel.id) return; - - queue.voiceConnection.dispatcher.pause(); - channel - .join() - .then(() => queue.voiceConnection.dispatcher.resume()) - .catch(() => this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.UNABLE_TO_JOIN, message)); - - return true; - } - - /** - * Pause the playback - * @param {DiscordMessage} message The message object - * @returns {Boolean} - */ - pause(message: Message): boolean { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return false; - } - if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); - return false; - } - - queue.voiceConnection.dispatcher.pause(); - queue.paused = true; - return true; - } - - /** - * Resume the playback - * @param {DiscordMessage} message The message object - * @returns {Boolean} - */ - resume(message: Message): boolean { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return false; - } - if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); - return false; - } - - queue.voiceConnection.dispatcher.resume(); - queue.paused = false; - return true; - } - - /** - * Stops the player - * @param {DiscordMessage} message The message object - * @returns {Boolean} - */ - stop(message: Message): boolean { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return false; - } - if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); - return false; - } - - queue.stopped = true; - queue.tracks = []; - if (queue.stream) queue.stream.destroy(); - queue.voiceConnection.dispatcher.end(); - if (this.options.leaveOnStop) queue.voiceConnection.channel.leave(); - this.queues.delete(message.guild.id); - return true; - } - - /** - * Sets music volume - * @param {DiscordMessage} message The message object - * @param {Number} percent The volume percentage/amount to set - * @returns {Boolean} - */ - setVolume(message: Message, percent: number): boolean { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return false; - } - if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); - return false; - } - - queue.volume = percent; - queue.voiceConnection.dispatcher.setVolumeLogarithmic(queue.calculatedVolume / 200); - - return true; - } - - /** - * Clears the queue - * @param {DiscordMessage} message The message object - * @returns {Boolean} - */ - clearQueue(message: Message): boolean { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return false; - } - - queue.tracks = queue.playing ? [queue.playing] : []; - - return true; - } - - /** - * Plays previous track - * @param {DiscordMessage} message The message object - * @returns {Boolean} - */ - back(message: Message): boolean { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return false; - } - if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); - return false; - } - - queue.tracks.splice(1, 0, queue.previousTracks.shift()); - queue.voiceConnection.dispatcher.end(); - queue.lastSkipped = true; - - return true; - } - - /** - * Sets repeat mode - * @param {DiscordMessage} message The message object - * @param {Boolean} enabled If it should enable the repeat mode - */ - setRepeatMode(message: Message, enabled: boolean): boolean { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return; - } - - queue.repeatMode = Boolean(enabled); - - return queue.repeatMode; - } - - /** - * Sets loop mode - * @param {DiscordMessage} message The message object - * @param {Boolean} enabled If it should enable the loop mode - * @returns {Boolean} - */ - setLoopMode(message: Message, enabled: boolean): boolean { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return; - } - - queue.loopMode = Boolean(enabled); - - return queue.loopMode; - } - - /** - * Returns currently playing track - * @param {DiscordMessage} message The message object - * @returns {Track} - */ - nowPlaying(message: Message): Track { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return; - } - - return queue.tracks[0]; - } - - /** - * Shuffles the queue - * @param {DiscordMessage} message The message object - * @returns {Queue} - */ - shuffle(message: Message): Queue { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return; - } - - const currentTrack = queue.tracks.shift(); - - for (let i = queue.tracks.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [queue.tracks[i], queue.tracks[j]] = [queue.tracks[j], queue.tracks[i]]; - } - - queue.tracks.unshift(currentTrack); - - return queue; - } - - /** - * Removes specified track - * @param {DiscordMessage} message The message object - * @param {Track|number} track The track object/id to remove - * @returns {Track} - */ - remove(message: Message, track: Track | number): Track { - const queue = this.getQueue(message); - if (!queue) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - return; - } - - let trackFound: Track = null; - if (typeof track === 'number') { - trackFound = queue.tracks[track]; - if (trackFound) { - queue.tracks = queue.tracks.filter((t) => t !== trackFound); - } - } else { - trackFound = queue.tracks.find((s) => s.url === track.url); - if (trackFound) { - queue.tracks = queue.tracks.filter((s) => s.url !== trackFound.url); - } - } - - return trackFound; - } - - /** - * Returns time code of currently playing song - * @param {DiscordMessage} message The message object - * @param {Boolean} [queueTime] If it should make the time code of the whole queue - * @returns {Object} - */ - getTimeCode(message: Message, queueTime?: boolean): { current: string; end: string } { - const queue = this.getQueue(message); - if (!queue) return; - - const previousTracksTime = queue.previousTracks.length > 0 ? queue.previousTracks.reduce((p, c) => p + c.durationMS, 0) : 0; - const currentStreamTime = queueTime ? previousTracksTime + queue.currentStreamTime : queue.currentStreamTime; - const totalTracksTime = queue.totalTime; - const totalTime = queueTime ? previousTracksTime + totalTracksTime : queue.playing.durationMS; - - const currentTimecode = Util.buildTimeCode(Util.parseMS(currentStreamTime)); - const endTimecode = Util.buildTimeCode(Util.parseMS(totalTime)); - - return { - current: currentTimecode, - end: endTimecode - }; - } - - /** - * Creates progressbar - * @param {DiscordMessage} message The message object - * @param {PlayerProgressbarOptions} [options] Progressbar options - * @returns {String} - */ - createProgressBar(message: Message, options?: PlayerProgressbarOptions): string { - const queue = this.getQueue(message); - if (!queue) return; - - const previousTracksTime = queue.previousTracks.length > 0 ? queue.previousTracks.reduce((p, c) => p + c.durationMS, 0) : 0; - const currentStreamTime = options?.queue ? previousTracksTime + queue.currentStreamTime : queue.currentStreamTime; - const totalTracksTime = queue.totalTime; - const totalTime = options?.queue ? previousTracksTime + totalTracksTime : queue.playing.durationMS; - const length = typeof options?.length === 'number' ? (options?.length <= 0 || options?.length === Infinity ? 15 : options?.length) : 15; - - const index = Math.round((currentStreamTime / totalTime) * length); - const indicator = typeof options?.indicator === 'string' && options?.indicator.length > 0 ? options?.indicator : '🔘'; - const line = typeof options?.line === 'string' && options?.line.length > 0 ? options?.line : '▬'; - - if (index >= 1 && index <= length) { - const bar = line.repeat(length - 1).split(''); - bar.splice(index, 0, indicator); - if (Boolean(options?.timecodes)) { - const currentTimecode = Util.buildTimeCode(Util.parseMS(currentStreamTime)); - const endTimecode = Util.buildTimeCode(Util.parseMS(totalTime)); - return `${currentTimecode} ┃ ${bar.join('')} ┃ ${endTimecode}`; - } else { - return `${bar.join('')}`; - } - } else { - if (Boolean(options?.timecodes)) { - const currentTimecode = Util.buildTimeCode(Util.parseMS(currentStreamTime)); - const endTimecode = Util.buildTimeCode(Util.parseMS(totalTime)); - return `${currentTimecode} ┃ ${indicator}${line.repeat(length - 1)} ┃ ${endTimecode}`; - } else { - return `${indicator}${line.repeat(length - 1)}`; - } - } - } - - /** - * Gets lyrics of a song - * You need to have `@discord-player/extractor` installed in order to use this method! - * @param {String} query Search query - * @example const lyrics = await player.lyrics("alan walker faded") - * message.channel.send(lyrics.lyrics); - * @returns {Promise} - */ - async lyrics(query: string): Promise { - const extractor = Util.require('@discord-player/extractor'); - if (!extractor) throw new PlayerError("Cannot call 'Player.lyrics()' without '@discord-player/extractor'"); - - const data = await extractor.Lyrics.init().search(query); - if (Array.isArray(data)) return null; - - return data; - } - - /** - * Toggle autoplay for youtube streams - * @param {DiscordMessage} message The message object - * @param {Boolean} enable Enable/Disable autoplay - * @returns {boolean} - */ - setAutoPlay(message: Message, enable: boolean): boolean { - const queue = this.getQueue(message); - if (!queue) return void this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); - - queue.autoPlay = Boolean(enable); - - return queue.autoPlay; - } - - /** - * Player stats - * @returns {PlayerStats} - */ - getStats(): PlayerStats { - return { - uptime: this.client.uptime, - connections: this.client.voice.connections.size, - // tslint:disable:no-shadowed-variable - users: this.client.voice.connections.reduce((a, c) => a + c.channel.members.filter((a) => a.user.id !== this.client.user.id).size, 0), - queues: this.queues.size, - extractors: this.Extractors.size, - versions: { - ffmpeg: Util.getFFmpegVersion(), - node: process.version, - v8: process.versions.v8 - }, - system: { - arch: process.arch, - // @ts-ignore - platform: process.platform, - cpu: os.cpus().length, - memory: { - total: (process.memoryUsage().heapTotal / 1024 / 1024).toFixed(2), - usage: (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2), - rss: (process.memoryUsage().rss / 1024 / 1024).toFixed(2), - arrayBuffers: (process.memoryUsage().arrayBuffers / 1024 / 1024).toFixed(2) - }, - uptime: process.uptime() - } - }; - } - - /** - * Jumps to particular track - * @param {DiscordMessage} message The message - * @param {Track|number} track The track to jump to - * @returns {boolean} - */ - jump(message: Message, track: Track | number): boolean { - const toJUMP = this.remove(message, track); - const queue = this.getQueue(message); - if (!toJUMP || !queue) throw new PlayerError('Specified Track not found'); - - queue.tracks.splice(1, 0, toJUMP); - - return this.skip(message); - } - - /** - * Internal method to handle VoiceStateUpdate events - * @param {DiscordVoiceState} oldState The old voice state - * @param {DiscordVoiceState} newState The new voice state + * Handles voice state update + * @param {VoiceState} oldState The old voice state + * @param {VoiceState} newState The new voice state * @returns {void} * @private */ - private _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState): void { - const queue = this.queues.find((g) => g.guildID === oldState.guild.id); + private _handleVoiceState(oldState: VoiceState, newState: VoiceState): void { + const queue = this.getQueue(oldState.guild.id); if (!queue) return; - if (newState.member.id === this.client.user.id && !newState.channelID) { - queue.stream.destroy(); - this.queues.delete(newState.guild.id); - this.emit(PlayerEvents.BOT_DISCONNECT, queue.firstMessage); + if (oldState.channelId && newState.channelId && oldState.channelId !== newState.channelId) { + queue.connection.channel = newState.channel; } - if (!queue.voiceConnection || !queue.voiceConnection.channel) return; - if (!this.options.leaveOnEmpty) return; + if (!oldState.channelId && newState.channelId && newState.member.id === newState.guild.me.id) { + if (newState.serverMute || !newState.serverMute) { + queue.setPaused(newState.serverMute); + } else if (newState.suppress || !newState.suppress) { + if (newState.suppress) newState.guild.me.voice.setRequestToSpeak(true).catch(Util.noop); + queue.setPaused(newState.suppress); + } + } - if (!oldState.channelID || newState.channelID) { - const emptyTimeout = this._cooldownsTimeout.get(`empty_${oldState.guild.id}`); + if (oldState.channelId === newState.channelId && oldState.member.id === newState.guild.me.id) { + if (oldState.serverMute !== newState.serverMute) { + queue.setPaused(newState.serverMute); + } else if (oldState.suppress !== newState.suppress) { + if (newState.suppress) newState.guild.me.voice.setRequestToSpeak(true).catch(Util.noop); + queue.setPaused(newState.suppress); + } + } + + if (oldState.member.id === this.client.user.id && !newState.channelId) { + queue.destroy(); + return void this.emit("botDisconnect", queue); + } + + if (!queue.options.leaveOnEmpty || !queue.connection || !queue.connection.channel) return; + + if (!oldState.channelId || newState.channelId) { + const emptyTimeout = queue._cooldownsTimeout.get(`empty_${oldState.guild.id}`); + const channelEmpty = Util.isVoiceEmpty(queue.connection.channel); - // @todo: make stage channels stable - const channelEmpty = Util.isVoiceEmpty(queue.voiceConnection.channel as VoiceChannel); if (!channelEmpty && emptyTimeout) { clearTimeout(emptyTimeout); - this._cooldownsTimeout.delete(`empty_${oldState.guild.id}`); + queue._cooldownsTimeout.delete(`empty_${oldState.guild.id}`); } } else { - if (!Util.isVoiceEmpty(queue.voiceConnection.channel as VoiceChannel)) return; + if (!Util.isVoiceEmpty(queue.connection.channel)) return; const timeout = setTimeout(() => { - if (!Util.isVoiceEmpty(queue.voiceConnection.channel as VoiceChannel)) return; - if (!this.queues.has(queue.guildID)) return; - queue.voiceConnection.channel.leave(); - this.queues.delete(queue.guildID); - this.emit(PlayerEvents.CHANNEL_EMPTY, queue.firstMessage, queue); - }, this.options.leaveOnEmptyCooldown || 0); - this._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout); + if (!Util.isVoiceEmpty(queue.connection.channel)) return; + if (!this.queues.has(queue.guild.id)) return; + queue.destroy(); + this.emit("channelEmpty", queue); + }, queue.options.leaveOnEmptyCooldown || 0).unref(); + queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout); } } /** - * Internal method used to add tracks to the queue - * @param {DiscordMessage} message The discord message - * @param {Track} track The track + * Creates a queue for a guild if not available, else returns existing queue + * @param {GuildResolvable} guild The guild + * @param {PlayerOptions} queueInitOptions Queue init options * @returns {Queue} - * @private */ - _addTrackToQueue(message: Message, track: Track): Queue { - const queue = this.getQueue(message); - if (!queue) this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message, new PlayerError('Player is not available in this server')); - if (!track || !(track instanceof Track)) throw new PlayerError('No track specified to add to the queue'); - queue.tracks.push(track); - return queue; + createQueue(guild: GuildResolvable, queueInitOptions: PlayerOptions & { metadata?: T } = {}): Queue { + guild = this.client.guilds.resolve(guild); + if (!guild) throw new PlayerError("Unknown Guild", ErrorStatusCode.UNKNOWN_GUILD); + if (this.queues.has(guild.id)) return this.queues.get(guild.id) as Queue; + + const _meta = queueInitOptions.metadata; + delete queueInitOptions["metadata"]; + queueInitOptions.ytdlOptions ??= this.options.ytdlOptions; + const queue = new Queue(this, guild, queueInitOptions); + queue.metadata = _meta; + this.queues.set(guild.id, queue); + + return queue as Queue; } /** - * Same as `_addTrackToQueue` but used for multiple tracks - * @param {DiscordMessage} message Discord message - * @param {Track[]} tracks The tracks + * Returns the queue if available + * @param {GuildResolvable} guild The guild id * @returns {Queue} - * @private */ - _addTracksToQueue(message: Message, tracks: Track[]): Queue { - const queue = this.getQueue(message); - if (!queue) throw new PlayerError('Cannot add tracks to queue because no song is currently being played on the server.'); - queue.tracks.push(...tracks); - return queue; + getQueue(guild: GuildResolvable) { + guild = this.client.guilds.resolve(guild); + if (!guild) throw new PlayerError("Unknown Guild", ErrorStatusCode.UNKNOWN_GUILD); + return this.queues.get(guild.id) as Queue; } /** - * Internal method used to create queue - * @param {DiscordMessage} message The message - * @param {Track} track The track - * @returns {Promise} - * @private + * Deletes a queue and returns deleted queue object + * @param {GuildResolvable} guild The guild id to remove + * @returns {Queue} */ - private _createQueue(message: Message, track: Track): Promise { - return new Promise((resolve) => { - const channel = message.member.voice ? message.member.voice.channel : null; - if (!channel) return void this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_CONNECTED, message, new PlayerError('Voice connection is not available in this server!')); + deleteQueue(guild: GuildResolvable) { + guild = this.client.guilds.resolve(guild); + if (!guild) throw new PlayerError("Unknown Guild", ErrorStatusCode.UNKNOWN_GUILD); + const prev = this.getQueue(guild); - const queue = new Queue(this, message); - queue.volume = this.options.volume || 100; - this.queues.set(message.guild.id, queue); + try { + prev.destroy(); + } catch {} // eslint-disable-line no-empty + this.queues.delete(guild.id); - channel - .join() - .then((connection) => { - this.emit(PlayerEvents.CONNECTION_CREATE, message, connection); + return prev; + } - queue.voiceConnection = connection; - if (this.options.autoSelfDeaf) connection.voice.setSelfDeaf(true); - queue.tracks.push(track); - this.emit(PlayerEvents.QUEUE_CREATE, message, queue); - resolve(queue); - this._playTrack(queue, true).catch((e) => { - this.emit(PlayerEvents.ERROR, e, queue.firstMessage, queue.playing); + /** + * @typedef {object} SearchResult + * @property {Playlist} [playlist] The playlist (if any) + * @property {Track[]} tracks The tracks + */ + /** + * Search tracks + * @param {string|Track} query The search query + * @param {SearchOptions} options The search options + * @returns {Promise} + */ + async search(query: string | Track, options: SearchOptions) { + if (query instanceof Track) return { playlist: null, tracks: [query] }; + if (!options) throw new PlayerError("DiscordPlayer#search needs search options!", ErrorStatusCode.INVALID_ARG_TYPE); + options.requestedBy = this.client.users.resolve(options.requestedBy); + if (!("searchEngine" in options)) options.searchEngine = QueryType.AUTO; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + for (const [_, extractor] of this.extractors) { + if (options.blockExtractor) break; + if (!extractor.validate(query)) continue; + const data = await extractor.handle(query); + if (data && data.data.length) { + const playlist = !data.playlist + ? null + : new Playlist(this, { + ...data.playlist, + tracks: [] + }); + + const tracks = data.data.map( + (m) => + new Track(this, { + ...m, + requestedBy: options.requestedBy as User, + duration: Util.buildTimeCode(Util.parseMS(m.duration)), + playlist: playlist + }) + ); + + if (playlist) playlist.tracks = tracks; + + return { playlist: playlist, tracks: tracks }; + } + } + + const qt = options.searchEngine === QueryType.AUTO ? QueryResolver.resolve(query) : options.searchEngine; + switch (qt) { + case QueryType.YOUTUBE_SEARCH: { + const videos = await YouTube.search(query, { + type: "video" + }).catch(Util.noop); + if (!videos) return { playlist: null, tracks: [] }; + + const tracks = videos.map((m) => { + (m as any).source = "youtube"; // eslint-disable-line @typescript-eslint/no-explicit-any + return new Track(this, { + title: m.title, + description: m.description, + author: m.channel?.name, + url: m.url, + requestedBy: options.requestedBy as User, + thumbnail: m.thumbnail?.displayThumbnailURL("maxresdefault"), + views: m.views, + duration: m.durationFormatted, + raw: m }); - }) - .catch((err) => { - this.queues.delete(message.guild.id); - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.UNABLE_TO_JOIN, message, new PlayerError(err.message ?? err)); }); - }); + + return { playlist: null, tracks }; + } + case QueryType.SOUNDCLOUD_TRACK: + case QueryType.SOUNDCLOUD_SEARCH: { + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-empty-function + const result: any[] = QueryResolver.resolve(query) === QueryType.SOUNDCLOUD_TRACK ? [{ url: query }] : await soundcloud.search(query, "track").catch(Util.noop); + if (!result || !result.length) return { playlist: null, tracks: [] }; + const res: Track[] = []; + + for (const r of result) { + const trackInfo = await soundcloud.getSongInfo(r.url).catch(Util.noop); + if (!trackInfo) continue; + + const track = new Track(this, { + title: trackInfo.title, + url: trackInfo.url, + duration: Util.buildTimeCode(Util.parseMS(trackInfo.duration)), + description: trackInfo.description, + thumbnail: trackInfo.thumbnail, + views: trackInfo.playCount, + author: trackInfo.author.name, + requestedBy: options.requestedBy, + source: "soundcloud", + engine: trackInfo + }); + + res.push(track); + } + + return { playlist: null, tracks: res }; + } + case QueryType.SPOTIFY_SONG: { + const spotifyData = await Spotify.getData(query).catch(Util.noop); + if (!spotifyData) return { playlist: null, tracks: [] }; + const spotifyTrack = new Track(this, { + title: spotifyData.name, + description: spotifyData.description ?? "", + author: spotifyData.artists[0]?.name ?? "Unknown Artist", + url: spotifyData.external_urls?.spotify ?? query, + thumbnail: + spotifyData.album?.images[0]?.url ?? spotifyData.preview_url?.length + ? `https://i.scdn.co/image/${spotifyData.preview_url?.split("?cid=")[1]}` + : "https://www.scdn.co/i/_global/twitter_card-default.jpg", + duration: Util.buildTimeCode(Util.parseMS(spotifyData.duration_ms)), + views: 0, + requestedBy: options.requestedBy, + source: "spotify" + }); + + return { playlist: null, tracks: [spotifyTrack] }; + } + case QueryType.SPOTIFY_PLAYLIST: + case QueryType.SPOTIFY_ALBUM: { + const spotifyPlaylist = await Spotify.getData(query).catch(Util.noop); + if (!spotifyPlaylist) return { playlist: null, tracks: [] }; + + const playlist = new Playlist(this, { + title: spotifyPlaylist.name ?? spotifyPlaylist.title, + description: spotifyPlaylist.description ?? "", + thumbnail: spotifyPlaylist.images[0]?.url ?? "https://www.scdn.co/i/_global/twitter_card-default.jpg", + type: spotifyPlaylist.type, + source: "spotify", + author: + spotifyPlaylist.type !== "playlist" + ? { + name: spotifyPlaylist.artists[0]?.name ?? "Unknown Artist", + url: spotifyPlaylist.artists[0]?.external_urls?.spotify ?? null + } + : { + name: spotifyPlaylist.owner?.display_name ?? spotifyPlaylist.owner?.id ?? "Unknown Artist", + url: spotifyPlaylist.owner?.external_urls?.spotify ?? null + }, + tracks: [], + id: spotifyPlaylist.id, + url: spotifyPlaylist.external_urls?.spotify ?? query, + rawPlaylist: spotifyPlaylist + }); + + if (spotifyPlaylist.type !== "playlist") { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + playlist.tracks = spotifyPlaylist.tracks.items.map((m: any) => { + const data = new Track(this, { + title: m.name ?? "", + description: m.description ?? "", + author: m.artists[0]?.name ?? "Unknown Artist", + url: m.external_urls?.spotify ?? query, + thumbnail: spotifyPlaylist.images[0]?.url ?? "https://www.scdn.co/i/_global/twitter_card-default.jpg", + duration: Util.buildTimeCode(Util.parseMS(m.duration_ms)), + views: 0, + requestedBy: options.requestedBy as User, + playlist, + source: "spotify" + }); + + return data; + }) as Track[]; + } else { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + playlist.tracks = spotifyPlaylist.tracks.items.map((m: any) => { + const data = new Track(this, { + title: m.track.name ?? "", + description: m.track.description ?? "", + author: m.track.artists[0]?.name ?? "Unknown Artist", + url: m.track.external_urls?.spotify ?? query, + thumbnail: m.track.album?.images[0]?.url ?? "https://www.scdn.co/i/_global/twitter_card-default.jpg", + duration: Util.buildTimeCode(Util.parseMS(m.track.duration_ms)), + views: 0, + requestedBy: options.requestedBy as User, + playlist, + source: "spotify" + }); + + return data; + }) as Track[]; + } + + return { playlist: playlist, tracks: playlist.tracks }; + } + case QueryType.SOUNDCLOUD_PLAYLIST: { + const data = await SoundCloud.getPlaylist(query).catch(Util.noop); + if (!data) return { playlist: null, tracks: [] }; + + const res = new Playlist(this, { + title: data.title, + description: data.description ?? "", + thumbnail: data.thumbnail ?? "https://soundcloud.com/pwa-icon-192.png", + type: "playlist", + source: "soundcloud", + author: { + name: data.author?.name ?? data.author?.username ?? "Unknown Artist", + url: data.author?.profile + }, + tracks: [], + id: `${data.id}`, // stringified + url: data.url, + rawPlaylist: data + }); + + for (const song of data) { + const track = new Track(this, { + title: song.title, + description: song.description ?? "", + author: song.author?.username ?? song.author?.name ?? "Unknown Artist", + url: song.url, + thumbnail: song.thumbnail, + duration: Util.buildTimeCode(Util.parseMS(song.duration)), + views: song.playCount ?? 0, + requestedBy: options.requestedBy, + playlist: res, + source: "soundcloud", + engine: song + }); + res.tracks.push(track); + } + + return { playlist: res, tracks: res.tracks }; + } + case QueryType.YOUTUBE_PLAYLIST: { + const ytpl = await YouTube.getPlaylist(query).catch(Util.noop); + if (!ytpl) return { playlist: null, tracks: [] }; + + await ytpl.fetch().catch(Util.noop); + + const playlist: Playlist = new Playlist(this, { + title: ytpl.title, + thumbnail: ytpl.thumbnail as unknown as string, + description: "", + type: "playlist", + source: "youtube", + author: { + name: ytpl.channel.name, + url: ytpl.channel.url + }, + tracks: [], + id: ytpl.id, + url: ytpl.url, + rawPlaylist: ytpl + }); + + playlist.tracks = ytpl.videos.map( + (video) => + new Track(this, { + title: video.title, + description: video.description, + author: video.channel?.name, + url: video.url, + requestedBy: options.requestedBy as User, + thumbnail: video.thumbnail.url, + views: video.views, + duration: video.durationFormatted, + raw: video, + playlist: playlist, + source: "youtube" + }) + ); + + return { playlist: playlist, tracks: playlist.tracks }; + } + default: + return { playlist: null, tracks: [] }; + } } /** - * Internal method used to init stream playing - * @param {Queue} queue The queue - * @param {boolean} firstPlay If this is a first play - * @returns {Promise} - * @private + * Registers extractor + * @param {string} extractorName The extractor name + * @param {ExtractorModel|any} extractor The extractor object + * @param {boolean} [force=false] Overwrite existing extractor with this name (if available) + * @returns {ExtractorModel} */ - private async _playTrack(queue: Queue, firstPlay: boolean): Promise { - if (queue.stopped) return; - - if (!(queue.autoPlay && ['youtube', 'spotify'].includes(queue.playing?.source)) && queue.tracks.length === 1 && !queue.loopMode && !queue.repeatMode && !firstPlay) { - if (this.options.leaveOnEnd && !queue.stopped) { - this.queues.delete(queue.guildID); - const timeout = setTimeout(() => { - queue.voiceConnection.channel.leave(); - }, this.options.leaveOnEndCooldown || 0); - this._cooldownsTimeout.set(`end_${queue.guildID}`, timeout); - } - - this.queues.delete(queue.guildID); - - if (queue.stopped) { - return void this.emit(PlayerEvents.MUSIC_STOP, queue.firstMessage); - } - - return void this.emit(PlayerEvents.QUEUE_END, queue.firstMessage, queue); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + use(extractorName: string, extractor: ExtractorModel | any, force = false): ExtractorModel { + if (!extractorName) throw new PlayerError("Cannot use unknown extractor!", ErrorStatusCode.UNKNOWN_EXTRACTOR); + if (this.extractors.has(extractorName) && !force) return this.extractors.get(extractorName); + if (extractor instanceof ExtractorModel) { + this.extractors.set(extractorName, extractor); + return extractor; } - if (queue.autoPlay && !queue.repeatMode && !firstPlay) { - const oldTrack = queue.tracks.shift(); - - const info = ['youtube', 'spotify'].includes(oldTrack?.raw.source) ? await ytdl.getInfo((oldTrack as any).backupLink ?? oldTrack.url).catch((e) => {}) : null; - if (info) { - const res = await Util.ytSearch(info.related_videos[0].title, { - player: this, - limit: 1, - user: oldTrack.requestedBy - }) - .then((v) => v[0]) - .catch((e) => {}); - - if (res) { - queue.tracks.push(res); - if (queue.loopMode) queue.tracks.push(oldTrack); - queue.previousTracks.push(oldTrack); - } - } - } else if (!queue.autoPlay && !queue.repeatMode && !firstPlay) { - const oldTrack = queue.tracks.shift(); - if (queue.loopMode) queue.tracks.push(oldTrack); - queue.previousTracks.push(oldTrack); + for (const method of ["validate", "getInfo"]) { + if (typeof extractor[method] !== "function") throw new PlayerError("Invalid extractor data!", ErrorStatusCode.INVALID_EXTRACTOR); } - const track = queue.playing; + const model = new ExtractorModel(extractorName, extractor); + this.extractors.set(model.name, model); - queue.lastSkipped = false; - this._playStream(queue, false) - .then(() => { - if (!firstPlay) this.emit(PlayerEvents.TRACK_START, queue.firstMessage, track, queue); - }) - .catch((e) => { - this.emit(PlayerEvents.ERROR, e, queue.firstMessage, queue.playing); - }); + return model; } /** - * Internal method to play audio - * @param {Queue} queue The queue - * @param {boolean} updateFilter If this method was called for audio filter update - * @param {number} [seek] Time in ms to seek to - * @returns {Promise} - * @private + * Removes registered extractor + * @param {string} extractorName The extractor name + * @returns {ExtractorModel} */ - private _playStream(queue: Queue, updateFilter: boolean, seek?: number): Promise { - return new Promise(async (resolve) => { - const ffmpeg = Util.checkFFmpeg(); - if (!ffmpeg) return; - - const seekTime = typeof seek === 'number' ? seek : updateFilter ? queue.voiceConnection.dispatcher.streamTime + queue.additionalStreamTime : undefined; - const encoderArgsFilters: string[] = []; - - Object.keys(queue.filters).forEach((filterName) => { - // @ts-ignore - if (queue.filters[filterName]) { - // @ts-ignore - encoderArgsFilters.push(this.filters[filterName]); - } - }); - - let encoderArgs: string[] = []; - if (encoderArgsFilters.length < 1) { - encoderArgs = []; - } else { - encoderArgs = ['-af', encoderArgsFilters.join(',')]; - } - - let newStream: any; - - if (!queue.playing?.raw?.source) return void this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.VIDEO_UNAVAILABLE, queue.firstMessage, queue.playing, new PlayerError("Don't know how to play this item", 'PlayerError')); - - // modify spotify - if (queue.playing.raw.source === 'spotify' && !(queue.playing as any).backupLink) { - const searchQueryString = this.options.disableArtistSearch ? queue.playing.title : `${queue.playing.title}${' - ' + queue.playing.author}`; - const yteqv = await YouTube.search(searchQueryString, { type: 'video', limit: 1 }).catch(() => {}); - - if (!yteqv || !yteqv.length) return void this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.VIDEO_UNAVAILABLE, queue.firstMessage, queue.playing, new PlayerError('Could not find alternative track on youtube!', 'SpotifyTrackError')); - - Util.define({ - target: queue.playing, - prop: 'backupLink', - value: yteqv[0].url - }); - } - - if (queue.playing.raw.source === 'youtube' || queue.playing.raw.source === 'spotify') { - newStream = ytdl((queue.playing as any).backupLink ?? queue.playing.url, { - opusEncoded: true, - encoderArgs: queue.playing.raw.live ? [] : encoderArgs, - seek: seekTime / 1000, - // tslint:disable-next-line:no-bitwise - highWaterMark: 1 << 25, - ...this.options.ytdlDownloadOptions - }); - } else { - newStream = ytdl.arbitraryStream(queue.playing.raw.source === 'soundcloud' ? await queue.playing.raw.engine.downloadProgressive() : queue.playing.raw.engine, { - opusEncoded: true, - encoderArgs, - seek: seekTime / 1000 - }); - } - - setTimeout(() => { - if (queue.stream) queue.stream.destroy(); - queue.stream = newStream; - queue.voiceConnection.play(newStream, { - type: 'opus', - bitrate: 'auto' - }); - - if (seekTime) { - queue.additionalStreamTime = seekTime; - } - queue.voiceConnection.dispatcher.setVolumeLogarithmic(queue.calculatedVolume / 200); - queue.voiceConnection.dispatcher.on('start', () => { - resolve(); - }); - - queue.voiceConnection.dispatcher.on('finish', () => { - queue.additionalStreamTime = 0; - return this._playTrack(queue, false); - }); - - newStream.on('error', (error: Error) => { - if (error.message.toLowerCase().includes('video unavailable')) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.VIDEO_UNAVAILABLE, queue.firstMessage, queue.playing, error); - this._playTrack(queue, false); - } else { - this.emit(PlayerEvents.ERROR, error, queue.firstMessage, error); - } - }); - }, 1000); - }); + unuse(extractorName: string) { + if (!this.extractors.has(extractorName)) throw new PlayerError(`Cannot find extractor "${extractorName}"`, ErrorStatusCode.UNKNOWN_EXTRACTOR); + const prev = this.extractors.get(extractorName); + this.extractors.delete(extractorName); + return prev; } - toString() { - return ``; + /** + * Generates a report of the dependencies used by the `@discordjs/voice` module. Useful for debugging. + * @returns {string} + */ + scanDeps() { + return generateDependencyReport(); + } + + /** + * Resolves qeuue + * @param {GuildResolvable|Queue} queueLike Queue like object + * @returns {Queue} + */ + resolveQueue(queueLike: GuildResolvable | Queue): Queue { + return this.getQueue(queueLike instanceof Queue ? queueLike.guild : queueLike); + } + + *[Symbol.iterator]() { + yield* Array.from(this.queues.values()); } } -export default Player; - -/** - * Emitted when a track starts - * @event Player#trackStart - * @param {DiscordMessage} message The message - * @param {Track} track The track - * @param {Queue} queue The queue - */ - -/** - * Emitted when a playlist is started - * @event Player#queueCreate - * @param {DiscordMessage} message The message - * @param {Queue} queue The queue - */ - -/** - * Emitted when the bot is awaiting search results - * @event Player#searchResults - * @param {DiscordMessage} message The message - * @param {String} query The query - * @param {Track[]} tracks The tracks - * @param {DiscordCollector} collector The collector - */ - -/** - * Emitted when the user has sent an invalid response for search results - * @event Player#searchInvalidResponse - * @param {DiscordMessage} message The message - * @param {String} query The query - * @param {Track[]} tracks The tracks - * @param {String} invalidResponse The `invalidResponse` string - * @param {DiscordCollector} collector The collector - */ - -/** - * Emitted when the bot has stopped awaiting search results (timeout) - * @event Player#searchCancel - * @param {DiscordMessage} message The message - * @param {String} query The query - * @param {Track[]} tracks The tracks - */ - -/** - * Emitted when the bot can't find related results to the query - * @event Player#noResults - * @param {DiscordMessage} message The message - * @param {String} query The query - */ - -/** - * Emitted when the bot is disconnected from the channel - * @event Player#botDisconnect - * @param {DiscordMessage} message The message - */ - -/** - * Emitted when the channel of the bot is empty - * @event Player#channelEmpty - * @param {DiscordMessage} message The message - * @param {Queue} queue The queue - */ - -/** - * Emitted when the queue of the server is ended - * @event Player#queueEnd - * @param {DiscordMessage} message The message - * @param {Queue} queue The queue - */ - -/** - * Emitted when a track is added to the queue - * @event Player#trackAdd - * @param {DiscordMessage} message The message - * @param {Queue} queue The queue - * @param {Track} track The track - */ - -/** - * Emitted when a playlist is added to the queue - * @event Player#playlistAdd - * @param {DiscordMessage} message The message - * @param {Queue} queue The queue - * @param {Object} playlist The playlist - */ - -/** - * Emitted when an error is triggered. - * This event should handled properly by the users otherwise it might crash the process! - * @event Player#error - * @param {String} error It can be `NotConnected`, `UnableToJoin`, `NotPlaying`, `ParseError`, `LiveVideo` or `VideoUnavailable`. - * @param {DiscordMessage} message The message - */ - -/** - * Emitted when discord-player attempts to parse playlist contents (mostly soundcloud playlists) - * @event Player#playlistParseStart - * @param {Object} playlist Raw playlist (unparsed) - * @param {DiscordMessage} message The message - */ - -/** - * Emitted when discord-player finishes parsing playlist contents (mostly soundcloud playlists) - * @event Player#playlistParseEnd - * @param {Object} playlist The playlist data (parsed) - * @param {DiscordMessage} message The message - */ - -/** - * @typedef {Object} PlayerOptions - * @property {Boolean} [leaveOnEnd=false] If it should leave on queue end - * @property {Number} [leaveOnEndCooldown=0] Time in ms to wait before executing `leaveOnEnd` - * @property {Boolean} [leaveOnStop=false] If it should leave on stop command - * @property {Boolean} [leaveOnEmpty=false] If it should leave on empty voice channel - * @property {Number} [leaveOnEmptyCooldown=0] Time in ms to wait before executing `leaveOnEmpty` - * @property {Boolean} [autoSelfDeaf=false] If it should set the client to `self deaf` mode on joining - * @property {Boolean} [enableLive=false] If it should enable live videos support - * @property {YTDLDownloadOptions} [ytdlDownloadOptions={}] The download options passed to `ytdl-core` - * @property {Boolean} [useSafeSearch=false] If it should use `safe search` method for youtube searches - * @property {Boolean} [disableAutoRegister=false] If it should disable auto-registeration of `@discord-player/extractor` - * @property {Boolean} [disableArtistSearch=false] If it should disable artist search for spotify - * @property {Boolean} [fetchBeforeQueued=false] If it should fetch all songs loaded from spotify before playing - * @property {Number} [volume=100] Startup player volume - */ - -/** - * The type of Track source, either: - * * `soundcloud` - a stream from SoundCloud - * * `youtube` - a stream from YouTube - * * `spotify` - a spotify track - * * `arbitrary` - arbitrary stream - * @typedef {String} TrackSource - */ - -/** - * @typedef {Object} TrackData - * @property {String} title The title - * @property {String} description The description - * @property {String} author The author - * @property {String} url The url - * @property {String} duration The duration - * @property {Number} views The view count - * @property {DiscordUser} requestedBy The user who requested this track - * @property {Boolean} fromPlaylist If this track came from a playlist - * @property {TrackSource} [source] The track source - * @property {string|Readable} [engine] The stream engine - * @property {Boolean} [live=false] If this track is livestream instance - */ - -/** - * @typedef {Object} QueueFilters - * The FFmpeg Filters - */ - -/** - * The query type, either: - * * `soundcloud_track` - a SoundCloud Track - * * `soundcloud_playlist` - a SoundCloud Playlist - * * `spotify_song` - a Spotify Song - * * `spotify_album` - a Spotify album - * * `spotify_playlist` - a Spotify playlist - * * `youtube_video` - a YouTube video - * * `youtube_playlist` - a YouTube playlist - * * `vimeo` - a Vimeo link - * * `facebook` - a Facebook link - * * `reverbnation` - a Reverbnation link - * * `attachment` - an attachment link - * * `youtube_search` - a YouTube search keyword - * @typedef {String} QueryType The query type - */ - -/** - * @typedef {Object} ExtractorModelData - * @property {String} title The title - * @property {Number} duration The duration in ms - * @property {String} thumbnail The thumbnail url - * @property {string|Readable} engine The audio engine - * @property {Number} views The views count of this stream - * @property {String} author The author - * @property {String} description The description - * @property {String} url The url - * @property {String} [version='0.0.0'] The extractor version - * @property {Boolean} [important=false] Mark as important - */ - -/** - * @typedef {Object} PlayerProgressbarOptions - * @property {Boolean} [timecodes] If it should return progres bar with time codes - * @property {Boolean} [queue] if it should return the progress bar of the whole queue - * @property {Number} [length] The length of progress bar to build - * @property {String} [indicator] The progress indicator - * @property {String} [line] The progress bar track - */ - -/** - * @typedef {Object} LyricsData - * @property {String} title The title of the lyrics - * @property {Number} id The song id - * @property {String} thumbnail The thumbnail - * @property {String} image The image - * @property {String} url The url - * @property {Object} artist The artist info - * @property {String} [artist.name] The name of the artist - * @property {Number} [artist.id] The ID of the artist - * @property {String} [artist.url] The profile link of the artist - * @property {String} [artist.image] The artist image url - * @property {String?} lyrics The lyrics - */ - -/** - * @typedef {Object} PlayerStats - * @property {Number} uptime The uptime in ms - * @property {Number} connections The number of connections - * @property {Number} users The number of users - * @property {Number} queues The number of queues - * @property {Number} extractors The number of custom extractors registered - * @property {Object} versions The versions metadata - * @property {String} [versions.ffmpeg] The ffmpeg version - * @property {String} [versions.node] The node version - * @property {String} [versions.v8] The v8 JavaScript engine version - * @property {Object} system The system data - * @property {String} [system.arch] The system arch - * @property {String} [system.platform] The system platform - * @property {Number} [system.cpu] The cpu count - * @property {Object} [system.memory] The memory info - * @property {String} [system.memory.total] The total memory - * @property {String} [system.memory.usage] The memory usage - * @property {String} [system.memory.rss] The memory usage in RSS - * @property {String} [system.memory.arrayBuffers] The memory usage in ArrayBuffers - * @property {Number} [system.uptime] The system uptime - */ - -/** - * @typedef {Object} TimeData - * @property {Number} days The time in days - * @property {Number} hours The time in hours - * @property {Number} minutes The time in minutes - * @property {Number} seconds The time in seconds - */ +export { Player }; diff --git a/src/Structures/ExtractorModel.ts b/src/Structures/ExtractorModel.ts index 578470a..f85d438 100644 --- a/src/Structures/ExtractorModel.ts +++ b/src/Structures/ExtractorModel.ts @@ -1,27 +1,34 @@ -import { ExtractorModelData } from '../types/types'; +import { ExtractorModelData } from "../types/types"; class ExtractorModel { name: string; - private _raw: any; + private _raw: any; // eslint-disable-line @typescript-eslint/no-explicit-any /** * Model for raw Discord Player extractors - * @param {String} extractorName Name of the extractor - * @param {Object} data Extractor object + * @param {string} extractorName Name of the extractor + * @param {object} data Extractor object */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(extractorName: string, data: any) { /** * The extractor name - * @type {String} + * @type {string} */ this.name = extractorName; - Object.defineProperty(this, '_raw', { value: data, configurable: false, writable: false, enumerable: false }); + /** + * The raw model + * @name ExtractorModel#_raw + * @type {any} + * @private + */ + Object.defineProperty(this, "_raw", { value: data, configurable: false, writable: false, enumerable: false }); } /** * Method to handle requests from `Player.play()` - * @param {String} query Query to handle + * @param {string} query Query to handle * @returns {Promise} */ async handle(query: string): Promise { @@ -29,21 +36,26 @@ class ExtractorModel { if (!data) return null; return { - title: data.title, - duration: data.duration, - thumbnail: data.thumbnail, - engine: data.engine, - views: data.views, - author: data.author, - description: data.description, - url: data.url + playlist: data.playlist ?? null, + data: + // eslint-disable-next-line @typescript-eslint/no-explicit-any + data.info?.map((m: any) => ({ + title: m.title, + duration: m.duration, + thumbnail: m.thumbnail, + engine: m.engine, + views: m.views, + author: m.author, + description: m.description, + url: m.url + })) ?? [] }; } /** * Method used by Discord Player to validate query with this extractor - * @param {String} query The query to validate - * @returns {Boolean} + * @param {string} query The query to validate + * @returns {boolean} */ validate(query: string): boolean { return Boolean(this._raw.validate(query)); @@ -51,20 +63,11 @@ class ExtractorModel { /** * The extractor version - * @type {String} + * @type {string} */ get version(): string { - return this._raw.version ?? '0.0.0'; - } - - /** - * If player should mark this extractor as important - * @type {Boolean} - */ - get important(): boolean { - return Boolean(this._raw.important); + return this._raw.version ?? "0.0.0"; } } -export default ExtractorModel; export { ExtractorModel }; diff --git a/src/Structures/PlayerError.ts b/src/Structures/PlayerError.ts new file mode 100644 index 0000000..bce0fbc --- /dev/null +++ b/src/Structures/PlayerError.ts @@ -0,0 +1,48 @@ +export enum ErrorStatusCode { + STREAM_ERROR = "StreamError", + AUDIO_PLAYER_ERROR = "AudioPlayerError", + PLAYER_ERROR = "PlayerError", + NO_AUDIO_RESOURCE = "NoAudioResource", + UNKNOWN_GUILD = "UnknownGuild", + INVALID_ARG_TYPE = "InvalidArgType", + UNKNOWN_EXTRACTOR = "UnknownExtractor", + INVALID_EXTRACTOR = "InvalidExtractor", + INVALID_CHANNEL_TYPE = "InvalidChannelType", + INVALID_TRACK = "InvalidTrack", + UNKNOWN_REPEAT_MODE = "UnknownRepeatMode", + TRACK_NOT_FOUND = "TrackNotFound", + NO_CONNECTION = "NoConnection", + DESTROYED_QUEUE = "DestroyedQueue" +} + +export class PlayerError extends Error { + message: string; + statusCode: ErrorStatusCode; + createdAt = new Date(); + + constructor(message: string, code: ErrorStatusCode = ErrorStatusCode.PLAYER_ERROR) { + super(); + + this.message = `[${code}] ${message}`; + this.statusCode = code; + this.name = code; + + Error.captureStackTrace(this); + } + + get createdTimestamp() { + return this.createdAt.getTime(); + } + + valueOf() { + return this.statusCode; + } + + toJSON() { + return { stack: this.stack, code: this.statusCode, created: this.createdTimestamp }; + } + + toString() { + return this.stack; + } +} diff --git a/src/Structures/Playlist.ts b/src/Structures/Playlist.ts new file mode 100644 index 0000000..d76dd66 --- /dev/null +++ b/src/Structures/Playlist.ts @@ -0,0 +1,138 @@ +import { Player } from "../Player"; +import { Track } from "./Track"; +import { PlaylistInitData, PlaylistJSON, TrackJSON, TrackSource } from "../types/types"; + +class Playlist { + public readonly player: Player; + public tracks: Track[]; + public title: string; + public description: string; + public thumbnail: string; + public type: "album" | "playlist"; + public source: TrackSource; + public author: { + name: string; + url: string; + }; + public id: string; + public url: string; + public readonly rawPlaylist?: any; // eslint-disable-line @typescript-eslint/no-explicit-any + + /** + * Playlist constructor + * @param {Player} player The player + * @param {PlaylistInitData} data The data + */ + constructor(player: Player, data: PlaylistInitData) { + /** + * The player + * @name Playlist#player + * @type {Player} + * @readonly + */ + this.player = player; + + /** + * The tracks in this playlist + * @name Playlist#tracks + * @type {Track[]} + */ + this.tracks = data.tracks ?? []; + + /** + * The author of this playlist + * @name Playlist#author + * @type {object} + */ + this.author = data.author; + + /** + * The description + * @name Playlist#description + * @type {string} + */ + this.description = data.description; + + /** + * The thumbnail of this playlist + * @name Playlist#thumbnail + * @type {string} + */ + this.thumbnail = data.thumbnail; + + /** + * The playlist type: + * - `album` + * - `playlist` + * @name Playlist#type + * @type {string} + */ + this.type = data.type; + + /** + * The source of this playlist: + * - `youtube` + * - `soundcloud` + * - `spotify` + * - `arbitrary` + * @name Playlist#source + * @type {string} + */ + this.source = data.source; + + /** + * The playlist id + * @name Playlist#id + * @type {string} + */ + this.id = data.id; + + /** + * The playlist url + * @name Playlist#url + * @type {string} + */ + this.url = data.url; + + /** + * The playlist title + * @type {string} + */ + this.title = data.title; + + /** + * @name Playlist#rawPlaylist + * @type {any} + * @readonly + */ + } + + *[Symbol.iterator]() { + yield* this.tracks; + } + + /** + * JSON representation of this playlist + * @param {boolean} [withTracks=true] If it should build json with tracks + * @returns {PlaylistJSON} + */ + toJSON(withTracks = true) { + const payload = { + id: this.id, + url: this.url, + title: this.title, + description: this.description, + thumbnail: this.thumbnail, + type: this.type, + source: this.source, + author: this.author, + tracks: [] as TrackJSON[] + }; + + if (withTracks) payload.tracks = this.tracks.map((m) => m.toJSON(true)); + + return payload as PlaylistJSON; + } +} + +export { Playlist }; diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index 7398466..ef3681c 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -1,146 +1,583 @@ -import { Message, Snowflake, VoiceConnection } from 'discord.js'; -import AudioFilters from '../utils/AudioFilters'; -import { Player } from '../Player'; -import { EventEmitter } from 'events'; -import { Track } from './Track'; -import { QueueFilters } from '../types/types'; +import { Collection, Guild, StageChannel, VoiceChannel, Snowflake, SnowflakeUtil, GuildChannelResolvable } from "discord.js"; +import { Player } from "../Player"; +import { StreamDispatcher } from "../VoiceInterface/StreamDispatcher"; +import Track from "./Track"; +import { PlayerOptions, PlayerProgressbarOptions, PlayOptions, QueueFilters, QueueRepeatMode } from "../types/types"; +import ytdl from "discord-ytdl-core"; +import { AudioResource, StreamType } from "@discordjs/voice"; +import { Util } from "../utils/Util"; +import YouTube from "youtube-sr"; +import AudioFilters from "../utils/AudioFilters"; +import { PlayerError, ErrorStatusCode } from "./PlayerError"; -export class Queue extends EventEmitter { - public player!: Player; - public guildID: Snowflake; - public voiceConnection?: VoiceConnection; - public stream?: any; - public tracks: Track[]; - public previousTracks: Track[]; - public stopped: boolean; - public lastSkipped: boolean; - public volume: number; - public paused: boolean; - public repeatMode: boolean; - public loopMode: boolean; - public filters: QueueFilters; - public additionalStreamTime: number; - public firstMessage: Message; - - /** - * If autoplay is enabled in this queue - * @type {boolean} - */ - public autoPlay = false; +class Queue { + public readonly guild: Guild; + public readonly player: Player; + public connection: StreamDispatcher; + public tracks: Track[] = []; + public previousTracks: Track[] = []; + public options: PlayerOptions; + public playing = false; + public metadata?: T = null; + public repeatMode: QueueRepeatMode = 0; + public readonly id: Snowflake = SnowflakeUtil.generate(); + private _streamTime = 0; + public _cooldownsTimeout = new Collection(); + private _activeFilters: any[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any + private _filtersUpdate = false; + #lastVolume = 0; + #destroyed = false; /** * Queue constructor - * @param {Player} player The player that instantiated this Queue - * @param {DiscordMessage} message The message object + * @param {Player} player The player that instantiated this queue + * @param {Guild} guild The guild that instantiated this queue + * @param {PlayerOptions} [options={}] Player options for the queue */ - constructor(player: Player, message: Message) { - super(); - + constructor(player: Player, guild: Guild, options: PlayerOptions = {}) { /** - * The player that instantiated this Queue - * @name Queue#player + * The player that instantiated this queue * @type {Player} * @readonly */ - Object.defineProperty(this, 'player', { value: player, enumerable: false }); + this.player = player; /** - * ID of the guild assigned to this queue - * @type {DiscordSnowflake} + * The guild that instantiated this queue + * @type {Guild} + * @readonly */ - this.guildID = message.guild.id; + this.guild = guild; /** - * The voice connection of this queue - * @type {DiscordVoiceConnection} + * The player options for this queue + * @type {PlayerOptions} */ - this.voiceConnection = null; + this.options = {}; /** - * Tracks of this queue + * Queue repeat mode + * @type {QueueRepeatMode} + * @name Queue#repeatMode + */ + + /** + * Queue metadata + * @type {any} + * @name Queue#metadata + */ + + /** + * Previous tracks * @type {Track[]} + * @name Queue#previousTracks */ - this.tracks = []; /** - * Previous tracks of this queue + * Regular tracks * @type {Track[]} + * @name Queue#tracks */ - this.previousTracks = []; /** - * If the player of this queue is stopped - * @type {boolean} + * The connection + * @type {StreamDispatcher} + * @name Queue#connection */ - this.stopped = false; /** - * If last track was skipped - * @type {boolean} + * The ID of this queue + * @type {Snowflake} + * @name Queue#id */ - this.lastSkipped = false; - /** - * Queue volume - * @type {Number} - */ - this.volume = 100; + Object.assign( + this.options, + { + leaveOnEnd: true, + leaveOnStop: true, + leaveOnEmpty: true, + leaveOnEmptyCooldown: 1000, + autoSelfDeaf: true, + ytdlOptions: { + highWaterMark: 1 << 25 + }, + initialVolume: 100, + bufferingTimeout: 3000 + } as PlayerOptions, + options + ); + } - /** - * If the player of this queue is paused - * @type {boolean} - */ - this.paused = Boolean(this.voiceConnection?.dispatcher?.paused); + /** + * Returns current track + * @type {Track} + */ + get current() { + if (this.#watchDestroyed()) return; + return this.connection.audioResource?.metadata ?? this.tracks[0]; + } - /** - * If repeat mode is enabled in this queue - * @type {boolean} - */ - this.repeatMode = false; + /** + * If this queue is destroyed + * @type {boolean} + */ + get destroyed() { + return this.#destroyed; + } - /** - * If loop mode is enabled in this queue - * @type {boolean} - */ - this.loopMode = false; + /** + * Returns current track + * @returns {Track} + */ + nowPlaying() { + if (this.#watchDestroyed()) return; + return this.current; + } - /** - * The additional calculated stream time - * @type {Number} - */ - this.additionalStreamTime = 0; + /** + * Connects to a voice channel + * @param {GuildChannelResolvable} channel The voice/stage channel + * @returns {Promise} + */ + async connect(channel: GuildChannelResolvable) { + if (this.#watchDestroyed()) return; + const _channel = this.guild.channels.resolve(channel) as StageChannel | VoiceChannel; + if (!["GUILD_STAGE_VOICE", "GUILD_VOICE"].includes(_channel?.type)) + throw new PlayerError(`Channel type must be GUILD_VOICE or GUILD_STAGE_VOICE, got ${_channel?.type}!`, ErrorStatusCode.INVALID_ARG_TYPE); + const connection = await this.player.voiceUtils.connect(_channel, { + deaf: this.options.autoSelfDeaf, + maxTime: this.player.options.connectionTimeout || 20000 + }); + this.connection = connection; - /** - * The initial message object - * @type {DiscordMessage} - */ - this.firstMessage = message; + if (_channel.type === "GUILD_STAGE_VOICE") { + await _channel.guild.me.voice.setSuppressed(false).catch(async () => { + return await _channel.guild.me.voice.setRequestToSpeak(true).catch(Util.noop); + }); + } - /** - * The audio filters in this queue - * @type {QueueFilters} - */ - this.filters = {}; + this.connection.on("error", (err) => this.player.emit("connectionError", this, err)); + this.connection.on("debug", (msg) => this.player.emit("debug", this, msg)); - Object.keys(AudioFilters).forEach((fn) => { - this.filters[fn as keyof QueueFilters] = false; + this.player.emit("connectionCreate", this, this.connection); + + this.connection.on("start", (resource) => { + this.playing = true; + if (!this._filtersUpdate && resource?.metadata) this.player.emit("trackStart", this, resource?.metadata ?? this.current); + this._filtersUpdate = false; + }); + + this.connection.on("finish", async (resource) => { + this.playing = false; + if (this._filtersUpdate) return; + this._streamTime = 0; + if (resource && resource.metadata) this.previousTracks.push(resource.metadata); + + this.player.emit("trackEnd", this, resource.metadata); + + if (!this.tracks.length && this.repeatMode === QueueRepeatMode.OFF) { + if (this.options.leaveOnEnd) this.destroy(); + this.player.emit("queueEnd", this); + } else { + if (this.repeatMode !== QueueRepeatMode.AUTOPLAY) { + if (this.repeatMode === QueueRepeatMode.TRACK) return void this.play(Util.last(this.previousTracks), { immediate: true }); + if (this.repeatMode === QueueRepeatMode.QUEUE) this.tracks.push(Util.last(this.previousTracks)); + const nextTrack = this.tracks.shift(); + this.play(nextTrack, { immediate: true }); + return; + } else { + this._handleAutoplay(Util.last(this.previousTracks)); + } + } + }); + + return this; + } + + /** + * Destroys this queue + * @param {boolean} [disconnect=this.options.leaveOnStop] If it should leave on destroy + * @returns {void} + */ + destroy(disconnect = this.options.leaveOnStop) { + if (this.#watchDestroyed()) return; + if (this.connection) this.connection.end(); + if (disconnect) this.connection?.disconnect(); + this.player.queues.delete(this.guild.id); + this.player.voiceUtils.cache.delete(this.guild.id); + this.#destroyed = true; + } + + /** + * Skips current track + * @returns {boolean} + */ + skip() { + if (this.#watchDestroyed()) return; + if (!this.connection) return false; + this._filtersUpdate = false; + this.connection.end(); + return true; + } + + /** + * Adds single track to the queue + * @param {Track} track The track to add + * @returns {void} + */ + addTrack(track: Track) { + if (this.#watchDestroyed()) return; + if (!(track instanceof Track)) throw new PlayerError("invalid track", ErrorStatusCode.INVALID_TRACK); + this.tracks.push(track); + this.player.emit("trackAdd", this, track); + } + + /** + * Adds multiple tracks to the queue + * @param {Track[]} tracks Array of tracks to add + */ + addTracks(tracks: Track[]) { + if (this.#watchDestroyed()) return; + if (!tracks.every((y) => y instanceof Track)) throw new PlayerError("invalid track", ErrorStatusCode.INVALID_TRACK); + this.tracks.push(...tracks); + this.player.emit("tracksAdd", this, tracks); + } + + /** + * Sets paused state + * @param {boolean} paused The paused state + * @returns {boolean} + */ + setPaused(paused?: boolean) { + if (this.#watchDestroyed()) return; + if (!this.connection) return false; + return paused ? this.connection.pause(true) : this.connection.resume(); + } + + /** + * Sets bitrate + * @param {number|auto} bitrate bitrate to set + * @returns {void} + */ + setBitrate(bitrate: number | "auto") { + if (this.#watchDestroyed()) return; + if (!this.connection?.audioResource?.encoder) return; + if (bitrate === "auto") bitrate = this.connection.channel?.bitrate ?? 64000; + this.connection.audioResource.encoder.setBitrate(bitrate); + } + + /** + * Sets volume + * @param {number} amount The volume amount + * @returns {boolean} + */ + setVolume(amount: number) { + if (this.#watchDestroyed()) return; + if (!this.connection) return false; + this.#lastVolume = amount; + this.options.initialVolume = amount; + return this.connection.setVolume(amount); + } + /** + * Sets repeat mode + * @param {QueueRepeatMode} mode The repeat mode + * @returns {boolean} + */ + setRepeatMode(mode: QueueRepeatMode) { + if (this.#watchDestroyed()) return; + if (![QueueRepeatMode.OFF, QueueRepeatMode.QUEUE, QueueRepeatMode.TRACK, QueueRepeatMode.AUTOPLAY].includes(mode)) + throw new PlayerError(`Unknown repeat mode "${mode}"!`, ErrorStatusCode.UNKNOWN_REPEAT_MODE); + if (mode === this.repeatMode) return false; + this.repeatMode = mode; + return true; + } + + /** + * The current volume amount + * @type {number} + */ + get volume() { + if (this.#watchDestroyed()) return; + if (!this.connection) return 100; + return this.connection.volume; + } + + set volume(amount: number) { + this.setVolume(amount); + } + + /** + * Mutes the playback + * @returns {void} + */ + mute() { + const lv = this.#lastVolume; + this.volume = 0; + this.#lastVolume = lv; + } + + /** + * Unmutes the playback. If the last volume was set to 0, unmute will produce no effect. + * @returns {void} + */ + unmute() { + this.volume = this.#lastVolume; + } + + /** + * The stream time of this queue + * @type {number} + */ + get streamTime() { + if (this.#watchDestroyed()) return; + if (!this.connection) return 0; + const playbackTime = this._streamTime + this.connection.streamTime; + const NC = this._activeFilters.includes("nightcore") ? 1.25 : null; + const VW = this._activeFilters.includes("vaporwave") ? 0.8 : null; + + if (NC && VW) return playbackTime * (NC + VW); + return NC ? playbackTime * NC : VW ? playbackTime * VW : playbackTime; + } + + set streamTime(time: number) { + if (this.#watchDestroyed()) return; + this.seek(time); + } + + /** + * Returns enabled filters + * @returns {AudioFilters} + */ + getFiltersEnabled() { + if (this.#watchDestroyed()) return; + return AudioFilters.names.filter((x) => this._activeFilters.includes(x)); + } + + /** + * Returns disabled filters + * @returns {AudioFilters} + */ + getFiltersDisabled() { + if (this.#watchDestroyed()) return; + return AudioFilters.names.filter((x) => !this._activeFilters.includes(x)); + } + + /** + * Sets filters + * @param {QueueFilters} filters Queue filters + * @returns {Promise} + */ + async setFilters(filters?: QueueFilters) { + if (this.#watchDestroyed()) return; + if (!filters || !Object.keys(filters).length) { + // reset filters + const streamTime = this.streamTime; + this._activeFilters = []; + return await this.play(this.current, { + immediate: true, + filtersUpdate: true, + seek: streamTime, + encoderArgs: [] + }); + } + + const _filters: any[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any + + for (const filter in filters) { + if (filters[filter as keyof QueueFilters] === true) _filters.push(filter); + } + + if (this._activeFilters.join("") === _filters.join("")) return; + + const newFilters = AudioFilters.create(_filters).trim(); + const streamTime = this.streamTime; + this._activeFilters = _filters; + + return await this.play(this.current, { + immediate: true, + filtersUpdate: true, + seek: streamTime, + encoderArgs: !_filters.length ? undefined : ["-af", newFilters] }); } /** - * Currently playing track - * @type {Track} + * Seeks to the given time + * @param {number} position The position + * @returns {boolean} */ - get playing(): Track { - return this.tracks[0]; + async seek(position: number) { + if (this.#watchDestroyed()) return; + if (!this.playing || !this.current) return false; + if (position < 1) position = 0; + if (position >= this.current.durationMS) return this.skip(); + + await this.play(this.current, { + immediate: true, + filtersUpdate: true, // to stop events + seek: position + }); + + return true; } /** - * Calculated volume of this queue - * @type {Number} + * Plays previous track + * @returns {Promise} */ - get calculatedVolume(): number { - return this.filters.normalizer ? this.volume + 70 : this.volume; + async back() { + if (this.#watchDestroyed()) return; + const prev = this.previousTracks[this.previousTracks.length - 2]; // because last item is the current track + if (!prev) throw new PlayerError("Could not find previous track", ErrorStatusCode.TRACK_NOT_FOUND); + + return await this.play(prev, { immediate: true }); + } + + /** + * Clear this queue + */ + clear() { + if (this.#watchDestroyed()) return; + this.tracks = []; + this.previousTracks = []; + } + + /** + * Stops the player + * @returns {void} + */ + stop() { + if (this.#watchDestroyed()) return; + return this.destroy(); + } + + /** + * Shuffles this queue + * @returns {boolean} + */ + shuffle() { + if (this.#watchDestroyed()) return; + if (!this.tracks.length || this.tracks.length < 3) return false; + const currentTrack = this.tracks.shift(); + + for (let i = this.tracks.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [this.tracks[i], this.tracks[j]] = [this.tracks[j], this.tracks[i]]; + } + + this.tracks.unshift(currentTrack); + + return true; + } + + /** + * Removes a track from the queue + * @param {Track|Snowflake|number} track The track to remove + * @returns {Track} + */ + remove(track: Track | Snowflake | number) { + if (this.#watchDestroyed()) return; + let trackFound: Track = null; + if (typeof track === "number") { + trackFound = this.tracks[track]; + if (trackFound) { + this.tracks = this.tracks.filter((t) => t.id !== trackFound.id); + } + } else { + trackFound = this.tracks.find((s) => s.id === (track instanceof Track ? track.id : track)); + if (trackFound) { + this.tracks = this.tracks.filter((s) => s.id !== trackFound.id); + } + } + + return trackFound; + } + + /** + * Jumps to particular track + * @param {Track|number} track The track + * @returns {void} + */ + jump(track: Track | number): void { + if (this.#watchDestroyed()) return; + const foundTrack = this.remove(track); + if (!foundTrack) throw new PlayerError("Track not found", ErrorStatusCode.TRACK_NOT_FOUND); + this.tracks.splice(1, 0, foundTrack); + + return void this.skip(); + } + + /** + * Inserts the given track to specified index + * @param {Track} track The track to insert + * @param {number} [index=0] The index where this track should be + */ + insert(track: Track, index = 0) { + if (!track || !(track instanceof Track)) throw new PlayerError("track must be the instance of Track", ErrorStatusCode.INVALID_TRACK); + if (typeof index !== "number" || index < 0 || !Number.isFinite(index)) throw new PlayerError(`Invalid index "${index}"`, ErrorStatusCode.INVALID_ARG_TYPE); + + this.tracks.splice(index, 0, track); + + this.player.emit("trackAdd", this, track); + } + + /** + * @typedef {object} PlayerTimestamp + * @property {string} current The current progress + * @property {string} end The total time + * @property {number} progress Progress in % + */ + + /** + * Returns player stream timestamp + * @returns {PlayerTimestamp} + */ + getPlayerTimestamp() { + if (this.#watchDestroyed()) return; + const currentStreamTime = this.streamTime; + const totalTime = this.current.durationMS; + + const currentTimecode = Util.buildTimeCode(Util.parseMS(currentStreamTime)); + const endTimecode = Util.buildTimeCode(Util.parseMS(totalTime)); + + return { + current: currentTimecode, + end: endTimecode, + progress: Math.round((currentStreamTime / totalTime) * 100) + }; + } + + /** + * Creates progress bar string + * @param {PlayerProgressbarOptions} options The progress bar options + * @returns {string} + */ + createProgressBar(options: PlayerProgressbarOptions = { timecodes: true }) { + if (this.#watchDestroyed()) return; + const length = typeof options.length === "number" ? (options.length <= 0 || options.length === Infinity ? 15 : options.length) : 15; + + const index = Math.round((this.streamTime / this.current.durationMS) * length); + const indicator = typeof options.indicator === "string" && options.indicator.length > 0 ? options.indicator : "🔘"; + const line = typeof options.line === "string" && options.line.length > 0 ? options.line : "▬"; + + if (index >= 1 && index <= length) { + const bar = line.repeat(length - 1).split(""); + bar.splice(index, 0, indicator); + if (options.timecodes) { + const timestamp = this.getPlayerTimestamp(); + return `${timestamp.current} ┃ ${bar.join("")} ┃ ${timestamp.end}`; + } else { + return `${bar.join("")}`; + } + } else { + if (options.timecodes) { + const timestamp = this.getPlayerTimestamp(); + return `${timestamp.current} ┃ ${indicator}${line.repeat(length - 1)} ┃ ${timestamp.end}`; + } else { + return `${indicator}${line.repeat(length - 1)}`; + } + } } /** @@ -148,70 +585,159 @@ export class Queue extends EventEmitter { * @type {Number} */ get totalTime(): number { + if (this.#watchDestroyed()) return; return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0; } /** - * Current stream time - * @type {Number} - */ - get currentStreamTime(): number { - const NC = this.filters.nightcore ? 1.25 : null; - const VW = this.filters.vaporwave ? 0.8 : null; - const streamTime = this.voiceConnection?.dispatcher?.streamTime + this.additionalStreamTime || 0; - - if (NC && VW) return streamTime * (NC + VW); - return NC ? streamTime * NC : VW ? streamTime * VW : streamTime; - } - - /** - * Sets audio filters in this player - * @param {QueueFilters} filters Audio filters to set + * Play stream in a voice/stage channel + * @param {Track} [src] The track to play (if empty, uses first track from the queue) + * @param {PlayOptions} [options={}] The options * @returns {Promise} */ - setFilters(filters: QueueFilters): Promise { - return this.player.setFilters(this.firstMessage, filters); - } + async play(src?: Track, options: PlayOptions = {}): Promise { + if (!this.destroyed) this.#watchDestroyed(); + if (!this.connection || !this.connection.voiceConnection) throw new PlayerError("Voice connection is not available, use .connect()!", ErrorStatusCode.NO_CONNECTION); + if (src && (this.playing || this.tracks.length) && !options.immediate) return this.addTrack(src); + const track = options.filtersUpdate && !options.immediate ? src || this.current : src ?? this.tracks.shift(); + if (!track) return; - /** - * Returns array of all enabled filters - * @returns {String[]} - */ - getFiltersEnabled(): string[] { - const filters: string[] = []; + this.player.emit("debug", this, "Received play request"); - for (const filter in this.filters) { - if (this.filters[filter as keyof QueueFilters] !== false) filters.push(filter); + if (!options.filtersUpdate) { + this.previousTracks = this.previousTracks.filter((x) => x.id !== track.id); + this.previousTracks.push(track); } - return filters; + let stream; + if (["youtube", "spotify"].includes(track.raw.source)) { + if (track.raw.source === "spotify" && !track.raw.engine) { + track.raw.engine = await YouTube.search(`${track.author} ${track.title}`, { type: "video" }) + .then((x) => x[0].url) + .catch(() => null); + } + const link = track.raw.source === "spotify" ? track.raw.engine : track.url; + if (!link) return void this.play(this.tracks.shift(), { immediate: true }); + + stream = ytdl(link, { + ...this.options.ytdlOptions, + // discord-ytdl-core + opusEncoded: false, + fmt: "s16le", + encoderArgs: options.encoderArgs ?? this._activeFilters.length ? ["-af", AudioFilters.create(this._activeFilters)] : [], + seek: options.seek ? options.seek / 1000 : 0 + }).on("error", (err) => { + return err.message.toLowerCase().includes("premature close") ? null : this.player.emit("error", this, err); + }); + } else { + stream = ytdl + .arbitraryStream( + track.raw.source === "soundcloud" ? await track.raw.engine.downloadProgressive() : typeof track.raw.engine === "function" ? await track.raw.engine() : track.raw.engine, + { + opusEncoded: false, + fmt: "s16le", + encoderArgs: options.encoderArgs ?? this._activeFilters.length ? ["-af", AudioFilters.create(this._activeFilters)] : [], + seek: options.seek ? options.seek / 1000 : 0 + } + ) + .on("error", (err) => { + return err.message.toLowerCase().includes("premature close") ? null : this.player.emit("error", this, err); + }); + } + + const resource: AudioResource = this.connection.createStream(stream, { + type: StreamType.Raw, + data: track + }); + + if (options.seek) this._streamTime = options.seek; + this._filtersUpdate = options.filtersUpdate; + + setTimeout(() => { + this.connection.playStream(resource).then(() => { + this.setVolume(this.options.initialVolume); + }); + }, this.#getBufferingTimeout()).unref(); } /** - * Returns all disabled filters - * @returns {String[]} + * Private method to handle autoplay + * @param {Track} track The source track to find its similar track for autoplay + * @returns {Promise} + * @private */ - getFiltersDisabled(): string[] { - const enabled = this.getFiltersEnabled(); + private async _handleAutoplay(track: Track): Promise { + if (this.#watchDestroyed()) return; + if (!track || ![track.source, track.raw?.source].includes("youtube")) { + if (this.options.leaveOnEnd) this.destroy(); + return void this.player.emit("queueEnd", this); + } + const info = await YouTube.getVideo(track.url) + .then((x) => x.videos[0]) + .catch(Util.noop); + if (!info) { + if (this.options.leaveOnEnd) this.destroy(); + return void this.player.emit("queueEnd", this); + } - return Object.keys(this.filters).filter((f) => !enabled.includes(f)); + const nextTrack = new Track(this.player, { + title: info.title, + url: `https://www.youtube.com/watch?v=${info.id}`, + duration: info.durationFormatted ? Util.buildTimeCode(Util.parseMS(info.duration * 1000)) : "0:00", + description: "", + thumbnail: typeof info.thumbnail === "string" ? info.thumbnail : info.thumbnail.url, + views: info.views, + author: info.channel.name, + requestedBy: track.requestedBy, + source: "youtube" + }); + + this.play(nextTrack, { immediate: true }); + } + + *[Symbol.iterator]() { + if (this.#watchDestroyed()) return; + yield* this.tracks; } /** - * Destroys this queue - * @returns {Boolean} + * JSON representation of this queue + * @returns {object} */ - destroy() { - return this.player.stop(this.firstMessage); + toJSON() { + if (this.#watchDestroyed()) return; + return { + id: this.id, + guild: this.guild.id, + voiceChannel: this.connection?.channel?.id, + options: this.options, + tracks: this.tracks.map((m) => m.toJSON()) + }; } /** - * String representation of this Queue - * @returns {String} + * String representation of this queue + * @returns {string} */ - toString(): string { - return ``; + toString() { + if (this.#watchDestroyed()) return; + if (!this.tracks.length) return "No songs available to display!"; + return `**Upcoming Songs:**\n${this.tracks.map((m, i) => `${i + 1}. **${m.title}**`).join("\n")}`; + } + + #watchDestroyed() { + if (this.#destroyed) { + this.player.emit("error", this, new PlayerError("Cannot use destroyed queue", ErrorStatusCode.DESTROYED_QUEUE)); + return true; + } + } + + #getBufferingTimeout() { + const timeout = this.options.bufferingTimeout; + + if (isNaN(timeout) || timeout < 0 || !Number.isFinite(timeout)) return 1000; + return timeout; } } -export default Queue; +export { Queue }; diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index e24b791..456de2b 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -1,9 +1,10 @@ -import { Player } from '../Player'; -import { User } from 'discord.js'; -import { TrackData } from '../types/types'; -import Queue from './Queue'; +import { User, Util, SnowflakeUtil, Snowflake } from "discord.js"; +import { Player } from "../Player"; +import { RawTrackData, TrackJSON } from "../types/types"; +import { Playlist } from "./Playlist"; +import { Queue } from "./Queue"; -export class Track { +class Track { public player!: Player; public title!: string; public description!: string; @@ -13,99 +14,106 @@ export class Track { public duration!: string; public views!: number; public requestedBy!: User; - public fromPlaylist!: boolean; - public raw!: TrackData; + public playlist?: Playlist; + public readonly raw: RawTrackData = {} as RawTrackData; + public readonly id: Snowflake = SnowflakeUtil.generate(); /** * Track constructor * @param {Player} player The player that instantiated this Track - * @param {TrackData} data Track data + * @param {RawTrackData} data Track data */ - constructor(player: Player, data: TrackData) { + constructor(player: Player, data: RawTrackData) { /** * The player that instantiated this Track * @name Track#player * @type {Player} * @readonly */ - Object.defineProperty(this, 'player', { value: player, enumerable: false }); + Object.defineProperty(this, "player", { value: player, enumerable: false }); /** * Title of this track * @name Track#title - * @type {String} + * @type {string} */ /** * Description of this track * @name Track#description - * @type {String} + * @type {string} */ /** * Author of this track * @name Track#author - * @type {String} + * @type {string} */ /** * URL of this track * @name Track#url - * @type {String} + * @type {string} */ /** * Thumbnail of this track * @name Track#thumbnail - * @type {String} + * @type {string} */ /** * Duration of this track * @name Track#duration - * @type {String} + * @type {string} */ /** * Views count of this track * @name Track#views - * @type {Number} + * @type {number} */ /** * Person who requested this track * @name Track#requestedBy - * @type {DiscordUser} + * @type {User} */ /** * If this track belongs to playlist * @name Track#fromPlaylist - * @type {Boolean} + * @type {boolean} */ /** * Raw track data * @name Track#raw - * @type {TrackData} + * @type {RawTrackData} + */ + + /** + * The track id + * @name Track#id + * @type {Snowflake} + * @readonly */ void this._patch(data); } - private _patch(data: TrackData) { - this.title = data.title ?? ''; - this.description = data.description ?? ''; - this.author = data.author ?? ''; - this.url = data.url ?? ''; - this.thumbnail = data.thumbnail ?? ''; - this.duration = data.duration ?? ''; + private _patch(data: RawTrackData) { + this.title = Util.escapeMarkdown(data.title ?? ""); + this.author = data.author ?? ""; + this.url = data.url ?? ""; + this.thumbnail = data.thumbnail ?? ""; + this.duration = data.duration ?? ""; this.views = data.views ?? 0; this.requestedBy = data.requestedBy; - this.fromPlaylist = Boolean(data.fromPlaylist); + this.playlist = data.playlist; // raw - Object.defineProperty(this, 'raw', { get: () => data, enumerable: false }); + Object.defineProperty(this, "raw", { value: Object.assign({}, { source: data.raw?.source ?? data.source }, data.raw ?? data), enumerable: false }); } /** @@ -118,7 +126,7 @@ export class Track { /** * The track duration in millisecond - * @type {Number} + * @type {number} */ get durationMS(): number { const times = (n: number, t: number) => { @@ -128,7 +136,7 @@ export class Track { }; return this.duration - .split(':') + .split(":") .reverse() .map((m, i) => parseInt(m) * times(60, i)) .reduce((a, c) => a + c, 0); @@ -139,16 +147,38 @@ export class Track { * @type {TrackSource} */ get source() { - return this.raw.source ?? 'arbitrary'; + return this.raw.source ?? "arbitrary"; } /** * String representation of this track - * @returns {String} + * @returns {string} */ toString(): string { return `${this.title} by ${this.author}`; } + + /** + * Raw JSON representation of this track + * @returns {TrackJSON} + */ + toJSON(hidePlaylist?: boolean) { + return { + id: this.id, + title: this.title, + description: this.description, + author: this.author, + url: this.url, + thumbnail: this.thumbnail, + duration: this.duration, + durationMS: this.durationMS, + views: this.views, + requestedBy: this.requestedBy.id, + playlist: hidePlaylist ? null : this.playlist?.toJSON(false) ?? null + } as TrackJSON; + } } export default Track; + +export { Track }; diff --git a/src/VoiceInterface/StreamDispatcher.ts b/src/VoiceInterface/StreamDispatcher.ts new file mode 100644 index 0000000..513178b --- /dev/null +++ b/src/VoiceInterface/StreamDispatcher.ts @@ -0,0 +1,227 @@ +import { + AudioPlayer, + AudioPlayerError, + AudioPlayerStatus, + AudioResource, + createAudioPlayer, + createAudioResource, + entersState, + StreamType, + VoiceConnection, + VoiceConnectionStatus, + VoiceConnectionDisconnectReason +} from "@discordjs/voice"; +import { StageChannel, VoiceChannel } from "discord.js"; +import { Duplex, Readable } from "stream"; +import { TypedEmitter as EventEmitter } from "tiny-typed-emitter"; +import Track from "../Structures/Track"; +import { Util } from "../utils/Util"; +import { PlayerError, ErrorStatusCode } from "../Structures/PlayerError"; + +export interface VoiceEvents { + /* eslint-disable @typescript-eslint/no-explicit-any */ + error: (error: AudioPlayerError) => any; + debug: (message: string) => any; + start: (resource: AudioResource) => any; + finish: (resource: AudioResource) => any; + /* eslint-enable @typescript-eslint/no-explicit-any */ +} + +class StreamDispatcher extends EventEmitter { + public readonly voiceConnection: VoiceConnection; + public readonly audioPlayer: AudioPlayer; + public channel: VoiceChannel | StageChannel; + public audioResource?: AudioResource; + private readyLock = false; + public paused: boolean; + + /** + * Creates new connection object + * @param {VoiceConnection} connection The connection + * @param {VoiceChannel|StageChannel} channel The connected channel + * @private + */ + constructor(connection: VoiceConnection, channel: VoiceChannel | StageChannel, public readonly connectionTimeout: number = 20000) { + super(); + + /** + * The voice connection + * @type {VoiceConnection} + */ + this.voiceConnection = connection; + + /** + * The audio player + * @type {AudioPlayer} + */ + this.audioPlayer = createAudioPlayer(); + + /** + * The voice channel + * @type {VoiceChannel|StageChannel} + */ + this.channel = channel; + + /** + * The paused state + * @type {boolean} + */ + this.paused = false; + + this.voiceConnection.on("stateChange", async (_, newState) => { + if (newState.status === VoiceConnectionStatus.Disconnected) { + if (newState.reason === VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) { + try { + await entersState(this.voiceConnection, VoiceConnectionStatus.Connecting, this.connectionTimeout); + } catch { + this.voiceConnection.destroy(); + } + } else if (this.voiceConnection.rejoinAttempts < 5) { + await Util.wait((this.voiceConnection.rejoinAttempts + 1) * 5000); + this.voiceConnection.rejoin(); + } else { + this.voiceConnection.destroy(); + } + } else if (newState.status === VoiceConnectionStatus.Destroyed) { + this.end(); + } else if (!this.readyLock && (newState.status === VoiceConnectionStatus.Connecting || newState.status === VoiceConnectionStatus.Signalling)) { + this.readyLock = true; + try { + await entersState(this.voiceConnection, VoiceConnectionStatus.Ready, this.connectionTimeout); + } catch { + if (this.voiceConnection.state.status !== VoiceConnectionStatus.Destroyed) this.voiceConnection.destroy(); + } finally { + this.readyLock = false; + } + } + }); + + this.audioPlayer.on("stateChange", (oldState, newState) => { + if (newState.status === AudioPlayerStatus.Playing) { + if (!this.paused) return void this.emit("start", this.audioResource); + } else if (newState.status === AudioPlayerStatus.Idle && oldState.status !== AudioPlayerStatus.Idle) { + if (!this.paused) { + void this.emit("finish", this.audioResource); + this.audioResource = null; + } + } + }); + + this.audioPlayer.on("debug", (m) => void this.emit("debug", m)); + this.audioPlayer.on("error", (error) => void this.emit("error", error)); + this.voiceConnection.subscribe(this.audioPlayer); + } + + /** + * Creates stream + * @param {Readable|Duplex|string} src The stream source + * @param {object} [ops={}] Options + * @returns {AudioResource} + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + createStream(src: Readable | Duplex | string, ops?: { type?: StreamType; data?: any }) { + this.audioResource = createAudioResource(src, { + inputType: ops?.type ?? StreamType.Arbitrary, + metadata: ops?.data, + inlineVolume: true // we definitely need volume controls, right? + }); + + return this.audioResource; + } + + /** + * The player status + * @type {AudioPlayerStatus} + */ + get status() { + return this.audioPlayer.state.status; + } + + /** + * Disconnects from voice + * @returns {void} + */ + disconnect() { + try { + this.audioPlayer.stop(true); + this.voiceConnection.destroy(); + } catch {} // eslint-disable-line no-empty + } + + /** + * Stops the player + * @returns {void} + */ + end() { + this.audioPlayer.stop(); + } + + /** + * Pauses the stream playback + * @param {boolean} [interpolateSilence=false] If true, the player will play 5 packets of silence after pausing to prevent audio glitches. + * @returns {boolean} + */ + pause(interpolateSilence?: boolean) { + const success = this.audioPlayer.pause(interpolateSilence); + this.paused = success; + return success; + } + + /** + * Resumes the stream playback + * @returns {boolean} + */ + resume() { + const success = this.audioPlayer.unpause(); + this.paused = !success; + return success; + } + + /** + * Play stream + * @param {AudioResource} [resource=this.audioResource] The audio resource to play + * @returns {Promise} + */ + async playStream(resource: AudioResource = this.audioResource) { + if (!resource) throw new PlayerError("Audio resource is not available!", ErrorStatusCode.NO_AUDIO_RESOURCE); + if (!this.audioResource) this.audioResource = resource; + if (this.voiceConnection.state.status !== VoiceConnectionStatus.Ready) await entersState(this.voiceConnection, VoiceConnectionStatus.Ready, this.connectionTimeout); + this.audioPlayer.play(resource); + + return this; + } + + /** + * Sets playback volume + * @param {number} value The volume amount + * @returns {boolean} + */ + setVolume(value: number) { + if (!this.audioResource || isNaN(value) || value < 0 || value > Infinity) return false; + + // ye boi logarithmic ✌ + this.audioResource.volume.setVolumeLogarithmic(value / 100); + return true; + } + + /** + * The current volume + * @type {number} + */ + get volume() { + if (!this.audioResource || !this.audioResource.volume) return 100; + const currentVol = this.audioResource.volume.volume; + return Math.round(Math.pow(currentVol, 1 / 1.660964) * 100); + } + + /** + * The playback time + * @type {number} + */ + get streamTime() { + if (!this.audioResource) return 0; + return this.audioResource.playbackDuration; + } +} + +export { StreamDispatcher as StreamDispatcher }; diff --git a/src/VoiceInterface/VoiceUtils.ts b/src/VoiceInterface/VoiceUtils.ts new file mode 100644 index 0000000..7de4433 --- /dev/null +++ b/src/VoiceInterface/VoiceUtils.ts @@ -0,0 +1,88 @@ +import { VoiceChannel, StageChannel, Collection, Snowflake } from "discord.js"; +import { DiscordGatewayAdapterCreator, entersState, joinVoiceChannel, VoiceConnection, VoiceConnectionStatus } from "@discordjs/voice"; +import { StreamDispatcher } from "./StreamDispatcher"; + +class VoiceUtils { + public cache: Collection; + + /** + * The voice utils + * @private + */ + constructor() { + /** + * The cache where voice utils stores stream managers + * @type {Collection} + */ + this.cache = new Collection(); + } + + /** + * Joins a voice channel, creating basic stream dispatch manager + * @param {StageChannel|VoiceChannel} channel The voice channel + * @param {object} [options={}] Join options + * @returns {Promise} + */ + public async connect( + channel: VoiceChannel | StageChannel, + options?: { + deaf?: boolean; + maxTime?: number; + } + ): Promise { + const conn = await this.join(channel, options); + const sub = new StreamDispatcher(conn, channel, options.maxTime); + this.cache.set(channel.guild.id, sub); + return sub; + } + + /** + * Joins a voice channel + * @param {StageChannel|VoiceChannel} [channel] The voice/stage channel to join + * @param {object} [options={}] Join options + * @returns {VoiceConnection} + */ + public async join( + channel: VoiceChannel | StageChannel, + options?: { + deaf?: boolean; + maxTime?: number; + } + ) { + let conn = joinVoiceChannel({ + guildId: channel.guild.id, + channelId: channel.id, + adapterCreator: channel.guild.voiceAdapterCreator as unknown as DiscordGatewayAdapterCreator, + selfDeaf: Boolean(options.deaf) + }); + + try { + conn = await entersState(conn, VoiceConnectionStatus.Ready, options?.maxTime ?? 20000); + return conn; + } catch (err) { + conn.destroy(); + throw err; + } + } + + /** + * Disconnects voice connection + * @param {VoiceConnection} connection The voice connection + * @returns {void} + */ + public disconnect(connection: VoiceConnection | StreamDispatcher) { + if (connection instanceof StreamDispatcher) return connection.voiceConnection.destroy(); + return connection.destroy(); + } + + /** + * Returns Discord Player voice connection + * @param {Snowflake} guild The guild id + * @returns {StreamDispatcher} + */ + public getConnection(guild: Snowflake) { + return this.cache.get(guild); + } +} + +export { VoiceUtils }; diff --git a/src/index.ts b/src/index.ts index 4dd3a82..49e9ed9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,12 @@ -export { AudioFilters } from './utils/AudioFilters'; -export * as Constants from './utils/Constants'; -export { ExtractorModel } from './Structures/ExtractorModel'; -export { Player } from './Player'; -export { Util } from './utils/Util'; -export { Track } from './Structures/Track'; -export { Queue } from './Structures/Queue'; -export * from './types/types'; -export { PlayerError } from './utils/PlayerError'; +export { AudioFilters } from "./utils/AudioFilters"; +export { ExtractorModel } from "./Structures/ExtractorModel"; +export { Playlist } from "./Structures/Playlist"; +export { Player } from "./Player"; +export { PlayerError, ErrorStatusCode } from "./Structures/PlayerError"; +export { QueryResolver } from "./utils/QueryResolver"; +export { Queue } from "./Structures/Queue"; +export { Track } from "./Structures/Track"; +export { Util } from "./utils/Util"; +export { VoiceUtils } from "./VoiceInterface/VoiceUtils"; +export { VoiceEvents, StreamDispatcher } from "./VoiceInterface/StreamDispatcher"; +export * from "./types/types"; diff --git a/src/types/types.ts b/src/types/types.ts index 00af839..8a21666 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,45 +1,21 @@ -import { downloadOptions } from 'ytdl-core'; -import { User } from 'discord.js'; -import { Readable, Duplex } from 'stream'; - -export interface PlayerOptions { - leaveOnEnd?: boolean; - leaveOnEndCooldown?: number; - leaveOnStop?: boolean; - leaveOnEmpty?: boolean; - leaveOnEmptyCooldown?: number; - autoSelfDeaf?: boolean; - enableLive?: boolean; - ytdlDownloadOptions?: downloadOptions; - useSafeSearch?: boolean; - disableAutoRegister?: boolean; - disableArtistSearch?: boolean; - fetchBeforeQueued?: boolean; - volume?: number; -} +import { Snowflake, User, UserResolvable } from "discord.js"; +import { Readable, Duplex } from "stream"; +import { Queue } from "../Structures/Queue"; +import Track from "../Structures/Track"; +import { Playlist } from "../Structures/Playlist"; +import { StreamDispatcher } from "../VoiceInterface/StreamDispatcher"; +import { downloadOptions } from "ytdl-core"; export type FiltersName = keyof QueueFilters; -export type TrackSource = 'soundcloud' | 'youtube' | 'spotify' | 'arbitrary'; - -export interface TrackData { - title: string; - description: string; - author: string; - url: string; - thumbnail: string; - duration: string; - views: number; - requestedBy: User; - fromPlaylist: boolean; - source?: TrackSource; - engine?: any; - live?: boolean; -} - -export type QueueFilters = { +/** + * @typedef {AudioFilters} QueueFilters + */ +export interface QueueFilters { + bassboost_low?: boolean; bassboost?: boolean; - '8D'?: boolean; + bassboost_high?: boolean; + "8D"?: boolean; vaporwave?: boolean; nightcore?: boolean; phaser?: boolean; @@ -48,6 +24,7 @@ export type QueueFilters = { reverse?: boolean; treble?: boolean; normalizer?: boolean; + normalizer2?: boolean; surrounding?: boolean; pulsator?: boolean; subboost?: boolean; @@ -66,75 +43,421 @@ export type QueueFilters = { chorus2d?: boolean; chorus3d?: boolean; fadein?: boolean; -}; + dim?: boolean; + earrape?: boolean; +} -export type QueryType = 'soundcloud_track' | 'soundcloud_playlist' | 'spotify_song' | 'spotify_album' | 'spotify_playlist' | 'youtube_video' | 'youtube_playlist' | 'vimeo' | 'facebook' | 'reverbnation' | 'attachment' | 'youtube_search'; +/** + * The track source: + * - soundcloud + * - youtube + * - spotify + * - arbitrary + * @typedef {string} TrackSource + */ +export type TrackSource = "soundcloud" | "youtube" | "spotify" | "arbitrary"; -export interface ExtractorModelData { +/** + * @typedef {object} RawTrackData + * @property {string} title The title + * @property {string} description The description + * @property {string} author The author + * @property {string} url The url + * @property {string} thumbnail The thumbnail + * @property {string} duration The duration + * @property {number} views The views + * @property {User} requestedBy The user who requested this track + * @property {Playlist} [playlist] The playlist + * @property {TrackSource} [source="arbitrary"] The source + * @property {any} [engine] The engine + * @property {boolean} [live] If this track is live + * @property {any} [raw] The raw data + */ +export interface RawTrackData { title: string; - duration: number; - thumbnail: string; - engine: string | Readable | Duplex; - views: number; - author: string; description: string; + author: string; url: string; - version?: string; - important?: boolean; - source?: TrackSource; -} - -export interface PlayerProgressbarOptions { - timecodes?: boolean; - queue?: boolean; - length?: number; - line?: string; - indicator?: string; -} - -export interface LyricsData { - title: string; - id: number; thumbnail: string; - image: string; - url: string; - artist: { - name: string; - id: number; - url: string; - image: string; - }; - lyrics?: string; -} - -export interface PlayerStats { - uptime: number; - connections: number; - users: number; - queues: number; - extractors: number; - versions: { - ffmpeg: string; - node: string; - v8: string; - }; - system: { - arch: string; - platform: 'aix' | 'android' | 'darwin' | 'freebsd' | 'linux' | 'openbsd' | 'sunos' | 'win32' | 'cygwin' | 'netbsd'; - cpu: number; - memory: { - total: string; - usage: string; - rss: string; - arrayBuffers: string; - }; - uptime: number; - }; + duration: string; + views: number; + requestedBy: User; + playlist?: Playlist; + source?: TrackSource; + engine?: any; // eslint-disable-line @typescript-eslint/no-explicit-any + live?: boolean; + raw?: any; // eslint-disable-line @typescript-eslint/no-explicit-any } +/** + * @typedef {object} TimeData + * @property {number} days Time in days + * @property {number} hours Time in hours + * @property {number} minutes Time in minutes + * @property {number} seconds Time in seconds + */ export interface TimeData { days: number; hours: number; minutes: number; seconds: number; } + +/** + * @typedef {object} PlayerProgressbarOptions + * @property {boolean} [timecodes] If it should render time codes + * @property {boolean} [queue] If it should create progress bar for the whole queue + * @property {number} [length] The bar length + * @property {string} [line] The bar track + * @property {string} [indicator] The indicator + */ +export interface PlayerProgressbarOptions { + timecodes?: boolean; + length?: number; + line?: string; + indicator?: string; +} + +/** + * @typedef {object} PlayerOptions + * @property {boolean} [leaveOnEnd=true] If it should leave on end + * @property {boolean} [leaveOnStop=true] If it should leave on stop + * @property {boolean} [leaveOnEmpty=true] If it should leave on empty + * @property {number} [leaveOnEmptyCooldown=1000] The cooldown in ms + * @property {boolean} [autoSelfDeaf=true] If it should set the bot in deaf mode + * @property {YTDLDownloadOptions} [ytdlOptions={}] The youtube download options + * @property {number} [initialVolume=100] The initial player volume + * @property {number} [bufferingTimeout=3000] Buffering timeout for the stream + */ +export interface PlayerOptions { + leaveOnEnd?: boolean; + leaveOnStop?: boolean; + leaveOnEmpty?: boolean; + leaveOnEmptyCooldown?: number; + autoSelfDeaf?: boolean; + ytdlOptions?: downloadOptions; + initialVolume?: number; + bufferingTimeout?: number; +} + +/** + * @typedef {object} ExtractorModelData + * @property {object} [playlist] The playlist info (if any) + * @property {string} [playlist.title] The playlist title + * @property {string} [playlist.description] The playlist description + * @property {string} [playlist.thumbnail] The playlist thumbnail + * @property {album|playlist} [playlist.type] The playlist type: `album` | `playlist` + * @property {TrackSource} [playlist.source] The playlist source + * @property {object} [playlist.author] The playlist author + * @property {string} [playlist.author.name] The author name + * @property {string} [playlist.author.url] The author url + * @property {string} [playlist.id] The playlist id + * @property {string} [playlist.url] The playlist url + * @property {any} [playlist.rawPlaylist] The raw data + * @property {ExtractorData[]} data The data + */ + +/** + * @typedef {object} ExtractorData + * @property {string} title The title + * @property {number} duration The duration + * @property {string} thumbnail The thumbnail + * @property {string|Readable|Duplex} engine The stream engine + * @property {number} views The views count + * @property {string} author The author + * @property {string} description The description + * @property {string} url The url + * @property {string} [version] The extractor version + * @property {TrackSource} [source="arbitrary"] The source + */ +export interface ExtractorModelData { + playlist?: { + title: string; + description: string; + thumbnail: string; + type: "album" | "playlist"; + source: TrackSource; + author: { + name: string; + url: string; + }; + id: string; + url: string; + rawPlaylist?: any; // eslint-disable-line @typescript-eslint/no-explicit-any + }; + data: { + title: string; + duration: number; + thumbnail: string; + engine: string | Readable | Duplex; + views: number; + author: string; + description: string; + url: string; + version?: string; + source?: TrackSource; + }[]; +} + +/** + * The search query type + * This can be one of: + * - AUTO + * - YOUTUBE + * - YOUTUBE_PLAYLIST + * - SOUNDCLOUD_TRACK + * - SOUNDCLOUD_PLAYLIST + * - SOUNDCLOUD + * - SPOTIFY_SONG + * - SPOTIFY_ALBUM + * - SPOTIFY_PLAYLIST + * - FACEBOOK + * - VIMEO + * - ARBITRARY + * - REVERBNATION + * - YOUTUBE_SEARCH + * - SOUNDCLOUD_SEARCH + * @typedef {string} QueryType + */ +export enum QueryType { + AUTO = "auto", + YOUTUBE = "youtube", + YOUTUBE_PLAYLIST = "youtube_playlist", + SOUNDCLOUD_TRACK = "soundcloud_track", + SOUNDCLOUD_PLAYLIST = "soundcloud_playlist", + SOUNDCLOUD = "soundcloud", + SPOTIFY_SONG = "spotify_song", + SPOTIFY_ALBUM = "spotify_album", + SPOTIFY_PLAYLIST = "spotify_playlist", + FACEBOOK = "facebook", + VIMEO = "vimeo", + ARBITRARY = "arbitrary", + REVERBNATION = "reverbnation", + YOUTUBE_SEARCH = "youtube_search", + SOUNDCLOUD_SEARCH = "soundcloud_search" +} + +/** + * Emitted when bot gets disconnected from a voice channel + * @event Player#botDisconnect + * @param {Queue} queue The queue + */ + +/** + * Emitted when the voice channel is empty + * @event Player#channelEmpty + * @param {Queue} queue The queue + */ + +/** + * Emitted when bot connects to a voice channel + * @event Player#connectionCreate + * @param {Queue} queue The queue + * @param {StreamDispatcher} connection The discord player connection object + */ + +/** + * Debug information + * @event Player#debug + * @param {Queue} queue The queue + * @param {string} message The message + */ + +/** + * Emitted on error + * This event should handled properly otherwise it may crash your process! + * @event Player#error + * @param {Queue} queue The queue + * @param {Error} error The error + */ + +/** + * Emitted on connection error. Sometimes stream errors are emitted here as well. + * @event Player#connectionError + * @param {Queue} queue The queue + * @param {Error} error The error + */ + +/** + * Emitted when queue ends + * @event Player#queueEnd + * @param {Queue} queue The queue + */ + +/** + * Emitted when a single track is added + * @event Player#trackAdd + * @param {Queue} queue The queue + * @param {Track} track The track + */ + +/** + * Emitted when multiple tracks are added + * @event Player#tracksAdd + * @param {Queue} queue The queue + * @param {Track[]} tracks The tracks + */ + +/** + * Emitted when a track starts playing + * @event Player#trackStart + * @param {Queue} queue The queue + * @param {Track} track The track + */ + +/* eslint-disable @typescript-eslint/no-explicit-any */ +export interface PlayerEvents { + botDisconnect: (queue: Queue) => any; + channelEmpty: (queue: Queue) => any; + connectionCreate: (queue: Queue, connection: StreamDispatcher) => any; + debug: (queue: Queue, message: string) => any; + error: (queue: Queue, error: Error) => any; + connectionError: (queue: Queue, error: Error) => any; + queueEnd: (queue: Queue) => any; + trackAdd: (queue: Queue, track: Track) => any; + tracksAdd: (queue: Queue, track: Track[]) => any; + trackStart: (queue: Queue, track: Track) => any; + trackEnd: (queue: Queue, track: Track) => any; +} + +/* eslint-enable @typescript-eslint/no-explicit-any */ + +/** + * @typedef {object} PlayOptions + * @property {boolean} [filtersUpdate=false] If this play was triggered for filters update + * @property {string[]} [encoderArgs=[]] FFmpeg args passed to encoder + * @property {number} [seek] Time to seek to before playing + * @property {boolean} [immediate=false] If it should start playing the provided track immediately + */ +export interface PlayOptions { + filtersUpdate?: boolean; + encoderArgs?: string[]; + seek?: number; + immediate?: boolean; +} + +/** + * @typedef {object} SearchOptions + * @property {UserResolvable} requestedBy The user who requested this search + * @property {QueryType} [searchEngine=QueryType.AUTO] The query search engine + * @property {boolean} [blockExtractor=false] If it should block custom extractors + */ +export interface SearchOptions { + requestedBy: UserResolvable; + searchEngine?: QueryType; + blockExtractor?: boolean; +} + +/** + * The queue repeat mode. This can be one of: + * - OFF + * - TRACK + * - QUEUE + * - AUTOPLAY + * @typedef {number} QueueRepeatMode + */ +export enum QueueRepeatMode { + OFF = 0, + TRACK = 1, + QUEUE = 2, + AUTOPLAY = 3 +} + +/** + * @typedef {object} PlaylistInitData + * @property {Track[]} tracks The tracks of this playlist + * @property {string} title The playlist title + * @property {string} description The description + * @property {string} thumbnail The thumbnail + * @property {album|playlist} type The playlist type: `album` | `playlist` + * @property {TrackSource} source The playlist source + * @property {object} author The playlist author + * @property {string} [author.name] The author name + * @property {string} [author.url] The author url + * @property {string} id The playlist id + * @property {string} url The playlist url + * @property {any} [rawPlaylist] The raw playlist data + */ +export interface PlaylistInitData { + tracks: Track[]; + title: string; + description: string; + thumbnail: string; + type: "album" | "playlist"; + source: TrackSource; + author: { + name: string; + url: string; + }; + id: string; + url: string; + rawPlaylist?: any; // eslint-disable-line @typescript-eslint/no-explicit-any +} + +/** + * @typedef {object} TrackJSON + * @property {string} title The track title + * @property {string} description The track description + * @property {string} author The author + * @property {string} url The url + * @property {string} thumbnail The thumbnail + * @property {string} duration The duration + * @property {number} durationMS The duration in ms + * @property {number} views The views count + * @property {Snowflake} requestedBy The id of the user who requested this track + * @property {PlaylistJSON} [playlist] The playlist info (if any) + */ +export interface TrackJSON { + id: Snowflake; + title: string; + description: string; + author: string; + url: string; + thumbnail: string; + duration: string; + durationMS: number; + views: number; + requestedBy: Snowflake; + playlist?: PlaylistJSON; +} + +/** + * @typedef {object} PlaylistJSON + * @property {string} id The playlist id + * @property {string} url The playlist url + * @property {string} title The playlist title + * @property {string} description The playlist description + * @property {string} thumbnail The thumbnail + * @property {album|playlist} type The playlist type: `album` | `playlist` + * @property {TrackSource} source The track source + * @property {object} author The playlist author + * @property {string} [author.name] The author name + * @property {string} [author.url] The author url + * @property {TrackJSON[]} tracks The tracks data (if any) + */ +export interface PlaylistJSON { + id: string; + url: string; + title: string; + description: string; + thumbnail: string; + type: "album" | "playlist"; + source: TrackSource; + author: { + name: string; + url: string; + }; + tracks: TrackJSON[]; +} + +/** + * @typedef {object} PlayerInitOptions + * @property {boolean} [autoRegisterExtractor=true] If it should automatically register `@discord-player/extractor` + * @property {YTDLDownloadOptions} [ytdlOptions={}] The options passed to `ytdl-core` + * @property {number} [connectionTimeout=20000] The voice connection timeout + */ +export interface PlayerInitOptions { + autoRegisterExtractor?: boolean; + ytdlOptions?: downloadOptions; + connectionTimeout?: number; +} diff --git a/src/utils/AudioFilters.ts b/src/utils/AudioFilters.ts index ff21b68..8afefbf 100644 --- a/src/utils/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -1,96 +1,108 @@ -import { FiltersName } from '../types/types'; +import { FiltersName } from "../types/types"; + +const bass = (g: number) => `bass=g=${g}:f=110:w=0.3`; /** * The available audio filters - * @typedef {Object} AudioFilters - * @property {String} bassboost The bassboost filter - * @property {String} 8D The 8D filter - * @property {String} vaporwave The vaporwave filter - * @property {String} nightcore The nightcore filter - * @property {String} phaser The phaser filter - * @property {String} tremolo The tremolo filter - * @property {String} vibrato The vibrato filter - * @property {String} reverse The reverse filter - * @property {String} treble The treble filter - * @property {String} normalizer The normalizer filter - * @property {String} surrounding The surrounding filter - * @property {String} pulsator The pulsator filter - * @property {String} subboost The subboost filter - * @property {String} kakaoke The kakaoke filter - * @property {String} flanger The flanger filter - * @property {String} gate The gate filter - * @property {String} haas The haas filter - * @property {String} mcompand The mcompand filter - * @property {String} mono The mono filter - * @property {String} mstlr The mstlr filter - * @property {String} mstrr The mstrr filter - * @property {String} compressor The compressor filter - * @property {String} expander The expander filter - * @property {String} softlimiter The softlimiter filter - * @property {String} chorus The chorus filter - * @property {String} chorus2d The chorus2d filter - * @property {String} chorus3d The chorus3d filter - * @property {String} fadein The fadein filter + * @typedef {object} AudioFilters + * @property {string} bassboost_low The bassboost filter (+15dB) + * @property {string} bassboost The bassboost filter (+20dB) + * @property {string} bassboost_high The bassboost filter (+30dB) + * @property {string} 8D The 8D filter + * @property {string} vaporwave The vaporwave filter + * @property {string} nightcore The nightcore filter + * @property {string} phaser The phaser filter + * @property {string} tremolo The tremolo filter + * @property {string} vibrato The vibrato filter + * @property {string} reverse The reverse filter + * @property {string} treble The treble filter + * @property {string} normalizer The normalizer filter (dynamic audio normalizer based) + * @property {string} normalizer2 The normalizer filter (audio compressor based) + * @property {string} surrounding The surrounding filter + * @property {string} pulsator The pulsator filter + * @property {string} subboost The subboost filter + * @property {string} kakaoke The kakaoke filter + * @property {string} flanger The flanger filter + * @property {string} gate The gate filter + * @property {string} haas The haas filter + * @property {string} mcompand The mcompand filter + * @property {string} mono The mono filter + * @property {string} mstlr The mstlr filter + * @property {string} mstrr The mstrr filter + * @property {string} compressor The compressor filter + * @property {string} expander The expander filter + * @property {string} softlimiter The softlimiter filter + * @property {string} chorus The chorus filter + * @property {string} chorus2d The chorus2d filter + * @property {string} chorus3d The chorus3d filter + * @property {string} fadein The fadein filter + * @property {string} dim The dim filter + * @property {string} earrape The earrape filter */ const FilterList = { - bassboost: 'bass=g=20', - '8D': 'apulsator=hz=0.09', - vaporwave: 'aresample=48000,asetrate=48000*0.8', - nightcore: 'aresample=48000,asetrate=48000*1.25', - phaser: 'aphaser=in_gain=0.4', - tremolo: 'tremolo', - vibrato: 'vibrato=f=6.5', - reverse: 'areverse', - treble: 'treble=g=5', - normalizer: 'dynaudnorm=g=101', - surrounding: 'surround', - pulsator: 'apulsator=hz=1', - subboost: 'asubboost', - karaoke: 'stereotools=mlev=0.03', - flanger: 'flanger', - gate: 'agate', - haas: 'haas', - mcompand: 'mcompand', - mono: 'pan=mono|c0=.5*c0+.5*c1', - mstlr: 'stereotools=mode=ms>lr', - mstrr: 'stereotools=mode=ms>rr', - compressor: 'compand=points=-80/-105|-62/-80|-15.4/-15.4|0/-12|20/-7.6', - expander: 'compand=attacks=0:points=-80/-169|-54/-80|-49.5/-64.6|-41.1/-41.1|-25.8/-15|-10.8/-4.5|0/0|20/8.3', - softlimiter: 'compand=attacks=0:points=-80/-80|-12.4/-12.4|-6/-8|0/-6.8|20/-2.8', - chorus: 'chorus=0.7:0.9:55:0.4:0.25:2', - chorus2d: 'chorus=0.6:0.9:50|60:0.4|0.32:0.25|0.4:2|1.3', - chorus3d: 'chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3', - fadein: 'afade=t=in:ss=0:d=10', + bassboost_low: bass(15), + bassboost: bass(20), + bassboost_high: bass(30), + "8D": "apulsator=hz=0.09", + vaporwave: "aresample=48000,asetrate=48000*0.8", + nightcore: "aresample=48000,asetrate=48000*1.25", + phaser: "aphaser=in_gain=0.4", + tremolo: "tremolo", + vibrato: "vibrato=f=6.5", + reverse: "areverse", + treble: "treble=g=5", + normalizer: "dynaudnorm=g=101", + normalizer2: "acompressor", + surrounding: "surround", + pulsator: "apulsator=hz=1", + subboost: "asubboost", + karaoke: "stereotools=mlev=0.03", + flanger: "flanger", + gate: "agate", + haas: "haas", + mcompand: "mcompand", + mono: "pan=mono|c0=.5*c0+.5*c1", + mstlr: "stereotools=mode=ms>lr", + mstrr: "stereotools=mode=ms>rr", + compressor: "compand=points=-80/-105|-62/-80|-15.4/-15.4|0/-12|20/-7.6", + expander: "compand=attacks=0:points=-80/-169|-54/-80|-49.5/-64.6|-41.1/-41.1|-25.8/-15|-10.8/-4.5|0/0|20/8.3", + softlimiter: "compand=attacks=0:points=-80/-80|-12.4/-12.4|-6/-8|0/-6.8|20/-2.8", + chorus: "chorus=0.7:0.9:55:0.4:0.25:2", + chorus2d: "chorus=0.6:0.9:50|60:0.4|0.32:0.25|0.4:2|1.3", + chorus3d: "chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3", + fadein: "afade=t=in:ss=0:d=10", + dim: `afftfilt="'real=re * (1-clip((b/nb)*b,0,1))':imag='im * (1-clip((b/nb)*b,0,1))'"`, + earrape: "channelsplit,sidechaingate=level_in=64", *[Symbol.iterator](): IterableIterator<{ name: FiltersName; value: string }> { for (const [k, v] of Object.entries(this)) { - if (typeof this[k as FiltersName] === 'string') yield { name: k as FiltersName, value: v as string }; + if (typeof this[k as FiltersName] === "string") yield { name: k as FiltersName, value: v as string }; } }, get names() { - return Object.keys(this).filter((p) => !['names', 'length'].includes(p) && typeof this[p as FiltersName] !== 'function'); + return Object.keys(this).filter((p) => !["names", "length"].includes(p) && typeof this[p as FiltersName] !== "function") as FiltersName[]; }, get length() { - return Object.keys(this).filter((p) => !['names', 'length'].includes(p) && typeof this[p as FiltersName] !== 'function').length; + return Object.keys(this).filter((p) => !["names", "length"].includes(p) && typeof this[p as FiltersName] !== "function").length; }, toString() { - return `${Object.values(this).join(',')}`; + return this.names.map((m) => (this as any)[m]).join(","); // eslint-disable-line @typescript-eslint/no-explicit-any }, create(filter?: FiltersName[]): string { if (!filter || !Array.isArray(filter)) return this.toString(); return filter - .filter((predicate) => typeof predicate === 'string') + .filter((predicate) => typeof predicate === "string") .map((m) => this[m]) - .join(','); + .join(","); }, define(filterName: string, value: string): void { - if (typeof this[filterName as FiltersName] && typeof this[filterName as FiltersName] === 'function') return; + if (typeof this[filterName as FiltersName] && typeof this[filterName as FiltersName] === "function") return; this[filterName as FiltersName] = value; }, diff --git a/src/utils/Constants.ts b/src/utils/Constants.ts deleted file mode 100644 index 8a08c07..0000000 --- a/src/utils/Constants.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { PlayerOptions as DP_OPTIONS } from '../types/types'; - -export enum PlayerEvents { - BOT_DISCONNECT = 'botDisconnect', - CHANNEL_EMPTY = 'channelEmpty', - CONNECTION_CREATE = 'connectionCreate', - ERROR = 'error', - MUSIC_STOP = 'musicStop', - NO_RESULTS = 'noResults', - PLAYLIST_ADD = 'playlistAdd', - PLAYLIST_PARSE_END = 'playlistParseEnd', - PLAYLIST_PARSE_START = 'playlistParseStart', - QUEUE_CREATE = 'queueCreate', - QUEUE_END = 'queueEnd', - SEARCH_CANCEL = 'searchCancel', - SEARCH_INVALID_RESPONSE = 'searchInvalidResponse', - SEARCH_RESULTS = 'searchResults', - TRACK_ADD = 'trackAdd', - TRACK_START = 'trackStart' -} - -export enum PlayerErrorEventCodes { - LIVE_VIDEO = 'LiveVideo', - NOT_CONNECTED = 'NotConnected', - UNABLE_TO_JOIN = 'UnableToJoin', - NOT_PLAYING = 'NotPlaying', - PARSE_ERROR = 'ParseError', - VIDEO_UNAVAILABLE = 'VideoUnavailable', - MUSIC_STARTING = 'MusicStarting' -} - -export const PlayerOptions: DP_OPTIONS = { - leaveOnEnd: true, - leaveOnStop: true, - leaveOnEmpty: true, - leaveOnEmptyCooldown: 0, - autoSelfDeaf: true, - enableLive: false, - ytdlDownloadOptions: {}, - volume: 100 -}; diff --git a/src/utils/PlayerError.ts b/src/utils/PlayerError.ts deleted file mode 100644 index c87e1f6..0000000 --- a/src/utils/PlayerError.ts +++ /dev/null @@ -1,10 +0,0 @@ -export default class PlayerError extends Error { - constructor(msg: string, name?: string) { - super(); - this.name = name ?? 'PlayerError'; - this.message = msg; - Error.captureStackTrace(this); - } -} - -export { PlayerError }; diff --git a/src/utils/QueryResolver.ts b/src/utils/QueryResolver.ts new file mode 100644 index 0000000..d39e808 --- /dev/null +++ b/src/utils/QueryResolver.ts @@ -0,0 +1,61 @@ +import { validateID, validateURL } from "ytdl-core"; +import { YouTube } from "youtube-sr"; +import { QueryType } from "../types/types"; +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +import { validateURL as SoundcloudValidateURL } from "soundcloud-scraper"; + +// scary things below *sigh* +const spotifySongRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/; +const spotifyPlaylistRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/; +const spotifyAlbumRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})/; +const vimeoRegex = /(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/; +const facebookRegex = /(https?:\/\/)(www\.|m\.)?(facebook|fb).com\/.*\/videos\/.*/; +const reverbnationRegex = /https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/; +const attachmentRegex = + /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/; +// scary things above *sigh* + +class QueryResolver { + /** + * Query resolver + */ + private constructor() {} // eslint-disable-line @typescript-eslint/no-empty-function + + /** + * Resolves the given search query + * @param {string} query The query + * @returns {QueryType} + */ + static resolve(query: string): QueryType { + if (SoundcloudValidateURL(query, "track")) return QueryType.SOUNDCLOUD_TRACK; + if (SoundcloudValidateURL(query, "playlist") || query.includes("/sets/")) return QueryType.SOUNDCLOUD_PLAYLIST; + if (YouTube.isPlaylist(query)) return QueryType.YOUTUBE_PLAYLIST; + if (validateID(query) || validateURL(query)) return QueryType.YOUTUBE_SEARCH; + if (spotifySongRegex.test(query)) return QueryType.SPOTIFY_SONG; + if (spotifyPlaylistRegex.test(query)) return QueryType.SPOTIFY_PLAYLIST; + if (spotifyAlbumRegex.test(query)) return QueryType.SPOTIFY_ALBUM; + if (vimeoRegex.test(query)) return QueryType.VIMEO; + if (facebookRegex.test(query)) return QueryType.FACEBOOK; + if (reverbnationRegex.test(query)) return QueryType.REVERBNATION; + if (attachmentRegex.test(query)) return QueryType.ARBITRARY; + + return QueryType.YOUTUBE_SEARCH; + } + + /** + * Parses vimeo id from url + * @param {string} query The query + * @returns {string} + */ + static getVimeoID(query: string): string { + return QueryResolver.resolve(query) === QueryType.VIMEO + ? query + .split("/") + .filter((x) => !!x) + .pop() + : null; + } +} + +export { QueryResolver }; diff --git a/src/utils/Util.ts b/src/utils/Util.ts index 37baa1f..ff9d0e2 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -1,200 +1,83 @@ -import { QueryType, TimeData } from '../types/types'; -import { FFmpeg } from 'prism-media'; -import YouTube from 'youtube-sr'; -import { Track } from '../Structures/Track'; -// @ts-ignore -import { validateURL as SoundcloudValidateURL } from 'soundcloud-scraper'; -import { VoiceChannel } from 'discord.js'; +import { StageChannel, VoiceChannel } from "discord.js"; +import { TimeData } from "../types/types"; -const spotifySongRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/; -const spotifyPlaylistRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/; -const spotifyAlbumRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})/; -const vimeoRegex = /(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/; -const facebookRegex = /(https?:\/\/)(www\.|m\.)?(facebook|fb).com\/.*\/videos\/.*/; -const reverbnationRegex = /https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/; -const attachmentRegex = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/; - -export class Util { +class Util { /** - * Static Player Util class + * Utils */ - constructor() { - throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`); - } + private constructor() {} // eslint-disable-line @typescript-eslint/no-empty-function /** - * Checks FFmpeg Version - * @param {Boolean} [force] If it should forcefully get the version - * @returns {String} + * Creates duration string + * @param {object} durObj The duration object + * @returns {string} */ - static getFFmpegVersion(force?: boolean): string { - try { - const info = FFmpeg.getInfo(Boolean(force)); - - return info.version; - } catch { - return null; - } - } - - /** - * Checks FFmpeg - * @param {Boolean} [force] If it should forcefully get the version - * @returns {Boolean} - */ - static checkFFmpeg(force?: boolean): boolean { - const version = Util.getFFmpegVersion(force); - return version === null ? false : true; - } - - /** - * Alerts if FFmpeg is not available - */ - static alertFFmpeg(): void { - const hasFFmpeg = Util.checkFFmpeg(); - - if (!hasFFmpeg) console.warn('[Discord Player] FFmpeg/Avconv not found! Install via "npm install ffmpeg-static" or download from https://ffmpeg.org/download.html'); - } - - /** - * Resolves query type - * @param {String} query The query - * @returns {QueryType} - */ - static getQueryType(query: string): QueryType { - if (SoundcloudValidateURL(query, 'track')) return 'soundcloud_track'; - if (SoundcloudValidateURL(query, 'playlist') || query.includes('/sets/')) return 'soundcloud_playlist'; - if (spotifySongRegex.test(query)) return 'spotify_song'; - if (spotifyAlbumRegex.test(query)) return 'spotify_album'; - if (spotifyPlaylistRegex.test(query)) return 'spotify_playlist'; - if (YouTube.validate(query, 'PLAYLIST')) return 'youtube_playlist'; - if (YouTube.validate(query, 'VIDEO')) return 'youtube_video'; - if (vimeoRegex.test(query)) return 'vimeo'; - if (facebookRegex.test(query)) return 'facebook'; - if (reverbnationRegex.test(query)) return 'reverbnation'; - if (Util.isURL(query)) return 'attachment'; - - return 'youtube_search'; - } - - /** - * Checks if the given string is url - * @param {String} str URL to check - * @returns {Boolean} - */ - static isURL(str: string): boolean { - return str.length < 2083 && attachmentRegex.test(str); - } - - /** - * Returns Vimeo ID - * @param {String} query Vimeo link - * @returns {String} - */ - static getVimeoID(query: string): string { - return Util.getQueryType(query) === 'vimeo' - ? query - .split('/') - .filter((x) => !!x) - .pop() - : null; - } - - /** - * Parses ms time - * @param {Number} milliseconds Time to parse - * @returns {TimeData} - */ - static parseMS(milliseconds: number): TimeData { - const roundTowardsZero = milliseconds > 0 ? Math.floor : Math.ceil; - - return { - days: roundTowardsZero(milliseconds / 86400000), - hours: roundTowardsZero(milliseconds / 3600000) % 24, - minutes: roundTowardsZero(milliseconds / 60000) % 60, - seconds: roundTowardsZero(milliseconds / 1000) % 60 - }; - } - - /** - * Creates simple duration string - * @param {object} durObj Duration object - * @returns {String} - */ - static durationString(durObj: object): string { + static durationString(durObj: Record) { return Object.values(durObj) .map((m) => (isNaN(m) ? 0 : m)) - .join(':'); + .join(":"); } /** - * Makes youtube searches - * @param {String} query The query - * @param {any} options Options - * @returns {Promise} + * Parses milliseconds to consumable time object + * @param {number} milliseconds The time in ms + * @returns {TimeData} */ - static ytSearch(query: string, options?: any): Promise { - return new Promise(async (resolve) => { - await YouTube.search(query, { - type: 'video', - safeSearch: Boolean(options?.player.options.useSafeSearch), - limit: options.limit ?? 10 - }) - .then((results) => { - resolve( - results.map( - (r) => - new Track(options?.player, { - title: r.title, - description: r.description, - author: r.channel.name, - url: r.url, - thumbnail: r.thumbnail.displayThumbnailURL(), - duration: Util.buildTimeCode(Util.parseMS(r.duration)), - views: r.views, - requestedBy: options?.user, - fromPlaylist: Boolean(options?.pl), - source: 'youtube' - }) - ) - ); - }) - .catch(() => resolve([])); - }); - } + static parseMS(milliseconds: number) { + const round = milliseconds > 0 ? Math.floor : Math.ceil; - /** - * Checks if the given voice channel is empty - * @param {DiscordVoiceChannel} channel The voice channel - * @returns {Boolean} - */ - static isVoiceEmpty(channel: VoiceChannel): boolean { - return channel.members.filter((member) => !member.user.bot).size === 0; + return { + days: round(milliseconds / 86400000), + hours: round(milliseconds / 3600000) % 24, + minutes: round(milliseconds / 60000) % 60, + seconds: round(milliseconds / 1000) % 60 + } as TimeData; } /** * Builds time code - * @param {object} data The data to build time code from - * @returns {String} + * @param {TimeData} duration The duration object + * @returns {string} */ - static buildTimeCode(data: any): string { - const items = Object.keys(data); - const required = ['days', 'hours', 'minutes', 'seconds']; + static buildTimeCode(duration: TimeData) { + const items = Object.keys(duration); + const required = ["days", "hours", "minutes", "seconds"]; - const parsed = items.filter((x) => required.includes(x)).map((m) => (data[m] > 0 ? data[m] : '')); + const parsed = items.filter((x) => required.includes(x)).map((m) => duration[m as keyof TimeData]); const final = parsed - .filter((x) => !!x) - .map((x) => x.toString().padStart(2, '0')) - .join(':'); - return final.length <= 3 ? `0:${final.padStart(2, '0') || 0}` : final; + .slice(parsed.findIndex((x) => x !== 0)) + .map((x) => x.toString().padStart(2, "0")) + .join(":"); + + return final.length <= 3 ? `0:${final.padStart(2, "0") || 0}` : final; } /** - * Manage CJS require - * @param {String} id id to require + * Picks last item of the given array + * @param {any[]} arr The array * @returns {any} */ - static require(id: string): any { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + static last(arr: T[]): T { + if (!Array.isArray(arr)) return; + return arr[arr.length - 1]; + } + + /** + * Checks if the voice channel is empty + * @param {VoiceChannel|StageChannel} channel The voice channel + * @returns {boolean} + */ + static isVoiceEmpty(channel: VoiceChannel | StageChannel) { + return channel.members.filter((member) => !member.user.bot).size === 0; + } + + /** + * Safer require + * @param {string} id Node require id + * @returns {any} + */ + static require(id: string) { try { return require(id); } catch { @@ -203,20 +86,15 @@ export class Util { } /** - * Defines a property in the given object - * @param {any} target The target - * @param {any} prop The property to define - * @param {any} value The value - * @returns {void} + * Asynchronous timeout + * @param {number} time The time in ms to wait + * @returns {Promise} */ - static define(ops: { target: any; prop: any; value: any; enumerate?: boolean }) { - Object.defineProperty(ops.target, ops.prop, { - value: ops.value, - writable: true, - enumerable: Boolean(ops.enumerate), - configurable: true - }); + static wait(time: number) { + return new Promise((r) => setTimeout(r, time).unref()); } + + static noop() {} // eslint-disable-line @typescript-eslint/no-empty-function } -export default Util; +export { Util }; diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json new file mode 100644 index 0000000..6a357fa --- /dev/null +++ b/tsconfig.eslint.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "**/*.ts", + "**/*.js" + ], + "exclude": [] +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 629bcf8..d7ef062 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,10 +3,12 @@ "target": "ES6", "module": "commonjs", "declaration": true, - "outDir": "./lib", + "outDir": "./dist", "strict": true, "strictNullChecks": false, - "esModuleInterop": true + "esModuleInterop": true, + "pretty": true, + "skipLibCheck": true }, "include": [ "src/**/*" diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 4e5571c..0000000 --- a/tslint.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": ["tslint:recommended", "tslint-config-prettier"], - "jsRules": { - "no-unused-expression": true - }, - "rules": { - "object-literal-sort-keys": false, - "interface-name": false, - "no-empty": false, - "no-console": false, - "radix": false - }, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index fdebb4b..2419a4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@babel/cli@^7.13.16": - version "7.13.16" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.13.16.tgz#9d372e943ced0cc291f068204a9b010fd9cfadbc" - integrity sha512-cL9tllhqvsQ6r1+d9Invf7nNXg/3BlfL1vvvL/AdH9fZ2l5j0CeBcoq6UjsqHpvyN1v5nXSZgqJZoGeK+ZOAbw== +"@babel/cli@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.14.8.tgz#fac73c0e2328a8af9fd3560c06b096bfa3730933" + integrity sha512-lcy6Lymft9Rpfqmrqdd4oTDdUx9ZwaAhAfywVrHG4771Pa6PPT0danJ1kDHBXYqh4HHSmIdA+nlmfxfxSDPtBg== dependencies: commander "^4.0.1" convert-source-map "^1.1.0" @@ -15,35 +15,42 @@ slash "^2.0.0" source-map "^0.5.0" optionalDependencies: - "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents" + "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents.2" chokidar "^3.4.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" - integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== dependencies: - "@babel/highlight" "^7.12.13" + "@babel/highlight" "^7.10.4" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.4": - version "7.14.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.4.tgz#45720fe0cecf3fd42019e1d12cc3d27fadc98d58" - integrity sha512-i2wXrWQNkH6JplJQGn3Rd2I4Pij8GdHkXwHMxm+zV5YG/Jci+bCNrWZEWC4o+umiDkRrRs4dVzH3X4GP7vyjQQ== - -"@babel/core@^7.13.16": - version "7.13.16" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.16.tgz#7756ab24396cc9675f1c3fcd5b79fcce192ea96a" - integrity sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" + integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.13.16" - "@babel/helper-compilation-targets" "^7.13.16" - "@babel/helper-module-transforms" "^7.13.14" - "@babel/helpers" "^7.13.16" - "@babel/parser" "^7.13.16" - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.13.15" - "@babel/types" "^7.13.16" + "@babel/highlight" "^7.14.5" + +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.7", "@babel/compat-data@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" + integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== + +"@babel/core@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.0.tgz#749e57c68778b73ad8082775561f67f5196aafa8" + integrity sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.15.0" + "@babel/helper-compilation-targets" "^7.15.0" + "@babel/helper-module-transforms" "^7.15.0" + "@babel/helpers" "^7.14.8" + "@babel/parser" "^7.15.0" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.15.0" + "@babel/types" "^7.15.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -51,84 +58,64 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.13.16": - version "7.13.16" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.16.tgz#0befc287031a201d84cdfc173b46b320ae472d14" - integrity sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg== +"@babel/generator@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.0.tgz#a7d0c172e0d814974bad5aa77ace543b97917f15" + integrity sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ== dependencies: - "@babel/types" "^7.13.16" + "@babel/types" "^7.15.0" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.14.2": - version "7.14.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.3.tgz#0c2652d91f7bddab7cccc6ba8157e4f40dcedb91" - integrity sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA== +"@babel/helper-annotate-as-pure@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61" + integrity sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA== dependencies: - "@babel/types" "^7.14.2" - jsesc "^2.5.1" - source-map "^0.5.0" + "@babel/types" "^7.14.5" -"@babel/helper-annotate-as-pure@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" - integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz#b939b43f8c37765443a19ae74ad8b15978e0a191" + integrity sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w== dependencies: - "@babel/types" "^7.12.13" + "@babel/helper-explode-assignable-expression" "^7.14.5" + "@babel/types" "^7.14.5" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc" - integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA== +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5", "@babel/helper-compilation-targets@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz#973df8cbd025515f3ff25db0c05efc704fa79818" + integrity sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A== dependencies: - "@babel/helper-explode-assignable-expression" "^7.12.13" - "@babel/types" "^7.12.13" - -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.14.4": - version "7.14.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.4.tgz#33ebd0ffc34248051ee2089350a929ab02f2a516" - integrity sha512-JgdzOYZ/qGaKTVkn5qEDV/SXAh8KcyUVkCoSWGN8T3bwrgd6m+/dJa2kVGi6RJYJgEYPBdZ84BZp9dUjNWkBaA== - dependencies: - "@babel/compat-data" "^7.14.4" - "@babel/helper-validator-option" "^7.12.17" + "@babel/compat-data" "^7.15.0" + "@babel/helper-validator-option" "^7.14.5" browserslist "^4.16.6" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.13.0": - version "7.13.11" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz#30d30a005bca2c953f5653fc25091a492177f4f6" - integrity sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw== +"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.0.tgz#c9a137a4d137b2d0e2c649acf536d7ba1a76c0f7" + integrity sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q== dependencies: - "@babel/helper-function-name" "^7.12.13" - "@babel/helper-member-expression-to-functions" "^7.13.0" - "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/helper-replace-supers" "^7.13.0" - "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/helper-annotate-as-pure" "^7.14.5" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-member-expression-to-functions" "^7.15.0" + "@babel/helper-optimise-call-expression" "^7.14.5" + "@babel/helper-replace-supers" "^7.15.0" + "@babel/helper-split-export-declaration" "^7.14.5" -"@babel/helper-create-class-features-plugin@^7.14.0", "@babel/helper-create-class-features-plugin@^7.14.3": - version "7.14.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.4.tgz#abf888d836a441abee783c75229279748705dc42" - integrity sha512-idr3pthFlDCpV+p/rMgGLGYIVtazeatrSOQk8YzO2pAepIjQhCN3myeihVg58ax2bbbGK9PUE1reFi7axOYIOw== +"@babel/helper-create-regexp-features-plugin@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz#c7d5ac5e9cf621c26057722fb7a8a4c5889358c4" + integrity sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A== dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-function-name" "^7.14.2" - "@babel/helper-member-expression-to-functions" "^7.13.12" - "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/helper-replace-supers" "^7.14.4" - "@babel/helper-split-export-declaration" "^7.12.13" - -"@babel/helper-create-regexp-features-plugin@^7.12.13": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz#a2ac87e9e319269ac655b8d4415e94d38d663cb7" - integrity sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-annotate-as-pure" "^7.14.5" regexpu-core "^4.7.1" -"@babel/helper-define-polyfill-provider@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz#a640051772045fedaaecc6f0c6c69f02bdd34bf1" - integrity sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw== +"@babel/helper-define-polyfill-provider@^0.2.2": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz#0525edec5094653a282688d34d846e4c75e9c0b6" + integrity sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew== dependencies: "@babel/helper-compilation-targets" "^7.13.0" "@babel/helper-module-imports" "^7.12.13" @@ -139,339 +126,295 @@ resolve "^1.14.2" semver "^6.1.2" -"@babel/helper-explode-assignable-expression@^7.12.13": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f" - integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA== +"@babel/helper-explode-assignable-expression@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz#8aa72e708205c7bb643e45c73b4386cdf2a1f645" + integrity sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ== dependencies: - "@babel/types" "^7.13.0" + "@babel/types" "^7.14.5" -"@babel/helper-function-name@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" - integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== +"@babel/helper-function-name@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4" + integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ== dependencies: - "@babel/helper-get-function-arity" "^7.12.13" - "@babel/template" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/helper-get-function-arity" "^7.14.5" + "@babel/template" "^7.14.5" + "@babel/types" "^7.14.5" -"@babel/helper-function-name@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz#397688b590760b6ef7725b5f0860c82427ebaac2" - integrity sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ== +"@babel/helper-get-function-arity@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815" + integrity sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg== dependencies: - "@babel/helper-get-function-arity" "^7.12.13" - "@babel/template" "^7.12.13" - "@babel/types" "^7.14.2" + "@babel/types" "^7.14.5" -"@babel/helper-get-function-arity@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" - integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== +"@babel/helper-hoist-variables@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d" + integrity sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ== dependencies: - "@babel/types" "^7.12.13" + "@babel/types" "^7.14.5" -"@babel/helper-hoist-variables@^7.13.0": - version "7.13.16" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz#1b1651249e94b51f8f0d33439843e33e39775b30" - integrity sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg== +"@babel/helper-member-expression-to-functions@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz#0ddaf5299c8179f27f37327936553e9bba60990b" + integrity sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg== dependencies: - "@babel/traverse" "^7.13.15" - "@babel/types" "^7.13.16" + "@babel/types" "^7.15.0" -"@babel/helper-member-expression-to-functions@^7.13.0", "@babel/helper-member-expression-to-functions@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" - integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3" + integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ== dependencies: - "@babel/types" "^7.13.12" + "@babel/types" "^7.14.5" -"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" - integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== +"@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz#679275581ea056373eddbe360e1419ef23783b08" + integrity sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg== dependencies: - "@babel/types" "^7.13.12" + "@babel/helper-module-imports" "^7.14.5" + "@babel/helper-replace-supers" "^7.15.0" + "@babel/helper-simple-access" "^7.14.8" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/helper-validator-identifier" "^7.14.9" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.15.0" + "@babel/types" "^7.15.0" -"@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.13.14": - version "7.13.14" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz#e600652ba48ccb1641775413cb32cfa4e8b495ef" - integrity sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g== +"@babel/helper-optimise-call-expression@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c" + integrity sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA== dependencies: - "@babel/helper-module-imports" "^7.13.12" - "@babel/helper-replace-supers" "^7.13.12" - "@babel/helper-simple-access" "^7.13.12" - "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/helper-validator-identifier" "^7.12.11" - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.13.13" - "@babel/types" "^7.13.14" + "@babel/types" "^7.14.5" -"@babel/helper-module-transforms@^7.14.0", "@babel/helper-module-transforms@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz#ac1cc30ee47b945e3e0c4db12fa0c5389509dfe5" - integrity sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" + integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== + +"@babel/helper-remap-async-to-generator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz#51439c913612958f54a987a4ffc9ee587a2045d6" + integrity sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A== dependencies: - "@babel/helper-module-imports" "^7.13.12" - "@babel/helper-replace-supers" "^7.13.12" - "@babel/helper-simple-access" "^7.13.12" - "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/helper-validator-identifier" "^7.14.0" - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.14.2" - "@babel/types" "^7.14.2" + "@babel/helper-annotate-as-pure" "^7.14.5" + "@babel/helper-wrap-function" "^7.14.5" + "@babel/types" "^7.14.5" -"@babel/helper-optimise-call-expression@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" - integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== +"@babel/helper-replace-supers@^7.14.5", "@babel/helper-replace-supers@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz#ace07708f5bf746bf2e6ba99572cce79b5d4e7f4" + integrity sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA== dependencies: - "@babel/types" "^7.12.13" + "@babel/helper-member-expression-to-functions" "^7.15.0" + "@babel/helper-optimise-call-expression" "^7.14.5" + "@babel/traverse" "^7.15.0" + "@babel/types" "^7.15.0" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" - integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== - -"@babel/helper-remap-async-to-generator@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209" - integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg== +"@babel/helper-simple-access@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz#82e1fec0644a7e775c74d305f212c39f8fe73924" + integrity sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg== dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-wrap-function" "^7.13.0" - "@babel/types" "^7.13.0" + "@babel/types" "^7.14.8" -"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" - integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== +"@babel/helper-skip-transparent-expression-wrappers@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz#96f486ac050ca9f44b009fbe5b7d394cab3a0ee4" + integrity sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ== dependencies: - "@babel/helper-member-expression-to-functions" "^7.13.12" - "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/traverse" "^7.13.0" - "@babel/types" "^7.13.12" + "@babel/types" "^7.14.5" -"@babel/helper-replace-supers@^7.14.4": - version "7.14.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz#b2ab16875deecfff3ddfcd539bc315f72998d836" - integrity sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ== +"@babel/helper-split-export-declaration@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a" + integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA== dependencies: - "@babel/helper-member-expression-to-functions" "^7.13.12" - "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/traverse" "^7.14.2" - "@babel/types" "^7.14.4" + "@babel/types" "^7.14.5" -"@babel/helper-simple-access@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" - integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== +"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9": + version "7.14.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" + integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== + +"@babel/helper-validator-option@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" + integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== + +"@babel/helper-wrap-function@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz#5919d115bf0fe328b8a5d63bcb610f51601f2bff" + integrity sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ== dependencies: - "@babel/types" "^7.13.12" + "@babel/helper-function-name" "^7.14.5" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.5" + "@babel/types" "^7.14.5" -"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" - integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== +"@babel/helpers@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.8.tgz#839f88f463025886cff7f85a35297007e2da1b77" + integrity sha512-ZRDmI56pnV+p1dH6d+UN6GINGz7Krps3+270qqI9UJ4wxYThfAIcI5i7j5vXC4FJ3Wap+S9qcebxeYiqn87DZw== dependencies: - "@babel/types" "^7.12.1" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.8" + "@babel/types" "^7.14.8" -"@babel/helper-split-export-declaration@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05" - integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== +"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" + integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== dependencies: - "@babel/types" "^7.12.13" - -"@babel/helper-validator-identifier@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" - integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== - -"@babel/helper-validator-identifier@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" - integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== - -"@babel/helper-validator-option@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" - integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== - -"@babel/helper-wrap-function@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4" - integrity sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA== - dependencies: - "@babel/helper-function-name" "^7.12.13" - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.13.0" - "@babel/types" "^7.13.0" - -"@babel/helpers@^7.13.16": - version "7.13.17" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.17.tgz#b497c7a00e9719d5b613b8982bda6ed3ee94caf6" - integrity sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg== - dependencies: - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.13.17" - "@babel/types" "^7.13.17" - -"@babel/highlight@^7.12.13": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" - integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" + "@babel/helper-validator-identifier" "^7.14.5" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.12.13", "@babel/parser@^7.13.16", "@babel/parser@^7.9.4": - version "7.13.16" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.16.tgz#0f18179b0448e6939b1f3f5c4c355a3a9bcdfd37" - integrity sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw== +"@babel/parser@^7.14.5", "@babel/parser@^7.15.0", "@babel/parser@^7.9.4": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.0.tgz#b6d6e29058ca369127b0eeca2a1c4b5794f1b6b9" + integrity sha512-0v7oNOjr6YT9Z2RAOTv4T9aP+ubfx4Q/OhVtAet7PFDt0t9Oy6Jn+/rfC6b8HJ5zEqrQCiMxJfgtHpmIminmJQ== -"@babel/parser@^7.14.2": - version "7.14.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.4.tgz#a5c560d6db6cd8e6ed342368dea8039232cbab18" - integrity sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA== - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a" - integrity sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e" + integrity sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" - "@babel/plugin-proposal-optional-chaining" "^7.13.12" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" + "@babel/plugin-proposal-optional-chaining" "^7.14.5" -"@babel/plugin-proposal-async-generator-functions@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.2.tgz#3a2085abbf5d5f962d480dbc81347385ed62eb1e" - integrity sha512-b1AM4F6fwck4N8ItZ/AtC4FP/cqZqmKRQ4FaTDutwSYyjuhtvsGEMLK4N/ztV/ImP40BjIDyMgBQAeAMsQYVFQ== +"@babel/plugin-proposal-async-generator-functions@^7.14.9": + version "7.14.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.9.tgz#7028dc4fa21dc199bbacf98b39bab1267d0eaf9a" + integrity sha512-d1lnh+ZnKrFKwtTYdw320+sQWCTwgkB9fmUhNXRADA4akR6wLjaruSGnIEUjpt9HCOwTr4ynFTKu19b7rFRpmw== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-remap-async-to-generator" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-remap-async-to-generator" "^7.14.5" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-class-properties@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37" - integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg== +"@babel/plugin-proposal-class-properties@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz#40d1ee140c5b1e31a350f4f5eed945096559b42e" + integrity sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.13.0" - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-create-class-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-proposal-class-static-block@^7.14.3": - version "7.14.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.3.tgz#5a527e2cae4a4753119c3a3e7f64ecae8ccf1360" - integrity sha512-HEjzp5q+lWSjAgJtSluFDrGGosmwTgKwCXdDQZvhKsRlwv3YdkUEqxNrrjesJd+B9E9zvr1PVPVBvhYZ9msjvQ== +"@babel/plugin-proposal-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz#158e9e10d449c3849ef3ecde94a03d9f1841b681" + integrity sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.3" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/plugin-syntax-class-static-block" "^7.12.13" + "@babel/helper-create-class-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-proposal-dynamic-import@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.2.tgz#01ebabd7c381cff231fa43e302939a9de5be9d9f" - integrity sha512-oxVQZIWFh91vuNEMKltqNsKLFWkOIyJc95k2Gv9lWVyDfPUQGSSlbDEgWuJUU1afGE9WwlzpucMZ3yDRHIItkA== +"@babel/plugin-proposal-dynamic-import@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz#0c6617df461c0c1f8fff3b47cd59772360101d2c" + integrity sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-proposal-export-namespace-from@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.2.tgz#62542f94aa9ce8f6dba79eec698af22112253791" - integrity sha512-sRxW3z3Zp3pFfLAgVEvzTFutTXax837oOatUIvSG9o5gRj9mKwm3br1Se5f4QalTQs9x4AzlA/HrCWbQIHASUQ== +"@babel/plugin-proposal-export-namespace-from@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz#dbad244310ce6ccd083072167d8cea83a52faf76" + integrity sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.2.tgz#830b4e2426a782e8b2878fbfe2cba85b70cbf98c" - integrity sha512-w2DtsfXBBJddJacXMBhElGEYqCZQqN99Se1qeYn8DVLB33owlrlLftIbMzn5nz1OITfDVknXF433tBrLEAOEjA== +"@babel/plugin-proposal-json-strings@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz#38de60db362e83a3d8c944ac858ddf9f0c2239eb" + integrity sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.2.tgz#222348c080a1678e0e74ea63fe76f275882d1fd7" - integrity sha512-1JAZtUrqYyGsS7IDmFeaem+/LJqujfLZ2weLR9ugB0ufUPjzf8cguyVT1g5im7f7RXxuLq1xUxEzvm68uYRtGg== +"@babel/plugin-proposal-logical-assignment-operators@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz#6e6229c2a99b02ab2915f82571e0cc646a40c738" + integrity sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.2.tgz#425b11dc62fc26939a2ab42cbba680bdf5734546" - integrity sha512-ebR0zU9OvI2N4qiAC38KIAK75KItpIPTpAtd2r4OZmMFeKbKJpUFLYP2EuDut82+BmYi8sz42B+TfTptJ9iG5Q== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz#ee38589ce00e2cc59b299ec3ea406fcd3a0fdaf6" + integrity sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.2.tgz#82b4cc06571143faf50626104b335dd71baa4f9e" - integrity sha512-DcTQY9syxu9BpU3Uo94fjCB3LN9/hgPS8oUL7KrSW3bA2ePrKZZPJcc5y0hoJAM9dft3pGfErtEUvxXQcfLxUg== +"@babel/plugin-proposal-numeric-separator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz#83631bf33d9a51df184c2102a069ac0c58c05f18" + integrity sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.14.4": - version "7.14.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.4.tgz#0e2b4de419915dc0b409378e829412e2031777c4" - integrity sha512-AYosOWBlyyXEagrPRfLJ1enStufsr7D1+ddpj8OLi9k7B6+NdZ0t/9V7Fh+wJ4g2Jol8z2JkgczYqtWrZd4vbA== +"@babel/plugin-proposal-object-rest-spread@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz#5920a2b3df7f7901df0205974c0641b13fd9d363" + integrity sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g== dependencies: - "@babel/compat-data" "^7.14.4" - "@babel/helper-compilation-targets" "^7.14.4" - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/compat-data" "^7.14.7" + "@babel/helper-compilation-targets" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.14.2" + "@babel/plugin-transform-parameters" "^7.14.5" -"@babel/plugin-proposal-optional-catch-binding@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.2.tgz#150d4e58e525b16a9a1431bd5326c4eed870d717" - integrity sha512-XtkJsmJtBaUbOxZsNk0Fvrv8eiqgneug0A6aqLFZ4TSkar2L5dSXWcnUKHgmjJt49pyB/6ZHvkr3dPgl9MOWRQ== +"@babel/plugin-proposal-optional-catch-binding@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz#939dd6eddeff3a67fdf7b3f044b5347262598c3c" + integrity sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.2.tgz#df8171a8b9c43ebf4c1dabe6311b432d83e1b34e" - integrity sha512-qQByMRPwMZJainfig10BoaDldx/+VDtNcrA7qdNaEOAj6VXud+gfrkA8j4CRAU5HjnWREXqIpSpH30qZX1xivA== +"@babel/plugin-proposal-optional-chaining@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz#fa83651e60a360e3f13797eef00b8d519695b603" + integrity sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787" - integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q== +"@babel/plugin-proposal-private-methods@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz#37446495996b2945f30f5be5b60d5e2aa4f5792d" + integrity sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g== dependencies: - "@babel/helper-create-class-features-plugin" "^7.13.0" - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-create-class-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-proposal-private-property-in-object@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.0.tgz#b1a1f2030586b9d3489cc26179d2eb5883277636" - integrity sha512-59ANdmEwwRUkLjB7CRtwJxxwtjESw+X2IePItA+RGQh+oy5RmpCh/EvVVvh5XQc3yxsm5gtv0+i9oBZhaDNVTg== +"@babel/plugin-proposal-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz#9f65a4d0493a940b4c01f8aa9d3f1894a587f636" + integrity sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q== dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-create-class-features-plugin" "^7.14.0" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/plugin-syntax-private-property-in-object" "^7.14.0" + "@babel/helper-annotate-as-pure" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" - integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg== +"@babel/plugin-proposal-unicode-property-regex@^7.14.5", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz#0f95ee0e757a5d647f378daa0eca7e93faa8bbe8" + integrity sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-create-regexp-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -487,12 +430,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-class-static-block@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.12.13.tgz#8e3d674b0613e67975ceac2776c97b60cafc5c9c" - integrity sha512-ZmKQ0ZXR0nYpHZIIuj9zE7oIqCx2hw9TKi+lIo73NNrMPAZGHfS92/VRV0ZmPj6H2ffBgyFHXvJ5NYsNeEaP2A== +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" @@ -557,312 +500,312 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-private-property-in-object@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.0.tgz#762a4babec61176fec6c88480dec40372b140c0b" - integrity sha512-bda3xF8wGl5/5btF794utNOL0Jw+9jE5C1sLZcoK7c4uonE/y3iQiyG+KbkF3WBV/paX58VCpjhxLPkdj5Fe4w== +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-top-level-await@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" - integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz#9dff111ca64154cef0f4dc52cf843d9f12ce4474" - integrity sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w== +"@babel/plugin-syntax-typescript@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" + integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-arrow-functions@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" - integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg== +"@babel/plugin-transform-arrow-functions@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz#f7187d9588a768dd080bf4c9ffe117ea62f7862a" + integrity sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-async-to-generator@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f" - integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg== +"@babel/plugin-transform-async-to-generator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz#72c789084d8f2094acb945633943ef8443d39e67" + integrity sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA== dependencies: - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-remap-async-to-generator" "^7.13.0" + "@babel/helper-module-imports" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-remap-async-to-generator" "^7.14.5" -"@babel/plugin-transform-block-scoped-functions@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4" - integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg== +"@babel/plugin-transform-block-scoped-functions@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz#e48641d999d4bc157a67ef336aeb54bc44fd3ad4" + integrity sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-block-scoping@^7.14.4": - version "7.14.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.4.tgz#caf140b0b2e2462c509553d140e6d0abefb61ed8" - integrity sha512-5KdpkGxsZlTk+fPleDtGKsA+pon28+ptYmMO8GBSa5fHERCJWAzj50uAfCKBqq42HO+Zot6JF1x37CRprwmN4g== +"@babel/plugin-transform-block-scoping@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz#8cc63e61e50f42e078e6f09be775a75f23ef9939" + integrity sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-classes@^7.14.4": - version "7.14.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.4.tgz#a83c15503fc71a0f99e876fdce7dadbc6575ec3a" - integrity sha512-p73t31SIj6y94RDVX57rafVjttNr8MvKEgs5YFatNB/xC68zM3pyosuOEcQmYsYlyQaGY9R7rAULVRcat5FKJQ== +"@babel/plugin-transform-classes@^7.14.9": + version "7.14.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.9.tgz#2a391ffb1e5292710b00f2e2c210e1435e7d449f" + integrity sha512-NfZpTcxU3foGWbl4wxmZ35mTsYJy8oQocbeIMoDAGGFarAmSQlL+LWMkDx/tj6pNotpbX3rltIA4dprgAPOq5A== dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-function-name" "^7.14.2" - "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-replace-supers" "^7.14.4" - "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/helper-annotate-as-pure" "^7.14.5" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-optimise-call-expression" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-replace-supers" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed" - integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg== +"@babel/plugin-transform-computed-properties@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz#1b9d78987420d11223d41195461cc43b974b204f" + integrity sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-destructuring@^7.14.4": - version "7.14.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.4.tgz#acbec502e9951f30f4441eaca1d2f29efade59ed" - integrity sha512-JyywKreTCGTUsL1OKu1A3ms/R1sTP0WxbpXlALeGzF53eB3bxtNkYdMj9SDgK7g6ImPy76J5oYYKoTtQImlhQA== +"@babel/plugin-transform-destructuring@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz#0ad58ed37e23e22084d109f185260835e5557576" + integrity sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" - integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ== +"@babel/plugin-transform-dotall-regex@^7.14.5", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz#2f6bf76e46bdf8043b4e7e16cf24532629ba0c7a" + integrity sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-create-regexp-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-duplicate-keys@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de" - integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ== +"@babel/plugin-transform-duplicate-keys@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz#365a4844881bdf1501e3a9f0270e7f0f91177954" + integrity sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-exponentiation-operator@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" - integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA== +"@babel/plugin-transform-exponentiation-operator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz#5154b8dd6a3dfe6d90923d61724bd3deeb90b493" + integrity sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-for-of@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062" - integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg== +"@babel/plugin-transform-for-of@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz#dae384613de8f77c196a8869cbf602a44f7fc0eb" + integrity sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-function-name@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051" - integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ== +"@babel/plugin-transform-function-name@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz#e81c65ecb900746d7f31802f6bed1f52d915d6f2" + integrity sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ== dependencies: - "@babel/helper-function-name" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-literals@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9" - integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ== +"@babel/plugin-transform-literals@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz#41d06c7ff5d4d09e3cf4587bd3ecf3930c730f78" + integrity sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-member-expression-literals@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40" - integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg== +"@babel/plugin-transform-member-expression-literals@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz#b39cd5212a2bf235a617d320ec2b48bcc091b8a7" + integrity sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-modules-amd@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.2.tgz#6622806fe1a7c07a1388444222ef9535f2ca17b0" - integrity sha512-hPC6XBswt8P3G2D1tSV2HzdKvkqOpmbyoy+g73JG0qlF/qx2y3KaMmXb1fLrpmWGLZYA0ojCvaHdzFWjlmV+Pw== +"@babel/plugin-transform-modules-amd@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz#4fd9ce7e3411cb8b83848480b7041d83004858f7" + integrity sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g== dependencies: - "@babel/helper-module-transforms" "^7.14.2" - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-module-transforms" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz#52bc199cb581e0992edba0f0f80356467587f161" - integrity sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ== +"@babel/plugin-transform-modules-commonjs@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.0.tgz#3305896e5835f953b5cdb363acd9e8c2219a5281" + integrity sha512-3H/R9s8cXcOGE8kgMlmjYYC9nqr5ELiPkJn4q0mypBrjhYQoc+5/Maq69vV4xRPWnkzZuwJPf5rArxpB/35Cig== dependencies: - "@babel/helper-module-transforms" "^7.14.0" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-simple-access" "^7.13.12" + "@babel/helper-module-transforms" "^7.15.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-simple-access" "^7.14.8" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3" - integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A== +"@babel/plugin-transform-modules-systemjs@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz#c75342ef8b30dcde4295d3401aae24e65638ed29" + integrity sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA== dependencies: - "@babel/helper-hoist-variables" "^7.13.0" - "@babel/helper-module-transforms" "^7.13.0" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-validator-identifier" "^7.12.11" + "@babel/helper-hoist-variables" "^7.14.5" + "@babel/helper-module-transforms" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-identifier" "^7.14.5" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz#2f8179d1bbc9263665ce4a65f305526b2ea8ac34" - integrity sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw== +"@babel/plugin-transform-modules-umd@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz#fb662dfee697cce274a7cda525190a79096aa6e0" + integrity sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA== dependencies: - "@babel/helper-module-transforms" "^7.14.0" - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-module-transforms" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9" - integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA== +"@babel/plugin-transform-named-capturing-groups-regex@^7.14.9": + version "7.14.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz#c68f5c5d12d2ebaba3762e57c2c4f6347a46e7b2" + integrity sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-create-regexp-features-plugin" "^7.14.5" -"@babel/plugin-transform-new-target@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c" - integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ== +"@babel/plugin-transform-new-target@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz#31bdae8b925dc84076ebfcd2a9940143aed7dbf8" + integrity sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-object-super@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" - integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ== +"@babel/plugin-transform-object-super@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz#d0b5faeac9e98597a161a9cf78c527ed934cdc45" + integrity sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/helper-replace-supers" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-replace-supers" "^7.14.5" -"@babel/plugin-transform-parameters@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.2.tgz#e4290f72e0e9e831000d066427c4667098decc31" - integrity sha512-NxoVmA3APNCC1JdMXkdYXuQS+EMdqy0vIwyDHeKHiJKRxmp1qGSdb0JLEIoPRhkx6H/8Qi3RJ3uqOCYw8giy9A== +"@babel/plugin-transform-parameters@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz#49662e86a1f3ddccac6363a7dfb1ff0a158afeb3" + integrity sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-property-literals@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81" - integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A== +"@babel/plugin-transform-property-literals@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz#0ddbaa1f83db3606f1cdf4846fa1dfb473458b34" + integrity sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-regenerator@^7.13.15": - version "7.13.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz#e5eb28945bf8b6563e7f818945f966a8d2997f39" - integrity sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ== +"@babel/plugin-transform-regenerator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz#9676fd5707ed28f522727c5b3c0aa8544440b04f" + integrity sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg== dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695" - integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg== +"@babel/plugin-transform-reserved-words@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz#c44589b661cfdbef8d4300dcc7469dffa92f8304" + integrity sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-shorthand-properties@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad" - integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw== +"@babel/plugin-transform-shorthand-properties@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz#97f13855f1409338d8cadcbaca670ad79e091a58" + integrity sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-spread@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd" - integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg== +"@babel/plugin-transform-spread@^7.14.6": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz#6bd40e57fe7de94aa904851963b5616652f73144" + integrity sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" -"@babel/plugin-transform-sticky-regex@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f" - integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg== +"@babel/plugin-transform-sticky-regex@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz#5b617542675e8b7761294381f3c28c633f40aeb9" + integrity sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-template-literals@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d" - integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw== +"@babel/plugin-transform-template-literals@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz#a5f2bc233937d8453885dc736bdd8d9ffabf3d93" + integrity sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-typeof-symbol@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f" - integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ== +"@babel/plugin-transform-typeof-symbol@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz#39af2739e989a2bd291bf6b53f16981423d457d4" + integrity sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-typescript@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz#4a498e1f3600342d2a9e61f60131018f55774853" - integrity sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ== +"@babel/plugin-transform-typescript@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.0.tgz#553f230b9d5385018716586fc48db10dd228eb7e" + integrity sha512-WIIEazmngMEEHDaPTx0IZY48SaAmjVWe3TRSX7cmJXn0bEv9midFzAjxiruOWYIVf5iQ10vFx7ASDpgEO08L5w== dependencies: - "@babel/helper-create-class-features-plugin" "^7.13.0" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/plugin-syntax-typescript" "^7.12.13" + "@babel/helper-create-class-features-plugin" "^7.15.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-typescript" "^7.14.5" -"@babel/plugin-transform-unicode-escapes@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74" - integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw== +"@babel/plugin-transform-unicode-escapes@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz#9d4bd2a681e3c5d7acf4f57fa9e51175d91d0c6b" + integrity sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-unicode-regex@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac" - integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA== +"@babel/plugin-transform-unicode-regex@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz#4cd09b6c8425dd81255c7ceb3fb1836e7414382e" + integrity sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-create-regexp-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/preset-env@^7.13.15": - version "7.14.4" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.4.tgz#73fc3228c59727e5e974319156f304f0d6685a2d" - integrity sha512-GwMMsuAnDtULyOtuxHhzzuSRxFeP0aR/LNzrHRzP8y6AgDNgqnrfCCBm/1cRdTU75tRs28Eh76poHLcg9VF0LA== +"@babel/preset-env@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.15.0.tgz#e2165bf16594c9c05e52517a194bf6187d6fe464" + integrity sha512-FhEpCNFCcWW3iZLg0L2NPE9UerdtsCR6ZcsGHUX6Om6kbCQeL5QZDqFDmeNHC6/fy6UH3jEge7K4qG5uC9In0Q== dependencies: - "@babel/compat-data" "^7.14.4" - "@babel/helper-compilation-targets" "^7.14.4" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-validator-option" "^7.12.17" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.13.12" - "@babel/plugin-proposal-async-generator-functions" "^7.14.2" - "@babel/plugin-proposal-class-properties" "^7.13.0" - "@babel/plugin-proposal-class-static-block" "^7.14.3" - "@babel/plugin-proposal-dynamic-import" "^7.14.2" - "@babel/plugin-proposal-export-namespace-from" "^7.14.2" - "@babel/plugin-proposal-json-strings" "^7.14.2" - "@babel/plugin-proposal-logical-assignment-operators" "^7.14.2" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.2" - "@babel/plugin-proposal-numeric-separator" "^7.14.2" - "@babel/plugin-proposal-object-rest-spread" "^7.14.4" - "@babel/plugin-proposal-optional-catch-binding" "^7.14.2" - "@babel/plugin-proposal-optional-chaining" "^7.14.2" - "@babel/plugin-proposal-private-methods" "^7.13.0" - "@babel/plugin-proposal-private-property-in-object" "^7.14.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.12.13" + "@babel/compat-data" "^7.15.0" + "@babel/helper-compilation-targets" "^7.15.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.14.5" + "@babel/plugin-proposal-async-generator-functions" "^7.14.9" + "@babel/plugin-proposal-class-properties" "^7.14.5" + "@babel/plugin-proposal-class-static-block" "^7.14.5" + "@babel/plugin-proposal-dynamic-import" "^7.14.5" + "@babel/plugin-proposal-export-namespace-from" "^7.14.5" + "@babel/plugin-proposal-json-strings" "^7.14.5" + "@babel/plugin-proposal-logical-assignment-operators" "^7.14.5" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.5" + "@babel/plugin-proposal-numeric-separator" "^7.14.5" + "@babel/plugin-proposal-object-rest-spread" "^7.14.7" + "@babel/plugin-proposal-optional-catch-binding" "^7.14.5" + "@babel/plugin-proposal-optional-chaining" "^7.14.5" + "@babel/plugin-proposal-private-methods" "^7.14.5" + "@babel/plugin-proposal-private-property-in-object" "^7.14.5" + "@babel/plugin-proposal-unicode-property-regex" "^7.14.5" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-syntax-json-strings" "^7.8.3" @@ -872,46 +815,46 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.0" - "@babel/plugin-syntax-top-level-await" "^7.12.13" - "@babel/plugin-transform-arrow-functions" "^7.13.0" - "@babel/plugin-transform-async-to-generator" "^7.13.0" - "@babel/plugin-transform-block-scoped-functions" "^7.12.13" - "@babel/plugin-transform-block-scoping" "^7.14.4" - "@babel/plugin-transform-classes" "^7.14.4" - "@babel/plugin-transform-computed-properties" "^7.13.0" - "@babel/plugin-transform-destructuring" "^7.14.4" - "@babel/plugin-transform-dotall-regex" "^7.12.13" - "@babel/plugin-transform-duplicate-keys" "^7.12.13" - "@babel/plugin-transform-exponentiation-operator" "^7.12.13" - "@babel/plugin-transform-for-of" "^7.13.0" - "@babel/plugin-transform-function-name" "^7.12.13" - "@babel/plugin-transform-literals" "^7.12.13" - "@babel/plugin-transform-member-expression-literals" "^7.12.13" - "@babel/plugin-transform-modules-amd" "^7.14.2" - "@babel/plugin-transform-modules-commonjs" "^7.14.0" - "@babel/plugin-transform-modules-systemjs" "^7.13.8" - "@babel/plugin-transform-modules-umd" "^7.14.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13" - "@babel/plugin-transform-new-target" "^7.12.13" - "@babel/plugin-transform-object-super" "^7.12.13" - "@babel/plugin-transform-parameters" "^7.14.2" - "@babel/plugin-transform-property-literals" "^7.12.13" - "@babel/plugin-transform-regenerator" "^7.13.15" - "@babel/plugin-transform-reserved-words" "^7.12.13" - "@babel/plugin-transform-shorthand-properties" "^7.12.13" - "@babel/plugin-transform-spread" "^7.13.0" - "@babel/plugin-transform-sticky-regex" "^7.12.13" - "@babel/plugin-transform-template-literals" "^7.13.0" - "@babel/plugin-transform-typeof-symbol" "^7.12.13" - "@babel/plugin-transform-unicode-escapes" "^7.12.13" - "@babel/plugin-transform-unicode-regex" "^7.12.13" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.14.5" + "@babel/plugin-transform-async-to-generator" "^7.14.5" + "@babel/plugin-transform-block-scoped-functions" "^7.14.5" + "@babel/plugin-transform-block-scoping" "^7.14.5" + "@babel/plugin-transform-classes" "^7.14.9" + "@babel/plugin-transform-computed-properties" "^7.14.5" + "@babel/plugin-transform-destructuring" "^7.14.7" + "@babel/plugin-transform-dotall-regex" "^7.14.5" + "@babel/plugin-transform-duplicate-keys" "^7.14.5" + "@babel/plugin-transform-exponentiation-operator" "^7.14.5" + "@babel/plugin-transform-for-of" "^7.14.5" + "@babel/plugin-transform-function-name" "^7.14.5" + "@babel/plugin-transform-literals" "^7.14.5" + "@babel/plugin-transform-member-expression-literals" "^7.14.5" + "@babel/plugin-transform-modules-amd" "^7.14.5" + "@babel/plugin-transform-modules-commonjs" "^7.15.0" + "@babel/plugin-transform-modules-systemjs" "^7.14.5" + "@babel/plugin-transform-modules-umd" "^7.14.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.9" + "@babel/plugin-transform-new-target" "^7.14.5" + "@babel/plugin-transform-object-super" "^7.14.5" + "@babel/plugin-transform-parameters" "^7.14.5" + "@babel/plugin-transform-property-literals" "^7.14.5" + "@babel/plugin-transform-regenerator" "^7.14.5" + "@babel/plugin-transform-reserved-words" "^7.14.5" + "@babel/plugin-transform-shorthand-properties" "^7.14.5" + "@babel/plugin-transform-spread" "^7.14.6" + "@babel/plugin-transform-sticky-regex" "^7.14.5" + "@babel/plugin-transform-template-literals" "^7.14.5" + "@babel/plugin-transform-typeof-symbol" "^7.14.5" + "@babel/plugin-transform-unicode-escapes" "^7.14.5" + "@babel/plugin-transform-unicode-regex" "^7.14.5" "@babel/preset-modules" "^0.1.4" - "@babel/types" "^7.14.4" - babel-plugin-polyfill-corejs2 "^0.2.0" - babel-plugin-polyfill-corejs3 "^0.2.0" - babel-plugin-polyfill-regenerator "^0.2.0" - core-js-compat "^3.9.0" + "@babel/types" "^7.15.0" + babel-plugin-polyfill-corejs2 "^0.2.2" + babel-plugin-polyfill-corejs3 "^0.2.2" + babel-plugin-polyfill-regenerator "^0.2.2" + core-js-compat "^3.16.0" semver "^6.3.0" "@babel/preset-modules@^0.1.4": @@ -925,81 +868,89 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-typescript@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.13.0.tgz#ab107e5f050609d806fbb039bec553b33462c60a" - integrity sha512-LXJwxrHy0N3f6gIJlYbLta1D9BDtHpQeqwzM0LIfjDlr6UE/D5Mc7W4iDiQzaE+ks0sTjT26ArcHWnJVt0QiHw== +"@babel/preset-typescript@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz#e8fca638a1a0f64f14e1119f7fe4500277840945" + integrity sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow== dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-validator-option" "^7.12.17" - "@babel/plugin-transform-typescript" "^7.13.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + "@babel/plugin-transform-typescript" "^7.15.0" "@babel/runtime@^7.8.4": - version "7.13.17" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.17.tgz#8966d1fc9593bf848602f0662d6b4d0069e3a7ec" - integrity sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA== + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.8.tgz#7119a56f421018852694290b9f9148097391b446" + integrity sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" - integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== +"@babel/template@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" + integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/parser" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/code-frame" "^7.14.5" + "@babel/parser" "^7.14.5" + "@babel/types" "^7.14.5" -"@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13", "@babel/traverse@^7.13.15", "@babel/traverse@^7.13.17": - version "7.13.17" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.17.tgz#c85415e0c7d50ac053d758baec98b28b2ecfeea3" - integrity sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg== +"@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.14.8", "@babel/traverse@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98" + integrity sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw== dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.13.16" - "@babel/helper-function-name" "^7.12.13" - "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/parser" "^7.13.16" - "@babel/types" "^7.13.17" + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.15.0" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-hoist-variables" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/parser" "^7.15.0" + "@babel/types" "^7.15.0" debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.14.2": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.2.tgz#9201a8d912723a831c2679c7ebbf2fe1416d765b" - integrity sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA== +"@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.15.0", "@babel/types@^7.4.4": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd" + integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ== dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.14.2" - "@babel/helper-function-name" "^7.14.2" - "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/parser" "^7.14.2" - "@babel/types" "^7.14.2" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.14", "@babel/types@^7.13.16", "@babel/types@^7.13.17", "@babel/types@^7.14.2", "@babel/types@^7.14.4", "@babel/types@^7.4.4": - version "7.14.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.4.tgz#bfd6980108168593b38b3eb48a24aa026b919bc0" - integrity sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw== - dependencies: - "@babel/helper-validator-identifier" "^7.14.0" + "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" -"@discord-player/extractor@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@discord-player/extractor/-/extractor-3.0.0.tgz#2baa733da054b991f83417054cad1575cf57c4ab" - integrity sha512-6A2QmrbQXTpv1oequiAYQMnWzvv1fu9Yg0GJwAMoLUXZjvb5Yoak2lnohsDI1Hc14LW//Z5xyLGtmFivTWTXDQ== +"@devsnowflake/docgen@devsnowflake/docgen#ts-patch": + version "0.9.0" + resolved "https://codeload.github.com/devsnowflake/docgen/tar.gz/cc87c4dfa7136fa1046946eff708bb995ca5e1f7" + dependencies: + eslint "^6.3.0" + js-yaml "^3.13.1" + jsdoc-to-markdown "^5.0.1" + tsubaki "^1.3.2" + yargs "^14.0.0" + +"@discord-player/extractor@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@discord-player/extractor/-/extractor-3.0.2.tgz#932b37c881a371279b7b1d1eb35bcab256008a76" + integrity sha512-bVGzucZTYksvsL7TFBhe/8ZzWuDDSc7f1fZYXS5CSu3vYez8ieG8ySAaeHdEbFKhxHIYhvUhvgY1mWcX/3ZBQA== dependencies: genius-lyrics "^4.2.9" jsdom "^16.5.3" node-fetch "^2.6.1" reverbnation-scraper "^2.0.0" -"@discordjs/collection@^0.1.6": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.1.6.tgz#9e9a7637f4e4e0688fd8b2b5c63133c91607682c" - integrity sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ== +"@discordjs/builders@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-0.4.0.tgz#bb41573ce4824aa9194a53b52c29c5219b610010" + integrity sha512-EiwLltKph6TSaPJIzJYdzNc1PnA2ZNaaE0t0ODg3ghnpVHqfgd0YX9/srsleYHW2cw1sfIq+kbM+h0etf7GWLA== + dependencies: + "@sindresorhus/is" "^4.0.1" + discord-api-types "^0.22.0" + ow "^0.27.0" + ts-mixer "^6.0.0" + tslib "^2.3.0" + +"@discordjs/collection@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.2.1.tgz#ea4bc7b41b7b7b6daa82e439141222ec95c469b2" + integrity sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog== "@discordjs/form-data@^3.0.1": version "3.0.1" @@ -1010,38 +961,88 @@ combined-stream "^1.0.8" mime-types "^2.1.12" -"@discordjs/node-pre-gyp@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@discordjs/node-pre-gyp/-/node-pre-gyp-0.3.2.tgz#e882e803b2be444fb557c3b46d9bbe75a053bc9c" - integrity sha512-NqRvPz0X+/3h+6ClElrSfvsD5XEG9ljYzXhzyo81DslVkVKzmmxX9FLs3MUr9qI7p53DG1eYru633qosrOqMyA== +"@discordjs/node-pre-gyp@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@discordjs/node-pre-gyp/-/node-pre-gyp-0.4.0.tgz#32740b1ff362c86a280877df9637313c7bf250ee" + integrity sha512-CXLpoM2hgS94i9+EAVowR92y8o3KdKc9fmoe8/FTp5XTzvoXzJln3+Ctl0oBpE6c9+11zd9oJnZPdkkOBkDPSA== dependencies: detect-libc "^1.0.3" - http-proxy-agent "^4.0.1" + 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" + semver "^7.3.5" tar "^6.1.0" -"@discordjs/opus@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@discordjs/opus/-/opus-0.5.0.tgz#26ae9f30d52c03ce1671b1db8eec957206fdf92b" - integrity sha512-s3XUJ7dYV+UvYUiqkgs7sq8JKWMhQrHcwDECP2SKdxtL9h9qGa4mr0IR6XnZw+G/Sogx8c+HRS7+wEspkqk3zA== +"@discordjs/opus@github:discordjs/opus": + version "0.5.3" + resolved "https://codeload.github.com/discordjs/opus/tar.gz/d929bdb7574fbf3ad1cea9c96277ab3fc4b96132" dependencies: - "@discordjs/node-pre-gyp" "^0.3.2" - node-addon-api "^3.1.0" + "@discordjs/node-pre-gyp" "^0.4.0" + node-addon-api "^3.2.1" -"@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents": - version "2.1.8-no-fsevents" - resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.tgz#da7c3996b8e6e19ebd14d82eaced2313e7769f9b" - integrity sha512-+nb9vWloHNNMFHjGofEam3wopE3m1yuambrrd/fnPc+lFOMB9ROTqQlche9ByFWNkdNqfSgR/kkQtQ8DzEWt2w== +"@discordjs/voice@^0.5.5": + version "0.5.5" + resolved "https://registry.yarnpkg.com/@discordjs/voice/-/voice-0.5.5.tgz#25dfe4709e5da103875f212f40cf63068abd8850" + integrity sha512-i7QSRlPq34UAoTUfxLjlyWJONdrxJ4kZH7F6ZfoDK1rt3AHZv5vFzijBu8bsy040zaYpU3LZQ2MPw/kz1uCr5w== + dependencies: + "@types/ws" "^7.4.4" + discord-api-types "^0.19.0" + prism-media "^1.3.1" + tiny-typed-emitter "^2.0.3" + ws "^7.4.4" + +"@eslint/eslintrc@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" + integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@favware/rollup-type-bundler@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@favware/rollup-type-bundler/-/rollup-type-bundler-1.0.3.tgz#cf42805ed3d1a37d3eeaf79efff9ef2b1d36c142" + integrity sha512-fbwfdBx7xm3b6dsnuJ2MvB/S4y0SrknPnuQLPvnzmrZpf8pEi/gkUifn8P2WmCPLclN71IMhP8YKL1ZmPifGbw== + dependencies: + colorette "^1.2.2" + commander "^8.0.0" + js-yaml "^4.1.0" + rollup "^2.52.6" + rollup-plugin-dts "^3.0.2" + +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" + integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + +"@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.2": + version "2.1.8-no-fsevents.2" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.2.tgz#e324c0a247a5567192dd7180647709d7e2faf94b" + integrity sha512-Fb8WxUFOBQVl+CX4MWet5o7eCc6Pj04rXIwVKZ6h1NnqTo45eOQW6aWyhG25NIODvWFwTDMwBsYxrQ3imxpetg== dependencies: anymatch "^2.0.0" async-each "^1.0.1" braces "^2.3.2" - glob-parent "^3.1.0" + glob-parent "^5.1.2" inherits "^2.0.3" is-binary-path "^1.0.0" is-glob "^4.0.0" @@ -1050,23 +1051,148 @@ readdirp "^2.2.1" upath "^1.1.1" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@sapphire/async-queue@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.1.4.tgz#ae431310917a8880961cebe8e59df6ffa40f2957" + integrity sha512-fFrlF/uWpGOX5djw5Mu2Hnnrunao75WGey0sP0J3jnhmrJ5TAPzHYOmytD5iN/+pMxS+f+u/gezqHa9tPhRHEA== + +"@sindresorhus/is@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5" + integrity sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g== + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== -"@types/node@*", "@types/node@^15.6.1": - version "15.6.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.1.tgz#32d43390d5c62c5b6ec486a9bc9c59544de39a08" - integrity sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA== +"@tsconfig/node10@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" + integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== -"@types/ws@^7.4.1": - version "7.4.1" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.1.tgz#49eacb15a0534663d53a36fbf5b4d98f5ae9a73a" - integrity sha512-ISCK1iFnR+jYv7+jLNX0wDqesZ/5RAeY3wUx6QaphmocphU61h+b+PHjS18TF4WIPTu/MMzxIq2PHr32o2TS5Q== +"@tsconfig/node12@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" + integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== + +"@tsconfig/node14@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" + integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== + +"@tsconfig/node16@^1.0.1": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" + integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== + +"@types/json-schema@^7.0.7": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/node@*", "@types/node@^16.4.13": + version "16.4.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.13.tgz#7dfd9c14661edc65cccd43a29eb454174642370d" + integrity sha512-bLL69sKtd25w7p1nvg9pigE4gtKVpGTPojBFLMkGHXuUgap2sLqQt2qUnqmVCDfzGUL0DRNZP+1prIZJbMeAXg== + +"@types/ws@^7.4.4", "@types/ws@^7.4.7": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== dependencies: "@types/node" "*" +"@typescript-eslint/eslint-plugin@^4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.0.tgz#b866c9cd193bfaba5e89bade0015629ebeb27996" + integrity sha512-eiREtqWRZ8aVJcNru7cT/AMVnYd9a2UHsfZT8MR1dW3UUEg6jDv9EQ9Cq4CUPZesyQ58YUpoAADGv71jY8RwgA== + dependencies: + "@typescript-eslint/experimental-utils" "4.29.0" + "@typescript-eslint/scope-manager" "4.29.0" + debug "^4.3.1" + functional-red-black-tree "^1.0.1" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.0.tgz#19b1417602d0e1ef325b3312ee95f61220542df5" + integrity sha512-FpNVKykfeaIxlArLUP/yQfv/5/3rhl1ov6RWgud4OgbqWLkEq7lqgQU9iiavZRzpzCRQV4XddyFz3wFXdkiX9w== + dependencies: + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.29.0" + "@typescript-eslint/types" "4.29.0" + "@typescript-eslint/typescript-estree" "4.29.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@^4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.29.0.tgz#e5367ca3c63636bb5d8e0748fcbab7a4f4a04289" + integrity sha512-+92YRNHFdXgq+GhWQPT2bmjX09X7EH36JfgN2/4wmhtwV/HPxozpCNst8jrWcngLtEVd/4zAwA6BKojAlf+YqA== + dependencies: + "@typescript-eslint/scope-manager" "4.29.0" + "@typescript-eslint/types" "4.29.0" + "@typescript-eslint/typescript-estree" "4.29.0" + debug "^4.3.1" + +"@typescript-eslint/scope-manager@4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.0.tgz#cf5474f87321bedf416ef65839b693bddd838599" + integrity sha512-HPq7XAaDMM3DpmuijxLV9Io8/6pQnliiXMQUcAdjpJJSR+fdmbD/zHCd7hMkjJn04UQtCQBtshgxClzg6NIS2w== + dependencies: + "@typescript-eslint/types" "4.29.0" + "@typescript-eslint/visitor-keys" "4.29.0" + +"@typescript-eslint/types@4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.0.tgz#c8f1a1e4441ea4aca9b3109241adbc145f7f8a4e" + integrity sha512-2YJM6XfWfi8pgU2HRhTp7WgRw78TCRO3dOmSpAvIQ8MOv4B46JD2chnhpNT7Jq8j0APlIbzO1Bach734xxUl4A== + +"@typescript-eslint/typescript-estree@4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.0.tgz#af7ab547757b86c91bfdbc54ff86845410856256" + integrity sha512-8ZpNHDIOyqzzgZrQW9+xQ4k5hM62Xy2R4RPO3DQxMc5Rq5QkCdSpk/drka+DL9w6sXNzV5nrdlBmf8+x495QXQ== + dependencies: + "@typescript-eslint/types" "4.29.0" + "@typescript-eslint/visitor-keys" "4.29.0" + debug "^4.3.1" + globby "^11.0.3" + is-glob "^4.0.1" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.0.tgz#1ff60f240def4d85ea68d4fd2e4e9759b7850c04" + integrity sha512-LoaofO1C/jAJYs0uEpYMXfHboGXzOJeV118X4OsZu9f7rG7Pr9B3+4HTU8+err81rADa4xfQmAxnRnPAI2jp+Q== + dependencies: + "@typescript-eslint/types" "4.29.0" + eslint-visitor-keys "^2.0.0" + abab@^2.0.3, abab@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" @@ -1077,13 +1203,6 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - acorn-globals@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" @@ -1092,25 +1211,25 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-jsx@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== +acorn-jsx@^5.2.0, acorn-jsx@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^7.1.1: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^7.1.1: +acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.1.tgz#fb0026885b9ac9f48bac1e185e4af472971149ff" - integrity sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g== +acorn@^8.2.4: + version "8.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" + integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== agent-base@6: version "6.0.2" @@ -1119,7 +1238,7 @@ agent-base@6: dependencies: debug "4" -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1129,6 +1248,21 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.1: + version "8.6.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" + integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + ansi-escape-sequences@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz#2483c8773f50dd9174dd9557e92b1718f1816097" @@ -1170,7 +1304,7 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.1.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -1185,7 +1319,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@~3.1.1: +anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -1206,6 +1340,11 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1213,6 +1352,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -1242,32 +1386,33 @@ array-back@^2.0.0: dependencies: typical "^2.6.1" -array-back@^3.0.1: +array-back@^3.0.1, array-back@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== array-back@^4.0.0, array-back@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.1.tgz#9b80312935a52062e1a233a9c7abeb5481b30e90" - integrity sha512-Z/JnaVEXv+A9xabHzN43FiiiWEE7gPCRXMrVmRm00tWbjZRul1iHm7ECzlyNq1p4a4ATXz+G9FJ3GqGOkOV3fg== + version "4.0.2" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" + integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== +assert@^1.4.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + object-assign "^4.1.1" + util "0.10.3" assign-symbols@^1.0.0: version "1.0.0" @@ -1279,6 +1424,11 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + async-each@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" @@ -1294,16 +1444,6 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - axios@^0.21.1: version "0.21.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" @@ -1318,34 +1458,34 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-plugin-polyfill-corejs2@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz#686775bf9a5aa757e10520903675e3889caeedc4" - integrity sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg== +babel-plugin-polyfill-corejs2@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz#e9124785e6fd94f94b618a7954e5693053bf5327" + integrity sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ== dependencies: "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.2.0" + "@babel/helper-define-polyfill-provider" "^0.2.2" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz#f4b4bb7b19329827df36ff56f6e6d367026cb7a2" - integrity sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg== +babel-plugin-polyfill-corejs3@^0.2.2: + version "0.2.4" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.4.tgz#68cb81316b0e8d9d721a92e0009ec6ecd4cd2ca9" + integrity sha512-z3HnJE5TY/j4EFEa/qpQMSbcUJZ5JQi+3UFjXzn6pQCmIKc5Ug5j98SuYyH+m4xQnvKlMDIW4plLfgyVnd0IcQ== dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.0" - core-js-compat "^3.9.1" + "@babel/helper-define-polyfill-provider" "^0.2.2" + core-js-compat "^3.14.0" -babel-plugin-polyfill-regenerator@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz#853f5f5716f4691d98c84f8069c7636ea8da7ab8" - integrity sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg== +babel-plugin-polyfill-regenerator@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz#b310c8d642acada348c1fa3b3e6ce0e851bee077" + integrity sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.0" + "@babel/helper-define-polyfill-provider" "^0.2.2" balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base@^0.11.1: version "0.11.2" @@ -1360,13 +1500,6 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - binary-extensions@^1.0.0: version "1.13.1" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" @@ -1411,7 +1544,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@~3.0.2: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -1423,21 +1556,21 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.16.4, browserslist@^4.16.6: - version "4.16.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" - integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== +browserslist@^4.16.6: + version "4.16.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.7.tgz#108b0d1ef33c4af1b587c54f390e7041178e4335" + integrity sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA== dependencies: - caniuse-lite "^1.0.30001219" + caniuse-lite "^1.0.30001248" colorette "^1.2.2" - electron-to-chromium "^1.3.723" + electron-to-chromium "^1.3.793" escalade "^3.1.1" - node-releases "^1.1.71" + node-releases "^1.1.73" -builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== cache-base@^1.0.1: version "1.0.1" @@ -1471,7 +1604,7 @@ call-bind@^1.0.0: function-bind "^1.1.1" get-intrinsic "^1.0.2" -callsites@^3.0.0: +callsites@^3.0.0, callsites@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== @@ -1481,24 +1614,19 @@ camelcase@^5.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30001219: - version "1.0.30001230" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71" - integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ== +caniuse-lite@^1.0.30001248: + version "1.0.30001249" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz#90a330057f8ff75bfe97a94d047d5e14fabb2ee8" + integrity sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -catharsis@^0.8.11: - version "0.8.11" - resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.8.11.tgz#d0eb3d2b82b7da7a3ce2efb1a7b00becc6643468" - integrity sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g== +catharsis@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.9.0.tgz#40382a168be0e6da308c277d3a2b3eb40c7d2121" + integrity sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A== dependencies: - lodash "^4.17.14" + lodash "^4.17.15" -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0: +chalk@^2.0.0, chalk@^2.1.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1507,10 +1635,10 @@ chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" @@ -1520,24 +1648,24 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -cheerio-select@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-1.4.0.tgz#3a16f21e37a2ef0f211d6d1aa4eff054bb22cdc9" - integrity sha512-sobR3Yqz27L553Qa7cK6rtJlMDbiKPdNywtR95Sj/YgfpLfy0u6CGJuaBKe5YE/vTc23SCRKxWSdlon/w6I/Ew== +cheerio-select@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-1.5.0.tgz#faf3daeb31b17c5e1a9dabcee288aaf8aafa5823" + integrity sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg== dependencies: - css-select "^4.1.2" - css-what "^5.0.0" + css-select "^4.1.3" + css-what "^5.0.1" domelementtype "^2.2.0" domhandler "^4.2.0" - domutils "^2.6.0" + domutils "^2.7.0" -cheerio@^1.0.0-rc.9: - version "1.0.0-rc.9" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.9.tgz#a3ae6b7ce7af80675302ff836f628e7cb786a67f" - integrity sha512-QF6XVdrLONO6DXRF5iaolY+odmhj2CLj+xzNod7INPWMi/x9X4SOylH0S/vaPpX+AUU6t04s34SQNh7DbkuCng== +cheerio@^1.0.0-rc.10, cheerio@^1.0.0-rc.9: + version "1.0.0-rc.10" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.10.tgz#2ba3dcdfcc26e7956fc1f440e61d51c643379f3e" + integrity sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw== dependencies: - cheerio-select "^1.4.0" - dom-serializer "^1.3.1" + cheerio-select "^1.5.0" + dom-serializer "^1.3.2" domhandler "^4.2.0" htmlparser2 "^6.1.0" parse5 "^6.0.1" @@ -1545,19 +1673,19 @@ cheerio@^1.0.0-rc.9: tslib "^2.2.0" chokidar@^3.4.0: - version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== dependencies: - anymatch "~3.1.1" + anymatch "~3.1.2" braces "~3.0.2" - glob-parent "~5.1.0" + glob-parent "~5.1.2" is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.5.0" + readdirp "~3.6.0" optionalDependencies: - fsevents "~2.3.1" + fsevents "~2.3.2" chownr@^2.0.0: version "2.0.0" @@ -1645,7 +1773,7 @@ colorette@^1.2.2: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -1653,11 +1781,11 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: delayed-stream "~1.0.0" command-line-args@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.1.1.tgz#88e793e5bb3ceb30754a86863f0401ac92fd369a" - integrity sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg== + version "5.2.0" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.0.tgz#087b02748272169741f1fd7c785b295df079b9be" + integrity sha512-4zqtU1hYsSJzcJBOcNZIbW5Fbk9BkjCp1pZVhQKoRaWL5J7N4XphDLwo8aWwdQpTugxwu+jf9u2ZhkXiqp5Z6A== dependencies: - array-back "^3.0.1" + array-back "^3.1.0" find-replace "^3.0.0" lodash.camelcase "^4.3.0" typical "^4.0.0" @@ -1683,16 +1811,16 @@ command-line-usage@^4.1.0: table-layout "^0.4.2" typical "^2.6.1" -commander@^2.12.1: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - commander@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== +commander@^8.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.1.0.tgz#db36e3e66edf24ff591d639862c6ab2c52664362" + integrity sha512-mf45ldcuHSYShkplHHGKWb4TrmwQadxOn7v4WuhDJy0ZVoY5JFajaRDKD0PNe5qXzBX0rhovjTnP6Kz9LETcuA== + common-sequence@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/common-sequence/-/common-sequence-2.0.2.tgz#accc76bdc5876a1fcd92b73484d4285fff99d838" @@ -1721,9 +1849,9 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= convert-source-map@^1.1.0, convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== dependencies: safe-buffer "~5.1.1" @@ -1732,19 +1860,24 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-compat@^3.9.0, core-js-compat@^3.9.1: - version "3.10.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.10.2.tgz#0a675b4e1cde599616322a72c8886bcf696f3ec3" - integrity sha512-IGHnpuaM1N++gLSPI1F1wu3WXICPxSyj/Q++clcwsIOnUVp5uKUIPl/+6h0TQ112KU3fMiSxqJuM+OrCyKj5+A== +core-js-compat@^3.14.0, core-js-compat@^3.16.0: + version "3.16.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.16.0.tgz#fced4a0a534e7e02f7e084bff66c701f8281805f" + integrity sha512-5D9sPHCdewoUK7pSUPfTF7ZhLh8k9/CoJXWUEo+F1dZT5Z1DVgcuRqUKhjeKW+YLb8f21rTFgWwQJiNw1hoZ5Q== dependencies: - browserslist "^4.16.4" + browserslist "^4.16.6" semver "7.0.0" -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-fetch@~3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" @@ -1763,10 +1896,19 @@ cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -css-select@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.2.tgz#8b52b6714ed3a80d8221ec971c543f3b12653286" - integrity sha512-nu5ye2Hg/4ISq4XqdLY2bEatAcLIdt3OYGFc9Tm9n7VSlFBcfRv0gBNksHRgSdUDQGtN3XrZ94ztW+NfzkFSUw== +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-select@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067" + integrity sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA== dependencies: boolbase "^1.0.0" css-what "^5.0.0" @@ -1774,10 +1916,10 @@ css-select@^4.1.2: domutils "^2.6.0" nth-check "^2.0.0" -css-what@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.0.0.tgz#f0bf4f8bac07582722346ab243f6a35b512cfc47" - integrity sha512-qxyKHQvgKwzwDWC/rGbT821eJalfupxYW2qbSJSAtdSTimsr/MlaGONoNLllaUPZWf8QnbcKM/kPVYUQuEKAFA== +css-what@^5.0.0, css-what@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.0.1.tgz#3efa820131f4669a8ac2408f9c32e7c7de9f4cad" + integrity sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg== cssom@^0.4.4: version "0.4.4" @@ -1796,13 +1938,6 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -1812,10 +1947,10 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== dependencies: ms "2.1.2" @@ -1832,9 +1967,9 @@ decamelize@^1.2.0: integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= decimal.js@^10.2.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" - integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== decode-uri-component@^0.2.0: version "0.2.0" @@ -1846,7 +1981,7 @@ deep-extend@~0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-is@~0.1.3: +deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= @@ -1900,6 +2035,23 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +discord-api-types@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.19.0.tgz#86ba8021b29190cf860e90a2bc3e29b1d7aab3ba" + integrity sha512-t2HKLd43Lbe+rf+ffYfKVv9Kk5f6p7sFqvO6CMV55ZB0PgZv8WigCkt9FoJciYo5S3Q6CGYK+WnE/ZG+6vkBDQ== + +discord-api-types@^0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.22.0.tgz#34dc57fe8e016e5eaac5e393646cd42a7e1ccc2a" + integrity sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg== + discord-ytdl-core@^5.0.4: version "5.0.4" resolved "https://registry.yarnpkg.com/discord-ytdl-core/-/discord-ytdl-core-5.0.4.tgz#84a2af1a8e8c235b4fc109b23350d12782ab66cd" @@ -1907,29 +2059,19 @@ discord-ytdl-core@^5.0.4: dependencies: prism-media "^1.2.9" -discord.js-docgen@discordjs/docgen#ts-patch: - version "0.9.0" - resolved "https://codeload.github.com/discordjs/docgen/tar.gz/9c58620ea4fcdeda432a1370d4333e8537b37491" +discord.js@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.0.1.tgz#58f009706d1d7587fe9ff6c6c781e4540ae085f9" + integrity sha512-pEODCFfxypBnGEYpSgjkn1jt70raCS1um7Zp0AXEfW1DcR29wISzQ/WeWdnjP5KTXGi0LTtkRiUjOsMgSoukxA== dependencies: - eslint "^6.3.0" - js-yaml "^3.13.1" - jsdoc-to-markdown "^5.0.1" - tsubaki "^1.3.2" - yargs "^14.0.0" - -discord.js@^12.5.3: - version "12.5.3" - resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-12.5.3.tgz#56820d473c24320871df9ea0bbc6b462f21cf85c" - integrity sha512-D3nkOa/pCkNyn6jLZnAiJApw2N9XrIsXUAdThf01i7yrEuqUmDGc7/CexVWwEcgbQR97XQ+mcnqJpmJ/92B4Aw== - dependencies: - "@discordjs/collection" "^0.1.6" + "@discordjs/builders" "^0.4.0" + "@discordjs/collection" "^0.2.1" "@discordjs/form-data" "^3.0.1" - abort-controller "^3.0.0" + "@sapphire/async-queue" "^1.1.4" + "@types/ws" "^7.4.7" + discord-api-types "^0.22.0" node-fetch "^2.6.1" - prism-media "^1.2.9" - setimmediate "^1.0.5" - tweetnacl "^1.0.3" - ws "^7.4.4" + ws "^7.5.1" dmd@^4.0.5: version "4.0.6" @@ -1956,22 +2098,13 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-serializer@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1" - integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA== +dom-serializer@^1.0.1, dom-serializer@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== dependencies: domelementtype "^2.0.1" - domhandler "^4.0.0" - entities "^2.0.0" - -dom-serializer@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.1.tgz#d845a1565d7c041a95e5dab62184ab41e3a519be" - integrity sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.0.0" + domhandler "^4.2.0" entities "^2.0.0" domelementtype@^2.0.1, domelementtype@^2.2.0: @@ -1986,41 +2119,33 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" -domhandler@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.1.0.tgz#c1d8d494d5ec6db22de99e46a149c2a4d23ddd43" - integrity sha512-/6/kmsGlMY4Tup/nGVutdrK9yQi4YjWVcVeoQmixpzjOUK1U7pQkvAPHBJeUxOgxF0J8f8lwCJSlCfD0V4CMGQ== - dependencies: - domelementtype "^2.2.0" - -domhandler@^4.2.0: +domhandler@^4.0.0, domhandler@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059" integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA== dependencies: domelementtype "^2.2.0" -domutils@^2.5.2, domutils@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.6.0.tgz#2e15c04185d43fb16ae7057cb76433c6edb938b7" - integrity sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA== +domutils@^2.5.2, domutils@^2.6.0, domutils@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.7.0.tgz#8ebaf0c41ebafcf55b0b72ec31c56323712c5442" + integrity sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg== dependencies: dom-serializer "^1.0.1" domelementtype "^2.2.0" domhandler "^4.2.0" -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= +dot-prop@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" + integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" + is-obj "^2.0.0" -electron-to-chromium@^1.3.723: - version "1.3.742" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.742.tgz#7223215acbbd3a5284962ebcb6df85d88b95f200" - integrity sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q== +electron-to-chromium@^1.3.793: + version "1.3.798" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.798.tgz#12b0bb826ddf35486f2ca41c01be4bd6ad1b9b1e" + integrity sha512-fwsr6oXAORoV9a6Ak2vMCdXfmHIpAGgpOGesulS1cbGgJmrMl3H+GicUyRG3t+z9uHTMrIuMTleFDW+EUFYT3g== emoji-regex@^7.0.1: version "7.0.3" @@ -2032,6 +2157,13 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + entities@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" @@ -2057,6 +2189,11 @@ escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escodegen@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" @@ -2069,7 +2206,7 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-scope@^5.0.0: +eslint-scope@^5.0.0, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -2084,11 +2221,30 @@ eslint-utils@^1.4.3: dependencies: eslint-visitor-keys "^1.1.0" -eslint-visitor-keys@^1.1.0: +eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + eslint@^6.3.0: version "6.8.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" @@ -2132,6 +2288,52 @@ eslint@^6.3.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" +eslint@^7.32.0: + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.3" + "@humanwhocodes/config-array" "^0.5.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.1.2" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + espree@^6.1.2: version "6.2.1" resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" @@ -2141,12 +2343,21 @@ espree@^6.1.2: acorn-jsx "^5.2.0" eslint-visitor-keys "^1.1.0" +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.0.1: +esquery@^1.0.1, esquery@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== @@ -2175,11 +2386,6 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -2208,11 +2414,6 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -2236,31 +2437,39 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-glob@^3.1.1: + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fastq@^1.6.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.1.tgz#5d8175aae17db61947f8b162cfc7f63264d22807" + integrity sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw== + dependencies: + reusify "^1.0.4" + figures@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -2275,6 +2484,13 @@ file-entry-cache@^5.0.1: dependencies: flat-cache "^2.0.1" +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + file-set@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/file-set/-/file-set-2.0.1.tgz#db9bc4b70a7e5ba81c9d279c20a37f13369c7850" @@ -2331,33 +2547,41 @@ flat-cache@^2.0.1: rimraf "2.6.3" write "1.0.3" +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + flatted@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +flatted@^3.1.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561" + integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA== + follow-redirects@^1.10.0: - version "1.13.3" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267" - integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA== + version "1.14.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" + integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" fragment-cache@^0.2.1: @@ -2389,7 +2613,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@~2.3.1: +fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -2418,6 +2642,13 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +gen-esm-wrapper@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/gen-esm-wrapper/-/gen-esm-wrapper-1.1.2.tgz#ea91a4f0dae497060bd9462d8a9bc5bc2dacc3d0" + integrity sha512-ZzqvusFKGZEWunpoz5Yg4+tdODUa7Swv1pvd83VF9nVJNCIu5i1KJ6pFjTFFkvk8deeSWLdMgc8FNRaTe5MTTA== + dependencies: + is-valid-identifier "^2.0.2" + genius-lyrics@^4.2.9: version "4.2.9" resolved "https://registry.yarnpkg.com/genius-lyrics/-/genius-lyrics-4.2.9.tgz#87d12946589d3e96df4e100c51805aa5046de2c7" @@ -2450,32 +2681,17 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-parent@^5.0.0, glob-parent@~5.1.0: +glob-parent@^5.0.0, glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob@^7.0.0, glob@^7.1.1, glob@^7.1.3, glob@^7.1.5: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== +glob@^7.0.0, glob@^7.1.3, glob@^7.1.5: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -2496,10 +2712,29 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" +globals@^13.6.0, globals@^13.9.0: + version "13.10.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.10.0.tgz#60ba56c3ac2ca845cfbf4faeca727ad9dd204676" + integrity sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g== + dependencies: + type-fest "^0.20.2" + +globby@^11.0.3: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + graceful-fs@^4.1.11, graceful-fs@^4.1.9: - version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== handlebars@^4.5.3: version "4.7.7" @@ -2513,19 +2748,6 @@ handlebars@^4.5.3: optionalDependencies: uglify-js "^3.1.4" -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -2615,14 +2837,18 @@ http-proxy-agent@^4.0.1: agent-base "6" debug "4" -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" + agent-base "6" + debug "4" + +husky@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.1.tgz#579f4180b5da4520263e8713cc832942b48e1f1c" + integrity sha512-gceRaITVZ+cJH9sNHqx5tFwbzlLCVxtVZcusME8JYQ8Edy5mpGDOqD8QBCdMhpyo9a+JXddnujQ4rpY2Ff9SJA== iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" @@ -2636,7 +2862,12 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -import-fresh@^3.0.0: +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -2662,6 +2893,11 @@ inherits@2, inherits@^2.0.3, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + inquirer@^7.0.0: version "7.3.3" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" @@ -2715,9 +2951,9 @@ is-buffer@^1.1.5: integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-core-module@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + version "2.5.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.5.0.tgz#f754843617c70bfd29b7bd87327400cda5c18491" + integrity sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg== dependencies: has "^1.0.3" @@ -2765,7 +3001,7 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" -is-extglob@^2.1.0, is-extglob@^2.1.1: +is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= @@ -2787,13 +3023,6 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" @@ -2813,6 +3042,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -2820,15 +3054,17 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-potential-custom-element-name@^1.0.0: +is-potential-custom-element-name@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-valid-identifier@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-valid-identifier/-/is-valid-identifier-2.0.2.tgz#146d9dbf29821b8118580b039d2203aa4bd1da4b" + integrity sha512-mpS5EGqXOwzXtKAg6I44jIAqeBfntFLxpAth1rrKbxtKyI6LPktyDYpHBI+tHlduhhX/SF26mFXmxQu995QVqg== + dependencies: + assert "^1.4.1" is-windows@^1.0.2: version "1.0.2" @@ -2857,11 +3093,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -2875,6 +3106,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + js2xmlparser@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-4.0.1.tgz#670ef71bc5661f089cc90481b99a05a1227ae3bd" @@ -2882,11 +3120,6 @@ js2xmlparser@^4.0.1: dependencies: xmlcreate "^2.0.3" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - jsdoc-api@^5.0.4: version "5.0.4" resolved "https://registry.yarnpkg.com/jsdoc-api/-/jsdoc-api-5.0.4.tgz#6b60cddaa4e7ff9a2e139acfc19ecaa9c48f8575" @@ -2941,32 +3174,32 @@ jsdoc-to-markdown@^5.0.1: walk-back "^4.0.0" jsdoc@^3.6.3: - version "3.6.6" - resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.6.6.tgz#9fe162bbdb13ee7988bf74352b5147565bcfd8e1" - integrity sha512-znR99e1BHeyEkSvgDDpX0sTiTu+8aQyDl9DawrkOGZTTW8hv0deIFXx87114zJ7gRaDZKVQD/4tr1ifmJp9xhQ== + version "3.6.7" + resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.6.7.tgz#00431e376bed7f9de4716c6f15caa80e64492b89" + integrity sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw== dependencies: "@babel/parser" "^7.9.4" bluebird "^3.7.2" - catharsis "^0.8.11" + catharsis "^0.9.0" escape-string-regexp "^2.0.0" js2xmlparser "^4.0.1" klaw "^3.0.0" markdown-it "^10.0.0" markdown-it-anchor "^5.2.7" - marked "^0.8.2" + marked "^2.0.3" mkdirp "^1.0.4" requizzle "^0.2.3" strip-json-comments "^3.1.0" taffydb "2.6.2" - underscore "~1.10.2" + underscore "~1.13.1" jsdom@^16.5.3: - version "16.5.3" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.3.tgz#13a755b3950eb938b4482c407238ddf16f0d2136" - integrity sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA== + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== dependencies: abab "^2.0.5" - acorn "^8.1.0" + acorn "^8.2.4" acorn-globals "^6.0.0" cssom "^0.4.4" cssstyle "^2.3.0" @@ -2974,12 +3207,13 @@ jsdom@^16.5.3: decimal.js "^10.2.1" domexception "^2.0.1" escodegen "^2.0.0" + form-data "^3.0.0" html-encoding-sniffer "^2.0.1" - is-potential-custom-element-name "^1.0.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" 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" @@ -2989,7 +3223,7 @@ jsdom@^16.5.3: whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" whatwg-url "^8.5.0" - ws "^7.4.4" + ws "^7.4.6" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -3007,21 +3241,16 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - json5@^2.1.2: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" @@ -3029,16 +3258,6 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -3078,6 +3297,26 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +libsodium-wrappers@^0.7.9: + version "0.7.9" + resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz#4ffc2b69b8f7c7c7c5594a93a4803f80f6d0f346" + integrity sha512-9HaAeBGk1nKTRFRHkt7nzxqCvnkWTjn1pdjKgcUnZxj0FyOP4CnhgFhMdrFfgNsukijBGyBLpP2m2uKT1vuWhQ== + dependencies: + libsodium "^0.7.0" + +libsodium@^0.7.0: + version "0.7.9" + resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.9.tgz#4bb7bcbf662ddd920d8795c227ae25bbbfa3821b" + integrity sha512-gfeADtR4D/CM0oRUviKBViMGXZDgnFdMKMzHsvBdqLBHd9ySi6EtYnmuhHVDDYgYpAO8eU8hEY+F8vIUAPh08A== + linkify-it@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" @@ -3098,11 +3337,26 @@ lodash.camelcase@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + lodash.omit@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" @@ -3118,7 +3372,12 @@ lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= -lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.7.0: +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + +lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -3130,14 +3389,21 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -m3u8stream@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/m3u8stream/-/m3u8stream-0.8.3.tgz#c4624e92b4240eb356d040c4a5e155586cf58108" - integrity sha512-0nAcdrF8YJKUkb6PzWdvGftTPyCVWgoiot1AkNVbPKTeIGsWs6DrOjifrJ0Zi8WQfQmD2SuVCjkYIOip12igng== +m3u8stream@^0.8.3, m3u8stream@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/m3u8stream/-/m3u8stream-0.8.4.tgz#15b49d0c2b510755ea43c1e53f85d7aaa4dc65c2" + integrity sha512-sco80Db+30RvcaIOndenX6E6oQNgTiBKeJbFPc+yDXwPQIkryfboEbCvXPlBRq3mQTCVPQO93TDVlfRwqpD35w== dependencies: miniget "^4.0.0" sax "^1.2.4" +magic-string@^0.25.7: + version "0.25.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" + integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== + dependencies: + sourcemap-codec "^1.4.4" + make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -3153,6 +3419,11 @@ make-dir@^3.1.0: dependencies: semver "^6.0.0" +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -3186,16 +3457,21 @@ marked@^0.7.0: resolved "https://registry.yarnpkg.com/marked/-/marked-0.7.0.tgz#b64201f051d271b1edc10a04d1ae9b74bb8e5c0e" integrity sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg== -marked@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.2.tgz#4faad28d26ede351a7a1aaa5fec67915c869e355" - integrity sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw== +marked@^2.0.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.3.tgz#bd017cef6431724fd4b27e0657f5ceb14bff3753" + integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA== mdurl@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -3215,17 +3491,25 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -mime-db@1.47.0: - version "1.47.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" - integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.30" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" - integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== +micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== dependencies: - mime-db "1.47.0" + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.49.0: + version "1.49.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed" + integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA== + +mime-types@^2.1.12: + version "2.1.32" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.32.tgz#1d00e89e7de7fe02008db61001d9e02852670fd5" + integrity sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A== + dependencies: + mime-db "1.49.0" mimic-fn@^2.1.0: version "2.1.0" @@ -3233,9 +3517,9 @@ mimic-fn@^2.1.0: integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== miniget@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/miniget/-/miniget-4.2.0.tgz#0004e95536b192d95a7d09f4435d67b9285481d0" - integrity sha512-IzTOaNgBw/qEpzkPTE7X2cUVXQfSKbG8w52Emi93zb+Zya2ZFrbmavpixzebuDJD9Ku4ecbaFlC7Y1cEESzQtQ== + version "4.2.1" + resolved "https://registry.yarnpkg.com/miniget/-/miniget-4.2.1.tgz#11a1c24817a059e292378eb9cff4328d9240c665" + integrity sha512-O/DduzDR6f+oDtVype9S/Qu5hhnx73EDYGyZKwU/qN82lehFZdfhoa4DT51SpsO+8epYrB3gcRmws56ROfTIoQ== minimatch@^3.0.4: version "3.0.4" @@ -3273,11 +3557,11 @@ mixin-deep@^1.2.0: is-extendable "^1.0.1" mkdirp2@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp2/-/mkdirp2-1.0.4.tgz#56de1f8f5c93cf2199906362eba0f9f262ee4437" - integrity sha512-Q2PKB4ZR4UPtjLl76JfzlgSCUZhSV1AXQgAZa1qt5RiaALFjP/CDrGvFBrOz7Ck6McPcwMAxTsJvWOUjOU8XMw== + version "1.0.5" + resolved "https://registry.yarnpkg.com/mkdirp2/-/mkdirp2-1.0.5.tgz#68bbe61defefafce4b48948608ec0bac942512c2" + integrity sha512-xOE9xbICroUDmG1ye2h4bZ8WBie9EGmACaco8K8cx6RlkJJrxGIqjGqztAI+NMhexXBcdGbSEzI6N3EJPevxZw== -mkdirp@^0.5.1, mkdirp@^0.5.3: +mkdirp@^0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -3336,20 +3620,20 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -node-addon-api@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239" - integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== +node-addon-api@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" + integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== node-fetch@2.6.1, node-fetch@^2.6.0, node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== -node-releases@^1.1.71: - version "1.1.72" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" - integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== +node-releases@^1.1.73: + version "1.1.73" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" + integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== nopt@^5.0.0: version "5.0.0" @@ -3397,12 +3681,7 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.1.0: +object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -3481,11 +3760,35 @@ optionator@^0.8.1, optionator@^0.8.3: type-check "~0.3.2" word-wrap "~1.2.3" +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= +ow@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/ow/-/ow-0.27.0.tgz#d44da088e8184fa11de64b5813206f9f86ab68d0" + integrity sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ== + dependencies: + "@sindresorhus/is" "^4.0.1" + callsites "^3.1.0" + dot-prop "^6.0.1" + lodash.isequal "^4.5.0" + type-fest "^1.2.1" + vali-date "^1.0.0" + p-limit@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -3529,11 +3832,6 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -3549,20 +3847,25 @@ path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" - integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== pify@^4.0.1: version "4.0.1" @@ -3574,20 +3877,25 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prettier@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" - integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== +prettier@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" + integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== -prism-media@^1.2.9: - version "1.2.9" - resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.2.9.tgz#8d4f97b36efdfc82483eb8d3db64020767866f36" - integrity sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q== +prism-media@^1.2.9, prism-media@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.3.1.tgz#418acd2b122bedea2e834056d678f9a5ad2943ae" + integrity sha512-nyYAa3KB4qteJIqdguKmwxTJgy55xxUtkJ3uRnOvO5jO+frci+9zpRXw6QZVcfDeva3S654fU9+26P2OSTzjHw== process-nextick-args@~2.0.0: version "2.0.1" @@ -3599,7 +3907,7 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== @@ -3609,10 +3917,10 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== readable-stream@^2.0.2, readable-stream@^2.0.6: version "2.3.7" @@ -3636,10 +3944,10 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" @@ -3656,9 +3964,9 @@ reduce-flatten@^1.0.1: integrity sha1-JYx479FT3fk8tWEjf2EYTzaW4yc= reduce-flatten@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-3.0.0.tgz#da477d68453fd9510f9a5fbef86e0fa04b4fd315" - integrity sha512-eczl8wAYBxJ6Egl6I1ECIF+8z6sHu+KE7BzaEDZTpPXKXfy9SUDQlVYwkRcNTjJLC3Iakxbhss50KuT/R6SYfg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-3.0.1.tgz#3db6b48ced1f4dbe4f4f5e31e422aa9ff0cd21ba" + integrity sha512-bYo+97BmUUOzg09XwfkwALt4PQH1M5L0wzKerBt6WLm3Fhdd43mMS89HiT1B9pJIqko/6lWx3OnV4J9f2Kqp5Q== reduce-unique@^2.0.1: version "2.0.1" @@ -3685,9 +3993,9 @@ regenerate@^1.4.0: integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== regenerator-transform@^0.14.2: version "0.14.5" @@ -3709,6 +4017,11 @@ regexpp@^2.0.1: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== +regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + regexpu-core@^4.7.1: version "4.7.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" @@ -3748,53 +4061,16 @@ repeat-string@^1.6.1: resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - 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" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" @@ -3817,7 +4093,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.14.2, resolve@^1.3.2: +resolve@^1.14.2: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -3838,6 +4114,11 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + reverbnation-scraper@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/reverbnation-scraper/-/reverbnation-scraper-2.0.0.tgz#c17539aba218cc29033a63e732ba3e4953cb5bd5" @@ -3859,11 +4140,34 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +rollup-plugin-dts@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-dts/-/rollup-plugin-dts-3.0.2.tgz#2b628d88f864d271d6eaec2e4c2a60ae4e944c5c" + integrity sha512-hswlsdWu/x7k5pXzaLP6OvKRKcx8Bzprksz9i9mUe72zvt8LvqAb/AZpzs6FkLgmyRaN8B6rUQOVtzA3yEt9Yw== + dependencies: + magic-string "^0.25.7" + optionalDependencies: + "@babel/code-frame" "^7.12.13" + +rollup@^2.52.6: + version "2.56.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.56.0.tgz#daa832955d2b58f1ed52a3c4c85b7d1adaf076d0" + integrity sha512-weEafgbjbHCnrtJPNyCrhYnjP62AkF04P0BcV/1mofy1+gytWln4VVB1OK462cq2EAyWzRDpTMheSP/o+quoiA== + optionalDependencies: + fsevents "~2.3.2" + run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + rxjs@^6.6.0: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" @@ -3871,11 +4175,6 @@ rxjs@^6.6.0: dependencies: tslib "^1.9.0" -safe-buffer@^5.0.1, safe-buffer@^5.1.2: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -3888,7 +4187,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -3910,7 +4209,7 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^5.3.0, semver@^5.5.0, semver@^5.6.0: +semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -3920,7 +4219,7 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.4: +semver@^7.2.1, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -3942,11 +4241,6 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -3954,11 +4248,23 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -3969,6 +4275,11 @@ slash@^2.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + slice-ansi@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" @@ -3978,6 +4289,15 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -4017,13 +4337,13 @@ sort-array@^2.0.0: object-get "^2.1.0" typical "^2.6.0" -soundcloud-scraper@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/soundcloud-scraper/-/soundcloud-scraper-5.0.0.tgz#3f4e9d9fc9ee79cbaf6cdd64f462ad6803e25ac1" - integrity sha512-8Rt7WbW85AqiFoKkemF5BKsGAThLGnhOi13ztctAI0Y/wso/iuR97yiVXK1eYRc2YqaD8gkpKUAjEY7bOxLxnw== +soundcloud-scraper@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/soundcloud-scraper/-/soundcloud-scraper-5.0.1.tgz#4872d3c09d7cac40a81c99b3c509095ab17bcbcc" + integrity sha512-f3JxM/afLRumaT06YsLs8u/WtXDZYvMBis7kB3+rFcx0cyJeu825D3b8D3oTSflNWeFgbGt2+QRrvsXnUi/n1Q== dependencies: - cheerio "^1.0.0-rc.9" - m3u8stream "^0.8.3" + cheerio "^1.0.0-rc.10" + m3u8stream "^0.8.4" node-fetch "^2.6.1" source-map-resolve@^0.5.0: @@ -4037,6 +4357,14 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" +source-map-support@^0.5.17: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" @@ -4047,11 +4375,16 @@ source-map@^0.5.0, source-map@^0.5.6: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sourcemap-codec@^1.4.4: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -4078,21 +4411,6 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - 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" - static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -4101,11 +4419,6 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - stream-connect@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/stream-connect/-/stream-connect-1.0.2.tgz#18bc81f2edb35b8b5d9a8009200a985314428a97" @@ -4144,7 +4457,7 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string-width@^4.1.0: +string-width@^4.1.0, string-width@^4.2.0: version "4.2.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== @@ -4188,7 +4501,7 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" -strip-json-comments@^3.0.1, strip-json-comments@^3.1.0: +strip-json-comments@^3.0.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -4233,15 +4546,27 @@ table@^5.2.3: slice-ansi "^2.1.0" string-width "^3.0.0" +table@^6.0.9: + version "6.7.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" + integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== + dependencies: + ajv "^8.0.1" + lodash.clonedeep "^4.5.0" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.0" + strip-ansi "^6.0.0" + taffydb@2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268" integrity sha1-fLy2S1oUG2ou/CxdLGe04VCyomg= tar@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" - integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== + version "6.1.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.6.tgz#c23d797b0a1efe5d479b1490805c5443f3560c5d" + integrity sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" @@ -4289,6 +4614,11 @@ through@^2.3.6: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= +tiny-typed-emitter@^2.0.3, tiny-typed-emitter@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz#b3b027fdd389ff81a152c8e847ee2f5be9fad7b5" + integrity sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -4333,14 +4663,6 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -tough-cookie@^2.3.3, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tough-cookie@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" @@ -4350,75 +4672,62 @@ tough-cookie@^4.0.0: punycode "^2.1.1" universalify "^0.1.2" -tr46@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" - integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== dependencies: punycode "^2.1.1" -tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0: +ts-mixer@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.0.tgz#4e631d3a36e3fa9521b973b132e8353bc7267f9f" + integrity sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ== + +ts-node@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.1.0.tgz#e656d8ad3b61106938a867f69c39a8ba6efc966e" + integrity sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA== + dependencies: + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + +tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" - integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== - -tslint-config-prettier@^1.18.0: - version "1.18.0" - resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" - integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg== - -tslint@^6.1.3: - version "6.1.3" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904" - integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg== - dependencies: - "@babel/code-frame" "^7.0.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^4.0.1" - glob "^7.1.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - mkdirp "^0.5.3" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.13.0" - tsutils "^2.29.0" +tslib@^2.2.0, tslib@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== tsubaki@^1.3.2: version "1.3.9" resolved "https://registry.yarnpkg.com/tsubaki/-/tsubaki-1.3.9.tgz#3e7e3eeb1e85ab010329ebd84266b9b4ef5ccb6c" integrity sha512-neUK2wk0vu12jbuyTDYx9UcYZFXsyjkbQmZAWOKQ6d+dBnJG6E7VTS+3jUjEpwapLyp7bfojbl/pHVZj7oqbPw== -tsutils@^2.29.0: - version "2.29.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" - integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -tweetnacl@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + prelude-ls "^1.2.1" type-check@~0.3.2: version "0.3.2" @@ -4427,6 +4736,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" @@ -4437,10 +4751,15 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -typescript@^4.2.3: - version "4.3.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" - integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw== +type-fest@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== + +typescript@^4.3.5: + version "4.3.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" + integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== typical@^2.4.2, typical@^2.6.0, typical@^2.6.1: version "2.6.1" @@ -4458,14 +4777,14 @@ uc.micro@^1.0.1, uc.micro@^1.0.5: integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== uglify-js@^3.1.4: - version "3.13.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.4.tgz#592588bb9f47ae03b24916e2471218d914955574" - integrity sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw== + version "3.14.1" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.1.tgz#e2cb9fe34db9cb4cf7e35d1d26dfea28e09a7d06" + integrity sha512-JhS3hmcVaXlp/xSo3PKY5R0JqKs5M3IV+exdLHW99qKvKivPO4Z8qbej6mte17SOPqAOVMjt/XGgWacnFSzM3g== -underscore@~1.10.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.10.2.tgz#73d6aa3668f3188e4adb0f1943bd12cfd7efaaaf" - integrity sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg== +underscore@~1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.1.tgz#0c1c6bd2df54b6b69f2314066d65b6cde6fcf9d1" + integrity sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g== unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" @@ -4540,24 +4859,22 @@ util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" +vali-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" + integrity sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY= w3c-hr-time@^1.0.2: version "1.0.2" @@ -4611,12 +4928,12 @@ whatwg-mimetype@^2.3.0: integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" - integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== dependencies: lodash "^4.7.0" - tr46 "^2.0.2" + tr46 "^2.1.0" webidl-conversions "^6.1.0" which-module@^2.0.0: @@ -4631,6 +4948,13 @@ which@^1.2.9: dependencies: isexe "^2.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" @@ -4638,7 +4962,7 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -word-wrap@~1.2.3: +word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== @@ -4677,10 +5001,10 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" -ws@^7.4.4: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@^7.4.4, ws@^7.4.6, ws@^7.5.1: + version "7.5.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" + integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== xml-name-validator@^3.0.0: version "3.0.0" @@ -4708,9 +5032,9 @@ yallist@^4.0.0: integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yargs-parser@^15.0.1: - version "15.0.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.1.tgz#54786af40b820dcb2fb8025b11b4d659d76323b3" - integrity sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw== + version "15.0.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.3.tgz#316e263d5febe8b38eef61ac092b33dfcc9b1115" + integrity sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" @@ -4732,17 +5056,22 @@ yargs@^14.0.0: y18n "^4.0.0" yargs-parser "^15.0.1" -youtube-sr@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/youtube-sr/-/youtube-sr-4.1.5.tgz#f35627574a47b6d5b39dec792e8bb00f93e04809" - integrity sha512-yLTtjy8ougH6ReCEsCRN9mxgS+rcm44421pYxown3QR9bUivNjxkYwB1+OfW+Z9V9hBE/chp9y7SBpK63vrk7g== +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +youtube-sr@^4.1.7: + version "4.1.7" + resolved "https://registry.yarnpkg.com/youtube-sr/-/youtube-sr-4.1.7.tgz#a7cdff3e2ce3027170c96e0ca936bfba05955538" + integrity sha512-OKbm+561Fq5RlnUtJBmPhnyfS6Zon44zdPhY1v/Y9vpAHzqdfxomD43yc0ZQv6zNsVzSlAkGeWhoweNd6DUUjQ== dependencies: node-fetch "^2.6.1" -ytdl-core@^4.8.3: - version "4.8.3" - resolved "https://registry.yarnpkg.com/ytdl-core/-/ytdl-core-4.8.3.tgz#21570d1834db13dec7828cf87bbf4c83c0fe68d7" - integrity sha512-cWCBeX4FCgjcKmuVK384MT582RIAakpUSeMF/NPVmhO8cWiG+LeQLnBordvLolb0iXYzfUvalgmycYAE5Sy6Xw== +ytdl-core@^4.9.1: + version "4.9.1" + resolved "https://registry.yarnpkg.com/ytdl-core/-/ytdl-core-4.9.1.tgz#f587e2bd8329b5133c0bac4ce5ee1f3c7a1175a9" + integrity sha512-6Jbp5RDhUEozlaJQAR+l8oV8AHsx3WUXxSyPxzE6wOIAaLql7Hjiy0ZM58wZoyj1YEenlEPjEqcJIjKYKxvHtQ== dependencies: m3u8stream "^0.8.3" miniget "^4.0.0"