├── .eslintrc.json ├── .github └── workflows │ └── build.yml ├── .gitignore ├── .prettierrc.json ├── LICENSE.txt ├── Procfile ├── README.md ├── app.json ├── package.json ├── src ├── blocks │ ├── chat_prompt.ts │ ├── home_layout.ts │ └── index.ts ├── config.ts ├── data │ ├── icons.json │ └── nouns.json ├── features │ ├── chat_read.ts │ ├── chat_start.ts │ ├── command.ts │ ├── home.ts │ ├── index.ts │ ├── message.ts │ ├── onboard.ts │ └── react.ts ├── index.ts ├── manager.ts ├── middlewares │ └── index.ts ├── models │ ├── chat.ts │ ├── chat_metadata.ts │ ├── index.ts │ ├── installation.ts │ ├── user.ts │ └── user_pool.ts ├── redis.ts └── utils │ ├── index.ts │ └── slack.ts ├── tsconfig.json └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true 4 | }, 5 | "extends": [ 6 | "eslint:recommended", 7 | "plugin:@typescript-eslint/eslint-recommended", 8 | "plugin:@typescript-eslint/recommended", 9 | "prettier" 10 | ], 11 | "parser": "@typescript-eslint/parser", 12 | "parserOptions": { 13 | "project": "./tsconfig.json" 14 | }, 15 | "plugins": ["prettier"], 16 | "rules": { 17 | "prettier/prettier": ["error"], 18 | "@typescript-eslint/explicit-module-boundary-types": "off", 19 | "@typescript-eslint/no-non-null-assertion": "off" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | - push 5 | - pull_request 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v1 13 | - run: yarn install --frozen-lockfile 14 | - run: yarn build 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | node_modules/ 3 | .env 4 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "semi": false, 4 | "singleQuote": true, 5 | "trailingComma": "none" 6 | } 7 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Victor Truong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: yarn start 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Whirl 3 |

4 |

Whirl

5 |

6 | Fun, anonymous chats with random members of your Slack! 7 |
8 |
9 | 10 | Add to Slack 11 | 12 |

13 | 14 |

15 | Whirl home tab 16 | Example chat 17 |

18 | 19 | ## Deploy 20 | 21 | [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) 22 | 23 | ## Setup 24 | 25 | Whirl comprises of four components: 26 | 27 | 1. The web server for receiving and responding to event payloads from Slack 28 | 2. A **MongoDB database** to save chat metadata (e.g., start time, message count, participants, etc.) after a chat has ended 29 | 3. A **Redis cache** for storing references to the users who should receive messages from a chat while it is ongoing 30 | 4. The Slack app itself 31 | 32 | ### Environment variables 33 | 34 | Here are all the variables you need to set up on the server, with hints. 35 | 36 | ```bash 37 | # Port to run the server on 38 | PORT=3000 39 | 40 | DATABASE_URL=mongodb://… 41 | REDIS_URL=redis://… 42 | 43 | # App config. Obtained from the "Basic Information" page of your app. 44 | SLACK_CLIENT_ID=… 45 | SLACK_CLIENT_SECRET=… 46 | SLACK_SIGNING_SECRET=… 47 | # Can be anything you want it to be. 48 | SLACK_STATE_SECRET=… 49 | 50 | # A chat must have at least this many messages for its metadata to be saved. 51 | CHAT_METADATA_THRESHOLD=3 52 | ``` 53 | 54 | ### Starting the server 55 | 56 | _This section is only relevent to you if you’ve decided to run Whirl on a platform other than Heroku._ 57 | 58 | ```bash 59 | git clone https://github.com/ifvictr/whirl 60 | cd whirl 61 | 62 | # Install dependencies 63 | yarn 64 | 65 | # Start Whirl in production! This will build the source files and then run them. 66 | yarn start 67 | # Or, if you need to run it in development mode instead. 68 | yarn dev 69 | ``` 70 | 71 | ### Creating the Slack app 72 | 73 | For Whirl to work, you’ll need to [register a Slack app](https://api.slack.com/apps) with the appropriate OAuth permissions, event subscriptions, and commands. 74 | 75 | #### App Home 76 | 77 | For Whirl to work, you’ll need to enable both the **Home** and **Messages** tabs of the app. 78 | 79 | #### Interactivity & Shortcuts 80 | 81 | For the **Request URL** under the **Interactivity** section, enter `http:///slack/events`. This will be used for the app’s buttons. 82 | 83 | #### Slash Commands 84 | 85 | The following commands are needed. Enter the same request URL you used in the previous section. 86 | 87 | - `/end`: Ends the current chat 88 | - `/next`: Go to the next chat 89 | 90 | #### OAuth & Permissions 91 | 92 | Install the Slack app to your development Slack workspace first. 93 | 94 | The following bot token scopes are required: 95 | 96 | - `chat:write`: Used for sending messages. 97 | - `chat:write.customize`: Used for sending messages to the receiving side of a chat with the sender’s pseudonym. 98 | - `commands`: Used for `/end` and `/next`. 99 | - `im:history`: Used for reading the messages a user sends in a DM with Whirl. If they’re in a chat, Whirl will send it to the other users with a pseudonym. 100 | - `reactions:read`: Used for notifying users that reactions aren’t currently supported 😞 101 | - `reactions:write`: Used for chat read receipts. 102 | 103 | #### Event Subscriptions 104 | 105 | Subscribe to the following bot events: 106 | 107 | - `app_home_opened` 108 | - `message.im` 109 | - `reaction_added` 110 | 111 | The request URL is also the same here. 112 | 113 | After you’ve followed all the above steps, you should see something like this in the console: 114 | 115 | ```bash 116 | Starting Whirl… 117 | Listening on port 3000 118 | ``` 119 | 120 | ## License 121 | 122 | [MIT License](LICENSE.txt) 123 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Whirl", 3 | "description": "Fun, anonymous chats with random members of your Slack!", 4 | "logo": "https://files.ifvictr.com/2020/06/whirl.png", 5 | "repository": "https://github.com/ifvictr/whirl", 6 | "addons": ["heroku-redis"], 7 | "buildpacks": [ 8 | { 9 | "url": "heroku/nodejs" 10 | } 11 | ], 12 | "env": { 13 | "DATABASE_URL": { 14 | "description": "Your MongoDB database’s URL. Used to store chat metadata." 15 | }, 16 | "SLACK_CLIENT_ID": { 17 | "description": "ID of the app to use in OAuth requests." 18 | }, 19 | "SLACK_CLIENT_SECRET": { 20 | "description": "Secret value to use when making OAuth requests." 21 | }, 22 | "SLACK_SIGNING_SECRET": { 23 | "description": "Signing secret from Slack used to confirm source of incoming messages." 24 | }, 25 | "SLACK_STATE_SECRET": { 26 | "description": "Additional secret value to secure your app." 27 | }, 28 | "CHAT_METADATA_THRESHOLD": { 29 | "description": "The minimum amount of messages needed for a chat’s metadata to be saved.", 30 | "value": "3", 31 | "required": false 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "whirl", 3 | "version": "1.0.1", 4 | "private": true, 5 | "homepage": "https://github.com/ifvictr/whirl#readme", 6 | "bugs": { 7 | "url": "https://github.com/ifvictr/whirl/issues" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/ifvictr/whirl.git" 12 | }, 13 | "license": "MIT", 14 | "author": { 15 | "name": "Victor Truong", 16 | "email": "victor@victortruong.com", 17 | "url": "https://victortruong.com" 18 | }, 19 | "main": "./build/index.js", 20 | "scripts": { 21 | "build": "yarn clean && tsc", 22 | "clean": "rm -rf ./build && mkdir ./build", 23 | "dev": "nodemon -r ./node_modules/dotenv/config --watch './src/**/*.ts' --exec ts-node ./src/index.ts", 24 | "format": "prettier './src/**/*.ts' --write", 25 | "lint": "eslint './src/**/*.ts'", 26 | "start": "yarn build && node ./build/index.js" 27 | }, 28 | "dependencies": { 29 | "@slack/bolt": "^2.2.3", 30 | "@slack/oauth": "^1.1.0", 31 | "@slack/types": "^1.7.0", 32 | "@slack/web-api": "^5.11.0", 33 | "ioredis": "^4.17.3", 34 | "lodash.samplesize": "^4.2.0", 35 | "mongoose": "^5.9.24", 36 | "randomatic": "^3.1.1" 37 | }, 38 | "devDependencies": { 39 | "@types/ioredis": "^4.17.2", 40 | "@types/lodash.samplesize": "^4.2.6", 41 | "@types/mongoose": "^5.7.32", 42 | "@types/randomatic": "^3.1.0", 43 | "@typescript-eslint/eslint-plugin": "^3.7.1", 44 | "@typescript-eslint/parser": "^3.7.1", 45 | "dotenv": "^8.2.0", 46 | "eslint": "^7.5.0", 47 | "eslint-config-prettier": "^6.11.0", 48 | "eslint-plugin-prettier": "^3.1.4", 49 | "nodemon": "^2.0.4", 50 | "prettier": "^2.0.5", 51 | "ts-node": "^8.10.2", 52 | "typescript": "^3.9.7" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/blocks/chat_prompt.ts: -------------------------------------------------------------------------------- 1 | export interface ChatPromptProps { 2 | isExistingUser?: boolean 3 | } 4 | 5 | export const ChatPrompt = ({ isExistingUser = true }: ChatPromptProps = {}) => [ 6 | { 7 | type: 'section', 8 | text: { 9 | type: 'mrkdwn', 10 | text: isExistingUser 11 | ? 'You left the chat. Want to join another one?' 12 | : ':wave: Hey, welcome to Whirl! Here, you can have fun, completely anonymous chats with random members of your Slack. Just click below to get started.' 13 | } 14 | }, 15 | { 16 | type: 'actions', 17 | elements: [ 18 | { 19 | type: 'button', 20 | action_id: 'chat_start', 21 | style: 'primary', 22 | text: { 23 | type: 'plain_text', 24 | text: `Join ${isExistingUser ? 'another' : 'a'} chat` 25 | } 26 | } 27 | ] 28 | } 29 | ] 30 | -------------------------------------------------------------------------------- /src/blocks/home_layout.ts: -------------------------------------------------------------------------------- 1 | import { ActionsBlock, Block, PlainTextElement, View } from '@slack/types' 2 | 3 | // TODO: Remove this after there's a new release of `@slack/types` containing the 4 | // changes made here: https://github.com/slackapi/node-slack-sdk/pull/1068 5 | interface HeaderBlock extends Block { 6 | type: 'header' 7 | text: PlainTextElement 8 | } 9 | 10 | export interface HomeLayoutProps { 11 | isInChat?: boolean 12 | activeChatCount?: number 13 | activeUserCount?: number 14 | totalChatCount?: number 15 | totalMessagesSent?: number 16 | totalUserCount?: number 17 | } 18 | 19 | export const HomeLayout = ({ 20 | isInChat = false, 21 | activeChatCount = 0, 22 | activeUserCount = 0, 23 | totalChatCount = 0, 24 | totalMessagesSent = 0, 25 | totalUserCount = 0 26 | }: HomeLayoutProps = {}): View => ({ 27 | type: 'home', 28 | blocks: [ 29 | { 30 | type: 'section', 31 | text: { 32 | type: 'mrkdwn', 33 | text: 34 | ':cyclone: *Whirl* lets you have fun, anonymous chats with random members of your Slack. Just click on the *Messages* tab to start whirlin’!' 35 | } 36 | }, 37 | ...(!isInChat 38 | ? [ 39 | { 40 | type: 'actions', 41 | elements: [ 42 | { 43 | type: 'button', 44 | action_id: 'chat_start', 45 | style: 'primary', 46 | text: { 47 | type: 'plain_text', 48 | text: 'Join a chat' 49 | } 50 | } 51 | ] 52 | } as ActionsBlock 53 | ] 54 | : []), 55 | { 56 | type: 'divider' 57 | }, 58 | { 59 | type: 'header', 60 | text: { 61 | type: 'plain_text', 62 | text: 'Live Stats' 63 | } 64 | } as HeaderBlock, 65 | { 66 | type: 'section', 67 | text: { 68 | type: 'mrkdwn', 69 | text: ` 70 | :man-surfing: *${activeUserCount}* ${ 71 | activeUserCount === 1 ? 'person is' : 'people are' 72 | } chatting right now${ 73 | activeChatCount > 1 ? ` in *${activeChatCount}* different chats` : '' 74 | }\n 75 | :busts_in_silhouette: *${totalChatCount}* chat${ 76 | totalChatCount === 1 ? ' has' : 's have' 77 | } been started with Whirl\n 78 | :speech_balloon: *${totalMessagesSent}* message${ 79 | totalMessagesSent === 1 ? ' has' : 's have' 80 | } been sent in total by *${totalUserCount}* ${ 81 | totalUserCount === 1 ? 'person' : 'people' 82 | }` 83 | } 84 | }, 85 | { 86 | type: 'header', 87 | text: { 88 | type: 'plain_text', 89 | text: 'Quick Info' 90 | } 91 | } as HeaderBlock, 92 | { 93 | type: 'section', 94 | text: { 95 | type: 'mrkdwn', 96 | text: ` 97 | • A read receipt in the form of an :eyes: reaction (or animal emoji like :monkey_face:, depending on the group size) will appear under a message when another user reads it. 98 | • *\`/next\`:* Go to the next chat. Will add you to the waiting pool if there are no chats that can be immediately joined. 99 | • *\`/end\`:* Ends the current chat.` 100 | } 101 | } 102 | ] 103 | }) 104 | -------------------------------------------------------------------------------- /src/blocks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './chat_prompt' 2 | export * from './home_layout' 3 | -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | interface Config { 2 | databaseUrl: string 3 | port: number 4 | redisUrl: string 5 | signingSecret?: string 6 | stateSecret?: string 7 | clientId?: string 8 | clientSecret?: string 9 | chatMetadataThreshold: number 10 | } 11 | 12 | const config: Config = { 13 | databaseUrl: process.env.DATABASE_URL || process.env.MONGODB_URI || '', 14 | port: parseInt(process.env.PORT || '') || 3000, 15 | redisUrl: process.env.REDIS_URL || '', 16 | // Slack-specific config 17 | signingSecret: process.env.SLACK_SIGNING_SECRET, 18 | stateSecret: process.env.SLACK_STATE_SECRET, 19 | clientId: process.env.SLACK_CLIENT_ID, 20 | clientSecret: process.env.SLACK_CLIENT_SECRET, 21 | chatMetadataThreshold: 22 | parseInt(process.env.CHAT_METADATA_THRESHOLD || '') ?? 3 23 | } 24 | 25 | export default config 26 | -------------------------------------------------------------------------------- /src/data/icons.json: -------------------------------------------------------------------------------- 1 | { 2 | "buffalo": "water_buffalo", 3 | "dragon": "dragon_face", 4 | "fox": "fox_face", 5 | "giraffe": "giraffe_face", 6 | "lion": "lion_face", 7 | "monkey": "monkey_face", 8 | "panda": "panda_face", 9 | "rhino": "rhinoceros", 10 | "unicorn": "unicorn_face", 11 | "zebra": "zebra_face" 12 | } 13 | -------------------------------------------------------------------------------- /src/data/nouns.json: -------------------------------------------------------------------------------- 1 | [ 2 | "ant", 3 | "bat", 4 | "bear", 5 | "bee", 6 | "beetle", 7 | "bird", 8 | "buffalo", 9 | "bug", 10 | "butterfly", 11 | "camel", 12 | "cat", 13 | "chicken", 14 | "chipmunk", 15 | "cow", 16 | "crab", 17 | "cricket", 18 | "crocodile", 19 | "deer", 20 | "dog", 21 | "dolphin", 22 | "dragon", 23 | "duck", 24 | "eagle", 25 | "elephant", 26 | "fish", 27 | "fox", 28 | "frog", 29 | "giraffe", 30 | "goat", 31 | "gorilla", 32 | "hamster", 33 | "hedgehog", 34 | "horse", 35 | "koala", 36 | "leopard", 37 | "lion", 38 | "lizard", 39 | "monkey", 40 | "mouse", 41 | "octopus", 42 | "owl", 43 | "ox", 44 | "panda", 45 | "penguin", 46 | "pig", 47 | "poodle", 48 | "rabbit", 49 | "ram", 50 | "rat", 51 | "rhino", 52 | "scorpion", 53 | "shark", 54 | "sheep", 55 | "shrimp", 56 | "snail", 57 | "snake", 58 | "spider", 59 | "squid", 60 | "tiger", 61 | "turkey", 62 | "turtle", 63 | "unicorn", 64 | "whale", 65 | "wolf", 66 | "zebra" 67 | ] 68 | -------------------------------------------------------------------------------- /src/features/chat_read.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@slack/bolt' 2 | import { MessageAttachment, WebAPICallResult } from '@slack/web-api' 3 | import { Chat, User } from '../models' 4 | import { getEmoji } from '../utils' 5 | import { updateReadReceipt } from '../utils/slack' 6 | 7 | interface ConversationsHistoryResult extends WebAPICallResult { 8 | messages: MessageAttachment[] 9 | } 10 | 11 | export default (app: App) => { 12 | app.event('app_home_opened', async ({ client, context, event }) => { 13 | if (event.tab !== 'messages') { 14 | return 15 | } 16 | 17 | const user = await context.manager.getUser(event.user) 18 | if (!user) { 19 | return 20 | } 21 | 22 | // Only chatting users receive read receipts 23 | if (!(await user.isInChat())) { 24 | return 25 | } 26 | 27 | const chat = (await user.getCurrentChat()) as Chat 28 | 29 | // Send a read receipt reaction to everyone else in the chat 30 | const members = await chat.getMembers() 31 | const noun = (await user.getNoun()) as string 32 | const receiptEmoji = 33 | members.length > Chat.MIN_SIZE ? getEmoji(noun) : 'eyes' 34 | for (const memberId of members) { 35 | // Don't send a receipt to the reading user 36 | if (memberId === event.user) { 37 | continue 38 | } 39 | 40 | const member = (await context.manager.getUser(memberId)) as User 41 | const dmChannelId = (await member.getDmChannelId()) as string 42 | 43 | // Update the read receipt so it's on the latest message in the channel 44 | const { messages } = (await client.conversations.history({ 45 | channel: dmChannelId, 46 | limit: 1 47 | })) as ConversationsHistoryResult 48 | const latestMessageId = messages[0].ts as string 49 | await updateReadReceipt({ 50 | client, 51 | sender: user, 52 | receiver: member, 53 | messageId: latestMessageId, 54 | emoji: receiptEmoji 55 | }) 56 | } 57 | }) 58 | } 59 | -------------------------------------------------------------------------------- /src/features/chat_start.ts: -------------------------------------------------------------------------------- 1 | import { App, BlockButtonAction } from '@slack/bolt' 2 | 3 | export default (app: App) => { 4 | app.action('chat_start', async ({ ack, action, body, client, context }) => { 5 | await ack() 6 | 7 | // Ensure the action is a BlockButtonAction. 8 | if (action.type !== 'button') { 9 | return 10 | } 11 | body = body as BlockButtonAction 12 | 13 | const user = await context.manager.getUser(body.user.id) 14 | if (!user) { 15 | return 16 | } 17 | 18 | // User can't join the pool again if they're in it 19 | if (await user.isInPool()) { 20 | await client.chat.postEphemeral({ 21 | channel: body.user.id, 22 | user: body.user.id, 23 | text: 'You’re already in :beach_with_umbrella: *The Waiting Pool*.' 24 | }) 25 | return 26 | } 27 | 28 | // User can't join another chat while they're in one 29 | if (await user.isInChat()) { 30 | await client.chat.postEphemeral({ 31 | channel: body.user.id, 32 | user: body.user.id, 33 | text: 'You can’t join another chat while you’re in one.' 34 | }) 35 | return 36 | } 37 | 38 | // Delete the prompt if the action originated from a message. 39 | if ('message' in body) { 40 | await client.chat.delete({ 41 | channel: body.user.id, 42 | ts: body.message!.ts 43 | }) 44 | } 45 | 46 | // Attempt to create a chat. If that fails, add the user to the pool. 47 | const newChat = await context.manager 48 | .getPool() 49 | .attemptToCreateChat(body.user.id) 50 | if (!newChat) { 51 | await context.manager.getPool().add(body.user.id) 52 | await client.chat.postMessage({ 53 | channel: body.user.id, 54 | text: 55 | 'You’ve been added to :beach_with_umbrella: *The Waiting Pool*! A chat will start as soon as more people join.' 56 | }) 57 | return 58 | } 59 | 60 | await newChat.sendIntroMessages(client) 61 | }) 62 | } 63 | -------------------------------------------------------------------------------- /src/features/command.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@slack/bolt' 2 | import { ChatPrompt } from '../blocks' 3 | import { Chat } from '../models' 4 | 5 | export default (app: App) => { 6 | app.command('/end', async ({ ack, client, command, context, respond }) => { 7 | await ack() 8 | 9 | const user = await context.manager.getUser(command.user_id) 10 | if (!user) { 11 | await respond( 12 | `You need to visit your DM with <@${context.botUserId}> first to use this command.` 13 | ) 14 | return 15 | } 16 | 17 | // User can't end a chat if they're not in one 18 | if (!(await user.isInChat())) { 19 | await client.chat.postEphemeral({ 20 | channel: command.channel_id, 21 | user: command.user_id, 22 | text: 'You’re not in a chat right now.' 23 | }) 24 | return 25 | } 26 | 27 | const chat = (await user.getCurrentChat()) as Chat 28 | const noun = (await user.getNoun()) as string 29 | 30 | // Prompt the user to join another chat after they leave 31 | await user.leave() 32 | await client.chat.postMessage({ 33 | channel: command.user_id, 34 | text: 'You left the chat. Want to join another one?', 35 | blocks: ChatPrompt() 36 | }) 37 | 38 | await chat.sendLeaveMessages(client, noun) 39 | 40 | if (!(await chat.hasEnoughMembers())) { 41 | await chat.end() 42 | } 43 | }) 44 | 45 | app.command('/next', async ({ ack, client, command, context, respond }) => { 46 | await ack() 47 | 48 | const user = await context.manager.getUser(command.user_id) 49 | if (!user) { 50 | await respond( 51 | `You need to visit your DM with <@${context.botUserId}> first to use this command.` 52 | ) 53 | return 54 | } 55 | 56 | // User can't join the pool again if they're in it 57 | if (await user.isInPool()) { 58 | await client.chat.postEphemeral({ 59 | channel: command.channel_id, 60 | user: command.user_id, 61 | text: 'You’re already in :beach_with_umbrella: *The Waiting Pool*.' 62 | }) 63 | return 64 | } 65 | 66 | if (await user.isInChat()) { 67 | const chat = (await user.getCurrentChat()) as Chat 68 | const noun = (await user.getNoun()) as string 69 | 70 | await user.leave() 71 | 72 | await chat.sendLeaveMessages(client, noun) 73 | 74 | if (!(await chat.hasEnoughMembers())) { 75 | await chat.end() 76 | } 77 | } 78 | 79 | // Attempt to create a chat. If that fails, add the user to the pool. 80 | const newChat = await context.manager 81 | .getPool() 82 | .attemptToCreateChat(command.user_id) 83 | if (!newChat) { 84 | await context.manager.getPool().add(command.user_id) 85 | await client.chat.postMessage({ 86 | channel: command.user_id, 87 | text: 88 | 'You’ve been added to :beach_with_umbrella: *The Waiting Pool*! A chat will start as soon as more people join.' 89 | }) 90 | return 91 | } 92 | 93 | await newChat.sendIntroMessages(client) 94 | }) 95 | } 96 | -------------------------------------------------------------------------------- /src/features/home.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@slack/bolt' 2 | import { HomeLayout } from '../blocks' 3 | import redis from '../redis' 4 | 5 | const COUNTER_KEYS = [ 6 | 'active_chats', 7 | 'active_users', 8 | 'total_chats', 9 | 'total_messages_sent', 10 | 'total_users' 11 | ] 12 | 13 | export default (app: App) => { 14 | app.event('app_home_opened', async ({ body, client, context, event }) => { 15 | if (event.tab !== 'home') { 16 | return 17 | } 18 | 19 | // Get the user's chat status to display the appropriate button 20 | const user = await context.manager.getUser(event.user) 21 | const isInChat = user !== null && (await user.isInChat()) 22 | 23 | // Fetch the latest stats to display to the user 24 | const rawCounts = (await Promise.all( 25 | COUNTER_KEYS.map(key => redis.get(`counter:${body.team_id}:${key}`)) 26 | )) as string[] 27 | const [ 28 | activeChatCount, 29 | activeUserCount, 30 | totalChatCount, 31 | totalMessagesSent, 32 | totalUserCount 33 | ] = rawCounts.map(count => parseInt(count) || 0) 34 | 35 | await client.views.publish({ 36 | user_id: event.user, 37 | view: HomeLayout({ 38 | isInChat, 39 | activeChatCount, 40 | activeUserCount, 41 | totalChatCount, 42 | totalMessagesSent, 43 | totalUserCount 44 | }) 45 | }) 46 | }) 47 | } 48 | -------------------------------------------------------------------------------- /src/features/index.ts: -------------------------------------------------------------------------------- 1 | export { default as chatRead } from './chat_read' 2 | export { default as chatStart } from './chat_start' 3 | export { default as command } from './command' 4 | export { default as home } from './home' 5 | export { default as message } from './message' 6 | export { default as onboard } from './onboard' 7 | export { default as react } from './react' 8 | -------------------------------------------------------------------------------- /src/features/message.ts: -------------------------------------------------------------------------------- 1 | import { App, subtype } from '@slack/bolt' 2 | import { WebAPICallResult } from '@slack/web-api' 3 | import { channelType } from '../middlewares' 4 | import { Chat, User } from '../models' 5 | import redis from '../redis' 6 | import { capitalize, getEmoji, removeSpecialTags } from '../utils' 7 | import { updateReadReceipt } from '../utils/slack' 8 | 9 | interface ChatPostMessageResult extends WebAPICallResult { 10 | channel: string 11 | ts: string 12 | } 13 | 14 | export default (app: App) => { 15 | app.message(channelType('im'), async ({ client, context, event }) => { 16 | const user = await context.manager.getUser(event.user) 17 | if (!user) { 18 | return 19 | } 20 | 21 | // If the user isn't in a chat, prompt them to start one 22 | if (!(await user.isInChat())) { 23 | await client.chat.postEphemeral({ 24 | channel: event.channel, 25 | user: event.user, 26 | text: 'You’re not in a chat right now. Run *`/next`* to join one!' 27 | }) 28 | return 29 | } 30 | 31 | // Let the user know that thread replies aren't supported 32 | if ('thread_ts' in event) { 33 | await client.chat.postEphemeral({ 34 | channel: event.channel, 35 | user: event.user, 36 | text: 'Thread replies aren’t supported. Your message will not be seen.', 37 | thread_ts: event.thread_ts 38 | }) 39 | return 40 | } 41 | 42 | // Let the user know that file attachments aren't supported 43 | if ('files' in event) { 44 | await client.chat.postEphemeral({ 45 | channel: event.channel, 46 | user: event.user, 47 | text: 48 | 'Sorry, file attachments aren’t currently supported. The text portion will still be sent though.' 49 | }) 50 | } 51 | 52 | const currentChat = (await user.getCurrentChat()) as Chat 53 | 54 | // Broadcast the message to other chat members 55 | const members = await currentChat.getMembers() 56 | const noun = (await user.getNoun()) as string 57 | const displayName = `Anonymous ${capitalize(noun)}` 58 | const emoji = getEmoji(noun) 59 | const receiptEmoji = members.length > Chat.MIN_SIZE ? noun : 'eyes' 60 | for (const memberId of members) { 61 | // Don't send the message back to the sender 62 | if (memberId === event.user) { 63 | continue 64 | } 65 | 66 | const member = (await context.manager.getUser(memberId)) as User 67 | const dmChannelId = (await member.getDmChannelId()) as string 68 | 69 | // Send message with pseudonym, then update the read receipt so it's on 70 | // that message. 71 | const { ts: newMessageId } = (await client.chat.postMessage({ 72 | channel: dmChannelId, 73 | text: removeSpecialTags(event.text!), 74 | attachments: event.attachments, 75 | icon_emoji: `:${emoji}:`, 76 | username: displayName 77 | })) as ChatPostMessageResult 78 | await updateReadReceipt({ 79 | client, 80 | sender: user, 81 | receiver: member, 82 | messageId: newMessageId, 83 | emoji: receiptEmoji 84 | }) 85 | } 86 | 87 | // Increment the message counters 88 | await redis 89 | .multi() 90 | .hincrby(currentChat.key, 'message_count', 1) 91 | .incr(`counter:${currentChat.teamId}:total_messages_sent`) 92 | .exec() 93 | }) 94 | 95 | app.message( 96 | channelType('im'), 97 | subtype('message_changed'), 98 | async ({ client, context, event }) => { 99 | const user = await context.manager.getUser(event.message.user) 100 | if (!user) { 101 | return 102 | } 103 | 104 | // Won't matter if the user isn't currently in a chat 105 | if (!(await user.isInChat())) { 106 | return 107 | } 108 | 109 | await client.chat.postEphemeral({ 110 | channel: (await user.getDmChannelId()) as string, 111 | user: event.message.user, 112 | text: 113 | 'Changes to your message aren’t shown to the other members of the chat.' 114 | }) 115 | } 116 | ) 117 | } 118 | -------------------------------------------------------------------------------- /src/features/onboard.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@slack/bolt' 2 | import { ChatPrompt } from '../blocks' 3 | import { User } from '../models' 4 | 5 | export default (app: App) => { 6 | app.event('app_home_opened', async ({ body, event, say }) => { 7 | // Only show the intro message if the user doesn't exist in the DB yet 8 | if (await User.exists(event.user, body.team_id)) { 9 | return 10 | } 11 | 12 | await User.create(event.user, body.team_id, event.channel) 13 | await say({ 14 | blocks: ChatPrompt({ isExistingUser: false }), 15 | text: 16 | 'Welcome to Whirl, where you can have fun, completely anonymous chats with other members of your Slack. Check your DMs to get started.' 17 | }) 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /src/features/react.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@slack/bolt' 2 | 3 | export default (app: App) => { 4 | app.event('reaction_added', async ({ client, context, event }) => { 5 | // Ensure the event contains a ReactionMessageItem. 6 | if (!('channel' in event.item)) { 7 | return 8 | } 9 | 10 | const isDM = event.item.channel.startsWith('D') 11 | if (!isDM) { 12 | return 13 | } 14 | 15 | const user = await context.manager.getUser(event.user) 16 | if (!user) { 17 | return 18 | } 19 | 20 | // We don't care if a user reacts and they're not in a chat 21 | if (!(await user.isInChat())) { 22 | return 23 | } 24 | 25 | await client.chat.postEphemeral({ 26 | channel: event.item.channel, 27 | user: event.user, 28 | text: 29 | 'User reactions aren’t currently supported, so only you will be able to see them.' 30 | }) 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@slack/bolt' 2 | import mongoose from 'mongoose' 3 | import config from './config' 4 | import * as features from './features' 5 | import { addManagerContext } from './middlewares' 6 | import { Installation, IInstallation } from './models' 7 | 8 | const init = async () => { 9 | console.log('Starting Whirl…') 10 | 11 | // Set up database connection 12 | await mongoose.connect(config.databaseUrl, { 13 | useFindAndModify: false, 14 | useNewUrlParser: true, 15 | useUnifiedTopology: true 16 | }) 17 | 18 | // Initialize Slack app 19 | const app = new App({ 20 | signingSecret: config.signingSecret, 21 | clientId: config.clientId, 22 | clientSecret: config.clientSecret, 23 | stateSecret: config.stateSecret, 24 | scopes: [ 25 | 'chat:write', 26 | 'chat:write.customize', 27 | 'commands', 28 | 'im:history', 29 | 'reactions:read', 30 | 'reactions:write' 31 | ], 32 | installationStore: { 33 | storeInstallation: async installation => { 34 | // Prevent duplicate installations being stored 35 | const installationQuery = { 36 | 'team.id': installation.team.id 37 | } 38 | if (await Installation.exists(installationQuery)) { 39 | await Installation.deleteOne(installationQuery) 40 | } 41 | 42 | await Installation.create(installation) 43 | }, 44 | fetchInstallation: async query => { 45 | const installation = (await Installation.findOne({ 46 | 'team.id': query.teamId 47 | })) as IInstallation 48 | return installation 49 | } 50 | } 51 | }) 52 | 53 | // Load global middleware 54 | // TODO: Handle types properly so we don't have to ignore 55 | // @ts-ignore 56 | app.use(addManagerContext) 57 | 58 | // Load feature modules 59 | for (const [featureName, handler] of Object.entries(features)) { 60 | handler(app) 61 | console.log(`Loaded feature module: ${featureName}`) 62 | } 63 | 64 | const featuresCount = Object.keys(features).length 65 | console.log( 66 | `Loaded ${featuresCount} feature${featuresCount === 1 ? '' : 's'}` 67 | ) 68 | 69 | // Start receiving events 70 | await app.start(config.port) 71 | console.log(`Listening on port ${config.port}`) 72 | } 73 | 74 | init() 75 | -------------------------------------------------------------------------------- /src/manager.ts: -------------------------------------------------------------------------------- 1 | import { Chat, User, UserPool } from './models' 2 | 3 | class Manager { 4 | readonly teamId: string 5 | 6 | constructor(teamId: string) { 7 | this.teamId = teamId 8 | } 9 | 10 | getPool() { 11 | return new UserPool(this.teamId) 12 | } 13 | 14 | getChat(id: string) { 15 | return Chat.get(id, this.teamId) 16 | } 17 | 18 | getUser(id: string) { 19 | return User.get(id, this.teamId) 20 | } 21 | } 22 | 23 | export default Manager 24 | -------------------------------------------------------------------------------- /src/middlewares/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Context, 3 | MessageEvent, 4 | NextFn, 5 | SlackEventMiddlewareArgs 6 | } from '@slack/bolt' 7 | import Manager from '../manager' 8 | 9 | const filterEvent = (filterFn: (event: MessageEvent) => boolean) => { 10 | return async ({ 11 | event, 12 | next 13 | }: SlackEventMiddlewareArgs<'message'> & { next?: NextFn }) => { 14 | if (filterFn(event)) { 15 | await next!() 16 | } 17 | } 18 | } 19 | 20 | export const channelType = (type: string) => 21 | filterEvent((event: MessageEvent) => event.channel_type === type) 22 | 23 | // TODO: Use the proper type for middleware args because this can be applied to 24 | // other events besides the `message` event. 25 | export const addManagerContext = async ({ 26 | body, 27 | context, 28 | next 29 | }: SlackEventMiddlewareArgs<'message'> & { 30 | context: Context 31 | next?: NextFn 32 | }) => { 33 | // Slack's API doesn't return the team ID in a consistent format. This just 34 | // pulls the value depending on the shape of the payload. 35 | const teamId = 'team_id' in body ? body.team_id : body.team.id 36 | context.manager = new Manager(teamId) 37 | 38 | await next!() 39 | } 40 | -------------------------------------------------------------------------------- /src/models/chat.ts: -------------------------------------------------------------------------------- 1 | import { WebClient } from '@slack/web-api' 2 | import { ChatPrompt } from '../blocks' 3 | import config from '../config' 4 | import { User } from '../models' 5 | import redis from '../redis' 6 | import { capitalize, getEmoji } from '../utils' 7 | import { ChatMetadata, IChatMetadata } from '.' 8 | 9 | export class Chat { 10 | static readonly MIN_SIZE = 2 11 | 12 | readonly id: string 13 | readonly teamId: string 14 | readonly key: string 15 | 16 | constructor(id: string, teamId: string) { 17 | this.id = id 18 | this.teamId = teamId 19 | this.key = `chat:${this.teamId}_${this.id}` 20 | } 21 | 22 | async delete() { 23 | return redis 24 | .multi() 25 | .del(this.key) 26 | .del(`${this.key}:members`) 27 | .decr(`counter:${this.teamId}:active_chats`) 28 | .exec() 29 | } 30 | 31 | async end() { 32 | // Remove all members from the chat 33 | for (const memberId of await this.getMembers()) { 34 | await this.removeMember(memberId) 35 | } 36 | 37 | // Check the chat's total message count. If it's at least the minimum, 38 | // we'll update the metadata with the ending timestamp and the amount of 39 | // messages sent. But if it falls below that, it's considered insignificant 40 | // (e.g., a user running /next many times in a row without having sent a 41 | // message) and is simply discarded from the database. 42 | const messageCount = await this.getMessageCount() 43 | if (messageCount >= config.chatMetadataThreshold) { 44 | await this.saveMetadata() 45 | } else { 46 | await ChatMetadata.deleteOne({ _id: this.id, teamId: this.teamId }) 47 | } 48 | 49 | // Delete from Redis' memory 50 | await this.delete() 51 | } 52 | 53 | async getMembers() { 54 | return redis.smembers(`${this.key}:members`) 55 | } 56 | 57 | async hasEnoughMembers() { 58 | const currentSize = await this.getSize() 59 | return currentSize >= Chat.MIN_SIZE 60 | } 61 | 62 | async addMember(userId: string, noun: string) { 63 | const userKey = `user:${this.teamId}_${userId}` 64 | return redis 65 | .multi() 66 | .sadd(`${this.key}:members`, userId) 67 | .hset(userKey, 'chat_id', this.id) 68 | .hset(userKey, 'noun', noun) 69 | .incr(`counter:${this.teamId}:active_users`) 70 | .exec() 71 | } 72 | 73 | async removeMember(userId: string) { 74 | const userKey = `user:${this.teamId}_${userId}` 75 | let commands = redis 76 | .multi() 77 | .srem(`${this.key}:members`, userId) 78 | .hdel(userKey, 'chat_id') 79 | .hdel(userKey, 'noun') 80 | .del(`${userKey}:last_read_message_ids`) 81 | .decr(`counter:${this.teamId}:active_users`) 82 | 83 | // Remove the user from the other members' last read message IDs 84 | for (const memberId of await this.getMembers()) { 85 | if (memberId === userId) { 86 | continue 87 | } 88 | 89 | const memberKey = `user:${this.teamId}_${memberId}` 90 | commands = commands.hdel(`${memberKey}:last_read_message_ids`, userId) 91 | } 92 | 93 | return commands.exec() 94 | } 95 | 96 | async getCreatedAt() { 97 | return redis.hget(this.key, 'created_at') 98 | } 99 | 100 | async getMessageCount() { 101 | const messageCount = await redis.hget(this.key, 'message_count') 102 | if (!messageCount) { 103 | return 0 104 | } 105 | 106 | return parseInt(messageCount) 107 | } 108 | 109 | async getSize() { 110 | return redis.scard(`${this.key}:members`) 111 | } 112 | 113 | async sendIntroMessages(client: WebClient) { 114 | const members = await this.getMembers() 115 | for (const memberId of members) { 116 | const member = (await User.get(memberId, this.teamId)) as User 117 | 118 | // Send intro message to everyone but the member being introduced 119 | const noun = (await member.getNoun()) as string 120 | const displayName = `Anonymous ${capitalize(noun)}` 121 | const emoji = getEmoji(noun) 122 | for (const otherMemberId of members) { 123 | if (otherMemberId === memberId) { 124 | continue 125 | } 126 | await client.chat.postMessage({ 127 | channel: otherMemberId, 128 | text: `You are now talking to :${emoji}: *${displayName}*. Say hi! To end this chat at any time, run *\`/next\`*.` 129 | }) 130 | } 131 | } 132 | } 133 | 134 | async sendLeaveMessages(client: WebClient, noun: string) { 135 | const displayName = `Anonymous ${capitalize(noun)}` 136 | const emoji = getEmoji(noun) 137 | 138 | const hasEnoughMembers = await this.hasEnoughMembers() 139 | const message = `:${emoji}: _${displayName} left${ 140 | !hasEnoughMembers ? ', ending' : '' 141 | } the chat._` 142 | 143 | for (const memberId of await this.getMembers()) { 144 | await client.chat.postMessage({ 145 | channel: memberId, 146 | text: message 147 | }) 148 | 149 | if (!hasEnoughMembers) { 150 | await client.chat.postMessage({ 151 | channel: memberId, 152 | text: 'Want to join another one?', 153 | blocks: ChatPrompt() 154 | }) 155 | } 156 | } 157 | } 158 | 159 | private async saveMetadata() { 160 | const chatMetadata = (await ChatMetadata.findOne({ 161 | _id: this.id, 162 | teamId: this.teamId 163 | })) as IChatMetadata 164 | chatMetadata.endedAt = new Date(Date.now()) 165 | chatMetadata.messageCount = await this.getMessageCount() 166 | await chatMetadata.save() 167 | } 168 | 169 | static async exists(chatId: string, teamId: string) { 170 | return !!(await redis.exists(`chat:${teamId}_${chatId}`)) 171 | } 172 | 173 | static async get(chatId: string, teamId: string) { 174 | if (!(await Chat.exists(chatId, teamId))) { 175 | return null 176 | } 177 | 178 | return new Chat(chatId, teamId) 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/models/chat_metadata.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Document, Schema } from 'mongoose' 2 | 3 | interface ChatMember { 4 | id: string 5 | noun: string 6 | } 7 | 8 | export interface IChatMetadata extends Document { 9 | teamId: string 10 | startedAt: Date 11 | size: number 12 | members?: ChatMember[] 13 | endedAt?: Date 14 | messageCount?: number 15 | } 16 | 17 | const ChatMetadataSchema = new Schema({ 18 | _id: { 19 | type: String, 20 | required: true, 21 | immutable: true 22 | }, 23 | teamId: { 24 | type: String, 25 | required: true, 26 | immutable: true 27 | }, 28 | startedAt: { 29 | type: Date, 30 | required: true, 31 | immutable: true 32 | }, 33 | size: { 34 | type: Number, 35 | required: true, 36 | immutable: true 37 | }, 38 | members: [ 39 | { 40 | id: String, 41 | noun: String 42 | } 43 | ], 44 | endedAt: Date, 45 | messageCount: { 46 | type: Number, 47 | required: true, 48 | default: 0 49 | } 50 | }) 51 | 52 | export const ChatMetadata = mongoose.model( 53 | 'ChatMetadata', 54 | ChatMetadataSchema 55 | ) 56 | -------------------------------------------------------------------------------- /src/models/index.ts: -------------------------------------------------------------------------------- 1 | export * from './chat' 2 | export * from './chat_metadata' 3 | export * from './installation' 4 | export * from './user' 5 | export * from './user_pool' 6 | -------------------------------------------------------------------------------- /src/models/installation.ts: -------------------------------------------------------------------------------- 1 | import { Installation as SlackInstallation } from '@slack/oauth' 2 | import mongoose, { Document, Schema } from 'mongoose' 3 | 4 | export type IInstallation = SlackInstallation & Document 5 | 6 | const InstallationSchema = new Schema({ 7 | appId: String, 8 | bot: { 9 | id: String, 10 | scopes: [String], 11 | token: String, 12 | userId: String 13 | }, 14 | enterprise: { 15 | id: String, 16 | name: String 17 | }, 18 | incomingWebhook: { 19 | channel: String, 20 | channelId: String, 21 | configurationUrl: String, 22 | url: String 23 | }, 24 | team: { 25 | id: String, 26 | name: String 27 | }, 28 | tokenType: String, 29 | user: { 30 | id: String, 31 | token: String, 32 | scopes: [String] 33 | } 34 | }) 35 | 36 | export const Installation = mongoose.model( 37 | 'Installation', 38 | InstallationSchema 39 | ) 40 | -------------------------------------------------------------------------------- /src/models/user.ts: -------------------------------------------------------------------------------- 1 | import redis from '../redis' 2 | import { Chat } from '.' 3 | 4 | export class User { 5 | readonly id: string 6 | readonly teamId: string 7 | readonly key: string 8 | 9 | constructor(id: string, teamId: string) { 10 | this.id = id 11 | this.teamId = teamId 12 | this.key = `user:${teamId}_${id}` 13 | } 14 | 15 | async getCurrentChat() { 16 | const chatId = await this.getCurrentChatId() 17 | if (!chatId) { 18 | return null 19 | } 20 | 21 | return Chat.get(chatId, this.teamId) 22 | } 23 | 24 | async getCurrentChatId() { 25 | return redis.hget(this.key, 'chat_id') 26 | } 27 | 28 | async getDmChannelId() { 29 | return redis.hget(this.key, 'dm_channel_id') 30 | } 31 | 32 | async getLastReadMessageId(senderId: string) { 33 | return redis.hget(`${this.key}:last_read_message_ids`, senderId) 34 | } 35 | 36 | async setLastReadMessageId(senderId: string, messageId: string) { 37 | await redis.hset(`${this.key}:last_read_message_ids`, senderId, messageId) 38 | } 39 | 40 | async getNoun() { 41 | return redis.hget(this.key, 'noun') 42 | } 43 | 44 | async isInChat() { 45 | return !!(await redis.hexists(this.key, 'chat_id')) 46 | } 47 | 48 | async isInPool() { 49 | return !!(await redis.sismember(`user_pool:${this.teamId}`, this.id)) 50 | } 51 | 52 | async leave() { 53 | const currentChat = await this.getCurrentChat() 54 | if (!currentChat) { 55 | return 56 | } 57 | 58 | await currentChat.removeMember(this.id) 59 | } 60 | 61 | static async create(userId: string, teamId: string, dmChannelId: string) { 62 | const newUser = new User(userId, teamId) 63 | await redis 64 | .multi() 65 | .hset(newUser.key, 'dm_channel_id', dmChannelId) 66 | .incr(`counter:${teamId}:total_users`) 67 | .exec() 68 | 69 | return newUser 70 | } 71 | 72 | static async exists(userId: string, teamId: string) { 73 | return !!(await redis.exists(`user:${teamId}_${userId}`)) 74 | } 75 | 76 | static async get(userId: string, teamId: string) { 77 | if (!(await User.exists(userId, teamId))) { 78 | return null 79 | } 80 | 81 | return new User(userId, teamId) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/models/user_pool.ts: -------------------------------------------------------------------------------- 1 | import sampleSize from 'lodash.samplesize' 2 | import randomatic from 'randomatic' 3 | import nouns from '../data/nouns.json' 4 | import redis from '../redis' 5 | import { Chat, ChatMetadata, IChatMetadata } from '.' 6 | 7 | export class UserPool { 8 | readonly teamId: string 9 | readonly key: string 10 | 11 | constructor(teamId: string) { 12 | this.teamId = teamId 13 | this.key = `user_pool:${this.teamId}` 14 | } 15 | 16 | async add(userId: string) { 17 | await redis.sadd(this.key, userId) 18 | } 19 | 20 | async remove(userId: string) { 21 | await redis.srem(this.key, userId) 22 | } 23 | 24 | async canCreateChat(size: number = Chat.MIN_SIZE) { 25 | return (await redis.scard(this.key)) >= size 26 | } 27 | 28 | async attemptToCreateChat( 29 | initiatingUserId: string, 30 | size: number = Chat.MIN_SIZE 31 | ) { 32 | const membersNeeded = size - 1 33 | if (!(await this.canCreateChat(membersNeeded))) { 34 | return null 35 | } 36 | 37 | const newChat = await this.createChat(size) 38 | 39 | // Generate the nouns that will be used 40 | const randomNouns = sampleSize(nouns, size) 41 | const membersMetadata = [] 42 | 43 | // Add the initiating user to the chat 44 | const initiatorNoun = randomNouns[0] 45 | await newChat.addMember(initiatingUserId, initiatorNoun) 46 | await this.remove(initiatingUserId) 47 | 48 | membersMetadata.push({ 49 | id: initiatingUserId, 50 | noun: initiatorNoun 51 | }) 52 | 53 | // Keep adding random users from the pool to this chat until its at the size 54 | for (let i = 0; i < membersNeeded; i++) { 55 | const randomUserId = (await redis.srandmember(this.key)) as string 56 | 57 | // Theoretically, it shouldn't be possible for the user who initiated 58 | // this to be drawn because they haven't been added to the pool. 59 | if (randomUserId === initiatingUserId) { 60 | i-- 61 | continue 62 | } 63 | 64 | const noun = randomNouns[1 + i] // Add 1 because the initiating user already claimed the first noun 65 | await newChat.addMember(randomUserId, noun) 66 | await this.remove(randomUserId) 67 | 68 | membersMetadata.push({ 69 | id: randomUserId, 70 | noun 71 | }) 72 | } 73 | 74 | // Add user IDs and pseudonyms to metadata 75 | const newChatMetadata = (await ChatMetadata.findOne({ 76 | _id: newChat.id, 77 | teamId: this.teamId 78 | })) as IChatMetadata 79 | newChatMetadata.members = membersMetadata 80 | await newChatMetadata.save() 81 | 82 | return newChat 83 | } 84 | 85 | async createChat(size: number = Chat.MIN_SIZE) { 86 | // TODO: Guarantee the ID is unique within the DB and Redis cache 87 | const randomId = randomatic('A0', 10) 88 | const startedAt = Date.now() 89 | 90 | // Create the base chat representation in Redis 91 | const newChat = new Chat(randomId, this.teamId) 92 | await redis 93 | .multi() 94 | .hset(newChat.key, 'created_at', Math.floor(startedAt / 1000)) // UNIX timestamp 95 | .hset(newChat.key, 'message_count', 0) 96 | .incr(`counter:${this.teamId}:active_chats`) 97 | .incr(`counter:${this.teamId}:total_chats`) 98 | .exec() 99 | 100 | // Store the base metadata in Mongo 101 | await ChatMetadata.create({ 102 | _id: randomId, 103 | teamId: this.teamId, 104 | startedAt, 105 | size 106 | }) 107 | 108 | return newChat 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/redis.ts: -------------------------------------------------------------------------------- 1 | import Redis from 'ioredis' 2 | import config from './config' 3 | 4 | const redis = new Redis(config.redisUrl) 5 | 6 | export default redis 7 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import iconsJson from '../data/icons.json' 2 | import nounsJson from '../data/nouns.json' 3 | 4 | const icons = iconsJson as { [noun: string]: string } 5 | const nouns = nounsJson as string[] 6 | 7 | export const capitalize = (str: string) => 8 | str.charAt(0).toUpperCase() + str.slice(1) 9 | 10 | export class EmojiNotFoundError extends Error { 11 | constructor(noun: string) { 12 | super(`${noun} does not have an emoji`) 13 | this.name = this.constructor.name 14 | } 15 | } 16 | 17 | export const getEmoji = (noun: string) => { 18 | if (!nouns.includes(noun)) { 19 | throw new EmojiNotFoundError(noun) 20 | } 21 | 22 | return icons[noun] ?? noun 23 | } 24 | 25 | // Inserts zero-width non-joiner to prevent special tags like "@everyone" and "" from working 26 | export const removeSpecialTags = (str: string): string => 27 | str 28 | .replace(/@(channel|everyone|here)/gi, '@\u200c$1') 29 | .replace(//gi, '<\u200c!$1|$2>') 30 | -------------------------------------------------------------------------------- /src/utils/slack.ts: -------------------------------------------------------------------------------- 1 | import { WebClient } from '@slack/web-api' 2 | import { User } from '../models' 3 | 4 | export interface UpdateReadReceiptArguments { 5 | client: WebClient 6 | sender: User 7 | receiver: User 8 | messageId: string 9 | emoji: string 10 | } 11 | 12 | export const updateReadReceipt = async ({ 13 | client, 14 | sender, 15 | receiver, 16 | messageId, 17 | emoji 18 | }: UpdateReadReceiptArguments) => { 19 | // Get the latest message in the receiving user's DM channel 20 | const dmChannelId = (await receiver.getDmChannelId()) as string 21 | const lastReadMessageId = await sender.getLastReadMessageId(receiver.id) 22 | 23 | // Check the ID of the latest message. If it matches the previously saved 24 | // ID, then we know that there hasn't been any new messages sent in the chat. 25 | // 26 | // This also prevents unnecessary API calls from being made by the read receipt 27 | // getting removed and immediately re-added to the same message. 28 | if (lastReadMessageId === messageId) { 29 | return 30 | } 31 | 32 | // Remove the reaction from the previous latest message, if it exists. 33 | const reactOptions = { 34 | channel: dmChannelId, 35 | name: emoji 36 | } 37 | if (lastReadMessageId !== null) { 38 | try { 39 | await client.reactions.remove({ 40 | ...reactOptions, 41 | timestamp: lastReadMessageId 42 | }) 43 | } catch { 44 | // Ignore errors like `message_not_found` and `no_reaction` because any 45 | // non-existent messages associated with a read receipt will be overwritten 46 | // when the last read message ID is set. This usually happens when 47 | // a user sends a message and deletes it after everyone has received it. 48 | } 49 | } 50 | 51 | // Save the ID of the latest message, then add the reaction to it. 52 | await sender.setLastReadMessageId(receiver.id, messageId) 53 | try { 54 | await client.reactions.add({ 55 | ...reactOptions, 56 | timestamp: messageId 57 | }) 58 | } catch { 59 | // Ignore errors like `already_reacted`. This usually happens when Slack 60 | // sends the same payload multiple times. 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "alwaysStrict": true, 4 | "esModuleInterop": true, 5 | "forceConsistentCasingInFileNames": true, 6 | "module": "commonjs", 7 | "noFallthroughCasesInSwitch": true, 8 | "noImplicitReturns": true, 9 | "noUnusedLocals": true, 10 | "noUnusedParameters": true, 11 | "outDir": "build", 12 | "resolveJsonModule": true, 13 | "rootDir": "src", 14 | "skipLibCheck": true, 15 | "strict": true, 16 | "target": "es2018" 17 | }, 18 | "compileOnSave": true, 19 | "include": ["src"] 20 | } 21 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/code-frame@^7.0.0": 6 | version "7.10.4" 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" 8 | integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== 9 | dependencies: 10 | "@babel/highlight" "^7.10.4" 11 | 12 | "@babel/helper-validator-identifier@^7.10.4": 13 | version "7.10.4" 14 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" 15 | integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== 16 | 17 | "@babel/highlight@^7.10.4": 18 | version "7.10.4" 19 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" 20 | integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== 21 | dependencies: 22 | "@babel/helper-validator-identifier" "^7.10.4" 23 | chalk "^2.0.0" 24 | js-tokens "^4.0.0" 25 | 26 | "@sindresorhus/is@^0.14.0": 27 | version "0.14.0" 28 | resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" 29 | integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== 30 | 31 | "@slack/bolt@^2.2.3": 32 | version "2.2.3" 33 | resolved "https://registry.yarnpkg.com/@slack/bolt/-/bolt-2.2.3.tgz#f0a106b011ec98fcb0ef61e16ddfbb1505f96628" 34 | integrity sha512-J6PZ3mufbegKmCVRD2tqGnVtXKbT1cFFWqrCY6pmK07SvQ7hN3w5KGcJeMIJALAEDzQqZRafjHs8lCWtZHN6/A== 35 | dependencies: 36 | "@slack/logger" "^2.0.0" 37 | "@slack/oauth" "^1.1.0" 38 | "@slack/types" "^1.6.0" 39 | "@slack/web-api" "^5.9.0" 40 | "@types/express" "^4.16.1" 41 | "@types/node" ">=10" 42 | "@types/promise.allsettled" "^1.0.3" 43 | axios "^0.19.0" 44 | express "^4.16.4" 45 | please-upgrade-node "^3.2.0" 46 | promise.allsettled "^1.0.2" 47 | raw-body "^2.3.3" 48 | tsscmp "^1.0.6" 49 | 50 | "@slack/logger@>=1.0.0 <3.0.0", "@slack/logger@^2.0.0": 51 | version "2.0.0" 52 | resolved "https://registry.yarnpkg.com/@slack/logger/-/logger-2.0.0.tgz#6a4e1c755849bc0f66dac08a8be54ce790ec0e6b" 53 | integrity sha512-OkIJpiU2fz6HOJujhlhfIGrc8hB4ibqtf7nnbJQDerG0BqwZCfmgtK5sWzZ0TkXVRBKD5MpLrTmCYyMxoMCgPw== 54 | dependencies: 55 | "@types/node" ">=8.9.0" 56 | 57 | "@slack/oauth@^1.1.0": 58 | version "1.1.0" 59 | resolved "https://registry.yarnpkg.com/@slack/oauth/-/oauth-1.1.0.tgz#68967f3ae92941132bad773e263976ebd6d9fad5" 60 | integrity sha512-v4yawvn9DCmWO0HXXnWxjmwVikLkoZKjCU042o6UES5u0FroYX8ozs+xWbueO8lb7YYqSKPsIX6A6nlbR4pUyA== 61 | dependencies: 62 | "@slack/logger" "^2.0.0" 63 | "@slack/web-api" "^5.7.0" 64 | "@types/jsonwebtoken" "^8.3.7" 65 | "@types/node" ">=6.0.0" 66 | jsonwebtoken "^8.5.1" 67 | lodash.isstring "^4.0.1" 68 | 69 | "@slack/types@^1.6.0", "@slack/types@^1.7.0": 70 | version "1.7.0" 71 | resolved "https://registry.yarnpkg.com/@slack/types/-/types-1.7.0.tgz#0a00b60bc6703c1413edd823dcb0f829d16457ed" 72 | integrity sha512-aigLPmTO513JxeFyeII/74y+S5jU39tabDWPsZyMHJWCYqK3vCkRvV73NL+Ay+Tq5RC2NgSmkedk1wvQJ6oXLg== 73 | 74 | "@slack/web-api@^5.11.0", "@slack/web-api@^5.7.0", "@slack/web-api@^5.9.0": 75 | version "5.11.0" 76 | resolved "https://registry.yarnpkg.com/@slack/web-api/-/web-api-5.11.0.tgz#6549ec71d13c2837cc672cbf7793a88eef22802f" 77 | integrity sha512-4a/uj7IZjFLu7Qmq0nH74ecLqk1iI/9x3yRS/v6M5vXDyc5lEruRFp4d5/bz4eN5Bathlq4Bws0wioY516fPag== 78 | dependencies: 79 | "@slack/logger" ">=1.0.0 <3.0.0" 80 | "@slack/types" "^1.7.0" 81 | "@types/is-stream" "^1.1.0" 82 | "@types/node" ">=8.9.0" 83 | "@types/p-queue" "^2.3.2" 84 | axios "^0.19.0" 85 | eventemitter3 "^3.1.0" 86 | form-data "^2.5.0" 87 | is-stream "^1.1.0" 88 | p-queue "^2.4.2" 89 | p-retry "^4.0.0" 90 | 91 | "@szmarczak/http-timer@^1.1.2": 92 | version "1.1.2" 93 | resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" 94 | integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== 95 | dependencies: 96 | defer-to-connect "^1.0.1" 97 | 98 | "@types/body-parser@*": 99 | version "1.19.0" 100 | resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" 101 | integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== 102 | dependencies: 103 | "@types/connect" "*" 104 | "@types/node" "*" 105 | 106 | "@types/bson@*": 107 | version "4.0.2" 108 | resolved "https://registry.yarnpkg.com/@types/bson/-/bson-4.0.2.tgz#7accb85942fc39bbdb7515d4de437c04f698115f" 109 | integrity sha512-+uWmsejEHfmSjyyM/LkrP0orfE2m5Mx9Xel4tXNeqi1ldK5XMQcDsFkBmLDtuyKUbxj2jGDo0H240fbCRJZo7Q== 110 | dependencies: 111 | "@types/node" "*" 112 | 113 | "@types/color-name@^1.1.1": 114 | version "1.1.1" 115 | resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" 116 | integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== 117 | 118 | "@types/connect@*": 119 | version "3.4.33" 120 | resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" 121 | integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== 122 | dependencies: 123 | "@types/node" "*" 124 | 125 | "@types/eslint-visitor-keys@^1.0.0": 126 | version "1.0.0" 127 | resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" 128 | integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== 129 | 130 | "@types/express-serve-static-core@*": 131 | version "4.17.9" 132 | resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.9.tgz#2d7b34dcfd25ec663c25c85d76608f8b249667f1" 133 | integrity sha512-DG0BYg6yO+ePW+XoDENYz8zhNGC3jDDEpComMYn7WJc4mY1Us8Rw9ax2YhJXxpyk2SF47PQAoQ0YyVT1a0bEkA== 134 | dependencies: 135 | "@types/node" "*" 136 | "@types/qs" "*" 137 | "@types/range-parser" "*" 138 | 139 | "@types/express@^4.16.1": 140 | version "4.17.7" 141 | resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.7.tgz#42045be6475636d9801369cd4418ef65cdb0dd59" 142 | integrity sha512-dCOT5lcmV/uC2J9k0rPafATeeyz+99xTt54ReX11/LObZgfzJqZNcW27zGhYyX+9iSEGXGt5qLPwRSvBZcLvtQ== 143 | dependencies: 144 | "@types/body-parser" "*" 145 | "@types/express-serve-static-core" "*" 146 | "@types/qs" "*" 147 | "@types/serve-static" "*" 148 | 149 | "@types/ioredis@^4.17.2": 150 | version "4.17.3" 151 | resolved "https://registry.yarnpkg.com/@types/ioredis/-/ioredis-4.17.3.tgz#65ba8b9344576ecb229c57ec1db92be3fe830ee9" 152 | integrity sha512-G0pN/WZb7OBMFksZOBcqATBUeBII00IZ7C9OW0bm7VG3XMXBI75stTXWLBxm6iNLQxdjFZgzThRbc3gBXBhZGw== 153 | dependencies: 154 | "@types/node" "*" 155 | 156 | "@types/is-stream@^1.1.0": 157 | version "1.1.0" 158 | resolved "https://registry.yarnpkg.com/@types/is-stream/-/is-stream-1.1.0.tgz#b84d7bb207a210f2af9bed431dc0fbe9c4143be1" 159 | integrity sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg== 160 | dependencies: 161 | "@types/node" "*" 162 | 163 | "@types/json-schema@^7.0.3": 164 | version "7.0.5" 165 | resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" 166 | integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== 167 | 168 | "@types/jsonwebtoken@^8.3.7": 169 | version "8.5.0" 170 | resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#2531d5e300803aa63279b232c014acf780c981c5" 171 | integrity sha512-9bVao7LvyorRGZCw0VmH/dr7Og+NdjYSsKAxB43OQoComFbBgsEpoR9JW6+qSq/ogwVBg8GI2MfAlk4SYI4OLg== 172 | dependencies: 173 | "@types/node" "*" 174 | 175 | "@types/lodash.samplesize@^4.2.6": 176 | version "4.2.6" 177 | resolved "https://registry.yarnpkg.com/@types/lodash.samplesize/-/lodash.samplesize-4.2.6.tgz#d9ba20aa254cc39705737e840cb4a8228d31ef29" 178 | integrity sha512-yBgEuIxVIM+corHdvB+NHgzni1Oc0aEd7acuO/jET0vO2Y2f6sl7vfQlaZKgzcN+ZqWLB6B2VQTKc1T5zQra+Q== 179 | dependencies: 180 | "@types/lodash" "*" 181 | 182 | "@types/lodash@*": 183 | version "4.14.158" 184 | resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.158.tgz#b38ea8b6fe799acd076d7a8d7ab71c26ef77f785" 185 | integrity sha512-InCEXJNTv/59yO4VSfuvNrZHt7eeNtWQEgnieIA+mIC+MOWM9arOWG2eQ8Vhk6NbOre6/BidiXhkZYeDY9U35w== 186 | 187 | "@types/mime@*": 188 | version "2.0.3" 189 | resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a" 190 | integrity sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q== 191 | 192 | "@types/mongodb@*": 193 | version "3.5.25" 194 | resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-3.5.25.tgz#ab187db04d79f8e3f15af236327dc9139d9d4736" 195 | integrity sha512-2H/Owt+pHCl9YmBOYnXc3VdnxejJEjVdH+QCWL5ZAfPehEn3evygKBX3/vKRv7aTwfNbUd0E5vjJdQklH/9a6w== 196 | dependencies: 197 | "@types/bson" "*" 198 | "@types/node" "*" 199 | 200 | "@types/mongoose@^5.7.32": 201 | version "5.7.34" 202 | resolved "https://registry.yarnpkg.com/@types/mongoose/-/mongoose-5.7.34.tgz#37d226fbb00b91319ca70014d0240d09a7164187" 203 | integrity sha512-AGzGNS+/eu6IAaMU38wis5ZWlePJhIIo9BKr2/qgkZylgWmX/eO21vNl7QWEstXb80r3US2ZwEnFYjBWIDXfBQ== 204 | dependencies: 205 | "@types/mongodb" "*" 206 | "@types/node" "*" 207 | 208 | "@types/node@*", "@types/node@>=10", "@types/node@>=6.0.0", "@types/node@>=8.9.0": 209 | version "14.0.27" 210 | resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.27.tgz#a151873af5a5e851b51b3b065c9e63390a9e0eb1" 211 | integrity sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g== 212 | 213 | "@types/p-queue@^2.3.2": 214 | version "2.3.2" 215 | resolved "https://registry.yarnpkg.com/@types/p-queue/-/p-queue-2.3.2.tgz#16bc5fece69ef85efaf2bce8b13f3ebe39c5a1c8" 216 | integrity sha512-eKAv5Ql6k78dh3ULCsSBxX6bFNuGjTmof5Q/T6PiECDq0Yf8IIn46jCyp3RJvCi8owaEmm3DZH1PEImjBMd/vQ== 217 | 218 | "@types/promise.allsettled@^1.0.3": 219 | version "1.0.3" 220 | resolved "https://registry.yarnpkg.com/@types/promise.allsettled/-/promise.allsettled-1.0.3.tgz#6f3166618226a570b98c8250fc78687a912e56d5" 221 | integrity sha512-b/IFHHTkYkTqu41IH9UtpICwqrpKj2oNlb4KHPzFQDMiz+h1BgAeATeO0/XTph4+UkH9W2U0E4B4j64KWOovag== 222 | 223 | "@types/qs@*": 224 | version "6.9.4" 225 | resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a" 226 | integrity sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ== 227 | 228 | "@types/randomatic@^3.1.0": 229 | version "3.1.0" 230 | resolved "https://registry.yarnpkg.com/@types/randomatic/-/randomatic-3.1.0.tgz#b593dae46c80689be735aa826a3fa06aa9c1ac59" 231 | integrity sha512-/q4VZpGKoT1s2Tc9lEpbghQe7+pQWpD+hJDEhXv0BOzMp1xhNalFeoUUaBfb6w7NWMhmAxMO0J9OA9ac/t1Xhw== 232 | 233 | "@types/range-parser@*": 234 | version "1.2.3" 235 | resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" 236 | integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== 237 | 238 | "@types/retry@^0.12.0": 239 | version "0.12.0" 240 | resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" 241 | integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== 242 | 243 | "@types/serve-static@*": 244 | version "1.13.5" 245 | resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.5.tgz#3d25d941a18415d3ab092def846e135a08bbcf53" 246 | integrity sha512-6M64P58N+OXjU432WoLLBQxbA0LRGBCRm7aAGQJ+SMC1IMl0dgRVi9EFfoDcS2a7Xogygk/eGN94CfwU9UF7UQ== 247 | dependencies: 248 | "@types/express-serve-static-core" "*" 249 | "@types/mime" "*" 250 | 251 | "@typescript-eslint/eslint-plugin@^3.7.1": 252 | version "3.7.1" 253 | resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.7.1.tgz#d144c49a9a0ffe8dd704bb179c243df76c111bc9" 254 | integrity sha512-3DB9JDYkMrc8Au00rGFiJLK2Ja9CoMP6Ut0sHsXp3ZtSugjNxvSSHTnKLfo4o+QmjYBJqEznDqsG1zj4F2xnsg== 255 | dependencies: 256 | "@typescript-eslint/experimental-utils" "3.7.1" 257 | debug "^4.1.1" 258 | functional-red-black-tree "^1.0.1" 259 | regexpp "^3.0.0" 260 | semver "^7.3.2" 261 | tsutils "^3.17.1" 262 | 263 | "@typescript-eslint/experimental-utils@3.7.1": 264 | version "3.7.1" 265 | resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.7.1.tgz#ab036caaed4c870d22531d41f9352f3147364d61" 266 | integrity sha512-TqE97pv7HrqWcGJbLbZt1v59tcqsSVpWTOf1AqrWK7n8nok2sGgVtYRuGXeNeLw3wXlLEbY1MKP3saB2HsO/Ng== 267 | dependencies: 268 | "@types/json-schema" "^7.0.3" 269 | "@typescript-eslint/types" "3.7.1" 270 | "@typescript-eslint/typescript-estree" "3.7.1" 271 | eslint-scope "^5.0.0" 272 | eslint-utils "^2.0.0" 273 | 274 | "@typescript-eslint/parser@^3.7.1": 275 | version "3.7.1" 276 | resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.7.1.tgz#5d9ccecb116d12d9c6073e9861c57c9b1aa88128" 277 | integrity sha512-W4QV/gXvfIsccN8225784LNOorcm7ch68Fi3V4Wg7gmkWSQRKevO4RrRqWo6N/Z/myK1QAiGgeaXN57m+R/8iQ== 278 | dependencies: 279 | "@types/eslint-visitor-keys" "^1.0.0" 280 | "@typescript-eslint/experimental-utils" "3.7.1" 281 | "@typescript-eslint/types" "3.7.1" 282 | "@typescript-eslint/typescript-estree" "3.7.1" 283 | eslint-visitor-keys "^1.1.0" 284 | 285 | "@typescript-eslint/types@3.7.1": 286 | version "3.7.1" 287 | resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.7.1.tgz#90375606b2fd73c1224fe9e397ee151e28fa1e0c" 288 | integrity sha512-PZe8twm5Z4b61jt7GAQDor6KiMhgPgf4XmUb9zdrwTbgtC/Sj29gXP1dws9yEn4+aJeyXrjsD9XN7AWFhmnUfg== 289 | 290 | "@typescript-eslint/typescript-estree@3.7.1": 291 | version "3.7.1" 292 | resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.7.1.tgz#ce1ffbd0fa53f34d4ce851a7a364e392432f6eb3" 293 | integrity sha512-m97vNZkI08dunYOr2lVZOHoyfpqRs0KDpd6qkGaIcLGhQ2WPtgHOd/eVbsJZ0VYCQvupKrObAGTOvk3tfpybYA== 294 | dependencies: 295 | "@typescript-eslint/types" "3.7.1" 296 | "@typescript-eslint/visitor-keys" "3.7.1" 297 | debug "^4.1.1" 298 | glob "^7.1.6" 299 | is-glob "^4.0.1" 300 | lodash "^4.17.15" 301 | semver "^7.3.2" 302 | tsutils "^3.17.1" 303 | 304 | "@typescript-eslint/visitor-keys@3.7.1": 305 | version "3.7.1" 306 | resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.7.1.tgz#b90191e74efdee656be8c5a30f428ed16dda46d1" 307 | integrity sha512-xn22sQbEya+Utj2IqJHGLA3i1jDzR43RzWupxojbSWnj3nnPLavaQmWe5utw03CwYao3r00qzXfgJMGNkrzrAA== 308 | dependencies: 309 | eslint-visitor-keys "^1.1.0" 310 | 311 | abbrev@1: 312 | version "1.1.1" 313 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 314 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== 315 | 316 | accepts@~1.3.7: 317 | version "1.3.7" 318 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" 319 | integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== 320 | dependencies: 321 | mime-types "~2.1.24" 322 | negotiator "0.6.2" 323 | 324 | acorn-jsx@^5.2.0: 325 | version "5.2.0" 326 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" 327 | integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== 328 | 329 | acorn@^7.3.1: 330 | version "7.3.1" 331 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd" 332 | integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA== 333 | 334 | ajv@^6.10.0, ajv@^6.10.2: 335 | version "6.12.3" 336 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706" 337 | integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA== 338 | dependencies: 339 | fast-deep-equal "^3.1.1" 340 | fast-json-stable-stringify "^2.0.0" 341 | json-schema-traverse "^0.4.1" 342 | uri-js "^4.2.2" 343 | 344 | ansi-align@^3.0.0: 345 | version "3.0.0" 346 | resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" 347 | integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== 348 | dependencies: 349 | string-width "^3.0.0" 350 | 351 | ansi-colors@^4.1.1: 352 | version "4.1.1" 353 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 354 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 355 | 356 | ansi-regex@^4.1.0: 357 | version "4.1.0" 358 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" 359 | integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== 360 | 361 | ansi-regex@^5.0.0: 362 | version "5.0.0" 363 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" 364 | integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== 365 | 366 | ansi-styles@^3.2.0, ansi-styles@^3.2.1: 367 | version "3.2.1" 368 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 369 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 370 | dependencies: 371 | color-convert "^1.9.0" 372 | 373 | ansi-styles@^4.1.0: 374 | version "4.2.1" 375 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" 376 | integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== 377 | dependencies: 378 | "@types/color-name" "^1.1.1" 379 | color-convert "^2.0.1" 380 | 381 | anymatch@~3.1.1: 382 | version "3.1.1" 383 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" 384 | integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== 385 | dependencies: 386 | normalize-path "^3.0.0" 387 | picomatch "^2.0.4" 388 | 389 | arg@^4.1.0: 390 | version "4.1.3" 391 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" 392 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 393 | 394 | argparse@^1.0.7: 395 | version "1.0.10" 396 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 397 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 398 | dependencies: 399 | sprintf-js "~1.0.2" 400 | 401 | array-flatten@1.1.1: 402 | version "1.1.1" 403 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 404 | integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= 405 | 406 | array.prototype.map@^1.0.1: 407 | version "1.0.2" 408 | resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.2.tgz#9a4159f416458a23e9483078de1106b2ef68f8ec" 409 | integrity sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw== 410 | dependencies: 411 | define-properties "^1.1.3" 412 | es-abstract "^1.17.0-next.1" 413 | es-array-method-boxes-properly "^1.0.0" 414 | is-string "^1.0.4" 415 | 416 | astral-regex@^1.0.0: 417 | version "1.0.0" 418 | resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" 419 | integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== 420 | 421 | asynckit@^0.4.0: 422 | version "0.4.0" 423 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 424 | integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= 425 | 426 | axios@^0.19.0: 427 | version "0.19.2" 428 | resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" 429 | integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== 430 | dependencies: 431 | follow-redirects "1.5.10" 432 | 433 | balanced-match@^1.0.0: 434 | version "1.0.0" 435 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 436 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 437 | 438 | binary-extensions@^2.0.0: 439 | version "2.1.0" 440 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" 441 | integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== 442 | 443 | bl@^2.2.0: 444 | version "2.2.1" 445 | resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.1.tgz#8c11a7b730655c5d56898cdc871224f40fd901d5" 446 | integrity sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g== 447 | dependencies: 448 | readable-stream "^2.3.5" 449 | safe-buffer "^5.1.1" 450 | 451 | bluebird@3.5.1: 452 | version "3.5.1" 453 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" 454 | integrity sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA== 455 | 456 | body-parser@1.19.0: 457 | version "1.19.0" 458 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 459 | integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== 460 | dependencies: 461 | bytes "3.1.0" 462 | content-type "~1.0.4" 463 | debug "2.6.9" 464 | depd "~1.1.2" 465 | http-errors "1.7.2" 466 | iconv-lite "0.4.24" 467 | on-finished "~2.3.0" 468 | qs "6.7.0" 469 | raw-body "2.4.0" 470 | type-is "~1.6.17" 471 | 472 | boxen@^4.2.0: 473 | version "4.2.0" 474 | resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" 475 | integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ== 476 | dependencies: 477 | ansi-align "^3.0.0" 478 | camelcase "^5.3.1" 479 | chalk "^3.0.0" 480 | cli-boxes "^2.2.0" 481 | string-width "^4.1.0" 482 | term-size "^2.1.0" 483 | type-fest "^0.8.1" 484 | widest-line "^3.1.0" 485 | 486 | brace-expansion@^1.1.7: 487 | version "1.1.11" 488 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 489 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 490 | dependencies: 491 | balanced-match "^1.0.0" 492 | concat-map "0.0.1" 493 | 494 | braces@~3.0.2: 495 | version "3.0.2" 496 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 497 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 498 | dependencies: 499 | fill-range "^7.0.1" 500 | 501 | bson@^1.1.4: 502 | version "1.1.4" 503 | resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.4.tgz#f76870d799f15b854dffb7ee32f0a874797f7e89" 504 | integrity sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q== 505 | 506 | buffer-equal-constant-time@1.0.1: 507 | version "1.0.1" 508 | resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" 509 | integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= 510 | 511 | buffer-from@^1.0.0: 512 | version "1.1.1" 513 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" 514 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== 515 | 516 | bytes@3.1.0: 517 | version "3.1.0" 518 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" 519 | integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== 520 | 521 | cacheable-request@^6.0.0: 522 | version "6.1.0" 523 | resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" 524 | integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== 525 | dependencies: 526 | clone-response "^1.0.2" 527 | get-stream "^5.1.0" 528 | http-cache-semantics "^4.0.0" 529 | keyv "^3.0.0" 530 | lowercase-keys "^2.0.0" 531 | normalize-url "^4.1.0" 532 | responselike "^1.0.2" 533 | 534 | callsites@^3.0.0: 535 | version "3.1.0" 536 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 537 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 538 | 539 | camelcase@^5.3.1: 540 | version "5.3.1" 541 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 542 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 543 | 544 | chalk@^2.0.0: 545 | version "2.4.2" 546 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 547 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 548 | dependencies: 549 | ansi-styles "^3.2.1" 550 | escape-string-regexp "^1.0.5" 551 | supports-color "^5.3.0" 552 | 553 | chalk@^3.0.0: 554 | version "3.0.0" 555 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" 556 | integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== 557 | dependencies: 558 | ansi-styles "^4.1.0" 559 | supports-color "^7.1.0" 560 | 561 | chalk@^4.0.0: 562 | version "4.1.0" 563 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" 564 | integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== 565 | dependencies: 566 | ansi-styles "^4.1.0" 567 | supports-color "^7.1.0" 568 | 569 | chokidar@^3.2.2: 570 | version "3.4.1" 571 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.1.tgz#e905bdecf10eaa0a0b1db0c664481cc4cbc22ba1" 572 | integrity sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g== 573 | dependencies: 574 | anymatch "~3.1.1" 575 | braces "~3.0.2" 576 | glob-parent "~5.1.0" 577 | is-binary-path "~2.1.0" 578 | is-glob "~4.0.1" 579 | normalize-path "~3.0.0" 580 | readdirp "~3.4.0" 581 | optionalDependencies: 582 | fsevents "~2.1.2" 583 | 584 | ci-info@^2.0.0: 585 | version "2.0.0" 586 | resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" 587 | integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== 588 | 589 | cli-boxes@^2.2.0: 590 | version "2.2.0" 591 | resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d" 592 | integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w== 593 | 594 | clone-response@^1.0.2: 595 | version "1.0.2" 596 | resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" 597 | integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= 598 | dependencies: 599 | mimic-response "^1.0.0" 600 | 601 | cluster-key-slot@^1.1.0: 602 | version "1.1.0" 603 | resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" 604 | integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw== 605 | 606 | color-convert@^1.9.0: 607 | version "1.9.3" 608 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 609 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 610 | dependencies: 611 | color-name "1.1.3" 612 | 613 | color-convert@^2.0.1: 614 | version "2.0.1" 615 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 616 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 617 | dependencies: 618 | color-name "~1.1.4" 619 | 620 | color-name@1.1.3: 621 | version "1.1.3" 622 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 623 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 624 | 625 | color-name@~1.1.4: 626 | version "1.1.4" 627 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 628 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 629 | 630 | combined-stream@^1.0.6: 631 | version "1.0.8" 632 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 633 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 634 | dependencies: 635 | delayed-stream "~1.0.0" 636 | 637 | concat-map@0.0.1: 638 | version "0.0.1" 639 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 640 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 641 | 642 | configstore@^5.0.1: 643 | version "5.0.1" 644 | resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" 645 | integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== 646 | dependencies: 647 | dot-prop "^5.2.0" 648 | graceful-fs "^4.1.2" 649 | make-dir "^3.0.0" 650 | unique-string "^2.0.0" 651 | write-file-atomic "^3.0.0" 652 | xdg-basedir "^4.0.0" 653 | 654 | content-disposition@0.5.3: 655 | version "0.5.3" 656 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" 657 | integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== 658 | dependencies: 659 | safe-buffer "5.1.2" 660 | 661 | content-type@~1.0.4: 662 | version "1.0.4" 663 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 664 | integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== 665 | 666 | cookie-signature@1.0.6: 667 | version "1.0.6" 668 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 669 | integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= 670 | 671 | cookie@0.4.0: 672 | version "0.4.0" 673 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" 674 | integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== 675 | 676 | core-util-is@~1.0.0: 677 | version "1.0.2" 678 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 679 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 680 | 681 | cross-spawn@^7.0.2: 682 | version "7.0.3" 683 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 684 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 685 | dependencies: 686 | path-key "^3.1.0" 687 | shebang-command "^2.0.0" 688 | which "^2.0.1" 689 | 690 | crypto-random-string@^2.0.0: 691 | version "2.0.0" 692 | resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" 693 | integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== 694 | 695 | debug@2.6.9, debug@^2.2.0: 696 | version "2.6.9" 697 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 698 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 699 | dependencies: 700 | ms "2.0.0" 701 | 702 | debug@3.1.0, debug@=3.1.0: 703 | version "3.1.0" 704 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 705 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== 706 | dependencies: 707 | ms "2.0.0" 708 | 709 | debug@^3.2.6: 710 | version "3.2.6" 711 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" 712 | integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== 713 | dependencies: 714 | ms "^2.1.1" 715 | 716 | debug@^4.0.1, debug@^4.1.1: 717 | version "4.1.1" 718 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" 719 | integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== 720 | dependencies: 721 | ms "^2.1.1" 722 | 723 | decompress-response@^3.3.0: 724 | version "3.3.0" 725 | resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" 726 | integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= 727 | dependencies: 728 | mimic-response "^1.0.0" 729 | 730 | deep-extend@^0.6.0: 731 | version "0.6.0" 732 | resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" 733 | integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== 734 | 735 | deep-is@^0.1.3: 736 | version "0.1.3" 737 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" 738 | integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= 739 | 740 | defer-to-connect@^1.0.1: 741 | version "1.1.3" 742 | resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" 743 | integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== 744 | 745 | define-properties@^1.1.2, define-properties@^1.1.3: 746 | version "1.1.3" 747 | resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" 748 | integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== 749 | dependencies: 750 | object-keys "^1.0.12" 751 | 752 | delayed-stream@~1.0.0: 753 | version "1.0.0" 754 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 755 | integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= 756 | 757 | denque@^1.1.0, denque@^1.4.1: 758 | version "1.4.1" 759 | resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf" 760 | integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ== 761 | 762 | depd@~1.1.2: 763 | version "1.1.2" 764 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 765 | integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 766 | 767 | destroy@~1.0.4: 768 | version "1.0.4" 769 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 770 | integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= 771 | 772 | diff@^4.0.1: 773 | version "4.0.2" 774 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 775 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 776 | 777 | doctrine@^3.0.0: 778 | version "3.0.0" 779 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" 780 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 781 | dependencies: 782 | esutils "^2.0.2" 783 | 784 | dot-prop@^5.2.0: 785 | version "5.2.0" 786 | resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" 787 | integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A== 788 | dependencies: 789 | is-obj "^2.0.0" 790 | 791 | dotenv@^8.2.0: 792 | version "8.2.0" 793 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" 794 | integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== 795 | 796 | duplexer3@^0.1.4: 797 | version "0.1.4" 798 | resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" 799 | integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= 800 | 801 | ecdsa-sig-formatter@1.0.11: 802 | version "1.0.11" 803 | resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" 804 | integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== 805 | dependencies: 806 | safe-buffer "^5.0.1" 807 | 808 | ee-first@1.1.1: 809 | version "1.1.1" 810 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 811 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= 812 | 813 | emoji-regex@^7.0.1: 814 | version "7.0.3" 815 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" 816 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== 817 | 818 | emoji-regex@^8.0.0: 819 | version "8.0.0" 820 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 821 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 822 | 823 | encodeurl@~1.0.2: 824 | version "1.0.2" 825 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 826 | integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 827 | 828 | end-of-stream@^1.1.0: 829 | version "1.4.4" 830 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" 831 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 832 | dependencies: 833 | once "^1.4.0" 834 | 835 | enquirer@^2.3.5: 836 | version "2.3.6" 837 | resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" 838 | integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== 839 | dependencies: 840 | ansi-colors "^4.1.1" 841 | 842 | es-abstract@^1.17.0-next.1, es-abstract@^1.17.4, es-abstract@^1.17.5: 843 | version "1.17.6" 844 | resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" 845 | integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== 846 | dependencies: 847 | es-to-primitive "^1.2.1" 848 | function-bind "^1.1.1" 849 | has "^1.0.3" 850 | has-symbols "^1.0.1" 851 | is-callable "^1.2.0" 852 | is-regex "^1.1.0" 853 | object-inspect "^1.7.0" 854 | object-keys "^1.1.1" 855 | object.assign "^4.1.0" 856 | string.prototype.trimend "^1.0.1" 857 | string.prototype.trimstart "^1.0.1" 858 | 859 | es-array-method-boxes-properly@^1.0.0: 860 | version "1.0.0" 861 | resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" 862 | integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== 863 | 864 | es-get-iterator@^1.0.2: 865 | version "1.1.0" 866 | resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8" 867 | integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ== 868 | dependencies: 869 | es-abstract "^1.17.4" 870 | has-symbols "^1.0.1" 871 | is-arguments "^1.0.4" 872 | is-map "^2.0.1" 873 | is-set "^2.0.1" 874 | is-string "^1.0.5" 875 | isarray "^2.0.5" 876 | 877 | es-to-primitive@^1.2.1: 878 | version "1.2.1" 879 | resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" 880 | integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== 881 | dependencies: 882 | is-callable "^1.1.4" 883 | is-date-object "^1.0.1" 884 | is-symbol "^1.0.2" 885 | 886 | escape-goat@^2.0.0: 887 | version "2.1.1" 888 | resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" 889 | integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== 890 | 891 | escape-html@~1.0.3: 892 | version "1.0.3" 893 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 894 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= 895 | 896 | escape-string-regexp@^1.0.5: 897 | version "1.0.5" 898 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 899 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 900 | 901 | eslint-config-prettier@^6.11.0: 902 | version "6.11.0" 903 | resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz#f6d2238c1290d01c859a8b5c1f7d352a0b0da8b1" 904 | integrity sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA== 905 | dependencies: 906 | get-stdin "^6.0.0" 907 | 908 | eslint-plugin-prettier@^3.1.4: 909 | version "3.1.4" 910 | resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz#168ab43154e2ea57db992a2cd097c828171f75c2" 911 | integrity sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg== 912 | dependencies: 913 | prettier-linter-helpers "^1.0.0" 914 | 915 | eslint-scope@^5.0.0, eslint-scope@^5.1.0: 916 | version "5.1.0" 917 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" 918 | integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== 919 | dependencies: 920 | esrecurse "^4.1.0" 921 | estraverse "^4.1.1" 922 | 923 | eslint-utils@^2.0.0, eslint-utils@^2.1.0: 924 | version "2.1.0" 925 | resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" 926 | integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== 927 | dependencies: 928 | eslint-visitor-keys "^1.1.0" 929 | 930 | eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: 931 | version "1.3.0" 932 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" 933 | integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== 934 | 935 | eslint@^7.5.0: 936 | version "7.6.0" 937 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.6.0.tgz#522d67cfaea09724d96949c70e7a0550614d64d6" 938 | integrity sha512-QlAManNtqr7sozWm5TF4wIH9gmUm2hE3vNRUvyoYAa4y1l5/jxD/PQStEjBMQtCqZmSep8UxrcecI60hOpe61w== 939 | dependencies: 940 | "@babel/code-frame" "^7.0.0" 941 | ajv "^6.10.0" 942 | chalk "^4.0.0" 943 | cross-spawn "^7.0.2" 944 | debug "^4.0.1" 945 | doctrine "^3.0.0" 946 | enquirer "^2.3.5" 947 | eslint-scope "^5.1.0" 948 | eslint-utils "^2.1.0" 949 | eslint-visitor-keys "^1.3.0" 950 | espree "^7.2.0" 951 | esquery "^1.2.0" 952 | esutils "^2.0.2" 953 | file-entry-cache "^5.0.1" 954 | functional-red-black-tree "^1.0.1" 955 | glob-parent "^5.0.0" 956 | globals "^12.1.0" 957 | ignore "^4.0.6" 958 | import-fresh "^3.0.0" 959 | imurmurhash "^0.1.4" 960 | is-glob "^4.0.0" 961 | js-yaml "^3.13.1" 962 | json-stable-stringify-without-jsonify "^1.0.1" 963 | levn "^0.4.1" 964 | lodash "^4.17.19" 965 | minimatch "^3.0.4" 966 | natural-compare "^1.4.0" 967 | optionator "^0.9.1" 968 | progress "^2.0.0" 969 | regexpp "^3.1.0" 970 | semver "^7.2.1" 971 | strip-ansi "^6.0.0" 972 | strip-json-comments "^3.1.0" 973 | table "^5.2.3" 974 | text-table "^0.2.0" 975 | v8-compile-cache "^2.0.3" 976 | 977 | espree@^7.2.0: 978 | version "7.2.0" 979 | resolved "https://registry.yarnpkg.com/espree/-/espree-7.2.0.tgz#1c263d5b513dbad0ac30c4991b93ac354e948d69" 980 | integrity sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g== 981 | dependencies: 982 | acorn "^7.3.1" 983 | acorn-jsx "^5.2.0" 984 | eslint-visitor-keys "^1.3.0" 985 | 986 | esprima@^4.0.0: 987 | version "4.0.1" 988 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 989 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 990 | 991 | esquery@^1.2.0: 992 | version "1.3.1" 993 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" 994 | integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== 995 | dependencies: 996 | estraverse "^5.1.0" 997 | 998 | esrecurse@^4.1.0: 999 | version "4.2.1" 1000 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" 1001 | integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== 1002 | dependencies: 1003 | estraverse "^4.1.0" 1004 | 1005 | estraverse@^4.1.0, estraverse@^4.1.1: 1006 | version "4.3.0" 1007 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" 1008 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== 1009 | 1010 | estraverse@^5.1.0: 1011 | version "5.1.0" 1012 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642" 1013 | integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw== 1014 | 1015 | esutils@^2.0.2: 1016 | version "2.0.3" 1017 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 1018 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 1019 | 1020 | etag@~1.8.1: 1021 | version "1.8.1" 1022 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 1023 | integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= 1024 | 1025 | eventemitter3@^3.1.0: 1026 | version "3.1.2" 1027 | resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" 1028 | integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== 1029 | 1030 | express@^4.16.4: 1031 | version "4.17.1" 1032 | resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" 1033 | integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== 1034 | dependencies: 1035 | accepts "~1.3.7" 1036 | array-flatten "1.1.1" 1037 | body-parser "1.19.0" 1038 | content-disposition "0.5.3" 1039 | content-type "~1.0.4" 1040 | cookie "0.4.0" 1041 | cookie-signature "1.0.6" 1042 | debug "2.6.9" 1043 | depd "~1.1.2" 1044 | encodeurl "~1.0.2" 1045 | escape-html "~1.0.3" 1046 | etag "~1.8.1" 1047 | finalhandler "~1.1.2" 1048 | fresh "0.5.2" 1049 | merge-descriptors "1.0.1" 1050 | methods "~1.1.2" 1051 | on-finished "~2.3.0" 1052 | parseurl "~1.3.3" 1053 | path-to-regexp "0.1.7" 1054 | proxy-addr "~2.0.5" 1055 | qs "6.7.0" 1056 | range-parser "~1.2.1" 1057 | safe-buffer "5.1.2" 1058 | send "0.17.1" 1059 | serve-static "1.14.1" 1060 | setprototypeof "1.1.1" 1061 | statuses "~1.5.0" 1062 | type-is "~1.6.18" 1063 | utils-merge "1.0.1" 1064 | vary "~1.1.2" 1065 | 1066 | fast-deep-equal@^3.1.1: 1067 | version "3.1.3" 1068 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 1069 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 1070 | 1071 | fast-diff@^1.1.2: 1072 | version "1.2.0" 1073 | resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" 1074 | integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== 1075 | 1076 | fast-json-stable-stringify@^2.0.0: 1077 | version "2.1.0" 1078 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 1079 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 1080 | 1081 | fast-levenshtein@^2.0.6: 1082 | version "2.0.6" 1083 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 1084 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= 1085 | 1086 | file-entry-cache@^5.0.1: 1087 | version "5.0.1" 1088 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" 1089 | integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== 1090 | dependencies: 1091 | flat-cache "^2.0.1" 1092 | 1093 | fill-range@^7.0.1: 1094 | version "7.0.1" 1095 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 1096 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 1097 | dependencies: 1098 | to-regex-range "^5.0.1" 1099 | 1100 | finalhandler@~1.1.2: 1101 | version "1.1.2" 1102 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" 1103 | integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== 1104 | dependencies: 1105 | debug "2.6.9" 1106 | encodeurl "~1.0.2" 1107 | escape-html "~1.0.3" 1108 | on-finished "~2.3.0" 1109 | parseurl "~1.3.3" 1110 | statuses "~1.5.0" 1111 | unpipe "~1.0.0" 1112 | 1113 | flat-cache@^2.0.1: 1114 | version "2.0.1" 1115 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" 1116 | integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== 1117 | dependencies: 1118 | flatted "^2.0.0" 1119 | rimraf "2.6.3" 1120 | write "1.0.3" 1121 | 1122 | flatted@^2.0.0: 1123 | version "2.0.2" 1124 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" 1125 | integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== 1126 | 1127 | follow-redirects@1.5.10: 1128 | version "1.5.10" 1129 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" 1130 | integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== 1131 | dependencies: 1132 | debug "=3.1.0" 1133 | 1134 | form-data@^2.5.0: 1135 | version "2.5.1" 1136 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" 1137 | integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== 1138 | dependencies: 1139 | asynckit "^0.4.0" 1140 | combined-stream "^1.0.6" 1141 | mime-types "^2.1.12" 1142 | 1143 | forwarded@~0.1.2: 1144 | version "0.1.2" 1145 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" 1146 | integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= 1147 | 1148 | fresh@0.5.2: 1149 | version "0.5.2" 1150 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 1151 | integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= 1152 | 1153 | fs.realpath@^1.0.0: 1154 | version "1.0.0" 1155 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 1156 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 1157 | 1158 | fsevents@~2.1.2: 1159 | version "2.1.3" 1160 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" 1161 | integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== 1162 | 1163 | function-bind@^1.1.1: 1164 | version "1.1.1" 1165 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 1166 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 1167 | 1168 | functional-red-black-tree@^1.0.1: 1169 | version "1.0.1" 1170 | resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" 1171 | integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= 1172 | 1173 | get-stdin@^6.0.0: 1174 | version "6.0.0" 1175 | resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" 1176 | integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== 1177 | 1178 | get-stream@^4.1.0: 1179 | version "4.1.0" 1180 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" 1181 | integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== 1182 | dependencies: 1183 | pump "^3.0.0" 1184 | 1185 | get-stream@^5.1.0: 1186 | version "5.1.0" 1187 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" 1188 | integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== 1189 | dependencies: 1190 | pump "^3.0.0" 1191 | 1192 | glob-parent@^5.0.0, glob-parent@~5.1.0: 1193 | version "5.1.2" 1194 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 1195 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 1196 | dependencies: 1197 | is-glob "^4.0.1" 1198 | 1199 | glob@^7.1.3, glob@^7.1.6: 1200 | version "7.1.6" 1201 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" 1202 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 1203 | dependencies: 1204 | fs.realpath "^1.0.0" 1205 | inflight "^1.0.4" 1206 | inherits "2" 1207 | minimatch "^3.0.4" 1208 | once "^1.3.0" 1209 | path-is-absolute "^1.0.0" 1210 | 1211 | global-dirs@^2.0.1: 1212 | version "2.0.1" 1213 | resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201" 1214 | integrity sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A== 1215 | dependencies: 1216 | ini "^1.3.5" 1217 | 1218 | globals@^12.1.0: 1219 | version "12.4.0" 1220 | resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" 1221 | integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== 1222 | dependencies: 1223 | type-fest "^0.8.1" 1224 | 1225 | got@^9.6.0: 1226 | version "9.6.0" 1227 | resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" 1228 | integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== 1229 | dependencies: 1230 | "@sindresorhus/is" "^0.14.0" 1231 | "@szmarczak/http-timer" "^1.1.2" 1232 | cacheable-request "^6.0.0" 1233 | decompress-response "^3.3.0" 1234 | duplexer3 "^0.1.4" 1235 | get-stream "^4.1.0" 1236 | lowercase-keys "^1.0.1" 1237 | mimic-response "^1.0.1" 1238 | p-cancelable "^1.0.0" 1239 | to-readable-stream "^1.0.0" 1240 | url-parse-lax "^3.0.0" 1241 | 1242 | graceful-fs@^4.1.2: 1243 | version "4.2.4" 1244 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" 1245 | integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== 1246 | 1247 | has-flag@^3.0.0: 1248 | version "3.0.0" 1249 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 1250 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 1251 | 1252 | has-flag@^4.0.0: 1253 | version "4.0.0" 1254 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 1255 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 1256 | 1257 | has-symbols@^1.0.0, has-symbols@^1.0.1: 1258 | version "1.0.1" 1259 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" 1260 | integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== 1261 | 1262 | has-yarn@^2.1.0: 1263 | version "2.1.0" 1264 | resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" 1265 | integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== 1266 | 1267 | has@^1.0.3: 1268 | version "1.0.3" 1269 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 1270 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 1271 | dependencies: 1272 | function-bind "^1.1.1" 1273 | 1274 | http-cache-semantics@^4.0.0: 1275 | version "4.1.0" 1276 | resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" 1277 | integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== 1278 | 1279 | http-errors@1.7.2: 1280 | version "1.7.2" 1281 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" 1282 | integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== 1283 | dependencies: 1284 | depd "~1.1.2" 1285 | inherits "2.0.3" 1286 | setprototypeof "1.1.1" 1287 | statuses ">= 1.5.0 < 2" 1288 | toidentifier "1.0.0" 1289 | 1290 | http-errors@1.7.3, http-errors@~1.7.2: 1291 | version "1.7.3" 1292 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" 1293 | integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== 1294 | dependencies: 1295 | depd "~1.1.2" 1296 | inherits "2.0.4" 1297 | setprototypeof "1.1.1" 1298 | statuses ">= 1.5.0 < 2" 1299 | toidentifier "1.0.0" 1300 | 1301 | iconv-lite@0.4.24: 1302 | version "0.4.24" 1303 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 1304 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 1305 | dependencies: 1306 | safer-buffer ">= 2.1.2 < 3" 1307 | 1308 | ignore-by-default@^1.0.1: 1309 | version "1.0.1" 1310 | resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" 1311 | integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= 1312 | 1313 | ignore@^4.0.6: 1314 | version "4.0.6" 1315 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" 1316 | integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== 1317 | 1318 | import-fresh@^3.0.0: 1319 | version "3.2.1" 1320 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" 1321 | integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== 1322 | dependencies: 1323 | parent-module "^1.0.0" 1324 | resolve-from "^4.0.0" 1325 | 1326 | import-lazy@^2.1.0: 1327 | version "2.1.0" 1328 | resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" 1329 | integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= 1330 | 1331 | imurmurhash@^0.1.4: 1332 | version "0.1.4" 1333 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 1334 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= 1335 | 1336 | inflight@^1.0.4: 1337 | version "1.0.6" 1338 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 1339 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 1340 | dependencies: 1341 | once "^1.3.0" 1342 | wrappy "1" 1343 | 1344 | inherits@2, inherits@2.0.4, inherits@~2.0.3: 1345 | version "2.0.4" 1346 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 1347 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 1348 | 1349 | inherits@2.0.3: 1350 | version "2.0.3" 1351 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 1352 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 1353 | 1354 | ini@^1.3.5, ini@~1.3.0: 1355 | version "1.3.8" 1356 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" 1357 | integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== 1358 | 1359 | ioredis@^4.17.3: 1360 | version "4.17.3" 1361 | resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.17.3.tgz#9938c60e4ca685f75326337177bdc2e73ae9c9dc" 1362 | integrity sha512-iRvq4BOYzNFkDnSyhx7cmJNOi1x/HWYe+A4VXHBu4qpwJaGT1Mp+D2bVGJntH9K/Z/GeOM/Nprb8gB3bmitz1Q== 1363 | dependencies: 1364 | cluster-key-slot "^1.1.0" 1365 | debug "^4.1.1" 1366 | denque "^1.1.0" 1367 | lodash.defaults "^4.2.0" 1368 | lodash.flatten "^4.4.0" 1369 | redis-commands "1.5.0" 1370 | redis-errors "^1.2.0" 1371 | redis-parser "^3.0.0" 1372 | standard-as-callback "^2.0.1" 1373 | 1374 | ipaddr.js@1.9.1: 1375 | version "1.9.1" 1376 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" 1377 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== 1378 | 1379 | is-arguments@^1.0.4: 1380 | version "1.0.4" 1381 | resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" 1382 | integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== 1383 | 1384 | is-binary-path@~2.1.0: 1385 | version "2.1.0" 1386 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 1387 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 1388 | dependencies: 1389 | binary-extensions "^2.0.0" 1390 | 1391 | is-callable@^1.1.4, is-callable@^1.2.0: 1392 | version "1.2.0" 1393 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" 1394 | integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== 1395 | 1396 | is-ci@^2.0.0: 1397 | version "2.0.0" 1398 | resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" 1399 | integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== 1400 | dependencies: 1401 | ci-info "^2.0.0" 1402 | 1403 | is-date-object@^1.0.1: 1404 | version "1.0.2" 1405 | resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" 1406 | integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== 1407 | 1408 | is-extglob@^2.1.1: 1409 | version "2.1.1" 1410 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 1411 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 1412 | 1413 | is-fullwidth-code-point@^2.0.0: 1414 | version "2.0.0" 1415 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 1416 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 1417 | 1418 | is-fullwidth-code-point@^3.0.0: 1419 | version "3.0.0" 1420 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 1421 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 1422 | 1423 | is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: 1424 | version "4.0.1" 1425 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" 1426 | integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== 1427 | dependencies: 1428 | is-extglob "^2.1.1" 1429 | 1430 | is-installed-globally@^0.3.1: 1431 | version "0.3.2" 1432 | resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" 1433 | integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== 1434 | dependencies: 1435 | global-dirs "^2.0.1" 1436 | is-path-inside "^3.0.1" 1437 | 1438 | is-map@^2.0.1: 1439 | version "2.0.1" 1440 | resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" 1441 | integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== 1442 | 1443 | is-npm@^4.0.0: 1444 | version "4.0.0" 1445 | resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" 1446 | integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== 1447 | 1448 | is-number@^4.0.0: 1449 | version "4.0.0" 1450 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" 1451 | integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== 1452 | 1453 | is-number@^7.0.0: 1454 | version "7.0.0" 1455 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 1456 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 1457 | 1458 | is-obj@^2.0.0: 1459 | version "2.0.0" 1460 | resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" 1461 | integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== 1462 | 1463 | is-path-inside@^3.0.1: 1464 | version "3.0.2" 1465 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" 1466 | integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== 1467 | 1468 | is-regex@^1.1.0: 1469 | version "1.1.0" 1470 | resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" 1471 | integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== 1472 | dependencies: 1473 | has-symbols "^1.0.1" 1474 | 1475 | is-set@^2.0.1: 1476 | version "2.0.1" 1477 | resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43" 1478 | integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA== 1479 | 1480 | is-stream@^1.1.0: 1481 | version "1.1.0" 1482 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 1483 | integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= 1484 | 1485 | is-string@^1.0.4, is-string@^1.0.5: 1486 | version "1.0.5" 1487 | resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" 1488 | integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== 1489 | 1490 | is-symbol@^1.0.2: 1491 | version "1.0.3" 1492 | resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" 1493 | integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== 1494 | dependencies: 1495 | has-symbols "^1.0.1" 1496 | 1497 | is-typedarray@^1.0.0: 1498 | version "1.0.0" 1499 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 1500 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= 1501 | 1502 | is-yarn-global@^0.3.0: 1503 | version "0.3.0" 1504 | resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" 1505 | integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== 1506 | 1507 | isarray@^2.0.5: 1508 | version "2.0.5" 1509 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" 1510 | integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== 1511 | 1512 | isarray@~1.0.0: 1513 | version "1.0.0" 1514 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 1515 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 1516 | 1517 | isexe@^2.0.0: 1518 | version "2.0.0" 1519 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 1520 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 1521 | 1522 | iterate-iterator@^1.0.1: 1523 | version "1.0.1" 1524 | resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6" 1525 | integrity sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw== 1526 | 1527 | iterate-value@^1.0.0: 1528 | version "1.0.2" 1529 | resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" 1530 | integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== 1531 | dependencies: 1532 | es-get-iterator "^1.0.2" 1533 | iterate-iterator "^1.0.1" 1534 | 1535 | js-tokens@^4.0.0: 1536 | version "4.0.0" 1537 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 1538 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 1539 | 1540 | js-yaml@^3.13.1: 1541 | version "3.14.0" 1542 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" 1543 | integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== 1544 | dependencies: 1545 | argparse "^1.0.7" 1546 | esprima "^4.0.0" 1547 | 1548 | json-buffer@3.0.0: 1549 | version "3.0.0" 1550 | resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" 1551 | integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= 1552 | 1553 | json-schema-traverse@^0.4.1: 1554 | version "0.4.1" 1555 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 1556 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 1557 | 1558 | json-stable-stringify-without-jsonify@^1.0.1: 1559 | version "1.0.1" 1560 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" 1561 | integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= 1562 | 1563 | jsonwebtoken@^8.5.1: 1564 | version "8.5.1" 1565 | resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" 1566 | integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== 1567 | dependencies: 1568 | jws "^3.2.2" 1569 | lodash.includes "^4.3.0" 1570 | lodash.isboolean "^3.0.3" 1571 | lodash.isinteger "^4.0.4" 1572 | lodash.isnumber "^3.0.3" 1573 | lodash.isplainobject "^4.0.6" 1574 | lodash.isstring "^4.0.1" 1575 | lodash.once "^4.0.0" 1576 | ms "^2.1.1" 1577 | semver "^5.6.0" 1578 | 1579 | jwa@^1.4.1: 1580 | version "1.4.1" 1581 | resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" 1582 | integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== 1583 | dependencies: 1584 | buffer-equal-constant-time "1.0.1" 1585 | ecdsa-sig-formatter "1.0.11" 1586 | safe-buffer "^5.0.1" 1587 | 1588 | jws@^3.2.2: 1589 | version "3.2.2" 1590 | resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" 1591 | integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== 1592 | dependencies: 1593 | jwa "^1.4.1" 1594 | safe-buffer "^5.0.1" 1595 | 1596 | kareem@2.3.1: 1597 | version "2.3.1" 1598 | resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.3.1.tgz#def12d9c941017fabfb00f873af95e9c99e1be87" 1599 | integrity sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw== 1600 | 1601 | keyv@^3.0.0: 1602 | version "3.1.0" 1603 | resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" 1604 | integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== 1605 | dependencies: 1606 | json-buffer "3.0.0" 1607 | 1608 | kind-of@^6.0.0: 1609 | version "6.0.3" 1610 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" 1611 | integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== 1612 | 1613 | latest-version@^5.0.0: 1614 | version "5.1.0" 1615 | resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" 1616 | integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== 1617 | dependencies: 1618 | package-json "^6.3.0" 1619 | 1620 | levn@^0.4.1: 1621 | version "0.4.1" 1622 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" 1623 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 1624 | dependencies: 1625 | prelude-ls "^1.2.1" 1626 | type-check "~0.4.0" 1627 | 1628 | lodash.defaults@^4.2.0: 1629 | version "4.2.0" 1630 | resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" 1631 | integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= 1632 | 1633 | lodash.flatten@^4.4.0: 1634 | version "4.4.0" 1635 | resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" 1636 | integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= 1637 | 1638 | lodash.includes@^4.3.0: 1639 | version "4.3.0" 1640 | resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" 1641 | integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= 1642 | 1643 | lodash.isboolean@^3.0.3: 1644 | version "3.0.3" 1645 | resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" 1646 | integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= 1647 | 1648 | lodash.isinteger@^4.0.4: 1649 | version "4.0.4" 1650 | resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" 1651 | integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= 1652 | 1653 | lodash.isnumber@^3.0.3: 1654 | version "3.0.3" 1655 | resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" 1656 | integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= 1657 | 1658 | lodash.isplainobject@^4.0.6: 1659 | version "4.0.6" 1660 | resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" 1661 | integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= 1662 | 1663 | lodash.isstring@^4.0.1: 1664 | version "4.0.1" 1665 | resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" 1666 | integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= 1667 | 1668 | lodash.once@^4.0.0: 1669 | version "4.1.1" 1670 | resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" 1671 | integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= 1672 | 1673 | lodash.samplesize@^4.2.0: 1674 | version "4.2.0" 1675 | resolved "https://registry.yarnpkg.com/lodash.samplesize/-/lodash.samplesize-4.2.0.tgz#460762fbb2b342290517499e90d51586db465ff9" 1676 | integrity sha1-Rgdi+7KzQikFF0mekNUVhttGX/k= 1677 | 1678 | lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19: 1679 | version "4.17.21" 1680 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 1681 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 1682 | 1683 | lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: 1684 | version "1.0.1" 1685 | resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" 1686 | integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== 1687 | 1688 | lowercase-keys@^2.0.0: 1689 | version "2.0.0" 1690 | resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" 1691 | integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== 1692 | 1693 | make-dir@^3.0.0: 1694 | version "3.1.0" 1695 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" 1696 | integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== 1697 | dependencies: 1698 | semver "^6.0.0" 1699 | 1700 | make-error@^1.1.1: 1701 | version "1.3.6" 1702 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" 1703 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 1704 | 1705 | math-random@^1.0.1: 1706 | version "1.0.4" 1707 | resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" 1708 | integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== 1709 | 1710 | media-typer@0.3.0: 1711 | version "0.3.0" 1712 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 1713 | integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= 1714 | 1715 | memory-pager@^1.0.2: 1716 | version "1.5.0" 1717 | resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" 1718 | integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== 1719 | 1720 | merge-descriptors@1.0.1: 1721 | version "1.0.1" 1722 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 1723 | integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= 1724 | 1725 | methods@~1.1.2: 1726 | version "1.1.2" 1727 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 1728 | integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 1729 | 1730 | mime-db@1.44.0: 1731 | version "1.44.0" 1732 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" 1733 | integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== 1734 | 1735 | mime-types@^2.1.12, mime-types@~2.1.24: 1736 | version "2.1.27" 1737 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" 1738 | integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== 1739 | dependencies: 1740 | mime-db "1.44.0" 1741 | 1742 | mime@1.6.0: 1743 | version "1.6.0" 1744 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" 1745 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 1746 | 1747 | mimic-response@^1.0.0, mimic-response@^1.0.1: 1748 | version "1.0.1" 1749 | resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" 1750 | integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== 1751 | 1752 | minimatch@^3.0.4: 1753 | version "3.0.4" 1754 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 1755 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 1756 | dependencies: 1757 | brace-expansion "^1.1.7" 1758 | 1759 | minimist@^1.2.0, minimist@^1.2.5: 1760 | version "1.2.5" 1761 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" 1762 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 1763 | 1764 | mkdirp@^0.5.1: 1765 | version "0.5.5" 1766 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" 1767 | integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== 1768 | dependencies: 1769 | minimist "^1.2.5" 1770 | 1771 | mongodb@3.5.10: 1772 | version "3.5.10" 1773 | resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.5.10.tgz#ed414988d2935b529004cead6dfdd22681258887" 1774 | integrity sha512-p/C48UvTU/dr/PQEDKfb9DsCVDJWXGmdJNFC+u5FPmTQVtog69X6D8vrWHz+sJx1zJnd96sjdh9ueo7bx2ILTw== 1775 | dependencies: 1776 | bl "^2.2.0" 1777 | bson "^1.1.4" 1778 | denque "^1.4.1" 1779 | require_optional "^1.0.1" 1780 | safe-buffer "^5.1.2" 1781 | optionalDependencies: 1782 | saslprep "^1.0.0" 1783 | 1784 | mongoose-legacy-pluralize@1.0.2: 1785 | version "1.0.2" 1786 | resolved "https://registry.yarnpkg.com/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz#3ba9f91fa507b5186d399fb40854bff18fb563e4" 1787 | integrity sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ== 1788 | 1789 | mongoose@^5.9.24: 1790 | version "5.9.27" 1791 | resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-5.9.27.tgz#914cbc2a454520934fbbf2c0e366d9c7d8076b3b" 1792 | integrity sha512-N8zj4pj9J2xJ2BnQ4NiIHEtmjPldtbmbEZOMz4phLTQr3KFWPR0T0I6EzQxNioHwmDbHD4VFzbEd755oD2SJxA== 1793 | dependencies: 1794 | bson "^1.1.4" 1795 | kareem "2.3.1" 1796 | mongodb "3.5.10" 1797 | mongoose-legacy-pluralize "1.0.2" 1798 | mpath "0.7.0" 1799 | mquery "3.2.2" 1800 | ms "2.1.2" 1801 | regexp-clone "1.0.0" 1802 | safe-buffer "5.2.1" 1803 | sift "7.0.1" 1804 | sliced "1.0.1" 1805 | 1806 | mpath@0.7.0: 1807 | version "0.7.0" 1808 | resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.7.0.tgz#20e8102e276b71709d6e07e9f8d4d0f641afbfb8" 1809 | integrity sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg== 1810 | 1811 | mquery@3.2.2: 1812 | version "3.2.2" 1813 | resolved "https://registry.yarnpkg.com/mquery/-/mquery-3.2.2.tgz#e1383a3951852ce23e37f619a9b350f1fb3664e7" 1814 | integrity sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q== 1815 | dependencies: 1816 | bluebird "3.5.1" 1817 | debug "3.1.0" 1818 | regexp-clone "^1.0.0" 1819 | safe-buffer "5.1.2" 1820 | sliced "1.0.1" 1821 | 1822 | ms@2.0.0: 1823 | version "2.0.0" 1824 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 1825 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 1826 | 1827 | ms@2.1.1: 1828 | version "2.1.1" 1829 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 1830 | integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== 1831 | 1832 | ms@2.1.2, ms@^2.1.1: 1833 | version "2.1.2" 1834 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1835 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1836 | 1837 | natural-compare@^1.4.0: 1838 | version "1.4.0" 1839 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 1840 | integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= 1841 | 1842 | negotiator@0.6.2: 1843 | version "0.6.2" 1844 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" 1845 | integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== 1846 | 1847 | nodemon@^2.0.4: 1848 | version "2.0.4" 1849 | resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.4.tgz#55b09319eb488d6394aa9818148c0c2d1c04c416" 1850 | integrity sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ== 1851 | dependencies: 1852 | chokidar "^3.2.2" 1853 | debug "^3.2.6" 1854 | ignore-by-default "^1.0.1" 1855 | minimatch "^3.0.4" 1856 | pstree.remy "^1.1.7" 1857 | semver "^5.7.1" 1858 | supports-color "^5.5.0" 1859 | touch "^3.1.0" 1860 | undefsafe "^2.0.2" 1861 | update-notifier "^4.0.0" 1862 | 1863 | nopt@~1.0.10: 1864 | version "1.0.10" 1865 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" 1866 | integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= 1867 | dependencies: 1868 | abbrev "1" 1869 | 1870 | normalize-path@^3.0.0, normalize-path@~3.0.0: 1871 | version "3.0.0" 1872 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 1873 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1874 | 1875 | normalize-url@^4.1.0: 1876 | version "4.5.1" 1877 | resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" 1878 | integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== 1879 | 1880 | object-inspect@^1.7.0: 1881 | version "1.8.0" 1882 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" 1883 | integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== 1884 | 1885 | object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: 1886 | version "1.1.1" 1887 | resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" 1888 | integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== 1889 | 1890 | object.assign@^4.1.0: 1891 | version "4.1.0" 1892 | resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" 1893 | integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== 1894 | dependencies: 1895 | define-properties "^1.1.2" 1896 | function-bind "^1.1.1" 1897 | has-symbols "^1.0.0" 1898 | object-keys "^1.0.11" 1899 | 1900 | on-finished@~2.3.0: 1901 | version "2.3.0" 1902 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 1903 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= 1904 | dependencies: 1905 | ee-first "1.1.1" 1906 | 1907 | once@^1.3.0, once@^1.3.1, once@^1.4.0: 1908 | version "1.4.0" 1909 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1910 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 1911 | dependencies: 1912 | wrappy "1" 1913 | 1914 | optionator@^0.9.1: 1915 | version "0.9.1" 1916 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" 1917 | integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== 1918 | dependencies: 1919 | deep-is "^0.1.3" 1920 | fast-levenshtein "^2.0.6" 1921 | levn "^0.4.1" 1922 | prelude-ls "^1.2.1" 1923 | type-check "^0.4.0" 1924 | word-wrap "^1.2.3" 1925 | 1926 | p-cancelable@^1.0.0: 1927 | version "1.1.0" 1928 | resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" 1929 | integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== 1930 | 1931 | p-queue@^2.4.2: 1932 | version "2.4.2" 1933 | resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-2.4.2.tgz#03609826682b743be9a22dba25051bd46724fc34" 1934 | integrity sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng== 1935 | 1936 | p-retry@^4.0.0: 1937 | version "4.2.0" 1938 | resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.2.0.tgz#ea9066c6b44f23cab4cd42f6147cdbbc6604da5d" 1939 | integrity sha512-jPH38/MRh263KKcq0wBNOGFJbm+U6784RilTmHjB/HM9kH9V8WlCpVUcdOmip9cjXOh6MxZ5yk1z2SjDUJfWmA== 1940 | dependencies: 1941 | "@types/retry" "^0.12.0" 1942 | retry "^0.12.0" 1943 | 1944 | package-json@^6.3.0: 1945 | version "6.5.0" 1946 | resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" 1947 | integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== 1948 | dependencies: 1949 | got "^9.6.0" 1950 | registry-auth-token "^4.0.0" 1951 | registry-url "^5.0.0" 1952 | semver "^6.2.0" 1953 | 1954 | parent-module@^1.0.0: 1955 | version "1.0.1" 1956 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 1957 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 1958 | dependencies: 1959 | callsites "^3.0.0" 1960 | 1961 | parseurl@~1.3.3: 1962 | version "1.3.3" 1963 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" 1964 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== 1965 | 1966 | path-is-absolute@^1.0.0: 1967 | version "1.0.1" 1968 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1969 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 1970 | 1971 | path-key@^3.1.0: 1972 | version "3.1.1" 1973 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 1974 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1975 | 1976 | path-to-regexp@0.1.7: 1977 | version "0.1.7" 1978 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 1979 | integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= 1980 | 1981 | picomatch@^2.0.4, picomatch@^2.2.1: 1982 | version "2.2.2" 1983 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" 1984 | integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== 1985 | 1986 | please-upgrade-node@^3.2.0: 1987 | version "3.2.0" 1988 | resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" 1989 | integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== 1990 | dependencies: 1991 | semver-compare "^1.0.0" 1992 | 1993 | prelude-ls@^1.2.1: 1994 | version "1.2.1" 1995 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" 1996 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 1997 | 1998 | prepend-http@^2.0.0: 1999 | version "2.0.0" 2000 | resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" 2001 | integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= 2002 | 2003 | prettier-linter-helpers@^1.0.0: 2004 | version "1.0.0" 2005 | resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" 2006 | integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== 2007 | dependencies: 2008 | fast-diff "^1.1.2" 2009 | 2010 | prettier@^2.0.5: 2011 | version "2.0.5" 2012 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4" 2013 | integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg== 2014 | 2015 | process-nextick-args@~2.0.0: 2016 | version "2.0.1" 2017 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 2018 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 2019 | 2020 | progress@^2.0.0: 2021 | version "2.0.3" 2022 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" 2023 | integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== 2024 | 2025 | promise.allsettled@^1.0.2: 2026 | version "1.0.2" 2027 | resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.2.tgz#d66f78fbb600e83e863d893e98b3d4376a9c47c9" 2028 | integrity sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg== 2029 | dependencies: 2030 | array.prototype.map "^1.0.1" 2031 | define-properties "^1.1.3" 2032 | es-abstract "^1.17.0-next.1" 2033 | function-bind "^1.1.1" 2034 | iterate-value "^1.0.0" 2035 | 2036 | proxy-addr@~2.0.5: 2037 | version "2.0.6" 2038 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" 2039 | integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== 2040 | dependencies: 2041 | forwarded "~0.1.2" 2042 | ipaddr.js "1.9.1" 2043 | 2044 | pstree.remy@^1.1.7: 2045 | version "1.1.8" 2046 | resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" 2047 | integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== 2048 | 2049 | pump@^3.0.0: 2050 | version "3.0.0" 2051 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" 2052 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== 2053 | dependencies: 2054 | end-of-stream "^1.1.0" 2055 | once "^1.3.1" 2056 | 2057 | punycode@^2.1.0: 2058 | version "2.1.1" 2059 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 2060 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 2061 | 2062 | pupa@^2.0.1: 2063 | version "2.0.1" 2064 | resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.0.1.tgz#dbdc9ff48ffbea4a26a069b6f9f7abb051008726" 2065 | integrity sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA== 2066 | dependencies: 2067 | escape-goat "^2.0.0" 2068 | 2069 | qs@6.7.0: 2070 | version "6.7.0" 2071 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" 2072 | integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== 2073 | 2074 | randomatic@^3.1.1: 2075 | version "3.1.1" 2076 | resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" 2077 | integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== 2078 | dependencies: 2079 | is-number "^4.0.0" 2080 | kind-of "^6.0.0" 2081 | math-random "^1.0.1" 2082 | 2083 | range-parser@~1.2.1: 2084 | version "1.2.1" 2085 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" 2086 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 2087 | 2088 | raw-body@2.4.0: 2089 | version "2.4.0" 2090 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" 2091 | integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== 2092 | dependencies: 2093 | bytes "3.1.0" 2094 | http-errors "1.7.2" 2095 | iconv-lite "0.4.24" 2096 | unpipe "1.0.0" 2097 | 2098 | raw-body@^2.3.3: 2099 | version "2.4.1" 2100 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" 2101 | integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== 2102 | dependencies: 2103 | bytes "3.1.0" 2104 | http-errors "1.7.3" 2105 | iconv-lite "0.4.24" 2106 | unpipe "1.0.0" 2107 | 2108 | rc@^1.2.8: 2109 | version "1.2.8" 2110 | resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" 2111 | integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== 2112 | dependencies: 2113 | deep-extend "^0.6.0" 2114 | ini "~1.3.0" 2115 | minimist "^1.2.0" 2116 | strip-json-comments "~2.0.1" 2117 | 2118 | readable-stream@^2.3.5: 2119 | version "2.3.7" 2120 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" 2121 | integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== 2122 | dependencies: 2123 | core-util-is "~1.0.0" 2124 | inherits "~2.0.3" 2125 | isarray "~1.0.0" 2126 | process-nextick-args "~2.0.0" 2127 | safe-buffer "~5.1.1" 2128 | string_decoder "~1.1.1" 2129 | util-deprecate "~1.0.1" 2130 | 2131 | readdirp@~3.4.0: 2132 | version "3.4.0" 2133 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" 2134 | integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== 2135 | dependencies: 2136 | picomatch "^2.2.1" 2137 | 2138 | redis-commands@1.5.0: 2139 | version "1.5.0" 2140 | resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.5.0.tgz#80d2e20698fe688f227127ff9e5164a7dd17e785" 2141 | integrity sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg== 2142 | 2143 | redis-errors@^1.0.0, redis-errors@^1.2.0: 2144 | version "1.2.0" 2145 | resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" 2146 | integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60= 2147 | 2148 | redis-parser@^3.0.0: 2149 | version "3.0.0" 2150 | resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" 2151 | integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ= 2152 | dependencies: 2153 | redis-errors "^1.0.0" 2154 | 2155 | regexp-clone@1.0.0, regexp-clone@^1.0.0: 2156 | version "1.0.0" 2157 | resolved "https://registry.yarnpkg.com/regexp-clone/-/regexp-clone-1.0.0.tgz#222db967623277056260b992626354a04ce9bf63" 2158 | integrity sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw== 2159 | 2160 | regexpp@^3.0.0, regexpp@^3.1.0: 2161 | version "3.1.0" 2162 | resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" 2163 | integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== 2164 | 2165 | registry-auth-token@^4.0.0: 2166 | version "4.2.0" 2167 | resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.0.tgz#1d37dffda72bbecd0f581e4715540213a65eb7da" 2168 | integrity sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w== 2169 | dependencies: 2170 | rc "^1.2.8" 2171 | 2172 | registry-url@^5.0.0: 2173 | version "5.1.0" 2174 | resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" 2175 | integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== 2176 | dependencies: 2177 | rc "^1.2.8" 2178 | 2179 | require_optional@^1.0.1: 2180 | version "1.0.1" 2181 | resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e" 2182 | integrity sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g== 2183 | dependencies: 2184 | resolve-from "^2.0.0" 2185 | semver "^5.1.0" 2186 | 2187 | resolve-from@^2.0.0: 2188 | version "2.0.0" 2189 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" 2190 | integrity sha1-lICrIOlP+h2egKgEx+oUdhGWa1c= 2191 | 2192 | resolve-from@^4.0.0: 2193 | version "4.0.0" 2194 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 2195 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 2196 | 2197 | responselike@^1.0.2: 2198 | version "1.0.2" 2199 | resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" 2200 | integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= 2201 | dependencies: 2202 | lowercase-keys "^1.0.0" 2203 | 2204 | retry@^0.12.0: 2205 | version "0.12.0" 2206 | resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" 2207 | integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= 2208 | 2209 | rimraf@2.6.3: 2210 | version "2.6.3" 2211 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" 2212 | integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== 2213 | dependencies: 2214 | glob "^7.1.3" 2215 | 2216 | safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 2217 | version "5.1.2" 2218 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 2219 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 2220 | 2221 | safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2: 2222 | version "5.2.1" 2223 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 2224 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 2225 | 2226 | "safer-buffer@>= 2.1.2 < 3": 2227 | version "2.1.2" 2228 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 2229 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 2230 | 2231 | saslprep@^1.0.0: 2232 | version "1.0.3" 2233 | resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226" 2234 | integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag== 2235 | dependencies: 2236 | sparse-bitfield "^3.0.3" 2237 | 2238 | semver-compare@^1.0.0: 2239 | version "1.0.0" 2240 | resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" 2241 | integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= 2242 | 2243 | semver-diff@^3.1.1: 2244 | version "3.1.1" 2245 | resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" 2246 | integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== 2247 | dependencies: 2248 | semver "^6.3.0" 2249 | 2250 | semver@^5.1.0, semver@^5.6.0, semver@^5.7.1: 2251 | version "5.7.1" 2252 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 2253 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 2254 | 2255 | semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: 2256 | version "6.3.0" 2257 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" 2258 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== 2259 | 2260 | semver@^7.2.1, semver@^7.3.2: 2261 | version "7.3.2" 2262 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" 2263 | integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== 2264 | 2265 | send@0.17.1: 2266 | version "0.17.1" 2267 | resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" 2268 | integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== 2269 | dependencies: 2270 | debug "2.6.9" 2271 | depd "~1.1.2" 2272 | destroy "~1.0.4" 2273 | encodeurl "~1.0.2" 2274 | escape-html "~1.0.3" 2275 | etag "~1.8.1" 2276 | fresh "0.5.2" 2277 | http-errors "~1.7.2" 2278 | mime "1.6.0" 2279 | ms "2.1.1" 2280 | on-finished "~2.3.0" 2281 | range-parser "~1.2.1" 2282 | statuses "~1.5.0" 2283 | 2284 | serve-static@1.14.1: 2285 | version "1.14.1" 2286 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" 2287 | integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== 2288 | dependencies: 2289 | encodeurl "~1.0.2" 2290 | escape-html "~1.0.3" 2291 | parseurl "~1.3.3" 2292 | send "0.17.1" 2293 | 2294 | setprototypeof@1.1.1: 2295 | version "1.1.1" 2296 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" 2297 | integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== 2298 | 2299 | shebang-command@^2.0.0: 2300 | version "2.0.0" 2301 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 2302 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 2303 | dependencies: 2304 | shebang-regex "^3.0.0" 2305 | 2306 | shebang-regex@^3.0.0: 2307 | version "3.0.0" 2308 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 2309 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 2310 | 2311 | sift@7.0.1: 2312 | version "7.0.1" 2313 | resolved "https://registry.yarnpkg.com/sift/-/sift-7.0.1.tgz#47d62c50b159d316f1372f8b53f9c10cd21a4b08" 2314 | integrity sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g== 2315 | 2316 | signal-exit@^3.0.2: 2317 | version "3.0.3" 2318 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" 2319 | integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== 2320 | 2321 | slice-ansi@^2.1.0: 2322 | version "2.1.0" 2323 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" 2324 | integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== 2325 | dependencies: 2326 | ansi-styles "^3.2.0" 2327 | astral-regex "^1.0.0" 2328 | is-fullwidth-code-point "^2.0.0" 2329 | 2330 | sliced@1.0.1: 2331 | version "1.0.1" 2332 | resolved "https://registry.yarnpkg.com/sliced/-/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41" 2333 | integrity sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E= 2334 | 2335 | source-map-support@^0.5.17: 2336 | version "0.5.19" 2337 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" 2338 | integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== 2339 | dependencies: 2340 | buffer-from "^1.0.0" 2341 | source-map "^0.6.0" 2342 | 2343 | source-map@^0.6.0: 2344 | version "0.6.1" 2345 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 2346 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 2347 | 2348 | sparse-bitfield@^3.0.3: 2349 | version "3.0.3" 2350 | resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" 2351 | integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE= 2352 | dependencies: 2353 | memory-pager "^1.0.2" 2354 | 2355 | sprintf-js@~1.0.2: 2356 | version "1.0.3" 2357 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 2358 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 2359 | 2360 | standard-as-callback@^2.0.1: 2361 | version "2.0.1" 2362 | resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.0.1.tgz#ed8bb25648e15831759b6023bdb87e6b60b38126" 2363 | integrity sha512-NQOxSeB8gOI5WjSaxjBgog2QFw55FV8TkS6Y07BiB3VJ8xNTvUYm0wl0s8ObgQ5NhdpnNfigMIKjgPESzgr4tg== 2364 | 2365 | "statuses@>= 1.5.0 < 2", statuses@~1.5.0: 2366 | version "1.5.0" 2367 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 2368 | integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= 2369 | 2370 | string-width@^3.0.0: 2371 | version "3.1.0" 2372 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" 2373 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== 2374 | dependencies: 2375 | emoji-regex "^7.0.1" 2376 | is-fullwidth-code-point "^2.0.0" 2377 | strip-ansi "^5.1.0" 2378 | 2379 | string-width@^4.0.0, string-width@^4.1.0: 2380 | version "4.2.0" 2381 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" 2382 | integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== 2383 | dependencies: 2384 | emoji-regex "^8.0.0" 2385 | is-fullwidth-code-point "^3.0.0" 2386 | strip-ansi "^6.0.0" 2387 | 2388 | string.prototype.trimend@^1.0.1: 2389 | version "1.0.1" 2390 | resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" 2391 | integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== 2392 | dependencies: 2393 | define-properties "^1.1.3" 2394 | es-abstract "^1.17.5" 2395 | 2396 | string.prototype.trimstart@^1.0.1: 2397 | version "1.0.1" 2398 | resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" 2399 | integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== 2400 | dependencies: 2401 | define-properties "^1.1.3" 2402 | es-abstract "^1.17.5" 2403 | 2404 | string_decoder@~1.1.1: 2405 | version "1.1.1" 2406 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 2407 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 2408 | dependencies: 2409 | safe-buffer "~5.1.0" 2410 | 2411 | strip-ansi@^5.1.0: 2412 | version "5.2.0" 2413 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" 2414 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== 2415 | dependencies: 2416 | ansi-regex "^4.1.0" 2417 | 2418 | strip-ansi@^6.0.0: 2419 | version "6.0.0" 2420 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" 2421 | integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== 2422 | dependencies: 2423 | ansi-regex "^5.0.0" 2424 | 2425 | strip-json-comments@^3.1.0: 2426 | version "3.1.1" 2427 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 2428 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 2429 | 2430 | strip-json-comments@~2.0.1: 2431 | version "2.0.1" 2432 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 2433 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 2434 | 2435 | supports-color@^5.3.0, supports-color@^5.5.0: 2436 | version "5.5.0" 2437 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 2438 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 2439 | dependencies: 2440 | has-flag "^3.0.0" 2441 | 2442 | supports-color@^7.1.0: 2443 | version "7.1.0" 2444 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" 2445 | integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== 2446 | dependencies: 2447 | has-flag "^4.0.0" 2448 | 2449 | table@^5.2.3: 2450 | version "5.4.6" 2451 | resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" 2452 | integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== 2453 | dependencies: 2454 | ajv "^6.10.2" 2455 | lodash "^4.17.14" 2456 | slice-ansi "^2.1.0" 2457 | string-width "^3.0.0" 2458 | 2459 | term-size@^2.1.0: 2460 | version "2.2.0" 2461 | resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.0.tgz#1f16adedfe9bdc18800e1776821734086fcc6753" 2462 | integrity sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw== 2463 | 2464 | text-table@^0.2.0: 2465 | version "0.2.0" 2466 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 2467 | integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= 2468 | 2469 | to-readable-stream@^1.0.0: 2470 | version "1.0.0" 2471 | resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" 2472 | integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== 2473 | 2474 | to-regex-range@^5.0.1: 2475 | version "5.0.1" 2476 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 2477 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 2478 | dependencies: 2479 | is-number "^7.0.0" 2480 | 2481 | toidentifier@1.0.0: 2482 | version "1.0.0" 2483 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" 2484 | integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== 2485 | 2486 | touch@^3.1.0: 2487 | version "3.1.0" 2488 | resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" 2489 | integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== 2490 | dependencies: 2491 | nopt "~1.0.10" 2492 | 2493 | ts-node@^8.10.2: 2494 | version "8.10.2" 2495 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" 2496 | integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA== 2497 | dependencies: 2498 | arg "^4.1.0" 2499 | diff "^4.0.1" 2500 | make-error "^1.1.1" 2501 | source-map-support "^0.5.17" 2502 | yn "3.1.1" 2503 | 2504 | tslib@^1.8.1: 2505 | version "1.13.0" 2506 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" 2507 | integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== 2508 | 2509 | tsscmp@^1.0.6: 2510 | version "1.0.6" 2511 | resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" 2512 | integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== 2513 | 2514 | tsutils@^3.17.1: 2515 | version "3.17.1" 2516 | resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" 2517 | integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== 2518 | dependencies: 2519 | tslib "^1.8.1" 2520 | 2521 | type-check@^0.4.0, type-check@~0.4.0: 2522 | version "0.4.0" 2523 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" 2524 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 2525 | dependencies: 2526 | prelude-ls "^1.2.1" 2527 | 2528 | type-fest@^0.8.1: 2529 | version "0.8.1" 2530 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" 2531 | integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== 2532 | 2533 | type-is@~1.6.17, type-is@~1.6.18: 2534 | version "1.6.18" 2535 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" 2536 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== 2537 | dependencies: 2538 | media-typer "0.3.0" 2539 | mime-types "~2.1.24" 2540 | 2541 | typedarray-to-buffer@^3.1.5: 2542 | version "3.1.5" 2543 | resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" 2544 | integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== 2545 | dependencies: 2546 | is-typedarray "^1.0.0" 2547 | 2548 | typescript@^3.9.7: 2549 | version "3.9.7" 2550 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" 2551 | integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== 2552 | 2553 | undefsafe@^2.0.2: 2554 | version "2.0.3" 2555 | resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" 2556 | integrity sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A== 2557 | dependencies: 2558 | debug "^2.2.0" 2559 | 2560 | unique-string@^2.0.0: 2561 | version "2.0.0" 2562 | resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" 2563 | integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== 2564 | dependencies: 2565 | crypto-random-string "^2.0.0" 2566 | 2567 | unpipe@1.0.0, unpipe@~1.0.0: 2568 | version "1.0.0" 2569 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 2570 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= 2571 | 2572 | update-notifier@^4.0.0: 2573 | version "4.1.0" 2574 | resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.0.tgz#4866b98c3bc5b5473c020b1250583628f9a328f3" 2575 | integrity sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew== 2576 | dependencies: 2577 | boxen "^4.2.0" 2578 | chalk "^3.0.0" 2579 | configstore "^5.0.1" 2580 | has-yarn "^2.1.0" 2581 | import-lazy "^2.1.0" 2582 | is-ci "^2.0.0" 2583 | is-installed-globally "^0.3.1" 2584 | is-npm "^4.0.0" 2585 | is-yarn-global "^0.3.0" 2586 | latest-version "^5.0.0" 2587 | pupa "^2.0.1" 2588 | semver-diff "^3.1.1" 2589 | xdg-basedir "^4.0.0" 2590 | 2591 | uri-js@^4.2.2: 2592 | version "4.2.2" 2593 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" 2594 | integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== 2595 | dependencies: 2596 | punycode "^2.1.0" 2597 | 2598 | url-parse-lax@^3.0.0: 2599 | version "3.0.0" 2600 | resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" 2601 | integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= 2602 | dependencies: 2603 | prepend-http "^2.0.0" 2604 | 2605 | util-deprecate@~1.0.1: 2606 | version "1.0.2" 2607 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 2608 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 2609 | 2610 | utils-merge@1.0.1: 2611 | version "1.0.1" 2612 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 2613 | integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= 2614 | 2615 | v8-compile-cache@^2.0.3: 2616 | version "2.1.1" 2617 | resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" 2618 | integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== 2619 | 2620 | vary@~1.1.2: 2621 | version "1.1.2" 2622 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 2623 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 2624 | 2625 | which@^2.0.1: 2626 | version "2.0.2" 2627 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 2628 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 2629 | dependencies: 2630 | isexe "^2.0.0" 2631 | 2632 | widest-line@^3.1.0: 2633 | version "3.1.0" 2634 | resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" 2635 | integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== 2636 | dependencies: 2637 | string-width "^4.0.0" 2638 | 2639 | word-wrap@^1.2.3: 2640 | version "1.2.3" 2641 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" 2642 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== 2643 | 2644 | wrappy@1: 2645 | version "1.0.2" 2646 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 2647 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 2648 | 2649 | write-file-atomic@^3.0.0: 2650 | version "3.0.3" 2651 | resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" 2652 | integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== 2653 | dependencies: 2654 | imurmurhash "^0.1.4" 2655 | is-typedarray "^1.0.0" 2656 | signal-exit "^3.0.2" 2657 | typedarray-to-buffer "^3.1.5" 2658 | 2659 | write@1.0.3: 2660 | version "1.0.3" 2661 | resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" 2662 | integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== 2663 | dependencies: 2664 | mkdirp "^0.5.1" 2665 | 2666 | xdg-basedir@^4.0.0: 2667 | version "4.0.0" 2668 | resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" 2669 | integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== 2670 | 2671 | yn@3.1.1: 2672 | version "3.1.1" 2673 | resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" 2674 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 2675 | --------------------------------------------------------------------------------