├── .gitignore ├── .npmignore ├── src ├── transcripts │ ├── index.ts │ ├── transcript.interfaces.ts │ └── transcript.ts ├── pagination │ ├── index.ts │ ├── pagination.interfaces.ts │ └── pagination.ts ├── modmail │ ├── index.ts │ ├── modmail.interface.ts │ └── modmail.ts ├── giveaways │ ├── index.ts │ ├── giveaways.interfaces.ts │ └── giveaways.ts ├── starboard │ ├── index.ts │ ├── starboard.interfaces.ts │ └── starboard.ts ├── structures │ └── command.ts ├── index.ts ├── functions │ └── chatBot.ts └── database │ └── reconDB.ts ├── .prettierrc.json ├── .github └── workflows │ ├── publish.yml │ └── docs.yml ├── tsconfig.json ├── package.json ├── README.md ├── yarn-error.log ├── assets ├── template.html └── index.html └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | docs 4 | tests -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | docs/ 3 | tests/ 4 | tsconfig.json -------------------------------------------------------------------------------- /src/transcripts/index.ts: -------------------------------------------------------------------------------- 1 | export { generateTranscript } from "./transcript" 2 | export { Message, TranscriptOptions } from "./transcript.interfaces" 3 | -------------------------------------------------------------------------------- /src/pagination/index.ts: -------------------------------------------------------------------------------- 1 | export { pagination } from "./pagination" 2 | export { Button, ButtonNames, PaginationOptions } from "./pagination.interfaces" 3 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "endOfLine": "lf", 4 | "semi": false, 5 | "tabWidth": 4, 6 | "trailingComma": "none" 7 | } 8 | -------------------------------------------------------------------------------- /src/modmail/index.ts: -------------------------------------------------------------------------------- 1 | export { ModMailClient } from "./modmail" 2 | export { 3 | CloseMailSessionOptions, 4 | ModMailModelOptions, 5 | ModMailOptions 6 | } from "./modmail.interface" 7 | -------------------------------------------------------------------------------- /src/giveaways/index.ts: -------------------------------------------------------------------------------- 1 | export { GiveawayClient } from "./giveaways" 2 | export { 3 | GiveawayClientOptions, 4 | GiveawayClientSchema, 5 | StartOptions 6 | } from "./giveaways.interfaces" 7 | -------------------------------------------------------------------------------- /src/starboard/index.ts: -------------------------------------------------------------------------------- 1 | export { StarboardClient } from "./starboard" 2 | export { 3 | StarboardClientOptions, 4 | StarboardGuild, 5 | StarboardGuildOptions, 6 | starMessageData 7 | } from "./starboard.interfaces" 8 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | on: push 3 | 4 | jobs: 5 | publish: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v1 9 | - uses: actions/setup-node@v1 10 | with: 11 | node-version: 14 12 | - run: npm install 13 | - run: npm run build 14 | - uses: JS-DevTools/npm-publish@v1 15 | with: 16 | token: ${{ secrets.NPM_TOKEN }} 17 | -------------------------------------------------------------------------------- /src/transcripts/transcript.interfaces.ts: -------------------------------------------------------------------------------- 1 | export interface Message { 2 | author: { 3 | displayAvatarURL(): string 4 | tag: string 5 | } 6 | createdAt: Date 7 | content: string 8 | [key: string]: any 9 | } 10 | 11 | export interface TranscriptOptions { 12 | guild: { 13 | name: string 14 | iconURL(): string 15 | [key: string]: any 16 | } 17 | channel: { 18 | name: string 19 | [key: string]: any 20 | } 21 | messages: Message[] 22 | } 23 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ESNext"], 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "target": "ESNext", 7 | "declaration": true, 8 | "outDir": "dist", 9 | "sourceMap": true, 10 | "esModuleInterop": true, 11 | "experimentalDecorators": true, 12 | "emitDecoratorMetadata": true, 13 | "allowSyntheticDefaultImports": true, 14 | "skipLibCheck": true, 15 | "skipDefaultLibCheck": true, 16 | "resolveJsonModule": true 17 | }, 18 | "include": ["./src"], 19 | "exclude": ["./node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /src/structures/command.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChatInputApplicationCommandData, 3 | Client, 4 | CommandInteraction, 5 | GuildMember, 6 | PermissionResolvable 7 | } from "discord.js" 8 | 9 | export interface RunOptions { 10 | client: Client 11 | interaction: CommandInteraction & { member: GuildMember } 12 | args: Array 13 | } 14 | 15 | export type RunFunction = (options: RunOptions) => any 16 | 17 | export type CommandOptions = { 18 | userPermissions?: PermissionResolvable[] 19 | run: RunFunction 20 | } & ChatInputApplicationCommandData 21 | 22 | export class Command { 23 | constructor(commandOptions: CommandOptions) { 24 | Object.assign(this, commandOptions) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/starboard/starboard.interfaces.ts: -------------------------------------------------------------------------------- 1 | import { Client, Snowflake } from "discord.js" 2 | 3 | export interface StarboardClientOptions { 4 | /** 5 | * Discord Client 6 | */ 7 | client: Client 8 | 9 | /** 10 | * Preload data 11 | */ 12 | Guilds?: StarboardGuild[] 13 | } 14 | 15 | export interface StarboardGuild { 16 | id: Snowflake 17 | options: StarboardGuildOptions 18 | } 19 | 20 | export interface StarboardGuildOptions { 21 | /** 22 | * Amount of stars required in order to be registered as a starred channel 23 | */ 24 | starCount: number 25 | 26 | /** 27 | * Channel to send starred messages 28 | */ 29 | starboardChannel: Snowflake 30 | } 31 | 32 | export interface starMessageData { 33 | origin: Snowflake 34 | id: Snowflake 35 | } 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reconlx", 3 | "version": "2.5.6", 4 | "main": "dist/index.js", 5 | "types": "dist/index.d.ts", 6 | "license": "MIT", 7 | "author": { 8 | "name": "reconlx" 9 | }, 10 | "repository": { 11 | "url": "https://github.com/limxuan/reconlx-api" 12 | }, 13 | "homepage": "https://reconlx.github.io/reconlx-api/", 14 | "engines": { 15 | "node": ">=16.6.0" 16 | }, 17 | "scripts": { 18 | "build": "tsc", 19 | "docs": "typedoc src/index.ts --excludePrivate", 20 | "test": "ts-node tests/index.ts" 21 | }, 22 | "dependencies": { 23 | "axios": "^0.21.1", 24 | "jsdom": "^16.7.0", 25 | "sourcebin": "^4.2.5" 26 | }, 27 | "devDependencies": { 28 | "@types/jsdom": "^16.2.13", 29 | "discord.js": "^13.5.0", 30 | "mongoose": "^6.0.9", 31 | "ts-node": "^10.2.0", 32 | "typedoc": "^0.21.2", 33 | "typescript": "^4.3.5" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // reconDB 2 | export { reconDB, reconDBSchema } from "./database/reconDB" 3 | 4 | // giveaways 5 | export { 6 | GiveawayClientOptions, 7 | GiveawayClientSchema, 8 | StartOptions, 9 | GiveawayClient 10 | } from "./giveaways" 11 | 12 | // transcript 13 | export { generateTranscript, TranscriptOptions, Message } from "./transcripts" 14 | 15 | // pagination 16 | export { 17 | Button, 18 | ButtonNames, 19 | PaginationOptions, 20 | pagination 21 | } from "./pagination" 22 | 23 | // modmail 24 | export { 25 | CloseMailSessionOptions, 26 | ModMailClient, 27 | ModMailModelOptions, 28 | ModMailOptions 29 | } from "./modmail" 30 | 31 | // starboard 32 | export { 33 | StarboardClient, 34 | StarboardClientOptions, 35 | StarboardGuild, 36 | StarboardGuildOptions, 37 | starMessageData 38 | } from "./starboard" 39 | 40 | // functions 41 | export { chatBot, ChatBotOptions } from "./functions/chatBot" 42 | 43 | // structures 44 | export { 45 | Command, 46 | CommandOptions, 47 | RunFunction, 48 | RunOptions 49 | } from "./structures/command" 50 | -------------------------------------------------------------------------------- /src/functions/chatBot.ts: -------------------------------------------------------------------------------- 1 | import { Message } from "discord.js" 2 | import axios from "axios" 3 | 4 | export interface ChatBotOptions { 5 | /** 6 | * discord.js message class 7 | */ 8 | message: Message 9 | 10 | /** 11 | * input for the chatBot 12 | */ 13 | input: string 14 | 15 | /** 16 | * defaults to author's id 17 | */ 18 | uuid: string 19 | } 20 | 21 | /** 22 | * @method 23 | * @description An easy chatbot without api key 24 | */ 25 | export const chatBot = (options: ChatBotOptions): Promise => { 26 | const { message, input, uuid } = options 27 | const baseUrl = `https://api.monkedev.com/fun/chat` 28 | 29 | return new Promise(async (ful, rej) => { 30 | try { 31 | const res = await axios.get( 32 | `${baseUrl}?msg=${encodeURIComponent(input)}&uid=${ 33 | uuid || message.author.id 34 | }` 35 | ) 36 | 37 | if (!res.data) rej("an error occured!") 38 | 39 | ful(res.data) 40 | } catch (err) { 41 | rej(err) 42 | } 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /src/pagination/pagination.interfaces.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ButtonInteraction, 3 | MessageEmbed, 4 | TextChannel, 5 | User 6 | } from "discord.js" 7 | 8 | export interface PaginationOptions { 9 | /** 10 | * TextChannel to send to 11 | */ 12 | channel: TextChannel 13 | 14 | /** 15 | * Author's user class 16 | */ 17 | author: User 18 | 19 | /** 20 | * array of embed messages to paginate 21 | */ 22 | embeds: MessageEmbed[] 23 | 24 | /** 25 | * customize your buttons! 26 | */ 27 | button?: Button[] 28 | 29 | /** 30 | * travel pages by sending page numbers? 31 | */ 32 | pageTravel?: boolean 33 | 34 | /** 35 | * two additional buttons, a button to skip to the end and a button to skip to the first page 36 | */ 37 | fastSkip?: boolean 38 | 39 | /** 40 | * how long before buttons get disabled 41 | */ 42 | time?: number 43 | 44 | /** 45 | * maximum interactions before disabling the pagination 46 | */ 47 | max?: number 48 | /** 49 | * custom filter for message component collector 50 | */ 51 | customFilter?(interaction: ButtonInteraction): boolean 52 | } 53 | export type ButtonNames = "first" | "previous" | "next" | "last" | "number" 54 | 55 | export interface Button { 56 | name: ButtonNames 57 | emoji?: string 58 | style?: "PRIMARY" | "SECONDARY" | "SUCCESS" | "DANGER" 59 | } 60 | -------------------------------------------------------------------------------- /src/giveaways/giveaways.interfaces.ts: -------------------------------------------------------------------------------- 1 | import { Client, ColorResolvable, TextChannel, User } from "discord.js" 2 | 3 | export interface StartOptions { 4 | /** 5 | * Channel for the giveaway to be in 6 | */ 7 | channel: TextChannel 8 | 9 | /** 10 | * Duration of this giveaway 11 | */ 12 | time: number 13 | 14 | /** 15 | * Person that hosted the giveaway 16 | */ 17 | hostedBy: User 18 | 19 | /** 20 | * Description of the giveaway 21 | */ 22 | description: string 23 | 24 | /** 25 | * Amount of winners for the giveaway 26 | */ 27 | winners: number 28 | 29 | /** 30 | * Prize for the giveaway 31 | */ 32 | prize: string 33 | } 34 | 35 | export interface GiveawayClientSchema { 36 | MessageID: string 37 | EndsAt: number 38 | Guild: string 39 | Channel: string 40 | winners: number 41 | prize: string 42 | description: string 43 | hostedBy: string 44 | Activated: boolean 45 | } 46 | 47 | export interface GiveawayClientOptions { 48 | /** 49 | * discord.js client 50 | */ 51 | client: Client 52 | 53 | /** 54 | * mongodb compass connection string 55 | */ 56 | mongooseConnectionString: string 57 | 58 | /** 59 | * reaction emoji 60 | */ 61 | emoji?: string 62 | 63 | /** 64 | * default color for embeds 65 | */ 66 | defaultColor?: ColorResolvable 67 | } 68 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: GitHub Pages 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the master branch 8 | push: 9 | branches: [master] 10 | 11 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 12 | jobs: 13 | # This workflow contains a single job called "generate-docs" 14 | generate-docs: 15 | # The type of runner that the job will run on 16 | runs-on: ubuntu-latest 17 | 18 | # Steps represent a sequence of tasks that will be executed as part of the job 19 | steps: 20 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 21 | - uses: actions/checkout@v2 22 | 23 | - name: Use Node.js 14.x 24 | uses: actions/setup-node@v2.2.0 25 | with: 26 | node-version: 14.x 27 | 28 | - name: Install the dependencies 29 | run: npm install 30 | 31 | - name: Generate the documentation 32 | run: npm run docs 33 | 34 | - name: Deploy to GitHub Pages 35 | uses: peaceiris/actions-gh-pages@v3 36 | with: 37 | github_token: ${{ secrets.GITHUB_TOKEN }} 38 | publish_dir: ./docs 39 | force_orphan: true 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ❔ reconlx 2 | 3 | A simple api to configure and enhance the ways on coding your discord bot. Compatible with discord.js v13. 4 | 5 |
6 |

7 | Discord Banner 4 8 |

9 |
10 |
11 |

12 | NPM info 14 |

15 |
16 | 17 | ## 🛠 Usages (Click on it for more info on how to use it) 18 | 19 | - [Giveaways](https://reconlx.github.io/reconlx-api/classes/GiveawayClient.html) - Easy giveaway system with mongodb as the database 20 | - [reconDB](https://reconlx.github.io/reconlx-api/classes/reconDB.html) - Storing data into mongodb with easy functions (`.get`, `.set`, `.delete`, `.push`), data are cached for faster response times. 21 | - [ModMail](https://reconlx.github.io/reconlx-api/classes/ModMailClient.html) - Easy way to setup a modmail with awesome customisations 22 | - [starboard](https://reconlx.github.io/reconlx-api/classes/StarboardClient.html) - A starboard system which doesn't fetch 100 messages everytime someone reacts lmfao 23 | - [pagination](https://reconlx.github.io/reconlx-api/modules.html#pagination) - Easy and flexible way to paginate embeds with buttons! 24 | - [generateTranscript](https://reconlx.github.io/reconlx-api/modules.html#generateTranscript) - Easily generate a discord like transcript with an array of _[messages](https://reconlx.github.io/reconlx-api/interfaces/Message.html)_ 25 | - [chatBot](https://reconlx.github.io/reconlx-api/modules.html#chatBot) - An easy chatbot without api key 26 | 27 | more features coming soon! 28 | 29 | ps: if you are looking for the old features, use `npm i reconlx@version1` instead! 30 | -------------------------------------------------------------------------------- /src/modmail/modmail.interface.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Client, 3 | ColorResolvable, 4 | Message, 5 | MessageOptions, 6 | MessagePayload, 7 | Snowflake, 8 | User 9 | } from "discord.js" 10 | 11 | type msg = string | MessagePayload | MessageOptions 12 | 13 | export interface ModMailOptions { 14 | /** 15 | * connection string for mongoose 16 | */ 17 | mongooseConnectionString: string 18 | 19 | /** 20 | * main guild id 21 | */ 22 | guildId: Snowflake 23 | 24 | /** 25 | * category to create modmail channels in 26 | */ 27 | category: Snowflake 28 | 29 | /** 30 | * your discord.js client 31 | */ 32 | client: Client 33 | 34 | /** 35 | * a role that can view modmail tickets 36 | */ 37 | modmailRole?: Snowflake 38 | 39 | /** 40 | * a channel where transcripts are sent to 41 | */ 42 | transcriptChannel?: Snowflake 43 | 44 | /** 45 | * custom messages 46 | */ 47 | custom?: { 48 | /** 49 | * sourcebin language for transcript 50 | */ 51 | language?: string 52 | 53 | /** 54 | * color for embeds 55 | */ 56 | embedColor?: ColorResolvable 57 | 58 | /** 59 | * initial message to created channel when a new mail is opened 60 | */ 61 | channel?: (user: User) => msg 62 | 63 | /** 64 | * inital message sent to user when the user created a new modmail 65 | */ 66 | user?: (user: User) => msg 67 | 68 | /** 69 | * how do you want your message to look? 70 | */ 71 | saveMessageFormat?: (message: Message) => string 72 | } 73 | } 74 | 75 | export interface ModMailModelOptions { 76 | User: Snowflake 77 | Channel: Snowflake 78 | Messages: string[] 79 | } 80 | 81 | export interface CloseMailSessionOptions { 82 | channel: Snowflake 83 | reason: string 84 | } 85 | -------------------------------------------------------------------------------- /yarn-error.log: -------------------------------------------------------------------------------- 1 | Arguments: 2 | /usr/local/bin/node /usr/local/bin/yarn install 3 | 4 | PATH: 5 | /Users/limxuan/.cargo/bin:/Library/Frameworks/Python.framework/Versions/3.10/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/limxuan/.cargo/bin:/Library/Frameworks/Python.framework/Versions/3.10/bin 6 | 7 | Yarn version: 8 | 1.22.11 9 | 10 | Node version: 11 | 16.13.0 12 | 13 | Platform: 14 | darwin arm64 15 | 16 | Trace: 17 | SyntaxError: /Users/limxuan/Documents/github/reconlx-api/package.json: Unexpected token } in JSON at position 856 18 | at JSON.parse () 19 | at /usr/local/lib/node_modules/yarn/lib/cli.js:1625:59 20 | at Generator.next () 21 | at step (/usr/local/lib/node_modules/yarn/lib/cli.js:310:30) 22 | at /usr/local/lib/node_modules/yarn/lib/cli.js:321:13 23 | 24 | npm manifest: 25 | { 26 | "name": "reconlx", 27 | "version": "2.5.2", 28 | "main": "dist/index.js", 29 | "types": "dist/index.d.ts", 30 | "license": "MIT", 31 | "author": { 32 | "name": "reconlx" 33 | }, 34 | "repository": { 35 | "url": "https://github.com/reconlx/reconlx-api" 36 | }, 37 | "homepage": "https://reconlx.github.io/reconlx-api/", 38 | "engines": { 39 | "node": ">=16.6.0" 40 | }, 41 | "scripts": { 42 | "build": "tsc", 43 | "docs": "typedoc src/index.ts --excludePrivate", 44 | "test": "ts-node tests/index.ts" 45 | }, 46 | "dependencies": { 47 | "axios": "^0.21.1", 48 | "jsdom": "^16.7.0", 49 | "sourcebin": "^4.2.5" 50 | }, 51 | "devDependencies": { 52 | "@types/jsdom": "^16.2.13", 53 | "discord.js": "^13.5.0", 54 | "mongoose": "^6.0.9", 55 | "ts-node": "^10.2.0", 56 | "typedoc": "^0.21.2", 57 | "typescript": "^4.3.5" 58 | }, 59 | } 60 | 61 | yarn manifest: 62 | No manifest 63 | 64 | Lockfile: 65 | No lockfile 66 | -------------------------------------------------------------------------------- /assets/template.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/index.html: -------------------------------------------------------------------------------- 1 | 86 |
87 |
88 | 90 |
91 | 96 |
97 |
98 |
99 | 101 |
102 |
103 | recon#8448 Tue Aug 10 2021 10:40:34 AM ESThello world 104 |
105 |
-------------------------------------------------------------------------------- /src/database/reconDB.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema } from "mongoose" 2 | import { Client, Collection } from "discord.js" 3 | 4 | interface reconDBEvents { 5 | ready: (reconDB: reconDB) => unknown 6 | } 7 | 8 | export class reconDB { 9 | public schema = mongoose.model( 10 | "recondb-collection", 11 | new Schema({ 12 | key: String, 13 | value: mongoose.SchemaTypes.Mixed 14 | }) 15 | ) 16 | public dbCollection: Collection = new Collection() 17 | public client: Client 18 | 19 | /** 20 | * @name reconDB 21 | * @kind constructor 22 | * @param {reconDBOptions} options options to use the database 23 | */ 24 | 25 | constructor(mongooseConnectionString: string) { 26 | if (mongoose.connection.readyState !== 1) { 27 | if (!mongooseConnectionString) 28 | throw new Error( 29 | "There is no established connection with mongoose and a mongoose connection is required!" 30 | ) 31 | 32 | mongoose.connect(mongooseConnectionString) 33 | } 34 | this.ready() 35 | } 36 | 37 | private async ready() { 38 | await this.schema.find({}).then((data) => { 39 | data.forEach(({ key, value }) => { 40 | this.dbCollection.set(key, value) 41 | }) 42 | }) 43 | } 44 | 45 | /** 46 | * @method 47 | * @param key The key, so you can get it with .get("key") 48 | * @param value value The value which will be saved to the key 49 | * @description saves data to mongodb 50 | * @example .set("test","js is cool") 51 | */ 52 | public set(key: string, value: any) { 53 | if (!key || !value) return 54 | this.schema.findOne({ key }, async (err, data) => { 55 | if (err) throw err 56 | if (data) data.value = value 57 | else data = new this.schema({ key, value }) 58 | 59 | data.save() 60 | this.dbCollection.set(key, value) 61 | }) 62 | } 63 | 64 | /** 65 | * @method 66 | * @param key They key you wish to delete 67 | * @description Removes data from mongodb 68 | * @example .delete("test") 69 | */ 70 | public delete(key: string) { 71 | if (!key) return 72 | this.schema.findOne({ key }, async (err, data) => { 73 | if (err) throw err 74 | if (data) await data.delete() 75 | }) 76 | this.dbCollection.delete(key) 77 | } 78 | 79 | /** 80 | * @method 81 | * @param key The key you wish to get data 82 | * @description Gets data from the database with a key 83 | * @example .get('key1') 84 | */ 85 | public get(key: string): any { 86 | if (!key) return 87 | return this.dbCollection.get(key) 88 | } 89 | 90 | /** 91 | * @method 92 | * @param key The key you wish to push data to 93 | * @description Push data to the an array with a key 94 | * @example 95 | */ 96 | public push(key: string, ...pushValue: any) { 97 | const data = this.dbCollection.get(key) 98 | const values = pushValue.flat() 99 | if (!Array.isArray(data)) 100 | throw Error(`You cant push data to a ${typeof data} value!`) 101 | 102 | data.push(pushValue) 103 | this.schema.findOne({ key }, async (err, res) => { 104 | res.value = [...res.value, ...values] 105 | res.save() 106 | }) 107 | } 108 | 109 | /** 110 | * @method 111 | * @returns Cached data with discord.js collection 112 | */ 113 | public collection(): Collection { 114 | return this.dbCollection 115 | } 116 | } 117 | 118 | export interface reconDBSchema { 119 | key: string 120 | value: any 121 | } 122 | -------------------------------------------------------------------------------- /src/starboard/starboard.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Client, 3 | MessageReaction, 4 | Collection, 5 | Snowflake, 6 | TextChannel, 7 | Message, 8 | MessageEmbed, 9 | MessageOptions 10 | } from "discord.js" 11 | import { 12 | starMessageData, 13 | StarboardClientOptions, 14 | StarboardGuild 15 | } from "./starboard.interfaces" 16 | 17 | export class StarboardClient { 18 | public client: Client 19 | public guilds: StarboardGuild[] 20 | public cache: Collection = new Collection() 21 | 22 | constructor(options: StarboardClientOptions) { 23 | this.client = options.client 24 | this.guilds = options.Guilds || [] 25 | this.client.on("ready", () => this.cacheData()) 26 | } 27 | 28 | public config = { 29 | guilds: { 30 | set: (StarboardGuilds: StarboardGuild[]) => { 31 | this.guilds = StarboardGuilds 32 | this.cacheData() 33 | }, 34 | 35 | add: (StarboardGuild: StarboardGuild) => { 36 | const filtered = (this.guilds || []).filter( 37 | (x) => x.id === StarboardGuild.id 38 | ) 39 | 40 | this.guilds = [...filtered, StarboardGuild] 41 | this.cacheData() 42 | } 43 | } 44 | } 45 | 46 | private cacheData() { 47 | this.guilds.forEach(async (guild) => { 48 | const channel = this.client.channels.cache.get( 49 | guild.options.starboardChannel 50 | ) as TextChannel 51 | if (!channel) return 52 | 53 | const messages = await channel.messages.fetch({ limit: 100 }) 54 | if (!messages) return 55 | 56 | const value = messages.reduce( 57 | (accumulator: starMessageData[], message) => { 58 | if (message.author.id !== this.client.user.id) 59 | return accumulator 60 | 61 | const starCount = 62 | message.content.match(/(?<=\*\*)\d*(?=\*\*)/)?.[0] 63 | 64 | const origin = 65 | message.embeds?.[0]?.footer?.text.match(/\d*/)?.[0] 66 | 67 | if (!starCount || !origin) return accumulator 68 | 69 | const data: starMessageData = { 70 | id: message.id, 71 | origin 72 | } 73 | return [...accumulator, data] 74 | }, 75 | [] 76 | ) 77 | this.cache.set(guild.id, value) 78 | }) 79 | } 80 | 81 | private validGuild(guild: Snowflake) { 82 | return this.guilds.some((x) => x.id === guild) 83 | } 84 | 85 | private getData(guildId: Snowflake) { 86 | return this.guilds.find((x) => x.id === guildId) 87 | } 88 | 89 | private generateEdit(starCount: number, message: Message): MessageOptions { 90 | return { 91 | content: `⭐ **${starCount}** ${message.channel}`, 92 | embeds: [ 93 | new MessageEmbed() 94 | .setAuthor( 95 | message.author.tag, 96 | message.author.displayAvatarURL({ dynamic: true }) 97 | ) 98 | .setColor("#fcc444") 99 | .setDescription(message.content) 100 | .addField("Source", `[Jump!](${message.url})`) 101 | .setImage(message.attachments.first()?.url || null) 102 | .setFooter({ 103 | text: `${ 104 | message.id 105 | } • ${message.createdAt.toLocaleDateString()}` 106 | }) 107 | ] 108 | } 109 | } 110 | 111 | public async listener(reaction: MessageReaction) { 112 | if (!this.validGuild) return 113 | if (reaction.message.partial) await reaction.message.fetch() 114 | if (reaction.partial) await reaction.fetch() 115 | const { guildId, id } = reaction.message 116 | 117 | if ( 118 | reaction.emoji.name !== "⭐" || 119 | reaction.count < this.getData(guildId)?.options.starCount 120 | ) 121 | return 122 | 123 | const data = this.cache.get(guildId) || [] 124 | const starboardChannel = this.client.channels.cache.get( 125 | this.guilds.find((x) => x.id === guildId)?.options.starboardChannel 126 | ) as TextChannel 127 | const getMessage = data.find((x) => x.origin === id) 128 | const generateEdit = this.generateEdit( 129 | reaction.count, 130 | reaction.message as Message 131 | ) 132 | 133 | const sendMessage = () => { 134 | starboardChannel?.send(generateEdit).then((m) => { 135 | this.cache.set(reaction.message.guildId, [ 136 | ...data, 137 | { id: m.id, origin: reaction.message.id } 138 | ]) 139 | }) 140 | } 141 | if (getMessage) { 142 | starboardChannel.messages 143 | .fetch(getMessage.id) 144 | .then((publishedMessage) => { 145 | publishedMessage.edit(generateEdit) 146 | }) 147 | .catch(sendMessage) 148 | } else sendMessage() 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/pagination/pagination.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ButtonInteraction, 3 | MessageActionRow, 4 | MessageButton, 5 | MessageButtonStyleResolvable, 6 | Message, 7 | MessageComponentType, 8 | MessageEmbed, 9 | MessageCollectorOptions, 10 | InteractionCollector, 11 | Interaction 12 | } from "discord.js" 13 | import { ButtonNames, PaginationOptions } from "./pagination.interfaces" 14 | 15 | const defaultEmojis = { 16 | first: "⬅️", 17 | previous: "◀️", 18 | next: "▶️", 19 | last: "➡️", 20 | number: "#️⃣" 21 | } 22 | 23 | const defaultStyles = { 24 | first: "PRIMARY", 25 | previous: "PRIMARY", 26 | next: "PRIMARY", 27 | last: "PRIMARY", 28 | number: "SUCCESS" 29 | } 30 | 31 | export const pagination = async (options: PaginationOptions) => { 32 | const { 33 | author, 34 | channel, 35 | embeds, 36 | button, 37 | time, 38 | max, 39 | customFilter, 40 | fastSkip, 41 | pageTravel 42 | } = options 43 | let currentPage = 1 44 | 45 | const getButtonData = (name: ButtonNames) => { 46 | return button?.find((btn) => btn.name === name) 47 | } 48 | 49 | const generateButtons = (state?: boolean) => { 50 | const checkState = (name: ButtonNames) => { 51 | if ( 52 | (["first", "previous"] as ButtonNames[]).includes(name) && 53 | currentPage === 1 54 | ) 55 | return true 56 | 57 | if ( 58 | (["next", "last"] as ButtonNames[]).includes(name) && 59 | currentPage === embeds.length 60 | ) 61 | return true 62 | 63 | return false 64 | } 65 | 66 | let names: ButtonNames[] = ["previous", "next"] 67 | if (fastSkip) names = ["first", ...names, "last"] 68 | if (pageTravel) names.push("number") 69 | 70 | return names.reduce( 71 | (accumulator: MessageButton[], name: ButtonNames) => { 72 | accumulator.push( 73 | new MessageButton() 74 | .setEmoji( 75 | getButtonData(name)?.emoji || defaultEmojis[name] 76 | ) 77 | .setCustomId(name) 78 | .setDisabled(state || checkState(name)) 79 | .setStyle( 80 | getButtonData(name)?.style || 81 | (defaultStyles[ 82 | name 83 | ] as MessageButtonStyleResolvable) 84 | ) 85 | ) 86 | return accumulator 87 | }, 88 | [] 89 | ) 90 | } 91 | 92 | const components = (state?: boolean) => [ 93 | new MessageActionRow().addComponents(generateButtons(state)) 94 | ] 95 | 96 | const changeFooter = () => { 97 | const embed = embeds[currentPage - 1] 98 | const newEmbed = new MessageEmbed(embed) 99 | if (embed?.footer?.text) { 100 | return newEmbed.setFooter({ 101 | text: `${embed.footer.text} - Page ${currentPage} of ${embeds.length}`, 102 | iconURL: embed.footer.iconURL 103 | }) 104 | } 105 | return newEmbed.setFooter({ 106 | text: `Page ${currentPage} of ${embeds.length}` 107 | }) 108 | } 109 | 110 | const initialMessage = await channel.send({ 111 | embeds: [changeFooter()], 112 | components: components() 113 | }) 114 | 115 | const defaultFilter = (interaction: ButtonInteraction) => { 116 | if (!interaction.deferred) interaction.deferUpdate() 117 | return interaction.user.id === author.id 118 | } 119 | 120 | const filter = customFilter || defaultFilter 121 | 122 | let message: Message 123 | message.createMessageComponentCollector({ componentType: "BUTTON"}) 124 | 125 | 126 | const collectorOptions = (): any => { 127 | const opt = { 128 | filter, 129 | componentType: "BUTTON" as MessageComponentType 130 | } 131 | 132 | if (max) opt["max"] = max 133 | if (time) opt["time"] = time 134 | 135 | return opt 136 | } 137 | 138 | const collector = channel.createMessageComponentCollector( 139 | collectorOptions() 140 | ) 141 | 142 | const pageTravelling = new Set() 143 | 144 | const numberTravel = async () => { 145 | if (pageTravelling.has(author.id)) 146 | return channel.send("Type `end` to stop page travelling!") 147 | const collector = channel.createMessageCollector({ 148 | filter: (msg) => msg.author.id === author.id, 149 | time: 30000 150 | }) 151 | const numberTravelMessage = await channel.send( 152 | `${author.tag}, you have 30 seconds, send numbers in chat to change pages! Simply type \`end\` to exit from page travelling.` 153 | ) 154 | pageTravelling.add(author.id) 155 | 156 | collector.on("collect", (message) => { 157 | if (message.content.toLowerCase() === "end") { 158 | message.delete().catch(() => {}) 159 | return collector.stop() 160 | } 161 | const int = parseInt(message.content) 162 | if (isNaN(int) || !(int <= embeds.length) || !(int >= 1)) return 163 | currentPage = int 164 | initialMessage.edit({ 165 | embeds: [changeFooter()], 166 | components: components() 167 | }) 168 | if (message.guild.me.permissions.has("MANAGE_MESSAGES")) 169 | message.delete() 170 | }) 171 | 172 | collector.on("end", () => { 173 | if (numberTravelMessage.deletable) numberTravelMessage.delete() 174 | pageTravelling.delete(author.id) 175 | }) 176 | } 177 | 178 | collector.on("collect", async (interaction) => { 179 | const id = interaction.customId as ButtonNames 180 | 181 | if (id === "first") currentPage = 1 182 | if (id === "previous") currentPage-- 183 | if (id === "next") currentPage++ 184 | if (id === "last") currentPage = embeds.length 185 | if (id === "number") await numberTravel() 186 | 187 | initialMessage.edit({ 188 | embeds: [changeFooter()], 189 | components: components() 190 | }) 191 | }) 192 | 193 | collector.on("end", () => { 194 | initialMessage.edit({ 195 | components: components(true) 196 | }) 197 | }) 198 | } 199 | -------------------------------------------------------------------------------- /src/transcripts/transcript.ts: -------------------------------------------------------------------------------- 1 | import { JSDOM } from "jsdom" 2 | import fs from "fs" 3 | import { TranscriptOptions } from "./transcript.interfaces" 4 | import path from "path" 5 | import { BufferResolvable } from "discord.js" 6 | 7 | const dom = new JSDOM() 8 | const document = dom.window.document 9 | 10 | const basePath = (file: string) => { 11 | return path.join(__dirname, "..", "..", "assets", file) 12 | } 13 | 14 | export const generateTranscript = ( 15 | options: TranscriptOptions 16 | ): Promise => { 17 | const { guild, channel, messages } = options 18 | 19 | return new Promise(async (ful) => { 20 | fs.readFile( 21 | basePath("template.html"), 22 | "utf8", 23 | async function (_err, data) { 24 | if (data) { 25 | fs.writeFile( 26 | basePath("index.html"), 27 | data, 28 | async function (err) { 29 | if (err) return console.log(err) 30 | let info = document.createElement("div") 31 | info.className = "info" 32 | let iconClass = document.createElement("div") 33 | iconClass.className = "info__guild-icon-container" 34 | let guild__icon = document.createElement("img") 35 | guild__icon.className = "info__guild-icon" 36 | guild__icon.setAttribute("src", guild.iconURL()) 37 | iconClass.appendChild(guild__icon) 38 | info.appendChild(iconClass) 39 | 40 | let info__metadata = document.createElement("div") 41 | info__metadata.className = "info__metadata" 42 | 43 | let guildName = document.createElement("div") 44 | guildName.className = "info__guild-name" 45 | let gName = document.createTextNode(guild.name) 46 | guildName.appendChild(gName) 47 | info__metadata.appendChild(guildName) 48 | 49 | let channelName = document.createElement("div") 50 | channelName.className = "info__channel-name" 51 | let cName = document.createTextNode(channel.name) 52 | channelName.appendChild(cName) 53 | info__metadata.appendChild(channelName) 54 | 55 | let messagecount = document.createElement("div") 56 | messagecount.className = 57 | "info__channel-message-count" 58 | messagecount.appendChild( 59 | document.createTextNode( 60 | `Transcripted ${messages.length} messages.` 61 | ) 62 | ) 63 | info__metadata.appendChild(messagecount) 64 | info.appendChild(info__metadata) 65 | fs.appendFile( 66 | basePath("index.html"), 67 | info.outerHTML, 68 | async function (err) { 69 | if (err) return console.log(err) 70 | messages.forEach(async (msg) => { 71 | let parentContainer = 72 | document.createElement("div") 73 | parentContainer.className = 74 | "parent-container" 75 | let avatarDiv = 76 | document.createElement("div") 77 | avatarDiv.className = "avatar-container" 78 | let img = document.createElement("img") 79 | img.setAttribute( 80 | "src", 81 | msg.author.displayAvatarURL() 82 | ) 83 | img.className = "avatar" 84 | avatarDiv.appendChild(img) 85 | 86 | parentContainer.appendChild(avatarDiv) 87 | 88 | let messageContainer = 89 | document.createElement("div") 90 | messageContainer.className = 91 | "message-container" 92 | 93 | let nameElement = 94 | document.createElement("span") 95 | let name = document.createTextNode( 96 | msg.author.tag + 97 | " " + 98 | msg.createdAt.toDateString() + 99 | " " + 100 | msg.createdAt.toLocaleTimeString() + 101 | " EST" 102 | ) 103 | nameElement.appendChild(name) 104 | messageContainer.append(nameElement) 105 | 106 | if (msg.content.startsWith("```")) { 107 | let m = msg.content.replace( 108 | /```/g, 109 | "" 110 | ) 111 | let codeNode = 112 | document.createElement("code") 113 | let textNode = 114 | document.createTextNode(m) 115 | codeNode.appendChild(textNode) 116 | messageContainer.appendChild( 117 | codeNode 118 | ) 119 | } else { 120 | let msgNode = 121 | document.createElement("span") 122 | let textNode = 123 | document.createTextNode( 124 | msg.content 125 | ) 126 | msgNode.append(textNode) 127 | messageContainer.appendChild( 128 | msgNode 129 | ) 130 | } 131 | parentContainer.appendChild( 132 | messageContainer 133 | ) 134 | fs.appendFile( 135 | basePath("index.html"), 136 | parentContainer.outerHTML, 137 | function (err) { 138 | if (err) return console.log(err) 139 | } 140 | ) 141 | }) 142 | fs.readFile( 143 | basePath("index.html"), 144 | (err, data) => { 145 | if (err) console.log(err) 146 | ful(data) 147 | } 148 | ) 149 | } 150 | ) 151 | } 152 | ) 153 | } 154 | } 155 | ) 156 | }) 157 | } 158 | -------------------------------------------------------------------------------- /src/modmail/modmail.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CloseMailSessionOptions, 3 | ModMailModelOptions, 4 | ModMailOptions 5 | } from "./modmail.interface" 6 | import mongoose, { Schema } from "mongoose" 7 | import { 8 | Client, 9 | Collection, 10 | Message, 11 | MessageActionRow, 12 | MessageButton, 13 | MessageEmbed, 14 | Snowflake, 15 | TextChannel, 16 | User 17 | } from "discord.js" 18 | import { create } from "sourcebin" 19 | 20 | export class ModMailClient { 21 | public options: ModMailOptions 22 | public collection = new Collection() 23 | public set = new Set() 24 | public model = mongoose.model( 25 | "reconlx-modmail", 26 | new Schema({ 27 | User: String, 28 | Channel: String, 29 | Messages: Array 30 | }) 31 | ) 32 | 33 | constructor(options: ModMailOptions) { 34 | if (mongoose.connection.readyState !== 1) { 35 | if (!options.mongooseConnectionString) 36 | throw new Error( 37 | "There is no established connection with mongoose and a mongoose connection is required!" 38 | ) 39 | 40 | mongoose.connect(options.mongooseConnectionString) 41 | 42 | this.options = options 43 | } 44 | } 45 | 46 | public ready() { 47 | this.model.find({}).then((data) => { 48 | data.forEach((x) => { 49 | this.collection.set(x.User, x) 50 | }) 51 | }) 52 | } 53 | 54 | public async modmailListener(message: Message) { 55 | if (message.author.id === this.options.client.user.id) return 56 | const sendMessage = async ( 57 | channel: TextChannel | User, 58 | user: Snowflake 59 | ) => { 60 | const content = () => { 61 | const context = [] 62 | const attachment = message.attachments.first() 63 | if (message.content) context.push(message.content) 64 | if (attachment) 65 | context.push(`[${attachment.url || attachment.proxyURL}]`) 66 | 67 | return context.join(" ") 68 | } 69 | 70 | // saving messages 71 | const data = await this.model.findOne({ User: user }) 72 | if (data) { 73 | data.Messages = [ 74 | ...data.Messages, 75 | `${message.author.tag} :: ${content()}` 76 | ] 77 | 78 | data.save().catch((err) => {}) 79 | } 80 | return channel.send(content()).catch(console.log) 81 | } 82 | if (message.channel.type === "DM") { 83 | const createMail = async () => { 84 | const user = message.author 85 | if (this.set.has(user.id)) return 86 | const guild = this.options.client.guilds.cache.get( 87 | this.options.guildId 88 | ) 89 | message.author.send( 90 | this.options.custom?.user?.(user) || 91 | `Hi by dming me you are creating a modmail with **${guild.name}** staff team!` 92 | ) 93 | this.set.add(user.id) 94 | 95 | const createdChannel = await guild.channels.create( 96 | `${user.username}`, 97 | { 98 | type: "GUILD_TEXT", 99 | parent: this.options.category, 100 | permissionOverwrites: [ 101 | { 102 | id: guild.id, 103 | deny: ["VIEW_CHANNEL"] 104 | }, 105 | this.options.modmailRole 106 | ? { 107 | id: this.options.modmailRole, 108 | allow: ["VIEW_CHANNEL", "SEND_MESSAGES"] 109 | } 110 | : null 111 | ] 112 | } 113 | ) 114 | 115 | createdChannel 116 | .send( 117 | this.options.custom?.channel?.(user) || { 118 | content: `<@&${this.options.modmailRole}>\n**${user.tag}** (${user.id}) has created a new ticket` 119 | } 120 | ) 121 | .then((m) => m.pin()) 122 | 123 | const props: ModMailModelOptions = { 124 | User: user.id, 125 | Channel: createdChannel.id, 126 | Messages: [ 127 | this.options.custom?.saveMessageFormat?.(message) || 128 | `${message.author.tag} :: ${message.content}` 129 | ] 130 | } 131 | 132 | new this.model(props).save() 133 | 134 | this.collection.set(props.User, props) 135 | 136 | sendMessage(createdChannel, props.User) 137 | 138 | this.set.delete(props.User) 139 | } 140 | 141 | const data = this.collection.get(message.author.id) 142 | 143 | if (!data) return createMail() 144 | const channel = this.options.client.channels.cache.get( 145 | data.Channel 146 | ) as TextChannel 147 | 148 | if (!channel) 149 | return this.model.deleteMany({ Channel: data.Channel }) 150 | 151 | await sendMessage(channel, data.User) 152 | } else if ( 153 | (message.channel as TextChannel).parentId === this.options.category 154 | ) { 155 | const data = this.collection.find( 156 | (x) => x.Channel === message.channelId 157 | ) 158 | 159 | if (!data) 160 | return message.channel.send( 161 | "an error occured, user is not found please delete this channel!" 162 | ) 163 | 164 | const user = this.options.client.users.cache.get(data.User) 165 | await sendMessage(user, user.id) 166 | } 167 | } 168 | 169 | public async deleteMail({ channel, reason }: CloseMailSessionOptions) { 170 | const data = this.collection.find((x) => x.Channel === channel) 171 | const mailChannel = this.options.client.channels.cache.get(channel) 172 | 173 | if (data) { 174 | const modelData = await this.model.findOne({ User: data.User }) 175 | 176 | const user = await this.options.client.users.fetch(data.User) 177 | 178 | if (this.options.transcriptChannel) { 179 | const transcriptChannel = 180 | this.options.client.channels.cache.get( 181 | this.options.transcriptChannel 182 | ) as TextChannel 183 | 184 | const url = ( 185 | await create([ 186 | { 187 | content: modelData.Messages.join("\n"), 188 | language: 189 | this.options.custom?.language || "AsciiDoc", 190 | name: `Transcript [${ 191 | user.tag 192 | }] ${new Date().toLocaleString()}` 193 | } 194 | ]) 195 | ).url 196 | 197 | const embed = new MessageEmbed() 198 | .setAuthor( 199 | user.tag, 200 | user.displayAvatarURL({ dynamic: true }) 201 | ) 202 | .setColor(this.options.custom?.embedColor || "RANDOM") 203 | .setTimestamp() 204 | .setDescription( 205 | [ 206 | `Message Count: ${modelData.Messages?.length || 0}`, 207 | `Close Reason: ${reason || "No reason provided"}` 208 | ].join("\n") 209 | ) 210 | 211 | const components = [ 212 | new MessageActionRow().addComponents( 213 | new MessageButton() 214 | .setURL(url) 215 | .setLabel("Transcript") 216 | .setStyle("LINK") 217 | ) 218 | ] 219 | 220 | mailChannel.delete() 221 | 222 | transcriptChannel.send({ embeds: [embed], components }) 223 | this.collection.delete(data.User) 224 | await modelData.delete() 225 | } 226 | } 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /src/giveaways/giveaways.ts: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | import { 3 | Client, 4 | Collection, 5 | ColorResolvable, 6 | MessageEmbed, 7 | TextChannel, 8 | User 9 | } from "discord.js" 10 | import { 11 | GiveawayClientOptions, 12 | GiveawayClientSchema, 13 | StartOptions 14 | } from "./giveaways.interfaces" 15 | 16 | export class GiveawayClient { 17 | public schema = mongoose.model( 18 | "reconlx-giveaways", 19 | new mongoose.Schema({ 20 | MessageID: String, 21 | EndsAt: Number, 22 | Guild: String, 23 | Channel: String, 24 | winners: Number, 25 | prize: String, 26 | description: String, 27 | hostedBy: String, 28 | Activated: Boolean 29 | }) 30 | ) 31 | public options: GiveawayClientOptions 32 | public collection: Collection = 33 | new Collection() 34 | 35 | /** 36 | * @name GiveawayClient 37 | * @kind constructor 38 | * @description Initialzing the giveaway client 39 | */ 40 | constructor(options: GiveawayClientOptions) { 41 | const { client, mongooseConnectionString, defaultColor, emoji } = 42 | options 43 | 44 | if (mongoose.connection.readyState !== 1) { 45 | if (!options.mongooseConnectionString) 46 | throw new Error( 47 | "There is no established connection with mongoose and a mongoose connection is required!" 48 | ) 49 | mongoose.connect(options.mongooseConnectionString) 50 | } 51 | this.options = { 52 | client, 53 | mongooseConnectionString, 54 | defaultColor: defaultColor || "#FF0000", 55 | emoji: emoji || "🎉" 56 | } 57 | 58 | this.ready() 59 | } 60 | 61 | private ready() { 62 | this.schema.find().then((data) => { 63 | if (!data?.length) return 64 | data.forEach((value) => { 65 | this.collection.set(value.MessageID, value) 66 | }) 67 | }) 68 | 69 | this.checkWinners() 70 | } 71 | 72 | /** 73 | * @method 74 | * @description Starts a giveaway 75 | */ 76 | public start(options: StartOptions) { 77 | const { channel, time, winners, prize, description, hostedBy } = options 78 | const desc = [ 79 | `Giveaway ends at ${new Date( 80 | Date.now() + time 81 | ).toLocaleString()}\n` + `Hosted by: ${hostedBy}` 82 | ] 83 | if (description) desc.push(`Description: ${description}`) 84 | const embed = new MessageEmbed() 85 | .setTitle(`${prize}`) 86 | .setDescription(desc.join("\n")) 87 | .setFooter({ text: `${winners} winner(s)` }) 88 | .setColor(this.options.defaultColor) 89 | .setTimestamp() 90 | 91 | channel.send({ embeds: [embed] }).then((msg) => { 92 | msg.react(this.options.emoji) 93 | const values = { 94 | MessageID: msg.id, 95 | EndsAt: Date.now() + time, 96 | Guild: msg.guild.id, 97 | Channel: msg.channel.id, 98 | winners, 99 | prize, 100 | description, 101 | hostedBy: hostedBy.id, 102 | Activated: true 103 | } 104 | const newGiveawaySchema = new this.schema(values) 105 | 106 | newGiveawaySchema.save() 107 | this.collection.set(values.MessageID, values) 108 | }) 109 | } 110 | 111 | /** 112 | * @method 113 | * @param {String} MessageID Message ID for the giveaway 114 | * @param {Boolean} getWinner Choose a winner? 115 | * @description End a giveaway, choose a winner (optional) 116 | */ 117 | end(MessageID: string, getWinner: boolean) { 118 | this.schema.findOne( 119 | { MessageID, Activated: true }, 120 | async (err, data) => { 121 | const giveawayChannel = this.options.client.channels.cache.get( 122 | data.Channel 123 | ) 124 | if (err) throw err 125 | if (!data) 126 | throw new Error( 127 | "There are no giveaways currently running with " + 128 | MessageID + 129 | " id" 130 | ) 131 | if (getWinner) { 132 | this.getReactions( 133 | data.Channel, 134 | data.MessageID, 135 | data.winners 136 | ).then((reactions: any) => { 137 | const winners = reactions.map((user) => user).join(", ") 138 | ;(giveawayChannel as TextChannel).send( 139 | `Congrats ${winners} you have won **${data.prize}**` 140 | ) 141 | }) 142 | } else { 143 | const oldMessage = await this.getMessage( 144 | data.Channel, 145 | data.MessageID 146 | ) 147 | oldMessage.edit({ 148 | embeds: [new MessageEmbed().setTitle("Giveaway ended!")] 149 | }) 150 | } 151 | data.Activated = false 152 | data.save() 153 | this.collection.delete(MessageID) 154 | } 155 | ) 156 | } 157 | 158 | /** 159 | * @method 160 | * @description Picks a new winner! 161 | */ 162 | public reroll(MessageID: string) { 163 | return new Promise((ful, rej) => { 164 | const filtered = this.collection.filter( 165 | (value) => value.Activated === false 166 | ) 167 | const data = filtered.get(MessageID) 168 | if (!data) 169 | rej("The giveaway does not exist or has not been ended yet") 170 | const giveawayChannel = this.getChannel(data.Channel) 171 | this.getReactions(data.Channel, MessageID, data.winners).then( 172 | (reactions: any) => { 173 | const winner = reactions.map((user) => user).join(", ") 174 | giveawayChannel.send( 175 | `Giveway has been rerolled, ${winner} ${ 176 | reactions.size === 1 ? "is" : "are" 177 | } the new winner for **${data.prize}**` 178 | ) 179 | } 180 | ) 181 | }) 182 | } 183 | 184 | /** 185 | * @method 186 | * @param {Boolean} activatedOnly display activated giveaways only? 187 | * @param {Boolean} all display giveaways of all guilds? 188 | * @param {Message} message message if (all = false) 189 | * @description Get data on current giveaways hosted by the bot 190 | */ 191 | public getCurrentGiveaways(activatedOnly = true, all = false, message) { 192 | return new Promise((ful, rej) => { 193 | if (all) { 194 | if (activatedOnly) { 195 | ful( 196 | this.collection.filter( 197 | (value) => value.Activated === true 198 | ) 199 | ) 200 | } else { 201 | ful(this.collection) 202 | } 203 | } else { 204 | if (activatedOnly) { 205 | ful( 206 | this.collection.filter( 207 | (value) => 208 | value.Guild === message.guild.id && 209 | value.Activated === true 210 | ) 211 | ) 212 | } 213 | ful( 214 | this.collection.filter( 215 | (value) => value.Guild === message.guild.id 216 | ) 217 | ) 218 | } 219 | }) 220 | } 221 | 222 | /** 223 | * @method 224 | * @param {Boolean} all Get data from all guilds? 225 | * @param {String} guildID guild id if all=false 226 | * @description Removes (activated = false) giveaways 227 | */ 228 | public removeCachedGiveaways(all = false, guildID) { 229 | if (!all) { 230 | this.schema.find( 231 | { Guild: guildID, Activated: false }, 232 | async (err, data) => { 233 | if (err) throw err 234 | if (data) 235 | data.forEach((data: any) => { 236 | data.delete() 237 | }) 238 | } 239 | ) 240 | const filtered = this.collection.filter( 241 | (value) => value.Activated === false && value.Guild === guildID 242 | ) 243 | filtered.forEach((value) => { 244 | this.collection.delete(value.MessageID) 245 | }) 246 | } else { 247 | this.schema.find({ Activated: false }, async (err, data) => { 248 | if (err) throw err 249 | if (data) 250 | data.forEach((data: any) => { 251 | data.delete() 252 | }) 253 | }) 254 | const filtered = this.collection.filter( 255 | (value) => value.Activated === false 256 | ) 257 | filtered.forEach((value) => { 258 | this.collection.delete(value.MessageID) 259 | }) 260 | } 261 | } 262 | 263 | private getReactions(channelID, messageID, amount) { 264 | return new Promise((ful, rej) => { 265 | ;( 266 | this.options.client.channels.cache.get(channelID) as TextChannel 267 | ).messages 268 | .fetch(messageID) 269 | .then((msg) => { 270 | msg.reactions.cache 271 | .get(this.options.emoji) 272 | .users.fetch() 273 | .then((users) => { 274 | const real = users.filter((user) => !user.bot) 275 | if (amount && !real.size >= amount) 276 | rej( 277 | "Not Enough Reactions, winner was not decided" 278 | ) 279 | ful(real.random(amount)) 280 | }) 281 | }) 282 | }) 283 | } 284 | 285 | private getMessage(channel, message) { 286 | return ( 287 | this.options.client.channels.cache.get(channel) as TextChannel 288 | ).messages.fetch(message) 289 | } 290 | 291 | private getChannel(value) { 292 | return this.options.client.channels.cache.get(value) as TextChannel 293 | } 294 | 295 | private checkWinners() { 296 | setInterval(() => { 297 | const endedGiveaways = this.collection.filter( 298 | (value) => value.EndsAt < Date.now() && value.Activated === true 299 | ) 300 | if (endedGiveaways.size === 0) return 301 | 302 | endedGiveaways.forEach(async (giveaway) => { 303 | const giveawayChannel = this.getChannel(giveaway.Channel) 304 | this.getReactions( 305 | giveaway.Channel, 306 | giveaway.MessageID, 307 | giveaway.winners 308 | ) 309 | .then((reactions: any) => { 310 | const winners = reactions.map((user) => user).join(", ") 311 | giveawayChannel.send( 312 | `Congrats ${winners} you have won **${giveaway.prize}**` 313 | ) 314 | }) 315 | .catch((err) => { 316 | giveawayChannel.send( 317 | `No winner was determined for giveaway -> https://discord.com/channels/${giveaway.Guild}/${giveaway.Channel}/${giveaway.MessageID}` 318 | ) 319 | }) 320 | const oldMessage = await this.getMessage( 321 | giveaway.Channel, 322 | giveaway.MessageID 323 | ) 324 | oldMessage.edit({ 325 | embeds: [new MessageEmbed().setTitle("Giveaway Ended!")] 326 | }) 327 | this.collection.get(giveaway.MessageID).Activated = false 328 | const props = { 329 | MessageID: giveaway.MessageID, 330 | Activated: true 331 | } 332 | const data = await this.schema.findOne(props) 333 | if (data) data.Activated = false 334 | data.save() 335 | }) 336 | }, 5000) 337 | } 338 | } 339 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@cspotcode/source-map-consumer@0.8.0": 6 | "integrity" "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==" 7 | "resolved" "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz" 8 | "version" "0.8.0" 9 | 10 | "@cspotcode/source-map-support@0.7.0": 11 | "integrity" "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==" 12 | "resolved" "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz" 13 | "version" "0.7.0" 14 | dependencies: 15 | "@cspotcode/source-map-consumer" "0.8.0" 16 | 17 | "@discordjs/builders@^0.11.0": 18 | "integrity" "sha512-ZTB8yJdJKrKlq44dpWkNUrAtEJEq0gqpb7ASdv4vmq6/mZal5kOv312hQ56I/vxwMre+VIkoHquNUAfnTbiYtg==" 19 | "resolved" "https://registry.npmjs.org/@discordjs/builders/-/builders-0.11.0.tgz" 20 | "version" "0.11.0" 21 | dependencies: 22 | "@sindresorhus/is" "^4.2.0" 23 | "discord-api-types" "^0.26.0" 24 | "ts-mixer" "^6.0.0" 25 | "tslib" "^2.3.1" 26 | "zod" "^3.11.6" 27 | 28 | "@discordjs/collection@^0.4.0": 29 | "integrity" "sha512-zmjq+l/rV35kE6zRrwe8BHqV78JvIh2ybJeZavBi5NySjWXqN3hmmAKg7kYMMXSeiWtSsMoZ/+MQi0DiQWy2lw==" 30 | "resolved" "https://registry.npmjs.org/@discordjs/collection/-/collection-0.4.0.tgz" 31 | "version" "0.4.0" 32 | 33 | "@sapphire/async-queue@^1.1.9": 34 | "integrity" "sha512-z+CDw5X4UgIEpZL8KM+ThVx1i8V60HBg0l/oFewTNbQQeRDJHdVxHyJykv+SF1H+Rc8EkMS81VTWo95jVYgO/g==" 35 | "resolved" "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.3.0.tgz" 36 | "version" "1.3.0" 37 | 38 | "@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.2.0": 39 | "integrity" "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" 40 | "resolved" "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz" 41 | "version" "4.6.0" 42 | 43 | "@sourcebin/linguist@latest": 44 | "version" "0.0.3" 45 | 46 | "@szmarczak/http-timer@^4.0.5": 47 | "integrity" "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==" 48 | "resolved" "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz" 49 | "version" "4.0.6" 50 | dependencies: 51 | "defer-to-connect" "^2.0.0" 52 | 53 | "@tootallnate/once@1": 54 | "integrity" "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" 55 | "resolved" "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" 56 | "version" "1.1.2" 57 | 58 | "@tsconfig/node10@^1.0.7": 59 | "integrity" "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" 60 | "resolved" "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz" 61 | "version" "1.0.8" 62 | 63 | "@tsconfig/node12@^1.0.7": 64 | "integrity" "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" 65 | "resolved" "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz" 66 | "version" "1.0.9" 67 | 68 | "@tsconfig/node14@^1.0.0": 69 | "integrity" "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" 70 | "resolved" "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz" 71 | "version" "1.0.1" 72 | 73 | "@tsconfig/node16@^1.0.2": 74 | "integrity" "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" 75 | "resolved" "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz" 76 | "version" "1.0.2" 77 | 78 | "@types/cacheable-request@^6.0.1": 79 | "integrity" "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==" 80 | "resolved" "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz" 81 | "version" "6.0.2" 82 | dependencies: 83 | "@types/http-cache-semantics" "*" 84 | "@types/keyv" "*" 85 | "@types/node" "*" 86 | "@types/responselike" "*" 87 | 88 | "@types/http-cache-semantics@*": 89 | "integrity" "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" 90 | "resolved" "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz" 91 | "version" "4.0.1" 92 | 93 | "@types/jsdom@^16.2.13": 94 | "integrity" "sha512-6BAy1xXEmMuHeAJ4Fv4yXKwBDTGTOseExKE3OaHiNycdHdZw59KfYzrt0DkDluvwmik1HRt6QS7bImxUmpSy+w==" 95 | "resolved" "https://registry.npmjs.org/@types/jsdom/-/jsdom-16.2.14.tgz" 96 | "version" "16.2.14" 97 | dependencies: 98 | "@types/node" "*" 99 | "@types/parse5" "*" 100 | "@types/tough-cookie" "*" 101 | 102 | "@types/keyv@*": 103 | "integrity" "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==" 104 | "resolved" "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz" 105 | "version" "3.1.4" 106 | dependencies: 107 | "@types/node" "*" 108 | 109 | "@types/node-fetch@^2.5.12": 110 | "integrity" "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==" 111 | "resolved" "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz" 112 | "version" "2.6.1" 113 | dependencies: 114 | "@types/node" "*" 115 | "form-data" "^3.0.0" 116 | 117 | "@types/node@*": 118 | "integrity" "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" 119 | "resolved" "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz" 120 | "version" "17.0.23" 121 | 122 | "@types/parse5@*": 123 | "integrity" "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" 124 | "resolved" "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz" 125 | "version" "6.0.3" 126 | 127 | "@types/responselike@*", "@types/responselike@^1.0.0": 128 | "integrity" "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==" 129 | "resolved" "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz" 130 | "version" "1.0.0" 131 | dependencies: 132 | "@types/node" "*" 133 | 134 | "@types/tough-cookie@*": 135 | "integrity" "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==" 136 | "resolved" "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz" 137 | "version" "4.0.1" 138 | 139 | "@types/webidl-conversions@*": 140 | "integrity" "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q==" 141 | "resolved" "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz" 142 | "version" "6.1.1" 143 | 144 | "@types/whatwg-url@^8.2.1": 145 | "integrity" "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==" 146 | "resolved" "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz" 147 | "version" "8.2.1" 148 | dependencies: 149 | "@types/node" "*" 150 | "@types/webidl-conversions" "*" 151 | 152 | "@types/ws@^8.2.2": 153 | "integrity" "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==" 154 | "resolved" "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz" 155 | "version" "8.5.3" 156 | dependencies: 157 | "@types/node" "*" 158 | 159 | "abab@^2.0.3", "abab@^2.0.5": 160 | "integrity" "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" 161 | "resolved" "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz" 162 | "version" "2.0.5" 163 | 164 | "acorn-globals@^6.0.0": 165 | "integrity" "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==" 166 | "resolved" "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz" 167 | "version" "6.0.0" 168 | dependencies: 169 | "acorn" "^7.1.1" 170 | "acorn-walk" "^7.1.1" 171 | 172 | "acorn-walk@^7.1.1": 173 | "integrity" "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" 174 | "resolved" "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz" 175 | "version" "7.2.0" 176 | 177 | "acorn-walk@^8.1.1": 178 | "integrity" "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" 179 | "resolved" "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" 180 | "version" "8.2.0" 181 | 182 | "acorn@^7.1.1": 183 | "integrity" "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" 184 | "resolved" "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" 185 | "version" "7.4.1" 186 | 187 | "acorn@^8.2.4", "acorn@^8.4.1": 188 | "integrity" "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" 189 | "resolved" "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz" 190 | "version" "8.7.0" 191 | 192 | "agent-base@6": 193 | "integrity" "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==" 194 | "resolved" "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" 195 | "version" "6.0.2" 196 | dependencies: 197 | "debug" "4" 198 | 199 | "arg@^4.1.0": 200 | "integrity" "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 201 | "resolved" "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" 202 | "version" "4.1.3" 203 | 204 | "asynckit@^0.4.0": 205 | "integrity" "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 206 | "resolved" "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" 207 | "version" "0.4.0" 208 | 209 | "axios@^0.21.1": 210 | "integrity" "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==" 211 | "resolved" "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz" 212 | "version" "0.21.4" 213 | dependencies: 214 | "follow-redirects" "^1.14.0" 215 | 216 | "balanced-match@^1.0.0": 217 | "integrity" "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 218 | "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" 219 | "version" "1.0.2" 220 | 221 | "base64-js@^1.3.1": 222 | "integrity" "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" 223 | "resolved" "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" 224 | "version" "1.5.1" 225 | 226 | "brace-expansion@^1.1.7": 227 | "integrity" "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==" 228 | "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" 229 | "version" "1.1.11" 230 | dependencies: 231 | "balanced-match" "^1.0.0" 232 | "concat-map" "0.0.1" 233 | 234 | "browser-process-hrtime@^1.0.0": 235 | "integrity" "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" 236 | "resolved" "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz" 237 | "version" "1.0.0" 238 | 239 | "bson@^4.2.2", "bson@^4.6.1": 240 | "integrity" "sha512-VeJKHShcu1b/ugl0QiujlVuBepab714X9nNyBdA1kfekuDGecxgpTA2Z6nYbagrWFeiIyzSWIOzju3lhj+RNyQ==" 241 | "resolved" "https://registry.npmjs.org/bson/-/bson-4.6.2.tgz" 242 | "version" "4.6.2" 243 | dependencies: 244 | "buffer" "^5.6.0" 245 | 246 | "buffer@^5.6.0": 247 | "integrity" "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==" 248 | "resolved" "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" 249 | "version" "5.7.1" 250 | dependencies: 251 | "base64-js" "^1.3.1" 252 | "ieee754" "^1.1.13" 253 | 254 | "cacheable-lookup@^5.0.3": 255 | "integrity" "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==" 256 | "resolved" "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz" 257 | "version" "5.0.4" 258 | 259 | "cacheable-request@^7.0.2": 260 | "integrity" "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==" 261 | "resolved" "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz" 262 | "version" "7.0.2" 263 | dependencies: 264 | "clone-response" "^1.0.2" 265 | "get-stream" "^5.1.0" 266 | "http-cache-semantics" "^4.0.0" 267 | "keyv" "^4.0.0" 268 | "lowercase-keys" "^2.0.0" 269 | "normalize-url" "^6.0.1" 270 | "responselike" "^2.0.0" 271 | 272 | "clone-response@^1.0.2": 273 | "integrity" "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=" 274 | "resolved" "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz" 275 | "version" "1.0.2" 276 | dependencies: 277 | "mimic-response" "^1.0.0" 278 | 279 | "combined-stream@^1.0.8": 280 | "integrity" "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==" 281 | "resolved" "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" 282 | "version" "1.0.8" 283 | dependencies: 284 | "delayed-stream" "~1.0.0" 285 | 286 | "concat-map@0.0.1": 287 | "integrity" "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 288 | "resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" 289 | "version" "0.0.1" 290 | 291 | "create-require@^1.1.0": 292 | "integrity" "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" 293 | "resolved" "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" 294 | "version" "1.1.1" 295 | 296 | "cssom@^0.4.4": 297 | "integrity" "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" 298 | "resolved" "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz" 299 | "version" "0.4.4" 300 | 301 | "cssom@~0.3.6": 302 | "integrity" "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" 303 | "resolved" "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz" 304 | "version" "0.3.8" 305 | 306 | "cssstyle@^2.3.0": 307 | "integrity" "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==" 308 | "resolved" "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz" 309 | "version" "2.3.0" 310 | dependencies: 311 | "cssom" "~0.3.6" 312 | 313 | "data-urls@^2.0.0": 314 | "integrity" "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==" 315 | "resolved" "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz" 316 | "version" "2.0.0" 317 | dependencies: 318 | "abab" "^2.0.3" 319 | "whatwg-mimetype" "^2.3.0" 320 | "whatwg-url" "^8.0.0" 321 | 322 | "debug@4", "debug@4.x": 323 | "integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==" 324 | "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" 325 | "version" "4.3.4" 326 | dependencies: 327 | "ms" "2.1.2" 328 | 329 | "decimal.js@^10.2.1": 330 | "integrity" "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" 331 | "resolved" "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz" 332 | "version" "10.3.1" 333 | 334 | "decompress-response@^6.0.0": 335 | "integrity" "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==" 336 | "resolved" "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz" 337 | "version" "6.0.0" 338 | dependencies: 339 | "mimic-response" "^3.1.0" 340 | 341 | "deep-is@~0.1.3": 342 | "integrity" "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" 343 | "resolved" "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" 344 | "version" "0.1.4" 345 | 346 | "defer-to-connect@^2.0.0": 347 | "integrity" "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" 348 | "resolved" "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz" 349 | "version" "2.0.1" 350 | 351 | "delayed-stream@~1.0.0": 352 | "integrity" "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 353 | "resolved" "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" 354 | "version" "1.0.0" 355 | 356 | "denque@^2.0.1": 357 | "integrity" "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==" 358 | "resolved" "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz" 359 | "version" "2.0.1" 360 | 361 | "diff@^4.0.1": 362 | "integrity" "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 363 | "resolved" "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" 364 | "version" "4.0.2" 365 | 366 | "discord-api-types@^0.26.0": 367 | "integrity" "sha512-T5PdMQ+Y1MEECYMV5wmyi9VEYPagEDEi4S0amgsszpWY0VB9JJ/hEvM6BgLhbdnKky4gfmZEXtEEtojN8ZKJQQ==" 368 | "resolved" "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.26.1.tgz" 369 | "version" "0.26.1" 370 | 371 | "discord.js@^13.5.0": 372 | "integrity" "sha512-tXNR8zgsEPxPBvGk3AQjJ9ljIIC6/LOPjzKwpwz8Y1Q2X66Vi3ZqFgRHYwnHKC0jC0F+l4LzxlhmOJsBZDNg9g==" 373 | "resolved" "https://registry.npmjs.org/discord.js/-/discord.js-13.6.0.tgz" 374 | "version" "13.6.0" 375 | dependencies: 376 | "@discordjs/builders" "^0.11.0" 377 | "@discordjs/collection" "^0.4.0" 378 | "@sapphire/async-queue" "^1.1.9" 379 | "@types/node-fetch" "^2.5.12" 380 | "@types/ws" "^8.2.2" 381 | "discord-api-types" "^0.26.0" 382 | "form-data" "^4.0.0" 383 | "node-fetch" "^2.6.1" 384 | "ws" "^8.4.0" 385 | 386 | "domexception@^2.0.1": 387 | "integrity" "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==" 388 | "resolved" "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz" 389 | "version" "2.0.1" 390 | dependencies: 391 | "webidl-conversions" "^5.0.0" 392 | 393 | "end-of-stream@^1.1.0": 394 | "integrity" "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==" 395 | "resolved" "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" 396 | "version" "1.4.4" 397 | dependencies: 398 | "once" "^1.4.0" 399 | 400 | "escodegen@^2.0.0": 401 | "integrity" "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==" 402 | "resolved" "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz" 403 | "version" "2.0.0" 404 | dependencies: 405 | "esprima" "^4.0.1" 406 | "estraverse" "^5.2.0" 407 | "esutils" "^2.0.2" 408 | "optionator" "^0.8.1" 409 | optionalDependencies: 410 | "source-map" "~0.6.1" 411 | 412 | "esprima@^4.0.1": 413 | "integrity" "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" 414 | "resolved" "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" 415 | "version" "4.0.1" 416 | 417 | "estraverse@^5.2.0": 418 | "integrity" "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" 419 | "resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" 420 | "version" "5.3.0" 421 | 422 | "esutils@^2.0.2": 423 | "integrity" "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" 424 | "resolved" "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" 425 | "version" "2.0.3" 426 | 427 | "fast-levenshtein@~2.0.6": 428 | "integrity" "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" 429 | "resolved" "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" 430 | "version" "2.0.6" 431 | 432 | "follow-redirects@^1.14.0": 433 | "integrity" "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" 434 | "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz" 435 | "version" "1.14.9" 436 | 437 | "form-data@^3.0.0": 438 | "integrity" "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==" 439 | "resolved" "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz" 440 | "version" "3.0.1" 441 | dependencies: 442 | "asynckit" "^0.4.0" 443 | "combined-stream" "^1.0.8" 444 | "mime-types" "^2.1.12" 445 | 446 | "form-data@^4.0.0": 447 | "integrity" "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==" 448 | "resolved" "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" 449 | "version" "4.0.0" 450 | dependencies: 451 | "asynckit" "^0.4.0" 452 | "combined-stream" "^1.0.8" 453 | "mime-types" "^2.1.12" 454 | 455 | "fs.realpath@^1.0.0": 456 | "integrity" "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 457 | "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" 458 | "version" "1.0.0" 459 | 460 | "get-stream@^5.1.0": 461 | "integrity" "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==" 462 | "resolved" "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" 463 | "version" "5.2.0" 464 | dependencies: 465 | "pump" "^3.0.0" 466 | 467 | "glob@^7.1.7": 468 | "integrity" "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==" 469 | "resolved" "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" 470 | "version" "7.2.0" 471 | dependencies: 472 | "fs.realpath" "^1.0.0" 473 | "inflight" "^1.0.4" 474 | "inherits" "2" 475 | "minimatch" "^3.0.4" 476 | "once" "^1.3.0" 477 | "path-is-absolute" "^1.0.0" 478 | 479 | "got@^11.8.1": 480 | "integrity" "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==" 481 | "resolved" "https://registry.npmjs.org/got/-/got-11.8.3.tgz" 482 | "version" "11.8.3" 483 | dependencies: 484 | "@sindresorhus/is" "^4.0.0" 485 | "@szmarczak/http-timer" "^4.0.5" 486 | "@types/cacheable-request" "^6.0.1" 487 | "@types/responselike" "^1.0.0" 488 | "cacheable-lookup" "^5.0.3" 489 | "cacheable-request" "^7.0.2" 490 | "decompress-response" "^6.0.0" 491 | "http2-wrapper" "^1.0.0-beta.5.2" 492 | "lowercase-keys" "^2.0.0" 493 | "p-cancelable" "^2.0.0" 494 | "responselike" "^2.0.0" 495 | 496 | "handlebars@^4.7.7": 497 | "integrity" "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==" 498 | "resolved" "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz" 499 | "version" "4.7.7" 500 | dependencies: 501 | "minimist" "^1.2.5" 502 | "neo-async" "^2.6.0" 503 | "source-map" "^0.6.1" 504 | "wordwrap" "^1.0.0" 505 | optionalDependencies: 506 | "uglify-js" "^3.1.4" 507 | 508 | "html-encoding-sniffer@^2.0.1": 509 | "integrity" "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==" 510 | "resolved" "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz" 511 | "version" "2.0.1" 512 | dependencies: 513 | "whatwg-encoding" "^1.0.5" 514 | 515 | "http-cache-semantics@^4.0.0": 516 | "integrity" "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" 517 | "resolved" "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" 518 | "version" "4.1.0" 519 | 520 | "http-proxy-agent@^4.0.1": 521 | "integrity" "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==" 522 | "resolved" "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz" 523 | "version" "4.0.1" 524 | dependencies: 525 | "@tootallnate/once" "1" 526 | "agent-base" "6" 527 | "debug" "4" 528 | 529 | "http2-wrapper@^1.0.0-beta.5.2": 530 | "integrity" "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==" 531 | "resolved" "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz" 532 | "version" "1.0.3" 533 | dependencies: 534 | "quick-lru" "^5.1.1" 535 | "resolve-alpn" "^1.0.0" 536 | 537 | "https-proxy-agent@^5.0.0": 538 | "integrity" "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==" 539 | "resolved" "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz" 540 | "version" "5.0.0" 541 | dependencies: 542 | "agent-base" "6" 543 | "debug" "4" 544 | 545 | "iconv-lite@0.4.24": 546 | "integrity" "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==" 547 | "resolved" "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" 548 | "version" "0.4.24" 549 | dependencies: 550 | "safer-buffer" ">= 2.1.2 < 3" 551 | 552 | "ieee754@^1.1.13": 553 | "integrity" "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" 554 | "resolved" "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" 555 | "version" "1.2.1" 556 | 557 | "inflight@^1.0.4": 558 | "integrity" "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=" 559 | "resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" 560 | "version" "1.0.6" 561 | dependencies: 562 | "once" "^1.3.0" 563 | "wrappy" "1" 564 | 565 | "inherits@2": 566 | "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 567 | "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" 568 | "version" "2.0.4" 569 | 570 | "ip@^1.1.5": 571 | "integrity" "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" 572 | "resolved" "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz" 573 | "version" "1.1.5" 574 | 575 | "is-potential-custom-element-name@^1.0.1": 576 | "integrity" "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" 577 | "resolved" "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz" 578 | "version" "1.0.1" 579 | 580 | "jsdom@^16.7.0": 581 | "integrity" "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==" 582 | "resolved" "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz" 583 | "version" "16.7.0" 584 | dependencies: 585 | "abab" "^2.0.5" 586 | "acorn" "^8.2.4" 587 | "acorn-globals" "^6.0.0" 588 | "cssom" "^0.4.4" 589 | "cssstyle" "^2.3.0" 590 | "data-urls" "^2.0.0" 591 | "decimal.js" "^10.2.1" 592 | "domexception" "^2.0.1" 593 | "escodegen" "^2.0.0" 594 | "form-data" "^3.0.0" 595 | "html-encoding-sniffer" "^2.0.1" 596 | "http-proxy-agent" "^4.0.1" 597 | "https-proxy-agent" "^5.0.0" 598 | "is-potential-custom-element-name" "^1.0.1" 599 | "nwsapi" "^2.2.0" 600 | "parse5" "6.0.1" 601 | "saxes" "^5.0.1" 602 | "symbol-tree" "^3.2.4" 603 | "tough-cookie" "^4.0.0" 604 | "w3c-hr-time" "^1.0.2" 605 | "w3c-xmlserializer" "^2.0.0" 606 | "webidl-conversions" "^6.1.0" 607 | "whatwg-encoding" "^1.0.5" 608 | "whatwg-mimetype" "^2.3.0" 609 | "whatwg-url" "^8.5.0" 610 | "ws" "^7.4.6" 611 | "xml-name-validator" "^3.0.0" 612 | 613 | "json-buffer@3.0.1": 614 | "integrity" "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" 615 | "resolved" "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" 616 | "version" "3.0.1" 617 | 618 | "jsonc-parser@^3.0.0": 619 | "integrity" "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==" 620 | "resolved" "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz" 621 | "version" "3.0.0" 622 | 623 | "kareem@2.3.5": 624 | "integrity" "sha512-qxCyQtp3ioawkiRNQr/v8xw9KIviMSSNmy+63Wubj7KmMn3g7noRXIZB4vPCAP+ETi2SR8eH6CvmlKZuGpoHOg==" 625 | "resolved" "https://registry.npmjs.org/kareem/-/kareem-2.3.5.tgz" 626 | "version" "2.3.5" 627 | 628 | "keyv@^4.0.0": 629 | "integrity" "sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==" 630 | "resolved" "https://registry.npmjs.org/keyv/-/keyv-4.1.1.tgz" 631 | "version" "4.1.1" 632 | dependencies: 633 | "json-buffer" "3.0.1" 634 | 635 | "levn@~0.3.0": 636 | "integrity" "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=" 637 | "resolved" "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz" 638 | "version" "0.3.0" 639 | dependencies: 640 | "prelude-ls" "~1.1.2" 641 | "type-check" "~0.3.2" 642 | 643 | "lodash@^4.7.0": 644 | "integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 645 | "resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" 646 | "version" "4.17.21" 647 | 648 | "lowercase-keys@^2.0.0": 649 | "integrity" "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" 650 | "resolved" "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" 651 | "version" "2.0.0" 652 | 653 | "lunr@^2.3.9": 654 | "integrity" "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" 655 | "resolved" "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz" 656 | "version" "2.3.9" 657 | 658 | "make-error@^1.1.1": 659 | "integrity" "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 660 | "resolved" "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" 661 | "version" "1.3.6" 662 | 663 | "marked@^4.0.10": 664 | "integrity" "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==" 665 | "resolved" "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz" 666 | "version" "4.0.12" 667 | 668 | "memory-pager@^1.0.2": 669 | "integrity" "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" 670 | "resolved" "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz" 671 | "version" "1.5.0" 672 | 673 | "mime-db@1.52.0": 674 | "integrity" "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 675 | "resolved" "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" 676 | "version" "1.52.0" 677 | 678 | "mime-types@^2.1.12": 679 | "integrity" "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==" 680 | "resolved" "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" 681 | "version" "2.1.35" 682 | dependencies: 683 | "mime-db" "1.52.0" 684 | 685 | "mimic-response@^1.0.0": 686 | "integrity" "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" 687 | "resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" 688 | "version" "1.0.1" 689 | 690 | "mimic-response@^3.1.0": 691 | "integrity" "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" 692 | "resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" 693 | "version" "3.1.0" 694 | 695 | "minimatch@^3.0.0", "minimatch@^3.0.4": 696 | "integrity" "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==" 697 | "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" 698 | "version" "3.1.2" 699 | dependencies: 700 | "brace-expansion" "^1.1.7" 701 | 702 | "minimist@^1.2.5": 703 | "integrity" "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" 704 | "resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" 705 | "version" "1.2.6" 706 | 707 | "mongodb-connection-string-url@^2.4.1": 708 | "integrity" "sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==" 709 | "resolved" "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz" 710 | "version" "2.5.2" 711 | dependencies: 712 | "@types/whatwg-url" "^8.2.1" 713 | "whatwg-url" "^11.0.0" 714 | 715 | "mongodb@4.3.1": 716 | "integrity" "sha512-sNa8APSIk+r4x31ZwctKjuPSaeKuvUeNb/fu/3B6dRM02HpEgig7hTHM8A/PJQTlxuC/KFWlDlQjhsk/S43tBg==" 717 | "resolved" "https://registry.npmjs.org/mongodb/-/mongodb-4.3.1.tgz" 718 | "version" "4.3.1" 719 | dependencies: 720 | "bson" "^4.6.1" 721 | "denque" "^2.0.1" 722 | "mongodb-connection-string-url" "^2.4.1" 723 | "socks" "^2.6.1" 724 | optionalDependencies: 725 | "saslprep" "^1.0.3" 726 | 727 | "mongoose@^6.0.9": 728 | "integrity" "sha512-6ApgF3rKYah5pUEO/1H+QrT0GT05OR7FprtVM45yzcrT/IKKlXizPyttrMiK1mLPt+55pGU7PMsBWY7yx/xZ4g==" 729 | "resolved" "https://registry.npmjs.org/mongoose/-/mongoose-6.2.9.tgz" 730 | "version" "6.2.9" 731 | dependencies: 732 | "bson" "^4.2.2" 733 | "kareem" "2.3.5" 734 | "mongodb" "4.3.1" 735 | "mpath" "0.8.4" 736 | "mquery" "4.0.2" 737 | "ms" "2.1.3" 738 | "sift" "16.0.0" 739 | 740 | "mpath@0.8.4": 741 | "integrity" "sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g==" 742 | "resolved" "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz" 743 | "version" "0.8.4" 744 | 745 | "mquery@4.0.2": 746 | "integrity" "sha512-oAVF0Nil1mT3rxty6Zln4YiD6x6QsUWYz927jZzjMxOK2aqmhEz5JQ7xmrKK7xRFA2dwV+YaOpKU/S+vfNqKxA==" 747 | "resolved" "https://registry.npmjs.org/mquery/-/mquery-4.0.2.tgz" 748 | "version" "4.0.2" 749 | dependencies: 750 | "debug" "4.x" 751 | 752 | "ms@2.1.2": 753 | "integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 754 | "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" 755 | "version" "2.1.2" 756 | 757 | "ms@2.1.3": 758 | "integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 759 | "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" 760 | "version" "2.1.3" 761 | 762 | "neo-async@^2.6.0": 763 | "integrity" "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" 764 | "resolved" "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" 765 | "version" "2.6.2" 766 | 767 | "node-fetch@^2.6.1": 768 | "integrity" "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==" 769 | "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" 770 | "version" "2.6.7" 771 | dependencies: 772 | "whatwg-url" "^5.0.0" 773 | 774 | "normalize-url@^6.0.1": 775 | "integrity" "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" 776 | "resolved" "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" 777 | "version" "6.1.0" 778 | 779 | "nwsapi@^2.2.0": 780 | "integrity" "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" 781 | "resolved" "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz" 782 | "version" "2.2.0" 783 | 784 | "once@^1.3.0", "once@^1.3.1", "once@^1.4.0": 785 | "integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" 786 | "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz" 787 | "version" "1.4.0" 788 | dependencies: 789 | "wrappy" "1" 790 | 791 | "optionator@^0.8.1": 792 | "integrity" "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==" 793 | "resolved" "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz" 794 | "version" "0.8.3" 795 | dependencies: 796 | "deep-is" "~0.1.3" 797 | "fast-levenshtein" "~2.0.6" 798 | "levn" "~0.3.0" 799 | "prelude-ls" "~1.1.2" 800 | "type-check" "~0.3.2" 801 | "word-wrap" "~1.2.3" 802 | 803 | "p-cancelable@^2.0.0": 804 | "integrity" "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" 805 | "resolved" "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz" 806 | "version" "2.1.1" 807 | 808 | "parse5@6.0.1": 809 | "integrity" "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" 810 | "resolved" "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" 811 | "version" "6.0.1" 812 | 813 | "path-is-absolute@^1.0.0": 814 | "integrity" "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 815 | "resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" 816 | "version" "1.0.1" 817 | 818 | "prelude-ls@~1.1.2": 819 | "integrity" "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" 820 | "resolved" "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" 821 | "version" "1.1.2" 822 | 823 | "progress@^2.0.3": 824 | "integrity" "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" 825 | "resolved" "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" 826 | "version" "2.0.3" 827 | 828 | "psl@^1.1.33": 829 | "integrity" "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" 830 | "resolved" "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz" 831 | "version" "1.8.0" 832 | 833 | "pump@^3.0.0": 834 | "integrity" "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==" 835 | "resolved" "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" 836 | "version" "3.0.0" 837 | dependencies: 838 | "end-of-stream" "^1.1.0" 839 | "once" "^1.3.1" 840 | 841 | "punycode@^2.1.1": 842 | "integrity" "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 843 | "resolved" "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" 844 | "version" "2.1.1" 845 | 846 | "quick-lru@^5.1.1": 847 | "integrity" "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" 848 | "resolved" "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" 849 | "version" "5.1.1" 850 | 851 | "reconlx@file:../../../../../usr/local/lib/node_modules/reconlx": 852 | "resolved" "file:../../../../../usr/local/lib/node_modules/reconlx" 853 | "version" "2.5.5" 854 | dependencies: 855 | "axios" "^0.21.1" 856 | "jsdom" "^16.7.0" 857 | "sourcebin" "^4.2.5" 858 | 859 | "resolve-alpn@^1.0.0": 860 | "integrity" "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" 861 | "resolved" "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz" 862 | "version" "1.2.1" 863 | 864 | "responselike@^2.0.0": 865 | "integrity" "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==" 866 | "resolved" "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz" 867 | "version" "2.0.0" 868 | dependencies: 869 | "lowercase-keys" "^2.0.0" 870 | 871 | "safer-buffer@>= 2.1.2 < 3": 872 | "integrity" "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 873 | "resolved" "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" 874 | "version" "2.1.2" 875 | 876 | "saslprep@^1.0.3": 877 | "integrity" "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==" 878 | "resolved" "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz" 879 | "version" "1.0.3" 880 | dependencies: 881 | "sparse-bitfield" "^3.0.3" 882 | 883 | "saxes@^5.0.1": 884 | "integrity" "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==" 885 | "resolved" "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz" 886 | "version" "5.0.1" 887 | dependencies: 888 | "xmlchars" "^2.2.0" 889 | 890 | "shiki@^0.9.8": 891 | "integrity" "sha512-/Y0z9IzhJ8nD9nbceORCqu6NgT9X6I8Fk8c3SICHI5NbZRLdZYFaB233gwct9sU0vvSypyaL/qaKvzyQGJBZSw==" 892 | "resolved" "https://registry.npmjs.org/shiki/-/shiki-0.9.15.tgz" 893 | "version" "0.9.15" 894 | dependencies: 895 | "jsonc-parser" "^3.0.0" 896 | "vscode-oniguruma" "^1.6.1" 897 | "vscode-textmate" "5.2.0" 898 | 899 | "sift@16.0.0": 900 | "integrity" "sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ==" 901 | "resolved" "https://registry.npmjs.org/sift/-/sift-16.0.0.tgz" 902 | "version" "16.0.0" 903 | 904 | "smart-buffer@^4.2.0": 905 | "integrity" "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" 906 | "resolved" "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" 907 | "version" "4.2.0" 908 | 909 | "socks@^2.6.1": 910 | "integrity" "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==" 911 | "resolved" "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz" 912 | "version" "2.6.2" 913 | dependencies: 914 | "ip" "^1.1.5" 915 | "smart-buffer" "^4.2.0" 916 | 917 | "source-map@^0.6.1", "source-map@~0.6.1": 918 | "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 919 | "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" 920 | "version" "0.6.1" 921 | 922 | "sourcebin@^4.2.5": 923 | "integrity" "sha512-Sfg8eLOxSiRG6Rz1Dw1xOMcOwIINUyOkbPZMH5zdBMVsF3O/o28DvL9+zCupcwsGP7WxKZy6HO/S8h+c4xmP0A==" 924 | "resolved" "https://registry.npmjs.org/sourcebin/-/sourcebin-4.3.5.tgz" 925 | "version" "4.3.5" 926 | dependencies: 927 | "@sourcebin/linguist" "latest" 928 | "got" "^11.8.1" 929 | 930 | "sparse-bitfield@^3.0.3": 931 | "integrity" "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=" 932 | "resolved" "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz" 933 | "version" "3.0.3" 934 | dependencies: 935 | "memory-pager" "^1.0.2" 936 | 937 | "symbol-tree@^3.2.4": 938 | "integrity" "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" 939 | "resolved" "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz" 940 | "version" "3.2.4" 941 | 942 | "tough-cookie@^4.0.0": 943 | "integrity" "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==" 944 | "resolved" "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz" 945 | "version" "4.0.0" 946 | dependencies: 947 | "psl" "^1.1.33" 948 | "punycode" "^2.1.1" 949 | "universalify" "^0.1.2" 950 | 951 | "tr46@^2.1.0": 952 | "integrity" "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==" 953 | "resolved" "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz" 954 | "version" "2.1.0" 955 | dependencies: 956 | "punycode" "^2.1.1" 957 | 958 | "tr46@^3.0.0": 959 | "integrity" "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==" 960 | "resolved" "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz" 961 | "version" "3.0.0" 962 | dependencies: 963 | "punycode" "^2.1.1" 964 | 965 | "tr46@~0.0.3": 966 | "integrity" "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" 967 | "resolved" "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" 968 | "version" "0.0.3" 969 | 970 | "ts-mixer@^6.0.0": 971 | "integrity" "sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg==" 972 | "resolved" "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.1.tgz" 973 | "version" "6.0.1" 974 | 975 | "ts-node@^10.2.0": 976 | "integrity" "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==" 977 | "resolved" "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz" 978 | "version" "10.7.0" 979 | dependencies: 980 | "@cspotcode/source-map-support" "0.7.0" 981 | "@tsconfig/node10" "^1.0.7" 982 | "@tsconfig/node12" "^1.0.7" 983 | "@tsconfig/node14" "^1.0.0" 984 | "@tsconfig/node16" "^1.0.2" 985 | "acorn" "^8.4.1" 986 | "acorn-walk" "^8.1.1" 987 | "arg" "^4.1.0" 988 | "create-require" "^1.1.0" 989 | "diff" "^4.0.1" 990 | "make-error" "^1.1.1" 991 | "v8-compile-cache-lib" "^3.0.0" 992 | "yn" "3.1.1" 993 | 994 | "tslib@^2.3.1": 995 | "integrity" "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" 996 | "resolved" "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz" 997 | "version" "2.3.1" 998 | 999 | "type-check@~0.3.2": 1000 | "integrity" "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=" 1001 | "resolved" "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz" 1002 | "version" "0.3.2" 1003 | dependencies: 1004 | "prelude-ls" "~1.1.2" 1005 | 1006 | "typedoc-default-themes@^0.12.10": 1007 | "integrity" "sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA==" 1008 | "resolved" "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz" 1009 | "version" "0.12.10" 1010 | 1011 | "typedoc@^0.21.2": 1012 | "integrity" "sha512-Y0wYIehkjkPfsp3pv86fp3WPHUcOf8pnQUDLwG1PqSccUSqdsv7Pz1Gd5WrTJvXQB2wO1mKlZ8qW8qMiopKyjA==" 1013 | "resolved" "https://registry.npmjs.org/typedoc/-/typedoc-0.21.10.tgz" 1014 | "version" "0.21.10" 1015 | dependencies: 1016 | "glob" "^7.1.7" 1017 | "handlebars" "^4.7.7" 1018 | "lunr" "^2.3.9" 1019 | "marked" "^4.0.10" 1020 | "minimatch" "^3.0.0" 1021 | "progress" "^2.0.3" 1022 | "shiki" "^0.9.8" 1023 | "typedoc-default-themes" "^0.12.10" 1024 | 1025 | "typescript@^4.3.5", "typescript@>=2.7", "typescript@4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x": 1026 | "integrity" "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==" 1027 | "resolved" "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz" 1028 | "version" "4.6.3" 1029 | 1030 | "uglify-js@^3.1.4": 1031 | "integrity" "sha512-6iCVm2omGJbsu3JWac+p6kUiOpg3wFO2f8lIXjfEb8RrmLjzog1wTPMmwKB7swfzzqxj9YM+sGUM++u1qN4qJg==" 1032 | "resolved" "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.3.tgz" 1033 | "version" "3.15.3" 1034 | 1035 | "universalify@^0.1.2": 1036 | "integrity" "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 1037 | "resolved" "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" 1038 | "version" "0.1.2" 1039 | 1040 | "v8-compile-cache-lib@^3.0.0": 1041 | "integrity" "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==" 1042 | "resolved" "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz" 1043 | "version" "3.0.0" 1044 | 1045 | "vscode-oniguruma@^1.6.1": 1046 | "integrity" "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==" 1047 | "resolved" "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz" 1048 | "version" "1.6.2" 1049 | 1050 | "vscode-textmate@5.2.0": 1051 | "integrity" "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==" 1052 | "resolved" "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz" 1053 | "version" "5.2.0" 1054 | 1055 | "w3c-hr-time@^1.0.2": 1056 | "integrity" "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==" 1057 | "resolved" "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz" 1058 | "version" "1.0.2" 1059 | dependencies: 1060 | "browser-process-hrtime" "^1.0.0" 1061 | 1062 | "w3c-xmlserializer@^2.0.0": 1063 | "integrity" "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==" 1064 | "resolved" "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz" 1065 | "version" "2.0.0" 1066 | dependencies: 1067 | "xml-name-validator" "^3.0.0" 1068 | 1069 | "webidl-conversions@^3.0.0": 1070 | "integrity" "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" 1071 | "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" 1072 | "version" "3.0.1" 1073 | 1074 | "webidl-conversions@^5.0.0": 1075 | "integrity" "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" 1076 | "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz" 1077 | "version" "5.0.0" 1078 | 1079 | "webidl-conversions@^6.1.0": 1080 | "integrity" "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" 1081 | "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz" 1082 | "version" "6.1.0" 1083 | 1084 | "webidl-conversions@^7.0.0": 1085 | "integrity" "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" 1086 | "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" 1087 | "version" "7.0.0" 1088 | 1089 | "whatwg-encoding@^1.0.5": 1090 | "integrity" "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==" 1091 | "resolved" "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz" 1092 | "version" "1.0.5" 1093 | dependencies: 1094 | "iconv-lite" "0.4.24" 1095 | 1096 | "whatwg-mimetype@^2.3.0": 1097 | "integrity" "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" 1098 | "resolved" "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz" 1099 | "version" "2.3.0" 1100 | 1101 | "whatwg-url@^11.0.0": 1102 | "integrity" "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==" 1103 | "resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz" 1104 | "version" "11.0.0" 1105 | dependencies: 1106 | "tr46" "^3.0.0" 1107 | "webidl-conversions" "^7.0.0" 1108 | 1109 | "whatwg-url@^5.0.0": 1110 | "integrity" "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=" 1111 | "resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" 1112 | "version" "5.0.0" 1113 | dependencies: 1114 | "tr46" "~0.0.3" 1115 | "webidl-conversions" "^3.0.0" 1116 | 1117 | "whatwg-url@^8.0.0", "whatwg-url@^8.5.0": 1118 | "integrity" "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==" 1119 | "resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz" 1120 | "version" "8.7.0" 1121 | dependencies: 1122 | "lodash" "^4.7.0" 1123 | "tr46" "^2.1.0" 1124 | "webidl-conversions" "^6.1.0" 1125 | 1126 | "word-wrap@~1.2.3": 1127 | "integrity" "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" 1128 | "resolved" "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" 1129 | "version" "1.2.3" 1130 | 1131 | "wordwrap@^1.0.0": 1132 | "integrity" "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" 1133 | "resolved" "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" 1134 | "version" "1.0.0" 1135 | 1136 | "wrappy@1": 1137 | "integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1138 | "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" 1139 | "version" "1.0.2" 1140 | 1141 | "ws@^7.4.6": 1142 | "integrity" "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==" 1143 | "resolved" "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz" 1144 | "version" "7.5.7" 1145 | 1146 | "ws@^8.4.0": 1147 | "integrity" "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==" 1148 | "resolved" "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz" 1149 | "version" "8.5.0" 1150 | 1151 | "xml-name-validator@^3.0.0": 1152 | "integrity" "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" 1153 | "resolved" "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz" 1154 | "version" "3.0.0" 1155 | 1156 | "xmlchars@^2.2.0": 1157 | "integrity" "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" 1158 | "resolved" "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz" 1159 | "version" "2.2.0" 1160 | 1161 | "yn@3.1.1": 1162 | "integrity" "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 1163 | "resolved" "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" 1164 | "version" "3.1.1" 1165 | 1166 | "zod@^3.11.6": 1167 | "integrity" "sha512-OzwRCSXB1+/8F6w6HkYHdbuWysYWnAF4fkRgKDcSFc54CE+Sv0rHXKfeNUReGCrHukm1LNpi6AYeXotznhYJbQ==" 1168 | "resolved" "https://registry.npmjs.org/zod/-/zod-3.14.3.tgz" 1169 | "version" "3.14.3" 1170 | --------------------------------------------------------------------------------