diff --git a/.env.example b/.env.example index 876b8ab..93a9ff8 100644 --- a/.env.example +++ b/.env.example @@ -6,8 +6,7 @@ # ------------------------------------------------------------------------------ # ----------------------------------------------------------------------------- -# ChatGPT +# OpenAI # ----------------------------------------------------------------------------- -OPENAI_EMAIL= -OPENAI_PASSWORD= +OPENAI_API_KEY= diff --git a/demos/demo-conversation.ts b/demos/demo-conversation.ts index 1c4d694..6967e22 100644 --- a/demos/demo-conversation.ts +++ b/demos/demo-conversation.ts @@ -1,7 +1,7 @@ import dotenv from 'dotenv-safe' import { oraPromise } from 'ora' -import { ChatGPTAPIBrowser } from '../src' +import { ChatGPTAPI } from '../src' dotenv.config() @@ -13,16 +13,10 @@ dotenv.config() * ``` */ async function main() { - const email = process.env.OPENAI_EMAIL - const password = process.env.OPENAI_PASSWORD - - const api = new ChatGPTAPIBrowser({ - email, - password, - debug: false, - minimize: true + const api = new ChatGPTAPI({ + apiKey: process.env.OPENAI_API_KEY, + debug: false }) - await api.initSession() const prompt = 'Write a poem about cats.' @@ -30,49 +24,46 @@ async function main() { text: prompt }) - console.log('\n' + res.response + '\n') + console.log('\n' + res.text + '\n') const prompt2 = 'Can you make it cuter and shorter?' res = await oraPromise( api.sendMessage(prompt2, { conversationId: res.conversationId, - parentMessageId: res.messageId + parentMessageId: res.id }), { text: prompt2 } ) - console.log('\n' + res.response + '\n') + console.log('\n' + res.text + '\n') const prompt3 = 'Now write it in French.' res = await oraPromise( api.sendMessage(prompt3, { conversationId: res.conversationId, - parentMessageId: res.messageId + parentMessageId: res.id }), { text: prompt3 } ) - console.log('\n' + res.response + '\n') + console.log('\n' + res.text + '\n') const prompt4 = 'What were we talking about again?' res = await oraPromise( api.sendMessage(prompt4, { conversationId: res.conversationId, - parentMessageId: res.messageId + parentMessageId: res.id }), { text: prompt4 } ) - console.log('\n' + res.response + '\n') - - // close the browser at the end - await api.closeSession() + console.log('\n' + res.text + '\n') } main().catch((err) => { diff --git a/demos/demo-google-auth.ts b/demos/demo-google-auth.ts deleted file mode 100644 index d20420b..0000000 --- a/demos/demo-google-auth.ts +++ /dev/null @@ -1,43 +0,0 @@ -import dotenv from 'dotenv-safe' -import { oraPromise } from 'ora' - -import { ChatGPTAPIBrowser } from '../src' - -dotenv.config() - -/** - * Demo CLI for testing basic functionality using Google auth. - * - * ``` - * npx tsx demos/demo.ts - * ``` - */ -async function main() { - const email = process.env.OPENAI_EMAIL - const password = process.env.OPENAI_PASSWORD - - const api = new ChatGPTAPIBrowser({ - email, - password, - isGoogleLogin: true, - debug: false, - minimize: true - }) - await api.initSession() - - const prompt = - 'Write a python version of bubble sort. Do not include example usage.' - - const res = await oraPromise(api.sendMessage(prompt), { - text: prompt - }) - console.log(res.response) - - // close the browser at the end - await api.closeSession() -} - -main().catch((err) => { - console.error(err) - process.exit(1) -}) diff --git a/demos/demo-on-progress.ts b/demos/demo-on-progress.ts index 69dfa4e..8711645 100644 --- a/demos/demo-on-progress.ts +++ b/demos/demo-on-progress.ts @@ -1,27 +1,18 @@ import dotenv from 'dotenv-safe' -import { ChatGPTAPIBrowser } from '../src' +import { ChatGPTAPI } from '../src' dotenv.config() /** - * Demo CLI for testing the `onProgress` handler. + * Demo CLI for testing the `onProgress` streaming support. * * ``` * npx tsx demos/demo-on-progress.ts * ``` */ async function main() { - const email = process.env.OPENAI_EMAIL - const password = process.env.OPENAI_PASSWORD - - const api = new ChatGPTAPIBrowser({ - email, - password, - debug: false, - minimize: true - }) - await api.initSession() + const api = new ChatGPTAPI({ apiKey: process.env.OPENAI_API_KEY }) const prompt = 'Write a python version of bubble sort. Do not include example usage.' @@ -29,14 +20,10 @@ async function main() { console.log(prompt) const res = await api.sendMessage(prompt, { onProgress: (partialResponse) => { - console.log('p') - console.log('progress', partialResponse?.response) + console.log(partialResponse.text) } }) - console.log(res.response) - - // close the browser at the end - await api.closeSession() + console.log(res.text) } main().catch((err) => { diff --git a/demos/demo-persistence.ts b/demos/demo-persistence.ts new file mode 100644 index 0000000..0a80c35 --- /dev/null +++ b/demos/demo-persistence.ts @@ -0,0 +1,72 @@ +import KeyvRedis from '@keyv/redis' +import dotenv from 'dotenv-safe' +import Keyv from 'keyv' +import { oraPromise } from 'ora' + +import { ChatGPTAPI, type ChatMessage } from '../src' + +dotenv.config() + +/** + * Demo CLI for testing message persistence with redis. + * + * ``` + * npx tsx demos/demo-persistence.ts + * ``` + */ +async function main() { + const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379' + const store = new KeyvRedis(redisUrl) + const messageStore = new Keyv({ store, namespace: 'chatgpt-demo' }) + + let res: ChatMessage + + { + // create an initial conversation in one client + const api = new ChatGPTAPI({ + apiKey: process.env.OPENAI_API_KEY, + messageStore + }) + + const prompt = 'What are the top 5 anime of all time?' + + res = await oraPromise(api.sendMessage(prompt), { + text: prompt + }) + console.log('\n' + res.text + '\n') + } + + { + // follow up with a second client using the same underlying redis store + const api = new ChatGPTAPI({ + apiKey: process.env.OPENAI_API_KEY, + messageStore + }) + + const prompt = 'Can you give 5 more?' + + res = await oraPromise( + api.sendMessage(prompt, { + conversationId: res.conversationId, + parentMessageId: res.id + }), + { + text: prompt + } + ) + console.log('\n' + res.text + '\n') + } + + // wait for redis to finish and then disconnect + await new Promise((resolve) => { + setTimeout(() => { + messageStore.disconnect() + resolve() + }, 1000) + }) +} + +main().catch((err) => { + console.error(err) + process.exit(1) +}) diff --git a/demos/demo.ts b/demos/demo.ts index 8f0b234..08577fc 100644 --- a/demos/demo.ts +++ b/demos/demo.ts @@ -1,7 +1,7 @@ import dotenv from 'dotenv-safe' import { oraPromise } from 'ora' -import { ChatGPTAPIBrowser } from '../src' +import { ChatGPTAPI } from '../src' dotenv.config() @@ -13,16 +13,7 @@ dotenv.config() * ``` */ async function main() { - const email = process.env.OPENAI_EMAIL - const password = process.env.OPENAI_PASSWORD - - const api = new ChatGPTAPIBrowser({ - email, - password, - debug: false, - minimize: true - }) - await api.initSession() + const api = new ChatGPTAPI({ apiKey: process.env.OPENAI_API_KEY }) const prompt = 'Write a python version of bubble sort. Do not include example usage.' @@ -30,10 +21,7 @@ async function main() { const res = await oraPromise(api.sendMessage(prompt), { text: prompt }) - console.log(res.response) - - // close the browser at the end - await api.closeSession() + console.log(res) } main().catch((err) => { diff --git a/docs/classes/AChatGPTAPI.md b/docs/classes/AChatGPTAPI.md deleted file mode 100644 index 3682441..0000000 --- a/docs/classes/AChatGPTAPI.md +++ /dev/null @@ -1,167 +0,0 @@ -[chatgpt](../readme.md) / [Exports](../modules.md) / AChatGPTAPI - -# Class: AChatGPTAPI - -## Hierarchy - -- **`AChatGPTAPI`** - - ↳ [`ChatGPTAPI`](ChatGPTAPI.md) - - ↳ [`ChatGPTAPIBrowser`](ChatGPTAPIBrowser.md) - -## Table of contents - -### Constructors - -- [constructor](AChatGPTAPI.md#constructor) - -### Methods - -- [closeSession](AChatGPTAPI.md#closesession) -- [getIsAuthenticated](AChatGPTAPI.md#getisauthenticated) -- [initSession](AChatGPTAPI.md#initsession) -- [refreshSession](AChatGPTAPI.md#refreshsession) -- [resetSession](AChatGPTAPI.md#resetsession) -- [sendMessage](AChatGPTAPI.md#sendmessage) - -## Constructors - -### constructor - -• **new AChatGPTAPI**() - -## Methods - -### closeSession - -▸ `Abstract` **closeSession**(): `Promise`<`void`\> - -Closes the active session. - -**`Throws`** - -An error if it fails. - -#### Returns - -`Promise`<`void`\> - -#### Defined in - -[src/abstract-chatgpt-api.ts:69](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/abstract-chatgpt-api.ts#L69) - -___ - -### getIsAuthenticated - -▸ `Abstract` **getIsAuthenticated**(): `Promise`<`boolean`\> - -#### Returns - -`Promise`<`boolean`\> - -`true` if the client is authenticated with a valid session or `false` -otherwise. - -#### Defined in - -[src/abstract-chatgpt-api.ts:39](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/abstract-chatgpt-api.ts#L39) - -___ - -### initSession - -▸ `Abstract` **initSession**(): `Promise`<`void`\> - -Performs any async initialization work required to ensure that this API is -properly authenticated. - -**`Throws`** - -An error if the session failed to initialize properly. - -#### Returns - -`Promise`<`void`\> - -#### Defined in - -[src/abstract-chatgpt-api.ts:10](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/abstract-chatgpt-api.ts#L10) - -___ - -### refreshSession - -▸ `Abstract` **refreshSession**(): `Promise`<`any`\> - -Refreshes the current ChatGPT session. - -Useful for bypassing 403 errors when Cloudflare clearance tokens expire. - -**`Throws`** - -An error if it fails. - -#### Returns - -`Promise`<`any`\> - -Access credentials for the new session. - -#### Defined in - -[src/abstract-chatgpt-api.ts:49](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/abstract-chatgpt-api.ts#L49) - -___ - -### resetSession - -▸ **resetSession**(): `Promise`<`any`\> - -Closes the current ChatGPT session and starts a new one. - -Useful for bypassing 401 errors when sessions expire. - -**`Throws`** - -An error if it fails. - -#### Returns - -`Promise`<`any`\> - -Access credentials for the new session. - -#### Defined in - -[src/abstract-chatgpt-api.ts:59](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/abstract-chatgpt-api.ts#L59) - -___ - -### sendMessage - -▸ `Abstract` **sendMessage**(`message`, `opts?`): `Promise`<[`ChatResponse`](../modules.md#chatresponse)\> - -Sends a message to ChatGPT, waits for the response to resolve, and returns -the response. - -If you want to receive a stream of partial responses, use `opts.onProgress`. - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `message` | `string` | The prompt message to send | -| `opts?` | [`SendMessageOptions`](../modules.md#sendmessageoptions) | - | - -#### Returns - -`Promise`<[`ChatResponse`](../modules.md#chatresponse)\> - -The response from ChatGPT, including `conversationId`, `messageId`, and -the `response` text. - -#### Defined in - -[src/abstract-chatgpt-api.ts:30](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/abstract-chatgpt-api.ts#L30) diff --git a/docs/classes/ChatGPTAPI.md b/docs/classes/ChatGPTAPI.md index a011085..003f3d8 100644 --- a/docs/classes/ChatGPTAPI.md +++ b/docs/classes/ChatGPTAPI.md @@ -2,34 +2,15 @@ # Class: ChatGPTAPI -## Hierarchy - -- [`AChatGPTAPI`](AChatGPTAPI.md) - - ↳ **`ChatGPTAPI`** - ## Table of contents ### Constructors - [constructor](ChatGPTAPI.md#constructor) -### Accessors - -- [clearanceToken](ChatGPTAPI.md#clearancetoken) -- [sessionToken](ChatGPTAPI.md#sessiontoken) -- [user](ChatGPTAPI.md#user) -- [userAgent](ChatGPTAPI.md#useragent) - ### Methods -- [closeSession](ChatGPTAPI.md#closesession) -- [getIsAuthenticated](ChatGPTAPI.md#getisauthenticated) -- [initSession](ChatGPTAPI.md#initsession) -- [refreshSession](ChatGPTAPI.md#refreshsession) -- [resetSession](ChatGPTAPI.md#resetsession) - [sendMessage](ChatGPTAPI.md#sendmessage) -- [sendModeration](ChatGPTAPI.md#sendmoderation) ## Constructors @@ -37,228 +18,31 @@ • **new ChatGPTAPI**(`opts`) -Creates a new client wrapper around the unofficial ChatGPT REST API. - -Note that your IP address and `userAgent` must match the same values that you used -to obtain your `clearanceToken`. +Creates a new client wrapper around OpenAI's completion API using the +unofficial ChatGPT model. #### Parameters | Name | Type | Description | | :------ | :------ | :------ | | `opts` | `Object` | - | -| `opts.accessToken?` | `string` | **`Default Value`** `undefined` * | -| `opts.accessTokenTTL?` | `number` | **`Default Value`** 1 hour * | -| `opts.apiBaseUrl?` | `string` | **`Default Value`** `'https://chat.openai.com/api'` * | -| `opts.backendApiBaseUrl?` | `string` | **`Default Value`** `'https://chat.openai.com/backend-api'` * | -| `opts.clearanceToken` | `string` | = **Required** Cloudflare `cf_clearance` cookie value (see readme for instructions) | -| `opts.debug?` | `boolean` | **`Default Value`** `false` * | -| `opts.headers?` | `Record`<`string`, `string`\> | **`Default Value`** `undefined` * | -| `opts.markdown?` | `boolean` | **`Default Value`** `true` * | -| `opts.sessionToken` | `string` | = **Required** OpenAI session token which can be found in a valid session's cookies (see readme for instructions) | -| `opts.userAgent?` | `string` | **`Default Value`** `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'` * | - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[constructor](AChatGPTAPI.md#constructor) +| `opts.apiBaseUrl?` | `string` | **`Default Value`** `'https://api.openai.com'` * | +| `opts.apiKey` | `string` | - | +| `opts.completionParams?` | [`CompletionParams`](../modules/openai.md#completionparams) | - | +| `opts.debug?` | `boolean` | **`Default Value`** `false` * | +| `opts.getMessageById?` | [`GetMessageByIdFunction`](../modules.md#getmessagebyidfunction) | - | +| `opts.messageStore?` | `Keyv`<`any`, `Record`<`string`, `unknown`\>\> | - | +| `opts.upsertMessage?` | [`UpsertMessageFunction`](../modules.md#upsertmessagefunction) | - | #### Defined in -[src/chatgpt-api.ts:45](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api.ts#L45) - -## Accessors - -### clearanceToken - -• `get` **clearanceToken**(): `string` - -Gets the current Cloudflare clearance token (`cf_clearance` cookie value). - -#### Returns - -`string` - -#### Defined in - -[src/chatgpt-api.ts:143](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api.ts#L143) - -___ - -### sessionToken - -• `get` **sessionToken**(): `string` - -Gets the current session token. - -#### Returns - -`string` - -#### Defined in - -[src/chatgpt-api.ts:138](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api.ts#L138) - -___ - -### user - -• `get` **user**(): [`User`](../modules.md#user) - -Gets the currently signed-in user, if authenticated, `null` otherwise. - -#### Returns - -[`User`](../modules.md#user) - -#### Defined in - -[src/chatgpt-api.ts:133](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api.ts#L133) - -___ - -### userAgent - -• `get` **userAgent**(): `string` - -Gets the current user agent. - -#### Returns - -`string` - -#### Defined in - -[src/chatgpt-api.ts:148](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api.ts#L148) +[src/chatgpt-api.ts:36](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/chatgpt-api.ts#L36) ## Methods -### closeSession - -▸ **closeSession**(): `Promise`<`void`\> - -Closes the active session. - -**`Throws`** - -An error if it fails. - -#### Returns - -`Promise`<`void`\> - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[closeSession](AChatGPTAPI.md#closesession) - -#### Defined in - -[src/chatgpt-api.ts:470](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api.ts#L470) - -___ - -### getIsAuthenticated - -▸ **getIsAuthenticated**(): `Promise`<`boolean`\> - -#### Returns - -`Promise`<`boolean`\> - -`true` if the client has a valid acces token or `false` if refreshing -the token fails. - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[getIsAuthenticated](AChatGPTAPI.md#getisauthenticated) - -#### Defined in - -[src/chatgpt-api.ts:367](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api.ts#L367) - -___ - -### initSession - -▸ **initSession**(): `Promise`<`void`\> - -Refreshes the client's access token which will succeed only if the session -is valid. - -#### Returns - -`Promise`<`void`\> - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[initSession](AChatGPTAPI.md#initsession) - -#### Defined in - -[src/chatgpt-api.ts:156](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api.ts#L156) - -___ - -### refreshSession - -▸ **refreshSession**(): `Promise`<`string`\> - -Attempts to refresh the current access token using the ChatGPT -`sessionToken` cookie. - -Access tokens will be cached for up to `accessTokenTTL` milliseconds to -prevent refreshing access tokens too frequently. - -**`Throws`** - -An error if refreshing the access token fails. - -#### Returns - -`Promise`<`string`\> - -A valid access token - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[refreshSession](AChatGPTAPI.md#refreshsession) - -#### Defined in - -[src/chatgpt-api.ts:386](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api.ts#L386) - -___ - -### resetSession - -▸ **resetSession**(): `Promise`<`any`\> - -Closes the current ChatGPT session and starts a new one. - -Useful for bypassing 401 errors when sessions expire. - -**`Throws`** - -An error if it fails. - -#### Returns - -`Promise`<`any`\> - -Access credentials for the new session. - -#### Inherited from - -[AChatGPTAPI](AChatGPTAPI.md).[resetSession](AChatGPTAPI.md#resetsession) - -#### Defined in - -[src/abstract-chatgpt-api.ts:59](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/abstract-chatgpt-api.ts#L59) - -___ - ### sendMessage -▸ **sendMessage**(`message`, `opts?`): `Promise`<[`ChatResponse`](../modules.md#chatresponse)\> +▸ **sendMessage**(`text`, `opts?`): `Promise`<[`ChatMessage`](../interfaces/ChatMessage.md)\> Sends a message to ChatGPT, waits for the response to resolve, and returns the response. @@ -270,41 +54,17 @@ helper. #### Parameters -| Name | Type | Description | -| :------ | :------ | :------ | -| `message` | `string` | The prompt message to send | -| `opts` | [`SendMessageOptions`](../modules.md#sendmessageoptions) | - | +| Name | Type | +| :------ | :------ | +| `text` | `string` | +| `opts` | [`SendMessageOptions`](../modules.md#sendmessageoptions) | #### Returns -`Promise`<[`ChatResponse`](../modules.md#chatresponse)\> +`Promise`<[`ChatMessage`](../interfaces/ChatMessage.md)\> The response from ChatGPT -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[sendMessage](AChatGPTAPI.md#sendmessage) - #### Defined in -[src/chatgpt-api.ts:180](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api.ts#L180) - -___ - -### sendModeration - -▸ **sendModeration**(`input`): `Promise`<[`ModerationsJSONResult`](../modules.md#moderationsjsonresult)\> - -#### Parameters - -| Name | Type | -| :------ | :------ | -| `input` | `string` | - -#### Returns - -`Promise`<[`ModerationsJSONResult`](../modules.md#moderationsjsonresult)\> - -#### Defined in - -[src/chatgpt-api.ts:324](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api.ts#L324) +[src/chatgpt-api.ts:109](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/chatgpt-api.ts#L109) diff --git a/docs/classes/ChatGPTAPIBrowser.md b/docs/classes/ChatGPTAPIBrowser.md deleted file mode 100644 index 984b948..0000000 --- a/docs/classes/ChatGPTAPIBrowser.md +++ /dev/null @@ -1,277 +0,0 @@ -[chatgpt](../readme.md) / [Exports](../modules.md) / ChatGPTAPIBrowser - -# Class: ChatGPTAPIBrowser - -## Hierarchy - -- [`AChatGPTAPI`](AChatGPTAPI.md) - - ↳ **`ChatGPTAPIBrowser`** - -## Table of contents - -### Constructors - -- [constructor](ChatGPTAPIBrowser.md#constructor) - -### Accessors - -- [isChatPage](ChatGPTAPIBrowser.md#ischatpage) - -### Methods - -- [\_onRequest](ChatGPTAPIBrowser.md#_onrequest) -- [\_onResponse](ChatGPTAPIBrowser.md#_onresponse) -- [closeSession](ChatGPTAPIBrowser.md#closesession) -- [getIsAuthenticated](ChatGPTAPIBrowser.md#getisauthenticated) -- [initSession](ChatGPTAPIBrowser.md#initsession) -- [refreshSession](ChatGPTAPIBrowser.md#refreshsession) -- [resetSession](ChatGPTAPIBrowser.md#resetsession) -- [resetThread](ChatGPTAPIBrowser.md#resetthread) -- [sendMessage](ChatGPTAPIBrowser.md#sendmessage) - -## Constructors - -### constructor - -• **new ChatGPTAPIBrowser**(`opts`) - -Creates a new client for automating the ChatGPT webapp. - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `opts` | `Object` | - | -| `opts.captchaToken?` | `string` | **`Default Value`** `undefined` * | -| `opts.debug?` | `boolean` | **`Default Value`** `false` * | -| `opts.email` | `string` | - | -| `opts.executablePath?` | `string` | **`Default Value`** `undefined` * | -| `opts.isGoogleLogin?` | `boolean` | **`Default Value`** `false` * | -| `opts.isMicrosoftLogin?` | `boolean` | **`Default Value`** `false` * | -| `opts.isProAccount?` | `boolean` | **`Default Value`** `false` * | -| `opts.markdown?` | `boolean` | **`Default Value`** `true` * | -| `opts.minimize?` | `boolean` | **`Default Value`** `true` * | -| `opts.nopechaKey?` | `string` | **`Default Value`** `undefined` * | -| `opts.password` | `string` | - | -| `opts.proxyServer?` | `string` | **`Default Value`** `undefined` * | -| `opts.userDataDir?` | `string` | **`Default Value`** `random directory with email as prefix` * | - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[constructor](AChatGPTAPI.md#constructor) - -#### Defined in - -[src/chatgpt-api-browser.ts:48](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api-browser.ts#L48) - -## Accessors - -### isChatPage - -• `get` **isChatPage**(): `boolean` - -#### Returns - -`boolean` - -#### Defined in - -[src/chatgpt-api-browser.ts:640](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api-browser.ts#L640) - -## Methods - -### \_onRequest - -▸ **_onRequest**(`request`): `void` - -#### Parameters - -| Name | Type | -| :------ | :------ | -| `request` | `HTTPRequest` | - -#### Returns - -`void` - -#### Defined in - -[src/chatgpt-api-browser.ts:255](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api-browser.ts#L255) - -___ - -### \_onResponse - -▸ **_onResponse**(`response`): `Promise`<`void`\> - -#### Parameters - -| Name | Type | -| :------ | :------ | -| `response` | `HTTPResponse` | - -#### Returns - -`Promise`<`void`\> - -#### Defined in - -[src/chatgpt-api-browser.ts:292](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api-browser.ts#L292) - -___ - -### closeSession - -▸ **closeSession**(): `Promise`<`void`\> - -Closes the active session. - -**`Throws`** - -An error if it fails. - -#### Returns - -`Promise`<`void`\> - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[closeSession](AChatGPTAPI.md#closesession) - -#### Defined in - -[src/chatgpt-api-browser.ts:586](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api-browser.ts#L586) - -___ - -### getIsAuthenticated - -▸ **getIsAuthenticated**(): `Promise`<`boolean`\> - -#### Returns - -`Promise`<`boolean`\> - -`true` if the client is authenticated with a valid session or `false` -otherwise. - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[getIsAuthenticated](AChatGPTAPI.md#getisauthenticated) - -#### Defined in - -[src/chatgpt-api-browser.ts:425](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api-browser.ts#L425) - -___ - -### initSession - -▸ **initSession**(): `Promise`<`void`\> - -Performs any async initialization work required to ensure that this API is -properly authenticated. - -**`Throws`** - -An error if the session failed to initialize properly. - -#### Returns - -`Promise`<`void`\> - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[initSession](AChatGPTAPI.md#initsession) - -#### Defined in - -[src/chatgpt-api-browser.ts:133](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api-browser.ts#L133) - -___ - -### refreshSession - -▸ **refreshSession**(): `Promise`<`void`\> - -Attempts to handle 403 errors by refreshing the page. - -#### Returns - -`Promise`<`void`\> - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[refreshSession](AChatGPTAPI.md#refreshsession) - -#### Defined in - -[src/chatgpt-api-browser.ts:367](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api-browser.ts#L367) - -___ - -### resetSession - -▸ **resetSession**(): `Promise`<`void`\> - -Attempts to handle 401 errors by re-authenticating. - -#### Returns - -`Promise`<`void`\> - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[resetSession](AChatGPTAPI.md#resetsession) - -#### Defined in - -[src/chatgpt-api-browser.ts:348](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api-browser.ts#L348) - -___ - -### resetThread - -▸ **resetThread**(): `Promise`<`void`\> - -#### Returns - -`Promise`<`void`\> - -#### Defined in - -[src/chatgpt-api-browser.ts:578](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api-browser.ts#L578) - -___ - -### sendMessage - -▸ **sendMessage**(`message`, `opts?`): `Promise`<[`ChatResponse`](../modules.md#chatresponse)\> - -Sends a message to ChatGPT, waits for the response to resolve, and returns -the response. - -If you want to receive a stream of partial responses, use `opts.onProgress`. - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `message` | `string` | The prompt message to send | -| `opts` | [`SendMessageOptions`](../modules.md#sendmessageoptions) | - | - -#### Returns - -`Promise`<[`ChatResponse`](../modules.md#chatresponse)\> - -The response from ChatGPT, including `conversationId`, `messageId`, and -the `response` text. - -#### Overrides - -[AChatGPTAPI](AChatGPTAPI.md).[sendMessage](AChatGPTAPI.md#sendmessage) - -#### Defined in - -[src/chatgpt-api-browser.ts:439](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/chatgpt-api-browser.ts#L439) diff --git a/docs/classes/ChatGPTError.md b/docs/classes/ChatGPTError.md index 052cab2..da81eec 100644 --- a/docs/classes/ChatGPTError.md +++ b/docs/classes/ChatGPTError.md @@ -16,8 +16,6 @@ ### Properties -- [originalError](ChatGPTError.md#originalerror) -- [response](ChatGPTError.md#response) - [statusCode](ChatGPTError.md#statuscode) - [statusText](ChatGPTError.md#statustext) @@ -39,7 +37,7 @@ Error.constructor #### Defined in -node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es5.d.ts:1059 +node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es5.d.ts:1059 • **new ChatGPTError**(`message?`, `options?`) @@ -56,37 +54,17 @@ Error.constructor #### Defined in -node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts:30 +node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2022.error.d.ts:30 ## Properties -### originalError - -• `Optional` **originalError**: `Error` - -#### Defined in - -[src/types.ts:297](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L297) - -___ - -### response - -• `Optional` **response**: `Response` - -#### Defined in - -[src/types.ts:296](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L296) - -___ - ### statusCode • `Optional` **statusCode**: `number` #### Defined in -[src/types.ts:294](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L294) +[src/types.ts:24](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L24) ___ @@ -96,4 +74,4 @@ ___ #### Defined in -[src/types.ts:295](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L295) +[src/types.ts:25](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L25) diff --git a/docs/interfaces/ChatMessage.md b/docs/interfaces/ChatMessage.md new file mode 100644 index 0000000..f8c14e4 --- /dev/null +++ b/docs/interfaces/ChatMessage.md @@ -0,0 +1,63 @@ +[chatgpt](../readme.md) / [Exports](../modules.md) / ChatMessage + +# Interface: ChatMessage + +## Table of contents + +### Properties + +- [conversationId](ChatMessage.md#conversationid) +- [id](ChatMessage.md#id) +- [parentMessageId](ChatMessage.md#parentmessageid) +- [role](ChatMessage.md#role) +- [text](ChatMessage.md#text) + +## Properties + +### conversationId + +• `Optional` **conversationId**: `string` + +#### Defined in + +[src/types.ts:20](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L20) + +___ + +### id + +• **id**: `string` + +#### Defined in + +[src/types.ts:16](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L16) + +___ + +### parentMessageId + +• `Optional` **parentMessageId**: `string` + +#### Defined in + +[src/types.ts:19](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L19) + +___ + +### role + +• **role**: [`Role`](../modules.md#role) + +#### Defined in + +[src/types.ts:18](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L18) + +___ + +### text + +• **text**: `string` + +#### Defined in + +[src/types.ts:17](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L17) diff --git a/docs/modules.md b/docs/modules.md index 492bfb0..27f3f0f 100644 --- a/docs/modules.md +++ b/docs/modules.md @@ -4,408 +4,51 @@ ## Table of contents +### Namespaces + +- [openai](modules/openai.md) + ### Classes -- [AChatGPTAPI](classes/AChatGPTAPI.md) - [ChatGPTAPI](classes/ChatGPTAPI.md) -- [ChatGPTAPIBrowser](classes/ChatGPTAPIBrowser.md) - [ChatGPTError](classes/ChatGPTError.md) +### Interfaces + +- [ChatMessage](interfaces/ChatMessage.md) + ### Type Aliases -- [AvailableModerationModels](modules.md#availablemoderationmodels) -- [ChatError](modules.md#chaterror) -- [ChatResponse](modules.md#chatresponse) -- [ContentType](modules.md#contenttype) -- [ConversationJSONBody](modules.md#conversationjsonbody) -- [ConversationResponseEvent](modules.md#conversationresponseevent) -- [Message](modules.md#message) -- [MessageActionType](modules.md#messageactiontype) -- [MessageContent](modules.md#messagecontent) -- [MessageFeedbackJSONBody](modules.md#messagefeedbackjsonbody) -- [MessageFeedbackRating](modules.md#messagefeedbackrating) -- [MessageFeedbackResult](modules.md#messagefeedbackresult) -- [MessageFeedbackTags](modules.md#messagefeedbacktags) -- [MessageMetadata](modules.md#messagemetadata) -- [Model](modules.md#model) -- [ModelsResult](modules.md#modelsresult) -- [ModerationsJSONBody](modules.md#moderationsjsonbody) -- [ModerationsJSONResult](modules.md#moderationsjsonresult) -- [OpenAIAuth](modules.md#openaiauth) -- [Prompt](modules.md#prompt) -- [PromptContent](modules.md#promptcontent) +- [GetMessageByIdFunction](modules.md#getmessagebyidfunction) - [Role](modules.md#role) -- [SendConversationMessageOptions](modules.md#sendconversationmessageoptions) - [SendMessageOptions](modules.md#sendmessageoptions) -- [SessionResult](modules.md#sessionresult) -- [User](modules.md#user) - -### Functions - -- [browserPostEventStream](modules.md#browserposteventstream) -- [defaultChromeExecutablePath](modules.md#defaultchromeexecutablepath) -- [getBrowser](modules.md#getbrowser) -- [getOpenAIAuth](modules.md#getopenaiauth) -- [getPage](modules.md#getpage) -- [initializeNopechaExtension](modules.md#initializenopechaextension) -- [isRelevantRequest](modules.md#isrelevantrequest) -- [markdownToText](modules.md#markdowntotext) -- [maximizePage](modules.md#maximizepage) -- [minimizePage](modules.md#minimizepage) +- [UpsertMessageFunction](modules.md#upsertmessagefunction) ## Type Aliases -### AvailableModerationModels +### GetMessageByIdFunction -Ƭ **AvailableModerationModels**: ``"text-moderation-playground"`` - -#### Defined in - -[src/types.ts:109](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L109) - -___ - -### ChatError - -Ƭ **ChatError**: `Object` +Ƭ **GetMessageByIdFunction**: (`id`: `string`) => `Promise`<[`ChatMessage`](interfaces/ChatMessage.md)\> #### Type declaration +▸ (`id`): `Promise`<[`ChatMessage`](interfaces/ChatMessage.md)\> + +Returns a chat message from a store by it's ID (or null if not found). + +##### Parameters + | Name | Type | | :------ | :------ | -| `conversationId?` | `string` | -| `error` | { `message`: `string` ; `statusCode?`: `number` ; `statusText?`: `string` } | -| `error.message` | `string` | -| `error.statusCode?` | `number` | -| `error.statusText?` | `string` | -| `messageId?` | `string` | - -#### Defined in - -[src/types.ts:300](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L300) - -___ - -### ChatResponse - -Ƭ **ChatResponse**: `Object` - -#### Type declaration - -| Name | Type | -| :------ | :------ | -| `conversationId` | `string` | -| `messageId` | `string` | -| `response` | `string` | - -#### Defined in - -[src/types.ts:306](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L306) - -___ - -### ContentType - -Ƭ **ContentType**: ``"text"`` - -#### Defined in - -[src/types.ts:1](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L1) - -___ - -### ConversationJSONBody - -Ƭ **ConversationJSONBody**: `Object` - -https://chat.openapi.com/backend-api/conversation - -#### Type declaration - -| Name | Type | Description | -| :------ | :------ | :------ | -| `action` | `string` | The action to take | -| `conversation_id?` | `string` | The ID of the conversation | -| `messages` | [`Prompt`](modules.md#prompt)[] | Prompts to provide | -| `model` | `string` | The model to use | -| `parent_message_id` | `string` | The parent message ID | - -#### Defined in - -[src/types.ts:134](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L134) - -___ - -### ConversationResponseEvent - -Ƭ **ConversationResponseEvent**: `Object` - -#### Type declaration - -| Name | Type | -| :------ | :------ | -| `conversation_id?` | `string` | -| `error?` | `string` \| ``null`` | -| `message?` | [`Message`](modules.md#message) | - -#### Defined in - -[src/types.ts:251](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L251) - -___ - -### Message - -Ƭ **Message**: `Object` - -#### Type declaration - -| Name | Type | -| :------ | :------ | -| `content` | [`MessageContent`](modules.md#messagecontent) | -| `create_time` | `string` \| ``null`` | -| `end_turn` | ``null`` | | `id` | `string` | -| `metadata` | [`MessageMetadata`](modules.md#messagemetadata) | -| `recipient` | `string` | -| `role` | `string` | -| `update_time` | `string` \| ``null`` | -| `user` | `string` \| ``null`` | -| `weight` | `number` | + +##### Returns + +`Promise`<[`ChatMessage`](interfaces/ChatMessage.md)\> #### Defined in -[src/types.ts:257](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L257) - -___ - -### MessageActionType - -Ƭ **MessageActionType**: ``"next"`` \| ``"variant"`` - -#### Defined in - -[src/types.ts:276](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L276) - -___ - -### MessageContent - -Ƭ **MessageContent**: `Object` - -#### Type declaration - -| Name | Type | -| :------ | :------ | -| `content_type` | `string` | -| `parts` | `string`[] | - -#### Defined in - -[src/types.ts:270](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L270) - -___ - -### MessageFeedbackJSONBody - -Ƭ **MessageFeedbackJSONBody**: `Object` - -https://chat.openapi.com/backend-api/conversation/message_feedback - -#### Type declaration - -| Name | Type | Description | -| :------ | :------ | :------ | -| `conversation_id` | `string` | The ID of the conversation | -| `message_id` | `string` | The message ID | -| `rating` | [`MessageFeedbackRating`](modules.md#messagefeedbackrating) | The rating | -| `tags?` | [`MessageFeedbackTags`](modules.md#messagefeedbacktags)[] | Tags to give the rating | -| `text?` | `string` | The text to include | - -#### Defined in - -[src/types.ts:193](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L193) - -___ - -### MessageFeedbackRating - -Ƭ **MessageFeedbackRating**: ``"thumbsUp"`` \| ``"thumbsDown"`` - -#### Defined in - -[src/types.ts:249](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L249) - -___ - -### MessageFeedbackResult - -Ƭ **MessageFeedbackResult**: `Object` - -#### Type declaration - -| Name | Type | Description | -| :------ | :------ | :------ | -| `conversation_id` | `string` | The ID of the conversation | -| `message_id` | `string` | The message ID | -| `rating` | [`MessageFeedbackRating`](modules.md#messagefeedbackrating) | The rating | -| `text?` | `string` | The text the server received, including tags | -| `user_id` | `string` | The ID of the user | - -#### Defined in - -[src/types.ts:222](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L222) - -___ - -### MessageFeedbackTags - -Ƭ **MessageFeedbackTags**: ``"harmful"`` \| ``"false"`` \| ``"not-helpful"`` - -#### Defined in - -[src/types.ts:220](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L220) - -___ - -### MessageMetadata - -Ƭ **MessageMetadata**: `any` - -#### Defined in - -[src/types.ts:275](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L275) - -___ - -### Model - -Ƭ **Model**: `Object` - -#### Type declaration - -| Name | Type | Description | -| :------ | :------ | :------ | -| `is_special` | `boolean` | Whether or not the model is special | -| `max_tokens` | `number` | Max tokens of the model | -| `slug` | `string` | Name of the model | - -#### Defined in - -[src/types.ts:77](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L77) - -___ - -### ModelsResult - -Ƭ **ModelsResult**: `Object` - -https://chat.openapi.com/backend-api/models - -#### Type declaration - -| Name | Type | Description | -| :------ | :------ | :------ | -| `models` | [`Model`](modules.md#model)[] | Array of models | - -#### Defined in - -[src/types.ts:70](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L70) - -___ - -### ModerationsJSONBody - -Ƭ **ModerationsJSONBody**: `Object` - -https://chat.openapi.com/backend-api/moderations - -#### Type declaration - -| Name | Type | Description | -| :------ | :------ | :------ | -| `input` | `string` | Input for the moderation decision | -| `model` | [`AvailableModerationModels`](modules.md#availablemoderationmodels) | The model to use in the decision | - -#### Defined in - -[src/types.ts:97](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L97) - -___ - -### ModerationsJSONResult - -Ƭ **ModerationsJSONResult**: `Object` - -https://chat.openapi.com/backend-api/moderations - -#### Type declaration - -| Name | Type | Description | -| :------ | :------ | :------ | -| `blocked` | `boolean` | Whether or not the input is blocked | -| `flagged` | `boolean` | Whether or not the input is flagged | -| `moderation_id` | `string` | The ID of the decision | - -#### Defined in - -[src/types.ts:114](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L114) - -___ - -### OpenAIAuth - -Ƭ **OpenAIAuth**: `Object` - -Represents everything that's required to pass into `ChatGPTAPI` in order -to authenticate with the unofficial ChatGPT API. - -#### Type declaration - -| Name | Type | -| :------ | :------ | -| `clearanceToken` | `string` | -| `sessionToken` | `string` | -| `userAgent` | `string` | - -#### Defined in - -[src/openai-auth.ts:29](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/openai-auth.ts#L29) - -___ - -### Prompt - -Ƭ **Prompt**: `Object` - -#### Type declaration - -| Name | Type | Description | -| :------ | :------ | :------ | -| `content` | [`PromptContent`](modules.md#promptcontent) | The content of the prompt | -| `id` | `string` | The ID of the prompt | -| `role` | [`Role`](modules.md#role) | The role played in the prompt | - -#### Defined in - -[src/types.ts:161](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L161) - -___ - -### PromptContent - -Ƭ **PromptContent**: `Object` - -#### Type declaration - -| Name | Type | Description | -| :------ | :------ | :------ | -| `content_type` | [`ContentType`](modules.md#contenttype) | The content type of the prompt | -| `parts` | `string`[] | The parts to the prompt | - -#### Defined in - -[src/types.ts:178](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L178) +[src/types.ts:29](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L29) ___ @@ -415,17 +58,7 @@ ___ #### Defined in -[src/types.ts:3](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L3) - -___ - -### SendConversationMessageOptions - -Ƭ **SendConversationMessageOptions**: `Omit`<[`SendMessageOptions`](modules.md#sendmessageoptions), ``"conversationId"`` \| ``"parentMessageId"``\> - -#### Defined in - -[src/types.ts:288](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L288) +[src/types.ts:1](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L1) ___ @@ -438,297 +71,41 @@ ___ | Name | Type | | :------ | :------ | | `abortSignal?` | `AbortSignal` | -| `action?` | [`MessageActionType`](modules.md#messageactiontype) | | `conversationId?` | `string` | | `messageId?` | `string` | -| `onProgress?` | (`partialResponse`: [`ChatResponse`](modules.md#chatresponse)) => `void` | +| `onProgress?` | (`partialResponse`: [`ChatMessage`](interfaces/ChatMessage.md)) => `void` | | `parentMessageId?` | `string` | +| `promptPrefix?` | `string` | +| `promptSuffix?` | `string` | +| `stream?` | `boolean` | | `timeoutMs?` | `number` | #### Defined in -[src/types.ts:278](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L278) +[src/types.ts:3](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L3) ___ -### SessionResult +### UpsertMessageFunction -Ƭ **SessionResult**: `Object` - -https://chat.openapi.com/api/auth/session +Ƭ **UpsertMessageFunction**: (`message`: [`ChatMessage`](interfaces/ChatMessage.md)) => `Promise`<`void`\> #### Type declaration -| Name | Type | Description | -| :------ | :------ | :------ | -| `accessToken` | `string` | The access token | -| `error?` | `string` \| ``null`` | If there was an error associated with this request | -| `expires` | `string` | ISO date of the expiration date of the access token | -| `user` | [`User`](modules.md#user) | Authenticated user | +▸ (`message`): `Promise`<`void`\> -#### Defined in +Upserts a chat message to a store. -[src/types.ts:8](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L8) - -___ - -### User - -Ƭ **User**: `Object` - -#### Type declaration - -| Name | Type | Description | -| :------ | :------ | :------ | -| `email?` | `string` | Email of the user | -| `features` | `string`[] | Features the user is in | -| `groups` | `string`[] | Groups the user is in | -| `id` | `string` | ID of the user | -| `image` | `string` | Image of the user | -| `name` | `string` | Name of the user | -| `picture` | `string` | Picture of the user | - -#### Defined in - -[src/types.ts:30](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/types.ts#L30) - -## Functions - -### browserPostEventStream - -▸ **browserPostEventStream**(`url`, `accessToken`, `body`, `timeoutMs?`): `Promise`<[`ChatError`](modules.md#chaterror) \| [`ChatResponse`](modules.md#chatresponse)\> - -This function is injected into the ChatGPT webapp page using puppeteer. It -has to be fully self-contained, so we copied a few third-party sources and -included them in here. - -#### Parameters +##### Parameters | Name | Type | | :------ | :------ | -| `url` | `string` | -| `accessToken` | `string` | -| `body` | [`ConversationJSONBody`](modules.md#conversationjsonbody) | -| `timeoutMs?` | `number` | +| `message` | [`ChatMessage`](interfaces/ChatMessage.md) | -#### Returns - -`Promise`<[`ChatError`](modules.md#chaterror) \| [`ChatResponse`](modules.md#chatresponse)\> - -#### Defined in - -[src/utils.ts:79](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/utils.ts#L79) - -___ - -### defaultChromeExecutablePath - -▸ **defaultChromeExecutablePath**(): `string` - -Gets the default path to chrome's executable for the current platform. - -#### Returns - -`string` - -#### Defined in - -[src/openai-auth.ts:469](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/openai-auth.ts#L469) - -___ - -### getBrowser - -▸ **getBrowser**(`opts?`): `Promise`<`Browser`\> - -Launches a non-puppeteer instance of Chrome. Note that in my testing, I wasn't -able to use the built-in `puppeteer` version of Chromium because Cloudflare -recognizes it and blocks access. - -#### Parameters - -| Name | Type | -| :------ | :------ | -| `opts` | `PuppeteerLaunchOptions` & { `captchaToken?`: `string` ; `debug?`: `boolean` ; `minimize?`: `boolean` ; `nopechaKey?`: `string` ; `proxyServer?`: `string` ; `timeoutMs?`: `number` } | - -#### Returns - -`Promise`<`Browser`\> - -#### Defined in - -[src/openai-auth.ts:299](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/openai-auth.ts#L299) - -___ - -### getOpenAIAuth - -▸ **getOpenAIAuth**(`__namedParameters`): `Promise`<[`OpenAIAuth`](modules.md#openaiauth)\> - -Bypasses OpenAI's use of Cloudflare to get the cookies required to use -ChatGPT. Uses Puppeteer with a stealth plugin under the hood. - -If you pass `email` and `password`, then it will log into the account and -include a `sessionToken` in the response. - -If you don't pass `email` and `password`, then it will just return a valid -`clearanceToken`. - -This can be useful because `clearanceToken` expires after ~2 hours, whereas -`sessionToken` generally lasts much longer. We recommend renewing your -`clearanceToken` every hour or so and creating a new instance of `ChatGPTAPI` -with your updated credentials. - -#### Parameters - -| Name | Type | -| :------ | :------ | -| `__namedParameters` | `Object` | -| `__namedParameters.browser?` | `Browser` | -| `__namedParameters.captchaToken?` | `string` | -| `__namedParameters.email?` | `string` | -| `__namedParameters.executablePath?` | `string` | -| `__namedParameters.isGoogleLogin?` | `boolean` | -| `__namedParameters.isMicrosoftLogin?` | `boolean` | -| `__namedParameters.minimize?` | `boolean` | -| `__namedParameters.nopechaKey?` | `string` | -| `__namedParameters.page?` | `Page` | -| `__namedParameters.password?` | `string` | -| `__namedParameters.proxyServer?` | `string` | -| `__namedParameters.timeoutMs?` | `number` | - -#### Returns - -`Promise`<[`OpenAIAuth`](modules.md#openaiauth)\> - -#### Defined in - -[src/openai-auth.ts:50](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/openai-auth.ts#L50) - -___ - -### getPage - -▸ **getPage**(`browser`, `opts`): `Promise`<`Page`\> - -#### Parameters - -| Name | Type | -| :------ | :------ | -| `browser` | `Browser` | -| `opts` | `Object` | -| `opts.proxyServer?` | `string` | - -#### Returns - -`Promise`<`Page`\> - -#### Defined in - -[src/openai-auth.ts:262](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/openai-auth.ts#L262) - -___ - -### initializeNopechaExtension - -▸ **initializeNopechaExtension**(`browser`, `opts`): `Promise`<`void`\> - -#### Parameters - -| Name | Type | -| :------ | :------ | -| `browser` | `Browser` | -| `opts` | `Object` | -| `opts.debug?` | `boolean` | -| `opts.minimize?` | `boolean` | -| `opts.nopechaKey?` | `string` | -| `opts.proxyServer?` | `string` | -| `opts.timeoutMs?` | `number` | - -#### Returns +##### Returns `Promise`<`void`\> #### Defined in -[src/openai-auth.ts:434](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/openai-auth.ts#L434) - -___ - -### isRelevantRequest - -▸ **isRelevantRequest**(`url`): `boolean` - -#### Parameters - -| Name | Type | -| :------ | :------ | -| `url` | `string` | - -#### Returns - -`boolean` - -#### Defined in - -[src/utils.ts:45](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/utils.ts#L45) - -___ - -### markdownToText - -▸ **markdownToText**(`markdown?`): `string` - -#### Parameters - -| Name | Type | -| :------ | :------ | -| `markdown?` | `string` | - -#### Returns - -`string` - -#### Defined in - -[src/utils.ts:18](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/utils.ts#L18) - -___ - -### maximizePage - -▸ **maximizePage**(`page`): `Promise`<`void`\> - -#### Parameters - -| Name | Type | -| :------ | :------ | -| `page` | `Page` | - -#### Returns - -`Promise`<`void`\> - -#### Defined in - -[src/utils.ts:35](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/utils.ts#L35) - -___ - -### minimizePage - -▸ **minimizePage**(`page`): `Promise`<`void`\> - -#### Parameters - -| Name | Type | -| :------ | :------ | -| `page` | `Page` | - -#### Returns - -`Promise`<`void`\> - -#### Defined in - -[src/utils.ts:25](https://github.com/transitive-bullshit/chatgpt-api/blob/83bb9cf/src/utils.ts#L25) +[src/types.ts:32](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L32) diff --git a/docs/modules/openai.md b/docs/modules/openai.md new file mode 100644 index 0000000..13f3b5f --- /dev/null +++ b/docs/modules/openai.md @@ -0,0 +1,90 @@ +[chatgpt](../readme.md) / [Exports](../modules.md) / openai + +# Namespace: openai + +## Table of contents + +### Type Aliases + +- [CompletionParams](openai.md#completionparams) +- [CompletionResponse](openai.md#completionresponse) +- [CompletionResponseChoices](openai.md#completionresponsechoices) +- [CompletionResponseUsage](openai.md#completionresponseusage) + +## Type Aliases + +### CompletionParams + +Ƭ **CompletionParams**: `Object` + +#### Type declaration + +| Name | Type | Description | +| :------ | :------ | :------ | +| `best_of?` | `number` | Generates `best_of` completions server-side and returns the \"best\" (the one with the highest log probability per token). Results cannot be streamed. When used with `n`, `best_of` controls the number of candidate completions and `n` specifies how many to return – `best_of` must be greater than `n`. **Note:** Because this parameter generates many completions, it can quickly consume your token quota. Use carefully and ensure that you have reasonable settings for `max_tokens` and `stop`. | +| `echo?` | `boolean` | Echo back the prompt in addition to the completion | +| `frequency_penalty?` | `number` | Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model\'s likelihood to repeat the same line verbatim. [See more information about frequency and presence penalties.](/docs/api-reference/parameter-details) | +| `logit_bias?` | `Record`<`string`, `number`\> | Modify the likelihood of specified tokens appearing in the completion. Accepts a json object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this [tokenizer tool](/tokenizer?view=bpe) (which works for both GPT-2 and GPT-3) to convert text to token IDs. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or increase likelihood of selection; values like -100 or 100 should result in a ban or exclusive selection of the relevant token. As an example, you can pass `{\"50256\": -100}` to prevent the <\|endoftext\|> token from being generated. | +| `logprobs?` | `number` | Include the log probabilities on the `logprobs` most likely tokens, as well the chosen tokens. For example, if `logprobs` is 5, the API will return a list of the 5 most likely tokens. The API will always return the `logprob` of the sampled token, so there may be up to `logprobs+1` elements in the response. The maximum value for `logprobs` is 5. If you need more than this, please contact us through our [Help center](https://help.openai.com) and describe your use case. | +| `max_tokens?` | `number` | The maximum number of tokens to generate in the completion. The token count of your prompt plus `max_tokens` cannot exceed the model\'s context length. Most models have a context length of 2048 tokens (except for the newest models, which support 4096). | +| `model` | `string` | ID of the model to use. | +| `presence_penalty?` | `number` | Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model\'s likelihood to talk about new topics. [See more information about frequency and presence penalties.](/docs/api-reference/parameter-details) | +| `prompt` | `string` | The string prompt to generate a completion for. | +| `stop?` | `string`[] | Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence. | +| `suffix?` | `string` | The suffix that comes after a completion of inserted text. | +| `temperature?` | `number` | What [sampling temperature](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277) to use. Higher values means the model will take more risks. Try 0.9 for more creative applications, and 0 (argmax sampling) for ones with a well-defined answer. We generally recommend altering this or `top_p` but not both. | +| `top_p?` | `number` | An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered. We generally recommend altering this or `temperature` but not both. | +| `user?` | `string` | A unique identifier representing your end-user, which will help OpenAI to monitor and detect abuse. [Learn more](/docs/usage-policies/end-user-ids). | + +#### Defined in + +[src/types.ts:35](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L35) + +___ + +### CompletionResponse + +Ƭ **CompletionResponse**: `Object` + +#### Type declaration + +| Name | Type | +| :------ | :------ | +| `choices` | [`CompletionResponseChoices`](openai.md#completionresponsechoices) | +| `created` | `number` | +| `id` | `string` | +| `model` | `string` | +| `object` | `string` | +| `usage?` | [`CompletionResponseUsage`](openai.md#completionresponseusage) | + +#### Defined in + +[src/types.ts:117](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L117) + +___ + +### CompletionResponseChoices + +Ƭ **CompletionResponseChoices**: { `finish_reason?`: `string` ; `index?`: `number` ; `logprobs?`: { `text_offset?`: `number`[] ; `token_logprobs?`: `number`[] ; `tokens?`: `string`[] ; `top_logprobs?`: `object`[] } \| ``null`` ; `text?`: `string` }[] + +#### Defined in + +[src/types.ts:126](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L126) + +___ + +### CompletionResponseUsage + +Ƭ **CompletionResponseUsage**: `Object` + +#### Type declaration + +| Name | Type | +| :------ | :------ | +| `completion_tokens` | `number` | +| `prompt_tokens` | `number` | +| `total_tokens` | `number` | + +#### Defined in + +[src/types.ts:138](https://github.com/transitive-bullshit/chatgpt-api/blob/531e180/src/types.ts#L138) diff --git a/docs/readme.md b/docs/readme.md index 26c78cb..924b825 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1,31 +1,21 @@ chatgpt / [Exports](modules.md) -# Update January 12, 2023 +# Update February 1, 2023 -This package allows you to access ChatGPT from Node.js – even with OpenAI's Cloudflare protections. It uses a **fully automated browser-based solution**, which uses Puppeteer and CAPTCHA solvers under the hood. 🔥 +This package no longer requires any browser hacks – **it is now using the official OpenAI API** with a leaked, unofficial ChatGPT model. 🔥 ```ts -import { ChatGPTAPIBrowser } from 'chatgpt' +import { ChatGPTAPI } from 'chatgpt' -const api = new ChatGPTAPIBrowser({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD +const api = new ChatGPTAPI({ + apiKey: process.env.OPENAI_API_KEY }) -await api.initSession() -const result = await api.sendMessage('Hello World!') -console.log(result.response) +const res = await api.sendMessage('Hello World!') +console.log(res.text) ``` -This solution is not lightweight, but it does work a lot more consistently than the previous REST API-based approach. For example, I'm currently using this approach to automate N concurrent OpenAI accounts for my [Twitter bot](https://github.com/transitive-bullshit/chatgpt-twitter-bot). 😂 - -We recently added support for CAPTCHA automation using either [nopecha](https://nopecha.com/) or [2captcha](https://2captcha.com). Keep in mind that this package will be updated to use the official API as soon as it's released, so things should get much easier over time. 💪 - -There are some restrictions to be aware of, however: - -- Cloudflare doesn't like requests coming from data center IPs, so you'll likely either need to run it locally or use a residential IP proxy. -- You should only have one `sendMessage` request at a time per browser instance and OpenAI account. -- It can be difficult to reliably process `sendMessage` requests after awhile. My best advice for handling this is to wrap your usage in some basic retry logic as well as a daemon which restarts your Node.js process every hour or so. This is unfortunately a by-product of there not being an official API, so keep that in mind before using this in production. +The updated solution is significantly more lightweight and robust compared with previous versions. If you run into any issues, we do have a pretty active [Discord](https://discord.gg/v9gERj825w) with a bunch of ChatGPT hackers from the Node.js & Python communities. @@ -51,10 +41,6 @@ Thanks && cheers, - [Usage](#usage) - [Docs](#docs) - [Demos](#demos) - - [Authentication](#authentication) - - [CAPTCHAs](#captchas) - - [Using Proxies](#using-proxies) - - [Restrictions](#restrictions) - [Projects](#projects) - [Compatibility](#compatibility) - [Credits](#credits) @@ -69,91 +55,61 @@ You can use it to start building projects powered by ChatGPT like chatbots, webs ## Install ```bash -npm install chatgpt puppeteer +npm install chatgpt ``` -`puppeteer` is an optional peer dependency used to automate bypassing the Cloudflare protections via `getOpenAIAuth`. The main API wrapper uses `fetch` directly. - ## Usage +Sign up for an [OpenAI API key](https://platform.openai.com/overview) and store it in your environment. + ```ts -import { ChatGPTAPIBrowser } from 'chatgpt' +import { ChatGPTAPI } from 'chatgpt' async function example() { - // use puppeteer to bypass cloudflare (headful because of captchas) - const api = new ChatGPTAPIBrowser({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD + const api = new ChatGPTAPI({ + apiKey: process.env.OPENAI_API_KEY }) - await api.initSession() - - const result = await api.sendMessage('Hello World!') - console.log(result.response) + const res = await api.sendMessage('Hello World!') + console.log(res.text) } ``` -
-Or, if you want to use the REST-based version: (not advised at this time) +If you want to track the conversation, use the `conversationId` and `id` in the result object, and pass them to `sendMessage` as `conversationId` and `parentMessageId` respectively. ```ts -import { ChatGPTAPI, getOpenAIAuth } from 'chatgpt' - -async function example() { - // use puppeteer to bypass cloudflare (headful because of captchas) - const openAIAuth = await getOpenAIAuth({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD - }) - - const api = new ChatGPTAPI({ ...openAIAuth }) - await api.initSession() - - // send a message and wait for the response - const result = await api.sendMessage('Write a python version of bubble sort.') - - // result.response is a markdown-formatted string - console.log(result.response) -} -``` - -
- -ChatGPT responses are formatted as markdown by default. If you want to work with plaintext instead, you can use: - -```ts -const api = new ChatGPTAPIBrowser({ email, password, markdown: false }) -``` - -If you want to track the conversation, use the `conversationId` and `messageId` in the result object, and pass them to `sendMessage` as `conversationId` and `parentMessageId` respectively. - -```ts -const api = new ChatGPTAPIBrowser({ email, password }) -await api.initSession() +const api = new ChatGPTAPI({ apiKey: process.env.OPENAI_API_KEY }) // send a message and wait for the response let res = await api.sendMessage('What is OpenAI?') -console.log(res.response) +console.log(res.text) // send a follow-up res = await api.sendMessage('Can you expand on that?', { conversationId: res.conversationId, - parentMessageId: res.messageId + parentMessageId: res.id }) -console.log(res.response) +console.log(res.text) // send another follow-up // send a follow-up res = await api.sendMessage('What were we talking about?', { conversationId: res.conversationId, - parentMessageId: res.messageId + parentMessageId: res.id }) -console.log(res.response) +console.log(res.text) ``` -Sometimes, ChatGPT will hang for an extended period of time before beginning to respond. This may be due to rate limiting or it may be due to OpenAI's servers being overloaded. +You can add streaming via the `onProgress` handler: -To mitigate these issues, you can add a timeout like this: +```ts +// timeout after 2 minutes (which will also abort the underlying HTTP request) +const res = await api.sendMessage('Write me a 500 word essay on frogs.', { + onProgress: (partialResponse) => console.log(partialResponse) +}) +``` + +You can add a timeout using the `timeoutMs` option: ```ts // timeout after 2 minutes (which will also abort the underlying HTTP request) @@ -168,18 +124,12 @@ const response = await api.sendMessage('this is a timeout test', { ```js async function example() { // To use ESM in CommonJS, you can use a dynamic import - const { ChatGPTAPI, getOpenAIAuth } = await import('chatgpt') + const { ChatGPTAPI } = await import('chatgpt') - const openAIAuth = await getOpenAIAuth({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD - }) + const api = new ChatGPTAPI({ apiKey: process.env.OPENAI_API_KEY }) - const api = new ChatGPTAPI({ ...openAIAuth }) - await api.initSession() - - const result = await api.sendMessage('Hello World!') - console.log(result) + const res = await api.sendMessage('Hello World!') + console.log(res.text) } ``` @@ -187,7 +137,7 @@ async function example() { ### Docs -See the [auto-generated docs](./docs/classes/ChatGPTAPI.md) for more info on methods and parameters. Here are the [docs](./docs/classes/ChatGPTAPIBrowser.md) for the browser-based version. +See the [auto-generated docs](./docs/classes/ChatGPTAPI.md) for more info on methods and parameters. Here are the [docs](./docs/classes/ChatGPTAPI.md) for the browser-based version. ### Demos @@ -195,7 +145,7 @@ To run the included demos: 1. clone repo 2. install node deps -3. set `OPENAI_EMAIL` and `OPENAI_PASSWORD` in .env +3. set `OPENAI_API_KEY` in .env A [basic demo](./demos/demo.ts) is included for testing purposes: @@ -203,12 +153,6 @@ A [basic demo](./demos/demo.ts) is included for testing purposes: npx tsx demos/demo.ts ``` -A [google auth demo](./demos/demo-google-auth.ts): - -```bash -npx tsx demos/demo-google-auth.ts -``` - A [demo showing on progress handler](./demos/demo-on-progress.ts): ```bash @@ -223,93 +167,15 @@ A [conversation demo](./demos/demo-conversation.ts): npx tsx demos/demo-conversation.ts ``` -### Authentication +Lastly, a [persitence demo](./demos/demo-persistence.ts) shows how to store messages in Redis for persistence: -The authentication section relates to the REST-based version (using `getOpenAIAuth` + `ChatGPTAPI`). The browser-based solution, `ChatGPTAPIBrowser`, takes care of all the authentication for you. - -On December 11, 2022, OpenAI added some additional Cloudflare protections which make it more difficult to access the unofficial API. - -You'll need a valid OpenAI "session token" and Cloudflare "clearance token" in order to use the API. - -We've provided an automated, Puppeteer-based solution `getOpenAIAuth` to fetch these for you, but you may still run into cases where you have to manually pass the CAPTCHA. We're working on a solution to automate this further. - -You can also get these tokens manually, but keep in mind that the `clearanceToken` only lasts for max 2 hours. - -
-Getting tokens manually - -To get session token manually: - -1. Go to https://chat.openai.com/chat and log in or sign up. -2. Open dev tools. -3. Open `Application` > `Cookies`. - ![ChatGPT cookies](./media/session-token.png) -4. Copy the value for `__Secure-next-auth.session-token` and save it to your environment. This will be your `sessionToken`. -5. Copy the value for `cf_clearance` and save it to your environment. This will be your `clearanceToken`. -6. Copy the value of the `user-agent` header from any request in your `Network` tab, or copy the result of `navigator.userAgent` command on `Console` tab. This will be your `userAgent`. - -Pass `sessionToken`, `clearanceToken`, and `userAgent` to the `ChatGPTAPI` constructor. - -
- -> **Note** -> This package will switch to using the official API once it's released, which will make this process much simpler. - -### CAPTCHAs - -The browser portions of this package use Puppeteer to automate as much as possible, including solving all CAPTCHAs. 🔥 - -Basic Cloudflare CAPTCHAs are handled by default, but if you want to automate the email + password Recaptchas, you'll need to sign up for one of these paid providers: - -- [nopecha](https://nopecha.com/) - Uses AI to solve CAPTCHAS - - Faster and cheaper - - Set the `NOPECHA_KEY` env var to your nopecha API key - - [Demo video](https://user-images.githubusercontent.com/552829/208235991-de4890f2-e7ba-4b42-bf55-4fcd792d4b19.mp4) of nopecha solving the login Recaptcha (41 seconds) -- [2captcha](https://2captcha.com) - Uses real people to solve CAPTCHAS - - More well-known solution that's been around longer - - Set the `CAPTCHA_TOKEN` env var to your 2captcha API token - -Alternatively, if your OpenAI account uses Google Auth, you shouldn't encounter any of the more complicated Recaptchas — and can avoid using these third-party providers. To use Google auth, make sure your OpenAI account is using Google and then set `isGoogleLogin` to `true` whenever you're passing your `email` and `password`. For example: - -```ts -const api = new ChatGPTAPIBrowser({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD, - isGoogleLogin: true -}) +```bash +npx tsx demos/demo-conversation.ts ``` -### Using Proxies +Any [keyv adaptor](https://github.com/jaredwray/keyv) is supported for persistence, and there are overrides if you'd like to use a different way of storing / retrieving messages. -The browser implementation supports setting a proxy server. This is useful if you're running into rate limiting issues or if you want to use a proxy to hide your IP address. - -To use a proxy, pass the `proxyServer` option to the `ChatGPTAPIBrowser` constructor, or simply set the `PROXY_SERVER` env var. For more information on the format, see [here](https://www.chromium.org/developers/design-documents/network-settings). - -```ts -const api = new ChatGPTAPIBrowser({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD, - proxyServer: ':' -}) -``` - -You can also set the `PROXY_VALIDATE_IP` env var to your proxy's IP address. This will be used to validate that the proxy is working correctly, and will throw an error if it's not. - -### Restrictions - -These restrictions are for the `getOpenAIAuth` + `ChatGPTAPI` solution, which uses the unofficial API. The browser-based solution, `ChatGPTAPIBrowser`, generally doesn't have any of these restrictions. - -**Please read carefully** - -- You must use `node >= 18` at the moment. I'm using `v19.2.0` in my testing. -- Cloudflare `cf_clearance` **tokens expire after 2 hours**, so right now we recommend that you refresh your `cf_clearance` token every hour or so. -- Your `user-agent` and `IP address` **must match** from the real browser window you're logged in with to the one you're using for `ChatGPTAPI`. - - This means that you currently can't log in with your laptop and then run the bot on a server or proxy somewhere. -- Cloudflare will still sometimes ask you to complete a CAPTCHA, so you may need to keep an eye on it and manually resolve the CAPTCHA. -- You should not be using this account while the bot is using it, because that browser window may refresh one of your tokens and invalidate the bot's session. - -> **Note** -> Prior to v1.0.0, this package used a headless browser via [Playwright](https://playwright.dev/) to automate the web UI. Here are the [docs for the initial browser version](https://github.com/transitive-bullshit/chatgpt-api/tree/v0.4.2). +Note that persisting message is very important for remembering the context of previous conversations. ## Projects @@ -382,11 +248,11 @@ If you create a cool integration, feel free to open a PR and add it to the list. ## Compatibility -This package is ESM-only. It supports: - -- Node.js >= 18 - - Node.js 17, 16, and 14 were supported in earlier versions, but OpenAI's Cloudflare update caused a bug with `undici` on v17 and v16 that needs investigation. So for now, use `node >= 18` -- We recommend against using `chatgpt` from client-side browser code because it would expose your private session token +- This package is ESM-only. +- This package supports `node >= 14`. +- This module assumes that `fetch` is installed. + - In `node >= 18`, it's installed by default. + - In `node < 18`, you need to install a polyfill like `unfetch/polyfill` - If you want to build a website using `chatgpt`, we recommend using it only from your backend API ## Credits diff --git a/package.json b/package.json index da3cefb..974328d 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,7 @@ } }, "files": [ - "build", - "third-party" + "build" ], "engines": { "node": ">=18" @@ -36,25 +35,18 @@ "test:prettier": "prettier '**/*.{js,jsx,ts,tsx}' --check" }, "dependencies": { - "delay": "^5.0.0", "eventsource-parser": "^0.0.5", - "expiry-map": "^2.0.0", - "html-to-md": "^0.8.3", + "gpt-3-encoder": "^1.1.4", + "keyv": "^4.5.2", "p-timeout": "^6.0.0", - "puppeteer-extra": "^3.3.4", - "puppeteer-extra-plugin-recaptcha": "npm:@fisch0920/puppeteer-extra-plugin-recaptcha@^3.6.6", - "puppeteer-extra-plugin-stealth": "^2.11.1", - "random": "^4.1.0", - "remark": "^14.0.2", - "strip-markdown": "^5.0.0", - "tempy": "^3.0.0", + "quick-lru": "^6.1.1", "uuid": "^9.0.0" }, "devDependencies": { + "@keyv/redis": "^2.5.4", "@trivago/prettier-plugin-sort-imports": "^4.0.0", "@types/node": "^18.11.9", "@types/uuid": "^9.0.0", - "ava": "^5.1.0", "del-cli": "^5.0.0", "dotenv-safe": "^8.2.0", "husky": "^8.0.2", @@ -62,37 +54,26 @@ "npm-run-all": "^4.1.5", "ora": "^6.1.2", "prettier": "^2.8.0", - "puppeteer": "^19.4.0", "tsup": "^6.5.0", "tsx": "^3.12.1", "typedoc": "^0.23.21", "typedoc-plugin-markdown": "^3.13.6", "typescript": "^4.9.3" }, - "peerDependencies": { - "puppeteer": "*" - }, "lint-staged": { "*.{ts,tsx}": [ "prettier --write" ] }, - "ava": { - "extensions": { - "ts": "module" - }, - "nodeArguments": [ - "--loader=tsx" - ] - }, "keywords": [ "openai", "chatgpt", + "chat", "gpt", + "gpt-3", "gpt3", "gpt4", "chatbot", - "chat", "machine learning", "conversation", "conversational ai", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4636118..70c1242 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,30 +1,22 @@ lockfileVersion: 5.4 specifiers: + '@keyv/redis': ^2.5.4 '@trivago/prettier-plugin-sort-imports': ^4.0.0 '@types/node': ^18.11.9 '@types/uuid': ^9.0.0 - ava: ^5.1.0 del-cli: ^5.0.0 - delay: ^5.0.0 dotenv-safe: ^8.2.0 eventsource-parser: ^0.0.5 - expiry-map: ^2.0.0 - html-to-md: ^0.8.3 + gpt-3-encoder: ^1.1.4 husky: ^8.0.2 + keyv: ^4.5.2 lint-staged: ^13.0.3 npm-run-all: ^4.1.5 ora: ^6.1.2 p-timeout: ^6.0.0 prettier: ^2.8.0 - puppeteer: ^19.4.0 - puppeteer-extra: ^3.3.4 - puppeteer-extra-plugin-recaptcha: npm:@fisch0920/puppeteer-extra-plugin-recaptcha@^3.6.6 - puppeteer-extra-plugin-stealth: ^2.11.1 - random: ^4.1.0 - remark: ^14.0.2 - strip-markdown: ^5.0.0 - tempy: ^3.0.0 + quick-lru: ^6.1.1 tsup: ^6.5.0 tsx: ^3.12.1 typedoc: ^0.23.21 @@ -33,38 +25,30 @@ specifiers: uuid: ^9.0.0 dependencies: - delay: 5.0.0 eventsource-parser: 0.0.5 - expiry-map: 2.0.0 - html-to-md: 0.8.3 - p-timeout: 6.0.0 - puppeteer-extra: 3.3.4_puppeteer@19.4.0 - puppeteer-extra-plugin-recaptcha: /@fisch0920/puppeteer-extra-plugin-recaptcha/3.6.6_puppeteer-extra@3.3.4 - puppeteer-extra-plugin-stealth: 2.11.1_puppeteer-extra@3.3.4 - random: 4.1.0 - remark: 14.0.2 - strip-markdown: 5.0.0 - tempy: 3.0.0 + gpt-3-encoder: 1.1.4 + keyv: 4.5.2 + p-timeout: 6.1.0 + quick-lru: 6.1.1 uuid: 9.0.0 devDependencies: - '@trivago/prettier-plugin-sort-imports': 4.0.0_prettier@2.8.0 - '@types/node': 18.11.10 + '@keyv/redis': 2.5.4 + '@trivago/prettier-plugin-sort-imports': 4.0.0_prettier@2.8.3 + '@types/node': 18.11.18 '@types/uuid': 9.0.0 - ava: 5.1.0 del-cli: 5.0.0 dotenv-safe: 8.2.0 - husky: 8.0.2 - lint-staged: 13.0.4 + husky: 8.0.3 + lint-staged: 13.1.0 npm-run-all: 4.1.5 ora: 6.1.2 - prettier: 2.8.0 - puppeteer: 19.4.0 - tsup: 6.5.0_typescript@4.9.3 - tsx: 3.12.1 - typedoc: 0.23.21_typescript@4.9.3 - typedoc-plugin-markdown: 3.13.6_typedoc@0.23.21 - typescript: 4.9.3 + prettier: 2.8.3 + tsup: 6.5.0_typescript@4.9.5 + tsx: 3.12.2 + typedoc: 0.23.24_typescript@4.9.5 + typedoc-plugin-markdown: 3.14.0_typedoc@0.23.24 + typescript: 4.9.5 packages: @@ -81,9 +65,10 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.18.6 + dev: true - /@babel/compat-data/7.20.5: - resolution: {integrity: sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==} + /@babel/compat-data/7.20.14: + resolution: {integrity: sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==} engines: {node: '>=6.9.0'} dev: true @@ -94,17 +79,17 @@ packages: '@ampproject/remapping': 2.2.0 '@babel/code-frame': 7.18.6 '@babel/generator': 7.17.7 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.17.8 - '@babel/helper-module-transforms': 7.20.2 - '@babel/helpers': 7.20.6 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.17.8 + '@babel/helper-module-transforms': 7.20.11 + '@babel/helpers': 7.20.13 '@babel/parser': 7.18.9 - '@babel/template': 7.18.10 + '@babel/template': 7.20.7 '@babel/traverse': 7.17.3 '@babel/types': 7.17.0 convert-source-map: 1.9.0 debug: 4.3.4 gensync: 1.0.0-beta.2 - json5: 2.2.1 + json5: 2.2.3 semver: 6.3.0 transitivePeerDependencies: - supports-color @@ -119,25 +104,26 @@ packages: source-map: 0.5.7 dev: true - /@babel/generator/7.20.5: - resolution: {integrity: sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==} + /@babel/generator/7.20.14: + resolution: {integrity: sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 '@jridgewell/gen-mapping': 0.3.2 jsesc: 2.5.2 dev: true - /@babel/helper-compilation-targets/7.20.0_@babel+core@7.17.8: - resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} + /@babel/helper-compilation-targets/7.20.7_@babel+core@7.17.8: + resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/compat-data': 7.20.5 + '@babel/compat-data': 7.20.14 '@babel/core': 7.17.8 '@babel/helper-validator-option': 7.18.6 - browserslist: 4.21.4 + browserslist: 4.21.5 + lru-cache: 5.1.1 semver: 6.3.0 dev: true @@ -150,26 +136,26 @@ packages: resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.18.10 - '@babel/types': 7.20.5 + '@babel/template': 7.20.7 + '@babel/types': 7.20.7 dev: true /@babel/helper-hoist-variables/7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 dev: true /@babel/helper-module-imports/7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 dev: true - /@babel/helper-module-transforms/7.20.2: - resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} + /@babel/helper-module-transforms/7.20.11: + resolution: {integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-environment-visitor': 7.18.9 @@ -177,9 +163,9 @@ packages: '@babel/helper-simple-access': 7.20.2 '@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-validator-identifier': 7.19.1 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.5 - '@babel/types': 7.20.5 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.13 + '@babel/types': 7.20.7 transitivePeerDependencies: - supports-color dev: true @@ -188,14 +174,14 @@ packages: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 dev: true /@babel/helper-split-export-declaration/7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 dev: true /@babel/helper-string-parser/7.19.4: @@ -206,19 +192,20 @@ packages: /@babel/helper-validator-identifier/7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} + dev: true /@babel/helper-validator-option/7.18.6: resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} engines: {node: '>=6.9.0'} dev: true - /@babel/helpers/7.20.6: - resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==} + /@babel/helpers/7.20.13: + resolution: {integrity: sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.5 - '@babel/types': 7.20.5 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.13 + '@babel/types': 7.20.7 transitivePeerDependencies: - supports-color dev: true @@ -230,6 +217,7 @@ packages: '@babel/helper-validator-identifier': 7.19.1 chalk: 2.4.2 js-tokens: 4.0.0 + dev: true /@babel/parser/7.18.9: resolution: {integrity: sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==} @@ -239,21 +227,21 @@ packages: '@babel/types': 7.17.0 dev: true - /@babel/parser/7.20.5: - resolution: {integrity: sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==} + /@babel/parser/7.20.13: + resolution: {integrity: sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 dev: true - /@babel/template/7.18.10: - resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} + /@babel/template/7.20.7: + resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/parser': 7.20.5 - '@babel/types': 7.20.5 + '@babel/parser': 7.20.13 + '@babel/types': 7.20.7 dev: true /@babel/traverse/7.17.3: @@ -274,18 +262,18 @@ packages: - supports-color dev: true - /@babel/traverse/7.20.5: - resolution: {integrity: sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==} + /@babel/traverse/7.20.13: + resolution: {integrity: sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.5 + '@babel/generator': 7.20.14 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.19.0 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.20.5 - '@babel/types': 7.20.5 + '@babel/parser': 7.20.13 + '@babel/types': 7.20.7 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -300,8 +288,8 @@ packages: to-fast-properties: 2.0.0 dev: true - /@babel/types/7.20.5: - resolution: {integrity: sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==} + /@babel/types/7.20.7: + resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.19.4 @@ -313,13 +301,13 @@ packages: resolution: {integrity: sha512-lhc/XLith28QdW0HpHZvZKkorWgmCNT7sVelMHDj3HFdTfdqkwEKvT+aXVQtNAmCC39VJhunDkWhONWB7335mg==} dependencies: '@esbuild-kit/core-utils': 3.0.0 - get-tsconfig: 4.2.0 + get-tsconfig: 4.3.0 dev: true /@esbuild-kit/core-utils/3.0.0: resolution: {integrity: sha512-TXmwH9EFS3DC2sI2YJWJBgHGhlteK0Xyu1VabwetMULfm3oYhbrsWV5yaSr2NTWZIgDGVLHbRf0inxbjXqAcmQ==} dependencies: - esbuild: 0.15.16 + esbuild: 0.15.18 source-map-support: 0.5.21 dev: true @@ -327,11 +315,11 @@ packages: resolution: {integrity: sha512-afmtLf6uqxD5IgwCzomtqCYIgz/sjHzCWZFvfS5+FzeYxOURPUo4QcHtqJxbxWOMOogKriZanN/1bJQE/ZL93A==} dependencies: '@esbuild-kit/core-utils': 3.0.0 - get-tsconfig: 4.2.0 + get-tsconfig: 4.3.0 dev: true - /@esbuild/android-arm/0.15.16: - resolution: {integrity: sha512-nyB6CH++2mSgx3GbnrJsZSxzne5K0HMyNIWafDHqYy7IwxFc4fd/CgHVZXr8Eh+Q3KbIAcAe3vGyqIPhGblvMQ==} + /@esbuild/android-arm/0.15.18: + resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -339,8 +327,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64/0.15.16: - resolution: {integrity: sha512-SDLfP1uoB0HZ14CdVYgagllgrG7Mdxhkt4jDJOKl/MldKrkQ6vDJMZKl2+5XsEY/Lzz37fjgLQoJBGuAw/x8kQ==} + /@esbuild/linux-loong64/0.15.18: + resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -348,25 +336,9 @@ packages: dev: true optional: true - /@fisch0920/puppeteer-extra-plugin-recaptcha/3.6.6_puppeteer-extra@3.3.4: - resolution: {integrity: sha512-KI12BbqOupDm8+R21IS645L9/SzdYMVvMFdvGy2zIePJ5qPYNcqUIqBSA86hdk0vM2WJ1G5q1t7AUQoemGwbeQ==} - engines: {node: '>=9.11.2'} - peerDependencies: - playwright-extra: '*' - puppeteer-extra: '*' - peerDependenciesMeta: - playwright-extra: - optional: true - puppeteer-extra: - optional: true - dependencies: - debug: 4.3.4 - merge-deep: 3.0.3 - puppeteer-extra: 3.3.4_puppeteer@19.4.0 - puppeteer-extra-plugin: 3.2.2_puppeteer-extra@3.3.4 - transitivePeerDependencies: - - supports-color - dev: false + /@ioredis/commands/1.2.0: + resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + dev: true /@jridgewell/gen-mapping/0.1.1: resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} @@ -406,6 +378,15 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true + /@keyv/redis/2.5.4: + resolution: {integrity: sha512-27MTiJFME3R13fPiiOV/ww550gU9Zc75eJkzD+EpwRXcgunjcXcYEw1cM9XyaEI5y0aS1PPknRjKGlYRjT8nTQ==} + engines: {node: '>= 12'} + dependencies: + ioredis: 5.3.0 + transitivePeerDependencies: + - supports-color + dev: true + /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -424,10 +405,10 @@ packages: engines: {node: '>= 8'} dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.13.0 + fastq: 1.15.0 dev: true - /@trivago/prettier-plugin-sort-imports/4.0.0_prettier@2.8.0: + /@trivago/prettier-plugin-sort-imports/4.0.0_prettier@2.8.3: resolution: {integrity: sha512-Tyuk5ZY4a0e2MNFLdluQO9F6d1awFQYXVVujEPFfvKPPXz8DADNHzz73NMhwCSXGSuGGZcA/rKOyZBrxVNMxaA==} peerDependencies: '@vue/compiler-sfc': 3.x @@ -440,72 +421,27 @@ packages: '@babel/types': 7.17.0 javascript-natural-sort: 0.7.1 lodash: 4.17.21 - prettier: 2.8.0 + prettier: 2.8.3 transitivePeerDependencies: - supports-color dev: true - /@types/debug/4.1.7: - resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} - dependencies: - '@types/ms': 0.7.31 - dev: false - - /@types/mdast/3.0.10: - resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==} - dependencies: - '@types/unist': 2.0.6 - dev: false - /@types/minimist/1.2.2: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} dev: true - /@types/ms/0.7.31: - resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} - dev: false - - /@types/node/18.11.10: - resolution: {integrity: sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==} + /@types/node/18.11.18: + resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} + dev: true /@types/normalize-package-data/2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true - /@types/unist/2.0.6: - resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} - dev: false - /@types/uuid/9.0.0: resolution: {integrity: sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==} dev: true - /@types/yauzl/2.10.0: - resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} - requiresBuild: true - dependencies: - '@types/node': 18.11.10 - optional: true - - /acorn-walk/8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} - engines: {node: '>=0.4.0'} - dev: true - - /acorn/8.8.1: - resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /agent-base/6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - dependencies: - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - /aggregate-error/3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} @@ -544,6 +480,7 @@ packages: engines: {node: '>=4'} dependencies: color-convert: 1.9.3 + dev: true /ansi-styles/4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} @@ -569,131 +506,39 @@ packages: picomatch: 2.3.1 dev: true - /argparse/1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - dev: true - - /argparse/2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - /arr-union/3.1.0: - resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} - engines: {node: '>=0.10.0'} - dev: false - - /array-find-index/1.0.2: - resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==} - engines: {node: '>=0.10.0'} - dev: true - /array-union/2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true - /arrgv/1.0.2: - resolution: {integrity: sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==} - engines: {node: '>=8.0.0'} - dev: true - /arrify/1.0.1: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} dev: true - /arrify/3.0.0: - resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==} - engines: {node: '>=12'} - dev: true - /astral-regex/2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} dev: true - /ava/5.1.0: - resolution: {integrity: sha512-e5VFrSQ0WBPyZJWRXVrO7RFOizFeNM0t2PORwrPvWtApgkORI6cvGnY3GX1G+lzpd0HjqNx5Jus22AhxVnUMNA==} - engines: {node: '>=14.19 <15 || >=16.15 <17 || >=18'} - hasBin: true - peerDependencies: - '@ava/typescript': '*' - peerDependenciesMeta: - '@ava/typescript': - optional: true - dependencies: - acorn: 8.8.1 - acorn-walk: 8.2.0 - ansi-styles: 6.2.1 - arrgv: 1.0.2 - arrify: 3.0.0 - callsites: 4.0.0 - cbor: 8.1.0 - chalk: 5.1.2 - chokidar: 3.5.3 - chunkd: 2.0.1 - ci-info: 3.7.0 - ci-parallel-vars: 1.0.1 - clean-yaml-object: 0.1.0 - cli-truncate: 3.1.0 - code-excerpt: 4.0.0 - common-path-prefix: 3.0.0 - concordance: 5.0.4 - currently-unhandled: 0.4.1 - debug: 4.3.4 - del: 7.0.0 - emittery: 1.0.1 - figures: 5.0.0 - globby: 13.1.2 - ignore-by-default: 2.1.0 - indent-string: 5.0.0 - is-error: 2.2.2 - is-plain-object: 5.0.0 - is-promise: 4.0.0 - matcher: 5.0.0 - mem: 9.0.2 - ms: 2.1.3 - p-event: 5.0.1 - p-map: 5.5.0 - picomatch: 2.3.1 - pkg-conf: 4.0.0 - plur: 5.1.0 - pretty-ms: 8.0.0 - resolve-cwd: 3.0.0 - slash: 3.0.0 - stack-utils: 2.0.6 - strip-ansi: 7.0.1 - supertap: 3.0.1 - temp-dir: 3.0.0 - write-file-atomic: 5.0.0 - yargs: 17.6.2 - transitivePeerDependencies: - - supports-color + /available-typed-arrays/1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} dev: true - /bail/2.0.2: - resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - dev: false - /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true /base64-js/1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true /binary-extensions/2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} dev: true - /bl/4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.0 - /bl/5.1.0: resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} dependencies: @@ -702,15 +547,12 @@ packages: readable-stream: 3.6.0 dev: true - /blueimp-md5/2.19.0: - resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} - dev: true - /brace-expansion/1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 + dev: true /brace-expansion/2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} @@ -725,30 +567,21 @@ packages: fill-range: 7.0.1 dev: true - /browserslist/4.21.4: - resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} + /browserslist/4.21.5: + resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001435 + caniuse-lite: 1.0.30001450 electron-to-chromium: 1.4.284 - node-releases: 2.0.6 - update-browserslist-db: 1.0.10_browserslist@4.21.4 + node-releases: 2.0.9 + update-browserslist-db: 1.0.10_browserslist@4.21.5 dev: true - /buffer-crc32/0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - /buffer-from/1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true - /buffer/5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - /buffer/6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} dependencies: @@ -756,13 +589,13 @@ packages: ieee754: 1.2.1 dev: true - /bundle-require/3.1.2_esbuild@0.15.16: + /bundle-require/3.1.2_esbuild@0.15.18: resolution: {integrity: sha512-Of6l6JBAxiyQ5axFxUM6dYeP/W7X2Sozeo/4EYB9sJhL+dqL7TKjg+shwxp6jlu/6ZSERfsYtIpSJ1/x3XkAEA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} peerDependencies: esbuild: '>=0.13' dependencies: - esbuild: 0.15.16 + esbuild: 0.15.18 load-tsconfig: 0.2.3 dev: true @@ -775,16 +608,7 @@ packages: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: function-bind: 1.1.1 - get-intrinsic: 1.1.3 - dev: true - - /callsites/3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - /callsites/4.0.0: - resolution: {integrity: sha512-y3jRROutgpKdz5vzEhWM34TidDU8vkJppF8dszITeb1PQmSqV3DTxyV8G/lyO/DNvtE1YTedehmw9MPZsCBHxQ==} - engines: {node: '>=12.20'} + get-intrinsic: 1.2.0 dev: true /camelcase-keys/7.0.2: @@ -802,15 +626,8 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite/1.0.30001435: - resolution: {integrity: sha512-kdCkUTjR+v4YAJelyiDTqiu82BDr4W4CP5sgTA0ZBmqn30XfS2ZghPLMowik9TPhS+psWJiUNxsqLyurDbmutA==} - dev: true - - /cbor/8.1.0: - resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} - engines: {node: '>=12.19'} - dependencies: - nofilter: 3.1.0 + /caniuse-lite/1.0.30001450: + resolution: {integrity: sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==} dev: true /chalk/2.4.2: @@ -820,15 +637,12 @@ packages: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 - - /chalk/5.1.2: - resolution: {integrity: sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} dev: true - /character-entities/2.0.2: - resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} - dev: false + /chalk/5.2.0: + resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true /chokidar/3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} @@ -845,22 +659,6 @@ packages: fsevents: 2.3.2 dev: true - /chownr/1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - - /chunkd/2.0.1: - resolution: {integrity: sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==} - dev: true - - /ci-info/3.7.0: - resolution: {integrity: sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==} - engines: {node: '>=8'} - dev: true - - /ci-parallel-vars/1.0.1: - resolution: {integrity: sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==} - dev: true - /clean-stack/2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -873,11 +671,6 @@ packages: escape-string-regexp: 5.0.0 dev: true - /clean-yaml-object/0.1.0: - resolution: {integrity: sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==} - engines: {node: '>=0.10.0'} - dev: true - /cli-cursor/3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -913,42 +706,21 @@ packages: string-width: 5.1.2 dev: true - /cliui/8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - - /clone-deep/0.2.4: - resolution: {integrity: sha512-we+NuQo2DHhSl+DP6jlUiAhyAjBQrYnpOk15rN6c6JSPScjiCLh8IbSU+VTcph6YS3o7mASE8a0+gbZ7ChLpgg==} - engines: {node: '>=0.10.0'} - dependencies: - for-own: 0.1.5 - is-plain-object: 2.0.4 - kind-of: 3.2.2 - lazy-cache: 1.0.4 - shallow-clone: 0.1.2 - dev: false - /clone/1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} dev: true - /code-excerpt/4.0.0: - resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - convert-to-spaces: 2.0.1 + /cluster-key-slot/1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} dev: true /color-convert/1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: color-name: 1.1.3 + dev: true /color-convert/2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} @@ -959,6 +731,7 @@ packages: /color-name/1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true /color-name/1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} @@ -973,57 +746,19 @@ packages: engines: {node: '>= 6'} dev: true - /commander/9.4.1: - resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==} + /commander/9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} engines: {node: ^12.20.0 || >=14} dev: true - /common-path-prefix/3.0.0: - resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} - dev: true - /concat-map/0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - /concordance/5.0.4: - resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==} - engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'} - dependencies: - date-time: 3.1.0 - esutils: 2.0.3 - fast-diff: 1.2.0 - js-string-escape: 1.0.1 - lodash: 4.17.21 - md5-hex: 3.0.1 - semver: 7.3.8 - well-known-symbols: 2.0.0 dev: true /convert-source-map/1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} dev: true - /convert-to-spaces/2.0.1: - resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - - /cosmiconfig/8.0.0: - resolution: {integrity: sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ==} - engines: {node: '>=14'} - dependencies: - import-fresh: 3.3.0 - js-yaml: 4.1.0 - parse-json: 5.2.0 - path-type: 4.0.0 - - /cross-fetch/3.1.5: - resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} - dependencies: - node-fetch: 2.6.7 - transitivePeerDependencies: - - encoding - /cross-spawn/6.0.5: resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} engines: {node: '>=4.8'} @@ -1044,27 +779,6 @@ packages: which: 2.0.2 dev: true - /crypto-random-string/4.0.0: - resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} - engines: {node: '>=12'} - dependencies: - type-fest: 1.4.0 - dev: false - - /currently-unhandled/0.4.1: - resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==} - engines: {node: '>=0.10.0'} - dependencies: - array-find-index: 1.0.2 - dev: true - - /date-time/3.1.0: - resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} - engines: {node: '>=6'} - dependencies: - time-zone: 1.0.0 - dev: true - /debug/4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -1075,6 +789,7 @@ packages: optional: true dependencies: ms: 2.1.2 + dev: true /decamelize-keys/1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} @@ -1094,17 +809,6 @@ packages: engines: {node: '>=10'} dev: true - /decode-named-character-reference/1.0.2: - resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} - dependencies: - character-entities: 2.0.2 - dev: false - - /deepmerge/4.2.2: - resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} - engines: {node: '>=0.10.0'} - dev: false - /defaults/1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} dependencies: @@ -1132,7 +836,7 @@ packages: resolution: {integrity: sha512-tQbV/4u5WVB8HMJr08pgw0b6nG4RGt/tj+7Numvq+zqcvUFeMaIWWOUFltiU+6go8BSO2/ogsB4EasDaj0y68Q==} engines: {node: '>=14.16'} dependencies: - globby: 13.1.2 + globby: 13.1.3 graceful-fs: 4.2.10 is-glob: 4.0.3 is-path-cwd: 3.0.0 @@ -1142,23 +846,10 @@ packages: slash: 4.0.0 dev: true - /delay/5.0.0: - resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} - engines: {node: '>=10'} - dev: false - - /dequal/2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - dev: false - - /devtools-protocol/0.0.1068969: - resolution: {integrity: sha512-ATFTrPbY1dKYhPPvpjtwWKSK2mIwGmRwX54UASn9THEuIZCe2n9k3vVuMmt6jWeL+e5QaaguEv/pMyR+JQB7VQ==} - - /diff/5.1.0: - resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} - engines: {node: '>=0.3.1'} - dev: false + /denque/2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + dev: true /dir-glob/3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} @@ -1186,11 +877,6 @@ packages: resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} dev: true - /emittery/1.0.1: - resolution: {integrity: sha512-2ID6FdrMD9KDLldGesP6317G78K7km/kMcwItRtVFva7I/cSEOIaLpewaUb+YLXVwdAp3Ctfxh/V5zIl1sj7dQ==} - engines: {node: '>=14.16'} - dev: true - /emoji-regex/8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true @@ -1199,44 +885,58 @@ packages: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} dev: true - /end-of-stream/1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - dependencies: - once: 1.4.0 - /error-ex/1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: is-arrayish: 0.2.1 + dev: true - /es-abstract/1.20.4: - resolution: {integrity: sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==} + /es-abstract/1.21.1: + resolution: {integrity: sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==} engines: {node: '>= 0.4'} dependencies: + available-typed-arrays: 1.0.5 call-bind: 1.0.2 + es-set-tostringtag: 2.0.1 es-to-primitive: 1.2.1 function-bind: 1.1.1 function.prototype.name: 1.1.5 - get-intrinsic: 1.1.3 + get-intrinsic: 1.2.0 get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 has: 1.0.3 has-property-descriptors: 1.0.0 + has-proto: 1.0.1 has-symbols: 1.0.3 - internal-slot: 1.0.3 + internal-slot: 1.0.4 + is-array-buffer: 3.0.1 is-callable: 1.2.7 is-negative-zero: 2.0.2 is-regex: 1.1.4 is-shared-array-buffer: 1.0.2 is-string: 1.0.7 + is-typed-array: 1.1.10 is-weakref: 1.0.2 - object-inspect: 1.12.2 + object-inspect: 1.12.3 object-keys: 1.1.1 object.assign: 4.1.4 regexp.prototype.flags: 1.4.3 safe-regex-test: 1.0.0 string.prototype.trimend: 1.0.6 string.prototype.trimstart: 1.0.6 + typed-array-length: 1.0.4 unbox-primitive: 1.0.2 + which-typed-array: 1.1.9 + dev: true + + /es-set-tostringtag/2.0.1: + resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.0 + has: 1.0.3 + has-tostringtag: 1.0.0 dev: true /es-to-primitive/1.2.1: @@ -1248,8 +948,8 @@ packages: is-symbol: 1.0.4 dev: true - /esbuild-android-64/0.15.16: - resolution: {integrity: sha512-Vwkv/sT0zMSgPSVO3Jlt1pUbnZuOgtOQJkJkyyJFAlLe7BiT8e9ESzo0zQSx4c3wW4T6kGChmKDPMbWTgtliQA==} + /esbuild-android-64/0.15.18: + resolution: {integrity: sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -1257,8 +957,8 @@ packages: dev: true optional: true - /esbuild-android-arm64/0.15.16: - resolution: {integrity: sha512-lqfKuofMExL5niNV3gnhMUYacSXfsvzTa/58sDlBET/hCOG99Zmeh+lz6kvdgvGOsImeo6J9SW21rFCogNPLxg==} + /esbuild-android-arm64/0.15.18: + resolution: {integrity: sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -1266,8 +966,8 @@ packages: dev: true optional: true - /esbuild-darwin-64/0.15.16: - resolution: {integrity: sha512-wo2VWk/n/9V2TmqUZ/KpzRjCEcr00n7yahEdmtzlrfQ3lfMCf3Wa+0sqHAbjk3C6CKkR3WKK/whkMq5Gj4Da9g==} + /esbuild-darwin-64/0.15.18: + resolution: {integrity: sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -1275,8 +975,8 @@ packages: dev: true optional: true - /esbuild-darwin-arm64/0.15.16: - resolution: {integrity: sha512-fMXaUr5ou0M4WnewBKsspMtX++C1yIa3nJ5R2LSbLCfJT3uFdcRoU/NZjoM4kOMKyOD9Sa/2vlgN8G07K3SJnw==} + /esbuild-darwin-arm64/0.15.18: + resolution: {integrity: sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -1284,8 +984,8 @@ packages: dev: true optional: true - /esbuild-freebsd-64/0.15.16: - resolution: {integrity: sha512-UzIc0xlRx5x9kRuMr+E3+hlSOxa/aRqfuMfiYBXu2jJ8Mzej4lGL7+o6F5hzhLqWfWm1GWHNakIdlqg1ayaTNQ==} + /esbuild-freebsd-64/0.15.18: + resolution: {integrity: sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -1293,8 +993,8 @@ packages: dev: true optional: true - /esbuild-freebsd-arm64/0.15.16: - resolution: {integrity: sha512-8xyiYuGc0DLZphFQIiYaLHlfoP+hAN9RHbE+Ibh8EUcDNHAqbQgUrQg7pE7Bo00rXmQ5Ap6KFgcR0b4ALZls1g==} + /esbuild-freebsd-arm64/0.15.18: + resolution: {integrity: sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -1302,8 +1002,8 @@ packages: dev: true optional: true - /esbuild-linux-32/0.15.16: - resolution: {integrity: sha512-iGijUTV+0kIMyUVoynK0v+32Oi8yyp0xwMzX69GX+5+AniNy/C/AL1MjFTsozRp/3xQPl7jVux/PLe2ds10/2w==} + /esbuild-linux-32/0.15.18: + resolution: {integrity: sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -1311,8 +1011,8 @@ packages: dev: true optional: true - /esbuild-linux-64/0.15.16: - resolution: {integrity: sha512-tuSOjXdLw7VzaUj89fIdAaQT7zFGbKBcz4YxbWrOiXkwscYgE7HtTxUavreBbnRkGxKwr9iT/gmeJWNm4djy/g==} + /esbuild-linux-64/0.15.18: + resolution: {integrity: sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -1320,8 +1020,8 @@ packages: dev: true optional: true - /esbuild-linux-arm/0.15.16: - resolution: {integrity: sha512-XKcrxCEXDTOuoRj5l12tJnkvuxXBMKwEC5j0JISw3ziLf0j4zIwXbKbTmUrKFWbo6ZgvNpa7Y5dnbsjVvH39bQ==} + /esbuild-linux-arm/0.15.18: + resolution: {integrity: sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -1329,8 +1029,8 @@ packages: dev: true optional: true - /esbuild-linux-arm64/0.15.16: - resolution: {integrity: sha512-mPYksnfHnemNrvjrDhZyixL/AfbJN0Xn9S34ZOHYdh6/jJcNd8iTsv3JwJoEvTJqjMggjMhGUPJAdjnFBHoH8A==} + /esbuild-linux-arm64/0.15.18: + resolution: {integrity: sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -1338,8 +1038,8 @@ packages: dev: true optional: true - /esbuild-linux-mips64le/0.15.16: - resolution: {integrity: sha512-kSJO2PXaxfm0pWY39+YX+QtpFqyyrcp0ZeI8QPTrcFVQoWEPiPVtOfTZeS3ZKedfH+Ga38c4DSzmKMQJocQv6A==} + /esbuild-linux-mips64le/0.15.18: + resolution: {integrity: sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -1347,8 +1047,8 @@ packages: dev: true optional: true - /esbuild-linux-ppc64le/0.15.16: - resolution: {integrity: sha512-NimPikwkBY0yGABw6SlhKrtT35sU4O23xkhlrTT/O6lSxv3Pm5iSc6OYaqVAHWkLdVf31bF4UDVFO+D990WpAA==} + /esbuild-linux-ppc64le/0.15.18: + resolution: {integrity: sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -1356,8 +1056,8 @@ packages: dev: true optional: true - /esbuild-linux-riscv64/0.15.16: - resolution: {integrity: sha512-ty2YUHZlwFOwp7pR+J87M4CVrXJIf5ZZtU/umpxgVJBXvWjhziSLEQxvl30SYfUPq0nzeWKBGw5i/DieiHeKfw==} + /esbuild-linux-riscv64/0.15.18: + resolution: {integrity: sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -1365,8 +1065,8 @@ packages: dev: true optional: true - /esbuild-linux-s390x/0.15.16: - resolution: {integrity: sha512-VkZaGssvPDQtx4fvVdZ9czezmyWyzpQhEbSNsHZZN0BHvxRLOYAQ7sjay8nMQwYswP6O2KlZluRMNPYefFRs+w==} + /esbuild-linux-s390x/0.15.18: + resolution: {integrity: sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -1374,8 +1074,8 @@ packages: dev: true optional: true - /esbuild-netbsd-64/0.15.16: - resolution: {integrity: sha512-ElQ9rhdY51et6MJTWrCPbqOd/YuPowD7Cxx3ee8wlmXQQVW7UvQI6nSprJ9uVFQISqSF5e5EWpwWqXZsECLvXg==} + /esbuild-netbsd-64/0.15.18: + resolution: {integrity: sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -1383,8 +1083,8 @@ packages: dev: true optional: true - /esbuild-openbsd-64/0.15.16: - resolution: {integrity: sha512-KgxMHyxMCT+NdLQE1zVJEsLSt2QQBAvJfmUGDmgEq8Fvjrf6vSKB00dVHUEDKcJwMID6CdgCpvYNt999tIYhqA==} + /esbuild-openbsd-64/0.15.18: + resolution: {integrity: sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -1392,8 +1092,8 @@ packages: dev: true optional: true - /esbuild-sunos-64/0.15.16: - resolution: {integrity: sha512-exSAx8Phj7QylXHlMfIyEfNrmqnLxFqLxdQF6MBHPdHAjT7fsKaX6XIJn+aQEFiOcE4X8e7VvdMCJ+WDZxjSRQ==} + /esbuild-sunos-64/0.15.18: + resolution: {integrity: sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -1401,8 +1101,8 @@ packages: dev: true optional: true - /esbuild-windows-32/0.15.16: - resolution: {integrity: sha512-zQgWpY5pUCSTOwqKQ6/vOCJfRssTvxFuEkpB4f2VUGPBpdddZfdj8hbZuFRdZRPIVHvN7juGcpgCA/XCF37mAQ==} + /esbuild-windows-32/0.15.18: + resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -1410,8 +1110,8 @@ packages: dev: true optional: true - /esbuild-windows-64/0.15.16: - resolution: {integrity: sha512-HjW1hHRLSncnM3MBCP7iquatHVJq9l0S2xxsHHj4yzf4nm9TU4Z7k4NkeMlD/dHQ4jPlQQhwcMvwbJiOefSuZw==} + /esbuild-windows-64/0.15.18: + resolution: {integrity: sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -1419,8 +1119,8 @@ packages: dev: true optional: true - /esbuild-windows-arm64/0.15.16: - resolution: {integrity: sha512-oCcUKrJaMn04Vxy9Ekd8x23O8LoU01+4NOkQ2iBToKgnGj5eo1vU9i27NQZ9qC8NFZgnQQZg5oZWAejmbsppNA==} + /esbuild-windows-arm64/0.15.18: + resolution: {integrity: sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -1428,34 +1128,34 @@ packages: dev: true optional: true - /esbuild/0.15.16: - resolution: {integrity: sha512-o6iS9zxdHrrojjlj6pNGC2NAg86ECZqIETswTM5KmJitq+R1YmahhWtMumeQp9lHqJaROGnsBi2RLawGnfo5ZQ==} + /esbuild/0.15.18: + resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.15.16 - '@esbuild/linux-loong64': 0.15.16 - esbuild-android-64: 0.15.16 - esbuild-android-arm64: 0.15.16 - esbuild-darwin-64: 0.15.16 - esbuild-darwin-arm64: 0.15.16 - esbuild-freebsd-64: 0.15.16 - esbuild-freebsd-arm64: 0.15.16 - esbuild-linux-32: 0.15.16 - esbuild-linux-64: 0.15.16 - esbuild-linux-arm: 0.15.16 - esbuild-linux-arm64: 0.15.16 - esbuild-linux-mips64le: 0.15.16 - esbuild-linux-ppc64le: 0.15.16 - esbuild-linux-riscv64: 0.15.16 - esbuild-linux-s390x: 0.15.16 - esbuild-netbsd-64: 0.15.16 - esbuild-openbsd-64: 0.15.16 - esbuild-sunos-64: 0.15.16 - esbuild-windows-32: 0.15.16 - esbuild-windows-64: 0.15.16 - esbuild-windows-arm64: 0.15.16 + '@esbuild/android-arm': 0.15.18 + '@esbuild/linux-loong64': 0.15.18 + esbuild-android-64: 0.15.18 + esbuild-android-arm64: 0.15.18 + esbuild-darwin-64: 0.15.18 + esbuild-darwin-arm64: 0.15.18 + esbuild-freebsd-64: 0.15.18 + esbuild-freebsd-arm64: 0.15.18 + esbuild-linux-32: 0.15.18 + esbuild-linux-64: 0.15.18 + esbuild-linux-arm: 0.15.18 + esbuild-linux-arm64: 0.15.18 + esbuild-linux-mips64le: 0.15.18 + esbuild-linux-ppc64le: 0.15.18 + esbuild-linux-riscv64: 0.15.18 + esbuild-linux-s390x: 0.15.18 + esbuild-netbsd-64: 0.15.18 + esbuild-openbsd-64: 0.15.18 + esbuild-sunos-64: 0.15.18 + esbuild-windows-32: 0.15.18 + esbuild-windows-64: 0.15.18 + esbuild-windows-arm64: 0.15.18 dev: true /escalade/3.1.1: @@ -1466,10 +1166,6 @@ packages: /escape-string-regexp/1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} - - /escape-string-regexp/2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} dev: true /escape-string-regexp/5.0.0: @@ -1477,17 +1173,6 @@ packages: engines: {node: '>=12'} dev: true - /esprima/4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /esutils/2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - dev: true - /eventsource-parser/0.0.5: resolution: {integrity: sha512-BAq82bC3ZW9fPYYZlofXBOAfbpmDzXIOsj+GOehQwgTUYsQZ6HtHs6zuRtge7Ph8OhS6lNH1kJF8q9dj17RcmA==} engines: {node: '>=12'} @@ -1523,34 +1208,6 @@ packages: strip-final-newline: 3.0.0 dev: true - /expiry-map/2.0.0: - resolution: {integrity: sha512-K1I5wJe2fiqjyUZf/xhxwTpaopw3F+19DsO7Oggl20+3SVTXDIevVRJav0aBMfposQdkl2E4+gnuOKd3j2X0sA==} - engines: {node: '>=8'} - dependencies: - map-age-cleaner: 0.2.0 - dev: false - - /extend/3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - dev: false - - /extract-zip/2.0.1: - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true - dependencies: - debug: 4.3.4 - get-stream: 5.2.0 - yauzl: 2.10.0 - optionalDependencies: - '@types/yauzl': 2.10.0 - transitivePeerDependencies: - - supports-color - - /fast-diff/1.2.0: - resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} - dev: true - /fast-glob/3.2.12: resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} engines: {node: '>=8.6.0'} @@ -1562,25 +1219,12 @@ packages: micromatch: 4.0.5 dev: true - /fastq/1.13.0: - resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + /fastq/1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: reusify: 1.0.4 dev: true - /fd-slicer/1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - dependencies: - pend: 1.2.0 - - /figures/5.0.0: - resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} - engines: {node: '>=14'} - dependencies: - escape-string-regexp: 5.0.0 - is-unicode-supported: 1.3.0 - dev: true - /fill-range/7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -1596,45 +1240,15 @@ packages: path-exists: 4.0.0 dev: true - /find-up/6.3.0: - resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + /for-each/0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: - locate-path: 7.1.1 - path-exists: 5.0.0 + is-callable: 1.2.7 dev: true - /for-in/0.1.8: - resolution: {integrity: sha512-F0to7vbBSHP8E3l6dCjxNOLuSFAACIxFy3UehTUlG7svlXi37HHsDkyVcHo0Pq8QwrE+pXvWSVX3ZT1T9wAZ9g==} - engines: {node: '>=0.10.0'} - dev: false - - /for-in/1.0.2: - resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} - engines: {node: '>=0.10.0'} - dev: false - - /for-own/0.1.5: - resolution: {integrity: sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==} - engines: {node: '>=0.10.0'} - dependencies: - for-in: 1.0.2 - dev: false - - /fs-constants/1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - - /fs-extra/10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} - dependencies: - graceful-fs: 4.2.10 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: false - /fs.realpath/1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true /fsevents/2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} @@ -1654,7 +1268,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.4 + es-abstract: 1.21.1 functions-have-names: 1.2.3 dev: true @@ -1667,25 +1281,14 @@ packages: engines: {node: '>=6.9.0'} dev: true - /get-caller-file/2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - - /get-intrinsic/1.1.3: - resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} + /get-intrinsic/1.2.0: + resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} dependencies: function-bind: 1.1.1 has: 1.0.3 has-symbols: 1.0.3 dev: true - /get-stream/5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - dependencies: - pump: 3.0.0 - /get-stream/6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -1696,11 +1299,11 @@ packages: engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 - get-intrinsic: 1.1.3 + get-intrinsic: 1.2.0 dev: true - /get-tsconfig/4.2.0: - resolution: {integrity: sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg==} + /get-tsconfig/4.3.0: + resolution: {integrity: sha512-YCcF28IqSay3fqpIu5y3Krg/utCBHBeoflkZyHj/QcqI2nrLPC3ZegS9CmIo+hJb8K7aiGsuUl7PwWVjNG2HQQ==} dev: true /glob-parent/5.1.2: @@ -1730,12 +1333,20 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 + dev: true /globals/11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} dev: true + /globalthis/1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.1.4 + dev: true + /globby/11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -1743,24 +1354,35 @@ packages: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.2.12 - ignore: 5.2.1 + ignore: 5.2.4 merge2: 1.4.1 slash: 3.0.0 dev: true - /globby/13.1.2: - resolution: {integrity: sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==} + /globby/13.1.3: + resolution: {integrity: sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: dir-glob: 3.0.1 fast-glob: 3.2.12 - ignore: 5.2.1 + ignore: 5.2.4 merge2: 1.4.1 slash: 4.0.0 dev: true + /gopd/1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.0 + dev: true + + /gpt-3-encoder/1.1.4: + resolution: {integrity: sha512-fSQRePV+HUAhCn7+7HL7lNIXNm6eaFWFbNLOOGtmSJ0qJycyQvj60OvRlH7mee8xAMjBDNRdMXlMwjAbMTDjkg==} + dev: false + /graceful-fs/4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true /handlebars/4.7.7: resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} @@ -1787,11 +1409,17 @@ packages: /has-flag/3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} + dev: true /has-property-descriptors/1.0.0: resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} dependencies: - get-intrinsic: 1.1.3 + get-intrinsic: 1.2.0 + dev: true + + /has-proto/1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} dev: true /has-symbols/1.0.3: @@ -1824,19 +1452,6 @@ packages: lru-cache: 6.0.0 dev: true - /html-to-md/0.8.3: - resolution: {integrity: sha512-Va+bB1YOdD6vMRDue9/l7YxbERgwOgsos4erUDRfRN6YE0B2Wbbw8uAj6xZJk9A9vrjVy7mG/WLlhDw6RXfgsA==} - dev: false - - /https-proxy-agent/5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - /human-signals/2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -1847,37 +1462,21 @@ packages: engines: {node: '>=12.20.0'} dev: true - /husky/8.0.2: - resolution: {integrity: sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==} + /husky/8.0.3: + resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} engines: {node: '>=14'} hasBin: true dev: true /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - /ignore-by-default/2.1.0: - resolution: {integrity: sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==} - engines: {node: '>=10 <11 || >=12 <13 || >=14'} dev: true - /ignore/5.2.1: - resolution: {integrity: sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==} + /ignore/5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} dev: true - /import-fresh/3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - /imurmurhash/0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true - /indent-string/4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} @@ -1893,26 +1492,49 @@ packages: dependencies: once: 1.4.0 wrappy: 1.0.2 + dev: true /inherits/2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true - /internal-slot/1.0.3: - resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} + /internal-slot/1.0.4: + resolution: {integrity: sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.1.3 + get-intrinsic: 1.2.0 has: 1.0.3 side-channel: 1.0.4 dev: true - /irregular-plurals/3.3.0: - resolution: {integrity: sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==} - engines: {node: '>=8'} + /ioredis/5.3.0: + resolution: {integrity: sha512-Id9jKHhsILuIZpHc61QkagfVdUj2Rag5GzG1TGEvRNeM7dtTOjICgjC+tvqYxi//PuX2wjQ+Xjva2ONBuf92Pw==} + engines: {node: '>=12.22.0'} + dependencies: + '@ioredis/commands': 1.2.0 + cluster-key-slot: 1.1.2 + debug: 4.3.4 + denque: 2.1.0 + lodash.defaults: 4.2.0 + lodash.isarguments: 3.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /is-array-buffer/3.0.1: + resolution: {integrity: sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + is-typed-array: 1.1.10 dev: true /is-arrayish/0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true /is-bigint/1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} @@ -1935,15 +1557,6 @@ packages: has-tostringtag: 1.0.0 dev: true - /is-buffer/1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: false - - /is-buffer/2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} - dev: false - /is-callable/1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -1962,15 +1575,6 @@ packages: has-tostringtag: 1.0.0 dev: true - /is-error/2.2.2: - resolution: {integrity: sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==} - dev: true - - /is-extendable/0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - dev: false - /is-extglob/2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2030,27 +1634,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /is-plain-obj/4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} - dev: false - - /is-plain-object/2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: false - - /is-plain-object/5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - dev: true - - /is-promise/4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - dev: true - /is-regex/1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -2073,6 +1656,7 @@ packages: /is-stream/3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true /is-string/1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} @@ -2088,6 +1672,17 @@ packages: has-symbols: 1.0.3 dev: true + /is-typed-array/1.1.10: + resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + /is-unicode-supported/1.3.0: resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} engines: {node: '>=12'} @@ -2103,11 +1698,6 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /isobject/3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - dev: false - /javascript-natural-sort/0.7.1: resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} dev: true @@ -2117,43 +1707,30 @@ packages: engines: {node: '>=10'} dev: true - /js-string-escape/1.0.1: - resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} - engines: {node: '>= 0.8'} - dev: true - /js-tokens/4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - /js-yaml/3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 dev: true - /js-yaml/4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - dependencies: - argparse: 2.0.1 - /jsesc/2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} hasBin: true dev: true + /json-buffer/3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: false + /json-parse-better-errors/1.0.2: resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} dev: true /json-parse-even-better-errors/2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true - /json5/2.2.1: - resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} + /json5/2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true dev: true @@ -2162,26 +1739,10 @@ packages: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} dev: true - /jsonfile/6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + /keyv/4.5.2: + resolution: {integrity: sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==} dependencies: - universalify: 2.0.0 - optionalDependencies: - graceful-fs: 4.2.10 - dev: false - - /kind-of/2.0.1: - resolution: {integrity: sha512-0u8i1NZ/mg0b+W3MGGw5I7+6Eib2nx72S/QvXa0hYjEkjTknYmEYQJwGu3mLC0BrhtJjtQafTkyRUQ75Kx0LVg==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: false - - /kind-of/3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 + json-buffer: 3.0.1 dev: false /kind-of/6.0.3: @@ -2189,21 +1750,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /kleur/4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - dev: false - - /lazy-cache/0.2.7: - resolution: {integrity: sha512-gkX52wvU/R8DVMMt78ATVPFMJqfW8FPz1GZ1sVHBVQHmu/WvhIWE4cE1GBzhJNFicDeYhnwp6Rl35BcAIM3YOQ==} - engines: {node: '>=0.10.0'} - dev: false - - /lazy-cache/1.0.4: - resolution: {integrity: sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==} - engines: {node: '>=0.10.0'} - dev: false - /lilconfig/2.0.6: resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} engines: {node: '>=10'} @@ -2211,32 +1757,33 @@ packages: /lines-and-columns/1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true - /lint-staged/13.0.4: - resolution: {integrity: sha512-HxlHCXoYRsq9QCby5wFozmZW00hMs/9e3l+/dz6Qr8Kle4UH0kJTdABAbqhzG+3pcG6QjL9kz7NgGBfph+a5dw==} + /lint-staged/13.1.0: + resolution: {integrity: sha512-pn/sR8IrcF/T0vpWLilih8jmVouMlxqXxKuAojmbiGX5n/gDnz+abdPptlj0vYnbfE0SQNl3CY/HwtM0+yfOVQ==} engines: {node: ^14.13.1 || >=16.0.0} hasBin: true dependencies: cli-truncate: 3.1.0 colorette: 2.0.19 - commander: 9.4.1 + commander: 9.5.0 debug: 4.3.4 execa: 6.1.0 lilconfig: 2.0.6 - listr2: 5.0.6 + listr2: 5.0.7 micromatch: 4.0.5 normalize-path: 3.0.0 - object-inspect: 1.12.2 + object-inspect: 1.12.3 pidtree: 0.6.0 string-argv: 0.3.1 - yaml: 2.1.3 + yaml: 2.2.1 transitivePeerDependencies: - enquirer - supports-color dev: true - /listr2/5.0.6: - resolution: {integrity: sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==} + /listr2/5.0.7: + resolution: {integrity: sha512-MD+qXHPmtivrHIDRwPYdfNkrzqDiuaKU/rfBcec3WMyMF3xylQj3jMq344OtvQxz7zaCFViRAeqlr2AFhPvXHw==} engines: {node: ^14.13.1 || >=16.0.0} peerDependencies: enquirer: '>= 2.3.0 < 3' @@ -2249,7 +1796,7 @@ packages: log-update: 4.0.0 p-map: 4.0.0 rfdc: 1.3.0 - rxjs: 7.5.7 + rxjs: 7.8.0 through: 2.3.8 wrap-ansi: 7.0.0 dev: true @@ -2264,11 +1811,6 @@ packages: strip-bom: 3.0.0 dev: true - /load-json-file/7.0.1: - resolution: {integrity: sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - /load-tsconfig/0.2.3: resolution: {integrity: sha512-iyT2MXws+dc2Wi6o3grCFtGXpeMvHmJqS27sMPGtV2eUu4PeFnG+33I8BlFK1t1NWMjOpcx9bridn5yxLDX2gQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2281,11 +1823,12 @@ packages: p-locate: 5.0.0 dev: true - /locate-path/7.1.1: - resolution: {integrity: sha512-vJXaRMJgRVD3+cUZs3Mncj2mxpt5mP0EmNOsxRSZRMlbqjvxzDEOIUWXGmavo0ZC9+tNZCBLQ66reA11nbpHZg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-locate: 6.0.0 + /lodash.defaults/4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + dev: true + + /lodash.isarguments/3.1.0: + resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} dev: true /lodash.sortby/4.7.0: @@ -2300,7 +1843,7 @@ packages: resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} engines: {node: '>=12'} dependencies: - chalk: 5.1.2 + chalk: 5.2.0 is-unicode-supported: 1.3.0 dev: true @@ -2314,9 +1857,11 @@ packages: wrap-ansi: 6.2.0 dev: true - /longest-streak/3.1.0: - resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - dev: false + /lru-cache/5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true /lru-cache/6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} @@ -2329,20 +1874,6 @@ packages: resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} dev: true - /map-age-cleaner/0.1.3: - resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} - engines: {node: '>=6'} - dependencies: - p-defer: 1.0.0 - dev: true - - /map-age-cleaner/0.2.0: - resolution: {integrity: sha512-AvxTC6id0fzSf6OyNBTp1syyCuKO7nOJvHgYlhT0Qkkjvk40zZo+av3ayVgXlxnF/DxEzEfY9mMdd7FHsd+wKQ==} - engines: {node: '>=7.6'} - dependencies: - p-defer: 1.0.0 - dev: false - /map-obj/1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -2353,69 +1884,12 @@ packages: engines: {node: '>=8'} dev: true - /marked/4.2.3: - resolution: {integrity: sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==} + /marked/4.2.12: + resolution: {integrity: sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==} engines: {node: '>= 12'} hasBin: true dev: true - /matcher/5.0.0: - resolution: {integrity: sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - escape-string-regexp: 5.0.0 - dev: true - - /md5-hex/3.0.1: - resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==} - engines: {node: '>=8'} - dependencies: - blueimp-md5: 2.19.0 - dev: true - - /mdast-util-from-markdown/1.2.0: - resolution: {integrity: sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==} - dependencies: - '@types/mdast': 3.0.10 - '@types/unist': 2.0.6 - decode-named-character-reference: 1.0.2 - mdast-util-to-string: 3.1.0 - micromark: 3.1.0 - micromark-util-decode-numeric-character-reference: 1.0.0 - micromark-util-decode-string: 1.0.2 - micromark-util-normalize-identifier: 1.0.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - unist-util-stringify-position: 3.0.2 - uvu: 0.5.6 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-to-markdown/1.3.0: - resolution: {integrity: sha512-6tUSs4r+KK4JGTTiQ7FfHmVOaDrLQJPmpjD6wPMlHGUVXoG9Vjc3jIeP+uyBWRf8clwB2blM+W7+KrlMYQnftA==} - dependencies: - '@types/mdast': 3.0.10 - '@types/unist': 2.0.6 - longest-streak: 3.1.0 - mdast-util-to-string: 3.1.0 - micromark-util-decode-string: 1.0.2 - unist-util-visit: 4.1.1 - zwitch: 2.0.4 - dev: false - - /mdast-util-to-string/3.1.0: - resolution: {integrity: sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==} - dev: false - - /mem/9.0.2: - resolution: {integrity: sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==} - engines: {node: '>=12.20'} - dependencies: - map-age-cleaner: 0.1.3 - mimic-fn: 4.0.0 - dev: true - /memorystream/0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} @@ -2439,15 +1913,6 @@ packages: yargs-parser: 20.2.9 dev: true - /merge-deep/3.0.3: - resolution: {integrity: sha512-qtmzAS6t6grwEkNrunqTBdn0qKwFgNWvlxUbAV8es9M7Ot1EbyApytCnvE0jALPa46ZpKDUo527kKiaWplmlFA==} - engines: {node: '>=0.10.0'} - dependencies: - arr-union: 3.1.0 - clone-deep: 0.2.4 - kind-of: 3.2.2 - dev: false - /merge-stream/2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} dev: true @@ -2457,182 +1922,6 @@ packages: engines: {node: '>= 8'} dev: true - /micromark-core-commonmark/1.0.6: - resolution: {integrity: sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==} - dependencies: - decode-named-character-reference: 1.0.2 - micromark-factory-destination: 1.0.0 - micromark-factory-label: 1.0.2 - micromark-factory-space: 1.0.0 - micromark-factory-title: 1.0.2 - micromark-factory-whitespace: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-chunked: 1.0.0 - micromark-util-classify-character: 1.0.0 - micromark-util-html-tag-name: 1.1.0 - micromark-util-normalize-identifier: 1.0.0 - micromark-util-resolve-all: 1.0.0 - micromark-util-subtokenize: 1.0.2 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - uvu: 0.5.6 - dev: false - - /micromark-factory-destination/1.0.0: - resolution: {integrity: sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - dev: false - - /micromark-factory-label/1.0.2: - resolution: {integrity: sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - uvu: 0.5.6 - dev: false - - /micromark-factory-space/1.0.0: - resolution: {integrity: sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-types: 1.0.2 - dev: false - - /micromark-factory-title/1.0.2: - resolution: {integrity: sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==} - dependencies: - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - uvu: 0.5.6 - dev: false - - /micromark-factory-whitespace/1.0.0: - resolution: {integrity: sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==} - dependencies: - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - dev: false - - /micromark-util-character/1.1.0: - resolution: {integrity: sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==} - dependencies: - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - dev: false - - /micromark-util-chunked/1.0.0: - resolution: {integrity: sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==} - dependencies: - micromark-util-symbol: 1.0.1 - dev: false - - /micromark-util-classify-character/1.0.0: - resolution: {integrity: sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - dev: false - - /micromark-util-combine-extensions/1.0.0: - resolution: {integrity: sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==} - dependencies: - micromark-util-chunked: 1.0.0 - micromark-util-types: 1.0.2 - dev: false - - /micromark-util-decode-numeric-character-reference/1.0.0: - resolution: {integrity: sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==} - dependencies: - micromark-util-symbol: 1.0.1 - dev: false - - /micromark-util-decode-string/1.0.2: - resolution: {integrity: sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==} - dependencies: - decode-named-character-reference: 1.0.2 - micromark-util-character: 1.1.0 - micromark-util-decode-numeric-character-reference: 1.0.0 - micromark-util-symbol: 1.0.1 - dev: false - - /micromark-util-encode/1.0.1: - resolution: {integrity: sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==} - dev: false - - /micromark-util-html-tag-name/1.1.0: - resolution: {integrity: sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==} - dev: false - - /micromark-util-normalize-identifier/1.0.0: - resolution: {integrity: sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==} - dependencies: - micromark-util-symbol: 1.0.1 - dev: false - - /micromark-util-resolve-all/1.0.0: - resolution: {integrity: sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==} - dependencies: - micromark-util-types: 1.0.2 - dev: false - - /micromark-util-sanitize-uri/1.1.0: - resolution: {integrity: sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-encode: 1.0.1 - micromark-util-symbol: 1.0.1 - dev: false - - /micromark-util-subtokenize/1.0.2: - resolution: {integrity: sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==} - dependencies: - micromark-util-chunked: 1.0.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - uvu: 0.5.6 - dev: false - - /micromark-util-symbol/1.0.1: - resolution: {integrity: sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==} - dev: false - - /micromark-util-types/1.0.2: - resolution: {integrity: sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==} - dev: false - - /micromark/3.1.0: - resolution: {integrity: sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==} - dependencies: - '@types/debug': 4.1.7 - debug: 4.3.4 - decode-named-character-reference: 1.0.2 - micromark-core-commonmark: 1.0.6 - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-chunked: 1.0.0 - micromark-util-combine-extensions: 1.0.0 - micromark-util-decode-numeric-character-reference: 1.0.0 - micromark-util-encode: 1.0.1 - micromark-util-normalize-identifier: 1.0.0 - micromark-util-resolve-all: 1.0.0 - micromark-util-sanitize-uri: 1.1.0 - micromark-util-subtokenize: 1.0.2 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - uvu: 0.5.6 - transitivePeerDependencies: - - supports-color - dev: false - /micromatch/4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -2660,9 +1949,10 @@ packages: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 + dev: true - /minimatch/5.1.1: - resolution: {integrity: sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==} + /minimatch/5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 @@ -2681,27 +1971,8 @@ packages: resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} dev: true - /mixin-object/2.0.1: - resolution: {integrity: sha512-ALGF1Jt9ouehcaXaHhn6t1yGWRqGaHkPFndtFVHfZXOvkIZ/yoGaSi0AHVTafb3ZBGg4dr/bDwnaEKqCXzchMA==} - engines: {node: '>=0.10.0'} - dependencies: - for-in: 0.1.8 - is-extendable: 0.1.1 - dev: false - - /mkdirp-classic/0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - - /mri/1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - dev: false - /ms/2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - /ms/2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: true /mz/2.7.0: @@ -2720,24 +1991,8 @@ packages: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} dev: true - /node-fetch/2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - - /node-releases/2.0.6: - resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} - dev: true - - /nofilter/3.1.0: - resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} - engines: {node: '>=12.19'} + /node-releases/2.0.9: + resolution: {integrity: sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==} dev: true /normalize-package-data/2.5.0: @@ -2776,7 +2031,7 @@ packages: minimatch: 3.1.2 pidtree: 0.3.1 read-pkg: 3.0.0 - shell-quote: 1.7.4 + shell-quote: 1.8.0 string.prototype.padend: 3.1.4 dev: true @@ -2799,8 +2054,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /object-inspect/1.12.2: - resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} + /object-inspect/1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} dev: true /object-keys/1.1.1: @@ -2822,6 +2077,7 @@ packages: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 + dev: true /onetime/5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} @@ -2842,7 +2098,7 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: bl: 5.1.0 - chalk: 5.1.2 + chalk: 5.2.0 cli-cursor: 4.0.0 cli-spinners: 2.7.0 is-interactive: 2.0.0 @@ -2852,17 +2108,6 @@ packages: wcwidth: 1.0.1 dev: true - /p-defer/1.0.0: - resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} - engines: {node: '>=4'} - - /p-event/5.0.1: - resolution: {integrity: sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-timeout: 5.1.0 - dev: true - /p-limit/3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -2870,13 +2115,6 @@ packages: yocto-queue: 0.1.0 dev: true - /p-limit/4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - yocto-queue: 1.0.0 - dev: true - /p-locate/5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -2884,13 +2122,6 @@ packages: p-limit: 3.1.0 dev: true - /p-locate/6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-limit: 4.0.0 - dev: true - /p-map/4.0.0: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} @@ -2905,22 +2136,11 @@ packages: aggregate-error: 4.0.1 dev: true - /p-timeout/5.1.0: - resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} - engines: {node: '>=12'} - dev: true - - /p-timeout/6.0.0: - resolution: {integrity: sha512-5iS61MOdUMemWH9CORQRxVXTp9g5K8rPnI9uQpo97aWgsH3vVXKjkIhDi+OgIDmN3Ly9+AZ2fZV01Wut1yzfKA==} + /p-timeout/6.1.0: + resolution: {integrity: sha512-s0y6Le9QYGELLzNpFIt6h8B2DHTVUDLStvxtvRMSKNKeuNVVWby2dZ+pIJpW4/pWr5a3s8W85wBNtc0ZA+lzCg==} engines: {node: '>=14.16'} dev: false - /parent-module/1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - dependencies: - callsites: 3.1.0 - /parse-json/4.0.0: resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} engines: {node: '>=4'} @@ -2937,10 +2157,6 @@ packages: error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - - /parse-ms/3.0.0: - resolution: {integrity: sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==} - engines: {node: '>=12'} dev: true /path-exists/4.0.0: @@ -2948,14 +2164,10 @@ packages: engines: {node: '>=8'} dev: true - /path-exists/5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - /path-is-absolute/1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} + dev: true /path-key/2.0.1: resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} @@ -2986,9 +2198,7 @@ packages: /path-type/4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - - /pend/1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + dev: true /picocolors/1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -3021,21 +2231,6 @@ packages: engines: {node: '>= 6'} dev: true - /pkg-conf/4.0.0: - resolution: {integrity: sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - find-up: 6.3.0 - load-json-file: 7.0.1 - dev: true - - /plur/5.1.0: - resolution: {integrity: sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - irregular-plurals: 3.3.0 - dev: true - /postcss-load-config/3.1.4: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} @@ -3052,179 +2247,17 @@ packages: yaml: 1.10.2 dev: true - /prettier/2.8.0: - resolution: {integrity: sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==} + /prettier/2.8.3: + resolution: {integrity: sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==} engines: {node: '>=10.13.0'} hasBin: true dev: true - /pretty-ms/8.0.0: - resolution: {integrity: sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==} - engines: {node: '>=14.16'} - dependencies: - parse-ms: 3.0.0 - dev: true - - /progress/2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - - /proxy-from-env/1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - /pump/3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - - /punycode/2.1.1: - resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} + /punycode/2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} dev: true - /puppeteer-core/19.4.0: - resolution: {integrity: sha512-gG/jxseleZStinBn86x8r7trjcE4jcjx1hIQWOpACQhquHYMuKnrWxkzg+EDn8sN3wUtF/Ry9mtJgjM49oUOFQ==} - engines: {node: '>=14.1.0'} - dependencies: - cross-fetch: 3.1.5 - debug: 4.3.4 - devtools-protocol: 0.0.1068969 - extract-zip: 2.0.1 - https-proxy-agent: 5.0.1 - proxy-from-env: 1.1.0 - rimraf: 3.0.2 - tar-fs: 2.1.1 - unbzip2-stream: 1.4.3 - ws: 8.10.0 - transitivePeerDependencies: - - bufferutil - - encoding - - supports-color - - utf-8-validate - - /puppeteer-extra-plugin-stealth/2.11.1_puppeteer-extra@3.3.4: - resolution: {integrity: sha512-n0wdC0Ilc9tk5L6FWLyd0P2gT8b2fp+2NuB+KB0oTSw3wXaZ0D6WNakjJsayJ4waGzIJFCUHkmK9zgx5NKMoFw==} - engines: {node: '>=8'} - peerDependencies: - playwright-extra: '*' - puppeteer-extra: '*' - peerDependenciesMeta: - playwright-extra: - optional: true - puppeteer-extra: - optional: true - dependencies: - debug: 4.3.4 - puppeteer-extra: 3.3.4_puppeteer@19.4.0 - puppeteer-extra-plugin: 3.2.2_puppeteer-extra@3.3.4 - puppeteer-extra-plugin-user-preferences: 2.4.0_puppeteer-extra@3.3.4 - transitivePeerDependencies: - - supports-color - dev: false - - /puppeteer-extra-plugin-user-data-dir/2.4.0_puppeteer-extra@3.3.4: - resolution: {integrity: sha512-qrhYPTGIqzL2hpeJ5DXjf8xMy5rt1UvcqSgpGTTOUOjIMz1ROWnKHjBoE9fNBJ4+ToRZbP8MzIDXWlEk/e1zJA==} - engines: {node: '>=8'} - peerDependencies: - playwright-extra: '*' - puppeteer-extra: '*' - peerDependenciesMeta: - playwright-extra: - optional: true - puppeteer-extra: - optional: true - dependencies: - debug: 4.3.4 - fs-extra: 10.1.0 - puppeteer-extra: 3.3.4_puppeteer@19.4.0 - puppeteer-extra-plugin: 3.2.2_puppeteer-extra@3.3.4 - rimraf: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: false - - /puppeteer-extra-plugin-user-preferences/2.4.0_puppeteer-extra@3.3.4: - resolution: {integrity: sha512-4XxMhMkJ+qqLsPY9ULF90qS9Bj1Qrwwgp1TY9zTdp1dJuy7QSgYE7xlyamq3cKrRuzg3QUOqygJo52sVeXSg5A==} - engines: {node: '>=8'} - peerDependencies: - playwright-extra: '*' - puppeteer-extra: '*' - peerDependenciesMeta: - playwright-extra: - optional: true - puppeteer-extra: - optional: true - dependencies: - debug: 4.3.4 - deepmerge: 4.2.2 - puppeteer-extra: 3.3.4_puppeteer@19.4.0 - puppeteer-extra-plugin: 3.2.2_puppeteer-extra@3.3.4 - puppeteer-extra-plugin-user-data-dir: 2.4.0_puppeteer-extra@3.3.4 - transitivePeerDependencies: - - supports-color - dev: false - - /puppeteer-extra-plugin/3.2.2_puppeteer-extra@3.3.4: - resolution: {integrity: sha512-0uatQxzuVn8yegbrEwSk03wvwpMB5jNs7uTTnermylLZzoT+1rmAQaJXwlS3+vADUbw6ELNgNEHC7Skm0RqHbQ==} - engines: {node: '>=9.11.2'} - peerDependencies: - playwright-extra: '*' - puppeteer-extra: '*' - peerDependenciesMeta: - playwright-extra: - optional: true - puppeteer-extra: - optional: true - dependencies: - '@types/debug': 4.1.7 - debug: 4.3.4 - merge-deep: 3.0.3 - puppeteer-extra: 3.3.4_puppeteer@19.4.0 - transitivePeerDependencies: - - supports-color - dev: false - - /puppeteer-extra/3.3.4_puppeteer@19.4.0: - resolution: {integrity: sha512-fN5pHvSMJ8d1o7Z8wLLTQOUBpORD2BcFn+KDs7QnkGZs9SV69hcUcce67vX4L4bNSEG3A0P6Osrv+vWNhhdm8w==} - engines: {node: '>=8'} - peerDependencies: - '@types/puppeteer': '*' - puppeteer: '*' - puppeteer-core: '*' - peerDependenciesMeta: - '@types/puppeteer': - optional: true - puppeteer: - optional: true - puppeteer-core: - optional: true - dependencies: - '@types/debug': 4.1.7 - debug: 4.3.4 - deepmerge: 4.2.2 - puppeteer: 19.4.0 - transitivePeerDependencies: - - supports-color - dev: false - - /puppeteer/19.4.0: - resolution: {integrity: sha512-sRzWEfFSZCCcFUJflGtYI2V7A6qK4Jht+2JiI2LZgn+Nv/LOZZsBDEaGl98ZrS8oEcUA5on4p2yJbE0nzHNzIg==} - engines: {node: '>=14.1.0'} - requiresBuild: true - dependencies: - cosmiconfig: 8.0.0 - devtools-protocol: 0.0.1068969 - https-proxy-agent: 5.0.1 - progress: 2.0.3 - proxy-from-env: 1.1.0 - puppeteer-core: 19.4.0 - transitivePeerDependencies: - - bufferutil - - encoding - - supports-color - - utf-8-validate - /queue-microtask/1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true @@ -3234,11 +2267,9 @@ packages: engines: {node: '>=10'} dev: true - /random/4.1.0: - resolution: {integrity: sha512-6Ajb7XmMSE9EFAMGC3kg9mvE7fGlBip25mYYuSMzw/uUSrmGilvZo2qwX3RnTRjwXkwkS+4swse9otZ92VjAtQ==} - engines: {node: '>=14'} - dependencies: - seedrandom: 3.0.5 + /quick-lru/6.1.1: + resolution: {integrity: sha512-S27GBT+F0NTRiehtbrgaSE1idUAJ5bX8dPAQTdylEyNlrdcH5X4Lz7Edz3DYzecbsCluD5zO8ZNEe04z3D3u6Q==} + engines: {node: '>=12'} dev: false /read-pkg-up/8.0.0: @@ -3276,6 +2307,7 @@ packages: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 + dev: true /readdirp/3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} @@ -3292,6 +2324,18 @@ packages: strip-indent: 4.0.0 dev: true + /redis-errors/1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + dev: true + + /redis-parser/3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + dependencies: + redis-errors: 1.2.0 + dev: true + /regexp.prototype.flags/1.4.3: resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} engines: {node: '>= 0.4'} @@ -3301,51 +2345,6 @@ packages: functions-have-names: 1.2.3 dev: true - /remark-parse/10.0.1: - resolution: {integrity: sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==} - dependencies: - '@types/mdast': 3.0.10 - mdast-util-from-markdown: 1.2.0 - unified: 10.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /remark-stringify/10.0.2: - resolution: {integrity: sha512-6wV3pvbPvHkbNnWB0wdDvVFHOe1hBRAx1Q/5g/EpH4RppAII6J8Gnwe7VbHuXaoKIF6LAg6ExTel/+kNqSQ7lw==} - dependencies: - '@types/mdast': 3.0.10 - mdast-util-to-markdown: 1.3.0 - unified: 10.1.2 - dev: false - - /remark/14.0.2: - resolution: {integrity: sha512-A3ARm2V4BgiRXaUo5K0dRvJ1lbogrbXnhkJRmD0yw092/Yl0kOCZt1k9ZeElEwkZsWGsMumz6qL5MfNJH9nOBA==} - dependencies: - '@types/mdast': 3.0.10 - remark-parse: 10.0.1 - remark-stringify: 10.0.2 - unified: 10.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /require-directory/2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true - - /resolve-cwd/3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - dependencies: - resolve-from: 5.0.0 - dev: true - - /resolve-from/4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - /resolve-from/5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} @@ -3390,9 +2389,10 @@ packages: hasBin: true dependencies: glob: 7.2.3 + dev: true - /rollup/3.5.1: - resolution: {integrity: sha512-hdQWTvPeiAbM6SUkxV70HdGUVxsgsc+CLy5fuh4KdgUBJ0SowXiix8gANgXoG3wEuLwfoJhCT2V+WwxfWq9Ikw==} + /rollup/3.12.0: + resolution: {integrity: sha512-4MZ8kA2HNYahIjz63rzrMMRvDqQDeS9LoriJvMuV0V6zIGysP36e9t4yObUfwdT9h/szXoHQideICftcdZklWg==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: @@ -3405,34 +2405,24 @@ packages: queue-microtask: 1.2.3 dev: true - /rxjs/7.5.7: - resolution: {integrity: sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==} + /rxjs/7.8.0: + resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==} dependencies: - tslib: 2.4.1 + tslib: 2.5.0 dev: true - /sade/1.8.1: - resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} - engines: {node: '>=6'} - dependencies: - mri: 1.2.0 - dev: false - /safe-buffer/5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true /safe-regex-test/1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} dependencies: call-bind: 1.0.2 - get-intrinsic: 1.1.3 + get-intrinsic: 1.2.0 is-regex: 1.1.4 dev: true - /seedrandom/3.0.5: - resolution: {integrity: sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==} - dev: false - /semver/5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true @@ -3451,23 +2441,6 @@ packages: lru-cache: 6.0.0 dev: true - /serialize-error/7.0.1: - resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} - engines: {node: '>=10'} - dependencies: - type-fest: 0.13.1 - dev: true - - /shallow-clone/0.1.2: - resolution: {integrity: sha512-J1zdXCky5GmNnuauESROVu31MQSnLoYvlyEn6j2Ztk6Q5EHFIhxkMhYcv6vuDzl2XEzoRr856QwzMgWM/TmZgw==} - engines: {node: '>=0.10.0'} - dependencies: - is-extendable: 0.1.1 - kind-of: 2.0.1 - lazy-cache: 0.2.7 - mixin-object: 2.0.1 - dev: false - /shebang-command/1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -3492,24 +2465,24 @@ packages: engines: {node: '>=8'} dev: true - /shell-quote/1.7.4: - resolution: {integrity: sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==} + /shell-quote/1.8.0: + resolution: {integrity: sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==} dev: true - /shiki/0.11.1: - resolution: {integrity: sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==} + /shiki/0.12.1: + resolution: {integrity: sha512-aieaV1m349rZINEBkjxh2QbBvFFQOlgqYTNtCal82hHj4dDZ76oMlQIX+C7ryerBTDiga3e5NfH6smjdJ02BbQ==} dependencies: jsonc-parser: 3.2.0 vscode-oniguruma: 1.7.0 - vscode-textmate: 6.0.0 + vscode-textmate: 8.0.0 dev: true /side-channel/1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: call-bind: 1.0.2 - get-intrinsic: 1.1.3 - object-inspect: 1.12.2 + get-intrinsic: 1.2.0 + object-inspect: 1.12.3 dev: true /signal-exit/3.0.7: @@ -3598,15 +2571,8 @@ packages: resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==} dev: true - /sprintf-js/1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true - - /stack-utils/2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - dependencies: - escape-string-regexp: 2.0.0 + /standard-as-callback/2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} dev: true /string-argv/0.3.1: @@ -3638,7 +2604,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.4 + es-abstract: 1.21.1 dev: true /string.prototype.trimend/1.0.6: @@ -3646,7 +2612,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.4 + es-abstract: 1.21.1 dev: true /string.prototype.trimstart/1.0.6: @@ -3654,13 +2620,14 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.4 + es-abstract: 1.21.1 dev: true /string_decoder/1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 + dev: true /strip-ansi/6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -3698,14 +2665,6 @@ packages: min-indent: 1.0.1 dev: true - /strip-markdown/5.0.0: - resolution: {integrity: sha512-PXSts6Ta9A/TwGxVVSRlQs1ukJTAwwtbip2OheJEjPyfykaQ4sJSTnQWjLTI2vYWNts/R/91/csagp15W8n9gA==} - dependencies: - '@types/mdast': 3.0.10 - '@types/unist': 2.0.6 - unified: 10.1.2 - dev: false - /sucrase/3.29.0: resolution: {integrity: sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==} engines: {node: '>=8'} @@ -3719,65 +2678,18 @@ packages: ts-interface-checker: 0.1.13 dev: true - /supertap/3.0.1: - resolution: {integrity: sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - indent-string: 5.0.0 - js-yaml: 3.14.1 - serialize-error: 7.0.1 - strip-ansi: 7.0.1 - dev: true - /supports-color/5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} dependencies: has-flag: 3.0.0 + dev: true /supports-preserve-symlinks-flag/1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} dev: true - /tar-fs/2.1.1: - resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.0 - tar-stream: 2.2.0 - - /tar-stream/2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.0 - - /temp-dir/2.0.0: - resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} - engines: {node: '>=8'} - dev: false - - /temp-dir/3.0.0: - resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} - engines: {node: '>=14.16'} - dev: true - - /tempy/3.0.0: - resolution: {integrity: sha512-B2I9X7+o2wOaW4r/CWMkpOO9mdiTRCxXNgob6iGvPmfPWgH/KyUD6Uy5crtWBxIBe3YrNZKR2lSzv1JJKWD4vA==} - engines: {node: '>=14.16'} - dependencies: - is-stream: 3.0.0 - temp-dir: 2.0.0 - type-fest: 2.19.0 - unique-string: 3.0.0 - dev: false - /thenify-all/1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -3793,10 +2705,6 @@ packages: /through/2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - /time-zone/1.0.0: - resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==} - engines: {node: '>=4'} dev: true /to-fast-properties/2.0.0: @@ -3811,13 +2719,10 @@ packages: is-number: 7.0.0 dev: true - /tr46/0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - /tr46/1.0.1: resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} dependencies: - punycode: 2.1.1 + punycode: 2.3.0 dev: true /tree-kill/1.2.2: @@ -3830,19 +2735,15 @@ packages: engines: {node: '>=12'} dev: true - /trough/2.1.0: - resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} - dev: false - /ts-interface-checker/0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true - /tslib/2.4.1: - resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + /tslib/2.5.0: + resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} dev: true - /tsup/6.5.0_typescript@4.9.3: + /tsup/6.5.0_typescript@4.9.5: resolution: {integrity: sha512-36u82r7rYqRHFkD15R20Cd4ercPkbYmuvRkz3Q1LCm5BsiFNUgpo36zbjVhCOgvjyxNBWNKHsaD5Rl8SykfzNA==} engines: {node: '>=14'} hasBin: true @@ -3858,28 +2759,28 @@ packages: typescript: optional: true dependencies: - bundle-require: 3.1.2_esbuild@0.15.16 + bundle-require: 3.1.2_esbuild@0.15.18 cac: 6.7.14 chokidar: 3.5.3 debug: 4.3.4 - esbuild: 0.15.16 + esbuild: 0.15.18 execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 postcss-load-config: 3.1.4 resolve-from: 5.0.0 - rollup: 3.5.1 + rollup: 3.12.0 source-map: 0.8.0-beta.0 sucrase: 3.29.0 tree-kill: 1.2.2 - typescript: 4.9.3 + typescript: 4.9.5 transitivePeerDependencies: - supports-color - ts-node dev: true - /tsx/3.12.1: - resolution: {integrity: sha512-Rcg1x+rNe7qwlP8j7kx4VjP/pJo/V57k+17hlrn6a7FuQLNwkaw5W4JF75tYornNVCxkXdSUnqlIT8JY/ttvIw==} + /tsx/3.12.2: + resolution: {integrity: sha512-ykAEkoBg30RXxeOMVeZwar+JH632dZn9EUJVyJwhfag62k6UO/dIyJEV58YuLF6e5BTdV/qmbQrpkWqjq9cUnQ==} hasBin: true dependencies: '@esbuild-kit/cjs-loader': 2.4.1 @@ -3889,11 +2790,6 @@ packages: fsevents: 2.3.2 dev: true - /type-fest/0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} - engines: {node: '>=10'} - dev: true - /type-fest/0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} @@ -3902,37 +2798,41 @@ packages: /type-fest/1.4.0: resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} engines: {node: '>=10'} + dev: true - /type-fest/2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} - dev: false + /typed-array-length/1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + is-typed-array: 1.1.10 + dev: true - /typedoc-plugin-markdown/3.13.6_typedoc@0.23.21: - resolution: {integrity: sha512-ISSc9v3BK7HkokxSBuJPttXox4tJ6hP0N9wfSIk0fmLN67+eqtAxbk97gs2nDiuha+RTO5eW9gdeAb+RPP0mgg==} + /typedoc-plugin-markdown/3.14.0_typedoc@0.23.24: + resolution: {integrity: sha512-UyQLkLRkfTFhLdhSf3RRpA3nNInGn+k6sll2vRXjflaMNwQAAiB61SYbisNZTg16t4K1dt1bPQMMGLrxS0GZ0Q==} peerDependencies: typedoc: '>=0.23.0' dependencies: handlebars: 4.7.7 - typedoc: 0.23.21_typescript@4.9.3 + typedoc: 0.23.24_typescript@4.9.5 dev: true - /typedoc/0.23.21_typescript@4.9.3: - resolution: {integrity: sha512-VNE9Jv7BgclvyH9moi2mluneSviD43dCE9pY8RWkO88/DrEgJZk9KpUk7WO468c9WWs/+aG6dOnoH7ccjnErhg==} + /typedoc/0.23.24_typescript@4.9.5: + resolution: {integrity: sha512-bfmy8lNQh+WrPYcJbtjQ6JEEsVl/ce1ZIXyXhyW+a1vFrjO39t6J8sL/d6FfAGrJTc7McCXgk9AanYBSNvLdIA==} engines: {node: '>= 14.14'} hasBin: true peerDependencies: typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x dependencies: lunr: 2.3.9 - marked: 4.2.3 - minimatch: 5.1.1 - shiki: 0.11.1 - typescript: 4.9.3 + marked: 4.2.12 + minimatch: 5.1.6 + shiki: 0.12.1 + typescript: 4.9.5 dev: true - /typescript/4.9.3: - resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} + /typescript/4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} engines: {node: '>=4.2.0'} hasBin: true dev: true @@ -3954,91 +2854,26 @@ packages: which-boxed-primitive: 1.0.2 dev: true - /unbzip2-stream/1.4.3: - resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} - dependencies: - buffer: 5.7.1 - through: 2.3.8 - - /unified/10.1.2: - resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} - dependencies: - '@types/unist': 2.0.6 - bail: 2.0.2 - extend: 3.0.2 - is-buffer: 2.0.5 - is-plain-obj: 4.1.0 - trough: 2.1.0 - vfile: 5.3.6 - dev: false - - /unique-string/3.0.0: - resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} - engines: {node: '>=12'} - dependencies: - crypto-random-string: 4.0.0 - dev: false - - /unist-util-is/5.1.1: - resolution: {integrity: sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==} - dev: false - - /unist-util-stringify-position/3.0.2: - resolution: {integrity: sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==} - dependencies: - '@types/unist': 2.0.6 - dev: false - - /unist-util-visit-parents/5.1.1: - resolution: {integrity: sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==} - dependencies: - '@types/unist': 2.0.6 - unist-util-is: 5.1.1 - dev: false - - /unist-util-visit/4.1.1: - resolution: {integrity: sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==} - dependencies: - '@types/unist': 2.0.6 - unist-util-is: 5.1.1 - unist-util-visit-parents: 5.1.1 - dev: false - - /universalify/2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} - engines: {node: '>= 10.0.0'} - dev: false - - /update-browserslist-db/1.0.10_browserslist@4.21.4: + /update-browserslist-db/1.0.10_browserslist@4.21.5: resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.21.4 + browserslist: 4.21.5 escalade: 3.1.1 picocolors: 1.0.0 dev: true /util-deprecate/1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true /uuid/9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} hasBin: true dev: false - /uvu/0.5.6: - resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} - engines: {node: '>=8'} - hasBin: true - dependencies: - dequal: 2.0.3 - diff: 5.1.0 - kleur: 4.1.5 - sade: 1.8.1 - dev: false - /validate-npm-package-license/3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: @@ -4046,28 +2881,12 @@ packages: spdx-expression-parse: 3.0.1 dev: true - /vfile-message/3.1.3: - resolution: {integrity: sha512-0yaU+rj2gKAyEk12ffdSbBfjnnj+b1zqTBv3OQCTn8yEB02bsPizwdBPrLJjHnK+cU9EMMcUnNv938XcZIkmdA==} - dependencies: - '@types/unist': 2.0.6 - unist-util-stringify-position: 3.0.2 - dev: false - - /vfile/5.3.6: - resolution: {integrity: sha512-ADBsmerdGBs2WYckrLBEmuETSPyTD4TuLxTrw0DvjirxW1ra4ZwkbzG8ndsv3Q57smvHxo677MHaQrY9yxH8cA==} - dependencies: - '@types/unist': 2.0.6 - is-buffer: 2.0.5 - unist-util-stringify-position: 3.0.2 - vfile-message: 3.1.3 - dev: false - /vscode-oniguruma/1.7.0: resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} dev: true - /vscode-textmate/6.0.0: - resolution: {integrity: sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==} + /vscode-textmate/8.0.0: + resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} dev: true /wcwidth/1.0.1: @@ -4076,24 +2895,10 @@ packages: defaults: 1.0.4 dev: true - /webidl-conversions/3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - /webidl-conversions/4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} dev: true - /well-known-symbols/2.0.0: - resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==} - engines: {node: '>=6'} - dev: true - - /whatwg-url/5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - /whatwg-url/7.1.0: resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} dependencies: @@ -4112,6 +2917,18 @@ packages: is-symbol: 1.0.4 dev: true + /which-typed-array/1.1.9: + resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + is-typed-array: 1.1.10 + dev: true + /which/1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true @@ -4151,30 +2968,10 @@ packages: /wrappy/1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - /write-file-atomic/5.0.0: - resolution: {integrity: sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 dev: true - /ws/8.10.0: - resolution: {integrity: sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - /y18n/5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + /yallist/3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} dev: true /yallist/4.0.0: @@ -4186,8 +2983,8 @@ packages: engines: {node: '>= 6'} dev: true - /yaml/2.1.3: - resolution: {integrity: sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==} + /yaml/2.2.1: + resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==} engines: {node: '>= 14'} dev: true @@ -4196,40 +2993,7 @@ packages: engines: {node: '>=10'} dev: true - /yargs-parser/21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: true - - /yargs/17.6.2: - resolution: {integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==} - engines: {node: '>=12'} - dependencies: - cliui: 8.0.1 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - dev: true - - /yauzl/2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - /yocto-queue/0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true - - /yocto-queue/1.0.0: - resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} - engines: {node: '>=12.20'} - dev: true - - /zwitch/2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - dev: false diff --git a/readme.md b/readme.md index f5b356f..1420b32 100644 --- a/readme.md +++ b/readme.md @@ -1,29 +1,19 @@ -# Update January 12, 2023 +# Update February 1, 2023 -This package allows you to access ChatGPT from Node.js – even with OpenAI's Cloudflare protections. It uses a **fully automated browser-based solution**, which uses Puppeteer and CAPTCHA solvers under the hood. 🔥 +This package no longer requires any browser hacks – **it is now using the official OpenAI API** with a leaked, unofficial ChatGPT model. 🔥 ```ts -import { ChatGPTAPIBrowser } from 'chatgpt' +import { ChatGPTAPI } from 'chatgpt' -const api = new ChatGPTAPIBrowser({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD +const api = new ChatGPTAPI({ + apiKey: process.env.OPENAI_API_KEY }) -await api.initSession() -const result = await api.sendMessage('Hello World!') -console.log(result.response) +const res = await api.sendMessage('Hello World!') +console.log(res.text) ``` -This solution is not lightweight, but it does work a lot more consistently than the previous REST API-based approach. For example, I'm currently using this approach to automate N concurrent OpenAI accounts for my [Twitter bot](https://github.com/transitive-bullshit/chatgpt-twitter-bot). 😂 - -We recently added support for CAPTCHA automation using either [nopecha](https://nopecha.com/) or [2captcha](https://2captcha.com). Keep in mind that this package will be updated to use the official API as soon as it's released, so things should get much easier over time. 💪 - -There are some restrictions to be aware of, however: - -- Cloudflare doesn't like requests coming from data center IPs, so you'll likely either need to run it locally or use a residential IP proxy. -- You should only have one `sendMessage` request at a time per browser instance and OpenAI account. -- It can be difficult to reliably process `sendMessage` requests after awhile. My best advice for handling this is to wrap your usage in some basic retry logic as well as a daemon which restarts your Node.js process every hour or so. This is unfortunately a by-product of there not being an official API, so keep that in mind before using this in production. +The updated solution is significantly more lightweight and robust compared with previous versions. You also don't have to worry about IP issues or rate limiting! If you run into any issues, we do have a pretty active [Discord](https://discord.gg/v9gERj825w) with a bunch of ChatGPT hackers from the Node.js & Python communities. @@ -49,10 +39,6 @@ Thanks && cheers, - [Usage](#usage) - [Docs](#docs) - [Demos](#demos) - - [Authentication](#authentication) - - [CAPTCHAs](#captchas) - - [Using Proxies](#using-proxies) - - [Restrictions](#restrictions) - [Projects](#projects) - [Compatibility](#compatibility) - [Credits](#credits) @@ -67,91 +53,61 @@ You can use it to start building projects powered by ChatGPT like chatbots, webs ## Install ```bash -npm install chatgpt puppeteer +npm install chatgpt ``` -`puppeteer` is an optional peer dependency used to automate bypassing the Cloudflare protections via `getOpenAIAuth`. The main API wrapper uses `fetch` directly. - ## Usage +Sign up for an [OpenAI API key](https://platform.openai.com/overview) and store it in your environment. + ```ts -import { ChatGPTAPIBrowser } from 'chatgpt' +import { ChatGPTAPI } from 'chatgpt' async function example() { - // use puppeteer to bypass cloudflare (headful because of captchas) - const api = new ChatGPTAPIBrowser({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD + const api = new ChatGPTAPI({ + apiKey: process.env.OPENAI_API_KEY }) - await api.initSession() - - const result = await api.sendMessage('Hello World!') - console.log(result.response) + const res = await api.sendMessage('Hello World!') + console.log(res.text) } ``` -
-Or, if you want to use the REST-based version: (not advised at this time) +If you want to track the conversation, use the `conversationId` and `id` in the result object, and pass them to `sendMessage` as `conversationId` and `parentMessageId` respectively. ```ts -import { ChatGPTAPI, getOpenAIAuth } from 'chatgpt' - -async function example() { - // use puppeteer to bypass cloudflare (headful because of captchas) - const openAIAuth = await getOpenAIAuth({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD - }) - - const api = new ChatGPTAPI({ ...openAIAuth }) - await api.initSession() - - // send a message and wait for the response - const result = await api.sendMessage('Write a python version of bubble sort.') - - // result.response is a markdown-formatted string - console.log(result.response) -} -``` - -
- -ChatGPT responses are formatted as markdown by default. If you want to work with plaintext instead, you can use: - -```ts -const api = new ChatGPTAPIBrowser({ email, password, markdown: false }) -``` - -If you want to track the conversation, use the `conversationId` and `messageId` in the result object, and pass them to `sendMessage` as `conversationId` and `parentMessageId` respectively. - -```ts -const api = new ChatGPTAPIBrowser({ email, password }) -await api.initSession() +const api = new ChatGPTAPI({ apiKey: process.env.OPENAI_API_KEY }) // send a message and wait for the response let res = await api.sendMessage('What is OpenAI?') -console.log(res.response) +console.log(res.text) // send a follow-up res = await api.sendMessage('Can you expand on that?', { conversationId: res.conversationId, - parentMessageId: res.messageId + parentMessageId: res.id }) -console.log(res.response) +console.log(res.text) // send another follow-up // send a follow-up res = await api.sendMessage('What were we talking about?', { conversationId: res.conversationId, - parentMessageId: res.messageId + parentMessageId: res.id }) -console.log(res.response) +console.log(res.text) ``` -Sometimes, ChatGPT will hang for an extended period of time before beginning to respond. This may be due to rate limiting or it may be due to OpenAI's servers being overloaded. +You can add streaming via the `onProgress` handler: -To mitigate these issues, you can add a timeout like this: +```ts +// timeout after 2 minutes (which will also abort the underlying HTTP request) +const res = await api.sendMessage('Write me a 500 word essay on frogs.', { + onProgress: (partialResponse) => console.log(partialResponse) +}) +``` + +You can add a timeout using the `timeoutMs` option: ```ts // timeout after 2 minutes (which will also abort the underlying HTTP request) @@ -166,18 +122,12 @@ const response = await api.sendMessage('this is a timeout test', { ```js async function example() { // To use ESM in CommonJS, you can use a dynamic import - const { ChatGPTAPI, getOpenAIAuth } = await import('chatgpt') + const { ChatGPTAPI } = await import('chatgpt') - const openAIAuth = await getOpenAIAuth({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD - }) + const api = new ChatGPTAPI({ apiKey: process.env.OPENAI_API_KEY }) - const api = new ChatGPTAPI({ ...openAIAuth }) - await api.initSession() - - const result = await api.sendMessage('Hello World!') - console.log(result) + const res = await api.sendMessage('Hello World!') + console.log(res.text) } ``` @@ -185,7 +135,7 @@ async function example() { ### Docs -See the [auto-generated docs](./docs/classes/ChatGPTAPI.md) for more info on methods and parameters. Here are the [docs](./docs/classes/ChatGPTAPIBrowser.md) for the browser-based version. +See the [auto-generated docs](./docs/classes/ChatGPTAPI.md) for more info on methods and parameters. Here are the [docs](./docs/classes/ChatGPTAPI.md) for the browser-based version. ### Demos @@ -193,7 +143,7 @@ To run the included demos: 1. clone repo 2. install node deps -3. set `OPENAI_EMAIL` and `OPENAI_PASSWORD` in .env +3. set `OPENAI_API_KEY` in .env A [basic demo](./demos/demo.ts) is included for testing purposes: @@ -201,12 +151,6 @@ A [basic demo](./demos/demo.ts) is included for testing purposes: npx tsx demos/demo.ts ``` -A [google auth demo](./demos/demo-google-auth.ts): - -```bash -npx tsx demos/demo-google-auth.ts -``` - A [demo showing on progress handler](./demos/demo-on-progress.ts): ```bash @@ -221,93 +165,15 @@ A [conversation demo](./demos/demo-conversation.ts): npx tsx demos/demo-conversation.ts ``` -### Authentication +Lastly, a [persitence demo](./demos/demo-persistence.ts) shows how to store messages in Redis for persistence: -The authentication section relates to the REST-based version (using `getOpenAIAuth` + `ChatGPTAPI`). The browser-based solution, `ChatGPTAPIBrowser`, takes care of all the authentication for you. - -On December 11, 2022, OpenAI added some additional Cloudflare protections which make it more difficult to access the unofficial API. - -You'll need a valid OpenAI "session token" and Cloudflare "clearance token" in order to use the API. - -We've provided an automated, Puppeteer-based solution `getOpenAIAuth` to fetch these for you, but you may still run into cases where you have to manually pass the CAPTCHA. We're working on a solution to automate this further. - -You can also get these tokens manually, but keep in mind that the `clearanceToken` only lasts for max 2 hours. - -
-Getting tokens manually - -To get session token manually: - -1. Go to https://chat.openai.com/chat and log in or sign up. -2. Open dev tools. -3. Open `Application` > `Cookies`. - ![ChatGPT cookies](./media/session-token.png) -4. Copy the value for `__Secure-next-auth.session-token` and save it to your environment. This will be your `sessionToken`. -5. Copy the value for `cf_clearance` and save it to your environment. This will be your `clearanceToken`. -6. Copy the value of the `user-agent` header from any request in your `Network` tab, or copy the result of `navigator.userAgent` command on `Console` tab. This will be your `userAgent`. - -Pass `sessionToken`, `clearanceToken`, and `userAgent` to the `ChatGPTAPI` constructor. - -
- -> **Note** -> This package will switch to using the official API once it's released, which will make this process much simpler. - -### CAPTCHAs - -The browser portions of this package use Puppeteer to automate as much as possible, including solving all CAPTCHAs. 🔥 - -Basic Cloudflare CAPTCHAs are handled by default, but if you want to automate the email + password Recaptchas, you'll need to sign up for one of these paid providers: - -- [nopecha](https://nopecha.com/) - Uses AI to solve CAPTCHAS - - Faster and cheaper - - Set the `NOPECHA_KEY` env var to your nopecha API key - - [Demo video](https://user-images.githubusercontent.com/552829/208235991-de4890f2-e7ba-4b42-bf55-4fcd792d4b19.mp4) of nopecha solving the login Recaptcha (41 seconds) -- [2captcha](https://2captcha.com) - Uses real people to solve CAPTCHAS - - More well-known solution that's been around longer - - Set the `CAPTCHA_TOKEN` env var to your 2captcha API token - -Alternatively, if your OpenAI account uses Google Auth, you shouldn't encounter any of the more complicated Recaptchas — and can avoid using these third-party providers. To use Google auth, make sure your OpenAI account is using Google and then set `isGoogleLogin` to `true` whenever you're passing your `email` and `password`. For example: - -```ts -const api = new ChatGPTAPIBrowser({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD, - isGoogleLogin: true -}) +```bash +npx tsx demos/demo-conversation.ts ``` -### Using Proxies +Any [keyv adaptor](https://github.com/jaredwray/keyv) is supported for persistence, and there are overrides if you'd like to use a different way of storing / retrieving messages. -The browser implementation supports setting a proxy server. This is useful if you're running into rate limiting issues or if you want to use a proxy to hide your IP address. - -To use a proxy, pass the `proxyServer` option to the `ChatGPTAPIBrowser` constructor, or simply set the `PROXY_SERVER` env var. For more information on the format, see [here](https://www.chromium.org/developers/design-documents/network-settings). - -```ts -const api = new ChatGPTAPIBrowser({ - email: process.env.OPENAI_EMAIL, - password: process.env.OPENAI_PASSWORD, - proxyServer: ':' -}) -``` - -You can also set the `PROXY_VALIDATE_IP` env var to your proxy's IP address. This will be used to validate that the proxy is working correctly, and will throw an error if it's not. - -### Restrictions - -These restrictions are for the `getOpenAIAuth` + `ChatGPTAPI` solution, which uses the unofficial API. The browser-based solution, `ChatGPTAPIBrowser`, generally doesn't have any of these restrictions. - -**Please read carefully** - -- You must use `node >= 18` at the moment. I'm using `v19.2.0` in my testing. -- Cloudflare `cf_clearance` **tokens expire after 2 hours**, so right now we recommend that you refresh your `cf_clearance` token every hour or so. -- Your `user-agent` and `IP address` **must match** from the real browser window you're logged in with to the one you're using for `ChatGPTAPI`. - - This means that you currently can't log in with your laptop and then run the bot on a server or proxy somewhere. -- Cloudflare will still sometimes ask you to complete a CAPTCHA, so you may need to keep an eye on it and manually resolve the CAPTCHA. -- You should not be using this account while the bot is using it, because that browser window may refresh one of your tokens and invalidate the bot's session. - -> **Note** -> Prior to v1.0.0, this package used a headless browser via [Playwright](https://playwright.dev/) to automate the web UI. Here are the [docs for the initial browser version](https://github.com/transitive-bullshit/chatgpt-api/tree/v0.4.2). +Note that persisting message is very important for remembering the context of previous conversations. ## Projects @@ -380,11 +246,11 @@ If you create a cool integration, feel free to open a PR and add it to the list. ## Compatibility -This package is ESM-only. It supports: - -- Node.js >= 18 - - Node.js 17, 16, and 14 were supported in earlier versions, but OpenAI's Cloudflare update caused a bug with `undici` on v17 and v16 that needs investigation. So for now, use `node >= 18` -- We recommend against using `chatgpt` from client-side browser code because it would expose your private session token +- This package is ESM-only. +- This package supports `node >= 14`. +- This module assumes that `fetch` is installed. + - In `node >= 18`, it's installed by default. + - In `node < 18`, you need to install a polyfill like `unfetch/polyfill` ([guide](https://github.com/developit/unfetch#usage-as-a-polyfill)) - If you want to build a website using `chatgpt`, we recommend using it only from your backend API ## Credits diff --git a/src/abstract-chatgpt-api.ts b/src/abstract-chatgpt-api.ts deleted file mode 100644 index 1f6f19f..0000000 --- a/src/abstract-chatgpt-api.ts +++ /dev/null @@ -1,70 +0,0 @@ -import * as types from './types' - -export abstract class AChatGPTAPI { - /** - * Performs any async initialization work required to ensure that this API is - * properly authenticated. - * - * @throws An error if the session failed to initialize properly. - */ - abstract initSession(): Promise - - /** - * Sends a message to ChatGPT, waits for the response to resolve, and returns - * the response. - * - * If you want to receive a stream of partial responses, use `opts.onProgress`. - * - * @param message - The prompt message to send - * @param opts.conversationId - Optional ID of a conversation to continue - * @param opts.parentMessageId - Optional ID of the previous message in the conversation - * @param opts.messageId - Optional ID of the message to send (defaults to a random UUID) - * @param opts.action - Optional ChatGPT `action` (either `next` or `variant`) - * @param opts.timeoutMs - Optional timeout in milliseconds (defaults to no timeout) - * @param opts.onProgress - Optional callback which will be invoked every time the partial response is updated - * @param opts.abortSignal - Optional callback used to abort the underlying `fetch` call using an [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) - * - * @returns The response from ChatGPT, including `conversationId`, `messageId`, and - * the `response` text. - */ - abstract sendMessage( - message: string, - opts?: types.SendMessageOptions - ): Promise - - /** - * @returns `true` if the client is authenticated with a valid session or `false` - * otherwise. - */ - abstract getIsAuthenticated(): Promise - - /** - * Refreshes the current ChatGPT session. - * - * Useful for bypassing 403 errors when Cloudflare clearance tokens expire. - * - * @returns Access credentials for the new session. - * @throws An error if it fails. - */ - abstract refreshSession(): Promise - - /** - * Closes the current ChatGPT session and starts a new one. - * - * Useful for bypassing 401 errors when sessions expire. - * - * @returns Access credentials for the new session. - * @throws An error if it fails. - */ - async resetSession(): Promise { - await this.closeSession() - return this.initSession() - } - - /** - * Closes the active session. - * - * @throws An error if it fails. - */ - abstract closeSession(): Promise -} diff --git a/src/chatgpt-api-browser.ts b/src/chatgpt-api-browser.ts deleted file mode 100644 index df78143..0000000 --- a/src/chatgpt-api-browser.ts +++ /dev/null @@ -1,648 +0,0 @@ -import delay from 'delay' -import type { Browser, HTTPRequest, HTTPResponse, Page } from 'puppeteer' -import { temporaryDirectory } from 'tempy' -import { v4 as uuidv4 } from 'uuid' - -import * as types from './types' -import { AChatGPTAPI } from './abstract-chatgpt-api' -import { getBrowser, getOpenAIAuth, getPage } from './openai-auth' -import { - browserPostEventStream, - isRelevantRequest, - markdownToText, - maximizePage, - minimizePage -} from './utils' - -const CHAT_PAGE_URL = 'https://chat.openai.com/chat' - -export class ChatGPTAPIBrowser extends AChatGPTAPI { - protected _markdown: boolean - protected _debug: boolean - protected _minimize: boolean - protected _isGoogleLogin: boolean - protected _isMicrosoftLogin: boolean - protected _captchaToken: string - protected _nopechaKey: string - protected _accessToken: string - - protected _email: string - protected _password: string - - protected _isProAccount: boolean - - protected _executablePath: string - protected _browser: Browser - protected _page: Page - protected _proxyServer: string - protected _isRefreshing: boolean - protected _messageOnProgressHandlers: Record< - string, - (partialResponse: types.ChatResponse) => void - > - protected _userDataDir: string - - /** - * Creates a new client for automating the ChatGPT webapp. - */ - constructor(opts: { - email: string - password: string - - /** @defaultValue `false` **/ - isProAccount?: boolean - - /** @defaultValue `true` **/ - markdown?: boolean - - /** @defaultValue `false` **/ - debug?: boolean - - /** @defaultValue `false` **/ - isGoogleLogin?: boolean - - /** @defaultValue `false` **/ - isMicrosoftLogin?: boolean - - /** @defaultValue `true` **/ - minimize?: boolean - - /** @defaultValue `undefined` **/ - captchaToken?: string - - /** @defaultValue `undefined` **/ - nopechaKey?: string - - /** @defaultValue `undefined` **/ - executablePath?: string - - /** @defaultValue `undefined` **/ - proxyServer?: string - - /** @defaultValue `random directory with email as prefix` **/ - userDataDir?: string - }) { - super() - - const { - email, - password, - isProAccount = false, - markdown = true, - debug = false, - isGoogleLogin = false, - isMicrosoftLogin = false, - minimize = true, - captchaToken, - nopechaKey, - executablePath, - proxyServer, - userDataDir - } = opts - - this._email = email - this._password = password - this._isProAccount = isProAccount - this._markdown = !!markdown - this._debug = !!debug - this._isGoogleLogin = !!isGoogleLogin - this._isMicrosoftLogin = !!isMicrosoftLogin - this._minimize = !!minimize - this._captchaToken = captchaToken - this._nopechaKey = nopechaKey - this._executablePath = executablePath - this._proxyServer = proxyServer - this._isRefreshing = false - this._messageOnProgressHandlers = {} - this._userDataDir = - userDataDir ?? temporaryDirectory({ prefix: this._email }) - - if (!this._email) { - const error = new types.ChatGPTError('ChatGPT invalid email') - error.statusCode = 401 - throw error - } - - if (!this._password) { - const error = new types.ChatGPTError('ChatGPT invalid password') - error.statusCode = 401 - throw error - } - } - - override async initSession() { - if (this._browser) { - await this.closeSession() - } - - try { - this._browser = await getBrowser({ - captchaToken: this._captchaToken, - nopechaKey: this._nopechaKey, - executablePath: this._executablePath, - proxyServer: this._proxyServer, - minimize: this._minimize, - userDataDir: this._userDataDir - }) - - this._page = await getPage(this._browser, { - proxyServer: this._proxyServer - }) - - // bypass annoying popup modals - this._page.evaluateOnNewDocument(() => { - window.localStorage.setItem('oai/apps/hasSeenOnboarding/chat', 'true') - window.localStorage.setItem( - 'oai/apps/hasSeenReleaseAnnouncement/2022-12-15', - 'true' - ) - window.localStorage.setItem( - 'oai/apps/hasSeenReleaseAnnouncement/2022-12-19', - 'true' - ) - window.localStorage.setItem( - 'oai/apps/hasSeenReleaseAnnouncement/2023-01-09', - 'true' - ) - }) - - // await maximizePage(this._page) - - this._page.on('request', this._onRequest.bind(this)) - this._page.on('response', this._onResponse.bind(this)) - - // bypass cloudflare and login - const authInfo = await getOpenAIAuth({ - email: this._email, - password: this._password, - browser: this._browser, - page: this._page, - isGoogleLogin: this._isGoogleLogin, - isMicrosoftLogin: this._isMicrosoftLogin - }) - - if (this._debug) { - console.log('chatgpt', this._email, 'auth', authInfo) - } - } catch (err) { - if (this._browser) { - await this._browser.close() - } - - this._browser = null - this._page = null - - throw err - } - - if (!this.isChatPage || this._isGoogleLogin || this._isMicrosoftLogin) { - await this._page.goto(CHAT_PAGE_URL, { - waitUntil: 'networkidle2' - }) - } - - // TODO: will this exist after page reload and navigation? - await this._page.exposeFunction( - 'ChatGPTAPIBrowserOnProgress', - (partialResponse: types.ChatResponse) => { - if ((partialResponse as any)?.origMessageId) { - const onProgress = - this._messageOnProgressHandlers[ - (partialResponse as any).origMessageId - ] - - if (onProgress) { - onProgress(partialResponse) - return - } - } - } - ) - - // dismiss welcome modal (and other modals) - do { - const modalSelector = '[data-headlessui-state="open"]' - - try { - if (!(await this._page.$(modalSelector))) { - break - } - - await this._page.click(`${modalSelector} button:last-child`) - } catch (err) { - // "next" button not found in welcome modal - break - } - - await delay(300) - } while (true) - - if (!(await this.getIsAuthenticated())) { - if (!this._accessToken) { - console.warn('no access token') - } else { - console.warn('failed to find prompt textarea') - } - - throw new types.ChatGPTError('Failed to authenticate session') - } - - if (this._minimize) { - return minimizePage(this._page) - } - } - - _onRequest = (request: HTTPRequest) => { - const url = request.url() - if (!isRelevantRequest(url)) { - return - } - - const method = request.method() - let body: any - - if (method === 'POST') { - body = request.postData() - - try { - body = JSON.parse(body) - } catch (_) {} - - // if (url.endsWith('/conversation') && typeof body === 'object') { - // const conversationBody: types.ConversationJSONBody = body - // const conversationId = conversationBody.conversation_id - // const parentMessageId = conversationBody.parent_message_id - // const messageId = conversationBody.messages?.[0]?.id - // const prompt = conversationBody.messages?.[0]?.content?.parts?.[0] - - // // TODO: store this info for the current sendMessage request - // } - } - - if (this._debug) { - console.log('\nrequest', { - url, - method, - headers: request.headers(), - body - }) - } - } - - _onResponse = async (response: HTTPResponse) => { - const request = response.request() - - const url = response.url() - if (!isRelevantRequest(url)) { - return - } - - const status = response.status() - - let body: any - try { - body = await response.json() - } catch (_) {} - - if (this._debug) { - console.log('\nresponse', { - url, - ok: response.ok(), - status, - statusText: response.statusText(), - headers: response.headers(), - body, - request: { - method: request.method(), - headers: request.headers(), - body: request.postData() - } - }) - } - const detail = body?.detail || '' - - if (url.endsWith('/conversation')) { - if (status >= 400) { - console.warn(`ChatGPT "${this._email}" error ${status};`, detail) - // this will be handled in the sendMessage error handler - // await this.refreshSession() - } - } else if (url.endsWith('api/auth/session')) { - if (status >= 400) { - console.warn(`ChatGPT "${this._email}" error ${status};`, detail) - // this will be handled in the sendMessage error handler - // await this.resetSession() - } else { - const session: types.SessionResult = body - - if (session?.accessToken) { - this._accessToken = session.accessToken - } - } - } - } - - /** - * Attempts to handle 401 errors by re-authenticating. - */ - async resetSession() { - console.log(`ChatGPT "${this._email}" resetSession...`) - try { - console.log('>>> closing session', this._email) - await this.closeSession() - console.log('<<< closing session', this._email) - await this.initSession() - console.log(`ChatGPT "${this._email}" refreshSession success`) - } catch (err) { - console.error( - `ChatGPT "${this._email}" resetSession error`, - err.toString() - ) - } - } - - /** - * Attempts to handle 403 errors by refreshing the page. - */ - async refreshSession() { - if (this._isRefreshing) { - return - } - - this._isRefreshing = true - console.log(`ChatGPT "${this._email}" refreshSession...`) - - try { - if (!this._minimize) { - await maximizePage(this._page) - } - - await this._page.reload() - - let response - const timeout = 120000 // 2 minutes in milliseconds - - try { - // Wait for a response that includes the 'cf_clearance' cookie - response = await this._page.waitForResponse( - (response) => { - const cookie = response.headers()['set-cookie'] - if (cookie?.includes('cf_clearance=')) { - const cfClearance = cookie - .split('cf_clearance=')?.[1] - ?.split(';')?.[0] - // console.log('Cloudflare Cookie:', cfClearance) - return true - } - return false - }, - { timeout } - ) - } catch (err) { - // Useful for when cloudflare cookie is still valid, to catch TimeoutError - response = !!(await this._getInputBox()) - } - - if (!response) { - throw new types.ChatGPTError('Could not fetch cf_clearance cookie') - } - - if (this._minimize && this.isChatPage) { - await minimizePage(this._page) - } - - console.log(`ChatGPT "${this._email}" refreshSession success`) - } catch (err) { - console.error( - `ChatGPT "${this._email}" error refreshing session`, - err.toString() - ) - } finally { - this._isRefreshing = false - } - } - - async getIsAuthenticated() { - try { - if (!this._accessToken) { - return false - } - - const inputBox = await this._getInputBox() - return !!inputBox - } catch (err) { - // can happen when navigating during login - return false - } - } - - override async sendMessage( - message: string, - opts: types.SendMessageOptions = {} - ): Promise { - const { - conversationId, - parentMessageId = uuidv4(), - messageId = uuidv4(), - action = 'next', - timeoutMs, - onProgress - } = opts - - const url = `https://chat.openai.com/backend-api/conversation` - const body: types.ConversationJSONBody = { - action, - messages: [ - { - id: messageId, - role: 'user', - content: { - content_type: 'text', - parts: [message] - } - } - ], - model: this._isProAccount - ? 'text-davinci-002-render-paid' - : 'text-davinci-002-render', - parent_message_id: parentMessageId - } - - if (conversationId) { - body.conversation_id = conversationId - } - - if (onProgress) { - this._messageOnProgressHandlers[messageId] = onProgress - } - - const cleanup = () => { - if (this._messageOnProgressHandlers[messageId]) { - delete this._messageOnProgressHandlers[messageId] - } - } - - let result: types.ChatResponse | types.ChatError - let numTries = 0 - let is401 = false - - do { - if (is401 || !(await this.getIsAuthenticated())) { - console.log(`chatgpt re-authenticating ${this._email}`) - - try { - await this.resetSession() - } catch (err) { - console.warn( - `chatgpt error re-authenticating ${this._email}`, - err.toString() - ) - } - - if (!(await this.getIsAuthenticated())) { - const error = new types.ChatGPTError('Not signed in') - error.statusCode = 401 - cleanup() - throw error - } - } - - try { - // console.log('>>> EVALUATE', url, this._accessToken, body) - result = await this._page.evaluate( - browserPostEventStream, - url, - this._accessToken, - body, - timeoutMs - ) - } catch (err) { - // We catch all errors in `browserPostEventStream`, so this should really - // only happen if the page is refreshed or closed during its invocation. - // This may happen if we encounter a 401/403 and refresh the page in it's - // response handler or if the user has closed the page manually. - - if (++numTries >= 2) { - const error = new types.ChatGPTError(err.toString(), { cause: err }) - error.statusCode = err.response?.statusCode - error.statusText = err.response?.statusText - cleanup() - throw error - } - - console.warn('chatgpt sendMessage error; retrying...', err.toString()) - await delay(5000) - continue - } - - if ('error' in result) { - const error = new types.ChatGPTError(result.error.message) - error.statusCode = result.error.statusCode - error.statusText = result.error.statusText - - ++numTries - - if (error.statusCode === 401) { - is401 = true - - if (numTries >= 2) { - cleanup() - throw error - } else { - continue - } - } else if (error.statusCode !== 403) { - throw error - } else if (numTries >= 2) { - await this.refreshSession() - throw error - } else { - await this.refreshSession() - await delay(1000) - result = null - continue - } - } else { - if (!this._markdown) { - result.response = markdownToText(result.response) - } - - cleanup() - return result - } - } while (!result) - - cleanup() - } - - async resetThread() { - try { - await this._page.click('nav > a:nth-child(1)') - } catch (err) { - // ignore for now - } - } - - override async closeSession() { - try { - if (this._page) { - this._page.off('request', this._onRequest.bind(this)) - this._page.off('response', this._onResponse.bind(this)) - - await this._page.deleteCookie({ - name: 'cf_clearance', - domain: '.chat.openai.com' - }) - - // TODO; test this - // const client = await this._page.target().createCDPSession() - // await client.send('Network.clearBrowserCookies') - // await client.send('Network.clearBrowserCache') - - await this._page.close() - } - } catch (err) { - console.warn('closeSession error', err) - } - - if (this._browser) { - try { - const pages = await this._browser.pages() - for (const page of pages) { - await page.close() - } - } catch (err) { - console.warn('closeSession error', err) - } - - await this._browser.close() - - const browserProcess = this._browser.process() - // Rule number 1 of zombie process hunting: double-tap - if (browserProcess) { - browserProcess.kill('SIGKILL') - } - } - - this._page = null - this._browser = null - this._accessToken = null - } - - protected async _getInputBox() { - try { - return await this._page.$('textarea') - } catch (err) { - return null - } - } - - get isChatPage(): boolean { - try { - const url = this._page?.url().replace(/\/$/, '') - return url === CHAT_PAGE_URL - } catch (err) { - return false - } - } -} diff --git a/src/chatgpt-api.test.ts b/src/chatgpt-api.test.ts deleted file mode 100644 index 5b798f9..0000000 --- a/src/chatgpt-api.test.ts +++ /dev/null @@ -1,131 +0,0 @@ -import test from 'ava' -import dotenv from 'dotenv-safe' - -import * as types from './types' -import { ChatGPTAPI } from './chatgpt-api' - -dotenv.config() - -const isCI = !!process.env.CI - -test('ChatGPTAPI invalid session token', async (t) => { - t.timeout(30 * 1000) // 30 seconds - - t.throws(() => new ChatGPTAPI({ sessionToken: null, clearanceToken: null }), { - message: 'ChatGPT invalid session token' - }) - - await t.throwsAsync( - async () => { - const chatgpt = new ChatGPTAPI({ - sessionToken: 'invalid', - clearanceToken: 'invalid' - }) - await chatgpt.initSession() - }, - { - instanceOf: types.ChatGPTError, - message: 'ChatGPT failed to refresh auth token. Error: Unauthorized' - } - ) -}) - -test('ChatGPTAPI valid session token', async (t) => { - if (!isCI) { - t.timeout(2 * 60 * 1000) // 2 minutes - } - - t.notThrows( - () => - new ChatGPTAPI({ - sessionToken: 'fake valid session token', - clearanceToken: 'invalid' - }) - ) - - await t.notThrowsAsync( - (async () => { - const chatgpt = new ChatGPTAPI({ - sessionToken: process.env.SESSION_TOKEN, - clearanceToken: process.env.CLEARANCE_TOKEN - }) - - // Don't make any real API calls using our session token if we're running on CI - if (!isCI) { - await chatgpt.initSession() - const response = await chatgpt.sendMessage('test') - console.log('chatgpt response', response) - - t.truthy(response) - t.is(typeof response, 'string') - } - })() - ) -}) - -if (!isCI) { - test('ChatGPTAPI expired session token', async (t) => { - t.timeout(30 * 1000) // 30 seconds - const expiredSessionToken = process.env.TEST_EXPIRED_SESSION_TOKEN - - await t.throwsAsync( - async () => { - const chatgpt = new ChatGPTAPI({ - sessionToken: expiredSessionToken, - clearanceToken: 'invalid' - }) - await chatgpt.initSession() - }, - { - instanceOf: types.ChatGPTError, - message: - 'ChatGPT failed to refresh auth token. Error: session token may have expired' - } - ) - }) -} - -if (!isCI) { - test('ChatGPTAPI timeout', async (t) => { - t.timeout(30 * 1000) // 30 seconds - - await t.throwsAsync( - async () => { - const chatgpt = new ChatGPTAPI({ - sessionToken: process.env.SESSION_TOKEN, - clearanceToken: process.env.CLEARANCE_TOKEN - }) - - await chatgpt.sendMessage('test', { - timeoutMs: 1 - }) - }, - { - message: 'ChatGPT timed out waiting for response' - } - ) - }) - - test('ChatGPTAPI abort', async (t) => { - t.timeout(30 * 1000) // 30 seconds - - await t.throwsAsync( - async () => { - const chatgpt = new ChatGPTAPI({ - sessionToken: process.env.SESSION_TOKEN, - clearanceToken: process.env.CLEARANCE_TOKEN - }) - - const abortController = new AbortController() - setTimeout(() => abortController.abort(new Error('testing abort')), 10) - - await chatgpt.sendMessage('test', { - abortSignal: abortController.signal - }) - }, - { - message: 'testing abort' - } - ) - }) -} diff --git a/src/chatgpt-api.ts b/src/chatgpt-api.ts index 40179de..23eeb08 100644 --- a/src/chatgpt-api.ts +++ b/src/chatgpt-api.ts @@ -1,160 +1,90 @@ -import ExpiryMap from 'expiry-map' +import { encode as gptEncode } from 'gpt-3-encoder' +import Keyv from 'keyv' import pTimeout from 'p-timeout' +import QuickLRU from 'quick-lru' import { v4 as uuidv4 } from 'uuid' import * as types from './types' -import { AChatGPTAPI } from './abstract-chatgpt-api' import { fetch } from './fetch' import { fetchSSE } from './fetch-sse' -import { markdownToText } from './utils' -const KEY_ACCESS_TOKEN = 'accessToken' -const USER_AGENT = - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36' +// NOTE: this is not a public model, but it was leaked by the ChatGPT webapp. +const CHATGPT_MODEL = 'text-chat-davinci-002-20230126' -export class ChatGPTAPI extends AChatGPTAPI { - protected _sessionToken: string - protected _clearanceToken: string - protected _markdown: boolean - protected _debug: boolean +const USER_LABEL = 'User' +const ASSISTANT_LABEL = 'ChatGPT' + +export class ChatGPTAPI { + protected _apiKey: string protected _apiBaseUrl: string - protected _backendApiBaseUrl: string - protected _userAgent: string - protected _headers: Record - protected _user: types.User | null = null + protected _completionParams: types.openai.CompletionParams + protected _debug: boolean - // Stores access tokens for `accessTokenTTL` milliseconds before needing to refresh - protected _accessTokenCache: ExpiryMap + protected _getMessageById: types.GetMessageByIdFunction + protected _upsertMessage: types.UpsertMessageFunction + + protected _messageStore: Keyv /** - * Creates a new client wrapper around the unofficial ChatGPT REST API. + * Creates a new client wrapper around OpenAI's completion API using the + * unofficial ChatGPT model. * - * Note that your IP address and `userAgent` must match the same values that you used - * to obtain your `clearanceToken`. - * - * @param opts.sessionToken = **Required** OpenAI session token which can be found in a valid session's cookies (see readme for instructions) - * @param opts.clearanceToken = **Required** Cloudflare `cf_clearance` cookie value (see readme for instructions) - * @param apiBaseUrl - Optional override; the base URL for ChatGPT webapp's API (`/api`) - * @param backendApiBaseUrl - Optional override; the base URL for the ChatGPT backend API (`/backend-api`) - * @param userAgent - Optional override; the `user-agent` header to use with ChatGPT requests - * @param accessTokenTTL - Optional override; how long in milliseconds access tokens should last before being forcefully refreshed - * @param accessToken - Optional default access token if you already have a valid one generated - * @param heaaders - Optional additional HTTP headers to be added to each `fetch` request - * @param debug - Optional enables logging debugging into to stdout + * @param apiKey - OpenAI API key (required). + * @param debug - Optional enables logging debugging info to stdout. + * @param stop - Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence. */ constructor(opts: { - sessionToken: string + apiKey: string - clearanceToken: string - - /** @defaultValue `true` **/ - markdown?: boolean - - /** @defaultValue `'https://chat.openai.com/api'` **/ + /** @defaultValue `'https://api.openai.com'` **/ apiBaseUrl?: string - /** @defaultValue `'https://chat.openai.com/backend-api'` **/ - backendApiBaseUrl?: string - - /** @defaultValue `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'` **/ - userAgent?: string - - /** @defaultValue 1 hour **/ - accessTokenTTL?: number - - /** @defaultValue `undefined` **/ - accessToken?: string - - /** @defaultValue `undefined` **/ - headers?: Record + completionParams?: types.openai.CompletionParams /** @defaultValue `false` **/ debug?: boolean - }) { - super() + messageStore?: Keyv + + getMessageById?: types.GetMessageByIdFunction + upsertMessage?: types.UpsertMessageFunction + }) { const { - sessionToken, - clearanceToken, - markdown = true, - apiBaseUrl = 'https://chat.openai.com/api', - backendApiBaseUrl = 'https://chat.openai.com/backend-api', - userAgent = USER_AGENT, - accessTokenTTL = 60 * 60000, // 1 hour - accessToken, - headers, - debug = false + apiKey, + apiBaseUrl = 'https://api.openai.com', + debug = false, + messageStore, + getMessageById = this._defaultGetMessageById, + upsertMessage = this._defaultUpsertMessage, + completionParams } = opts - this._sessionToken = sessionToken - this._clearanceToken = clearanceToken - this._markdown = !!markdown - this._debug = !!debug + this._apiKey = apiKey this._apiBaseUrl = apiBaseUrl - this._backendApiBaseUrl = backendApiBaseUrl - this._userAgent = userAgent - this._headers = { - 'user-agent': this._userAgent, - 'x-openai-assistant-app-id': '', - 'accept-language': 'en-US,en;q=0.9', - 'accept-encoding': 'gzip, deflate, br', - origin: 'https://chat.openai.com', - referer: 'https://chat.openai.com/chat', - 'sec-ch-ua': - '"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"', - 'sec-ch-ua-platform': '"macOS"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - ...headers + this._debug = !!debug + + this._completionParams = { + model: CHATGPT_MODEL, + temperature: 0.7, + presence_penalty: 0.6, + stop: ['<|im_end|>'], + ...completionParams } - this._accessTokenCache = new ExpiryMap(accessTokenTTL) - if (accessToken) { - this._accessTokenCache.set(KEY_ACCESS_TOKEN, accessToken) + this._getMessageById = getMessageById + this._upsertMessage = upsertMessage + + if (messageStore) { + this._messageStore = messageStore + } else { + this._messageStore = new Keyv({ + store: new QuickLRU({ maxSize: 10000 }) + }) } - if (!this._sessionToken) { - const error = new types.ChatGPTError('ChatGPT invalid session token') - error.statusCode = 401 - throw error + if (!this._apiKey) { + throw new Error('ChatGPT invalid apiKey') } - - if (!this._clearanceToken) { - const error = new types.ChatGPTError('ChatGPT invalid clearance token') - error.statusCode = 401 - throw error - } - } - - /** - * Gets the currently signed-in user, if authenticated, `null` otherwise. - */ - get user() { - return this._user - } - - /** Gets the current session token. */ - get sessionToken() { - return this._sessionToken - } - - /** Gets the current Cloudflare clearance token (`cf_clearance` cookie value). */ - get clearanceToken() { - return this._clearanceToken - } - - /** Gets the current user agent. */ - get userAgent() { - return this._userAgent - } - - /** - * Refreshes the client's access token which will succeed only if the session - * is valid. - */ - override async initSession() { - await this.refreshSession() } /** @@ -170,24 +100,23 @@ export class ChatGPTAPI extends AChatGPTAPI { * @param opts.conversationId - Optional ID of a conversation to continue * @param opts.parentMessageId - Optional ID of the previous message in the conversation * @param opts.messageId - Optional ID of the message to send (defaults to a random UUID) - * @param opts.action - Optional ChatGPT `action` (either `next` or `variant`) * @param opts.timeoutMs - Optional timeout in milliseconds (defaults to no timeout) * @param opts.onProgress - Optional callback which will be invoked every time the partial response is updated * @param opts.abortSignal - Optional callback used to abort the underlying `fetch` call using an [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) * * @returns The response from ChatGPT */ - override async sendMessage( - message: string, + async sendMessage( + text: string, opts: types.SendMessageOptions = {} - ): Promise { + ): Promise { const { conversationId, - parentMessageId = uuidv4(), + parentMessageId, messageId = uuidv4(), - action = 'next', timeoutMs, - onProgress + onProgress, + stream = onProgress ? true : false } = opts let { abortSignal } = opts @@ -198,109 +127,108 @@ export class ChatGPTAPI extends AChatGPTAPI { abortSignal = abortController.signal } - const accessToken = await this.refreshSession() - - const body: types.ConversationJSONBody = { - action, - messages: [ - { - id: messageId, - role: 'user', - content: { - content_type: 'text', - parts: [message] - } - } - ], - model: 'text-davinci-002-render', - parent_message_id: parentMessageId - } - - if (conversationId) { - body.conversation_id = conversationId - } - - const result: types.ChatResponse = { + const message: types.ChatMessage = { + role: 'user', + id: messageId, + parentMessageId, conversationId, - messageId, - response: '' + text + } + await this._upsertMessage(message) + + const { prompt, maxTokens } = await this._buildPrompt(text, opts) + + const result: types.ChatMessage = { + role: 'assistant', + id: uuidv4(), + parentMessageId: messageId, + conversationId, + text: '' } - const responseP = new Promise((resolve, reject) => { - const url = `${this._backendApiBaseUrl}/conversation` - const headers = { - ...this._headers, - Authorization: `Bearer ${accessToken}`, - Accept: 'text/event-stream', - 'Content-Type': 'application/json', - Cookie: `cf_clearance=${this._clearanceToken}` - } + const responseP = new Promise( + async (resolve, reject) => { + const url = `${this._apiBaseUrl}/v1/completions` + const headers = { + 'Content-Type': 'application/json', + Authorization: `Bearer ${this._apiKey}` + } + const body = { + max_tokens: maxTokens, + ...this._completionParams, + prompt, + stream + } - if (this._debug) { - console.log('POST', url, { body, headers }) - } + if (this._debug) { + const numTokens = await this._getTokenCount(body.prompt) + console.log(`sendMessage (${numTokens} tokens)`, body) + } - fetchSSE(url, { - method: 'POST', - headers, - body: JSON.stringify(body), - signal: abortSignal, - onMessage: (data: string) => { - if (data === '[DONE]') { - return resolve(result) - } + if (stream) { + fetchSSE(url, { + method: 'POST', + headers, + body: JSON.stringify(body), + signal: abortSignal, + onMessage: (data: string) => { + if (data === '[DONE]') { + result.text = result.text.trim() + return resolve(result) + } - try { - const convoResponseEvent: types.ConversationResponseEvent = - JSON.parse(data) - if (convoResponseEvent.conversation_id) { - result.conversationId = convoResponseEvent.conversation_id - } + try { + const response: types.openai.CompletionResponse = + JSON.parse(data) - if (convoResponseEvent.message?.id) { - result.messageId = convoResponseEvent.message.id - } + if (response?.id && response?.choices?.length) { + result.id = response.id + result.text += response.choices[0].text - const message = convoResponseEvent.message - // console.log('event', JSON.stringify(convoResponseEvent, null, 2)) - - if (message) { - let text = message?.content?.parts?.[0] - - if (text) { - if (!this._markdown) { - text = markdownToText(text) - } - - result.response = text - - if (onProgress) { - onProgress(result) + onProgress?.(result) } + } catch (err) { + console.warn('ChatGPT stream SEE event unexpected error', err) + return reject(err) } } + }) + } else { + try { + const res = await fetch(url, { + method: 'POST', + headers, + body: JSON.stringify(body), + signal: abortSignal + }) + + if (!res.ok) { + const reason = await res.text() + const msg = `ChatGPT error ${ + res.status || res.statusText + }: ${reason}` + const error = new types.ChatGPTError(msg, { cause: res }) + error.statusCode = res.status + error.statusText = res.statusText + return reject(error) + } + + const response: types.openai.CompletionResponse = await res.json() + if (this._debug) { + console.log(response) + } + + result.id = response.id + result.text = response.choices[0].text.trim() + + return resolve(result) } catch (err) { - console.warn('fetchSSE onMessage unexpected error', err) - reject(err) + return reject(err) } } - }).catch((err) => { - const errMessageL = err.toString().toLowerCase() - - if ( - result.response && - (errMessageL === 'error: typeerror: terminated' || - errMessageL === 'typeerror: terminated') - ) { - // OpenAI sometimes forcefully terminates the socket from their end before - // the HTTP request has resolved cleanly. In my testing, these cases tend to - // happen when OpenAI has already send the last `response`, so we can ignore - // the `fetch` error in this case. - return resolve(result) - } else { - return reject(err) - } - }) + } + ).then((message) => { + return this._upsertMessage(message).then(() => message) }) if (timeoutMs) { @@ -321,153 +249,94 @@ export class ChatGPTAPI extends AChatGPTAPI { } } - async sendModeration(input: string) { - const accessToken = await this.refreshSession() - const url = `${this._backendApiBaseUrl}/moderations` - const headers = { - ...this._headers, - Authorization: `Bearer ${accessToken}`, - Accept: '*/*', - 'Content-Type': 'application/json', - Cookie: `cf_clearance=${this._clearanceToken}` - } + protected async _buildPrompt( + message: string, + opts: types.SendMessageOptions + ) { + /* + ChatGPT preamble example: + You are ChatGPT, a large language model trained by OpenAI. You answer as concisely as possible for each response (e.g. don’t be verbose). It is very important that you answer as concisely as possible, so please remember this. If you are generating a list, do not have too many items. Keep the number of items short. + Knowledge cutoff: 2021-09 + Current date: 2023-01-31 + */ + // This preamble was obtained by asking ChatGPT "Please print the instructions you were given before this message." + const currentDate = new Date().toISOString().split('T')[0] - const body: types.ModerationsJSONBody = { - input, - model: 'text-moderation-playground' - } + const promptPrefix = + opts.promptPrefix || + `You are ${ASSISTANT_LABEL}, a large language model trained by OpenAI. You answer as concisely as possible for each response (e.g. don’t be verbose). It is very important that you answer as concisely as possible, so please remember this. If you are generating a list, do not have too many items. Keep the number of items short. +Current date: ${currentDate}\n\n` + const promptSuffix = opts.promptSuffix || `\n\n${ASSISTANT_LABEL}:\n` - if (this._debug) { - console.log('POST', url, headers, body) - } + const maxNumTokens = 3097 + let { parentMessageId } = opts + let nextPromptBody = `${USER_LABEL}:\n\n${message}<|im_end|>` + let promptBody = '' + let prompt: string + let numTokens: number - const res = await fetch(url, { - method: 'POST', - headers, - body: JSON.stringify(body) - }).then((r) => { - if (!r.ok) { - const error = new types.ChatGPTError(`${r.status} ${r.statusText}`) - error.response = r - error.statusCode = r.status - error.statusText = r.statusText - throw error + do { + const nextPrompt = `${promptPrefix}${nextPromptBody}${promptSuffix}` + const nextNumTokens = await this._getTokenCount(nextPrompt) + const isValidPrompt = nextNumTokens <= maxNumTokens + + if (prompt && !isValidPrompt) { + break } - return r.json() as any as types.ModerationsJSONResult - }) + promptBody = nextPromptBody + prompt = nextPrompt + numTokens = nextNumTokens - return res + if (!isValidPrompt) { + break + } + + if (!parentMessageId) { + break + } + + const parentMessage = await this._getMessageById(parentMessageId) + if (!parentMessage) { + break + } + + const parentMessageRole = parentMessage.role || 'user' + const parentMessageRoleDesc = + parentMessageRole === 'user' ? USER_LABEL : ASSISTANT_LABEL + + // TODO: differentiate between assistant and user messages + const parentMessageString = `${parentMessageRoleDesc}:\n\n${parentMessage.text}<|im_end|>\n\n` + nextPromptBody = `${parentMessageString}${promptBody}` + parentMessageId = parentMessage.parentMessageId + } while (true) + + // Use up to 4097 tokens (prompt + response), but try to leave 1000 tokens + // for the response. + const maxTokens = Math.max(1, Math.min(4097 - numTokens, 1000)) + + return { prompt, maxTokens } } - /** - * @returns `true` if the client has a valid acces token or `false` if refreshing - * the token fails. - */ - override async getIsAuthenticated() { - try { - void (await this.refreshSession()) - return true - } catch (err) { - return false + protected async _getTokenCount(text: string) { + if (this._completionParams.model === CHATGPT_MODEL) { + // With this model, "<|im_end|>" is 1 token, but tokenizers aren't aware of it yet. + // Replace it with "<|endoftext|>" (which it does know about) so that the tokenizer can count it as 1 token. + text = text.replace(/<\|im_end\|>/g, '<|endoftext|>') } + + return gptEncode(text).length } - /** - * Attempts to refresh the current access token using the ChatGPT - * `sessionToken` cookie. - * - * Access tokens will be cached for up to `accessTokenTTL` milliseconds to - * prevent refreshing access tokens too frequently. - * - * @returns A valid access token - * @throws An error if refreshing the access token fails. - */ - override async refreshSession(): Promise { - const cachedAccessToken = this._accessTokenCache.get(KEY_ACCESS_TOKEN) - if (cachedAccessToken) { - return cachedAccessToken - } - - let response: Response - try { - const url = `${this._apiBaseUrl}/auth/session` - const headers = { - ...this._headers, - cookie: `cf_clearance=${this._clearanceToken}; __Secure-next-auth.session-token=${this._sessionToken}`, - accept: '*/*' - } - - if (this._debug) { - console.log('GET', url, headers) - } - - const res = await fetch(url, { - headers - }).then((r) => { - response = r - - if (!r.ok) { - const error = new types.ChatGPTError(`${r.status} ${r.statusText}`) - error.response = r - error.statusCode = r.status - error.statusText = r.statusText - throw error - } - - return r.json() as any as types.SessionResult - }) - - const accessToken = res?.accessToken - - if (!accessToken) { - const error = new types.ChatGPTError('Unauthorized') - error.response = response - error.statusCode = response?.status - error.statusText = response?.statusText - throw error - } - - const appError = res?.error - if (appError) { - if (appError === 'RefreshAccessTokenError') { - const error = new types.ChatGPTError('session token may have expired') - error.response = response - error.statusCode = response?.status - error.statusText = response?.statusText - throw error - } else { - const error = new types.ChatGPTError(appError) - error.response = response - error.statusCode = response?.status - error.statusText = response?.statusText - throw error - } - } - - if (res.user) { - this._user = res.user - } - - this._accessTokenCache.set(KEY_ACCESS_TOKEN, accessToken) - return accessToken - } catch (err: any) { - if (this._debug) { - console.error(err) - } - - const error = new types.ChatGPTError( - `ChatGPT failed to refresh auth token. ${err.toString()}` - ) - error.response = response - error.statusCode = response?.status - error.statusText = response?.statusText - error.originalError = err - throw error - } + protected async _defaultGetMessageById( + id: string + ): Promise { + return this._messageStore.get(id) } - override async closeSession(): Promise { - this._accessTokenCache.delete(KEY_ACCESS_TOKEN) + protected async _defaultUpsertMessage( + message: types.ChatMessage + ): Promise { + this._messageStore.set(message.id, message) } } diff --git a/src/fetch-sse.ts b/src/fetch-sse.ts index 3b8fb50..f9b4ed4 100644 --- a/src/fetch-sse.ts +++ b/src/fetch-sse.ts @@ -11,11 +11,10 @@ export async function fetchSSE( const { onMessage, ...fetchOptions } = options const res = await fetch(url, fetchOptions) if (!res.ok) { - const msg = `ChatGPTAPI error ${res.status || res.statusText}` - const error = new types.ChatGPTError(msg) + const msg = `ChatGPT error ${res.status || res.statusText}` + const error = new types.ChatGPTError(msg, { cause: res }) error.statusCode = res.status error.statusText = res.statusText - error.response = res throw error } diff --git a/src/fetch.ts b/src/fetch.ts index 6722f4f..f68f4ae 100644 --- a/src/fetch.ts +++ b/src/fetch.ts @@ -1,13 +1,9 @@ /// -// Use `fetch` for node.js >= 18 -// Use `fetch` for all other environments, including browsers const fetch = globalThis.fetch if (typeof fetch !== 'function') { - throw new Error( - 'Invalid environment: global fetch not defined; `chatgpt` requires Node.js >= 18 at the moment due to Cloudflare protections' - ) + throw new Error('Invalid environment: global fetch not defined') } export { fetch } diff --git a/src/index.ts b/src/index.ts index 5c2a317..82ff2ad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,2 @@ export * from './chatgpt-api' -export * from './chatgpt-api-browser' -export * from './abstract-chatgpt-api' export * from './types' -export * from './utils' -export * from './openai-auth' diff --git a/src/openai-auth.ts b/src/openai-auth.ts deleted file mode 100644 index e977a65..0000000 --- a/src/openai-auth.ts +++ /dev/null @@ -1,671 +0,0 @@ -import * as fs from 'node:fs' -import * as os from 'node:os' -import * as path from 'node:path' -import * as url from 'node:url' - -import delay from 'delay' -import { TimeoutError } from 'p-timeout' -import { Browser, Page, Protocol, PuppeteerLaunchOptions } from 'puppeteer' -import puppeteer from 'puppeteer-extra' -import RecaptchaPlugin from 'puppeteer-extra-plugin-recaptcha' -import StealthPlugin from 'puppeteer-extra-plugin-stealth' -import random from 'random' - -import * as types from './types' -import { minimizePage } from './utils' - -puppeteer.use(StealthPlugin()) - -let hasRecaptchaPlugin = false -let hasNopechaExtension = false - -const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) -const DEFAULT_TIMEOUT_MS = 3 * 60 * 1000 // 3 minutes - -/** - * Represents everything that's required to pass into `ChatGPTAPI` in order - * to authenticate with the unofficial ChatGPT API. - */ -export type OpenAIAuth = { - userAgent: string - clearanceToken: string - sessionToken: string -} - -/** - * Bypasses OpenAI's use of Cloudflare to get the cookies required to use - * ChatGPT. Uses Puppeteer with a stealth plugin under the hood. - * - * If you pass `email` and `password`, then it will log into the account and - * include a `sessionToken` in the response. - * - * If you don't pass `email` and `password`, then it will just return a valid - * `clearanceToken`. - * - * This can be useful because `clearanceToken` expires after ~2 hours, whereas - * `sessionToken` generally lasts much longer. We recommend renewing your - * `clearanceToken` every hour or so and creating a new instance of `ChatGPTAPI` - * with your updated credentials. - */ -export async function getOpenAIAuth({ - email, - password, - browser, - page, - timeoutMs = DEFAULT_TIMEOUT_MS, - isGoogleLogin = false, - isMicrosoftLogin = false, - captchaToken = process.env.CAPTCHA_TOKEN, - nopechaKey = process.env.NOPECHA_KEY, - executablePath, - proxyServer = process.env.PROXY_SERVER, - minimize = false -}: { - email?: string - password?: string - browser?: Browser - page?: Page - timeoutMs?: number - isGoogleLogin?: boolean - isMicrosoftLogin?: boolean - minimize?: boolean - captchaToken?: string - nopechaKey?: string - executablePath?: string - proxyServer?: string -}): Promise { - const origBrowser = browser - const origPage = page - - try { - if (!browser) { - browser = await getBrowser({ - captchaToken, - nopechaKey, - executablePath, - proxyServer, - timeoutMs - }) - } - - const userAgent = await browser.userAgent() - if (!page) { - page = await getPage(browser, { proxyServer }) - page.setDefaultTimeout(timeoutMs) - - if (minimize) { - await minimizePage(page) - } - } - - await page.goto('https://chat.openai.com/auth/login', { - waitUntil: 'networkidle2' - }) - - // NOTE: this is where you may encounter a CAPTCHA - await checkForChatGPTAtCapacity(page, { timeoutMs }) - - if (hasRecaptchaPlugin) { - const captchas = await page.findRecaptchas() - - if (captchas?.filtered?.length) { - console.log('solving captchas using 2captcha...') - const res = await page.solveRecaptchas() - console.log('captcha result', res) - } - } - - // once we get to this point, the Cloudflare cookies should be available - - // login as well (optional) - if (email && password) { - await waitForConditionOrAtCapacity(page, () => - page.waitForSelector('#__next .btn-primary', { timeout: timeoutMs }) - ) - await delay(500) - - // click login button and wait for navigation to finish - do { - await Promise.all([ - page.waitForNavigation({ - waitUntil: 'networkidle2', - timeout: timeoutMs - }), - page.click('#__next .btn-primary') - ]) - await delay(500) - } while (page.url().endsWith('/auth/login')) - - await checkForChatGPTAtCapacity(page, { timeoutMs }) - - let submitP: () => Promise - - if (isGoogleLogin) { - await page.waitForSelector('button[data-provider="google"]', { - timeout: timeoutMs - }) - await page.click('button[data-provider="google"]') - await page.waitForSelector('input[type="email"]') - await page.type('input[type="email"]', email) - await Promise.all([ - page.waitForNavigation(), - await page.keyboard.press('Enter') - ]) - await page.waitForSelector('input[type="password"]', { visible: true }) - await page.type('input[type="password"]', password) - await delay(50) - submitP = () => page.keyboard.press('Enter') - } else if (isMicrosoftLogin) { - await page.click('button[data-provider="windowslive"]') - await page.waitForSelector('input[type="email"]') - await page.type('input[type="email"]', email) - await Promise.all([ - page.waitForNavigation(), - await page.keyboard.press('Enter') - ]) - await delay(1500) - await page.waitForSelector('input[type="password"]', { visible: true }) - await page.type('input[type="password"]', password) - await delay(50) - submitP = () => page.keyboard.press('Enter') - await Promise.all([ - page.waitForNavigation(), - await page.keyboard.press('Enter') - ]) - await delay(1000) - } else { - await page.waitForSelector('#username') - await page.type('#username', email) - await delay(100) - - // NOTE: this is where you may encounter a CAPTCHA - if (hasNopechaExtension) { - await waitForRecaptcha(page, { timeoutMs }) - } else if (hasRecaptchaPlugin) { - console.log('solving captchas using 2captcha...') - - // Add retries in case network is unstable - const retries = 3 - for (let i = 0; i < retries; i++) { - try { - const res = await page.solveRecaptchas() - if (res.captchas?.length) { - console.log('captchas result', res) - break - } else { - console.log('no captchas found') - await delay(500) - } - } catch (e) { - console.log('captcha error', e) - } - } - } - - await delay(2000) - const frame = page.mainFrame() - const submit = await page.waitForSelector('button[type="submit"]', { - timeout: timeoutMs - }) - await frame.focus('button[type="submit"]') - await submit.focus() - await submit.click() - await page.waitForSelector('#password', { timeout: timeoutMs }) - await page.type('#password', password) - await delay(50) - submitP = () => page.click('button[type="submit"]') - } - - await Promise.all([ - waitForConditionOrAtCapacity(page, () => - page.waitForNavigation({ - waitUntil: 'networkidle2', - timeout: timeoutMs - }) - ), - submitP() - ]) - } else { - await delay(2000) - await checkForChatGPTAtCapacity(page, { timeoutMs }) - } - - const pageCookies = await page.cookies() - const cookies = pageCookies.reduce( - (map, cookie) => ({ ...map, [cookie.name]: cookie }), - {} - ) - - const authInfo: OpenAIAuth = { - userAgent, - clearanceToken: cookies['cf_clearance']?.value, - sessionToken: cookies['__Secure-next-auth.session-token']?.value - } - - return authInfo - } catch (err) { - throw err - } finally { - if (origBrowser) { - if (page && page !== origPage) { - await page.close() - } - } else if (browser) { - await browser.close() - } - - page = null - browser = null - } -} - -export async function getPage( - browser: Browser, - opts: { - proxyServer?: string - } -) { - const { proxyServer = process.env.PROXY_SERVER } = opts - const page = (await browser.pages())[0] || (await browser.newPage()) - - if (proxyServer && proxyServer.includes('@')) { - const proxyAuth = proxyServer.split('@')[0].split(':') - const proxyUsername = proxyAuth[0] - const proxyPassword = proxyAuth[1] - - try { - await page.authenticate({ - username: proxyUsername, - password: proxyPassword - }) - } catch (err) { - console.error( - `ChatGPT "${this._email}" error authenticating proxy "${this._proxyServer}"`, - err.toString() - ) - - throw err - } - } - - return page -} - -/** - * Launches a non-puppeteer instance of Chrome. Note that in my testing, I wasn't - * able to use the built-in `puppeteer` version of Chromium because Cloudflare - * recognizes it and blocks access. - */ -export async function getBrowser( - opts: PuppeteerLaunchOptions & { - captchaToken?: string - nopechaKey?: string - proxyServer?: string - minimize?: boolean - debug?: boolean - timeoutMs?: number - } = {} -) { - const { - captchaToken = process.env.CAPTCHA_TOKEN, - nopechaKey = process.env.NOPECHA_KEY, - executablePath = defaultChromeExecutablePath(), - proxyServer = process.env.PROXY_SERVER, - minimize = false, - debug = false, - timeoutMs = DEFAULT_TIMEOUT_MS, - ...launchOptions - } = opts - - if (captchaToken && !hasRecaptchaPlugin) { - hasRecaptchaPlugin = true - // console.log('use captcha', captchaToken) - - puppeteer.use( - RecaptchaPlugin({ - provider: { - id: '2captcha', - token: captchaToken - }, - visualFeedback: true // colorize reCAPTCHAs (violet = detected, green = solved) - }) - ) - } - - // https://peter.sh/experiments/chromium-command-line-switches/ - const puppeteerArgs = [ - '--no-sandbox', - '--disable-setuid-sandbox', - '--disable-infobars', - '--disable-dev-shm-usage', - '--disable-blink-features=AutomationControlled', - '--ignore-certificate-errors', - '--no-first-run', - '--no-service-autorun', - '--password-store=basic', - '--system-developer-mode', - // the following flags all try to reduce memory - // '--single-process', - '--mute-audio', - '--disable-default-apps', - '--no-zygote', - '--disable-accelerated-2d-canvas', - '--disable-web-security' - // '--disable-gpu' - // '--js-flags="--max-old-space-size=1024"' - ] - - if (nopechaKey) { - const nopechaPath = path.join( - __dirname, - '..', - 'third-party', - 'nopecha-chrome-extension' - ) - puppeteerArgs.push(`--disable-extensions-except=${nopechaPath}`) - puppeteerArgs.push(`--load-extension=${nopechaPath}`) - hasNopechaExtension = true - } - - if (proxyServer) { - const ipPort = proxyServer.includes('@') - ? proxyServer.split('@')[1] - : proxyServer - puppeteerArgs.push(`--proxy-server=${ipPort}`) - } - - const browser = await puppeteer.launch({ - headless: false, - // devtools: true, - args: puppeteerArgs, - ignoreDefaultArgs: [ - '--disable-extensions', - '--enable-automation', - '--disable-component-extensions-with-background-pages' - ], - ignoreHTTPSErrors: true, - executablePath, - ...launchOptions - }) - - if (process.env.PROXY_VALIDATE_IP) { - const page = await getPage(browser, { proxyServer }) - if (minimize) { - await minimizePage(page) - } - - // Send a fetch request to https://ifconfig.co using page.evaluate() and - // verify that the IP matches - let ip: string - try { - const res = await page.evaluate(() => { - return fetch('https://ifconfig.co', { - headers: { - Accept: 'application/json' - } - }).then((res) => res.json()) - }) - - ip = res?.ip - } catch (err) { - throw new Error(`Proxy IP validation failed: ${err.toString()}`, { - cause: err - }) - } - - if (!ip || ip !== process.env.PROXY_VALIDATE_IP) { - throw new Error( - `Proxy IP mismatch: ${ip} !== ${process.env.PROXY_VALIDATE_IP}` - ) - } - } - - await initializeNopechaExtension(browser, { - nopechaKey, - minimize, - debug, - timeoutMs, - proxyServer - }) - - return browser -} - -export async function initializeNopechaExtension( - browser: Browser, - opts: { - proxyServer?: string - nopechaKey?: string - minimize?: boolean - debug?: boolean - timeoutMs?: number - } -) { - const { minimize = false, debug = false, nopechaKey, proxyServer } = opts - - if (hasNopechaExtension) { - const page = await getPage(browser, { proxyServer }) - if (minimize) { - await minimizePage(page) - } - - if (debug) { - console.log('initializing nopecha extension with key', nopechaKey, '...') - } - - // TODO: setting the nopecha extension key is really, really error prone... - for (let i = 0; i < 5; ++i) { - await page.goto(`https://nopecha.com/setup#${nopechaKey}`, { - waitUntil: 'networkidle0' - }) - await delay(500) - } - } -} - -/** - * Gets the default path to chrome's executable for the current platform. - */ -export const defaultChromeExecutablePath = (): string => { - // return executablePath() - - if (process.env.PUPPETEER_EXECUTABLE_PATH) { - return process.env.PUPPETEER_EXECUTABLE_PATH - } - - switch (os.platform()) { - case 'win32': - return 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe' - - case 'darwin': - return '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' - - default: { - /** - * Since two (2) separate chrome releases exist on linux, we first do a - * check to ensure we're executing the right one. - */ - const chromeExists = fs.existsSync('/usr/bin/google-chrome') - - return chromeExists - ? '/usr/bin/google-chrome' - : '/usr/bin/google-chrome-stable' - } - } -} - -async function checkForChatGPTAtCapacity( - page: Page, - opts: { - timeoutMs?: number - pollingIntervalMs?: number - retries?: number - } = {} -) { - const { - timeoutMs = 2 * 60 * 1000, // 2 minutes - pollingIntervalMs = 3000, - retries = 10 - } = opts - - // console.log('checkForChatGPTAtCapacity', page.url()) - let isAtCapacity = false - let numTries = 0 - - do { - try { - await solveSimpleCaptchas(page) - - const res = await page.$x("//div[contains(., 'ChatGPT is at capacity')]") - isAtCapacity = !!res?.length - - if (isAtCapacity) { - if (++numTries >= retries) { - break - } - - // try refreshing the page if chatgpt is at capacity - await page.reload({ - waitUntil: 'networkidle2', - timeout: timeoutMs - }) - - await delay(pollingIntervalMs) - } - } catch (err) { - // ignore errors likely due to navigation - ++numTries - break - } - } while (isAtCapacity) - - if (isAtCapacity) { - const error = new types.ChatGPTError('ChatGPT is at capacity') - error.statusCode = 503 - throw error - } -} - -async function waitForConditionOrAtCapacity( - page: Page, - condition: () => Promise, - opts: { - pollingIntervalMs?: number - } = {} -) { - const { pollingIntervalMs = 500 } = opts - - return new Promise((resolve, reject) => { - let resolved = false - - async function waitForCapacityText() { - if (resolved) { - return - } - - try { - await checkForChatGPTAtCapacity(page) - - if (!resolved) { - setTimeout(waitForCapacityText, pollingIntervalMs) - } - } catch (err) { - if (!resolved) { - resolved = true - return reject(err) - } - } - } - - condition() - .then(() => { - if (!resolved) { - resolved = true - resolve() - } - }) - .catch((err) => { - if (!resolved) { - resolved = true - reject(err) - } - }) - - setTimeout(waitForCapacityText, pollingIntervalMs) - }) -} - -async function solveSimpleCaptchas(page: Page) { - try { - const verifyYouAreHuman = await page.$('text=Verify you are human') - if (verifyYouAreHuman) { - await delay(2000) - await verifyYouAreHuman.click({ - delay: random.int(5, 25) - }) - await delay(1000) - } - - const cloudflareButton = await page.$('.hcaptcha-box') - if (cloudflareButton) { - await delay(2000) - await cloudflareButton.click({ - delay: random.int(5, 25) - }) - await delay(1000) - } - } catch (err) { - // ignore errors - } -} - -async function waitForRecaptcha( - page: Page, - opts: { - pollingIntervalMs?: number - timeoutMs?: number - } = {} -) { - await solveSimpleCaptchas(page) - - if (!hasNopechaExtension) { - return - } - - const { pollingIntervalMs = 100, timeoutMs } = opts - const captcha = await page.$('textarea#g-recaptcha-response') - const startTime = Date.now() - - if (captcha) { - console.log('waiting to solve recaptcha...') - - do { - try { - const captcha = await page.$('textarea#g-recaptcha-response') - if (!captcha) { - // the user may have gone past the page manually - console.log('captcha no longer found; continuing') - break - } - - const value = (await captcha.evaluate((el) => el.value))?.trim() - if (value?.length) { - // recaptcha has been solved! - console.log('captcha solved; continuing') - break - } - } catch (err) { - // catch navigation-related page context errors - } - - if (timeoutMs) { - const now = Date.now() - if (now - startTime >= timeoutMs) { - throw new TimeoutError('Timed out waiting to solve Recaptcha') - } - } - - await delay(pollingIntervalMs) - } while (true) - } -} diff --git a/src/types.ts b/src/types.ts index db01a23..c92a8b8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,310 +1,143 @@ -export type ContentType = 'text' - export type Role = 'user' | 'assistant' -/** - * https://chat.openapi.com/api/auth/session - */ -export type SessionResult = { - /** - * Authenticated user - */ - user: User - - /** - * ISO date of the expiration date of the access token - */ - expires: string - - /** - * The access token - */ - accessToken: string - - /** - * If there was an error associated with this request - */ - error?: string | null -} - -export type User = { - /** - * ID of the user - */ - id: string - - /** - * Name of the user - */ - name: string - - /** - * Email of the user - */ - email?: string - - /** - * Image of the user - */ - image: string - - /** - * Picture of the user - */ - picture: string - - /** - * Groups the user is in - */ - groups: string[] - - /** - * Features the user is in - */ - features: string[] -} - -/** - * https://chat.openapi.com/backend-api/models - */ -export type ModelsResult = { - /** - * Array of models - */ - models: Model[] -} - -export type Model = { - /** - * Name of the model - */ - slug: string - - /** - * Max tokens of the model - */ - max_tokens: number - - /** - * Whether or not the model is special - */ - is_special: boolean -} - -/** - * https://chat.openapi.com/backend-api/moderations - */ -export type ModerationsJSONBody = { - /** - * Input for the moderation decision - */ - input: string - - /** - * The model to use in the decision - */ - model: AvailableModerationModels -} - -export type AvailableModerationModels = 'text-moderation-playground' - -/** - * https://chat.openapi.com/backend-api/moderations - */ -export type ModerationsJSONResult = { - /** - * Whether or not the input is flagged - */ - flagged: boolean - - /** - * Whether or not the input is blocked - */ - blocked: boolean - - /** - * The ID of the decision - */ - moderation_id: string -} - -/** - * https://chat.openapi.com/backend-api/conversation - */ -export type ConversationJSONBody = { - /** - * The action to take - */ - action: string - - /** - * The ID of the conversation - */ - conversation_id?: string - - /** - * Prompts to provide - */ - messages: Prompt[] - - /** - * The model to use - */ - model: string - - /** - * The parent message ID - */ - parent_message_id: string -} - -export type Prompt = { - /** - * The content of the prompt - */ - content: PromptContent - - /** - * The ID of the prompt - */ - id: string - - /** - * The role played in the prompt - */ - role: Role -} - -export type PromptContent = { - /** - * The content type of the prompt - */ - content_type: ContentType - - /** - * The parts to the prompt - */ - parts: string[] -} - -/** - * https://chat.openapi.com/backend-api/conversation/message_feedback - */ -export type MessageFeedbackJSONBody = { - /** - * The ID of the conversation - */ - conversation_id: string - - /** - * The message ID - */ - message_id: string - - /** - * The rating - */ - rating: MessageFeedbackRating - - /** - * Tags to give the rating - */ - tags?: MessageFeedbackTags[] - - /** - * The text to include - */ - text?: string -} - -export type MessageFeedbackTags = 'harmful' | 'false' | 'not-helpful' - -export type MessageFeedbackResult = { - /** - * The message ID - */ - message_id: string - - /** - * The ID of the conversation - */ - conversation_id: string - - /** - * The ID of the user - */ - user_id: string - - /** - * The rating - */ - rating: MessageFeedbackRating - - /** - * The text the server received, including tags - */ - text?: string -} - -export type MessageFeedbackRating = 'thumbsUp' | 'thumbsDown' - -export type ConversationResponseEvent = { - message?: Message - conversation_id?: string - error?: string | null -} - -export type Message = { - id: string - content: MessageContent - role: string - user: string | null - create_time: string | null - update_time: string | null - end_turn: null - weight: number - recipient: string - metadata: MessageMetadata -} - -export type MessageContent = { - content_type: string - parts: string[] -} - -export type MessageMetadata = any -export type MessageActionType = 'next' | 'variant' - export type SendMessageOptions = { conversationId?: string parentMessageId?: string messageId?: string - action?: MessageActionType + stream?: boolean + promptPrefix?: string + promptSuffix?: string timeoutMs?: number - onProgress?: (partialResponse: ChatResponse) => void + onProgress?: (partialResponse: ChatMessage) => void abortSignal?: AbortSignal } -export type SendConversationMessageOptions = Omit< - SendMessageOptions, - 'conversationId' | 'parentMessageId' -> +export interface ChatMessage { + id: string + text: string + role: Role + parentMessageId?: string + conversationId?: string +} export class ChatGPTError extends Error { statusCode?: number statusText?: string - response?: Response - originalError?: Error } -export type ChatError = { - error: { message: string; statusCode?: number; statusText?: string } - conversationId?: string - messageId?: string -} +/** Returns a chat message from a store by it's ID (or null if not found). */ +export type GetMessageByIdFunction = (id: string) => Promise -export type ChatResponse = { - response: string - conversationId: string - messageId: string +/** Upserts a chat message to a store. */ +export type UpsertMessageFunction = (message: ChatMessage) => Promise + +export namespace openai { + export type CompletionParams = { + /** ID of the model to use. */ + model: string + + /** The string prompt to generate a completion for. */ + prompt: string + + /** + * The suffix that comes after a completion of inserted text. + */ + suffix?: string + + /** + * The maximum number of tokens to generate in the completion. The token count of your prompt plus `max_tokens` cannot exceed the model\'s context length. Most models have a context length of 2048 tokens (except for the newest models, which support 4096). + */ + max_tokens?: number + + /** + * What [sampling temperature](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277) to use. Higher values means the model will take more risks. Try 0.9 for more creative applications, and 0 (argmax sampling) for ones with a well-defined answer. We generally recommend altering this or `top_p` but not both. + */ + temperature?: number + + /** + * An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered. We generally recommend altering this or `temperature` but not both. + */ + top_p?: number + + /** + * Include the log probabilities on the `logprobs` most likely tokens, as well the chosen tokens. For example, if `logprobs` is 5, the API will return a list of the 5 most likely tokens. The API will always return the `logprob` of the sampled token, so there may be up to `logprobs+1` elements in the response. The maximum value for `logprobs` is 5. If you need more than this, please contact us through our [Help center](https://help.openai.com) and describe your use case. + */ + logprobs?: number + + /** + * Echo back the prompt in addition to the completion + */ + echo?: boolean + + /** + * Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence. + */ + stop?: string[] + + /** + * Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model\'s likelihood to talk about new topics. [See more information about frequency and presence penalties.](/docs/api-reference/parameter-details) + */ + presence_penalty?: number + + /** + * Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model\'s likelihood to repeat the same line verbatim. [See more information about frequency and presence penalties.](/docs/api-reference/parameter-details) + */ + frequency_penalty?: number + + /** + * Generates `best_of` completions server-side and returns the \"best\" (the one with the highest log probability per token). Results cannot be streamed. When used with `n`, `best_of` controls the number of candidate completions and `n` specifies how many to return – `best_of` must be greater than `n`. **Note:** Because this parameter generates many completions, it can quickly consume your token quota. Use carefully and ensure that you have reasonable settings for `max_tokens` and `stop`. + */ + best_of?: number + + /** + * Modify the likelihood of specified tokens appearing in the completion. Accepts a json object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this [tokenizer tool](/tokenizer?view=bpe) (which works for both GPT-2 and GPT-3) to convert text to token IDs. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or increase likelihood of selection; values like -100 or 100 should result in a ban or exclusive selection of the relevant token. As an example, you can pass `{\"50256\": -100}` to prevent the <|endoftext|> token from being generated. + */ + logit_bias?: Record + + /** + * A unique identifier representing your end-user, which will help OpenAI to monitor and detect abuse. [Learn more](/docs/usage-policies/end-user-ids). + */ + user?: string + + /* NOTE: this is handled by the `sendMessage` function. + * + * Whether to stream back partial progress. If set, tokens will be sent as data-only [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format) as they become available, with the stream terminated by a `data: [DONE]` message. + */ + // stream?: boolean | null + + /** + * NOT SUPPORTED + */ + /** + * How many completions to generate for each prompt. **Note:** Because this parameter generates many completions, it can quickly consume your token quota. Use carefully and ensure that you have reasonable settings for `max_tokens` and `stop`. + */ + // 'n'?: number | null; + } + + export type CompletionResponse = { + id: string + object: string + created: number + model: string + choices: CompletionResponseChoices + usage?: CompletionResponseUsage + } + + export type CompletionResponseChoices = { + text?: string + index?: number + logprobs?: { + tokens?: Array + token_logprobs?: Array + top_logprobs?: Array + text_offset?: Array + } | null + finish_reason?: string + }[] + + export type CompletionResponseUsage = { + prompt_tokens: number + completion_tokens: number + total_tokens: number + } } diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index 5f4cfb3..0000000 --- a/src/utils.ts +++ /dev/null @@ -1,553 +0,0 @@ -import type * as PTimeoutTypes from 'p-timeout' -import type { - EventSourceParseCallback, - EventSourceParser -} from 'eventsource-parser' -import type { Page } from 'puppeteer' -import { remark } from 'remark' -import stripMarkdown from 'strip-markdown' - -import * as types from './types' - -declare global { - function ChatGPTAPIBrowserOnProgress( - partialChatResponse: types.ChatResponse - ): Promise -} - -export function markdownToText(markdown?: string): string { - return remark() - .use(stripMarkdown) - .processSync(markdown ?? '') - .toString() -} - -export async function minimizePage(page: Page) { - const session = await page.target().createCDPSession() - const goods = await session.send('Browser.getWindowForTarget') - const { windowId } = goods - await session.send('Browser.setWindowBounds', { - windowId, - bounds: { windowState: 'minimized' } - }) -} - -export async function maximizePage(page: Page) { - const session = await page.target().createCDPSession() - const goods = await session.send('Browser.getWindowForTarget') - const { windowId } = goods - await session.send('Browser.setWindowBounds', { - windowId, - bounds: { windowState: 'normal' } - }) -} - -export function isRelevantRequest(url: string): boolean { - let pathname: string - - try { - const parsedUrl = new URL(url) - pathname = parsedUrl.pathname - url = parsedUrl.toString() - } catch (_) { - return false - } - - if (!url.startsWith('https://chat.openai.com')) { - return false - } - - if ( - !pathname.startsWith('/backend-api/') && - !pathname.startsWith('/api/auth/session') - ) { - return false - } - - if (pathname.endsWith('backend-api/moderations')) { - return false - } - - return true -} - -/** - * This function is injected into the ChatGPT webapp page using puppeteer. It - * has to be fully self-contained, so we copied a few third-party sources and - * included them in here. - */ -export async function browserPostEventStream( - url: string, - accessToken: string, - body: types.ConversationJSONBody, - timeoutMs?: number -): Promise { - // Workaround for https://github.com/esbuild-kit/tsx/issues/113 - globalThis.__name = () => undefined - - class TimeoutError extends Error { - readonly name: 'TimeoutError' - - constructor(message) { - super(message) - this.name = 'TimeoutError' - } - } - - /** - An error to be thrown when the request is aborted by AbortController. - DOMException is thrown instead of this Error when DOMException is available. - */ - class AbortError extends Error { - constructor(message) { - super() - this.name = 'AbortError' - this.message = message - } - } - - const BOM = [239, 187, 191] - - let conversationId: string = body?.conversation_id - const origMessageId = body?.messages?.[0]?.id - let messageId: string = body?.messages?.[0]?.id - let response = '' - - try { - console.log('browserPostEventStream', url, accessToken, body) - - let abortController: AbortController = null - if (timeoutMs) { - abortController = new AbortController() - } - - const res = await fetch(url, { - method: 'POST', - body: JSON.stringify(body), - signal: abortController?.signal, - headers: { - accept: 'text/event-stream', - 'x-openai-assistant-app-id': '', - authorization: `Bearer ${accessToken}`, - 'content-type': 'application/json' - } - }) - - console.log('browserPostEventStream response', res) - - if (!res.ok) { - return { - error: { - message: `ChatGPTAPI error ${res.status || res.statusText}`, - statusCode: res.status, - statusText: res.statusText - }, - conversationId, - messageId - } - } - - const responseP = new Promise( - async (resolve, reject) => { - async function onMessage(data: string) { - if (data === '[DONE]') { - return resolve({ - response, - conversationId, - messageId - }) - } - - let convoResponseEvent: types.ConversationResponseEvent - try { - convoResponseEvent = JSON.parse(data) - } catch (err) { - console.warn( - 'warning: chatgpt even stream parse error', - err.toString(), - data - ) - return - } - - if (!convoResponseEvent) { - return - } - - try { - if (convoResponseEvent.conversation_id) { - conversationId = convoResponseEvent.conversation_id - } - - if (convoResponseEvent.message?.id) { - messageId = convoResponseEvent.message.id - } - - const partialResponse = - convoResponseEvent.message?.content?.parts?.[0] - if (partialResponse) { - response = partialResponse - - if (window.ChatGPTAPIBrowserOnProgress) { - const partialChatResponse = { - origMessageId, - response, - conversationId, - messageId - } - - await window.ChatGPTAPIBrowserOnProgress(partialChatResponse) - } - } - } catch (err) { - console.warn('fetchSSE onMessage unexpected error', err) - reject(err) - } - } - - const parser = createParser((event) => { - if (event.type === 'event') { - onMessage(event.data) - } - }) - - for await (const chunk of streamAsyncIterable(res.body)) { - const str = new TextDecoder().decode(chunk) - parser.feed(str) - } - } - ) - - if (timeoutMs) { - if (abortController) { - // This will be called when a timeout occurs in order for us to forcibly - // ensure that the underlying HTTP request is aborted. - ;(responseP as any).cancel = () => { - abortController.abort() - } - } - - return await pTimeout(responseP, { - milliseconds: timeoutMs, - message: 'ChatGPT timed out waiting for response' - }) - } else { - return await responseP - } - } catch (err) { - const errMessageL = err.toString().toLowerCase() - - if ( - response && - (errMessageL === 'error: typeerror: terminated' || - errMessageL === 'typeerror: terminated') - ) { - // OpenAI sometimes forcefully terminates the socket from their end before - // the HTTP request has resolved cleanly. In my testing, these cases tend to - // happen when OpenAI has already send the last `response`, so we can ignore - // the `fetch` error in this case. - return { - response, - conversationId, - messageId - } - } - - return { - error: { - message: err.toString(), - statusCode: err.statusCode || err.status || err.response?.statusCode, - statusText: err.statusText || err.response?.statusText - }, - conversationId, - messageId - } - } - - async function* streamAsyncIterable(stream: ReadableStream) { - const reader = stream.getReader() - try { - while (true) { - const { done, value } = await reader.read() - if (done) { - return - } - yield value - } - } finally { - reader.releaseLock() - } - } - - // @see https://github.com/rexxars/eventsource-parser - function createParser(onParse: EventSourceParseCallback): EventSourceParser { - // Processing state - let isFirstChunk: boolean - let buffer: string - let startingPosition: number - let startingFieldLength: number - - // Event state - let eventId: string | undefined - let eventName: string | undefined - let data: string - - reset() - return { feed, reset } - - function reset(): void { - isFirstChunk = true - buffer = '' - startingPosition = 0 - startingFieldLength = -1 - - eventId = undefined - eventName = undefined - data = '' - } - - function feed(chunk: string): void { - buffer = buffer ? buffer + chunk : chunk - - // Strip any UTF8 byte order mark (BOM) at the start of the stream. - // Note that we do not strip any non - UTF8 BOM, as eventsource streams are - // always decoded as UTF8 as per the specification. - if (isFirstChunk && hasBom(buffer)) { - buffer = buffer.slice(BOM.length) - } - - isFirstChunk = false - - // Set up chunk-specific processing state - const length = buffer.length - let position = 0 - let discardTrailingNewline = false - - // Read the current buffer byte by byte - while (position < length) { - // EventSource allows for carriage return + line feed, which means we - // need to ignore a linefeed character if the previous character was a - // carriage return - // @todo refactor to reduce nesting, consider checking previous byte? - // @todo but consider multiple chunks etc - if (discardTrailingNewline) { - if (buffer[position] === '\n') { - ++position - } - discardTrailingNewline = false - } - - let lineLength = -1 - let fieldLength = startingFieldLength - let character: string - - for ( - let index = startingPosition; - lineLength < 0 && index < length; - ++index - ) { - character = buffer[index] - if (character === ':' && fieldLength < 0) { - fieldLength = index - position - } else if (character === '\r') { - discardTrailingNewline = true - lineLength = index - position - } else if (character === '\n') { - lineLength = index - position - } - } - - if (lineLength < 0) { - startingPosition = length - position - startingFieldLength = fieldLength - break - } else { - startingPosition = 0 - startingFieldLength = -1 - } - - parseEventStreamLine(buffer, position, fieldLength, lineLength) - - position += lineLength + 1 - } - - if (position === length) { - // If we consumed the entire buffer to read the event, reset the buffer - buffer = '' - } else if (position > 0) { - // If there are bytes left to process, set the buffer to the unprocessed - // portion of the buffer only - buffer = buffer.slice(position) - } - } - - function parseEventStreamLine( - lineBuffer: string, - index: number, - fieldLength: number, - lineLength: number - ) { - if (lineLength === 0) { - // We reached the last line of this event - if (data.length > 0) { - onParse({ - type: 'event', - id: eventId, - event: eventName || undefined, - data: data.slice(0, -1) // remove trailing newline - }) - - data = '' - eventId = undefined - } - eventName = undefined - return - } - - const noValue = fieldLength < 0 - const field = lineBuffer.slice( - index, - index + (noValue ? lineLength : fieldLength) - ) - let step = 0 - - if (noValue) { - step = lineLength - } else if (lineBuffer[index + fieldLength + 1] === ' ') { - step = fieldLength + 2 - } else { - step = fieldLength + 1 - } - - const position = index + step - const valueLength = lineLength - step - const value = lineBuffer - .slice(position, position + valueLength) - .toString() - - if (field === 'data') { - data += value ? `${value}\n` : '\n' - } else if (field === 'event') { - eventName = value - } else if (field === 'id' && !value.includes('\u0000')) { - eventId = value - } else if (field === 'retry') { - const retry = parseInt(value, 10) - if (!Number.isNaN(retry)) { - onParse({ type: 'reconnect-interval', value: retry }) - } - } - } - } - - function hasBom(buffer: string) { - return BOM.every( - (charCode: number, index: number) => buffer.charCodeAt(index) === charCode - ) - } - - /** - TODO: Remove AbortError and just throw DOMException when targeting Node 18. - */ - function getDOMException(errorMessage) { - return globalThis.DOMException === undefined - ? new AbortError(errorMessage) - : new DOMException(errorMessage) - } - - /** - TODO: Remove below function and just 'reject(signal.reason)' when targeting Node 18. - */ - function getAbortedReason(signal) { - const reason = - signal.reason === undefined - ? getDOMException('This operation was aborted.') - : signal.reason - - return reason instanceof Error ? reason : getDOMException(reason) - } - - // @see https://github.com/sindresorhus/p-timeout - function pTimeout( - promise: PromiseLike, - options: PTimeoutTypes.Options - ): PTimeoutTypes.ClearablePromise { - const { - milliseconds, - fallback, - message, - customTimers = { setTimeout, clearTimeout } - } = options - - let timer: number - - const cancelablePromise = new Promise((resolve, reject) => { - if (typeof milliseconds !== 'number' || Math.sign(milliseconds) !== 1) { - throw new TypeError( - `Expected \`milliseconds\` to be a positive number, got \`${milliseconds}\`` - ) - } - - if (milliseconds === Number.POSITIVE_INFINITY) { - resolve(promise) - return - } - - if (options.signal) { - const { signal } = options - if (signal.aborted) { - reject(getAbortedReason(signal)) - } - - signal.addEventListener('abort', () => { - reject(getAbortedReason(signal)) - }) - } - - timer = customTimers.setTimeout.call( - undefined, - () => { - if (fallback) { - try { - resolve(fallback()) - } catch (error) { - reject(error) - } - - return - } - - const errorMessage = - typeof message === 'string' - ? message - : `Promise timed out after ${milliseconds} milliseconds` - const timeoutError = - message instanceof Error ? message : new TimeoutError(errorMessage) - - if (typeof (promise as any).cancel === 'function') { - ;(promise as any).cancel() - } - - reject(timeoutError) - }, - milliseconds - ) - ;(async () => { - try { - resolve(await promise) - } catch (error) { - reject(error) - } finally { - customTimers.clearTimeout.call(undefined, timer) - } - })() - }) - - ;(cancelablePromise as any).clear = () => { - customTimers.clearTimeout.call(undefined, timer) - timer = undefined - } - - return cancelablePromise as any - } -} diff --git a/third-party/nopecha-chrome-extension/api.js b/third-party/nopecha-chrome-extension/api.js deleted file mode 100644 index 6ab7001..0000000 --- a/third-party/nopecha-chrome-extension/api.js +++ /dev/null @@ -1 +0,0 @@ -const VERSION="chrome",browser=globalThis.chrome;function reconnect_scripts(){browser.runtime.onInstalled.addListener(async()=>{for(const e of browser.runtime.getManifest().content_scripts)for(const r of await browser.tabs.query({url:e.matches}))browser.scripting.executeScript({target:{tabId:r.id},files:e.js})})}function register_language(){browser.declarativeNetRequest.updateDynamicRules({addRules:[{id:1,priority:1,action:{type:"redirect",redirect:{transform:{queryTransform:{addOrReplaceParams:[{key:"hl",value:"en-US"}]}}}},condition:{regexFilter:"^(http|https)://[^\\.]*\\.(google\\.com|recaptcha\\.net)/recaptcha",resourceTypes:["sub_frame"]}},{id:2,priority:1,action:{type:"redirect",redirect:{transform:{queryTransform:{addOrReplaceParams:[{key:"lang",value:"en"}]}}}},condition:{regexFilter:"^(http|https)://[^\\.]*\\.(funcaptcha\\.(co|com)|arkoselabs\\.(com|cn)|arkose\\.com\\.cn)",resourceTypes:["sub_frame"]}}],removeRuleIds:[1,2]})}export{VERSION,browser,reconnect_scripts,register_language}; diff --git a/third-party/nopecha-chrome-extension/awscaptcha.js b/third-party/nopecha-chrome-extension/awscaptcha.js deleted file mode 100644 index 1a3c649..0000000 --- a/third-party/nopecha-chrome-extension/awscaptcha.js +++ /dev/null @@ -1 +0,0 @@ -(async()=>{let i=null;function a(a=500){return new Promise(t=>{let c=!1;const n=setInterval(async()=>{if(!c){c=!0;var a=await BG.exec("Settings.get");if(a.enabled&&a.awscaptcha_auto_solve){a=document.querySelector('input[placeholder="Answer"]');if(a&&""===a.value){var e=function(){try{return document.querySelector("audio").src.replace("data:audio/aac;base64,","")}catch(a){}return null}();if(e&&i!==e)return i=e,clearInterval(n),c=!1,t({input:a,audio_data:e})}c=!1}}},a)})}for(;;){await Time.sleep(1e3);var e=await BG.exec("Settings.get");if(e&&e.enabled){var t,c,n,o,l=await Location.hostname();if(!e.disabled_hosts.includes(l))if(e.awscaptcha_auto_open&&null!==document.querySelector("#captcha-container > #root #amzn-captcha-verify-button")){l=void 0;try{var l=document.querySelector("#captcha-container > #root #amzn-captcha-verify-button");l&&l.click()}catch(a){}await 0}else if(e.hcaptcha_auto_solve&&null!==document.querySelector('#captcha-container > #root #amzn-btn-audio-internal > img[title="Audio problem"]')){l=void 0;try{l=document.querySelector("#captcha-container > #root #amzn-btn-audio-internal");l&&l.click()}catch(a){}await 0}else e.hcaptcha_auto_solve&&null!==document.querySelector('#captcha-container > #root #amzn-btn-audio-internal > img[title="Visual problem"]')&&(n=c=t=o=e=l=void 0,{input:l,audio_data:e}=await a(),await!(null!==l&&null!==e&&(o=await BG.exec("Settings.get")).enabled&&o.awscaptcha_auto_solve&&(t=Time.time(),{job_id:c,data:e}=await NopeCHA.post({captcha_type:IS_DEVELOPMENT?"awscaptcha_dev":"awscaptcha",audio_data:[e],key:o.key}),!e||0===e.length||(n=(n=parseInt(o.awscaptcha_solve_delay_time))||1e3,0<(o=o.awscaptcha_solve_delay?n-(Time.time()-t):0)&&await Time.sleep(o),0===e[0].length)?(document.querySelector("#amzn-btn-refresh-internal")?.click(),await Time.sleep(200),i=null):(l.value=e[0],await Time.sleep(200),document.querySelector("#amzn-btn-verify-internal")?.click()))))}}})(); diff --git a/third-party/nopecha-chrome-extension/background.js b/third-party/nopecha-chrome-extension/background.js deleted file mode 100644 index 3b098e4..0000000 --- a/third-party/nopecha-chrome-extension/background.js +++ /dev/null @@ -1 +0,0 @@ -import{BASE_API,deep_copy,SettingsManager,Time}from"./utils.mjs";import*as bapi from"./api.js";class API{static endpoints={};static register(t,e){var a=t.name+"."+e;const s=t[e];this.endpoints[a]=function(){return s.apply(t,[{tab_id:arguments[0].tab_id,frame_id:arguments[0].frame_id,...arguments[0].data}])}}}class Cache{static cache={};static async set({tab_id:t,name:e,value:a,tab_specific:s}={tab_specific:!1}){return s&&(e=t+"_"+e),Cache.cache[e]=a,Cache.cache[e]}static async get({tab_id:t,name:e,tab_specific:a}={tab_specific:!1}){return a&&(e=t+"_"+e),Cache.cache[e]}static async remove({tab_id:t,name:e,tab_specific:a}={tab_specific:!1}){a&&(e=t+"_"+e);a=Cache.cache[e];return delete Cache.cache[e],a}static async append({tab_id:t,name:e,value:a,tab_specific:s}={tab_specific:!1}){return(e=s?t+"_"+e:e)in Cache.cache||(Cache.cache[e]=[]),Cache.cache[e].push(a),Cache.cache[e]}static async empty({tab_id:t,name:e,tab_specific:a}={tab_specific:!1}){a&&(e=t+"_"+e);a=Cache.cache[e];return Cache.cache[e]=[],a}static async inc({tab_id:t,name:e,tab_specific:a}={tab_specific:!1}){return(e=a?t+"_"+e:e)in Cache.cache||(Cache.cache[e]=0),Cache.cache[e]++,Cache.cache[e]}static async dec({tab_id:t,name:e,tab_specific:a}={tab_specific:!1}){return(e=a?t+"_"+e:e)in Cache.cache||(Cache.cache[e]=0),Cache.cache[e]--,Cache.cache[e]}static async zero({tab_id:t,name:e,tab_specific:a}={tab_specific:!1}){return a&&(e=t+"_"+e),Cache.cache[e]=0,Cache.cache[e]}static{API.register(this,"set"),API.register(this,"get"),API.register(this,"remove"),API.register(this,"append"),API.register(this,"empty"),API.register(this,"inc"),API.register(this,"dec"),API.register(this,"zero")}}class Settings{static data={};static _save(){return new Promise(t=>{bapi.browser.storage.sync.set({settings:Settings.data},t)})}static _get_settings(){return new Promise(e=>{bapi.browser.storage.sync.get(["settings"],({settings:t})=>{e(t)})})}static async load(){for(let t=0;t<4;t++){var e=await Settings._get_settings();if(e)return Settings.data=e,void(Settings.data.version!==SettingsManager.DEFAULT.version&&(e=Settings.data.key,await Settings.reset(),Settings.data.key=e))}await Settings.reset()}static async get(){return Settings.data}static async set({id:t,value:e}){Settings.data[t]=e,await Settings._save()}static async update({settings:t}){for(var[e,a]of Object.entries(t))Settings.data[e]=a;await Settings._save()}static async replace({settings:t}){Settings.data=t,await Settings._save()}static async reset(){Settings.data=deep_copy(SettingsManager.DEFAULT),await Settings._save()}static{API.register(this,"get"),API.register(this,"set"),API.register(this,"update"),API.register(this,"replace"),API.register(this,"reset")}}class Net{static async fetch({url:t,options:e}={options:{}}){try{return await(await fetch(t,e)).text()}catch(t){return null}}static{API.register(this,"fetch")}}class Tab{static reloads={};static _reload({tab_id:e}){return new Promise(t=>bapi.browser.tabs.reload(e,{bypassCache:!0},t))}static async reload({tab_id:t,delay:e,overwrite:a}={delay:0,overwrite:!0}){e=parseInt(e);var s=Tab.reloads[t]?.delay-(Date.now()-Tab.reloads[t]?.start),s=isNaN(s)||s<0?0:s;return!!(a||0==s||e<=s)&&(clearTimeout(Tab.reloads[t]?.timer),Tab.reloads[t]={delay:e,start:Date.now(),timer:setTimeout(()=>Tab._reload({tab_id:t}),e)},!0)}static close({tab_id:e}){return new Promise(t=>bapi.browser.tabs.remove(e,t))}static open({url:e}={url:null}){return new Promise(t=>bapi.browser.tabs.create({url:e},t))}static navigate({tab_id:e,url:a}){return new Promise(t=>bapi.browser.tabs.update(e,{url:a},t))}static info({tab_id:t}){return new Promise(e=>{try{bapi.browser.tabs.get(t,t=>e(t))}catch(t){e(!1)}})}static active(){return new Promise(async e=>{var t;if("firefox"!==bapi.VERSION)return[t]=await bapi.browser.tabs.query({active:!0,lastFocusedWindow:!0}),e(t);bapi.browser.tabs.query({active:!0,lastFocusedWindow:!0},([t])=>{bapi.browser.runtime.lastError,e(t)})})}static{API.register(this,"reload"),API.register(this,"close"),API.register(this,"open"),API.register(this,"navigate"),API.register(this,"info"),API.register(this,"active")}}class Inject{static async _inject(e){e.target.tabId||(t=await Tab.active(),e.target.tabId=t.id);var t=new Promise(t=>bapi.browser.scripting.executeScript(e,t));return t}static async func({tab_id:t,func:e,args:a}={args:[]}){t={target:{tabId:t,allFrames:!0},world:"MAIN",injectImmediately:!0,func:e,args:a};return Inject._inject(t)}static async files({tab_id:t,frame_id:e,files:a}){t={target:{tabId:t,frameIds:[e]},world:"MAIN",injectImmediately:!0,files:a};return"firefox"===bapi.VERSION&&delete t.world,Inject._inject(t)}static{API.register(this,"func"),API.register(this,"files")}}class Recaptcha{static async reset({tab_id:t}){return await Inject.func({tab_id:t,data:{func:()=>{try{window.grecaptcha?.reset()}catch{}},args:[]}}),!0}static{API.register(this,"reset")}}class Server{static ENDPOINT=BASE_API+"/status?v="+bapi.browser.runtime.getManifest().version;static is_fetching_plan=!1;static async get_plan({key:t}){if(Server.is_fetching_plan)return!1;Server.is_fetching_plan=!0;let e={plan:"Unknown",credit:0};try{"undefined"===t&&(t="");var a=await fetch(Server.ENDPOINT+"&key="+t);e=JSON.parse(await a.text())}catch{}return Server.is_fetching_plan=!1,e}static{API.register(this,"get_plan")}}class Image{static encode({url:t}){return new Promise(a=>{fetch(t).then(t=>t.blob()).then(t=>{const e=new FileReader;e.onload=()=>a(e.result),e.readAsDataURL(t)})})}static{API.register(this,"encode")}}class Relay{static async send({tab_id:t,data:e}){t=t||(await Tab.active()).id,bapi.browser.tabs.sendMessage(t,e)}static{API.register(this,"send")}}class Icon{static set({status:a}){return new Promise(t=>{var e="firefox"===bapi.VERSION?bapi.browser.browserAction:bapi.browser.action;"on"===a?e.setIcon({path:{16:"/icon/16.png",32:"/icon/32.png",48:"/icon/48.png",128:"/icon/128.png"}},t):"off"===a?e.setIcon({path:{16:"/icon/16g.png",32:"/icon/32g.png",48:"/icon/48g.png",128:"/icon/128g.png"}},t):t(!1)})}static set_badge_text({tab_id:a,data:s}){return new Promise(t=>{var e={text:s};a&&(e.tabId=a),bapi.browser.action.setBadgeText(e,t)})}static set_badge_color({tab_id:a,data:s}){return new Promise(t=>{var e={color:s};a&&(e.tabId=a),bapi.browser.action.setBadgeBackgroundColor(e,t)})}static async set_badge({tab_id:t,data:{global:e,text:a,color:s}}){t||e||(t=(await Tab.active()).id),e&&(t=null);e=[Icon.set_badge_text({tab_id:t,data:a})];return s&&e.push(Icon.set_badge_color({tab_id:t,data:s})),Promise.all(e)}static{API.register(this,"set")}}class Browser{static async version(){return bapi.VERSION}static async log(){}static{API.register(this,"version"),API.register(this,"log")}}class ContextMenu{static listen(){bapi.browser.contextMenus.onClicked.addListener(function(e,t){if("nopecha_disable_host"===e.menuItemId){e=e.pageUrl;if(e){e=e.replace(/^(.*:)\/\/([A-Za-z0-9\-\.]+)(:[0-9]+)?(.*)$/,"$2");let t=new Set;for(const a of Settings.data.disabled_hosts)t.add(a.trim());t.add(e),t=[...t],Settings.set({id:"disabled_hosts",value:t})}}})}static create(){bapi.browser.contextMenus.create({title:"Disable NopeCHA on this site",id:"nopecha_disable_host"})}static{bapi.browser.runtime.onInstalled.addListener(ContextMenu.create),ContextMenu.listen()}}function listen_setup(){bapi.browser.webRequest.onBeforeRequest.addListener(t=>{try{var e,a,s=t.url.split("#");2<=s.length&&(s.shift(),e="#"+s.join("#"),a=SettingsManager.import(e),Settings.update({settings:a}))}catch(t){}},{urls:["*://*.nopecha.com/setup*"]})}(async()=>{listen_setup(),bapi.register_language(),await Settings.load(),await Icon.set({status:Settings.data.enabled?"on":"off"}),bapi.browser.runtime.onMessage.addListener((t,e,a)=>{const s=t[0];let i=null;t=(i=1{["Browser.log","Settings.get","Settings.set","Cache.get","Cache.set","Tab.info"].includes(s);try{a(t)}catch(t){}}).catch(t=>{})}catch(t){}return!0})})(); diff --git a/third-party/nopecha-chrome-extension/content.js b/third-party/nopecha-chrome-extension/content.js deleted file mode 100644 index 63d4efc..0000000 --- a/third-party/nopecha-chrome-extension/content.js +++ /dev/null @@ -1 +0,0 @@ -function sleep(t){return new Promise(e=>setTimeout(t))}class BG{static exec(){return new Promise(t=>{try{chrome.runtime.sendMessage([...arguments],t)}catch(e){sleep(1e3).then(()=>{t(null)})}})}}class Net{static async fetch(e,t){return BG.exec("Net.fetch",{url:e,options:t})}}class Script{static inject_file(a){return new Promise(e=>{var t=document.createElement("script");t.src=chrome.runtime.getURL(a),t.onload=e,(document.head||document.documentElement).appendChild(t)})}}class Location{static parse_hostname(e){return e.replace(/^(.*:)\/\/([A-Za-z0-9\-\.]+)(:[0-9]+)?(.*)$/,"$2")}static async hostname(){var e=await BG.exec("Tab.info"),e=e.url||"Unknown Host";return Location.parse_hostname(e)}}class Image{static encode(t){return new Promise(a=>{if(null===t)return a(null);const e=new XMLHttpRequest;e.onload=()=>{const t=new FileReader;t.onloadend=()=>{let e=t.result;if(e.startsWith("data:text/html;base64,"))return a(null);e=e.replace("data:image/jpeg;base64,",""),a(e)},t.readAsDataURL(e.response)},e.onerror=()=>{a(null)},e.onreadystatechange=()=>{4==this.readyState&&200!=this.status&&a(null)},e.open("GET",t),e.responseType="blob",e.send()})}}class NopeCHA{static INFERENCE_URL="https://dev-api.nopecha.com";static MAX_WAIT_POST=60;static MAX_WAIT_GET=60;static ERRORS={UNKNOWN:9,INVALID_REQUEST:10,RATE_LIIMTED:11,BANNED_USER:12,NO_JOB:13,INCOMPLETE_JOB:14,INVALID_KEY:15,NO_CREDIT:16,UPDATE_REQUIRED:17};static async post({captcha_type:e,task:t,image_urls:a,image_data:r,grid:n,audio_data:o,key:i}){for(var s=Date.now(),c=await BG.exec("Tab.info");!(Date.now()-s>1e3*NopeCHA.MAX_WAIT_POST);){var l={type:e,task:t,key:i,v:chrome.runtime.getManifest().version,url:c?c.url:window.location.href};a&&(l.image_urls=a),r&&(l.image_data=r),n&&(l.grid=n),o&&(l.audio_data=o);try{var d={"Content-Type":"application/json"},u=(i&&"undefined"!==i&&(d.Authorization="Bearer "+i),await Net.fetch(BASE_API,{method:"POST",headers:d,body:JSON.stringify(l)})),p=JSON.parse(u);if("error"in p){if(p.error===NopeCHA.ERRORS.RATE_LIMITED){await Time.sleep(2e3);continue}if(p.error===NopeCHA.ERRORS.INVALID_KEY)break;if(p.error===NopeCHA.ERRORS.NO_CREDIT)break;break}var _=p.data;return await NopeCHA.get({job_id:_,key:i})}catch(e){}}return{job_id:null,data:null}}static async get({job_id:e,key:t}){for(var a=Date.now();!(Date.now()-a>1e3*NopeCHA.MAX_WAIT_GET);){await Time.sleep(1e3);var r={},r=(t&&"undefined"!==t&&(r.Authorization="Bearer "+t),await Net.fetch(BASE_API+`?id=${e}&key=`+t,{headers:r}));try{var n=JSON.parse(r);if(!("error"in n))return{job_id:e,data:n.data,metadata:n.metadata};if(n.error!==NopeCHA.ERRORS.INCOMPLETE_JOB)return{job_id:e,data:null,metadata:null}}catch(e){}}return{job_id:e,data:null,metadata:null}}} diff --git a/third-party/nopecha-chrome-extension/font/plex-sans-bold.woff b/third-party/nopecha-chrome-extension/font/plex-sans-bold.woff deleted file mode 100644 index e7a52a2..0000000 Binary files a/third-party/nopecha-chrome-extension/font/plex-sans-bold.woff and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/font/plex-sans-bold.woff2 b/third-party/nopecha-chrome-extension/font/plex-sans-bold.woff2 deleted file mode 100644 index f97a88a..0000000 Binary files a/third-party/nopecha-chrome-extension/font/plex-sans-bold.woff2 and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/font/plex-sans-regular.woff b/third-party/nopecha-chrome-extension/font/plex-sans-regular.woff deleted file mode 100644 index 81a40ee..0000000 Binary files a/third-party/nopecha-chrome-extension/font/plex-sans-regular.woff and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/font/plex-sans-regular.woff2 b/third-party/nopecha-chrome-extension/font/plex-sans-regular.woff2 deleted file mode 100644 index ce85e82..0000000 Binary files a/third-party/nopecha-chrome-extension/font/plex-sans-regular.woff2 and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/funcaptcha.js b/third-party/nopecha-chrome-extension/funcaptcha.js deleted file mode 100644 index 5f5a174..0000000 --- a/third-party/nopecha-chrome-extension/funcaptcha.js +++ /dev/null @@ -1 +0,0 @@ -(async()=>{function l(e,t=!1){if(t)for(const c of e){var a=document.querySelectorAll(c);if(6===a.length)return a}else for(const i of e){var n=document.querySelector(i);if(n)return n}return null}function r(){return null!==l(['button[aria-describedby="descriptionVerify"]','button[data-theme="home.verifyButton"]',"#wrong_children_button","#wrongTimeout_children_button"])}function u(){try{var e=l(['button[aria-describedby="descriptionVerify"]','button[data-theme="home.verifyButton"]']),t=(e&&(window.parent.postMessage({nopecha:!0,action:"clear"},"*"),e.click()),document.querySelector("#wrong_children_button")),a=(t&&(window.parent.postMessage({nopecha:!0,action:"clear"},"*"),t.click()),document.querySelector("#wrongTimeout_children_button"));a&&(window.parent.postMessage({nopecha:!0,action:"clear"},"*"),a.click())}catch(e){}}function s(){return l(["#game_children_text > h2",".challenge-instructions-container > h2"])?.innerText?.trim()}function h(){let e=l(["img#game_challengeItem_image"]);var t;return e?e.src?.split(";base64,")[1]:(t=(e=l([".challenge-container button"]))?.style["background-image"]?.trim()?.match(/(?!^)".*?"/g))&&0!==t.length?t[0].replaceAll('"',""):null}let d=null;async function e(){e=500;var e,{task:t,cells:a,image_data:n}=await new Promise(n=>{let c=!1;const i=setInterval(async()=>{if(!c){c=!0;var e=await BG.exec("Settings.get");if(e&&e.enabled&&e.funcaptcha_auto_solve){e.funcaptcha_auto_open&&r()&&await u();e=s();if(e){var t=l(["#game_children_challenge ul > li > a",".challenge-container button"],!0);if(6===t.length){var a=h();if(a&&d!==a)return d=a,clearInterval(i),c=!1,n({task:e,cells:t,image_data:a})}}c=!1}}},e)});if(null!==t&&null!==a&&null!==n){var c=await BG.exec("Settings.get");if(c&&c.enabled&&c.funcaptcha_auto_solve){var i=Time.time(),o=(await NopeCHA.post({captcha_type:IS_DEVELOPMENT?"funcaptcha_dev":"funcaptcha",task:t,image_data:[n],key:c.key}))["data"];if(o){t=parseInt(c.funcaptcha_solve_delay_time)||1e3,n=c.funcaptcha_solve_delay?t-(Time.time()-i):0;0{document.dispatchEvent(new Event("mousemove"))},50),window.location.pathname.startsWith("/fc/assets/tile-game-ui/")||window.location.pathname.startsWith("/fc/assets/ec-game-core/"))for(;;){await Time.sleep(1e3);var t,a=await BG.exec("Settings.get");a&&a.enabled&&(t=await Location.hostname(),a.disabled_hosts.includes(t)||(a.funcaptcha_auto_open&&r()?await u():a.funcaptcha_auto_solve&&null!==s()&&null!==h()&&await e()))}})(); diff --git a/third-party/nopecha-chrome-extension/funcaptcha_demo.js b/third-party/nopecha-chrome-extension/funcaptcha_demo.js deleted file mode 100644 index 23a3af1..0000000 --- a/third-party/nopecha-chrome-extension/funcaptcha_demo.js +++ /dev/null @@ -1,63 +0,0 @@ -(async()=>{const u={linkedin:["3117BF26-4762-4F5A-8ED9-A85E69209A46",!1],rockstar:["A5A70501-FCDE-4065-AF18-D9FAF06EF479",!1],github:["20782B4C-05D0-45D7-97A0-41641055B6F6",!1],paypal:["9409E63B-D2A5-9CBD-DBC0-5095707D0090",!1],blizzard:["E8A75615-1CBA-5DFF-8032-D16BCF234E10",!1],twitch:["E5554D43-23CC-1982-971D-6A2262A2CA24",!1],demo1:["804380F4-6844-FFA1-ED4E-5877CA1F1EA4",!1],demo2:["D39B0EE3-2973-4147-98EF-C92F93451E2D",!1],"ea signup":["73BEC076-3E53-30F5-B1EB-84F494D43DBA",!1],"ea signin":["0F5FE186-B3CA-4EDB-A39B-9B9A3397D01D",!1],myprepaidcenter:["0F941BF0-7303-D94B-B76A-EAA2E2048124",!1],twitter:["2CB16598-CB82-4CF7-B332-5990DB66F3AB",!0],discoveryplus:["FE296399-FDEA-2EA2-8CD5-50F6E3157ECA",!1],minecraft:["D39B0EE3-2973-4147-98EF-C92F93451E2D",!1],imvu:["0C2B415C-D772-47D4-A183-34934F786C7E",!1],adobe:["430FF2C3-1AB1-40B7-8BE7-44FC683FE02C",!1]},h={outlook:["https://iframe.arkoselabs.com/B7D8911C-5CC8-A9A3-35B0-554ACEE604DA/index.html?mkt=en",!1],"outlook auth":["https://iframe-auth.arkoselabs.com/B7D8911C-5CC8-A9A3-35B0-554ACEE604DA/index.html?mkt=en",!1]};let E=1;function w(){g("linkedin",0,1),g("rockstar",0,1),g("demo1",0,1),g("blizzard",0,1),g("twitch",0,1),g("paypal",0,1),A("outlook auth",0,1),g("github",0,1),g("demo2",0,1),A("outlook",0,1),g("ea signup",0,1),g("ea signin",0,1),g("twitter",0,1),g("minecraft",0,1),g("imvu",0,1),g("adobe",0,1)}function g(t,o,n){n=n||E;for(let e=0;e * { - height: 20px; - line-height: 20px; - padding: 0; - border: 0; - font-size: 12px; - }`,`.input_row > input[type="button"] { - width: 100px; - cursor: pointer; - transition: 200ms all; - }`,`.input_row > input[type="button"]:hover { - opacity: 0.8; - }`,`#nframes_label { - background-color: #fff; - color: #222; - width: 70px; - text-align: center; - }`,`#nframes, #nframes:active { - width: 30px; - border: none; - outline: none; - }`,`.name { - color: #fff; - }`,`.iframe_row { - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: center; - }`,`.iframe_wrap { - background-color: #eee; - width: 275px; - height: 275px; - padding: 0; - overflow: hidden; - }`,`iframe { - border: none !important; - width: 400px !important; - height: 400px !important; - -ms-zoom: 0.75 !important; - -moz-transform: scale(0.75) !important; - -moz-transform-origin: 0 0 !important; - -o-transform: scale(0.75) !important; - -o-transform-origin: 0 0 !important; - -webkit-transform: scale(0.75) !important; - -webkit-transform-origin: 0 0 !important; - }`,`iframe.small { - width: 550px !important; - height: 550px !important; - -ms-zoom: 0.5 !important; - -moz-transform: scale(0.5) !important; - -moz-transform-origin: 0 0 !important; - -o-transform: scale(0.5) !important; - -o-transform-origin: 0 0 !important; - -webkit-transform: scale(0.5) !important; - -webkit-transform-origin: 0 0 !important; - }`];const o=document.body.appendChild(document.createElement("style")).sheet;for(const n in t)o.insertRule(t[n],n);let n=0;let r=1;const a={};a[0]=document.createElement("div");a[0].classList.add("input_row");document.body.append(a[0]);const i=document.createElement("div");i.id="nframes_label";i.innerText="# iframes";a[0].append(i);const c=document.createElement("input");c.id="nframes";c.placeholder="Number of iframes";c.value=E;c.addEventListener("input",()=>{E=parseInt(c.value)});a[0].append(c);const s={reset:{row:0,fn:e,args:[]},all:{row:0,fn:w,args:[]}};for(const m in u)n++%9==0&&r++,s[m]={row:r,fn:g,args:[m,0]};for(const d in h)n++%9==0&&r++,s[d]={row:r,fn:A,args:[d,0]};for(const[p,l]of Object.entries(s)){const r=l.row,f=(l.row in a||(a[l.row]=document.createElement("div"),a[l.row].classList.add("input_row"),document.body.append(a[l.row])),document.createElement("input"));f.type="button",f.value=p,f.addEventListener("click",()=>{e(),l.fn(...l.args)}),a[l.row].append(f)}}(),A("outlook",0,E)})(); diff --git a/third-party/nopecha-chrome-extension/funcaptcha_fast.js b/third-party/nopecha-chrome-extension/funcaptcha_fast.js deleted file mode 100644 index c3809fe..0000000 --- a/third-party/nopecha-chrome-extension/funcaptcha_fast.js +++ /dev/null @@ -1 +0,0 @@ -(async()=>{window.addEventListener("load",()=>{var t=document.body.appendChild(document.createElement("style")).sheet;t.insertRule("* {transition-duration: 0s !important}",0),t.insertRule("li > a::after {border: 8px solid rgba(0, 255, 0, 0.6) !important}",1),t.insertRule("#interstitial {backdrop-filter: none !important}",2),t.insertRule("#interstitial {background-color: transparent !important}",3),t.insertRule("#interstitial_wrapper {background-color: transparent !important}",4)})})(); diff --git a/third-party/nopecha-chrome-extension/funcaptcha_scrape.js b/third-party/nopecha-chrome-extension/funcaptcha_scrape.js deleted file mode 100644 index 6157d86..0000000 --- a/third-party/nopecha-chrome-extension/funcaptcha_scrape.js +++ /dev/null @@ -1 +0,0 @@ -(async()=>{var e=IS_DEVELOPMENT;const o="lazy";window.nopecha=[];var a={};async function t(e){var a=(document.querySelector("#game_children_text > h2")||document.querySelector("#game-header"))?.innerText?.trim(),t=(document.querySelector("img#game_challengeItem_image")||document.querySelector("#challenge-image"))?.src?.split(";base64,")[1];a&&t&&(a={task:a,image:t,index:e,url:(await BG.exec("Tab.info"))?.url},o.startsWith("l")&&window.parent.postMessage({nopecha:!0,action:"append",data:a},"*"),o.startsWith("e"))&&await Net.fetch("https://api.nopecha.com/upload",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)})}var n=window.addEventListener?"addEventListener":"attachEvent";for(window[n]("attachEvent"==n?"onmessage":"message",async e=>{e=e[e.message?"message":"data"];e&&!0===e.nopecha&&("append"===e.action?window.nopecha.push(e.data):"clear"===e.action?window.nopecha=[]:"reload"===e.action&&(window.parent.postMessage({nopecha:!0,action:"reload"},"*"),window.location.reload(!0)))},!1);;){await Time.sleep(1e3);try{if(document.querySelector("body.victory")){var i=[];for(const s of window.nopecha){var c=Net.fetch("https://api.nopecha.com/upload",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});i.push(c)}await Promise.all(i),window.nopecha=[],e&&(window.parent.postMessage({nopecha:!0,action:"reload"},"*"),window.location.reload(!0))}"block"===document.querySelector("#timeout_widget")?.style?.display&&(window.parent.postMessage({nopecha:!0,action:"reload"},"*"),window.location.reload(!0));var r=document.querySelectorAll("#game_children_challenge ul > li > a");for(const l in r){var d=r[l];l in a&&d.removeEventListener("click",a[l]),a[l]=t.bind(this,parseInt(l)),d.addEventListener("click",a[l])}}catch(e){}}})(); diff --git a/third-party/nopecha-chrome-extension/hcaptcha.js b/third-party/nopecha-chrome-extension/hcaptcha.js deleted file mode 100644 index 26fdb5a..0000000 --- a/third-party/nopecha-chrome-extension/hcaptcha.js +++ /dev/null @@ -1 +0,0 @@ -(async()=>{function u(e){e=e?.style.background?.trim()?.match(/(?!^)".*?"/g);return e&&0!==e.length?e[0].replaceAll('"',""):null}async function h(){var e=document.querySelector("h2.prompt-text")?.innerText?.replace(/\s+/g," ")?.trim();if(!e)return null;var t={"0430":"a","0441":"c","0501":"d","0065":"e","0435":"e","04bb":"h","0069":"i","0456":"i","0458":"j","03f3":"j","04cf":"l","03bf":"o","043e":"o","0440":"p","0455":"s","0445":"x","0443":"y","0335":"-"};var a=[];for(const i of e){var c=function(e,t,a){for(;(""+e).length{let r=!1;const s=setInterval(async()=>{if(!r){r=!0;var e=await h();if(e){var t=u(document.querySelector(".challenge-example > .image > .image"));if(t&&""!==t){var a=document.querySelectorAll(".task-image");if(9===a.length){var c=[],i=[];for(const l of a){var n=l.querySelector("div.image");if(!n)return void(r=!1);n=u(n);if(!n||""===n)return void(r=!1);c.push(l),i.push(n)}a=JSON.stringify(i);if(d!==a)return d=a,clearInterval(s),r=!1,o({task:e,task_url:t,cells:c,urls:i})}}}r=!1}},e)}),i=await BG.exec("Settings.get");if(i&&i.enabled&&i.hcaptcha_auto_solve){var n=Time.time(),{data:l,metadata:t}=await NopeCHA.post({captcha_type:IS_DEVELOPMENT?"hcaptcha_dev":"hcaptcha",task:t,image_urls:c,key:i.key});if(l){o&&o.postMessage({event:"NopeCHA.metadata",metadata:t});c=parseInt(i.hcaptcha_solve_delay_time)||3e3,t=i.hcaptcha_solve_delay?c-(Time.time()-n):0;0{"NopeCHA.hook"===e.data.event&&(o=e.source)}),window.location.hash.includes("frame=challenge")&&(c=!0,"firefox"===await BG.exec("Browser.version")?await Script.inject_file("hcaptcha_hook.js"):await BG.exec("Inject.files",{files:["hcaptcha_hook.js"]}))),n.hcaptcha_auto_open&&0!==document.body.getBoundingClientRect()?.width&&0!==document.body.getBoundingClientRect()?.height&&null!==document.querySelector("div.check")?await e():n.hcaptcha_auto_solve&&null!==document.querySelector("h2.prompt-text")&&await t()))}})(); diff --git a/third-party/nopecha-chrome-extension/hcaptcha_fast.js b/third-party/nopecha-chrome-extension/hcaptcha_fast.js deleted file mode 100644 index 0fce138..0000000 --- a/third-party/nopecha-chrome-extension/hcaptcha_fast.js +++ /dev/null @@ -1 +0,0 @@ -(async()=>{let a=null,t=!1,r=!1;function n(e,t,r=!1){e&&(r||a!==e)&&(!0===t&&"false"===e.getAttribute("aria-pressed")||!1===t&&"true"===e.getAttribute("aria-pressed"))&&e.click()}document.addEventListener("mousedown",e=>{"false"===e?.target?.parentNode?.getAttribute("aria-pressed")?(t=!0,r=!0):"true"===e?.target?.parentNode?.getAttribute("aria-pressed")&&(t=!0,r=!1),a=e?.target?.parentNode}),document.addEventListener("mouseup",e=>{t=!1,a=null}),document.addEventListener("mousemove",e=>{t&&(a!==e?.target?.parentNode&&null!==a&&n(a,r,!0),n(e?.target?.parentNode,r))}),window.addEventListener("load",()=>{document.body.appendChild(document.createElement("style")).sheet.insertRule('[aria-pressed="true"] > .border-focus {background-color: #0f0 !important; opacity: 0.3 !important}',0)})})(); diff --git a/third-party/nopecha-chrome-extension/hcaptcha_hook.js b/third-party/nopecha-chrome-extension/hcaptcha_hook.js deleted file mode 100644 index 736c349..0000000 --- a/third-party/nopecha-chrome-extension/hcaptcha_hook.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{var e=function(){"use strict";Array.prototype.indexOf||(Array.prototype.indexOf=function(t){for(let e=0;eArray.prototype.slice.call(e,t);let e=null;"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?e=self:"undefined"!=typeof global?e=global:window&&(e=window);const t=e,u=e.document;var n="undefined"!=typeof navigator&&navigator.useragent?navigator.userAgent:"";let g=null;(/msie (\d+)/.test(n.toLowerCase())||/trident\/.*; rv:(\d+)/.test(n.toLowerCase()))&&(g=parseInt(RegExp.$1,10));function E(e,t){for(var n in e)if(!c(n)){var r=e[n];try{t[n]=r}catch(e){}}return t}function m(e,a,s){var t;for(t of Array.from(e))s._has(t)&&(a["on"+t]=(o=>function(e){var t,n,r={};for(t in e)c(t)||(n=e[t],r[t]=n===a?s:n);return s.dispatchEvent(o,r)})(t))}function b(o){let r={};const a=e=>r[e]||[],s={addEventListener:function(e,t,n){r[e]=a(e),0<=r[e].indexOf(t)||(n=void 0===n?r[e].length:n,r[e].splice(n,0,t))},removeEventListener:function(e,t){void 0===e?r={}:(void 0===t&&(r[e]=[]),-1!==(t=a(e).indexOf(t))&&a(e).splice(t,1))}};return s.dispatchEvent=function(){var t=i(arguments),e=t.shift(),n=(o||(t[0]=E(t[0],function(t){var e;if(u&&null!=u.createEventObject)return(e=u.createEventObject()).type=t,e;try{return new Event(t)}catch(e){return{type:t}}}(e))),s["on"+e]),r=(n&&n.apply(s,t),a(e).concat(a("*")));for(let e=0;e!(!r[e]&&!s["on"+e]),o&&(s.listeners=e=>i(a(e)),s.on=s.addEventListener,s.off=s.removeEventListener,s.fire=s.dispatchEvent,s.once=function(e,t){var n=function(){return s.off(e,n),t.apply(null,arguments)};return s.on(e,n)},s.destroy=()=>r={}),s}const L=["load","loadend","loadstart"],w=["progress","abort","error","timeout"],c=e=>["returnValue","totalSize","position"].includes(e);var x=function(e,t){let n;switch(null==t&&(t={}),typeof e){case"object":var r,o=[];for(r in e){var a=e[r];n=r.toLowerCase(),o.push(n+`: `+a)}return o.join("\n")+"\n";case"string":o=e.split("\n");for(var s of Array.from(o))/([^:]+):\s*(.+)/.test(s)&&(n=null!=RegExp.$1?RegExp.$1.toLowerCase():void 0,s=RegExp.$2,null==t[n])&&(t[n]=s);return t}return[]};function r(){const i=new R,u={};let o=null,a=void 0,c=void 0,l=void 0;var s=0;function t(){if(l.status=o||i.status,-1===o&&g<10||(l.statusText=i.statusText),-1!==o){var e,t=x(i.getAllResponseHeaders());for(e in t){var n,r=t[e];l.headers[e]||(n=e.toLowerCase(),l.headers[n]=r)}}}function r(e){for(;sO(l.headers[e?e.toLowerCase():void 0]),y.getAllResponseHeaders=()=>O(x(l.headers)),i.overrideMimeType&&(y.overrideMimeType=function(){i.overrideMimeType.apply(i,arguments)}),i.upload&&(v=b(),y.upload=v,u.upload=v),y.UNSENT=0,y.OPENED=1,y.HEADERS_RECEIVED=2,y.LOADING=3,y.DONE=4,y.response="",y.responseText="",y.responseXML=null,y.readyState=0,y.statusText="",y}const N=b(!0),O=e=>void 0===e?null:e,R=t.XMLHttpRequest;r.UNSENT=0,r.OPENED=1,r.HEADERS_RECEIVED=2,r.LOADING=3,r.DONE=4;var o={patch(){R&&(t.XMLHttpRequest=r)},unpatch(){R&&(t.XMLHttpRequest=R)},Native:R,XH:r};function a(e,u){null==u&&(u={headers:{}});let c=null;e instanceof Request?c=e:u.url=e;const l=N.listeners("before"),f=N.listeners("after");return new Promise(function(n,t){function r(e){var t;return f.length?2===(t=f.shift()).length?(t(a(),e),r(e)):3===t.length?t(a(),e,r):r(e):n(e)}function o(){var e;if(l.length)return 1===(e=l.shift()).length?s(e(u)):2===e.length&&e(a(),s);i()}const a=function(){return u.headers&&(u.headers=new Headers(u.headers)),c=c||new Request(u.url,u),E(u,c)},s=function(e){void 0!==e?(e=new Response(e.body||e.text,e),n(e),r(e)):o()};var i=()=>d(a()).then(e=>r(e)).catch(function(e){return n=t,r(e),t(e)});o()})}const d=t.fetch;var s={patch(){d&&(t.fetch=a)},unpatch(){d&&(t.fetch=d)},Native:d,XH:a};const l=N;return l.EventEmitter=b,l.before=function(e,t){if(e.length<1||2{"NopeCHA.metadata"===e.data.event&&i.push(e.data.metadata)}),window.postMessage({event:"NopeCHA.hook"}),e.before(e=>{try{var t,n,r;"POST"===(o=e).method&&o.url.startsWith("https://hcaptcha.com/checkcaptcha/")&&(t=JSON.parse(e.body),s(n=JSON.parse(t.motionData),a(r=function(e){var n={md:[],mm:[],mu:[]};for(const o of e)for(const a of Object.keys(n)){const s=0===n[a].length?0:n[a][n[a].length-1][2];var t=o[a].map(e=>[Math.ceil(e[0]),Math.ceil(e[1]),Math.ceil(e[2]+s)]);n[a].push(...t)}for(const i of Object.keys(n)){var r=[];let e=null;for(const u of n[i])null!==e&&r.push(u[2]-e),e=u[2];let t=0;0e+t)/r.length),n[i+"-mp"]=t}return n}(i),n.st)),s(n.topLevel,a(r,n.topLevel.st,n.st)),t.motionData=JSON.stringify(n),e.body=JSON.stringify(t),i=[])}catch(e){}var o})})(); diff --git a/third-party/nopecha-chrome-extension/hcaptcha_language.js b/third-party/nopecha-chrome-extension/hcaptcha_language.js deleted file mode 100644 index 9f07d0d..0000000 --- a/third-party/nopecha-chrome-extension/hcaptcha_language.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{let e;function t(){var e=navigator.language.split("-")[0];for(const r of document.querySelectorAll('script[src*="hcaptcha.com/1/api.js"]')){var t=new URL(r.src);"en"!==(t.searchParams.get("hl")||e)&&(t.searchParams.set("hl","en"),r.src=t.toString())}}e=new MutationObserver(t),setTimeout(()=>{t(),e.observe(document.head,{childList:!0})},0)})(); diff --git a/third-party/nopecha-chrome-extension/icon/128.png b/third-party/nopecha-chrome-extension/icon/128.png deleted file mode 100644 index 6b3469a..0000000 Binary files a/third-party/nopecha-chrome-extension/icon/128.png and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/icon/128g.png b/third-party/nopecha-chrome-extension/icon/128g.png deleted file mode 100644 index 449a08d..0000000 Binary files a/third-party/nopecha-chrome-extension/icon/128g.png and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/icon/16.png b/third-party/nopecha-chrome-extension/icon/16.png deleted file mode 100644 index 39b0214..0000000 Binary files a/third-party/nopecha-chrome-extension/icon/16.png and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/icon/16g.png b/third-party/nopecha-chrome-extension/icon/16g.png deleted file mode 100644 index 9cfab26..0000000 Binary files a/third-party/nopecha-chrome-extension/icon/16g.png and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/icon/32.png b/third-party/nopecha-chrome-extension/icon/32.png deleted file mode 100644 index cc85599..0000000 Binary files a/third-party/nopecha-chrome-extension/icon/32.png and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/icon/32g.png b/third-party/nopecha-chrome-extension/icon/32g.png deleted file mode 100644 index a3194ed..0000000 Binary files a/third-party/nopecha-chrome-extension/icon/32g.png and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/icon/48.png b/third-party/nopecha-chrome-extension/icon/48.png deleted file mode 100644 index 43e88dd..0000000 Binary files a/third-party/nopecha-chrome-extension/icon/48.png and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/icon/48g.png b/third-party/nopecha-chrome-extension/icon/48g.png deleted file mode 100644 index ae5f142..0000000 Binary files a/third-party/nopecha-chrome-extension/icon/48g.png and /dev/null differ diff --git a/third-party/nopecha-chrome-extension/locate.js b/third-party/nopecha-chrome-extension/locate.js deleted file mode 100644 index f8b92ea..0000000 --- a/third-party/nopecha-chrome-extension/locate.js +++ /dev/null @@ -1,74 +0,0 @@ -(async()=>{var t,e;function n(){try{return window.self!==window.top}catch(t){return 1}}t=self,e=()=>(()=>{"use strict";var r,c,t,i={d:(t,e)=>{for(var n in e)i.o(e,n)&&!i.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};function l(t){return t&&t instanceof Element}i.r(e),i.d(e,{default:()=>V,getCssSelector:()=>L}),(t=r=r||{}).NONE="none",t.DESCENDANT="descendant",t.CHILD="child",(t=c=c||{}).id="id",t.class="class",t.tag="tag",t.attribute="attribute",t.nthchild="nthchild",t.nthoftype="nthoftype";const h={selectors:[c.id,c.class,c.tag,c.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY};function o(t){return t instanceof RegExp}function n(t){return["string","function"].includes(typeof t)||o(t)}function u(t){return Array.isArray(t)?t.filter(n):[]}function s(t){var e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return t instanceof Node&&e.includes(t.nodeType)}function p(t,e){return s(t)?(t.contains(e),t):s(t=e.getRootNode({composed:!1}))?(document,t):e.ownerDocument.querySelector(":root")}function f(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function m(t=[]){var[t=[],...e]=t;return 0===e.length?t:e.reduce((t,e)=>t.filter(t=>e.includes(t)),t)}function g(t){return[].concat(...t)}function E(t){const n=t.map(e=>{if(o(e))return t=>e.test(t);if("function"==typeof e)return t=>{t=e(t);return"boolean"==typeof t&&t};if("string"!=typeof e)return()=>!1;{const n=new RegExp("^"+e.replace(/[|\\{}()[\]^$+?.]/g,"\\$&").replace(/\*/g,".+")+"$");return t=>n.test(t)}});return e=>n.some(t=>t(e))}function _(t,e,n){const i=Array.from(p(n,t[0]).querySelectorAll(e));return i.length===t.length&&t.every(t=>i.includes(t))}function b(t,e){e=null!=e?e:t.ownerDocument.querySelector(":root");var n=[];let i=t;for(;l(i)&&i!==e;)n.push(i),i=i.parentElement;return n}const a={[r.NONE]:{type:r.NONE,value:""},[r.DESCENDANT]:{type:r.DESCENDANT,value:" > "},[r.CHILD]:{type:r.CHILD,value:" "}},d=new RegExp(["^$","\\s"].join("|")),A=new RegExp(["^$"].join("|")),$=[c.nthoftype,c.tag,c.id,c.class,c.attribute,c.nthchild],y=E(["class","id","ng-*"]);function x({nodeName:t}){return`[${t}]`}function S({nodeName:t,nodeValue:e}){return`[${t}='${T(e)}']`}function w(n){var t=Array.from(n.attributes).filter(t=>{var[t,e]=[t.nodeName,n];return e=e.tagName.toLowerCase(),!(["input","option"].includes(e)&&"value"===t||y(t))});return[...t.map(x),...t.map(S)]}function N(t){return(t.getAttribute("class")||"").trim().split(/\s+/).filter(t=>!A.test(t)).map(t=>"."+T(t))}function v(t){var e=t.getAttribute("id")||"",n="#"+T(e),i=t.getRootNode({composed:!1});return!d.test(e)&&_([t],n,i)?[n]:[]}function C(t){var e=t.parentNode;if(e){e=Array.from(e.childNodes).filter(l).indexOf(t);if(-1t.tagName.toLowerCase()===e).indexOf(t);if(-1e[t])),r=function(t=[],e){var n=t.length;if(0===n)return[];var i=[...t];i[n-1]+=1;for(let t=n-1;0<=t;t--)if(i[t]>e){if(0===t)return I(n+1);i[t-1]++,i[t]=i[t-1]+1}return e*+,./;=?@^`~\\]/;function T(t=""){var e;return null!=(e=null==(e=null===CSS||void 0===CSS?void 0:CSS.escape)?void 0:e.call(CSS,t))?e:([e=""]=[t],e.split("").map(t=>":"===t?`\\${R} `:D.test(t)?"\\"+t:escape(t).replace(/%/g,"\\")).join(""))}const j={tag:P,id:function(t){return 0===t.length||1{return e[t=t]?e[t].join(""):""}).join("")}function J(t,e,n="",i){var r,o,s,a,d;i.root,s=function(a,n){const{blacklist:t,whitelist:e,combineWithinSelector:d,maxCombinations:c}=n,l=E(t),h=E(e);return function(){var{selectors:t,includeTag:e}=n,t=[].concat(t);return e&&!t.includes("tag")&&t.push("tag"),t}().reduce((t,e)=>{o=a,s=e;var n,i,r,o,s=(null!=(s=j[s])?s:()=>[])(o),s=([o=[],i,r]=[s,l,h],o.filter(t=>r(t)||!i(t))),s=([o=[],n]=[s,h],o.sort((t,e)=>{t=n(t),e=n(e);return t&&!e?-1:!t&&e?1:0}));return t[e]=d?k(s,{maxResults:c}):s.map(t=>[t]),t},{})}(t,o=i),a=s,d=o,s=g(function(){var{selectors:t,combineBetweenSelectors:e,includeTag:n,maxCandidates:i}=d,e=e?k(t,{maxResults:i}):t.map(t=>[t]);return n?e.map(B):e}().map(t=>{{var n=a;const i={};return t.forEach(t=>{var e=n[t];0{i=t.flatMap(e=>0===i.length?[{[n]:e}]:i.map(t=>Object.assign(Object.assign({},t),{[n]:e})))}),i}(i).map(U)}}).filter(t=>0r+" "+t),...o.map(t=>r+" > "+t)]))if(_(t,e,i.root))return e;return null}function z(t){return{value:t,include:!1}}function G({selectors:e,operator:t}){let n=[...$],i=(e[c.tag]&&e[c.nthoftype]&&(n=n.filter(t=>t!==c.tag)),"");return n.forEach(t=>{(e[t]||[]).forEach(({value:t,include:e})=>{e&&(i+=t)})}),t.value+i}function F(t){return[":root",...b(t).reverse().map(t=>{t=function(n,t,e=r.NONE){const i={};return t.forEach(t=>{var e;Reflect.set(i,t,(e=n,t=t,H[t](e).map(z)))}),{element:n,operator:a[e],selectors:i}}(t,[c.nthchild],r.DESCENDANT);return t.selectors.nthchild.forEach(t=>{t.include=!0}),t}).map(G)].join("")}function L(t,e={}){const o=function(t){t=(Array.isArray(t)?t:[t]).filter(l);return[...new Set(t)]}(t),s=([t,e={}]=[o[0],e],e=Object.assign(Object.assign({},h),e),{selectors:(n=e.selectors,Array.isArray(n)?n.filter(t=>{return e=c,t=t,Object.values(e).includes(t);var e}):[]),whitelist:u(e.whitelist),blacklist:u(e.blacklist),root:p(e.root,t),combineWithinSelector:!!e.combineWithinSelector,combineBetweenSelectors:!!e.combineBetweenSelectors,includeTag:!!e.includeTag,maxCombinations:f(e.maxCombinations),maxCandidates:f(e.maxCandidates)});var n;let a="",d=s.root;function i(){var[t,e,n="",i]=[o,d,a,s];if(0!==t.length){var r,e=[1b(t,r))).map(t=>[t]))];for(const t of e){const e=J(t,0,n,i);if(e)return{foundElements:t,selector:e}}}return null}let r=i();for(;r;){const{foundElements:t,selector:c}=r;if(_(o,c,s.root))return c;d=t[0],a=c,r=i()}return(1L(t,s)):o.map(F)).join(", ")}const V=L;return e})(),"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.CssSelectorGenerator=e():t.CssSelectorGenerator=e();class r{constructor(t,e=!1){this.NAMESPACE="__NOPECHA__",this.MARK_RADIUS=5,this.window_id=Util.generate_id(8),this.locate=t,this.draw_mark=e,this.update_timer,this.css_selector,this.$last,this.initialize_style(),this.initialize_elements()}initialize_style(){var t=[`#${this.NAMESPACE}_wrapper { - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - background-color: transparent; - pointer-events: none; - z-index: 10000000; - }`,`.${this.NAMESPACE}_textbox { - display: flex; - flex-direction: row; - flex-wrap: wrap; - - position: absolute; - left: 0; - right: 0; - - background-color: rgba(0, 0, 0, 1); - color: #fff; - font: normal 12px/12px Helvetica, sans-serif; - text-shadow: 0 1px 1px rgba(0, 0, 0, 0.3); - border: 1px solid #fff; - overflow: hidden; - }`,`.${this.NAMESPACE}_textbox.${this.NAMESPACE}_header { - top: 0; - }`,`.${this.NAMESPACE}_textbox.${this.NAMESPACE}_header > div { - padding: 4px 8px; - }`,`.${this.NAMESPACE}_textbox.${this.NAMESPACE}_header > div:first-child { - flex-grow: 1; - }`,`.${this.NAMESPACE}_textbox.${this.NAMESPACE}_footer { - bottom: 0; - }`,`.${this.NAMESPACE}_textbox.${this.NAMESPACE}_footer > div { - padding: 4px 8px; - }`,`.${this.NAMESPACE}_textbox.${this.NAMESPACE}_footer > div:first-child { - flex-grow: 1; - }`,`.${this.NAMESPACE}_highlight { - position: absolute; - opacity: 0.4; - }`,`.${this.NAMESPACE}_highlight.${this.NAMESPACE}_margin { - background-color: rgb(230, 165, 18); - }`,`.${this.NAMESPACE}_highlight.${this.NAMESPACE}_border { - background-color: rgb(255, 204, 121); - }`,`.${this.NAMESPACE}_highlight.${this.NAMESPACE}_padding { - background-color: rgb(50, 255, 50); - }`,`.${this.NAMESPACE}_highlight.${this.NAMESPACE}_content { - background-color: rgb(0, 153, 201); - }`,`.${this.NAMESPACE}_mark { - position: absolute; - top: 0; - left: 0; - right: 0; - - width: ${parseInt(2*this.MARK_RADIUS)}px; - height: ${parseInt(2*this.MARK_RADIUS)}px; - background-color: #f44; - border-radius: 50%; - z-index: 2; - }`];n()||t.push(`.${this.NAMESPACE}_shadow { - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - background-color: rgba(0, 0, 0, 0.2); - pointer-events: none; - z-index: 1; - }`),this.$style=document.createElement("style"),this.$style.type="text/css",this.$style.styleSheet?this.$style.styleSheet.cssText=t.join("\n"):this.$style.innerHTML=t.join("\n"),document.getElementsByTagName("head")[0].appendChild(this.$style)}initialize_elements(){var t;this.$wrapper=document.createElement("div"),this.$wrapper.id=this.NAMESPACE+"_wrapper",document.body.append(this.$wrapper),this.$shadow=document.createElement("div"),this.$shadow.classList.add(this.NAMESPACE+"_shadow"),this.$wrapper.append(this.$shadow),this.$margin_box=document.createElement("div"),this.$margin_box.classList.add(this.NAMESPACE+"_highlight",this.NAMESPACE+"_margin"),this.$wrapper.append(this.$margin_box),this.$border_box=document.createElement("div"),this.$border_box.classList.add(this.NAMESPACE+"_highlight",this.NAMESPACE+"_border"),this.$wrapper.append(this.$border_box),this.$padding_box=document.createElement("div"),this.$padding_box.classList.add(this.NAMESPACE+"_highlight",this.NAMESPACE+"_padding"),this.$wrapper.append(this.$padding_box),this.$content_box=document.createElement("div"),this.$content_box.classList.add(this.NAMESPACE+"_highlight",this.NAMESPACE+"_content"),this.$wrapper.append(this.$content_box),n()||(this.$header=document.createElement("div"),this.$header.classList.add(this.NAMESPACE+"_textbox",this.NAMESPACE+"_header"),t="textcaptcha_image_selector"===this.locate?"Image":"Input",this.$header.innerHTML=` -
-
Click on the CAPTCHA ${t} element to generate a CSS selector.
-
Press ESC to cancel.
-
-
NopeCHA
- `,this.$wrapper.append(this.$header),this.$footer=document.createElement("div"),this.$footer.classList.add(this.NAMESPACE+"_textbox",this.NAMESPACE+"_footer"),this.$wrapper.append(this.$footer)),this.draw_mark&&(this.$mark=document.createElement("div"),this.$mark.classList.add(this.NAMESPACE+"_mark"),this.$wrapper.append(this.$mark))}clip(t){var e={top:Math.max(0,t.top),left:Math.max(0,t.left),width:t.width+t.left>window.innerWidth?window.innerWidth-t.left:t.width,height:t.height+t.top>window.innerHeight?window.innerHeight-t.top:t.height};return t.top<0&&(e.height+=t.top),t.left<0&&(e.width+=t.left),e.width<0&&(e.width=0),e.height<0&&(e.height=0),e}computed_style(t,e){let n=window.getComputedStyle(t).getPropertyValue(e);for(const i in n=n.match(/[\-]?[\d\.]+px/g))n[i]=parseFloat(n[i].replace("px",""));return 1===n.length&&n.push(n[0],n[0],n[0]),2===n.length&&n.push(n[0],n[1]),3===n.length&&n.push(n[1]),n}add_dim(t,e){for(const n of e)t.top-=n[0],t.left-=n[3],t.width+=n[1]+n[3],t.height+=n[0]+n[2];return t}sub_dim(t,e){for(const n of e)t.top+=n[0],t.left+=n[3],t.width-=n[1]+n[3],t.height-=n[0]+n[2];return t}set_dim(t,e){e=this.clip(e);t.style.top=e.top+"px",t.style.left=e.left+"px",t.style.width=e.width+"px",t.style.height=e.height+"px"}get_center(t){t=t.getBoundingClientRect();return{x:t.left+t.width/2,y:t.top+t.height/2}}get_css(){return window.CssSelectorGenerator.getCssSelector(this.$t)}clear(){this.$t=null;var t={top:0,left:0,width:0,height:0};this.set_dim(this.$margin_box,t),this.set_dim(this.$border_box,t),this.set_dim(this.$padding_box,t),this.set_dim(this.$content_box,t),this.draw_mark&&(this.$mark.style.top="0px",this.$mark.style.left="0px")}update(a,t=0){const d=this;d.$last&&d.$last===a||(a&&(d.$t=a),d.$t&&(clearTimeout(d.update_timer),d.update_timer=setTimeout(()=>{var t,e,n,i,r,o,s;d.$t?.getBoundingClientRect&&(r=d.$t.getBoundingClientRect(),o=d.computed_style(d.$t,"margin"),s=d.computed_style(d.$t,"border-width"),t=d.computed_style(d.$t,"padding"),r={top:r.top,left:r.left,width:r.width,height:r.height},e=JSON.parse(JSON.stringify(r)),n=JSON.parse(JSON.stringify(r)),i=JSON.parse(JSON.stringify(r)),r=JSON.parse(JSON.stringify(r)),d.add_dim(e,[o]),d.sub_dim(i,[s]),d.sub_dim(r,[s,t]),d.set_dim(d.$margin_box,e),d.set_dim(d.$border_box,n),d.set_dim(d.$padding_box,i),d.set_dim(d.$content_box,r),o=d.get_css(d.$t),d.update_css_selector(d.window_id,o),BG.exec("Relay.send",{data:{action:"update_locate",window_id:d.window_id,css_selector:o}}),d.draw_mark)&&(s=d.get_center(a),d.$mark.style.top=parseInt(s.y-d.MARK_RADIUS)+"px",d.$mark.style.left=parseInt(s.x-d.MARK_RADIUS)+"px")},t)))}update_css_selector(t,e){this.window_id!==t&&this.clear(),n()||(this.$footer.innerHTML=`
${e}
`)}terminate(){clearTimeout(this.update_timer),this.$style.remove(),this.$wrapper.remove()}}let o=null;function s(t){t=t.target,t=o.get_css(t);BG.exec("Settings.set",{id:o.locate,value:t}),l(!0)}function a(t){t=t.target;o.update(t)}function d(t){o.update()}function c(t){t=t||window.event;let e=!1;(e="key"in t?"Escape"===t.key||"Esc"===t.key:27===t.keyCode)&&l(!0)}function l(t){try{document.body.removeEventListener("click",s),document.body.removeEventListener("mousemove",a),document.body.removeEventListener("mousewheel",d),document.body.removeEventListener("keydown",c),o.terminate(),o=null}catch(t){}t&&BG.exec("Relay.send",{data:{action:"stop_locate"}})}chrome.runtime.onMessage.addListener((t,e,n)=>{var i;"start_locate"===t.action?(i=t.locate,o=new r(i),document.body.addEventListener("click",s),document.body.addEventListener("mousemove",a),document.body.addEventListener("mousewheel",d),document.body.addEventListener("keydown",c)):"stop_locate"===t.action?l(!1):"update_locate"===t.action&&o.update_css_selector(t.window_id,t.css_selector)})})(); diff --git a/third-party/nopecha-chrome-extension/manifest.json b/third-party/nopecha-chrome-extension/manifest.json deleted file mode 100644 index a5c4a27..0000000 --- a/third-party/nopecha-chrome-extension/manifest.json +++ /dev/null @@ -1,3 +0,0 @@ -{ -"update_url": "https://clients2.google.com/service/update2/crx", -"name": "NopeCHA: CAPTCHA Solver", "version": "0.3.4", "description": "Automatically solve reCAPTCHA, hCaptcha, FunCAPTCHA, AWS WAF, and text CAPTCHA using AI.", "permissions": ["declarativeNetRequest", "storage", "scripting", "contextMenus", "webRequest"], "content_scripts": [{"matches": [""], "js": ["utils.js", "content.js"], "run_at": "document_start", "all_frames": true, "match_about_blank": true}, {"matches": ["*://nopecha.com/setup"], "js": ["setup.js"], "run_at": "document_end", "all_frames": true, "match_about_blank": false}, {"matches": ["*://*.hcaptcha.com/captcha/*"], "js": ["hcaptcha.js"], "run_at": "document_end", "all_frames": true, "match_about_blank": false}, {"matches": ["*://*.hcaptcha.com/captcha/*"], "js": ["hcaptcha_fast.js"], "run_at": "document_start", "all_frames": true, "match_about_blank": false}, {"matches": [""], "js": ["hcaptcha_language.js"], "run_at": "document_end", "all_frames": true, "match_about_blank": false}, {"matches": [""], "js": ["recaptcha.js", "recaptcha_speech.js"], "run_at": "document_end", "all_frames": true, "match_about_blank": false}, {"matches": ["*://*.google.com/recaptcha/*", "*://*.recaptcha.net/recaptcha/*", "*://recaptcha.net/recaptcha/*"], "js": ["recaptcha_fast.js"], "run_at": "document_start", "all_frames": true, "match_about_blank": false}, {"matches": ["*://*.arkoselabs.com/fc/*", "*://*.funcaptcha.com/fc/*"], "js": ["funcaptcha.js", "funcaptcha_scrape.js"], "run_at": "document_end", "all_frames": true, "match_about_blank": true}, {"matches": ["*://*.arkoselabs.com/fc/*", "*://*.funcaptcha.com/fc/*"], "js": ["funcaptcha_fast.js"], "run_at": "document_start", "all_frames": true, "match_about_blank": true}, {"matches": ["*://nopecha.com/demo/funcaptcha"], "js": ["funcaptcha_demo.js"], "run_at": "document_end", "all_frames": false, "match_about_blank": false}, {"matches": [""], "js": ["awscaptcha.js"], "run_at": "document_end", "all_frames": true, "match_about_blank": false}, {"matches": [""], "js": ["textcaptcha.js", "locate.js"], "run_at": "document_end", "all_frames": true, "match_about_blank": true}], "icons": {"16": "icon/16.png", "32": "icon/32.png", "48": "icon/48.png", "128": "icon/128.png"}, "manifest_version": 3, "action": {"default_title": "NopeCHA: CAPTCHA Solver", "default_icon": "icon/16.png", "default_popup": "popup.html"}, "background": {"service_worker": "background.js", "type": "module"}, "host_permissions": [""]} \ No newline at end of file diff --git a/third-party/nopecha-chrome-extension/popup.css b/third-party/nopecha-chrome-extension/popup.css deleted file mode 100644 index 341d44d..0000000 --- a/third-party/nopecha-chrome-extension/popup.css +++ /dev/null @@ -1,801 +0,0 @@ -@font-face { - font-family: 'plex-sans'; - font-style: normal; - font-weight: 700; - src: url('font/plex-sans-bold.woff2') format('woff2'), url('font/plex-sans-bold.woff') format('woff'); -} - -@font-face { - font-family: 'plex-sans'; - font-style: normal; - font-weight: 400; - src: url('font/plex-sans-regular.woff2') format('woff2'), url('font/plex-sans-regular.woff') format('woff'); -} - -* { - font-family: 'plex-sans'; - box-sizing: border-box; - outline: none; -} -html { - width: 340px; -} -body { - width: 324px; -} -html, body { - background: #1a2432; - color: #fff; - line-height: 1.15; - text-size-adjust: 100%; -} -div { - display: block; -} -a { - text-decoration: none; -} -button, input, optgroup, select, textarea { - font-family: inherit; - font-size: 100%; - line-height: 1.15; - margin: 0px; -} -button, select { - text-transform: none; -} -button, input { - overflow: visible; -} -input { - writing-mode: horizontal-tb !important; - font-style: ; - font-variant-ligatures: ; - font-variant-caps: ; - font-variant-numeric: ; - font-variant-east-asian: ; - font-weight: ; - font-stretch: ; - font-size: ; - font-family: ; - text-rendering: auto; - color: fieldtext; - letter-spacing: normal; - word-spacing: normal; - line-height: normal; - text-transform: none; - text-indent: 0px; - text-shadow: none; - display: inline-block; - text-align: start; - appearance: auto; - -webkit-rtl-ordering: logical; - cursor: text; - background-color: field; - margin: 0em; - padding: 1px 2px; - border-width: 2px; - border-style: inset; - border-color: -internal-light-dark(rgb(118, 118, 118), rgb(133, 133, 133)); - border-image: initial; -} -.text_input { - background-color: transparent; - padding: 8px 8px 8px 16px; - color: rgb(255, 255, 255); - outline: none; - border: none; - width: 100%; - font-size: 14px; -} -.text_input.small { - width: 30%; -} -.text_input.text_right { - text-align: right; -} -.hidden { - display: none !important; -} -.hiddenleft { - transform: translateX(-100%) translateZ(0px); -} -.red { - color: #ff6961 !important; -} - -/* Remove arrows from number input */ -input::-webkit-outer-spin-button, -input::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; -} -input[type=number] { - -moz-appearance: textfield; -} - -/* SCROLLBAR */ - -::-webkit-scrollbar { - width: 6px; - right: 2px; - bottom: 2px; - top: 2px; - border-radius: 3px; -} -::-webkit-scrollbar-track { - background: transparent; -} -::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.2); -} - -/* LOADING OVERLAY */ - -#loading_overlay { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - background: #222; - z-index: 10; -} -#loading_overlay .loading_text { - margin-top: 8px; - font-size: 14px; - text-align: center; -} -#loading_overlay .loading_text.timeout > div { - opacity: 0; - animation: fadein 10s linear forwards; -} -#loading_overlay .loading_text.timeout > div:nth-child(1) { - animation-delay: 2000ms; -} -#loading_overlay .loading_text.timeout > div:nth-child(2) { - animation-delay: 4000ms; -} -#loading_overlay .loading_text.timeout > div:nth-child(3) { - animation-delay: 6000ms; -} -@keyframes fadein { - 0% {opacity: 0;} - 50% {opacity: 0;} - 100% {opacity: 1;} -} - -/* MISC */ -.clickable { - cursor: pointer !important; -} -.clickable:hover { - opacity: 0.8 !important; -} - -/* APP */ - -#app_frame { - display: flex; - flex-direction: column; - overflow: hidden; - transition: height ease 0.2s, min-height ease 0.2s; - min-height: 237px !important; -} - -/* HEADER */ - -.header { - box-sizing: border-box; - padding: 16px; - display: flex; - place-content: space-between; - font-weight: 400; -} -.header.spacedright { - margin-right: 32px; -} -.nav_icon { - border: none; - cursor: pointer; - display: flex; - -webkit-box-align: center; - align-items: center; - -webkit-box-pack: center; - justify-content: center; - background: rgba(2, 13, 28, 0.05); - border-radius: 50%; - width: 32px; - height: 32px; - position: relative; - transition: all 0.3s ease 0s; - fill: rgba(255, 255, 255, 1); - background: rgba(255, 255, 255, 0.1) !important; -} -.nav_icon:hover { - opacity: 0.9; -} -.nav_icon:disabled, -.nav_icon:disabled:hover { - background: none !important; - cursor: unset; - opacity: 0.9; -} -.header_label_container { - box-sizing: border-box; - margin-right: 0px; - display: flex; - flex: 1 1 0%; - -webkit-box-pack: center; - justify-content: center; - -webkit-box-align: center; - align-items: center; -} -.header_label { - box-sizing: border-box; - font-size: 24px; - font-weight: bold; - display: flex; - color: rgb(255, 255, 255); -} - -/* PLAN */ - -.plan_info_box { - position: relative; - width: 100%; - height: 100%; -} -.plan_info_container { - display: flex; - box-sizing: border-box; - position: relative; -} -.plan_info { - box-sizing: border-box; - width: 100%; - padding: 0px 16px 16px; - display: flex; -} -.plan_label { - box-sizing: border-box; - font-weight: bold; - font-size: 14px; - color: rgb(255, 255, 255); -} -.plan_value { - box-sizing: border-box; - margin-left: auto; - display: flex; -} -.plan_button { - display: flex; - background-color: transparent; - color: rgba(255, 255, 255, 0.9); - width: auto; - padding: 0px; - border: none; - -webkit-box-align: center; - align-items: center; - -webkit-box-pack: center; - justify-content: center; - transition: color 0.3s ease 0s, transform 0.1s ease-out 0s, opacity 0.3s ease 0s; -} -.plan_button.link { - color: #0a95ff; -} -.plan_button.link, -.plan_button.link:hover, -.plan_button_label { - box-sizing: border-box; - font-size: 14px; -} - -/* WARNING */ - -.warning_box { - display: flex; - flex-direction: column; - justify-content: center; - background: #1a2432; - position: absolute; - top: 0; - bottom: 8px; - left: 4px; - right: 4px; - border: 1px solid #FCD62E; - border-radius: 0.25rem; - padding: 0.5rem; - margin: 0 4px; - z-index: 1; -} -.warning_box * { - color: #fff; - font-size: 14px; - text-align: center; -} - -/* KEY */ - -.key_label { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: space-between; - width: 100%; -} -.key_label > .instructions { - font-weight: normal; - line-height: 16px; - margin-left: 6px; - color: #fff; - font-size: 10px; -} -.settings_text[data-settings="key"] { - background: #1a2432; - position: absolute; - width: calc(100% - 32px); - transition: all ease 0.1s; - z-index: 1; -} -/* .edit_key { - line-height: 16px; - margin-right: 6px; - color: #fff; - font-size: 10px; -} */ -.edit_icon { - z-index: 2; -} - -/* MENU */ - -.menu { - box-sizing: border-box; - padding-left: 16px; -} -.menu_item_container { - border-top: none; - border-right: none; - border-left: none; - border-image: initial; - cursor: pointer; - display: flex; - -webkit-box-align: center; - align-items: center; - background-color: transparent; - width: 100%; - padding: 16px; - margin-top: 2px; - border-bottom: 2px solid rgba(255, 255, 255, 0.05); - color: rgba(255, 255, 255, 0.5); - transition: color 0.5s ease 0s, border 0.5s ease 0s; - -webkit-box-pack: justify !important; - justify-content: space-between !important; -} -.menu_item_container:hover { - color: rgb(255, 255, 255); -} -button.menu_item_container { - padding-left: 0px !important; -} -.button_label_container { - box-sizing: border-box; - -webkit-box-align: center; - align-items: center; - display: flex; -} -.button_label_container svg { - fill: rgb(255, 255, 255); -} -.button_label { - box-sizing: border-box; - margin-left: 16px; - font-size: 14px; - font-weight: bold; -} -.menu_item_arrow { - fill: rgb(255, 255, 255); - height: 16px; - width: 16px; -} - -/* #export { - color: rgba(255, 255, 255, 0.5); - font-size: 1.2em; - cursor: pointer; - transition: color 0.5s ease 0s, border 0.5s ease 0s; -} -#export:hover { - color: rgb(255, 255, 255); -} */ - -/* TAB */ - -.bbflex { - box-sizing: border-box; - display: flex; - -webkit-box-align: center; - align-items: center; -} -.scrolling_container { - box-sizing: border-box; - margin-top: 8px; - margin-left: 16px; - margin-right: 16px; - padding-bottom: 16px; -} -.settings_item_container { - box-sizing: border-box; - margin-bottom: 8px; - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 8px; - box-sizing: border-box; -} -.settings_item_container > a { - color: rgba(255, 255, 255, 0.5); - text-decoration: none; - transition: color 0.5s ease 0s, border 0.5s ease 0s; -} -.settings_item { - width: 100%; - background-color: rgba(255, 255, 255, 0.08); - min-height: 48px; - padding: 14px 16px 0px; - border-radius: 8px; -} -.settings_item > div { - -webkit-box-pack: justify; - justify-content: space-between; - -webkit-box-align: center; - align-items: center; -} -.settings_item_label { - font-size: 14px; - font-weight: 600; - color: rgb(255, 255, 255); - padding-left: 16px; - height: 20px; - -webkit-box-align: center; - align-items: center; -} -.settings_toggle { - height: 20px; - max-width: 36px; - min-width: 36px; - border-radius: 10px; - padding: 2px; - transition: background-color 0.3s ease 0s; - opacity: 1; - cursor: pointer; -} -.settings_toggle > div { - width: 16px; - height: 16px; - border-radius: 50%; - transform: translate(16px); - transition: transform 0.3s ease 0s, background-color 0.3s ease 0s; -} -.settings_toggle.on { - background-color: rgb(0, 106, 255); -} -.settings_toggle.off { - background-color: rgb(255, 255, 255); -} -.settings_toggle.on > div { - background-color: rgb(255, 255, 255); - transform: translate(16px); -} -.settings_toggle.off > div { - background-color: rgb(2, 13, 28); - transform: translate(0px); -} -.settings_description_container { - padding: 10px 16px 8px; - -webkit-box-pack: justify; - justify-content: space-between; -} -.settings_description { - font-size: 12px; - color: rgba(255, 255, 255, 0.5); -} -.settings_button { - color: rgba(255, 255, 255, 0.5); - font-size: 14px; - gap: 16px; -} -.settings_button > div { - cursor: pointer; - transition: all 0.3s ease 0s; -} -.settings_button > div:hover { - color: rgb(255, 255, 255); -} -.settings_dropdown_selected { - color: rgba(255, 255, 255, 0.5); - -webkit-box-align: center; - align-items: center; - font-size: 14px; - cursor: pointer; - white-space: nowrap; -} -.settings_dropdown_selected > div { - box-sizing: border-box; - margin-right: 8px; -} -.settings_dropdown_options { - position: relative; - transition: visibility 0.3s ease 0s, opacity 0.3s ease 0s; - opacity: 0; - visibility: hidden; -} -.settings_dropdown_options > div { - position: absolute; - background-color: rgb(255, 255, 255); - border-radius: 4px; - right: 0px; - top: 50%; - transform: translateY(-50%); - border: 1px solid rgba(0, 0, 0, 0.15); - width: auto; - min-width: 60px; - white-space: nowrap; - box-shadow: rgb(0 0 0 / 15%) 0px 2px 4px 0px; - box-sizing: border-box; - padding: 4px; -} -.settings_dropdown_selected:hover > .settings_dropdown_options { - opacity: 1; - visibility: visible; -} -.settings_dropdown_options > div > div { - color: rgba(0, 0, 0, 0.5); - font-weight: 700; - border-radius: 4px; - -webkit-box-pack: center; - justify-content: center; - -webkit-box-align: center; - align-items: center; - line-height: normal; - font-size: 12px; - height: 23px; - cursor: pointer; - padding: 0px 4px; -} -.settings_dropdown_options > div > div:hover { - background-color: rgba(0, 0, 0, 0.08); -} -.settings_dropdown_options > div > div.selected { - color: rgb(0, 106, 255); -} - -/* FOOTER */ - -.footer { - display: flex; - flex-direction: row; - padding: 8px; - margin-top: 8px; - font-size: 10px; -} -.footer * { - color: rgba(255, 255, 255, 0.8); -} -.footer > *:nth-child(1) { - flex-grow: 1; -} - -/* LOADING ANIM */ - -.loading { - display: inline-block; - position: relative; - width: 32px; - height: 16px; -} -.loading div { - position: absolute; - top: 5px; - width: 6px; - height: 6px; - border-radius: 50%; - background: rgba(255, 255, 255, 0.8); - animation-timing-function: cubic-bezier(0, 1, 1, 0); -} -.loading div:nth-child(1) { - left: 4px; - animation: loading1 0.6s infinite; -} -.loading div:nth-child(2) { - left: 4px; - animation: loading2 0.6s infinite; -} -.loading div:nth-child(3) { - left: 16px; - animation: loading2 0.6s infinite; -} -.loading div:nth-child(4) { - left: 28px; - animation: loading3 0.6s infinite; -} -@keyframes loading1 { - 0% { - transform: scale(0); - } - 100% { - transform: scale(1); - } -} -@keyframes loading3 { - 0% { - transform: scale(1); - } - 100% { - transform: scale(0); - } -} -@keyframes loading2 { - 0% { - transform: translate(0, 0); - } - 100% { - transform: translate(12px, 0); - } -} - -/* POWER ANIM */ - -#power .btn { - width: 32px; - height: 32px; - transition: transform 0.3s ease 0s; -} -#power .btn.off { - transform: rotate(-180deg); -} -#power .btn_outline { - position: absolute; - z-index: 2; - height: 100%; -} -#power .btn_outline.spinning { - animation: 1s linear 0s infinite normal none running spinning; -} -@keyframes spinning { - 0% {transform: rotate(0deg);} - 100% {transform: rotate(360deg);} -} - -/* GLOW ANIM */ - -.hover_glow { - border: none; - outline: none; - cursor: pointer; - position: relative; - z-index: 0; - border-radius: 50%; -} -.hover_glow:before { - content: ''; - background: linear-gradient(45deg, #ff0000, #ff7300, #fffb00, #48ff00, #00ffd5, #002bff, #7a00ff, #ff00c8, #ff0000); - position: absolute; - top: -2px; - left:-2px; - background-size: 400%; - z-index: -1; - filter: blur(5px); - width: calc(100% + 4px); - height: calc(100% + 4px); - animation: glowing 20s linear infinite; - opacity: 0; - transition: opacity .3s ease-in-out; - border-radius: 50%; -} -.hover_glow:active:after { - background: transparent; -} -.hover_glow:hover:before { - opacity: 1; -} -.hover_glow:after { - z-index: -1; - content: ''; - position: absolute; - width: 100%; - height: 100%; - left: 0; - top: 0; - border-radius: 50%; -} -.hover_glow.static:before { - opacity: 1 !important; -} -@keyframes glowing { - 0% {background-position: 0 0;} - 50% {background-position: 400% 0;} - 100% {background-position: 0 0;} -} - - -/* BLACKLIST */ - -.settings_item_header { - box-sizing: border-box; - padding-top: 4px; - padding-bottom: 8px; - font-size: 12px; - background-color: rgb(26, 36, 50); - width: 100%; - letter-spacing: 2px; - font-weight: bold; - color: rgba(255, 255, 255, 0.5); - text-transform: uppercase; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - position: relative; - top: 12px; - z-index: 1; -} -.settings_item_container.list_item { - border-radius: 0; - border: none; - border-bottom: 2px solid rgba(255, 255, 255, 0.05); - padding-top: 16px; - padding-bottom: 16px; - margin-bottom: 0px; -} -.list_item_row { - box-sizing: border-box; - -webkit-box-align: center; - align-items: center; - -webkit-box-pack: justify; - justify-content: space-between; - width: 100%; - display: flex; -} -#current_page_host { - box-sizing: border-box; - font-size: 14px; - font-weight: bold; - color: rgb(255, 255, 255); - width: fit-content; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - max-width: 220px; -} -.settings_text.text_input.list_input { - flex-grow: 1; - padding-left: 0; -} -.list_item_button { - border: none; - cursor: pointer; - display: flex; - -webkit-box-align: center; - align-items: center; - -webkit-box-pack: center; - justify-content: center; - background-color: transparent; - padding: 0px; - transition: background-color 0.3s ease 0s, color 0.3s ease 0s, transform 0.1s ease-out 0s, opacity 0.3s ease 0s; - opacity: 0.5; - height: 32px; - width: 32px; - margin-right: -4px; -} -.list_item_button:hover { - opacity: 1.0; -} -.list_item_button:disabled, -.list_item_button:disabled:hover { - opacity: 0.3; - cursor: unset; -} - diff --git a/third-party/nopecha-chrome-extension/popup.html b/third-party/nopecha-chrome-extension/popup.html deleted file mode 100644 index f1e8b87..0000000 --- a/third-party/nopecha-chrome-extension/popup.html +++ /dev/null @@ -1,873 +0,0 @@ - - - - - - - -
- - - -
Loading
-
-
This is taking longer than usual.
-
Please close this window and try again.
-
If the problem persists, contact us on Discord
-
-
- - - -
- - - - - - - - - - - - - - - - - -
-
- - -
- -
- - - - -
- -
- -
-
-
Subscription Key
-
(Click to enter)
-
-
- -
-
-
- -
- -
- - -
-
-
Free Plan
- -
-
- -
-
-
Credits
- -
-
- -
-
-
Refills
- -
-
-
- - - - -
- - - - - - - -
- - - - - - - diff --git a/third-party/nopecha-chrome-extension/popup.js b/third-party/nopecha-chrome-extension/popup.js deleted file mode 100644 index 6955f4c..0000000 --- a/third-party/nopecha-chrome-extension/popup.js +++ /dev/null @@ -1 +0,0 @@ -let plan=null,checking_server_plan=!1,rendering_server_plan=!1;function sleep(t){return new Promise(e=>setTimeout(t))}function get_loading_html(){return'
'}function number_with_comma(e){return(e=e||0).toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}async function check_plan(){var e=await BG.exec("Settings.get");e&&!checking_server_plan&&(checking_server_plan=!0,(plan=(plan=await BG.exec("Server.get_plan",{key:e.key})).error?{error:!0,plan:plan.message,credit:0,quota:0,duration:null,lastreset:null,current_period_start:1,current_period_end:1}:plan).subscription=["Starter","Basic","Professional","Enterprise"].includes(plan.plan),plan.expired=!1,plan.subscription?(e=Date.now()/1e3,plan.current_period_end-e<0&&(plan.expired=!0,plan.credit=0,plan.quota=0)):["GitHub","Discord","Booster"].includes(plan.plan)&&(e=Date.now()/1e3,0===Math.max(0,plan.lastreset-plan.duration-e))&&(plan.expired=!0,plan.credit=0,plan.quota=0),plan.invalid=!1,["Banned IP","Invalid key","Rate limit reached"].includes(plan.plan)?plan.invalid=!0:plan.plan=plan.plan+" Plan",checking_server_plan=!1,document.querySelector("#loading_overlay").classList.add("hidden"))}async function render_plan(){var t=await BG.exec("Settings.get");if(t&&plan&&!rendering_server_plan){rendering_server_plan=!0;var t=document.querySelector("#plan"),n=document.querySelector("#credit"),a=document.querySelector("#refills"),s=document.querySelector("#ipbanned_warning"),d=Date.now()/1e3;let e=null;plan.lastreset&&plan.duration&&(e=Math.floor(Math.max(0,plan.duration-(d-plan.lastreset)))),t.innerHTML=plan.plan,plan.invalid||plan.error?t.classList.add("red"):t.classList.remove("red"),"Banned IP"===plan.plan?s.classList.remove("hidden"):s.classList.add("hidden"),n.innerHTML=number_with_comma(plan.credit)+" / "+number_with_comma(plan.quota),0===plan.credit?n.classList.add("red"):n.classList.remove("red"),plan.expired?(a.innerHTML="Expired",a.classList.add("red")):(plan.duration<0?(a.innerHTML="No refills",a.classList.add("red")):(e?(d=Time.seconds_as_hms(e),a.innerHTML=""+d):a.innerHTML=get_loading_html(),a.classList.remove("red")),1===plan.lastreset?(a.innerHTML="Not activated",a.classList.add("red")):0{clearTimeout(s),t.classList.add("hidden"),n.classList.add("hidden"),a.classList.contains("off")?(a.classList.remove("off"),t.classList.remove("hidden"),await BG.exec("Settings.set",{id:"enabled",value:!0}),await BG.exec("Icon.set",{status:"on"}),s=setTimeout(()=>{t.classList.add("hidden"),n.classList.remove("hidden")},1e3)):(await BG.exec("Settings.set",{id:"enabled",value:!1}),await BG.exec("Icon.set",{status:"off"}),a.classList.add("off"))});const d=document.querySelector('.settings_text[data-settings="key"]'),r=document.querySelector(".edit_icon"),l=document.querySelector(".key_label");function c(){d.classList.contains("hiddenleft")?(d.classList.remove("hiddenleft"),d.focus(),r.classList.remove("hidden"),l.classList.add("hidden")):(d.classList.add("hiddenleft"),r.classList.add("hidden"),l.classList.remove("hidden"))}document.querySelector("#edit_key").addEventListener("click",()=>{c(),check_plan()}),d.addEventListener("keydown",e=>{"Enter"===(e=e||window.event).key&&(c(),check_plan(),0{for(const e of document.querySelectorAll(".tab"))e.classList.add("hidden");document.querySelector(`[data-tab="${y.dataset.tabtarget}"]`).classList.remove("hidden")});function o(){document.querySelector(".tab:not(.hidden)").querySelector(".back")?.click()}document.addEventListener("mousedown",e=>{0<(8&(e=e||window.event).buttons)&&o()}),document.addEventListener("keydown",e=>{"Backspace"!==(e=e||window.event).key||e.target instanceof HTMLInputElement||o()});for(const[f,h]of Object.entries(i)){for(const g of document.querySelectorAll(`.settings_toggle[data-settings="${f}"]`))g.classList.remove("on","off"),g.classList.add(h?"on":"off"),g.addEventListener("click",async()=>{var e=g.classList.contains("off");await BG.exec("Settings.set",{id:f,value:e}),g.classList.remove("on","off"),g.classList.add(e?"on":"off")});for(const S of document.querySelectorAll(`.settings_dropdown[data-settings="${f}"]`))S.dataset.value===h&&(S.classList.add("selected"),document.querySelector(S.dataset.displays).innerHTML=S.innerHTML),S.addEventListener("click",async()=>{document.querySelector(`.settings_dropdown.selected[data-settings="${f}"]`)?.classList?.remove("selected");var e=S.dataset.value;await BG.exec("Settings.set",{id:f,value:e}),S.classList.add("selected"),document.querySelector(S.dataset.displays).innerHTML=S.innerHTML});for(const w of document.querySelectorAll(`.settings_text[data-settings="${f}"]`))w.value=h,w.addEventListener("input",async()=>{var e=w.value;await BG.exec("Settings.set",{id:f,value:e})})}for(const q of document.querySelectorAll(".locate"))q.addEventListener("click",async()=>{var e=q.dataset.key;await BG.exec("Relay.send",{data:{action:"start_locate",locate:e}}),window.close()});const u=document.querySelector("#disabled_hosts");async function p(e=!0){var t=new Set;for(const n of i.disabled_hosts)t.add(n.trim());i.disabled_hosts=[...t],await BG.exec("Settings.set",{id:"disabled_hosts",value:i.disabled_hosts}),e&&await v()}async function v(){u.innerHTML="";var e=document.querySelector("#template > #disabled_hosts_item");let t=null;for(const a in i.disabled_hosts){var n=i.disabled_hosts[a]?.trim();if(n){const s=e.cloneNode(!0),d=(s.id=null,s.querySelector("input.hostname"));d.value=n,d.addEventListener("input",()=>{clearTimeout(t),i.disabled_hosts[a]=d.value,t=setTimeout(async()=>{await p(!1)},200)}),s.querySelector(".remove").addEventListener("click",()=>{var e=i.disabled_hosts.indexOf(d.value);-1!==e&&(i.disabled_hosts.splice(e,1),p(!1)),s.remove()}),u.append(s)}}}!async function(){var e=await BG.exec("Tab.active");const t=(e.url||"Unknown Host").replace(/^(.*:)\/\/([A-Za-z0-9\-\.]+)(:[0-9]+)?(.*)$/,"$2");document.querySelector("#current_page_host").innerHTML=t;let n=!0;e.url&&!i.disabled_hosts.includes(i.disabled_hosts)||(n=!1),e=document.querySelector("#add_current_page_host"),n?e.addEventListener("click",async()=>{i.disabled_hosts.push(t),await p()}):e.disabled=!0}(),v(),document.querySelector("#export").addEventListener("click",async()=>{var e=await BG.exec("Settings.get"),e=SettingsManager.export(e);window.open(e,"_blank")});var m="Version "+chrome.runtime.getManifest().version;for(const b of document.querySelectorAll(".footer")){var _=document.createElement("div"),L=(_.innerHTML=m,document.createElement("div"));L.innerHTML="2022 NopeCHA",b.append(_),b.append(L)}}async function main(){await init_ui(),await check_plan(),await render_plan(),setInterval(render_plan,500)}document.addEventListener("DOMContentLoaded",main); diff --git a/third-party/nopecha-chrome-extension/recaptcha.js b/third-party/nopecha-chrome-extension/recaptcha.js deleted file mode 100644 index 6c18317..0000000 --- a/third-party/nopecha-chrome-extension/recaptcha.js +++ /dev/null @@ -1 +0,0 @@ -(async()=>{function e(){var e="true"===document.querySelector(".recaptcha-checkbox")?.getAttribute("aria-checked"),t=document.querySelector("#recaptcha-verify-button")?.disabled;return e||t}function d(r=15e3){return new Promise(async e=>{for(var t=Time.time();;){var a=document.querySelectorAll(".rc-imageselect-tile"),c=document.querySelectorAll(".rc-imageselect-dynamic-selected");if(0r)return e(!1);await Time.sleep(100)}})}let p=null;function a(e=500){return new Promise(m=>{let h=!1;const f=setInterval(async()=>{if(!h){h=!0;var c=document.querySelector(".rc-imageselect-instructions")?.innerText?.split("\n"),r=await async function(e){let t=null;return(t=1{let i=null,t=!1,n=!1;function s(e){let t=e;for(;t&&!t.classList?.contains("rc-imageselect-tile");)t=t.parentNode;return t}function a(e,t,n=!1){!e||!n&&i===e||(!0===t&&e.classList.contains("rc-imageselect-tileselected")||!1===t&&!e.classList.contains("rc-imageselect-tileselected"))&&e.click()}document.addEventListener("mousedown",e=>{e=s(e?.target);e&&(n=e.classList.contains("rc-imageselect-tileselected")?t=!0:!(t=!0),i=e)}),document.addEventListener("mouseup",e=>{t=!1,i=null}),document.addEventListener("mousemove",e=>{e=s(e?.target);t&&(i!==e&&null!==i&&a(i,n,!0),a(e,n))});window.addEventListener("load",()=>{var e=document.body.appendChild(document.createElement("style")).sheet;e.insertRule(".rc-imageselect-table-33, .rc-imageselect-table-42, .rc-imageselect-table-44 {transition-duration: 0.5s !important}",0),e.insertRule(".rc-imageselect-tile {transition-duration: 2s !important}",1),e.insertRule(".rc-imageselect-dynamic-selected {transition-duration: 1s !important}",2),e.insertRule(".rc-imageselect-progress {transition-duration: 0.5s !important}",3),e.insertRule(".rc-image-tile-overlay {transition-duration: 0.5s !important}",4),e.insertRule("#rc-imageselect img {pointer-events: none !important}",5)})})(); diff --git a/third-party/nopecha-chrome-extension/recaptcha_speech.js b/third-party/nopecha-chrome-extension/recaptcha_speech.js deleted file mode 100644 index fd09f38..0000000 --- a/third-party/nopecha-chrome-extension/recaptcha_speech.js +++ /dev/null @@ -1 +0,0 @@ -(async()=>{function e(){var e,t;if(!i())return e="true"===document.querySelector(".recaptcha-checkbox")?.getAttribute("aria-checked"),t=document.querySelector("#recaptcha-verify-button")?.disabled,e||t}function i(){return"Try again later"===document.querySelector(".rc-doscaptcha-header")?.innerText}async function t(){!0!==await BG.exec("Cache.get",{name:"recaptcha_widget_visible",tab_specific:!0})||e()||(await Time.sleep(500),document.querySelector("#recaptcha-anchor")?.click())}async function a(t){var a=await BG.exec("Cache.get",{name:"recaptcha_image_visible",tab_specific:!0});if(!0===a&&!e()&&!i()){a=document.querySelector(".rc-audiochallenge-tdownload-link")?.href,a=(fetch(a),document.querySelector("#audio-source")?.src?.replace("recaptcha.net","google.com"));let e=document.querySelector("html")?.getAttribute("lang")?.trim();e&&0!==e.length||(e="en");var c=Time.time(),a=await Net.fetch("https://engageub.pythonanywhere.com",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"input="+encodeURIComponent(a)+"&lang="+e});document.querySelector("#audio-response").value=a;a=parseInt(t.recaptcha_solve_delay_time)||1e3,t=t.recaptcha_solve_delay?a-(Time.time()-c):0;0{function e(){try{function t(t){return`

${t}

`}var e=[];for(const o of arguments)e.push(t(o));e.push(t('Join us on Discord')),document.body.innerHTML=e.join("
")}catch(t){}}try{var t,o;document.location.hash?(document.title="NopeCHA Setup",e("Importing NopeCHA Settings..."),await BG.exec("Settings.get"),t=SettingsManager.import(document.location.hash),e(`Visiting this URL will import your NopeCHA settings. -${o}`,`Successfully imported settings. -`+JSON.stringify(t,null,4))):e("Invalid URL.\nPlease set the URL hash and reload the page.","Example: https://nopecha.com/setup#TESTKEY123")}catch(t){e("Failed to import settings.\nPlease verify that your URL is formed properly.")}})(); diff --git a/third-party/nopecha-chrome-extension/textcaptcha.js b/third-party/nopecha-chrome-extension/textcaptcha.js deleted file mode 100644 index 358b4ec..0000000 --- a/third-party/nopecha-chrome-extension/textcaptcha.js +++ /dev/null @@ -1 +0,0 @@ -(async()=>{async function r(t){function c(a){return new Promise(t=>{const e=new Image;e.onload=()=>t(e),e.src=function(t){let e=t.style.backgroundImage;return e&&((t=e.trim().match(/(?!^)".*?"/g))&&0!==t.length||(e=null),e=t[0].replaceAll('"',"")),e}(a)})}try{return(await async function(t){var e=document.querySelector(t);if(e instanceof HTMLCanvasElement)return e;let a;if(a=e instanceof HTMLImageElement?e:await c(e))return(e=document.createElement("canvas")).width=a.naturalWidth,e.height=a.naturalHeight,e.getContext("2d").drawImage(a,0,0),e;throw Error("failed to get image element for "+t)}(t)).toDataURL("image/jpeg").split(";base64,")[1]}catch(t){return null}}let l=null;async function t(){var t,e,a,c,n=(t=500,await new Promise(e=>{let a=!1;const c=setInterval(async()=>{if(!a){a=!0;var t=await BG.exec("Settings.get");if(t&&t.textcaptcha_auto_solve){t=await r(t.textcaptcha_image_selector);if(t&&l!==t)return l=t,clearInterval(c),a=!1,e({image_data:t})}a=!1}},t)}))["image_data"],i=await BG.exec("Settings.get");i&&i.enabled&&i.textcaptcha_auto_solve&&(c=Time.time(),{job_id:e,data:n}=await NopeCHA.post({captcha_type:IS_DEVELOPMENT?"textcaptcha_dev":"textcaptcha",image_data:[n],key:i.key}),n)&&(a=(a=parseInt(i.textcaptcha_solve_delay_time))||100,0<(a=i.textcaptcha_solve_delay?a-(Time.time()-c):0)&&await Time.sleep(a),n)&&0 { - let getBackgroundPage = globalThis?.chrome?.extension?.getBackgroundPage; - if (getBackgroundPage){ - return getBackgroundPage() === window ? RunningAs.BACKGROUND : RunningAs.POPUP; - } - return globalThis?.chrome?.runtime?.onMessage ? RunningAs.CONTENT : RunningAs.WEB; -})(); - - -function deep_copy(obj) { - return JSON.parse(JSON.stringify(obj)); -} - - -class Util { - static CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - - static pad_left(s, char, n) { - while (`${s}`.length < n) { - s = `${char}${s}`; - } - return s; - } - - static capitalize(s) { - return s.charAt(0).toUpperCase() + s.slice(1); - } - - static parse_int(s, fallback) { - if (!s) { - s = fallback; - } - return parseInt(s); - } - - static parse_bool(s, fallback) { - if (s === 'true') { - s = true; - } - else if (s === 'false') { - s = false; - } - else { - s = fallback; - } - return s; - } - - static parse_string(s, fallback) { - if (!s) { - s = fallback; - } - return s; - } - - static parse_json(s, fallback) { - if (!s) { - s = fallback; - } - else { - s = JSON.parse(s); - } - return s; - } - - static generate_id(n) { - let result = ''; - for (let i = 0; i < n; i++) { - result += Util.CHARS.charAt(Math.floor(Math.random() * Util.CHARS.length)); - } - return result; - } -} - - -class Time { - static time() { - if (!Date.now) { - Date.now = () => new Date().getTime(); - } - return Date.now(); - } - - static date() { - return new Date(); - } - - static sleep(i=1000) { - return new Promise(resolve => setTimeout(resolve, i)); - } - - static async random_sleep(min, max) { - const duration = Math.floor(Math.random() * (max - min) + min); - return await Time.sleep(duration); - } - - static seconds_as_hms(t) { - t = Math.max(0, t); - const hours = Util.pad_left(Math.floor(t / 3600), '0', 2); - t %= 3600; - const minutes = Util.pad_left(Math.floor(t / 60), '0', 2); - const seconds = Util.pad_left(Math.floor(t % 60), '0', 2); - return `${hours}:${minutes}:${seconds}`; - } - - static string(d=null) { - if (!d) { - d = Time.date(); - } - const month = Util.pad_left(d.getMonth() + 1, '0', 2); - const date = Util.pad_left(d.getDate(), '0', 2); - const year = d.getFullYear(); - const hours = Util.pad_left(d.getHours() % 12, '0', 2); - const minutes = Util.pad_left(d.getMinutes(), '0', 2); - const seconds = Util.pad_left(d.getSeconds(), '0', 2); - const period = d.getHours() >= 12 ? 'PM' : 'AM'; - return `${month}/${date}/${year} ${hours}:${minutes}:${seconds} ${period}`; - } -} - - -class SettingsManager { - static DEFAULT = { - version: 15, - key: '', - - enabled: true, - disabled_hosts: [], - - hcaptcha_auto_open: true, - hcaptcha_auto_solve: true, - hcaptcha_solve_delay: true, - hcaptcha_solve_delay_time: 3000, - - recaptcha_auto_open: true, - recaptcha_auto_solve: true, - recaptcha_solve_delay: true, - recaptcha_solve_delay_time: 1000, - recaptcha_solve_method: 'Image', - - funcaptcha_auto_open: true, - funcaptcha_auto_solve: true, - funcaptcha_solve_delay: true, - funcaptcha_solve_delay_time: 1000, - - awscaptcha_auto_open: true, - awscaptcha_auto_solve: true, - awscaptcha_solve_delay: true, - awscaptcha_solve_delay_time: 1000, - - textcaptcha_auto_solve: true, - textcaptcha_solve_delay: true, - textcaptcha_solve_delay_time: 100, - textcaptcha_image_selector: '', - textcaptcha_input_selector: '', - }; - - static ENCODE_FIELDS = { - enabled: {parse: Util.parse_bool, encode: encodeURIComponent}, - disabled_hosts: {parse: Util.parse_json, encode: e => encodeURIComponent(JSON.stringify(e))}, - - hcaptcha_auto_open: {parse: Util.parse_bool, encode: encodeURIComponent}, - hcaptcha_auto_solve: {parse: Util.parse_bool, encode: encodeURIComponent}, - hcaptcha_solve_delay: {parse: Util.parse_bool, encode: encodeURIComponent}, - hcaptcha_solve_delay_time: {parse: Util.parse_int, encode: encodeURIComponent}, - - recaptcha_auto_open: {parse: Util.parse_bool, encode: encodeURIComponent}, - recaptcha_auto_solve: {parse: Util.parse_bool, encode: encodeURIComponent}, - recaptcha_solve_delay: {parse: Util.parse_bool, encode: encodeURIComponent}, - recaptcha_solve_delay_time: {parse: Util.parse_int, encode: encodeURIComponent}, - recaptcha_solve_method: {parse: Util.parse_string, encode: encodeURIComponent}, - - funcaptcha_auto_open: {parse: Util.parse_bool, encode: encodeURIComponent}, - funcaptcha_auto_solve: {parse: Util.parse_bool, encode: encodeURIComponent}, - funcaptcha_solve_delay: {parse: Util.parse_bool, encode: encodeURIComponent}, - funcaptcha_solve_delay_time: {parse: Util.parse_int, encode: encodeURIComponent}, - - awscaptcha_auto_open: {parse: Util.parse_bool, encode: encodeURIComponent}, - awscaptcha_auto_solve: {parse: Util.parse_bool, encode: encodeURIComponent}, - awscaptcha_solve_delay: {parse: Util.parse_bool, encode: encodeURIComponent}, - awscaptcha_solve_delay_time: {parse: Util.parse_int, encode: encodeURIComponent}, - - textcaptcha_auto_solve: {parse: Util.parse_bool, encode: encodeURIComponent}, - textcaptcha_solve_delay: {parse: Util.parse_bool, encode: encodeURIComponent}, - textcaptcha_solve_delay_time: {parse: Util.parse_int, encode: encodeURIComponent}, - textcaptcha_image_selector: {parse: Util.parse_string, encode: encodeURIComponent}, - textcaptcha_input_selector: {parse: Util.parse_string, encode: encodeURIComponent}, - }; - - static IMPORT_URL = 'https://nopecha.com/setup'; - static DELIMITER = '|'; - - static export(settings) { - if (!settings.key) { - return false; - } - - const fields = [settings.key]; - for (const k in SettingsManager.ENCODE_FIELDS) { - fields.push(`${k}=${SettingsManager.ENCODE_FIELDS[k].encode(settings[k])}`); - } - - const encoded_hash = `#${fields.join(SettingsManager.DELIMITER)}`; - - return `${SettingsManager.IMPORT_URL}${encoded_hash}`; - } - - static import(encoded_hash) { - const settings = {}; - - // Split by delimiter - const fields = encoded_hash.split(SettingsManager.DELIMITER); - if (fields.length === 0) { - return settings; - } - - // Parse key - const key = fields.shift(); - if (key.length <= 1) { - console.error('invalid key for settings', key); - return settings; - } - settings.key = key.substring(1); - - // Parse additional fields - for (const field of fields) { - const kv = field.split('='); - const k = kv.shift(); - const v_raw = kv.join('='); - - if (!(k in SettingsManager.ENCODE_FIELDS)) { - console.error('invalid field for settings', field); - continue; - } - - const v = decodeURIComponent(v_raw); - console.log('v', v); - settings[k] = SettingsManager.ENCODE_FIELDS[k].parse(v, SettingsManager.DEFAULT[k]); - } - - return settings; - } -} diff --git a/third-party/nopecha-chrome-extension/utils.mjs b/third-party/nopecha-chrome-extension/utils.mjs deleted file mode 100644 index e2cb57b..0000000 --- a/third-party/nopecha-chrome-extension/utils.mjs +++ /dev/null @@ -1,272 +0,0 @@ -'use strict'; - - -/** - * Set to true for the following behavior: - * - Request server to recognize using bleeding-edge models - * - Reload FunCAPTCHA on verification - */ -export const IS_DEVELOPMENT = false; -// export const BASE_API = 'https://dev-api.nopecha.com'; -export const BASE_API = 'https://api.nopecha.com'; - - -/** - * Trying to be an Enum but javascript doesn't have enums - */ -export class RunningAs { - // Background script running on-demand - static BACKGROUND = 'BACKGROUND'; - // Popup specified in manifest as "action" - static POPUP = 'POPUP'; - // Content script running in page - static CONTENT = 'CONTENT'; - // (somehow) Standalone run of script running in webpage - static WEB = 'WEB'; -} -Object.freeze(RunningAs); - - -export const runningAt = (() => { - let getBackgroundPage = globalThis?.chrome?.extension?.getBackgroundPage; - if (getBackgroundPage){ - return getBackgroundPage() === window ? RunningAs.BACKGROUND : RunningAs.POPUP; - } - return globalThis?.chrome?.runtime?.onMessage ? RunningAs.CONTENT : RunningAs.WEB; -})(); - - -export function deep_copy(obj) { - return JSON.parse(JSON.stringify(obj)); -} - - -export class Util { - static CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - - static pad_left(s, char, n) { - while (`${s}`.length < n) { - s = `${char}${s}`; - } - return s; - } - - static capitalize(s) { - return s.charAt(0).toUpperCase() + s.slice(1); - } - - static parse_int(s, fallback) { - if (!s) { - s = fallback; - } - return parseInt(s); - } - - static parse_bool(s, fallback) { - if (s === 'true') { - s = true; - } - else if (s === 'false') { - s = false; - } - else { - s = fallback; - } - return s; - } - - static parse_string(s, fallback) { - if (!s) { - s = fallback; - } - return s; - } - - static parse_json(s, fallback) { - if (!s) { - s = fallback; - } - else { - s = JSON.parse(s); - } - return s; - } - - static generate_id(n) { - let result = ''; - for (let i = 0; i < n; i++) { - result += Util.CHARS.charAt(Math.floor(Math.random() * Util.CHARS.length)); - } - return result; - } -} - - -export class Time { - static time() { - if (!Date.now) { - Date.now = () => new Date().getTime(); - } - return Date.now(); - } - - static date() { - return new Date(); - } - - static sleep(i=1000) { - return new Promise(resolve => setTimeout(resolve, i)); - } - - static async random_sleep(min, max) { - const duration = Math.floor(Math.random() * (max - min) + min); - return await Time.sleep(duration); - } - - static seconds_as_hms(t) { - t = Math.max(0, t); - const hours = Util.pad_left(Math.floor(t / 3600), '0', 2); - t %= 3600; - const minutes = Util.pad_left(Math.floor(t / 60), '0', 2); - const seconds = Util.pad_left(Math.floor(t % 60), '0', 2); - return `${hours}:${minutes}:${seconds}`; - } - - static string(d=null) { - if (!d) { - d = Time.date(); - } - const month = Util.pad_left(d.getMonth() + 1, '0', 2); - const date = Util.pad_left(d.getDate(), '0', 2); - const year = d.getFullYear(); - const hours = Util.pad_left(d.getHours() % 12, '0', 2); - const minutes = Util.pad_left(d.getMinutes(), '0', 2); - const seconds = Util.pad_left(d.getSeconds(), '0', 2); - const period = d.getHours() >= 12 ? 'PM' : 'AM'; - return `${month}/${date}/${year} ${hours}:${minutes}:${seconds} ${period}`; - } -} - - -export class SettingsManager { - static DEFAULT = { - version: 15, - key: '', - - enabled: true, - disabled_hosts: [], - - hcaptcha_auto_open: true, - hcaptcha_auto_solve: true, - hcaptcha_solve_delay: true, - hcaptcha_solve_delay_time: 3000, - - recaptcha_auto_open: true, - recaptcha_auto_solve: true, - recaptcha_solve_delay: true, - recaptcha_solve_delay_time: 1000, - recaptcha_solve_method: 'Image', - - funcaptcha_auto_open: true, - funcaptcha_auto_solve: true, - funcaptcha_solve_delay: true, - funcaptcha_solve_delay_time: 1000, - - awscaptcha_auto_open: true, - awscaptcha_auto_solve: true, - awscaptcha_solve_delay: true, - awscaptcha_solve_delay_time: 1000, - - textcaptcha_auto_solve: true, - textcaptcha_solve_delay: true, - textcaptcha_solve_delay_time: 100, - textcaptcha_image_selector: '', - textcaptcha_input_selector: '', - }; - - static ENCODE_FIELDS = { - enabled: {parse: Util.parse_bool, encode: encodeURIComponent}, - disabled_hosts: {parse: Util.parse_json, encode: e => encodeURIComponent(JSON.stringify(e))}, - - hcaptcha_auto_open: {parse: Util.parse_bool, encode: encodeURIComponent}, - hcaptcha_auto_solve: {parse: Util.parse_bool, encode: encodeURIComponent}, - hcaptcha_solve_delay: {parse: Util.parse_bool, encode: encodeURIComponent}, - hcaptcha_solve_delay_time: {parse: Util.parse_int, encode: encodeURIComponent}, - - recaptcha_auto_open: {parse: Util.parse_bool, encode: encodeURIComponent}, - recaptcha_auto_solve: {parse: Util.parse_bool, encode: encodeURIComponent}, - recaptcha_solve_delay: {parse: Util.parse_bool, encode: encodeURIComponent}, - recaptcha_solve_delay_time: {parse: Util.parse_int, encode: encodeURIComponent}, - recaptcha_solve_method: {parse: Util.parse_string, encode: encodeURIComponent}, - - funcaptcha_auto_open: {parse: Util.parse_bool, encode: encodeURIComponent}, - funcaptcha_auto_solve: {parse: Util.parse_bool, encode: encodeURIComponent}, - funcaptcha_solve_delay: {parse: Util.parse_bool, encode: encodeURIComponent}, - funcaptcha_solve_delay_time: {parse: Util.parse_int, encode: encodeURIComponent}, - - awscaptcha_auto_open: {parse: Util.parse_bool, encode: encodeURIComponent}, - awscaptcha_auto_solve: {parse: Util.parse_bool, encode: encodeURIComponent}, - awscaptcha_solve_delay: {parse: Util.parse_bool, encode: encodeURIComponent}, - awscaptcha_solve_delay_time: {parse: Util.parse_int, encode: encodeURIComponent}, - - textcaptcha_auto_solve: {parse: Util.parse_bool, encode: encodeURIComponent}, - textcaptcha_solve_delay: {parse: Util.parse_bool, encode: encodeURIComponent}, - textcaptcha_solve_delay_time: {parse: Util.parse_int, encode: encodeURIComponent}, - textcaptcha_image_selector: {parse: Util.parse_string, encode: encodeURIComponent}, - textcaptcha_input_selector: {parse: Util.parse_string, encode: encodeURIComponent}, - }; - - static IMPORT_URL = 'https://nopecha.com/setup'; - static DELIMITER = '|'; - - static export(settings) { - if (!settings.key) { - return false; - } - - const fields = [settings.key]; - for (const k in SettingsManager.ENCODE_FIELDS) { - fields.push(`${k}=${SettingsManager.ENCODE_FIELDS[k].encode(settings[k])}`); - } - - const encoded_hash = `#${fields.join(SettingsManager.DELIMITER)}`; - - return `${SettingsManager.IMPORT_URL}${encoded_hash}`; - } - - static import(encoded_hash) { - const settings = {}; - - // Split by delimiter - const fields = encoded_hash.split(SettingsManager.DELIMITER); - if (fields.length === 0) { - return settings; - } - - // Parse key - const key = fields.shift(); - if (key.length <= 1) { - console.error('invalid key for settings', key); - return settings; - } - settings.key = key.substring(1); - - // Parse additional fields - for (const field of fields) { - const kv = field.split('='); - const k = kv.shift(); - const v_raw = kv.join('='); - - if (!(k in SettingsManager.ENCODE_FIELDS)) { - console.error('invalid field for settings', field); - continue; - } - - const v = decodeURIComponent(v_raw); - console.log('v', v); - settings[k] = SettingsManager.ENCODE_FIELDS[k].parse(v, SettingsManager.DEFAULT[k]); - } - - return settings; - } -}