├── .eslintrc ├── .gitignore ├── .npmignore ├── .prettierignore ├── .prettierrc ├── .yarn ├── plugins │ └── @yarnpkg │ │ └── plugin-interactive-tools.cjs └── releases │ └── yarn-3.2.3.cjs ├── .yarnrc.yml ├── README.md ├── build.mjs ├── images └── chat.png ├── package.json ├── schema.bop ├── src ├── index.ts ├── internal │ ├── base.ts │ ├── decode.ts │ ├── encode.ts │ └── models.ts └── test.ts ├── tsconfig.json ├── watch.mjs └── yarn.lock /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "env": { 5 | "node": true 6 | }, 7 | "plugins": [ 8 | "@typescript-eslint" 9 | ], 10 | "extends": [ 11 | "eslint:recommended", 12 | "plugin:prettier/recommended", 13 | "plugin:@typescript-eslint/recommended" 14 | ], 15 | "ignorePatterns": [ 16 | "dist", 17 | "src/internal/models.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # misc 12 | .DS_Store 13 | *.pem 14 | 15 | # debug 16 | npm-debug.log* 17 | yarn-debug.log* 18 | yarn-error.log* 19 | 20 | # env files 21 | .env 22 | 23 | # output 24 | /lib 25 | 26 | # yarn v2 27 | .yarn/cache 28 | .yarn/unplugged 29 | .yarn/build-state.yml 30 | .yarn/install-state.gz 31 | .pnp.* 32 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | lib/index.dev.js 3 | .env 4 | .eslintrc 5 | .prettierignore 6 | .prettierrc 7 | .yarn 8 | build.mjs 9 | watch.mjs 10 | tsconfig.json 11 | schema.bop 12 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "tabWidth": 2, 5 | "useTabs": true 6 | } -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | plugins: 4 | - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs 5 | spec: "@yarnpkg/plugin-interactive-tools" 6 | 7 | yarnPath: .yarn/releases/yarn-3.2.3.cjs 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Twitch Chat Pubsub 2 | 3 | This is a proof-of-concept for using Twitch Chat as a PubSub system. It's not ready for production. Also, Twitch probably doesn't want you to do this, so don't. 4 | 5 | ![Example](./images/chat.png) 6 | 7 | ### Decodes to: 8 | ``` 9 | topic1 - Hello, World! 10 | topic2 - Hello, World! 11 | topic1 - aaaaaaaaaaaaaaaaaaaaaaaa... (2000 a's) 12 | ``` 13 | 14 | ## Idea 15 | 16 | Twitch Chat is scalable and reachable via websocket. If we have several thousand users who need to receive messages from a central server, we can abuse it as a PubSub system. 17 | 18 | ## How it works 19 | 20 | The publisher connects to a Twitch channel as an authenticated user. When sending messages: 21 | 22 | - If it fits in 500 characters, it's sent like this (encoded as binary via [Bebop](https://github.com/RainwayApp/bebop)): 23 | ```go 24 | struct FullMessage { 25 | string topic; 26 | string data; 27 | } 28 | ``` 29 | 30 | - Otherwise, it's split into one header and multiple parts, each of which is sent in a separate message: 31 | ```go 32 | struct SplitMessageHeader { 33 | guid id; 34 | string topic; 35 | uint16 parts; // Number of parts 36 | string data; // First part of data 37 | } 38 | ``` 39 | ```go 40 | struct SplitMessagePart { 41 | guid id; 42 | uint16 part; // Index of the part 43 | string data; // Part of data 44 | } 45 | ``` 46 | Once the subscriber receives all the parts, it can reassemble the message. This structure optimizes for as few sent messages as possible. 47 | 48 | We also use a custom base encoding to reduce the message size. Experimentally, the following alphabet seems to work: 49 | ``` 50 | :!"#$%&'()*+,-/0123456789;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ 51 | ``` 52 | 53 | This results in a message inflation size of `~110%`, versus the `~133%` of base64. Probably not worth it, but it's fun. 54 | 55 | 56 | ## How to use 57 | 58 | ```ts 59 | import { Publisher } from '@ottomated/twitch-chat-pubsub'; 60 | 61 | const publisher = new Publisher('channel-name', 'chatter-username', 'chatter-oauth-token'); 62 | 63 | await publisher.publish('topic', 'data'); 64 | ``` 65 | 66 | ```ts 67 | import { Subscriber } from '@ottomated/twitch-chat-pubsub'; 68 | 69 | const subscriber = new Subscriber('channel-name', 'chatter-username'); 70 | 71 | subscriber.on('topic', (data) => { 72 | console.log(data); 73 | }); 74 | ``` 75 | 76 | - `channel-name` is the name of the channel you want to use as a PubSub system. 77 | - `chatter-username` is the username of the user that will be used to send messages. 78 | - `chatter-oauth-token` is the OAuth token of that user. 79 | 80 | The first two parameters must be the same for both the publisher and the subscriber. 81 | -------------------------------------------------------------------------------- /build.mjs: -------------------------------------------------------------------------------- 1 | import { build } from 'esbuild'; 2 | 3 | build({ 4 | entryPoints: ['src/index.ts'], 5 | bundle: true, 6 | outfile: 'lib/index.js', 7 | external: ['util'], 8 | format: 'cjs', 9 | }); 10 | 11 | build({ 12 | entryPoints: ['src/index.ts'], 13 | bundle: true, 14 | outfile: 'lib/index.mjs', 15 | external: ['util'], 16 | format: 'esm', 17 | }); 18 | -------------------------------------------------------------------------------- /images/chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ottomated/twitch-chat-pubsub/fe0ef9766eec88e18c24d9f055f17840682d54c1/images/chat.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twitch-chat-pubsub", 3 | "version": "0.1.0", 4 | "author": { 5 | "name": "Ottomated", 6 | "email": "otto@ottomated.net" 7 | }, 8 | "main": "lib/index.js", 9 | "module": "lib/index.mjs", 10 | "scripts": { 11 | "dev": "node watch.mjs", 12 | "prepublish": "node build.mjs", 13 | "bebop": "bebopc --files schema.bop --ts lib/internal/models.ts" 14 | }, 15 | "dependencies": { 16 | "base-x": "^4.0.0", 17 | "bebop": "^2.4.6", 18 | "eventemitter3": "^4.0.7", 19 | "tmi.js": "^1.8.5", 20 | "uuid": "^9.0.0" 21 | }, 22 | "devDependencies": { 23 | "@types/node": "^18.7.23", 24 | "@types/tmi.js": "^1.8.1", 25 | "@types/uuid": "^8.3.4", 26 | "@typescript-eslint/eslint-plugin": "^5.38.1", 27 | "@typescript-eslint/parser": "^5.38.1", 28 | "bebop-tools": "^2.4.6", 29 | "dotenv": "^16.0.3", 30 | "esbuild": "^0.15.10", 31 | "eslint": "^8.24.0", 32 | "eslint-config-prettier": "^8.5.0", 33 | "eslint-plugin-prettier": "^4.2.1", 34 | "prettier": "^2.7.1", 35 | "typescript": "^4.8.4" 36 | }, 37 | "packageManager": "yarn@3.2.3" 38 | } 39 | -------------------------------------------------------------------------------- /schema.bop: -------------------------------------------------------------------------------- 1 | union Message { 2 | 1 -> struct FullMessage { 3 | string topic; 4 | string data; 5 | } 6 | 2 -> struct SplitMessageHeader { 7 | guid id; 8 | string topic; 9 | uint16 parts; 10 | string data; 11 | } 12 | 3 -> struct SplitMessagePart { 13 | guid id; 14 | uint16 index; 15 | string data; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from 'eventemitter3'; 2 | import { Client } from 'tmi.js'; 3 | import { Decoder } from './internal/decode'; 4 | import { encodeMessage } from './internal/encode'; 5 | 6 | export class Publisher { 7 | private client: Client; 8 | 9 | constructor(public channel: string, username: string, password: string) { 10 | this.client = new Client({ 11 | identity: { 12 | username, 13 | password, 14 | }, 15 | channels: [channel], 16 | }); 17 | } 18 | 19 | public async connect() { 20 | await this.client.connect(); 21 | } 22 | 23 | public async disconnect() { 24 | await this.client.disconnect(); 25 | } 26 | 27 | public async publish(topic: string, message: string) { 28 | const msgs = encodeMessage(topic, message); 29 | for (const msg of msgs) { 30 | await this.client.say(this.channel, msg); 31 | await new Promise((resolve) => setTimeout(resolve, 200)); 32 | } 33 | } 34 | } 35 | 36 | export class Subscriber extends EventEmitter { 37 | private client: Client; 38 | private decoder: Decoder; 39 | 40 | constructor(public channel: string, username: string) { 41 | super(); 42 | this.decoder = new Decoder(); 43 | this.client = new Client({ 44 | channels: [channel], 45 | }); 46 | this.client.on('message', (_, user, message) => { 47 | if (user.username !== username) return; 48 | const event = this.decoder.onMessage(message); 49 | if (event) { 50 | this.emit(event[0], event[1]); 51 | } 52 | }); 53 | } 54 | 55 | public async connect() { 56 | await this.client.connect(); 57 | } 58 | 59 | public async disconnect() { 60 | await this.client.disconnect(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/internal/base.ts: -------------------------------------------------------------------------------- 1 | import makeBase from 'base-x'; 2 | 3 | // determined through experimentation, should probably be checked 4 | export const charset = 5 | ':!"#$%&\'()*+,-/0123456789;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'; 6 | 7 | export const base = makeBase(charset); 8 | 9 | // The factor by which the message length is multiplied when encoded to get the byte length 10 | export const messageFactor = Math.log(256) / Math.log(charset.length); 11 | 12 | // Twitch allows 500 bytes, but we give it a little more room 13 | export const maximumMessageByteLength = 495; 14 | -------------------------------------------------------------------------------- /src/internal/decode.ts: -------------------------------------------------------------------------------- 1 | import { base } from './base'; 2 | import { 3 | FullMessage, 4 | ISplitMessageHeader, 5 | ISplitMessagePart, 6 | Message, 7 | SplitMessageHeader, 8 | } from './models'; 9 | 10 | type PartialData = { 11 | header?: ISplitMessageHeader; 12 | parts: Record; 13 | }; 14 | 15 | export class Decoder { 16 | private partialMessages = new Map(); 17 | 18 | onMessage(data: string): [string, string] | undefined { 19 | if (data[0] !== 'A' || data[data.length - 1] !== 'A') return; 20 | // Decode the message 21 | const message = Message.decode(base.decode(data.slice(1, -1))); 22 | 23 | // If the full message fits in one, return it 24 | if (message.discriminator === FullMessage.discriminator) { 25 | return [message.value.topic, message.value.data]; 26 | } 27 | 28 | const messageId = message.value.id; 29 | // Grab the existing partial message data 30 | let partialData = this.partialMessages.get(messageId); 31 | if (!partialData) { 32 | partialData = { parts: {} }; 33 | this.partialMessages.set(messageId, partialData); 34 | } 35 | 36 | // If it's the header, store it 37 | if (message.discriminator === SplitMessageHeader.discriminator) { 38 | if (partialData.header) console.warn('Received duplicate header'); 39 | partialData.header = message.value; 40 | } else { 41 | // If it's a part, store it 42 | if (partialData.parts[message.value.index]) { 43 | console.warn('Received duplicate part'); 44 | } 45 | 46 | partialData.parts[message.value.index] = message.value; 47 | } 48 | const completeMessage = this.checkPartialCompletion(partialData); 49 | if (completeMessage) { 50 | this.partialMessages.delete(messageId); 51 | return completeMessage; 52 | } 53 | } 54 | /** 55 | * Checks if the partial message is complete, and if so, returns it 56 | * @param partialData The message data that's been received so far 57 | * @returns [topic, message] if the message is complete, undefined otherwise 58 | */ 59 | checkPartialCompletion( 60 | partialData: PartialData 61 | ): [string, string] | undefined { 62 | // Need a header 63 | if (!partialData.header) return; 64 | 65 | // Get the part count from the header 66 | const partCount = partialData.header.parts; 67 | 68 | // Data will be concatenated in this string 69 | let data = partialData.header.data; 70 | 71 | // Check if all parts have been received 72 | for (let i = 0; i < partCount; i++) { 73 | const part = partialData.parts[i]; 74 | if (!part) return; 75 | data += part.data; 76 | } 77 | return [partialData.header.topic, data]; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/internal/encode.ts: -------------------------------------------------------------------------------- 1 | import { base, maximumMessageByteLength, messageFactor } from './base'; 2 | import { 3 | FullMessage, 4 | Message, 5 | SplitMessageHeader, 6 | SplitMessagePart, 7 | } from './models'; 8 | import { v4 } from 'uuid'; 9 | 10 | function encodeFullMessage(topic: string, data: string): string { 11 | return ( 12 | 'A' + 13 | base.encode( 14 | Message.encode({ 15 | discriminator: FullMessage.discriminator, 16 | value: { 17 | topic, 18 | data, 19 | }, 20 | }) 21 | ) + 22 | 'A' 23 | ); 24 | } 25 | 26 | export function encodeMessage(topic: string, data: string): string[] { 27 | // Encode it in one message if it fits 28 | const singleMessageLength = getMessageLength(topic, data); 29 | if (singleMessageLength <= maximumMessageByteLength) { 30 | return [encodeFullMessage(topic, data)]; 31 | } 32 | // Calculate header data length 33 | const headerLength = getHeaderDataLength(topic); 34 | 35 | const chatMessages: string[] = []; 36 | const id = v4(); 37 | 38 | // Slice the data up into chunks and encode them 39 | let dataSliceStart = headerLength; 40 | let index = 0; 41 | while (dataSliceStart < data.length) { 42 | const partLength = getPartDataLength(); 43 | const view = data.slice(dataSliceStart, dataSliceStart + partLength); 44 | chatMessages.push( 45 | base.encode( 46 | Message.encode({ 47 | discriminator: SplitMessagePart.discriminator, 48 | value: { 49 | id, 50 | index, 51 | data: view, 52 | }, 53 | }) 54 | ) 55 | ); 56 | index++; 57 | dataSliceStart += partLength; 58 | } 59 | // Encode the header (do this after the parts so we know how many there are) 60 | chatMessages.unshift( 61 | base.encode( 62 | Message.encode({ 63 | discriminator: SplitMessageHeader.discriminator, 64 | value: { 65 | id, 66 | topic, 67 | parts: chatMessages.length, 68 | data: data.slice(0, headerLength), 69 | }, 70 | }) 71 | ) 72 | ); 73 | return chatMessages.map((m) => `A${m}A`); 74 | } 75 | 76 | /** 77 | * @param topic The topic of the message 78 | * @param data The data of the message 79 | * @returns The length of the message if it were encoded in one message 80 | */ 81 | function getMessageLength(topic: string, data: string) { 82 | return ( 83 | 4 + // message length 84 | 1 + // discriminator 85 | 4 + // topic length 86 | topic.length + // topic string 87 | 4 + // data length 88 | data.length 89 | ); 90 | } 91 | 92 | /** 93 | * @returns The length of the data that can be stored in the header 94 | */ 95 | function getHeaderDataLength(topic: string): number { 96 | return Math.floor( 97 | maximumMessageByteLength / messageFactor - 98 | (4 + // message length 99 | 1 + // discriminator 100 | 16 + // guid 101 | 4 + // topic length 102 | topic.length + // topic string 103 | 2 + // number of parts 104 | 4) // data length 105 | ); 106 | } 107 | /** 108 | * @returns The length of the data that can be stored in a part 109 | */ 110 | function getPartDataLength(): number { 111 | return Math.floor( 112 | maximumMessageByteLength / messageFactor - 113 | (4 + // message length 114 | 1 + // discriminator 115 | 16 + // guid 116 | 2 + // part index 117 | 4) // data length 118 | ); 119 | } 120 | -------------------------------------------------------------------------------- /src/internal/models.ts: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // 5 | // 6 | // bebopc version: 7 | // 2.4.6 8 | // 9 | // 10 | // bebopc source: 11 | // https://github.com/RainwayApp/bebop 12 | // 13 | // 14 | // Changes to this file may cause incorrect behavior and will be lost if 15 | // the code is regenerated. 16 | // 17 | import { BebopView, BebopRuntimeError } from "bebop"; 18 | 19 | export interface IFullMessage { 20 | topic: string; 21 | data: string; 22 | } 23 | 24 | export const FullMessage = { 25 | discriminator: 1 as 1, 26 | encode(message: IFullMessage): Uint8Array { 27 | const view = BebopView.getInstance(); 28 | view.startWriting(); 29 | this.encodeInto(message, view); 30 | return view.toArray(); 31 | }, 32 | 33 | encodeInto(message: IFullMessage, view: BebopView): number { 34 | const before = view.length; 35 | view.writeString(message.topic); 36 | view.writeString(message.data); 37 | const after = view.length; 38 | return after - before; 39 | }, 40 | 41 | decode(buffer: Uint8Array): IFullMessage { 42 | const view = BebopView.getInstance(); 43 | view.startReading(buffer); 44 | return this.readFrom(view); 45 | }, 46 | 47 | readFrom(view: BebopView): IFullMessage { 48 | let field0: string; 49 | field0 = view.readString(); 50 | let field1: string; 51 | field1 = view.readString(); 52 | let message: IFullMessage = { 53 | topic: field0, 54 | data: field1, 55 | }; 56 | return message; 57 | }, 58 | }; 59 | 60 | export interface ISplitMessageHeader { 61 | id: string; 62 | topic: string; 63 | parts: number; 64 | data: string; 65 | } 66 | 67 | export const SplitMessageHeader = { 68 | discriminator: 2 as 2, 69 | encode(message: ISplitMessageHeader): Uint8Array { 70 | const view = BebopView.getInstance(); 71 | view.startWriting(); 72 | this.encodeInto(message, view); 73 | return view.toArray(); 74 | }, 75 | 76 | encodeInto(message: ISplitMessageHeader, view: BebopView): number { 77 | const before = view.length; 78 | view.writeGuid(message.id); 79 | view.writeString(message.topic); 80 | view.writeUint16(message.parts); 81 | view.writeString(message.data); 82 | const after = view.length; 83 | return after - before; 84 | }, 85 | 86 | decode(buffer: Uint8Array): ISplitMessageHeader { 87 | const view = BebopView.getInstance(); 88 | view.startReading(buffer); 89 | return this.readFrom(view); 90 | }, 91 | 92 | readFrom(view: BebopView): ISplitMessageHeader { 93 | let field0: string; 94 | field0 = view.readGuid(); 95 | let field1: string; 96 | field1 = view.readString(); 97 | let field2: number; 98 | field2 = view.readUint16(); 99 | let field3: string; 100 | field3 = view.readString(); 101 | let message: ISplitMessageHeader = { 102 | id: field0, 103 | topic: field1, 104 | parts: field2, 105 | data: field3, 106 | }; 107 | return message; 108 | }, 109 | }; 110 | 111 | export interface ISplitMessagePart { 112 | id: string; 113 | index: number; 114 | data: string; 115 | } 116 | 117 | export const SplitMessagePart = { 118 | discriminator: 3 as 3, 119 | encode(message: ISplitMessagePart): Uint8Array { 120 | const view = BebopView.getInstance(); 121 | view.startWriting(); 122 | this.encodeInto(message, view); 123 | return view.toArray(); 124 | }, 125 | 126 | encodeInto(message: ISplitMessagePart, view: BebopView): number { 127 | const before = view.length; 128 | view.writeGuid(message.id); 129 | view.writeUint16(message.index); 130 | view.writeString(message.data); 131 | const after = view.length; 132 | return after - before; 133 | }, 134 | 135 | decode(buffer: Uint8Array): ISplitMessagePart { 136 | const view = BebopView.getInstance(); 137 | view.startReading(buffer); 138 | return this.readFrom(view); 139 | }, 140 | 141 | readFrom(view: BebopView): ISplitMessagePart { 142 | let field0: string; 143 | field0 = view.readGuid(); 144 | let field1: number; 145 | field1 = view.readUint16(); 146 | let field2: string; 147 | field2 = view.readString(); 148 | let message: ISplitMessagePart = { 149 | id: field0, 150 | index: field1, 151 | data: field2, 152 | }; 153 | return message; 154 | }, 155 | }; 156 | 157 | export type IMessage 158 | = { discriminator: 1, value: IFullMessage } 159 | | { discriminator: 2, value: ISplitMessageHeader } 160 | | { discriminator: 3, value: ISplitMessagePart }; 161 | 162 | export const Message = { 163 | encode(message: IMessage): Uint8Array { 164 | const view = BebopView.getInstance(); 165 | view.startWriting(); 166 | this.encodeInto(message, view); 167 | return view.toArray(); 168 | }, 169 | 170 | encodeInto(message: IMessage, view: BebopView): number { 171 | const before = view.length; 172 | const pos = view.reserveMessageLength(); 173 | const start = view.length + 1; 174 | view.writeByte(message.discriminator); 175 | switch (message.discriminator) { 176 | case 1: 177 | FullMessage.encodeInto(message.value, view); 178 | break; 179 | case 2: 180 | SplitMessageHeader.encodeInto(message.value, view); 181 | break; 182 | case 3: 183 | SplitMessagePart.encodeInto(message.value, view); 184 | break; 185 | } 186 | const end = view.length; 187 | view.fillMessageLength(pos, end - start); 188 | const after = view.length; 189 | return after - before; 190 | }, 191 | 192 | decode(buffer: Uint8Array): IMessage { 193 | const view = BebopView.getInstance(); 194 | view.startReading(buffer); 195 | return this.readFrom(view); 196 | }, 197 | 198 | readFrom(view: BebopView): IMessage { 199 | const length = view.readMessageLength(); 200 | const end = view.index + 1 + length; 201 | switch (view.readByte()) { 202 | case 1: 203 | return { discriminator: 1, value: FullMessage.readFrom(view) }; 204 | case 2: 205 | return { discriminator: 2, value: SplitMessageHeader.readFrom(view) }; 206 | case 3: 207 | return { discriminator: 3, value: SplitMessagePart.readFrom(view) }; 208 | default: 209 | view.index = end; 210 | throw new BebopRuntimeError("Unrecognized discriminator while decoding Message"); 211 | } 212 | }, 213 | }; 214 | 215 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | import { Publisher, Subscriber } from './index'; 2 | import { config } from 'dotenv'; 3 | config(); 4 | 5 | const publisher = new Publisher( 6 | 'cheatstream', 7 | 'ottomated', 8 | process.env.OAUTH_TOKEN as string 9 | ); 10 | 11 | const subscriber = new Subscriber('cheatstream', 'ottomated'); 12 | 13 | (async () => { 14 | const longMessage = 'a'.repeat(2000); 15 | 16 | await publisher.connect(); 17 | await subscriber.connect(); 18 | subscriber.on('topic1', (message) => { 19 | console.log('Topic 1:', message); 20 | }); 21 | subscriber.on('topic2', (message) => { 22 | console.log('Topic 2:', message); 23 | }); 24 | await publisher.publish('topic1', 'Hello, world!'); 25 | await publisher.publish('topic2', 'Hello, world!'); 26 | await publisher.publish('topic1', longMessage); 27 | })(); 28 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "lib": [ 5 | "esnext" 6 | ], 7 | "allowJs": true, 8 | "baseUrl": ".", 9 | "skipLibCheck": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "incremental": true, 13 | "esModuleInterop": true, 14 | "outDir": "dist", 15 | "module": "CommonJS", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true 18 | }, 19 | "include": [ 20 | "src/**/*.ts" 21 | ], 22 | "exclude": [ 23 | "node_modules", 24 | "lib" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /watch.mjs: -------------------------------------------------------------------------------- 1 | import { build } from 'esbuild'; 2 | import { spawn } from 'child_process'; 3 | 4 | let process; 5 | 6 | build({ 7 | entryPoints: ['src/test.ts'], 8 | bundle: true, 9 | platform: 'node', 10 | outfile: 'lib/index.dev.js', 11 | watch: { 12 | onRebuild: spawnResult, 13 | }, 14 | }).then(() => spawnResult()); 15 | 16 | function spawnResult(err) { 17 | if (process) process.kill(); 18 | 19 | if (err) console.error(err); 20 | // run output 21 | console.log('Running:\n'); 22 | process = spawn('node', ['lib/index.dev.js'], { stdio: 'inherit' }); 23 | } 24 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # This file is generated by running "yarn install" inside your project. 2 | # Manual changes might be lost - proceed with caution! 3 | 4 | __metadata: 5 | version: 6 6 | cacheKey: 8 7 | 8 | "@esbuild/android-arm@npm:0.15.10": 9 | version: 0.15.10 10 | resolution: "@esbuild/android-arm@npm:0.15.10" 11 | conditions: os=android & cpu=arm 12 | languageName: node 13 | linkType: hard 14 | 15 | "@esbuild/linux-loong64@npm:0.15.10": 16 | version: 0.15.10 17 | resolution: "@esbuild/linux-loong64@npm:0.15.10" 18 | conditions: os=linux & cpu=loong64 19 | languageName: node 20 | linkType: hard 21 | 22 | "@eslint/eslintrc@npm:^1.3.2": 23 | version: 1.3.2 24 | resolution: "@eslint/eslintrc@npm:1.3.2" 25 | dependencies: 26 | ajv: ^6.12.4 27 | debug: ^4.3.2 28 | espree: ^9.4.0 29 | globals: ^13.15.0 30 | ignore: ^5.2.0 31 | import-fresh: ^3.2.1 32 | js-yaml: ^4.1.0 33 | minimatch: ^3.1.2 34 | strip-json-comments: ^3.1.1 35 | checksum: 2074dca47d7e1c5c6323ff353f690f4b25d3ab53fe7d27337e2592d37a894cf60ca0e85ca66b50ff2db0bc7e630cc1e9c7347d65bb185b61416565584c38999c 36 | languageName: node 37 | linkType: hard 38 | 39 | "@humanwhocodes/config-array@npm:^0.10.5": 40 | version: 0.10.7 41 | resolution: "@humanwhocodes/config-array@npm:0.10.7" 42 | dependencies: 43 | "@humanwhocodes/object-schema": ^1.2.1 44 | debug: ^4.1.1 45 | minimatch: ^3.0.4 46 | checksum: 009d64be8d5bd098ff04e10af79e34f5633245250581fca032fac12a8667b2df8e7d169e69c05bff4d83ea3dd3c7d2d0e05ea9b94d89a7d092e26530caf6f8a3 47 | languageName: node 48 | linkType: hard 49 | 50 | "@humanwhocodes/gitignore-to-minimatch@npm:^1.0.2": 51 | version: 1.0.2 52 | resolution: "@humanwhocodes/gitignore-to-minimatch@npm:1.0.2" 53 | checksum: aba5c40c9e3770ed73a558b0bfb53323842abfc2ce58c91d7e8b1073995598e6374456d38767be24ab6176915f0a8d8b23eaae5c85e2b488c0dccca6d795e2ad 54 | languageName: node 55 | linkType: hard 56 | 57 | "@humanwhocodes/module-importer@npm:^1.0.1": 58 | version: 1.0.1 59 | resolution: "@humanwhocodes/module-importer@npm:1.0.1" 60 | checksum: 0fd22007db8034a2cdf2c764b140d37d9020bbfce8a49d3ec5c05290e77d4b0263b1b972b752df8c89e5eaa94073408f2b7d977aed131faf6cf396ebb5d7fb61 61 | languageName: node 62 | linkType: hard 63 | 64 | "@humanwhocodes/object-schema@npm:^1.2.1": 65 | version: 1.2.1 66 | resolution: "@humanwhocodes/object-schema@npm:1.2.1" 67 | checksum: a824a1ec31591231e4bad5787641f59e9633827d0a2eaae131a288d33c9ef0290bd16fda8da6f7c0fcb014147865d12118df10db57f27f41e20da92369fcb3f1 68 | languageName: node 69 | linkType: hard 70 | 71 | "@nodelib/fs.scandir@npm:2.1.5": 72 | version: 2.1.5 73 | resolution: "@nodelib/fs.scandir@npm:2.1.5" 74 | dependencies: 75 | "@nodelib/fs.stat": 2.0.5 76 | run-parallel: ^1.1.9 77 | checksum: a970d595bd23c66c880e0ef1817791432dbb7acbb8d44b7e7d0e7a22f4521260d4a83f7f9fd61d44fda4610105577f8f58a60718105fb38352baed612fd79e59 78 | languageName: node 79 | linkType: hard 80 | 81 | "@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": 82 | version: 2.0.5 83 | resolution: "@nodelib/fs.stat@npm:2.0.5" 84 | checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 85 | languageName: node 86 | linkType: hard 87 | 88 | "@nodelib/fs.walk@npm:^1.2.3": 89 | version: 1.2.8 90 | resolution: "@nodelib/fs.walk@npm:1.2.8" 91 | dependencies: 92 | "@nodelib/fs.scandir": 2.1.5 93 | fastq: ^1.6.0 94 | checksum: 190c643f156d8f8f277bf2a6078af1ffde1fd43f498f187c2db24d35b4b4b5785c02c7dc52e356497b9a1b65b13edc996de08de0b961c32844364da02986dc53 95 | languageName: node 96 | linkType: hard 97 | 98 | "@types/json-schema@npm:^7.0.9": 99 | version: 7.0.9 100 | resolution: "@types/json-schema@npm:7.0.9" 101 | checksum: 259d0e25f11a21ba5c708f7ea47196bd396e379fddb79c76f9f4f62c945879dc21657904914313ec2754e443c5018ea8372362f323f30e0792897fdb2098a705 102 | languageName: node 103 | linkType: hard 104 | 105 | "@types/node@npm:^14.14.10, @types/node@npm:^14.14.7": 106 | version: 14.18.31 107 | resolution: "@types/node@npm:14.18.31" 108 | checksum: df33021d673a5e3c943cf96c9f3fbccf364d20f487b2ab7eb49db144974c2049f0a91e9358df09235f543c1f0b11388c5b0b636ae1f2ed55a27c75f63bc3d2c5 109 | languageName: node 110 | linkType: hard 111 | 112 | "@types/node@npm:^18.7.23": 113 | version: 18.7.23 114 | resolution: "@types/node@npm:18.7.23" 115 | checksum: 2c8df0830d8345e5cd1ca17feb9cf43fa667aae749888e0a068c5c1b35eaedd2f9b24ed987a0758078395edf7a03681e5e0b7790a518ff7afe1ff6d8459f7b4a 116 | languageName: node 117 | linkType: hard 118 | 119 | "@types/tmi.js@npm:^1.8.1": 120 | version: 1.8.1 121 | resolution: "@types/tmi.js@npm:1.8.1" 122 | checksum: 3411ba9cb00f1b221f8e5cf3839c0b13193f75e512e034fb3d9558cebf2d7cfc4707e10385d7fa96ef18d370195e282f8ceaa6f998014ef7c2b68f83aa7c3ae7 123 | languageName: node 124 | linkType: hard 125 | 126 | "@types/uuid@npm:^8.3.4": 127 | version: 8.3.4 128 | resolution: "@types/uuid@npm:8.3.4" 129 | checksum: 6f11f3ff70f30210edaa8071422d405e9c1d4e53abbe50fdce365150d3c698fe7bbff65c1e71ae080cbfb8fded860dbb5e174da96fdbbdfcaa3fb3daa474d20f 130 | languageName: node 131 | linkType: hard 132 | 133 | "@typescript-eslint/eslint-plugin@npm:^5.38.1": 134 | version: 5.38.1 135 | resolution: "@typescript-eslint/eslint-plugin@npm:5.38.1" 136 | dependencies: 137 | "@typescript-eslint/scope-manager": 5.38.1 138 | "@typescript-eslint/type-utils": 5.38.1 139 | "@typescript-eslint/utils": 5.38.1 140 | debug: ^4.3.4 141 | ignore: ^5.2.0 142 | regexpp: ^3.2.0 143 | semver: ^7.3.7 144 | tsutils: ^3.21.0 145 | peerDependencies: 146 | "@typescript-eslint/parser": ^5.0.0 147 | eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 148 | peerDependenciesMeta: 149 | typescript: 150 | optional: true 151 | checksum: a8895588022f75b2bf994ce52f7109d8814e0f5b3bef0d4fac19dc86a926202ca204bfca8c0e5a033d7566bae90815a772b64bcdc61c349f47ddd52d91989de5 152 | languageName: node 153 | linkType: hard 154 | 155 | "@typescript-eslint/parser@npm:^5.38.1": 156 | version: 5.38.1 157 | resolution: "@typescript-eslint/parser@npm:5.38.1" 158 | dependencies: 159 | "@typescript-eslint/scope-manager": 5.38.1 160 | "@typescript-eslint/types": 5.38.1 161 | "@typescript-eslint/typescript-estree": 5.38.1 162 | debug: ^4.3.4 163 | peerDependencies: 164 | eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 165 | peerDependenciesMeta: 166 | typescript: 167 | optional: true 168 | checksum: 3f84b33d598d9acef99f087bdfe319e74f838d3442d6a15f2498f077a1473f124e3ec6698dbb256f56c51ce38abd91c0ffb90f0856989309e28c43e005d99215 169 | languageName: node 170 | linkType: hard 171 | 172 | "@typescript-eslint/scope-manager@npm:5.38.1": 173 | version: 5.38.1 174 | resolution: "@typescript-eslint/scope-manager@npm:5.38.1" 175 | dependencies: 176 | "@typescript-eslint/types": 5.38.1 177 | "@typescript-eslint/visitor-keys": 5.38.1 178 | checksum: c3b38ca0074d09e26c30b4385c18933f8a6418c923a24c7f4c2297af60a85d604320f119863676f49ea4254b3c01c112504547436eda4951ade609e8d7f438a7 179 | languageName: node 180 | linkType: hard 181 | 182 | "@typescript-eslint/type-utils@npm:5.38.1": 183 | version: 5.38.1 184 | resolution: "@typescript-eslint/type-utils@npm:5.38.1" 185 | dependencies: 186 | "@typescript-eslint/typescript-estree": 5.38.1 187 | "@typescript-eslint/utils": 5.38.1 188 | debug: ^4.3.4 189 | tsutils: ^3.21.0 190 | peerDependencies: 191 | eslint: "*" 192 | peerDependenciesMeta: 193 | typescript: 194 | optional: true 195 | checksum: 1e5fbb5cd2cd97d8d6aaf6b0d1262517e74aba006ffc61526528352a8ab99205456d6247da8252388e868ed7ee8f6c2fa8e108dad68b696cbdbcef6473579173 196 | languageName: node 197 | linkType: hard 198 | 199 | "@typescript-eslint/types@npm:5.38.1": 200 | version: 5.38.1 201 | resolution: "@typescript-eslint/types@npm:5.38.1" 202 | checksum: 384f7fe9a1995d87507049a868aa1a1f9eb28af913e704540e1494c8c630985f9ef4f4e6bdd4df0d83cbe4611c4e6f4f07d5d91bfa57c88242fb227a6d828b7e 203 | languageName: node 204 | linkType: hard 205 | 206 | "@typescript-eslint/typescript-estree@npm:5.38.1": 207 | version: 5.38.1 208 | resolution: "@typescript-eslint/typescript-estree@npm:5.38.1" 209 | dependencies: 210 | "@typescript-eslint/types": 5.38.1 211 | "@typescript-eslint/visitor-keys": 5.38.1 212 | debug: ^4.3.4 213 | globby: ^11.1.0 214 | is-glob: ^4.0.3 215 | semver: ^7.3.7 216 | tsutils: ^3.21.0 217 | peerDependenciesMeta: 218 | typescript: 219 | optional: true 220 | checksum: ec73496f73bd7f97d1585d25484874f092141a5f92ade7bd324fb76ef52888f0d77cc4375bdecc92cc3bacf5d61d65197acbb9af4fd9322b51db286c68a320c6 221 | languageName: node 222 | linkType: hard 223 | 224 | "@typescript-eslint/utils@npm:5.38.1": 225 | version: 5.38.1 226 | resolution: "@typescript-eslint/utils@npm:5.38.1" 227 | dependencies: 228 | "@types/json-schema": ^7.0.9 229 | "@typescript-eslint/scope-manager": 5.38.1 230 | "@typescript-eslint/types": 5.38.1 231 | "@typescript-eslint/typescript-estree": 5.38.1 232 | eslint-scope: ^5.1.1 233 | eslint-utils: ^3.0.0 234 | peerDependencies: 235 | eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 236 | checksum: 06646ddeb6c1a5dac01e8336dff458cf37dff0d3d5a2f304048a4d6d8f62d504c5330a8b046ec66f6777f324bc1afe6a3f7ea1c5b015b123ab7062e8e22aff67 237 | languageName: node 238 | linkType: hard 239 | 240 | "@typescript-eslint/visitor-keys@npm:5.38.1": 241 | version: 5.38.1 242 | resolution: "@typescript-eslint/visitor-keys@npm:5.38.1" 243 | dependencies: 244 | "@typescript-eslint/types": 5.38.1 245 | eslint-visitor-keys: ^3.3.0 246 | checksum: 01c83a42900f8ab721bd0857abcc000a15183eb26d2d61cceeaef018a83a91325f48c0112d4356383c41dce23174a305bb3352af4705a61d1da46f8ac0e88340 247 | languageName: node 248 | linkType: hard 249 | 250 | "acorn-jsx@npm:^5.3.2": 251 | version: 5.3.2 252 | resolution: "acorn-jsx@npm:5.3.2" 253 | peerDependencies: 254 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 255 | checksum: c3d3b2a89c9a056b205b69530a37b972b404ee46ec8e5b341666f9513d3163e2a4f214a71f4dfc7370f5a9c07472d2fd1c11c91c3f03d093e37637d95da98950 256 | languageName: node 257 | linkType: hard 258 | 259 | "acorn@npm:^8.8.0": 260 | version: 8.8.0 261 | resolution: "acorn@npm:8.8.0" 262 | bin: 263 | acorn: bin/acorn 264 | checksum: 7270ca82b242eafe5687a11fea6e088c960af712683756abf0791b68855ea9cace3057bd5e998ffcef50c944810c1e0ca1da526d02b32110e13c722aa959afdc 265 | languageName: node 266 | linkType: hard 267 | 268 | "ajv@npm:^6.10.0, ajv@npm:^6.12.4": 269 | version: 6.12.6 270 | resolution: "ajv@npm:6.12.6" 271 | dependencies: 272 | fast-deep-equal: ^3.1.1 273 | fast-json-stable-stringify: ^2.0.0 274 | json-schema-traverse: ^0.4.1 275 | uri-js: ^4.2.2 276 | checksum: 874972efe5c4202ab0a68379481fbd3d1b5d0a7bd6d3cc21d40d3536ebff3352a2a1fabb632d4fd2cc7fe4cbdcd5ed6782084c9bbf7f32a1536d18f9da5007d4 277 | languageName: node 278 | linkType: hard 279 | 280 | "ansi-regex@npm:^5.0.1": 281 | version: 5.0.1 282 | resolution: "ansi-regex@npm:5.0.1" 283 | checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b 284 | languageName: node 285 | linkType: hard 286 | 287 | "ansi-styles@npm:^4.1.0": 288 | version: 4.3.0 289 | resolution: "ansi-styles@npm:4.3.0" 290 | dependencies: 291 | color-convert: ^2.0.1 292 | checksum: 513b44c3b2105dd14cc42a19271e80f386466c4be574bccf60b627432f9198571ebf4ab1e4c3ba17347658f4ee1711c163d574248c0c1cdc2d5917a0ad582ec4 293 | languageName: node 294 | linkType: hard 295 | 296 | "argparse@npm:^2.0.1": 297 | version: 2.0.1 298 | resolution: "argparse@npm:2.0.1" 299 | checksum: 83644b56493e89a254bae05702abf3a1101b4fa4d0ca31df1c9985275a5a5bd47b3c27b7fa0b71098d41114d8ca000e6ed90cad764b306f8a503665e4d517ced 300 | languageName: node 301 | linkType: hard 302 | 303 | "array-union@npm:^2.1.0": 304 | version: 2.1.0 305 | resolution: "array-union@npm:2.1.0" 306 | checksum: 5bee12395cba82da674931df6d0fea23c4aa4660cb3b338ced9f828782a65caa232573e6bf3968f23e0c5eb301764a382cef2f128b170a9dc59de0e36c39f98d 307 | languageName: node 308 | linkType: hard 309 | 310 | "balanced-match@npm:^1.0.0": 311 | version: 1.0.2 312 | resolution: "balanced-match@npm:1.0.2" 313 | checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 314 | languageName: node 315 | linkType: hard 316 | 317 | "base-x@npm:^4.0.0": 318 | version: 4.0.0 319 | resolution: "base-x@npm:4.0.0" 320 | checksum: b25db9e07eb1998472a20557c7f00c797dc0595f79df95155ab74274e7fa98b9f2659b3ee547ac8773666b7f69540656793aeb97ad2b1ceccdb6fa5faaf69ac0 321 | languageName: node 322 | linkType: hard 323 | 324 | "bebop-tools@npm:^2.4.6": 325 | version: 2.4.6 326 | resolution: "bebop-tools@npm:2.4.6" 327 | dependencies: 328 | "@types/node": ^14.14.10 329 | bin: 330 | bebopc: bebopc.js 331 | checksum: 9143df78aaa02268d44804b0ac40537238a5fea680bd442ac12ce7411b968dd605d792073717090bd1158f6e4ebc6f952a105fdb0987c02264c80b0102770fab 332 | languageName: node 333 | linkType: hard 334 | 335 | "bebop@npm:^2.4.6": 336 | version: 2.4.6 337 | resolution: "bebop@npm:2.4.6" 338 | dependencies: 339 | "@types/node": ^14.14.7 340 | checksum: 6b6123045251dd099fe6a2514c6330c14af17f5e0e4cc0cf280aedd7a7014cabb328a34eaee0cf4dd25430a2ac116485024e9756ff3bfa2b6a46ca10c0104778 341 | languageName: node 342 | linkType: hard 343 | 344 | "brace-expansion@npm:^1.1.7": 345 | version: 1.1.11 346 | resolution: "brace-expansion@npm:1.1.11" 347 | dependencies: 348 | balanced-match: ^1.0.0 349 | concat-map: 0.0.1 350 | checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 351 | languageName: node 352 | linkType: hard 353 | 354 | "braces@npm:^3.0.1": 355 | version: 3.0.2 356 | resolution: "braces@npm:3.0.2" 357 | dependencies: 358 | fill-range: ^7.0.1 359 | checksum: e2a8e769a863f3d4ee887b5fe21f63193a891c68b612ddb4b68d82d1b5f3ff9073af066c343e9867a393fe4c2555dcb33e89b937195feb9c1613d259edfcd459 360 | languageName: node 361 | linkType: hard 362 | 363 | "callsites@npm:^3.0.0": 364 | version: 3.1.0 365 | resolution: "callsites@npm:3.1.0" 366 | checksum: 072d17b6abb459c2ba96598918b55868af677154bec7e73d222ef95a8fdb9bbf7dae96a8421085cdad8cd190d86653b5b6dc55a4484f2e5b2e27d5e0c3fc15b3 367 | languageName: node 368 | linkType: hard 369 | 370 | "chalk@npm:^4.0.0": 371 | version: 4.1.2 372 | resolution: "chalk@npm:4.1.2" 373 | dependencies: 374 | ansi-styles: ^4.1.0 375 | supports-color: ^7.1.0 376 | checksum: fe75c9d5c76a7a98d45495b91b2172fa3b7a09e0cc9370e5c8feb1c567b85c4288e2b3fded7cfdd7359ac28d6b3844feb8b82b8686842e93d23c827c417e83fc 377 | languageName: node 378 | linkType: hard 379 | 380 | "color-convert@npm:^2.0.1": 381 | version: 2.0.1 382 | resolution: "color-convert@npm:2.0.1" 383 | dependencies: 384 | color-name: ~1.1.4 385 | checksum: 79e6bdb9fd479a205c71d89574fccfb22bd9053bd98c6c4d870d65c132e5e904e6034978e55b43d69fcaa7433af2016ee203ce76eeba9cfa554b373e7f7db336 386 | languageName: node 387 | linkType: hard 388 | 389 | "color-name@npm:~1.1.4": 390 | version: 1.1.4 391 | resolution: "color-name@npm:1.1.4" 392 | checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 393 | languageName: node 394 | linkType: hard 395 | 396 | "concat-map@npm:0.0.1": 397 | version: 0.0.1 398 | resolution: "concat-map@npm:0.0.1" 399 | checksum: 902a9f5d8967a3e2faf138d5cb784b9979bad2e6db5357c5b21c568df4ebe62bcb15108af1b2253744844eb964fc023fbd9afbbbb6ddd0bcc204c6fb5b7bf3af 400 | languageName: node 401 | linkType: hard 402 | 403 | "cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": 404 | version: 7.0.3 405 | resolution: "cross-spawn@npm:7.0.3" 406 | dependencies: 407 | path-key: ^3.1.0 408 | shebang-command: ^2.0.0 409 | which: ^2.0.1 410 | checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 411 | languageName: node 412 | linkType: hard 413 | 414 | "debug@npm:^4.1.1, debug@npm:^4.3.2": 415 | version: 4.3.3 416 | resolution: "debug@npm:4.3.3" 417 | dependencies: 418 | ms: 2.1.2 419 | peerDependenciesMeta: 420 | supports-color: 421 | optional: true 422 | checksum: 14472d56fe4a94dbcfaa6dbed2dd3849f1d72ba78104a1a328047bb564643ca49df0224c3a17fa63533fd11dd3d4c8636cd861191232a2c6735af00cc2d4de16 423 | languageName: node 424 | linkType: hard 425 | 426 | "debug@npm:^4.3.4": 427 | version: 4.3.4 428 | resolution: "debug@npm:4.3.4" 429 | dependencies: 430 | ms: 2.1.2 431 | peerDependenciesMeta: 432 | supports-color: 433 | optional: true 434 | checksum: 3dbad3f94ea64f34431a9cbf0bafb61853eda57bff2880036153438f50fb5a84f27683ba0d8e5426bf41a8c6ff03879488120cf5b3a761e77953169c0600a708 435 | languageName: node 436 | linkType: hard 437 | 438 | "deep-is@npm:^0.1.3": 439 | version: 0.1.4 440 | resolution: "deep-is@npm:0.1.4" 441 | checksum: edb65dd0d7d1b9c40b2f50219aef30e116cedd6fc79290e740972c132c09106d2e80aa0bc8826673dd5a00222d4179c84b36a790eef63a4c4bca75a37ef90804 442 | languageName: node 443 | linkType: hard 444 | 445 | "dir-glob@npm:^3.0.1": 446 | version: 3.0.1 447 | resolution: "dir-glob@npm:3.0.1" 448 | dependencies: 449 | path-type: ^4.0.0 450 | checksum: fa05e18324510d7283f55862f3161c6759a3f2f8dbce491a2fc14c8324c498286c54282c1f0e933cb930da8419b30679389499b919122952a4f8592362ef4615 451 | languageName: node 452 | linkType: hard 453 | 454 | "doctrine@npm:^3.0.0": 455 | version: 3.0.0 456 | resolution: "doctrine@npm:3.0.0" 457 | dependencies: 458 | esutils: ^2.0.2 459 | checksum: fd7673ca77fe26cd5cba38d816bc72d641f500f1f9b25b83e8ce28827fe2da7ad583a8da26ab6af85f834138cf8dae9f69b0cd6ab925f52ddab1754db44d99ce 460 | languageName: node 461 | linkType: hard 462 | 463 | "dotenv@npm:^16.0.3": 464 | version: 16.0.3 465 | resolution: "dotenv@npm:16.0.3" 466 | checksum: afcf03f373d7a6d62c7e9afea6328e62851d627a4e73f2e12d0a8deae1cd375892004f3021883f8aec85932cd2834b091f568ced92b4774625b321db83b827f8 467 | languageName: node 468 | linkType: hard 469 | 470 | "duplexer@npm:~0.1.1": 471 | version: 0.1.2 472 | resolution: "duplexer@npm:0.1.2" 473 | checksum: 62ba61a830c56801db28ff6305c7d289b6dc9f859054e8c982abd8ee0b0a14d2e9a8e7d086ffee12e868d43e2bbe8a964be55ddbd8c8957714c87373c7a4f9b0 474 | languageName: node 475 | linkType: hard 476 | 477 | "esbuild-android-64@npm:0.15.10": 478 | version: 0.15.10 479 | resolution: "esbuild-android-64@npm:0.15.10" 480 | conditions: os=android & cpu=x64 481 | languageName: node 482 | linkType: hard 483 | 484 | "esbuild-android-arm64@npm:0.15.10": 485 | version: 0.15.10 486 | resolution: "esbuild-android-arm64@npm:0.15.10" 487 | conditions: os=android & cpu=arm64 488 | languageName: node 489 | linkType: hard 490 | 491 | "esbuild-darwin-64@npm:0.15.10": 492 | version: 0.15.10 493 | resolution: "esbuild-darwin-64@npm:0.15.10" 494 | conditions: os=darwin & cpu=x64 495 | languageName: node 496 | linkType: hard 497 | 498 | "esbuild-darwin-arm64@npm:0.15.10": 499 | version: 0.15.10 500 | resolution: "esbuild-darwin-arm64@npm:0.15.10" 501 | conditions: os=darwin & cpu=arm64 502 | languageName: node 503 | linkType: hard 504 | 505 | "esbuild-freebsd-64@npm:0.15.10": 506 | version: 0.15.10 507 | resolution: "esbuild-freebsd-64@npm:0.15.10" 508 | conditions: os=freebsd & cpu=x64 509 | languageName: node 510 | linkType: hard 511 | 512 | "esbuild-freebsd-arm64@npm:0.15.10": 513 | version: 0.15.10 514 | resolution: "esbuild-freebsd-arm64@npm:0.15.10" 515 | conditions: os=freebsd & cpu=arm64 516 | languageName: node 517 | linkType: hard 518 | 519 | "esbuild-linux-32@npm:0.15.10": 520 | version: 0.15.10 521 | resolution: "esbuild-linux-32@npm:0.15.10" 522 | conditions: os=linux & cpu=ia32 523 | languageName: node 524 | linkType: hard 525 | 526 | "esbuild-linux-64@npm:0.15.10": 527 | version: 0.15.10 528 | resolution: "esbuild-linux-64@npm:0.15.10" 529 | conditions: os=linux & cpu=x64 530 | languageName: node 531 | linkType: hard 532 | 533 | "esbuild-linux-arm64@npm:0.15.10": 534 | version: 0.15.10 535 | resolution: "esbuild-linux-arm64@npm:0.15.10" 536 | conditions: os=linux & cpu=arm64 537 | languageName: node 538 | linkType: hard 539 | 540 | "esbuild-linux-arm@npm:0.15.10": 541 | version: 0.15.10 542 | resolution: "esbuild-linux-arm@npm:0.15.10" 543 | conditions: os=linux & cpu=arm 544 | languageName: node 545 | linkType: hard 546 | 547 | "esbuild-linux-mips64le@npm:0.15.10": 548 | version: 0.15.10 549 | resolution: "esbuild-linux-mips64le@npm:0.15.10" 550 | conditions: os=linux & cpu=mips64el 551 | languageName: node 552 | linkType: hard 553 | 554 | "esbuild-linux-ppc64le@npm:0.15.10": 555 | version: 0.15.10 556 | resolution: "esbuild-linux-ppc64le@npm:0.15.10" 557 | conditions: os=linux & cpu=ppc64 558 | languageName: node 559 | linkType: hard 560 | 561 | "esbuild-linux-riscv64@npm:0.15.10": 562 | version: 0.15.10 563 | resolution: "esbuild-linux-riscv64@npm:0.15.10" 564 | conditions: os=linux & cpu=riscv64 565 | languageName: node 566 | linkType: hard 567 | 568 | "esbuild-linux-s390x@npm:0.15.10": 569 | version: 0.15.10 570 | resolution: "esbuild-linux-s390x@npm:0.15.10" 571 | conditions: os=linux & cpu=s390x 572 | languageName: node 573 | linkType: hard 574 | 575 | "esbuild-netbsd-64@npm:0.15.10": 576 | version: 0.15.10 577 | resolution: "esbuild-netbsd-64@npm:0.15.10" 578 | conditions: os=netbsd & cpu=x64 579 | languageName: node 580 | linkType: hard 581 | 582 | "esbuild-openbsd-64@npm:0.15.10": 583 | version: 0.15.10 584 | resolution: "esbuild-openbsd-64@npm:0.15.10" 585 | conditions: os=openbsd & cpu=x64 586 | languageName: node 587 | linkType: hard 588 | 589 | "esbuild-sunos-64@npm:0.15.10": 590 | version: 0.15.10 591 | resolution: "esbuild-sunos-64@npm:0.15.10" 592 | conditions: os=sunos & cpu=x64 593 | languageName: node 594 | linkType: hard 595 | 596 | "esbuild-windows-32@npm:0.15.10": 597 | version: 0.15.10 598 | resolution: "esbuild-windows-32@npm:0.15.10" 599 | conditions: os=win32 & cpu=ia32 600 | languageName: node 601 | linkType: hard 602 | 603 | "esbuild-windows-64@npm:0.15.10": 604 | version: 0.15.10 605 | resolution: "esbuild-windows-64@npm:0.15.10" 606 | conditions: os=win32 & cpu=x64 607 | languageName: node 608 | linkType: hard 609 | 610 | "esbuild-windows-arm64@npm:0.15.10": 611 | version: 0.15.10 612 | resolution: "esbuild-windows-arm64@npm:0.15.10" 613 | conditions: os=win32 & cpu=arm64 614 | languageName: node 615 | linkType: hard 616 | 617 | "esbuild@npm:^0.15.10": 618 | version: 0.15.10 619 | resolution: "esbuild@npm:0.15.10" 620 | dependencies: 621 | "@esbuild/android-arm": 0.15.10 622 | "@esbuild/linux-loong64": 0.15.10 623 | esbuild-android-64: 0.15.10 624 | esbuild-android-arm64: 0.15.10 625 | esbuild-darwin-64: 0.15.10 626 | esbuild-darwin-arm64: 0.15.10 627 | esbuild-freebsd-64: 0.15.10 628 | esbuild-freebsd-arm64: 0.15.10 629 | esbuild-linux-32: 0.15.10 630 | esbuild-linux-64: 0.15.10 631 | esbuild-linux-arm: 0.15.10 632 | esbuild-linux-arm64: 0.15.10 633 | esbuild-linux-mips64le: 0.15.10 634 | esbuild-linux-ppc64le: 0.15.10 635 | esbuild-linux-riscv64: 0.15.10 636 | esbuild-linux-s390x: 0.15.10 637 | esbuild-netbsd-64: 0.15.10 638 | esbuild-openbsd-64: 0.15.10 639 | esbuild-sunos-64: 0.15.10 640 | esbuild-windows-32: 0.15.10 641 | esbuild-windows-64: 0.15.10 642 | esbuild-windows-arm64: 0.15.10 643 | dependenciesMeta: 644 | "@esbuild/android-arm": 645 | optional: true 646 | "@esbuild/linux-loong64": 647 | optional: true 648 | esbuild-android-64: 649 | optional: true 650 | esbuild-android-arm64: 651 | optional: true 652 | esbuild-darwin-64: 653 | optional: true 654 | esbuild-darwin-arm64: 655 | optional: true 656 | esbuild-freebsd-64: 657 | optional: true 658 | esbuild-freebsd-arm64: 659 | optional: true 660 | esbuild-linux-32: 661 | optional: true 662 | esbuild-linux-64: 663 | optional: true 664 | esbuild-linux-arm: 665 | optional: true 666 | esbuild-linux-arm64: 667 | optional: true 668 | esbuild-linux-mips64le: 669 | optional: true 670 | esbuild-linux-ppc64le: 671 | optional: true 672 | esbuild-linux-riscv64: 673 | optional: true 674 | esbuild-linux-s390x: 675 | optional: true 676 | esbuild-netbsd-64: 677 | optional: true 678 | esbuild-openbsd-64: 679 | optional: true 680 | esbuild-sunos-64: 681 | optional: true 682 | esbuild-windows-32: 683 | optional: true 684 | esbuild-windows-64: 685 | optional: true 686 | esbuild-windows-arm64: 687 | optional: true 688 | bin: 689 | esbuild: bin/esbuild 690 | checksum: bc2daadb952c527e7ab0a972fd4f79071c9fd3d948cd97290d3de8811b6b7fc0abc43fb20116dffa24dc923550f4fe7b0d930ff6418ae7dfbff3034c1a01d59a 691 | languageName: node 692 | linkType: hard 693 | 694 | "escape-string-regexp@npm:^4.0.0": 695 | version: 4.0.0 696 | resolution: "escape-string-regexp@npm:4.0.0" 697 | checksum: 98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5 698 | languageName: node 699 | linkType: hard 700 | 701 | "eslint-config-prettier@npm:^8.5.0": 702 | version: 8.5.0 703 | resolution: "eslint-config-prettier@npm:8.5.0" 704 | peerDependencies: 705 | eslint: ">=7.0.0" 706 | bin: 707 | eslint-config-prettier: bin/cli.js 708 | checksum: 0d0f5c32e7a0ad91249467ce71ca92394ccd343178277d318baf32063b79ea90216f4c81d1065d60f96366fdc60f151d4d68ae7811a58bd37228b84c2083f893 709 | languageName: node 710 | linkType: hard 711 | 712 | "eslint-plugin-prettier@npm:^4.2.1": 713 | version: 4.2.1 714 | resolution: "eslint-plugin-prettier@npm:4.2.1" 715 | dependencies: 716 | prettier-linter-helpers: ^1.0.0 717 | peerDependencies: 718 | eslint: ">=7.28.0" 719 | prettier: ">=2.0.0" 720 | peerDependenciesMeta: 721 | eslint-config-prettier: 722 | optional: true 723 | checksum: b9e839d2334ad8ec7a5589c5cb0f219bded260839a857d7a486997f9870e95106aa59b8756ff3f37202085ebab658de382b0267cae44c3a7f0eb0bcc03a4f6d6 724 | languageName: node 725 | linkType: hard 726 | 727 | "eslint-scope@npm:^5.1.1": 728 | version: 5.1.1 729 | resolution: "eslint-scope@npm:5.1.1" 730 | dependencies: 731 | esrecurse: ^4.3.0 732 | estraverse: ^4.1.1 733 | checksum: 47e4b6a3f0cc29c7feedee6c67b225a2da7e155802c6ea13bbef4ac6b9e10c66cd2dcb987867ef176292bf4e64eccc680a49e35e9e9c669f4a02bac17e86abdb 734 | languageName: node 735 | linkType: hard 736 | 737 | "eslint-scope@npm:^7.1.1": 738 | version: 7.1.1 739 | resolution: "eslint-scope@npm:7.1.1" 740 | dependencies: 741 | esrecurse: ^4.3.0 742 | estraverse: ^5.2.0 743 | checksum: 9f6e974ab2db641ca8ab13508c405b7b859e72afe9f254e8131ff154d2f40c99ad4545ce326fd9fde3212ff29707102562a4834f1c48617b35d98c71a97fbf3e 744 | languageName: node 745 | linkType: hard 746 | 747 | "eslint-utils@npm:^3.0.0": 748 | version: 3.0.0 749 | resolution: "eslint-utils@npm:3.0.0" 750 | dependencies: 751 | eslint-visitor-keys: ^2.0.0 752 | peerDependencies: 753 | eslint: ">=5" 754 | checksum: 0668fe02f5adab2e5a367eee5089f4c39033af20499df88fe4e6aba2015c20720404d8c3d6349b6f716b08fdf91b9da4e5d5481f265049278099c4c836ccb619 755 | languageName: node 756 | linkType: hard 757 | 758 | "eslint-visitor-keys@npm:^2.0.0": 759 | version: 2.1.0 760 | resolution: "eslint-visitor-keys@npm:2.1.0" 761 | checksum: e3081d7dd2611a35f0388bbdc2f5da60b3a3c5b8b6e928daffff7391146b434d691577aa95064c8b7faad0b8a680266bcda0a42439c18c717b80e6718d7e267d 762 | languageName: node 763 | linkType: hard 764 | 765 | "eslint-visitor-keys@npm:^3.3.0": 766 | version: 3.3.0 767 | resolution: "eslint-visitor-keys@npm:3.3.0" 768 | checksum: d59e68a7c5a6d0146526b0eec16ce87fbf97fe46b8281e0d41384224375c4e52f5ffb9e16d48f4ea50785cde93f766b0c898e31ab89978d88b0e1720fbfb7808 769 | languageName: node 770 | linkType: hard 771 | 772 | "eslint@npm:^8.24.0": 773 | version: 8.24.0 774 | resolution: "eslint@npm:8.24.0" 775 | dependencies: 776 | "@eslint/eslintrc": ^1.3.2 777 | "@humanwhocodes/config-array": ^0.10.5 778 | "@humanwhocodes/gitignore-to-minimatch": ^1.0.2 779 | "@humanwhocodes/module-importer": ^1.0.1 780 | ajv: ^6.10.0 781 | chalk: ^4.0.0 782 | cross-spawn: ^7.0.2 783 | debug: ^4.3.2 784 | doctrine: ^3.0.0 785 | escape-string-regexp: ^4.0.0 786 | eslint-scope: ^7.1.1 787 | eslint-utils: ^3.0.0 788 | eslint-visitor-keys: ^3.3.0 789 | espree: ^9.4.0 790 | esquery: ^1.4.0 791 | esutils: ^2.0.2 792 | fast-deep-equal: ^3.1.3 793 | file-entry-cache: ^6.0.1 794 | find-up: ^5.0.0 795 | glob-parent: ^6.0.1 796 | globals: ^13.15.0 797 | globby: ^11.1.0 798 | grapheme-splitter: ^1.0.4 799 | ignore: ^5.2.0 800 | import-fresh: ^3.0.0 801 | imurmurhash: ^0.1.4 802 | is-glob: ^4.0.0 803 | js-sdsl: ^4.1.4 804 | js-yaml: ^4.1.0 805 | json-stable-stringify-without-jsonify: ^1.0.1 806 | levn: ^0.4.1 807 | lodash.merge: ^4.6.2 808 | minimatch: ^3.1.2 809 | natural-compare: ^1.4.0 810 | optionator: ^0.9.1 811 | regexpp: ^3.2.0 812 | strip-ansi: ^6.0.1 813 | strip-json-comments: ^3.1.0 814 | text-table: ^0.2.0 815 | bin: 816 | eslint: bin/eslint.js 817 | checksum: ca293ce7116599b742d7ab4d43db469beec22f40dd272092d809498be3cff3a7c567769f9763bdf6799aac13dd53447b93a99629b7b54092783046eb57eaced6 818 | languageName: node 819 | linkType: hard 820 | 821 | "espree@npm:^9.4.0": 822 | version: 9.4.0 823 | resolution: "espree@npm:9.4.0" 824 | dependencies: 825 | acorn: ^8.8.0 826 | acorn-jsx: ^5.3.2 827 | eslint-visitor-keys: ^3.3.0 828 | checksum: 2e3020dde67892d2ba3632413b44d0dc31d92c29ce72267d7ec24216a562f0a6494d3696e2fa39a3ec8c0e0088d773947ab2925fbb716801a11eb8dd313ac89c 829 | languageName: node 830 | linkType: hard 831 | 832 | "esquery@npm:^1.4.0": 833 | version: 1.4.0 834 | resolution: "esquery@npm:1.4.0" 835 | dependencies: 836 | estraverse: ^5.1.0 837 | checksum: a0807e17abd7fbe5fbd4fab673038d6d8a50675cdae6b04fbaa520c34581be0c5fa24582990e8acd8854f671dd291c78bb2efb9e0ed5b62f33bac4f9cf820210 838 | languageName: node 839 | linkType: hard 840 | 841 | "esrecurse@npm:^4.3.0": 842 | version: 4.3.0 843 | resolution: "esrecurse@npm:4.3.0" 844 | dependencies: 845 | estraverse: ^5.2.0 846 | checksum: ebc17b1a33c51cef46fdc28b958994b1dc43cd2e86237515cbc3b4e5d2be6a811b2315d0a1a4d9d340b6d2308b15322f5c8291059521cc5f4802f65e7ec32837 847 | languageName: node 848 | linkType: hard 849 | 850 | "estraverse@npm:^4.1.1": 851 | version: 4.3.0 852 | resolution: "estraverse@npm:4.3.0" 853 | checksum: a6299491f9940bb246124a8d44b7b7a413a8336f5436f9837aaa9330209bd9ee8af7e91a654a3545aee9c54b3308e78ee360cef1d777d37cfef77d2fa33b5827 854 | languageName: node 855 | linkType: hard 856 | 857 | "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": 858 | version: 5.3.0 859 | resolution: "estraverse@npm:5.3.0" 860 | checksum: 072780882dc8416ad144f8fe199628d2b3e7bbc9989d9ed43795d2c90309a2047e6bc5979d7e2322a341163d22cfad9e21f4110597fe487519697389497e4e2b 861 | languageName: node 862 | linkType: hard 863 | 864 | "esutils@npm:^2.0.2": 865 | version: 2.0.3 866 | resolution: "esutils@npm:2.0.3" 867 | checksum: 22b5b08f74737379a840b8ed2036a5fb35826c709ab000683b092d9054e5c2a82c27818f12604bfc2a9a76b90b6834ef081edbc1c7ae30d1627012e067c6ec87 868 | languageName: node 869 | linkType: hard 870 | 871 | "event-stream@npm:=3.3.4": 872 | version: 3.3.4 873 | resolution: "event-stream@npm:3.3.4" 874 | dependencies: 875 | duplexer: ~0.1.1 876 | from: ~0 877 | map-stream: ~0.1.0 878 | pause-stream: 0.0.11 879 | split: 0.3 880 | stream-combiner: ~0.0.4 881 | through: ~2.3.1 882 | checksum: 80b467820b6daf824d9fb4345d2daf115a056e5c104463f2e98534e92d196a27f2df5ea2aa085624db26f4c45698905499e881d13bc7c01f7a13eac85be72a22 883 | languageName: node 884 | linkType: hard 885 | 886 | "eventemitter3@npm:^4.0.7": 887 | version: 4.0.7 888 | resolution: "eventemitter3@npm:4.0.7" 889 | checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374 890 | languageName: node 891 | linkType: hard 892 | 893 | "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": 894 | version: 3.1.3 895 | resolution: "fast-deep-equal@npm:3.1.3" 896 | checksum: e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d 897 | languageName: node 898 | linkType: hard 899 | 900 | "fast-diff@npm:^1.1.2": 901 | version: 1.2.0 902 | resolution: "fast-diff@npm:1.2.0" 903 | checksum: 1b5306eaa9e826564d9e5ffcd6ebd881eb5f770b3f977fcbf38f05c824e42172b53c79920e8429c54eb742ce15a0caf268b0fdd5b38f6de52234c4a8368131ae 904 | languageName: node 905 | linkType: hard 906 | 907 | "fast-glob@npm:^3.2.9": 908 | version: 3.2.11 909 | resolution: "fast-glob@npm:3.2.11" 910 | dependencies: 911 | "@nodelib/fs.stat": ^2.0.2 912 | "@nodelib/fs.walk": ^1.2.3 913 | glob-parent: ^5.1.2 914 | merge2: ^1.3.0 915 | micromatch: ^4.0.4 916 | checksum: f473105324a7780a20c06de842e15ddbb41d3cb7e71d1e4fe6e8373204f22245d54f5ab9e2061e6a1c613047345954d29b022e0e76f5c28b1df9858179a0e6d7 917 | languageName: node 918 | linkType: hard 919 | 920 | "fast-json-stable-stringify@npm:^2.0.0": 921 | version: 2.1.0 922 | resolution: "fast-json-stable-stringify@npm:2.1.0" 923 | checksum: b191531e36c607977e5b1c47811158733c34ccb3bfde92c44798929e9b4154884378536d26ad90dfecd32e1ffc09c545d23535ad91b3161a27ddbb8ebe0cbecb 924 | languageName: node 925 | linkType: hard 926 | 927 | "fast-levenshtein@npm:^2.0.6": 928 | version: 2.0.6 929 | resolution: "fast-levenshtein@npm:2.0.6" 930 | checksum: 92cfec0a8dfafd9c7a15fba8f2cc29cd0b62b85f056d99ce448bbcd9f708e18ab2764bda4dd5158364f4145a7c72788538994f0d1787b956ef0d1062b0f7c24c 931 | languageName: node 932 | linkType: hard 933 | 934 | "fastq@npm:^1.6.0": 935 | version: 1.13.0 936 | resolution: "fastq@npm:1.13.0" 937 | dependencies: 938 | reusify: ^1.0.4 939 | checksum: 32cf15c29afe622af187d12fc9cd93e160a0cb7c31a3bb6ace86b7dea3b28e7b72acde89c882663f307b2184e14782c6c664fa315973c03626c7d4bff070bb0b 940 | languageName: node 941 | linkType: hard 942 | 943 | "file-entry-cache@npm:^6.0.1": 944 | version: 6.0.1 945 | resolution: "file-entry-cache@npm:6.0.1" 946 | dependencies: 947 | flat-cache: ^3.0.4 948 | checksum: f49701feaa6314c8127c3c2f6173cfefff17612f5ed2daaafc6da13b5c91fd43e3b2a58fd0d63f9f94478a501b167615931e7200e31485e320f74a33885a9c74 949 | languageName: node 950 | linkType: hard 951 | 952 | "fill-range@npm:^7.0.1": 953 | version: 7.0.1 954 | resolution: "fill-range@npm:7.0.1" 955 | dependencies: 956 | to-regex-range: ^5.0.1 957 | checksum: cc283f4e65b504259e64fd969bcf4def4eb08d85565e906b7d36516e87819db52029a76b6363d0f02d0d532f0033c9603b9e2d943d56ee3b0d4f7ad3328ff917 958 | languageName: node 959 | linkType: hard 960 | 961 | "find-up@npm:^5.0.0": 962 | version: 5.0.0 963 | resolution: "find-up@npm:5.0.0" 964 | dependencies: 965 | locate-path: ^6.0.0 966 | path-exists: ^4.0.0 967 | checksum: 07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095 968 | languageName: node 969 | linkType: hard 970 | 971 | "flat-cache@npm:^3.0.4": 972 | version: 3.0.4 973 | resolution: "flat-cache@npm:3.0.4" 974 | dependencies: 975 | flatted: ^3.1.0 976 | rimraf: ^3.0.2 977 | checksum: 4fdd10ecbcbf7d520f9040dd1340eb5dfe951e6f0ecf2252edeec03ee68d989ec8b9a20f4434270e71bcfd57800dc09b3344fca3966b2eb8f613072c7d9a2365 978 | languageName: node 979 | linkType: hard 980 | 981 | "flatted@npm:^3.1.0": 982 | version: 3.2.4 983 | resolution: "flatted@npm:3.2.4" 984 | checksum: 7d33846428ab337ec81ef9b8b9103894c1c81f5f67feb32bd4ed106fbc47da60d56edb42efd36c9f1f30a010272aeccd34ec1ffacfe9dfdff19673b1d4df481b 985 | languageName: node 986 | linkType: hard 987 | 988 | "from@npm:~0": 989 | version: 0.1.7 990 | resolution: "from@npm:0.1.7" 991 | checksum: b85125b7890489656eb2e4f208f7654a93ec26e3aefaf3bbbcc0d496fc1941e4405834fcc9fe7333192aa2187905510ace70417bbf9ac6f6f4784a731d986939 992 | languageName: node 993 | linkType: hard 994 | 995 | "fs.realpath@npm:^1.0.0": 996 | version: 1.0.0 997 | resolution: "fs.realpath@npm:1.0.0" 998 | checksum: 99ddea01a7e75aa276c250a04eedeffe5662bce66c65c07164ad6264f9de18fb21be9433ead460e54cff20e31721c811f4fb5d70591799df5f85dce6d6746fd0 999 | languageName: node 1000 | linkType: hard 1001 | 1002 | "glob-parent@npm:^5.1.2": 1003 | version: 5.1.2 1004 | resolution: "glob-parent@npm:5.1.2" 1005 | dependencies: 1006 | is-glob: ^4.0.1 1007 | checksum: f4f2bfe2425296e8a47e36864e4f42be38a996db40420fe434565e4480e3322f18eb37589617a98640c5dc8fdec1a387007ee18dbb1f3f5553409c34d17f425e 1008 | languageName: node 1009 | linkType: hard 1010 | 1011 | "glob-parent@npm:^6.0.1": 1012 | version: 6.0.2 1013 | resolution: "glob-parent@npm:6.0.2" 1014 | dependencies: 1015 | is-glob: ^4.0.3 1016 | checksum: c13ee97978bef4f55106b71e66428eb1512e71a7466ba49025fc2aec59a5bfb0954d5abd58fc5ee6c9b076eef4e1f6d3375c2e964b88466ca390da4419a786a8 1017 | languageName: node 1018 | linkType: hard 1019 | 1020 | "glob@npm:^7.1.3": 1021 | version: 7.2.0 1022 | resolution: "glob@npm:7.2.0" 1023 | dependencies: 1024 | fs.realpath: ^1.0.0 1025 | inflight: ^1.0.4 1026 | inherits: 2 1027 | minimatch: ^3.0.4 1028 | once: ^1.3.0 1029 | path-is-absolute: ^1.0.0 1030 | checksum: 78a8ea942331f08ed2e055cb5b9e40fe6f46f579d7fd3d694f3412fe5db23223d29b7fee1575440202e9a7ff9a72ab106a39fee39934c7bedafe5e5f8ae20134 1031 | languageName: node 1032 | linkType: hard 1033 | 1034 | "globals@npm:^13.15.0": 1035 | version: 13.17.0 1036 | resolution: "globals@npm:13.17.0" 1037 | dependencies: 1038 | type-fest: ^0.20.2 1039 | checksum: fbaf4112e59b92c9f5575e85ce65e9e17c0b82711196ec5f58beb08599bbd92fd72703d6dfc9b080381fd35b644e1b11dcf25b38cc2341ec21df942594cbc8ce 1040 | languageName: node 1041 | linkType: hard 1042 | 1043 | "globby@npm:^11.1.0": 1044 | version: 11.1.0 1045 | resolution: "globby@npm:11.1.0" 1046 | dependencies: 1047 | array-union: ^2.1.0 1048 | dir-glob: ^3.0.1 1049 | fast-glob: ^3.2.9 1050 | ignore: ^5.2.0 1051 | merge2: ^1.4.1 1052 | slash: ^3.0.0 1053 | checksum: b4be8885e0cfa018fc783792942d53926c35c50b3aefd3fdcfb9d22c627639dc26bd2327a40a0b74b074100ce95bb7187bfeae2f236856aa3de183af7a02aea6 1054 | languageName: node 1055 | linkType: hard 1056 | 1057 | "grapheme-splitter@npm:^1.0.4": 1058 | version: 1.0.4 1059 | resolution: "grapheme-splitter@npm:1.0.4" 1060 | checksum: 0c22ec54dee1b05cd480f78cf14f732cb5b108edc073572c4ec205df4cd63f30f8db8025afc5debc8835a8ddeacf648a1c7992fe3dcd6ad38f9a476d84906620 1061 | languageName: node 1062 | linkType: hard 1063 | 1064 | "has-flag@npm:^4.0.0": 1065 | version: 4.0.0 1066 | resolution: "has-flag@npm:4.0.0" 1067 | checksum: 261a1357037ead75e338156b1f9452c016a37dcd3283a972a30d9e4a87441ba372c8b81f818cd0fbcd9c0354b4ae7e18b9e1afa1971164aef6d18c2b6095a8ad 1068 | languageName: node 1069 | linkType: hard 1070 | 1071 | "ignore@npm:^5.2.0": 1072 | version: 5.2.0 1073 | resolution: "ignore@npm:5.2.0" 1074 | checksum: 6b1f926792d614f64c6c83da3a1f9c83f6196c2839aa41e1e32dd7b8d174cef2e329d75caabb62cb61ce9dc432f75e67d07d122a037312db7caa73166a1bdb77 1075 | languageName: node 1076 | linkType: hard 1077 | 1078 | "import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1": 1079 | version: 3.3.0 1080 | resolution: "import-fresh@npm:3.3.0" 1081 | dependencies: 1082 | parent-module: ^1.0.0 1083 | resolve-from: ^4.0.0 1084 | checksum: 2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa 1085 | languageName: node 1086 | linkType: hard 1087 | 1088 | "imurmurhash@npm:^0.1.4": 1089 | version: 0.1.4 1090 | resolution: "imurmurhash@npm:0.1.4" 1091 | checksum: 7cae75c8cd9a50f57dadd77482359f659eaebac0319dd9368bcd1714f55e65badd6929ca58569da2b6494ef13fdd5598cd700b1eba23f8b79c5f19d195a3ecf7 1092 | languageName: node 1093 | linkType: hard 1094 | 1095 | "inflight@npm:^1.0.4": 1096 | version: 1.0.6 1097 | resolution: "inflight@npm:1.0.6" 1098 | dependencies: 1099 | once: ^1.3.0 1100 | wrappy: 1 1101 | checksum: f4f76aa072ce19fae87ce1ef7d221e709afb59d445e05d47fba710e85470923a75de35bfae47da6de1b18afc3ce83d70facf44cfb0aff89f0a3f45c0a0244dfd 1102 | languageName: node 1103 | linkType: hard 1104 | 1105 | "inherits@npm:2": 1106 | version: 2.0.4 1107 | resolution: "inherits@npm:2.0.4" 1108 | checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 1109 | languageName: node 1110 | linkType: hard 1111 | 1112 | "is-extglob@npm:^2.1.1": 1113 | version: 2.1.1 1114 | resolution: "is-extglob@npm:2.1.1" 1115 | checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 1116 | languageName: node 1117 | linkType: hard 1118 | 1119 | "is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": 1120 | version: 4.0.3 1121 | resolution: "is-glob@npm:4.0.3" 1122 | dependencies: 1123 | is-extglob: ^2.1.1 1124 | checksum: d381c1319fcb69d341cc6e6c7cd588e17cd94722d9a32dbd60660b993c4fb7d0f19438674e68dfec686d09b7c73139c9166b47597f846af387450224a8101ab4 1125 | languageName: node 1126 | linkType: hard 1127 | 1128 | "is-number@npm:^7.0.0": 1129 | version: 7.0.0 1130 | resolution: "is-number@npm:7.0.0" 1131 | checksum: 456ac6f8e0f3111ed34668a624e45315201dff921e5ac181f8ec24923b99e9f32ca1a194912dc79d539c97d33dba17dc635202ff0b2cf98326f608323276d27a 1132 | languageName: node 1133 | linkType: hard 1134 | 1135 | "isexe@npm:^2.0.0": 1136 | version: 2.0.0 1137 | resolution: "isexe@npm:2.0.0" 1138 | checksum: 26bf6c5480dda5161c820c5b5c751ae1e766c587b1f951ea3fcfc973bafb7831ae5b54a31a69bd670220e42e99ec154475025a468eae58ea262f813fdc8d1c62 1139 | languageName: node 1140 | linkType: hard 1141 | 1142 | "js-sdsl@npm:^4.1.4": 1143 | version: 4.1.4 1144 | resolution: "js-sdsl@npm:4.1.4" 1145 | checksum: 1977cea4ab18e0e03e28bdf0371d8b443fad65ca0988e0faa216406faf6bb943714fe8f7cc7a5bfe5f35ba3d94ddae399f4d10200f547f2c3320688b0670d726 1146 | languageName: node 1147 | linkType: hard 1148 | 1149 | "js-yaml@npm:^4.1.0": 1150 | version: 4.1.0 1151 | resolution: "js-yaml@npm:4.1.0" 1152 | dependencies: 1153 | argparse: ^2.0.1 1154 | bin: 1155 | js-yaml: bin/js-yaml.js 1156 | checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a 1157 | languageName: node 1158 | linkType: hard 1159 | 1160 | "json-schema-traverse@npm:^0.4.1": 1161 | version: 0.4.1 1162 | resolution: "json-schema-traverse@npm:0.4.1" 1163 | checksum: 7486074d3ba247769fda17d5181b345c9fb7d12e0da98b22d1d71a5db9698d8b4bd900a3ec1a4ffdd60846fc2556274a5c894d0c48795f14cb03aeae7b55260b 1164 | languageName: node 1165 | linkType: hard 1166 | 1167 | "json-stable-stringify-without-jsonify@npm:^1.0.1": 1168 | version: 1.0.1 1169 | resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" 1170 | checksum: cff44156ddce9c67c44386ad5cddf91925fe06b1d217f2da9c4910d01f358c6e3989c4d5a02683c7a5667f9727ff05831f7aa8ae66c8ff691c556f0884d49215 1171 | languageName: node 1172 | linkType: hard 1173 | 1174 | "levn@npm:^0.4.1": 1175 | version: 0.4.1 1176 | resolution: "levn@npm:0.4.1" 1177 | dependencies: 1178 | prelude-ls: ^1.2.1 1179 | type-check: ~0.4.0 1180 | checksum: 12c5021c859bd0f5248561bf139121f0358285ec545ebf48bb3d346820d5c61a4309535c7f387ed7d84361cf821e124ce346c6b7cef8ee09a67c1473b46d0fc4 1181 | languageName: node 1182 | linkType: hard 1183 | 1184 | "locate-path@npm:^6.0.0": 1185 | version: 6.0.0 1186 | resolution: "locate-path@npm:6.0.0" 1187 | dependencies: 1188 | p-locate: ^5.0.0 1189 | checksum: 72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a 1190 | languageName: node 1191 | linkType: hard 1192 | 1193 | "lodash.merge@npm:^4.6.2": 1194 | version: 4.6.2 1195 | resolution: "lodash.merge@npm:4.6.2" 1196 | checksum: ad580b4bdbb7ca1f7abf7e1bce63a9a0b98e370cf40194b03380a46b4ed799c9573029599caebc1b14e3f24b111aef72b96674a56cfa105e0f5ac70546cdc005 1197 | languageName: node 1198 | linkType: hard 1199 | 1200 | "lru-cache@npm:^6.0.0": 1201 | version: 6.0.0 1202 | resolution: "lru-cache@npm:6.0.0" 1203 | dependencies: 1204 | yallist: ^4.0.0 1205 | checksum: f97f499f898f23e4585742138a22f22526254fdba6d75d41a1c2526b3b6cc5747ef59c5612ba7375f42aca4f8461950e925ba08c991ead0651b4918b7c978297 1206 | languageName: node 1207 | linkType: hard 1208 | 1209 | "map-stream@npm:~0.1.0": 1210 | version: 0.1.0 1211 | resolution: "map-stream@npm:0.1.0" 1212 | checksum: 38abbe4eb883888031e6b2fc0630bc583c99396be16b8ace5794b937b682a8a081f03e8b15bfd4914d1bc88318f0e9ac73ba3512ae65955cd449f63256ddb31d 1213 | languageName: node 1214 | linkType: hard 1215 | 1216 | "merge2@npm:^1.3.0, merge2@npm:^1.4.1": 1217 | version: 1.4.1 1218 | resolution: "merge2@npm:1.4.1" 1219 | checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 1220 | languageName: node 1221 | linkType: hard 1222 | 1223 | "micromatch@npm:^4.0.4": 1224 | version: 4.0.4 1225 | resolution: "micromatch@npm:4.0.4" 1226 | dependencies: 1227 | braces: ^3.0.1 1228 | picomatch: ^2.2.3 1229 | checksum: ef3d1c88e79e0a68b0e94a03137676f3324ac18a908c245a9e5936f838079fcc108ac7170a5fadc265a9c2596963462e402841406bda1a4bb7b68805601d631c 1230 | languageName: node 1231 | linkType: hard 1232 | 1233 | "minimatch@npm:^3.0.4": 1234 | version: 3.0.4 1235 | resolution: "minimatch@npm:3.0.4" 1236 | dependencies: 1237 | brace-expansion: ^1.1.7 1238 | checksum: 66ac295f8a7b59788000ea3749938b0970344c841750abd96694f80269b926ebcafad3deeb3f1da2522978b119e6ae3a5869b63b13a7859a456b3408bd18a078 1239 | languageName: node 1240 | linkType: hard 1241 | 1242 | "minimatch@npm:^3.1.2": 1243 | version: 3.1.2 1244 | resolution: "minimatch@npm:3.1.2" 1245 | dependencies: 1246 | brace-expansion: ^1.1.7 1247 | checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a 1248 | languageName: node 1249 | linkType: hard 1250 | 1251 | "ms@npm:2.1.2": 1252 | version: 2.1.2 1253 | resolution: "ms@npm:2.1.2" 1254 | checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f 1255 | languageName: node 1256 | linkType: hard 1257 | 1258 | "natural-compare@npm:^1.4.0": 1259 | version: 1.4.0 1260 | resolution: "natural-compare@npm:1.4.0" 1261 | checksum: 23ad088b08f898fc9b53011d7bb78ec48e79de7627e01ab5518e806033861bef68d5b0cd0e2205c2f36690ac9571ff6bcb05eb777ced2eeda8d4ac5b44592c3d 1262 | languageName: node 1263 | linkType: hard 1264 | 1265 | "node-cleanup@npm:^2.1.2": 1266 | version: 2.1.2 1267 | resolution: "node-cleanup@npm:2.1.2" 1268 | checksum: 584cdc3e42560a998b4579f91ed8f936b27011628f3102e5a1093205f0691cdf8d899287d1f2e4d2071ea4ab1d615810bad6dbe2b988ef173a1cbaa76d8165b3 1269 | languageName: node 1270 | linkType: hard 1271 | 1272 | "node-fetch@npm:^2.6.1": 1273 | version: 2.6.7 1274 | resolution: "node-fetch@npm:2.6.7" 1275 | dependencies: 1276 | whatwg-url: ^5.0.0 1277 | peerDependencies: 1278 | encoding: ^0.1.0 1279 | peerDependenciesMeta: 1280 | encoding: 1281 | optional: true 1282 | checksum: 8d816ffd1ee22cab8301c7756ef04f3437f18dace86a1dae22cf81db8ef29c0bf6655f3215cb0cdb22b420b6fe141e64b26905e7f33f9377a7fa59135ea3e10b 1283 | languageName: node 1284 | linkType: hard 1285 | 1286 | "once@npm:^1.3.0": 1287 | version: 1.4.0 1288 | resolution: "once@npm:1.4.0" 1289 | dependencies: 1290 | wrappy: 1 1291 | checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 1292 | languageName: node 1293 | linkType: hard 1294 | 1295 | "optionator@npm:^0.9.1": 1296 | version: 0.9.1 1297 | resolution: "optionator@npm:0.9.1" 1298 | dependencies: 1299 | deep-is: ^0.1.3 1300 | fast-levenshtein: ^2.0.6 1301 | levn: ^0.4.1 1302 | prelude-ls: ^1.2.1 1303 | type-check: ^0.4.0 1304 | word-wrap: ^1.2.3 1305 | checksum: dbc6fa065604b24ea57d734261914e697bd73b69eff7f18e967e8912aa2a40a19a9f599a507fa805be6c13c24c4eae8c71306c239d517d42d4c041c942f508a0 1306 | languageName: node 1307 | linkType: hard 1308 | 1309 | "p-limit@npm:^3.0.2": 1310 | version: 3.1.0 1311 | resolution: "p-limit@npm:3.1.0" 1312 | dependencies: 1313 | yocto-queue: ^0.1.0 1314 | checksum: 7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360 1315 | languageName: node 1316 | linkType: hard 1317 | 1318 | "p-locate@npm:^5.0.0": 1319 | version: 5.0.0 1320 | resolution: "p-locate@npm:5.0.0" 1321 | dependencies: 1322 | p-limit: ^3.0.2 1323 | checksum: 1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3 1324 | languageName: node 1325 | linkType: hard 1326 | 1327 | "parent-module@npm:^1.0.0": 1328 | version: 1.0.1 1329 | resolution: "parent-module@npm:1.0.1" 1330 | dependencies: 1331 | callsites: ^3.0.0 1332 | checksum: 6ba8b255145cae9470cf5551eb74be2d22281587af787a2626683a6c20fbb464978784661478dd2a3f1dad74d1e802d403e1b03c1a31fab310259eec8ac560ff 1333 | languageName: node 1334 | linkType: hard 1335 | 1336 | "path-exists@npm:^4.0.0": 1337 | version: 4.0.0 1338 | resolution: "path-exists@npm:4.0.0" 1339 | checksum: 505807199dfb7c50737b057dd8d351b82c033029ab94cb10a657609e00c1bc53b951cfdbccab8de04c5584d5eff31128ce6afd3db79281874a5ef2adbba55ed1 1340 | languageName: node 1341 | linkType: hard 1342 | 1343 | "path-is-absolute@npm:^1.0.0": 1344 | version: 1.0.1 1345 | resolution: "path-is-absolute@npm:1.0.1" 1346 | checksum: 060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8 1347 | languageName: node 1348 | linkType: hard 1349 | 1350 | "path-key@npm:^3.1.0": 1351 | version: 3.1.1 1352 | resolution: "path-key@npm:3.1.1" 1353 | checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 1354 | languageName: node 1355 | linkType: hard 1356 | 1357 | "path-type@npm:^4.0.0": 1358 | version: 4.0.0 1359 | resolution: "path-type@npm:4.0.0" 1360 | checksum: 5b1e2daa247062061325b8fdbfd1fb56dde0a448fb1455453276ea18c60685bdad23a445dc148cf87bc216be1573357509b7d4060494a6fd768c7efad833ee45 1361 | languageName: node 1362 | linkType: hard 1363 | 1364 | "pause-stream@npm:0.0.11": 1365 | version: 0.0.11 1366 | resolution: "pause-stream@npm:0.0.11" 1367 | dependencies: 1368 | through: ~2.3 1369 | checksum: 3c4a14052a638b92e0c96eb00c0d7977df7f79ea28395250c525d197f1fc02d34ce1165d5362e2e6ebbb251524b94a76f3f0d4abc39ab8b016d97449fe15583c 1370 | languageName: node 1371 | linkType: hard 1372 | 1373 | "picomatch@npm:^2.2.3": 1374 | version: 2.3.1 1375 | resolution: "picomatch@npm:2.3.1" 1376 | checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf 1377 | languageName: node 1378 | linkType: hard 1379 | 1380 | "prelude-ls@npm:^1.2.1": 1381 | version: 1.2.1 1382 | resolution: "prelude-ls@npm:1.2.1" 1383 | checksum: cd192ec0d0a8e4c6da3bb80e4f62afe336df3f76271ac6deb0e6a36187133b6073a19e9727a1ff108cd8b9982e4768850d413baa71214dd80c7979617dca827a 1384 | languageName: node 1385 | linkType: hard 1386 | 1387 | "prettier-linter-helpers@npm:^1.0.0": 1388 | version: 1.0.0 1389 | resolution: "prettier-linter-helpers@npm:1.0.0" 1390 | dependencies: 1391 | fast-diff: ^1.1.2 1392 | checksum: 00ce8011cf6430158d27f9c92cfea0a7699405633f7f1d4a45f07e21bf78e99895911cbcdc3853db3a824201a7c745bd49bfea8abd5fb9883e765a90f74f8392 1393 | languageName: node 1394 | linkType: hard 1395 | 1396 | "prettier@npm:^2.7.1": 1397 | version: 2.7.1 1398 | resolution: "prettier@npm:2.7.1" 1399 | bin: 1400 | prettier: bin-prettier.js 1401 | checksum: 55a4409182260866ab31284d929b3cb961e5fdb91fe0d2e099dac92eaecec890f36e524b4c19e6ceae839c99c6d7195817579cdffc8e2c80da0cb794463a748b 1402 | languageName: node 1403 | linkType: hard 1404 | 1405 | "ps-tree@npm:^1.2.0": 1406 | version: 1.2.0 1407 | resolution: "ps-tree@npm:1.2.0" 1408 | dependencies: 1409 | event-stream: =3.3.4 1410 | bin: 1411 | ps-tree: ./bin/ps-tree.js 1412 | checksum: e635dd00f53d30d31696cf5f95b3a8dbdf9b1aeb36d4391578ce8e8cd22949b7c5536c73b0dc18c78615ea3ddd4be96101166be59ca2e3e3cb1e2f79ba3c7f98 1413 | languageName: node 1414 | linkType: hard 1415 | 1416 | "punycode@npm:^2.1.0": 1417 | version: 2.1.1 1418 | resolution: "punycode@npm:2.1.1" 1419 | checksum: 823bf443c6dd14f669984dea25757b37993f67e8d94698996064035edd43bed8a5a17a9f12e439c2b35df1078c6bec05a6c86e336209eb1061e8025c481168e8 1420 | languageName: node 1421 | linkType: hard 1422 | 1423 | "queue-microtask@npm:^1.2.2": 1424 | version: 1.2.3 1425 | resolution: "queue-microtask@npm:1.2.3" 1426 | checksum: b676f8c040cdc5b12723ad2f91414d267605b26419d5c821ff03befa817ddd10e238d22b25d604920340fd73efd8ba795465a0377c4adf45a4a41e4234e42dc4 1427 | languageName: node 1428 | linkType: hard 1429 | 1430 | "regexpp@npm:^3.2.0": 1431 | version: 3.2.0 1432 | resolution: "regexpp@npm:3.2.0" 1433 | checksum: a78dc5c7158ad9ddcfe01aa9144f46e192ddbfa7b263895a70a5c6c73edd9ce85faf7c0430e59ac38839e1734e275b9c3de5c57ee3ab6edc0e0b1bdebefccef8 1434 | languageName: node 1435 | linkType: hard 1436 | 1437 | "resolve-from@npm:^4.0.0": 1438 | version: 4.0.0 1439 | resolution: "resolve-from@npm:4.0.0" 1440 | checksum: f4ba0b8494846a5066328ad33ef8ac173801a51739eb4d63408c847da9a2e1c1de1e6cbbf72699211f3d13f8fc1325648b169bd15eb7da35688e30a5fb0e4a7f 1441 | languageName: node 1442 | linkType: hard 1443 | 1444 | "reusify@npm:^1.0.4": 1445 | version: 1.0.4 1446 | resolution: "reusify@npm:1.0.4" 1447 | checksum: c3076ebcc22a6bc252cb0b9c77561795256c22b757f40c0d8110b1300723f15ec0fc8685e8d4ea6d7666f36c79ccc793b1939c748bf36f18f542744a4e379fcc 1448 | languageName: node 1449 | linkType: hard 1450 | 1451 | "rimraf@npm:^3.0.2": 1452 | version: 3.0.2 1453 | resolution: "rimraf@npm:3.0.2" 1454 | dependencies: 1455 | glob: ^7.1.3 1456 | bin: 1457 | rimraf: bin.js 1458 | checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0 1459 | languageName: node 1460 | linkType: hard 1461 | 1462 | "run-parallel@npm:^1.1.9": 1463 | version: 1.2.0 1464 | resolution: "run-parallel@npm:1.2.0" 1465 | dependencies: 1466 | queue-microtask: ^1.2.2 1467 | checksum: cb4f97ad25a75ebc11a8ef4e33bb962f8af8516bb2001082ceabd8902e15b98f4b84b4f8a9b222e5d57fc3bd1379c483886ed4619367a7680dad65316993021d 1468 | languageName: node 1469 | linkType: hard 1470 | 1471 | "semver@npm:^7.3.7": 1472 | version: 7.3.7 1473 | resolution: "semver@npm:7.3.7" 1474 | dependencies: 1475 | lru-cache: ^6.0.0 1476 | bin: 1477 | semver: bin/semver.js 1478 | checksum: 2fa3e877568cd6ce769c75c211beaed1f9fce80b28338cadd9d0b6c40f2e2862bafd62c19a6cff42f3d54292b7c623277bcab8816a2b5521cf15210d43e75232 1479 | languageName: node 1480 | linkType: hard 1481 | 1482 | "shebang-command@npm:^2.0.0": 1483 | version: 2.0.0 1484 | resolution: "shebang-command@npm:2.0.0" 1485 | dependencies: 1486 | shebang-regex: ^3.0.0 1487 | checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa 1488 | languageName: node 1489 | linkType: hard 1490 | 1491 | "shebang-regex@npm:^3.0.0": 1492 | version: 3.0.0 1493 | resolution: "shebang-regex@npm:3.0.0" 1494 | checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 1495 | languageName: node 1496 | linkType: hard 1497 | 1498 | "slash@npm:^3.0.0": 1499 | version: 3.0.0 1500 | resolution: "slash@npm:3.0.0" 1501 | checksum: 94a93fff615f25a999ad4b83c9d5e257a7280c90a32a7cb8b4a87996e4babf322e469c42b7f649fd5796edd8687652f3fb452a86dc97a816f01113183393f11c 1502 | languageName: node 1503 | linkType: hard 1504 | 1505 | "split@npm:0.3": 1506 | version: 0.3.3 1507 | resolution: "split@npm:0.3.3" 1508 | dependencies: 1509 | through: 2 1510 | checksum: 2e076634c9637cfdc54ab4387b6a243b8c33b360874a25adf6f327a5647f07cb3bf1c755d515248eb3afee4e382278d01f62c62d87263c118f28065b86f74f02 1511 | languageName: node 1512 | linkType: hard 1513 | 1514 | "stream-combiner@npm:~0.0.4": 1515 | version: 0.0.4 1516 | resolution: "stream-combiner@npm:0.0.4" 1517 | dependencies: 1518 | duplexer: ~0.1.1 1519 | checksum: 844b622cfe8b9de45a6007404f613b60aaf85200ab9862299066204242f89a7c8033b1c356c998aa6cfc630f6cd9eba119ec1c6dc1f93e245982be4a847aee7d 1520 | languageName: node 1521 | linkType: hard 1522 | 1523 | "string-argv@npm:^0.1.1": 1524 | version: 0.1.2 1525 | resolution: "string-argv@npm:0.1.2" 1526 | checksum: 6877bd72af145f6e6eafa932818014a57b2f39225c924562b7fccb50f1fcee73717bbcd5e528fd4d86cec32835c14749c32a9d35f06e0bf96637d1e73158203f 1527 | languageName: node 1528 | linkType: hard 1529 | 1530 | "strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": 1531 | version: 6.0.1 1532 | resolution: "strip-ansi@npm:6.0.1" 1533 | dependencies: 1534 | ansi-regex: ^5.0.1 1535 | checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c 1536 | languageName: node 1537 | linkType: hard 1538 | 1539 | "strip-json-comments@npm:^3.1.0, strip-json-comments@npm:^3.1.1": 1540 | version: 3.1.1 1541 | resolution: "strip-json-comments@npm:3.1.1" 1542 | checksum: 492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443 1543 | languageName: node 1544 | linkType: hard 1545 | 1546 | "supports-color@npm:^7.1.0": 1547 | version: 7.2.0 1548 | resolution: "supports-color@npm:7.2.0" 1549 | dependencies: 1550 | has-flag: ^4.0.0 1551 | checksum: 3dda818de06ebbe5b9653e07842d9479f3555ebc77e9a0280caf5a14fb877ffee9ed57007c3b78f5a6324b8dbeec648d9e97a24e2ed9fdb81ddc69ea07100f4a 1552 | languageName: node 1553 | linkType: hard 1554 | 1555 | "text-table@npm:^0.2.0": 1556 | version: 0.2.0 1557 | resolution: "text-table@npm:0.2.0" 1558 | checksum: b6937a38c80c7f84d9c11dd75e49d5c44f71d95e810a3250bd1f1797fc7117c57698204adf676b71497acc205d769d65c16ae8fa10afad832ae1322630aef10a 1559 | languageName: node 1560 | linkType: hard 1561 | 1562 | "through@npm:2, through@npm:~2.3, through@npm:~2.3.1": 1563 | version: 2.3.8 1564 | resolution: "through@npm:2.3.8" 1565 | checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd 1566 | languageName: node 1567 | linkType: hard 1568 | 1569 | "tmi.js@npm:^1.8.5": 1570 | version: 1.8.5 1571 | resolution: "tmi.js@npm:1.8.5" 1572 | dependencies: 1573 | node-fetch: ^2.6.1 1574 | ws: ^8.2.0 1575 | checksum: a48a05d9f2c5ac27a6d14ef243e787e6693bce8a3891c65da26d359c12d311b46518b36f98fe8139d0f96b74c0d773e039a5ea2763e9aaeace4eed63f91c2c86 1576 | languageName: node 1577 | linkType: hard 1578 | 1579 | "to-regex-range@npm:^5.0.1": 1580 | version: 5.0.1 1581 | resolution: "to-regex-range@npm:5.0.1" 1582 | dependencies: 1583 | is-number: ^7.0.0 1584 | checksum: f76fa01b3d5be85db6a2a143e24df9f60dd047d151062d0ba3df62953f2f697b16fe5dad9b0ac6191c7efc7b1d9dcaa4b768174b7b29da89d4428e64bc0a20ed 1585 | languageName: node 1586 | linkType: hard 1587 | 1588 | "tr46@npm:~0.0.3": 1589 | version: 0.0.3 1590 | resolution: "tr46@npm:0.0.3" 1591 | checksum: 726321c5eaf41b5002e17ffbd1fb7245999a073e8979085dacd47c4b4e8068ff5777142fc6726d6ca1fd2ff16921b48788b87225cbc57c72636f6efa8efbffe3 1592 | languageName: node 1593 | linkType: hard 1594 | 1595 | "tsc-watch@npm:^5.0.3": 1596 | version: 5.0.3 1597 | resolution: "tsc-watch@npm:5.0.3" 1598 | dependencies: 1599 | cross-spawn: ^7.0.3 1600 | node-cleanup: ^2.1.2 1601 | ps-tree: ^1.2.0 1602 | string-argv: ^0.1.1 1603 | strip-ansi: ^6.0.0 1604 | peerDependencies: 1605 | typescript: "*" 1606 | bin: 1607 | tsc-watch: index.js 1608 | checksum: abd63295dd5fda098a45d27912031e6c35a95f1aa20d7a86d6ad1469580400069e6476f2ffd4b88e37886d016443e60b1ae2dbcaf756e324efc67d0fa713fb15 1609 | languageName: node 1610 | linkType: hard 1611 | 1612 | "tslib@npm:^1.8.1": 1613 | version: 1.14.1 1614 | resolution: "tslib@npm:1.14.1" 1615 | checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd 1616 | languageName: node 1617 | linkType: hard 1618 | 1619 | "tsutils@npm:^3.21.0": 1620 | version: 3.21.0 1621 | resolution: "tsutils@npm:3.21.0" 1622 | dependencies: 1623 | tslib: ^1.8.1 1624 | peerDependencies: 1625 | typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" 1626 | checksum: 1843f4c1b2e0f975e08c4c21caa4af4f7f65a12ac1b81b3b8489366826259323feb3fc7a243123453d2d1a02314205a7634e048d4a8009921da19f99755cdc48 1627 | languageName: node 1628 | linkType: hard 1629 | 1630 | "twitch-chat-pubsub@workspace:.": 1631 | version: 0.0.0-use.local 1632 | resolution: "twitch-chat-pubsub@workspace:." 1633 | dependencies: 1634 | "@types/node": ^18.7.23 1635 | "@types/tmi.js": ^1.8.1 1636 | "@types/uuid": ^8.3.4 1637 | "@typescript-eslint/eslint-plugin": ^5.38.1 1638 | "@typescript-eslint/parser": ^5.38.1 1639 | base-x: ^4.0.0 1640 | bebop: ^2.4.6 1641 | bebop-tools: ^2.4.6 1642 | dotenv: ^16.0.3 1643 | esbuild: ^0.15.10 1644 | eslint: ^8.24.0 1645 | eslint-config-prettier: ^8.5.0 1646 | eslint-plugin-prettier: ^4.2.1 1647 | eventemitter3: ^4.0.7 1648 | prettier: ^2.7.1 1649 | tmi.js: ^1.8.5 1650 | tsc-watch: ^5.0.3 1651 | typescript: ^4.8.4 1652 | uuid: ^9.0.0 1653 | languageName: unknown 1654 | linkType: soft 1655 | 1656 | "type-check@npm:^0.4.0, type-check@npm:~0.4.0": 1657 | version: 0.4.0 1658 | resolution: "type-check@npm:0.4.0" 1659 | dependencies: 1660 | prelude-ls: ^1.2.1 1661 | checksum: ec688ebfc9c45d0c30412e41ca9c0cdbd704580eb3a9ccf07b9b576094d7b86a012baebc95681999dd38f4f444afd28504cb3a89f2ef16b31d4ab61a0739025a 1662 | languageName: node 1663 | linkType: hard 1664 | 1665 | "type-fest@npm:^0.20.2": 1666 | version: 0.20.2 1667 | resolution: "type-fest@npm:0.20.2" 1668 | checksum: 4fb3272df21ad1c552486f8a2f8e115c09a521ad7a8db3d56d53718d0c907b62c6e9141ba5f584af3f6830d0872c521357e512381f24f7c44acae583ad517d73 1669 | languageName: node 1670 | linkType: hard 1671 | 1672 | "typescript@npm:^4.8.4": 1673 | version: 4.8.4 1674 | resolution: "typescript@npm:4.8.4" 1675 | bin: 1676 | tsc: bin/tsc 1677 | tsserver: bin/tsserver 1678 | checksum: 3e4f061658e0c8f36c820802fa809e0fd812b85687a9a2f5430bc3d0368e37d1c9605c3ce9b39df9a05af2ece67b1d844f9f6ea8ff42819f13bcb80f85629af0 1679 | languageName: node 1680 | linkType: hard 1681 | 1682 | "typescript@patch:typescript@^4.8.4#~builtin": 1683 | version: 4.8.4 1684 | resolution: "typescript@patch:typescript@npm%3A4.8.4#~builtin::version=4.8.4&hash=a1c5e5" 1685 | bin: 1686 | tsc: bin/tsc 1687 | tsserver: bin/tsserver 1688 | checksum: 563a0ef47abae6df27a9a3ab38f75fc681f633ccf1a3502b1108e252e187787893de689220f4544aaf95a371a4eb3141e4a337deb9895de5ac3c1ca76430e5f0 1689 | languageName: node 1690 | linkType: hard 1691 | 1692 | "uri-js@npm:^4.2.2": 1693 | version: 4.4.1 1694 | resolution: "uri-js@npm:4.4.1" 1695 | dependencies: 1696 | punycode: ^2.1.0 1697 | checksum: 7167432de6817fe8e9e0c9684f1d2de2bb688c94388f7569f7dbdb1587c9f4ca2a77962f134ec90be0cc4d004c939ff0d05acc9f34a0db39a3c797dada262633 1698 | languageName: node 1699 | linkType: hard 1700 | 1701 | "uuid@npm:^9.0.0": 1702 | version: 9.0.0 1703 | resolution: "uuid@npm:9.0.0" 1704 | bin: 1705 | uuid: dist/bin/uuid 1706 | checksum: 8dd2c83c43ddc7e1c71e36b60aea40030a6505139af6bee0f382ebcd1a56f6cd3028f7f06ffb07f8cf6ced320b76aea275284b224b002b289f89fe89c389b028 1707 | languageName: node 1708 | linkType: hard 1709 | 1710 | "webidl-conversions@npm:^3.0.0": 1711 | version: 3.0.1 1712 | resolution: "webidl-conversions@npm:3.0.1" 1713 | checksum: c92a0a6ab95314bde9c32e1d0a6dfac83b578f8fa5f21e675bc2706ed6981bc26b7eb7e6a1fab158e5ce4adf9caa4a0aee49a52505d4d13c7be545f15021b17c 1714 | languageName: node 1715 | linkType: hard 1716 | 1717 | "whatwg-url@npm:^5.0.0": 1718 | version: 5.0.0 1719 | resolution: "whatwg-url@npm:5.0.0" 1720 | dependencies: 1721 | tr46: ~0.0.3 1722 | webidl-conversions: ^3.0.0 1723 | checksum: b8daed4ad3356cc4899048a15b2c143a9aed0dfae1f611ebd55073310c7b910f522ad75d727346ad64203d7e6c79ef25eafd465f4d12775ca44b90fa82ed9e2c 1724 | languageName: node 1725 | linkType: hard 1726 | 1727 | "which@npm:^2.0.1": 1728 | version: 2.0.2 1729 | resolution: "which@npm:2.0.2" 1730 | dependencies: 1731 | isexe: ^2.0.0 1732 | bin: 1733 | node-which: ./bin/node-which 1734 | checksum: 1a5c563d3c1b52d5f893c8b61afe11abc3bab4afac492e8da5bde69d550de701cf9806235f20a47b5c8fa8a1d6a9135841de2596535e998027a54589000e66d1 1735 | languageName: node 1736 | linkType: hard 1737 | 1738 | "word-wrap@npm:^1.2.3": 1739 | version: 1.2.3 1740 | resolution: "word-wrap@npm:1.2.3" 1741 | checksum: 30b48f91fcf12106ed3186ae4fa86a6a1842416df425be7b60485de14bec665a54a68e4b5156647dec3a70f25e84d270ca8bc8cd23182ed095f5c7206a938c1f 1742 | languageName: node 1743 | linkType: hard 1744 | 1745 | "wrappy@npm:1": 1746 | version: 1.0.2 1747 | resolution: "wrappy@npm:1.0.2" 1748 | checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 1749 | languageName: node 1750 | linkType: hard 1751 | 1752 | "ws@npm:^8.2.0": 1753 | version: 8.9.0 1754 | resolution: "ws@npm:8.9.0" 1755 | peerDependencies: 1756 | bufferutil: ^4.0.1 1757 | utf-8-validate: ^5.0.2 1758 | peerDependenciesMeta: 1759 | bufferutil: 1760 | optional: true 1761 | utf-8-validate: 1762 | optional: true 1763 | checksum: 23aa0f021b2eb65c108ec4c3e08c0d81ba01f82b500432dfe327fd6be36079c1d81fdb0eac6464d2a0eb49904d34a9ab8c59619d673fa07b8346f83aeb0cbf12 1764 | languageName: node 1765 | linkType: hard 1766 | 1767 | "yallist@npm:^4.0.0": 1768 | version: 4.0.0 1769 | resolution: "yallist@npm:4.0.0" 1770 | checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5 1771 | languageName: node 1772 | linkType: hard 1773 | 1774 | "yocto-queue@npm:^0.1.0": 1775 | version: 0.1.0 1776 | resolution: "yocto-queue@npm:0.1.0" 1777 | checksum: f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 1778 | languageName: node 1779 | linkType: hard 1780 | --------------------------------------------------------------------------------