From e2ae3135893d979af40606429dfc150331c4e864 Mon Sep 17 00:00:00 2001 From: Daniel Salazar Date: Tue, 9 Dec 2025 15:59:21 -0800 Subject: [PATCH] feat: refactor ai to have single entry point and follow defined model structure (#2114) * feat: refactor ai to have single entry point and follow defined model structure * fix: missing openrouter registration * fix: dedupe models * feat: provide usage in stream mode :rocket: --- .gitignore | 3 +- package-lock.json | 2927 +---------------- package.json | 3 +- src/backend/exports.js | 55 +- src/backend/package.json | 2 +- src/backend/src/Kernel.js | 3 +- src/backend/src/api/APIError.js | 9 +- src/backend/src/api/filesystem/FSNodeParam.js | 8 +- .../src/filesystem/definitions/ts/fsentry.js | 15 +- .../src/modules/ai/PuterAIChatModule.js | 102 + .../src/modules/puterai/AIChatService.js | 792 ----- .../src/modules/puterai/AITestModeService.js | 42 - .../src/modules/puterai/ClaudeService.js | 495 --- .../src/modules/puterai/DeepSeekService.js | 224 -- .../src/modules/puterai/FakeChatService.js | 217 -- .../puterai/GeminiService/GeminiService.mjs | 114 - .../modules/puterai/GeminiService/models.mjs | 86 - .../src/modules/puterai/GroqAIService.js | 355 -- .../src/modules/puterai/MistralAIService.js | 621 ---- .../src/modules/puterai/OllamaService.js | 217 -- .../puterai/OpenAiCompletionService/index.mjs | 57 - .../OpenAiCompletionService/models.mjs | 206 -- .../src/modules/puterai/OpenRouterService.js | 214 -- .../src/modules/puterai/PuterAIModule.js | 164 - .../src/modules/puterai/TogetherAIService.js | 224 -- .../puterai/UsageLimitedChatService.js | 159 - src/backend/src/modules/puterai/XAIService.js | 251 -- .../puterai/experiment/stream_claude.js | 58 - .../puterai/experiment/stream_openai.js | 61 - .../modules/puterai/lib/FunctionCalling.js | 122 - .../src/modules/puterai/lib/Messages.js | 186 -- .../src/modules/puterai/samples/claude-1.js | 65 - .../modules/puterai/samples/claude-tools-1.js | 76 - .../src/modules/puterai/samples/openai-1.js | 46 - .../modules/puterai/samples/openai-tools-1.js | 102 - .../src/modules/test-core/TestCoreModule.js | 56 +- src/backend/src/om/entitystorage/BaseES.js | 9 - .../src/om/entitystorage/SubdomainES.js | 90 +- .../src/routers/get-launch-apps.test.js | 50 +- src/backend/src/services/BaseService.d.ts | 6 +- src/backend/src/services/ChatAPIService.js | 4 +- .../src/services/ChatAPIService.test.js | 8 +- .../MeteringService/MeteringService.ts | 2 +- .../costMaps/fileSystemCostMap.ts | 2 +- .../MeteringService/costMaps/index.ts | 32 +- .../costMaps/openaiImageCostMap.ts | 2 +- .../costMaps/openaiVideoCostMap.ts | 2 +- .../MeteringService/subPolicies/index.ts | 4 +- .../subPolicies/registeredUserFreePolicy.ts | 2 +- .../subPolicies/tempUserFreePolicy.ts | 2 +- src/backend/src/services/RegistryService.js | 8 +- .../src/services/RegistryService.test.ts | 28 +- src/backend/src/services/SUService.d.ts | 8 - src/backend/src/services/SUService.js | 16 +- src/backend/src/services/User.d.ts | 2 +- .../ai}/AIInterfaceService.js | 2 +- .../puterai => services/ai}/README.md | 0 src/backend/src/services/ai/chat/.gitignore | 2 + .../src/services/ai/chat/AIChatService.ts | 652 ++++ .../ai/chat/providers/ChatProvider.ts | 26 + .../ClaudeProvider/ClaudeProvider.test.ts} | 22 +- .../ClaudeProvider/ClaudeProvider.ts | 321 ++ .../chat/providers/ClaudeProvider/models.ts | 184 ++ .../DeepSeekProvider/DeepSeekProvider.ts | 131 + .../chat/providers/DeepSeekProvider/models.ts | 36 + .../ai/chat/providers/FakeChatProvider.ts | 173 + .../GeminiProvider/GeminiChatProvider.ts | 94 + .../chat/providers/GeminiProvider/models.ts | 94 + .../GroqAiProvider/GroqAIProvider.ts | 104 + .../chat/providers/GroqAiProvider/models.ts | 156 + .../MistralAiProvider/MistralAiProvider.ts | 121 + .../providers/MistralAiProvider/models.ts | 299 ++ .../ai/chat/providers/OllamaProvider.ts | 159 + .../OpenAiProvider/OpenAiChatProvider.ts} | 365 +- .../chat/providers/OpenAiProvider/models.ts | 265 ++ .../OpenRouterProvider/OpenRouterProvider.ts | 157 + .../TogetherAiProvider/TogetherAIProvider.ts | 140 + .../providers/UsageLimitedChatProvider.ts | 141 + .../chat/providers/XAIProvider/XAIProvider.ts | 96 + .../ai/chat/providers/XAIProvider/models.ts | 87 + .../src/services/ai/chat/providers/types.ts | 70 + .../doc => services/ai/docs}/README.md | 0 .../ai/docs}/ai-services-config.md | 0 .../doc => services/ai/docs}/api_examples.md | 0 .../doc => services/ai/docs}/config.md | 0 .../ai/docs}/contributors/ai_usage_testing.md | 0 .../ai/image}/GeminiImageGenerationService.js | 12 +- .../ai/image}/OpenAIImageGenerationService.js | 10 +- .../image}/TogetherImageGenerationService.js | 213 +- .../ai/moderation}/AsModeration.js | 29 +- .../ai/ocr}/AWSTextractService.js | 8 +- .../src/services/ai/ocr/MistralOCRService.js | 298 ++ .../ai/sts}/ElevenLabsVoiceChangerService.js | 24 +- .../ai/stt}/OpenAISpeechToTextService.js | 10 +- .../ai/tts}/AWSPollyService.js | 10 +- .../ai/tts}/ElevenLabsTTSService.js | 14 +- .../ai/tts}/OpenAITTSService.js | 10 +- .../src/services/ai/utils/FunctionCalling.js | 120 + src/backend/src/services/ai/utils/Messages.js | 184 ++ .../src/services/ai/utils/OpenAIUtil.d.ts | 116 + .../lib => services/ai/utils}/OpenAIUtil.js | 35 +- .../lib => services/ai/utils}/Streaming.js | 22 +- .../ai/utils}/messages.test.js | 4 +- .../ai/video}/OpenAIVideoGenerationService.js | 10 +- .../video}/TogetherVideoGenerationService.js | 10 +- src/backend/src/services/auth/Actor.d.ts | 65 +- src/backend/src/services/auth/Actor.js | 49 +- src/backend/src/services/database/consts.js | 22 +- .../src/services/drivers/DriverService.js | 1 - .../repositories/DBKVStore/DBKVStore.test.ts | 3 +- .../repositories/DBKVStore/DBKVStore.ts | 10 +- src/backend/src/util/context.js | 23 +- src/backend/src/util/kvSingleton.js | 3 + src/backend/tools/test.mjs | 26 +- src/backend/vitest.config.ts | 2 +- tsconfig.base.json | 15 + tsconfig.build.json | 23 + tsconfig.json | 21 +- ws-debug.mjs | 53 + 119 files changed, 5127 insertions(+), 8839 deletions(-) create mode 100644 src/backend/src/modules/ai/PuterAIChatModule.js delete mode 100644 src/backend/src/modules/puterai/AIChatService.js delete mode 100644 src/backend/src/modules/puterai/AITestModeService.js delete mode 100644 src/backend/src/modules/puterai/ClaudeService.js delete mode 100644 src/backend/src/modules/puterai/DeepSeekService.js delete mode 100644 src/backend/src/modules/puterai/FakeChatService.js delete mode 100644 src/backend/src/modules/puterai/GeminiService/GeminiService.mjs delete mode 100644 src/backend/src/modules/puterai/GeminiService/models.mjs delete mode 100644 src/backend/src/modules/puterai/GroqAIService.js delete mode 100644 src/backend/src/modules/puterai/MistralAIService.js delete mode 100644 src/backend/src/modules/puterai/OllamaService.js delete mode 100644 src/backend/src/modules/puterai/OpenAiCompletionService/index.mjs delete mode 100644 src/backend/src/modules/puterai/OpenAiCompletionService/models.mjs delete mode 100644 src/backend/src/modules/puterai/OpenRouterService.js delete mode 100644 src/backend/src/modules/puterai/PuterAIModule.js delete mode 100644 src/backend/src/modules/puterai/TogetherAIService.js delete mode 100644 src/backend/src/modules/puterai/UsageLimitedChatService.js delete mode 100644 src/backend/src/modules/puterai/XAIService.js delete mode 100644 src/backend/src/modules/puterai/experiment/stream_claude.js delete mode 100644 src/backend/src/modules/puterai/experiment/stream_openai.js delete mode 100644 src/backend/src/modules/puterai/lib/FunctionCalling.js delete mode 100644 src/backend/src/modules/puterai/lib/Messages.js delete mode 100644 src/backend/src/modules/puterai/samples/claude-1.js delete mode 100644 src/backend/src/modules/puterai/samples/claude-tools-1.js delete mode 100644 src/backend/src/modules/puterai/samples/openai-1.js delete mode 100644 src/backend/src/modules/puterai/samples/openai-tools-1.js delete mode 100644 src/backend/src/services/SUService.d.ts rename src/backend/src/{modules/puterai => services/ai}/AIInterfaceService.js (99%) rename src/backend/src/{modules/puterai => services/ai}/README.md (100%) create mode 100644 src/backend/src/services/ai/chat/.gitignore create mode 100644 src/backend/src/services/ai/chat/AIChatService.ts create mode 100644 src/backend/src/services/ai/chat/providers/ChatProvider.ts rename src/backend/src/{modules/puterai/ClaudeService.test.ts => services/ai/chat/providers/ClaudeProvider/ClaudeProvider.test.ts} (70%) create mode 100644 src/backend/src/services/ai/chat/providers/ClaudeProvider/ClaudeProvider.ts create mode 100644 src/backend/src/services/ai/chat/providers/ClaudeProvider/models.ts create mode 100644 src/backend/src/services/ai/chat/providers/DeepSeekProvider/DeepSeekProvider.ts create mode 100644 src/backend/src/services/ai/chat/providers/DeepSeekProvider/models.ts create mode 100644 src/backend/src/services/ai/chat/providers/FakeChatProvider.ts create mode 100644 src/backend/src/services/ai/chat/providers/GeminiProvider/GeminiChatProvider.ts create mode 100644 src/backend/src/services/ai/chat/providers/GeminiProvider/models.ts create mode 100644 src/backend/src/services/ai/chat/providers/GroqAiProvider/GroqAIProvider.ts create mode 100644 src/backend/src/services/ai/chat/providers/GroqAiProvider/models.ts create mode 100644 src/backend/src/services/ai/chat/providers/MistralAiProvider/MistralAiProvider.ts create mode 100644 src/backend/src/services/ai/chat/providers/MistralAiProvider/models.ts create mode 100644 src/backend/src/services/ai/chat/providers/OllamaProvider.ts rename src/backend/src/{modules/puterai/OpenAiCompletionService/OpenAICompletionService.mjs => services/ai/chat/providers/OpenAiProvider/OpenAiChatProvider.ts} (62%) create mode 100644 src/backend/src/services/ai/chat/providers/OpenAiProvider/models.ts create mode 100644 src/backend/src/services/ai/chat/providers/OpenRouterProvider/OpenRouterProvider.ts create mode 100644 src/backend/src/services/ai/chat/providers/TogetherAiProvider/TogetherAIProvider.ts create mode 100644 src/backend/src/services/ai/chat/providers/UsageLimitedChatProvider.ts create mode 100644 src/backend/src/services/ai/chat/providers/XAIProvider/XAIProvider.ts create mode 100644 src/backend/src/services/ai/chat/providers/XAIProvider/models.ts create mode 100644 src/backend/src/services/ai/chat/providers/types.ts rename src/backend/src/{modules/puterai/doc => services/ai/docs}/README.md (100%) rename src/backend/src/{modules/puterai/doc => services/ai/docs}/ai-services-config.md (100%) rename src/backend/src/{modules/puterai/doc => services/ai/docs}/api_examples.md (100%) rename src/backend/src/{modules/puterai/doc => services/ai/docs}/config.md (100%) rename src/backend/src/{modules/puterai/doc => services/ai/docs}/contributors/ai_usage_testing.md (100%) rename src/backend/src/{modules/puterai => services/ai/image}/GeminiImageGenerationService.js (96%) rename src/backend/src/{modules/puterai => services/ai/image}/OpenAIImageGenerationService.js (97%) rename src/backend/src/{modules/puterai => services/ai/image}/TogetherImageGenerationService.js (59%) rename src/backend/src/{modules/puterai/lib => services/ai/moderation}/AsModeration.js (82%) rename src/backend/src/{modules/puterai => services/ai/ocr}/AWSTextractService.js (97%) create mode 100644 src/backend/src/services/ai/ocr/MistralOCRService.js rename src/backend/src/{modules/puterai => services/ai/sts}/ElevenLabsVoiceChangerService.js (94%) rename src/backend/src/{modules/puterai => services/ai/stt}/OpenAISpeechToTextService.js (97%) rename src/backend/src/{modules/puterai => services/ai/tts}/AWSPollyService.js (97%) rename src/backend/src/{modules/puterai => services/ai/tts}/ElevenLabsTTSService.js (94%) rename src/backend/src/{modules/puterai => services/ai/tts}/OpenAITTSService.js (95%) create mode 100644 src/backend/src/services/ai/utils/FunctionCalling.js create mode 100644 src/backend/src/services/ai/utils/Messages.js create mode 100644 src/backend/src/services/ai/utils/OpenAIUtil.d.ts rename src/backend/src/{modules/puterai/lib => services/ai/utils}/OpenAIUtil.js (89%) rename src/backend/src/{modules/puterai/lib => services/ai/utils}/Streaming.js (78%) rename src/backend/src/{modules/puterai/lib => services/ai/utils}/messages.test.js (98%) rename src/backend/src/{modules/puterai => services/ai/video}/OpenAIVideoGenerationService.js (96%) rename src/backend/src/{modules/puterai => services/ai/video}/TogetherVideoGenerationService.js (96%) create mode 100644 src/backend/src/util/kvSingleton.js create mode 100644 tsconfig.base.json create mode 100644 tsconfig.build.json create mode 100644 ws-debug.mjs diff --git a/.gitignore b/.gitignore index c2b1df4a..0160eeb6 100644 --- a/.gitignore +++ b/.gitignore @@ -66,4 +66,5 @@ AGENTS.md *.map -coverage/ \ No newline at end of file +coverage/ +*.log diff --git a/package-lock.json b/package-lock.json index cba4c2c7..cf994a5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,7 @@ "@eslint/js": "^9.35.0", "@playwright/test": "^1.56.1", "@stylistic/eslint-plugin": "^5.3.1", + "@types/mime-types": "^3.0.1", "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^8.46.1", "@typescript-eslint/parser": "^8.46.1", @@ -74,15 +75,11 @@ }, "node_modules/@acemir/cssom": { "version": "0.9.24", - "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.24.tgz", - "integrity": "sha512-5YjgMmAiT2rjJZU7XK1SNI7iqTy92DpaYVgG6x63FxkJ11UpYfLndHJATtinWJClAXiOlW9XWaUyAQf8pMrQPg==", "dev": true, "license": "MIT" }, "node_modules/@anthropic-ai/sdk": { "version": "0.68.0", - "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.68.0.tgz", - "integrity": "sha512-SMYAmbbiprG8k1EjEPMTwaTqssDT7Ae+jxcR5kWXiqTlbwMR2AthXtscEVWOHkRfyAV5+y3PFYTJRNa3OJWIEw==", "license": "MIT", "dependencies": { "json-schema-to-ts": "^3.1.1" @@ -101,8 +98,6 @@ }, "node_modules/@asamuzakjp/css-color": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.0.tgz", - "integrity": "sha512-9xiBAtLn4aNsa4mDnpovJvBn72tNEIACyvlqaNJ+ADemR+yeMJWnBudOi2qGDviJa7SwcDOU/TRh5dnET7qk0w==", "dev": true, "license": "MIT", "dependencies": { @@ -115,8 +110,6 @@ }, "node_modules/@asamuzakjp/dom-selector": { "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.5.tgz", - "integrity": "sha512-Eks6dY8zau4m4wNRQjRVaKQRTalNcPcBvU1ZQ35w5kKRk1gUeNCkVLsRiATurjASTp3TKM4H10wsI50nx3NZdw==", "dev": true, "license": "MIT", "dependencies": { @@ -129,15 +122,11 @@ }, "node_modules/@asamuzakjp/nwsapi": { "version": "2.3.9", - "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", - "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", "dev": true, "license": "MIT" }, "node_modules/@aws-crypto/sha256-browser": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", - "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", @@ -151,8 +140,6 @@ }, "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -163,8 +150,6 @@ }, "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^2.2.0", @@ -176,8 +161,6 @@ }, "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^2.2.0", @@ -189,8 +172,6 @@ }, "node_modules/@aws-crypto/sha256-js": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", @@ -203,8 +184,6 @@ }, "node_modules/@aws-crypto/supports-web-crypto": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", - "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -212,8 +191,6 @@ }, "node_modules/@aws-crypto/util": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.222.0", @@ -223,8 +200,6 @@ }, "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -235,8 +210,6 @@ }, "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^2.2.0", @@ -248,8 +221,6 @@ }, "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^2.2.0", @@ -261,8 +232,6 @@ }, "node_modules/@aws-sdk/client-cloudwatch": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch/-/client-cloudwatch-3.940.0.tgz", - "integrity": "sha512-C35xpPntRAGdEg3X5iKpSUCBaP3yxYNo1U95qipN/X1e0/TYIDWHwGt8Z1ntRafK19jp5oVzhRQ+PD1JAPSEzA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -313,8 +282,6 @@ }, "node_modules/@aws-sdk/client-polly": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-polly/-/client-polly-3.940.0.tgz", - "integrity": "sha512-OvDdWpU2Nz6LvjYJOf0S1b8mcvWfkTBzDdA5Qgx3gO2nCKcLa1eV+FhUcvcYBfI2LtENGj7QSD2TyIkJYgXuyQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -364,8 +331,6 @@ }, "node_modules/@aws-sdk/client-secrets-manager": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.940.0.tgz", - "integrity": "sha512-fpxSRsGyuXmyNqEwdGJUDWVgN0v8xR7tr32Quls3K+HnYlnBGFmISu5Pcc+BfwmrZHnPaVpPc+S3PUzTnFpOJg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -414,8 +379,6 @@ }, "node_modules/@aws-sdk/client-sns": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.940.0.tgz", - "integrity": "sha512-TtLmzU8ylChGESzPA21vzsJiN7KTW2uLoAhYb5JAkxK+AsZSqwfqK8ycLsbguOp7xLuM4cqMILoUvF5me5LXdw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -464,8 +427,6 @@ }, "node_modules/@aws-sdk/client-sso": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.940.0.tgz", - "integrity": "sha512-SdqJGWVhmIURvCSgkDditHRO+ozubwZk9aCX9MK8qxyOndhobCndW1ozl3hX9psvMAo9Q4bppjuqy/GHWpjB+A==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -513,8 +474,6 @@ }, "node_modules/@aws-sdk/client-textract": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-textract/-/client-textract-3.940.0.tgz", - "integrity": "sha512-2a5++Skf23eYpXVhoSGd9nDmJJ77wKJ0x8v6Rra6gF/dosYZ6gj3u7UQg/p0Y2SLa3RF/hHmCHtAuBSJ1zzTVQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -563,8 +522,6 @@ }, "node_modules/@aws-sdk/core": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.940.0.tgz", - "integrity": "sha512-KsGD2FLaX5ngJao1mHxodIVU9VYd1E8810fcYiGwO1PFHDzf5BEkp6D9IdMeQwT8Q6JLYtiiT1Y/o3UCScnGoA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.936.0", @@ -587,8 +544,6 @@ }, "node_modules/@aws-sdk/credential-provider-env": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.940.0.tgz", - "integrity": "sha512-/G3l5/wbZYP2XEQiOoIkRJmlv15f1P3MSd1a0gz27lHEMrOJOGq66rF1Ca4OJLzapWt3Fy9BPrZAepoAX11kMw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.940.0", @@ -603,8 +558,6 @@ }, "node_modules/@aws-sdk/credential-provider-http": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.940.0.tgz", - "integrity": "sha512-dOrc03DHElNBD6N9Okt4U0zhrG4Wix5QUBSZPr5VN8SvmjD9dkrrxOkkJaMCl/bzrW7kbQEp7LuBdbxArMmOZQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.940.0", @@ -624,8 +577,6 @@ }, "node_modules/@aws-sdk/credential-provider-ini": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.940.0.tgz", - "integrity": "sha512-gn7PJQEzb/cnInNFTOaDoCN/hOKqMejNmLof1W5VW95Qk0TPO52lH8R4RmJPnRrwFMswOWswTOpR1roKNLIrcw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.940.0", @@ -649,8 +600,6 @@ }, "node_modules/@aws-sdk/credential-provider-login": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.940.0.tgz", - "integrity": "sha512-fOKC3VZkwa9T2l2VFKWRtfHQPQuISqqNl35ZhcXjWKVwRwl/o7THPMkqI4XwgT2noGa7LLYVbWMwnsgSsBqglg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.940.0", @@ -668,8 +617,6 @@ }, "node_modules/@aws-sdk/credential-provider-node": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.940.0.tgz", - "integrity": "sha512-M8NFAvgvO6xZjiti5kztFiAYmSmSlG3eUfr4ZHSfXYZUA/KUdZU/D6xJyaLnU8cYRWBludb6K9XPKKVwKfqm4g==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/credential-provider-env": "3.940.0", @@ -691,8 +638,6 @@ }, "node_modules/@aws-sdk/credential-provider-process": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.940.0.tgz", - "integrity": "sha512-pILBzt5/TYCqRsJb7vZlxmRIe0/T+FZPeml417EK75060ajDGnVJjHcuVdLVIeKoTKm9gmJc9l45gon6PbHyUQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.940.0", @@ -708,8 +653,6 @@ }, "node_modules/@aws-sdk/credential-provider-sso": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.940.0.tgz", - "integrity": "sha512-q6JMHIkBlDCOMnA3RAzf8cGfup+8ukhhb50fNpghMs1SNBGhanmaMbZSgLigBRsPQW7fOk2l8jnzdVLS+BB9Uw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/client-sso": "3.940.0", @@ -727,8 +670,6 @@ }, "node_modules/@aws-sdk/credential-provider-web-identity": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.940.0.tgz", - "integrity": "sha512-9QLTIkDJHHaYL0nyymO41H8g3ui1yz6Y3GmAN1gYQa6plXisuFBnGAbmKVj7zNvjWaOKdF0dV3dd3AFKEDoJ/w==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.940.0", @@ -745,8 +686,6 @@ }, "node_modules/@aws-sdk/middleware-host-header": { "version": "3.936.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.936.0.tgz", - "integrity": "sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.936.0", @@ -760,8 +699,6 @@ }, "node_modules/@aws-sdk/middleware-logger": { "version": "3.936.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.936.0.tgz", - "integrity": "sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.936.0", @@ -774,8 +711,6 @@ }, "node_modules/@aws-sdk/middleware-recursion-detection": { "version": "3.936.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.936.0.tgz", - "integrity": "sha512-l4aGbHpXM45YNgXggIux1HgsCVAvvBoqHPkqLnqMl9QVapfuSTjJHfDYDsx1Xxct6/m7qSMUzanBALhiaGO2fA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.936.0", @@ -790,8 +725,6 @@ }, "node_modules/@aws-sdk/middleware-user-agent": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.940.0.tgz", - "integrity": "sha512-nJbLrUj6fY+l2W2rIB9P4Qvpiy0tnTdg/dmixRxrU1z3e8wBdspJlyE+AZN4fuVbeL6rrRrO/zxQC1bB3cw5IA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.940.0", @@ -808,8 +741,6 @@ }, "node_modules/@aws-sdk/nested-clients": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.940.0.tgz", - "integrity": "sha512-x0mdv6DkjXqXEcQj3URbCltEzW6hoy/1uIL+i8gExP6YKrnhiZ7SzuB4gPls2UOpK5UqLiqXjhRLfBb1C9i4Dw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -857,8 +788,6 @@ }, "node_modules/@aws-sdk/region-config-resolver": { "version": "3.936.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.936.0.tgz", - "integrity": "sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.936.0", @@ -873,8 +802,6 @@ }, "node_modules/@aws-sdk/token-providers": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.940.0.tgz", - "integrity": "sha512-k5qbRe/ZFjW9oWEdzLIa2twRVIEx7p/9rutofyrRysrtEnYh3HAWCngAnwbgKMoiwa806UzcTRx0TjyEpnKcCg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.940.0", @@ -891,8 +818,6 @@ }, "node_modules/@aws-sdk/types": { "version": "3.936.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.936.0.tgz", - "integrity": "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -904,8 +829,6 @@ }, "node_modules/@aws-sdk/util-endpoints": { "version": "3.936.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.936.0.tgz", - "integrity": "sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.936.0", @@ -920,8 +843,6 @@ }, "node_modules/@aws-sdk/util-locate-window": { "version": "3.893.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.893.0.tgz", - "integrity": "sha512-T89pFfgat6c8nMmpI8eKjBcDcgJq36+m9oiXbcUzeU55MP9ZuGgBomGjGnHaEyF36jenW9gmg3NfZDm0AO2XPg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -932,8 +853,6 @@ }, "node_modules/@aws-sdk/util-user-agent-browser": { "version": "3.936.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.936.0.tgz", - "integrity": "sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.936.0", @@ -944,8 +863,6 @@ }, "node_modules/@aws-sdk/util-user-agent-node": { "version": "3.940.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.940.0.tgz", - "integrity": "sha512-dlD/F+L/jN26I8Zg5x0oDGJiA+/WEQmnSE27fi5ydvYnpfQLwThtQo9SsNS47XSR/SOULaaoC9qx929rZuo74A==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/middleware-user-agent": "3.940.0", @@ -968,8 +885,6 @@ }, "node_modules/@aws-sdk/xml-builder": { "version": "3.930.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.930.0.tgz", - "integrity": "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -982,8 +897,6 @@ }, "node_modules/@aws/lambda-invoke-store": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.1.tgz", - "integrity": "sha512-sIyFcoPZkTtNu9xFeEoynMef3bPJIAbOfUh+ueYcfhVl6xm2VRtMcMclSxmZCMnHHd4hlYKJeq/aggmBEWynww==", "license": "Apache-2.0", "engines": { "node": ">=18.0.0" @@ -991,8 +904,6 @@ }, "node_modules/@babel/code-frame": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", @@ -1005,8 +916,6 @@ }, "node_modules/@babel/compat-data": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", "dev": true, "license": "MIT", "engines": { @@ -1015,8 +924,6 @@ }, "node_modules/@babel/core": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", "dependencies": { @@ -1046,15 +953,11 @@ }, "node_modules/@babel/core/node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "license": "MIT" }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -1063,8 +966,6 @@ }, "node_modules/@babel/generator": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", @@ -1079,8 +980,6 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1096,8 +995,6 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "license": "ISC", "dependencies": { @@ -1106,8 +1003,6 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -1116,15 +1011,11 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "license": "ISC" }, "node_modules/@babel/helper-globals": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1132,8 +1023,6 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dev": true, "license": "MIT", "dependencies": { @@ -1146,8 +1035,6 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "dev": true, "license": "MIT", "dependencies": { @@ -1164,8 +1051,6 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1173,8 +1058,6 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1182,8 +1065,6 @@ }, "node_modules/@babel/helper-validator-option": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "license": "MIT", "engines": { @@ -1192,8 +1073,6 @@ }, "node_modules/@babel/helpers": { "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, "license": "MIT", "dependencies": { @@ -1206,8 +1085,6 @@ }, "node_modules/@babel/parser": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "license": "MIT", "dependencies": { "@babel/types": "^7.28.5" @@ -1221,8 +1098,6 @@ }, "node_modules/@babel/runtime": { "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1230,8 +1105,6 @@ }, "node_modules/@babel/template": { "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -1244,8 +1117,6 @@ }, "node_modules/@babel/traverse": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -1262,8 +1133,6 @@ }, "node_modules/@babel/types": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -1275,8 +1144,6 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", - "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", "dev": true, "license": "MIT", "engines": { @@ -1285,21 +1152,15 @@ }, "node_modules/@bufbuild/protobuf": { "version": "2.10.1", - "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.10.1.tgz", - "integrity": "sha512-ckS3+vyJb5qGpEYv/s1OebUHDi/xSNtfgw1wqKZo7MR9F2z+qXr0q5XagafAG/9O0QPVIUfST0smluYSTpYFkg==", "dev": true, "license": "(Apache-2.0 AND BSD-3-Clause)" }, "node_modules/@canvas/image-data": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@canvas/image-data/-/image-data-1.1.0.tgz", - "integrity": "sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==", "license": "MIT" }, "node_modules/@colors/colors": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", "license": "MIT", "engines": { "node": ">=0.1.90" @@ -1307,8 +1168,6 @@ }, "node_modules/@csstools/color-helpers": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", "dev": true, "funding": [ { @@ -1327,8 +1186,6 @@ }, "node_modules/@csstools/css-calc": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", "dev": true, "funding": [ { @@ -1351,8 +1208,6 @@ }, "node_modules/@csstools/css-color-parser": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", "dev": true, "funding": [ { @@ -1379,8 +1234,6 @@ }, "node_modules/@csstools/css-parser-algorithms": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, "funding": [ { @@ -1402,8 +1255,6 @@ }, "node_modules/@csstools/css-syntax-patches-for-csstree": { "version": "1.0.20", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.20.tgz", - "integrity": "sha512-8BHsjXfSciZxjmHQOuVdW2b8WLUPts9a+mfL13/PzEviufUEW2xnvQuOlKs9dRBHgRqJ53SF/DUoK9+MZk72oQ==", "dev": true, "funding": [ { @@ -1422,8 +1273,6 @@ }, "node_modules/@csstools/css-tokenizer": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", "dev": true, "funding": [ { @@ -1442,8 +1291,6 @@ }, "node_modules/@dabh/diagnostics": { "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz", - "integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==", "license": "MIT", "dependencies": { "@so-ric/colorspace": "^1.1.6", @@ -1453,8 +1300,6 @@ }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true, "license": "MIT", "engines": { @@ -1541,8 +1386,6 @@ }, "node_modules/@esbuild/darwin-arm64": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", "cpu": [ "arm64" ], @@ -1915,8 +1758,6 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -1933,8 +1774,6 @@ }, "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1945,8 +1784,6 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -1954,8 +1791,6 @@ }, "node_modules/@eslint/config-array": { "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.7", @@ -1968,8 +1803,6 @@ }, "node_modules/@eslint/config-helpers": { "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "license": "Apache-2.0", "dependencies": { "@eslint/core": "^0.17.0" @@ -1980,8 +1813,6 @@ }, "node_modules/@eslint/core": { "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" @@ -1992,8 +1823,6 @@ }, "node_modules/@eslint/eslintrc": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", "license": "MIT", "dependencies": { "ajv": "^6.12.4", @@ -2015,8 +1844,6 @@ }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "license": "MIT", "engines": { "node": ">=18" @@ -2027,8 +1854,6 @@ }, "node_modules/@eslint/eslintrc/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" @@ -2036,8 +1861,6 @@ }, "node_modules/@eslint/js": { "version": "9.39.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", - "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2048,8 +1871,6 @@ }, "node_modules/@eslint/object-schema": { "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2057,8 +1878,6 @@ }, "node_modules/@eslint/plugin-kit": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "license": "Apache-2.0", "dependencies": { "@eslint/core": "^0.17.0", @@ -2070,32 +1889,22 @@ }, "node_modules/@fastify/busboy": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.2.0.tgz", - "integrity": "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==", "license": "MIT" }, "node_modules/@firebase/app-check-interop-types": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", - "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", "license": "Apache-2.0" }, "node_modules/@firebase/app-types": { "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", - "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", "license": "Apache-2.0" }, "node_modules/@firebase/auth-interop-types": { "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", - "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", "license": "Apache-2.0" }, "node_modules/@firebase/component": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.0.tgz", - "integrity": "sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==", "license": "Apache-2.0", "dependencies": { "@firebase/util": "1.13.0", @@ -2107,8 +1916,6 @@ }, "node_modules/@firebase/database": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.0.tgz", - "integrity": "sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg==", "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.3", @@ -2125,8 +1932,6 @@ }, "node_modules/@firebase/database-compat": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.0.tgz", - "integrity": "sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.7.0", @@ -2142,8 +1947,6 @@ }, "node_modules/@firebase/database-types": { "version": "1.0.16", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.16.tgz", - "integrity": "sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw==", "license": "Apache-2.0", "dependencies": { "@firebase/app-types": "0.9.3", @@ -2152,8 +1955,6 @@ }, "node_modules/@firebase/logger": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.5.0.tgz", - "integrity": "sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -2164,8 +1965,6 @@ }, "node_modules/@firebase/util": { "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", - "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -2177,8 +1976,6 @@ }, "node_modules/@google-cloud/firestore": { "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.6.tgz", - "integrity": "sha512-EW/O8ktzwLfyWBOsNuhRoMi8lrC3clHM5LVFhGvO1HCsLozCOOXRAlHrYBoE6HL42Sc8yYMuCb2XqcnJ4OOEpw==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -2194,8 +1991,6 @@ }, "node_modules/@google-cloud/paginator": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", - "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -2208,8 +2003,6 @@ }, "node_modules/@google-cloud/projectify": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", - "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", "license": "Apache-2.0", "optional": true, "engines": { @@ -2218,8 +2011,6 @@ }, "node_modules/@google-cloud/promisify": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", - "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", "license": "Apache-2.0", "optional": true, "engines": { @@ -2228,8 +2019,6 @@ }, "node_modules/@google-cloud/storage": { "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.17.3.tgz", - "integrity": "sha512-gOnCAbFgAYKRozywLsxagdevTF7Gm+2Ncz5u5CQAuOv/2VCa0rdGJWvJFDOftPx1tc+q8TXiC2pEJfFKu+yeMQ==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -2255,8 +2044,6 @@ }, "node_modules/@google-cloud/storage/node_modules/fast-xml-parser": { "version": "4.5.3", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", - "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", "funding": [ { "type": "github", @@ -2274,8 +2061,6 @@ }, "node_modules/@google-cloud/storage/node_modules/google-auth-library": { "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", - "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -2292,8 +2077,6 @@ }, "node_modules/@google-cloud/storage/node_modules/gtoken": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", "license": "MIT", "optional": true, "dependencies": { @@ -2306,8 +2089,6 @@ }, "node_modules/@google-cloud/storage/node_modules/strnum": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", - "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", "funding": [ { "type": "github", @@ -2319,8 +2100,6 @@ }, "node_modules/@google-cloud/storage/node_modules/uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "license": "MIT", "optional": true, "bin": { @@ -2329,8 +2108,6 @@ }, "node_modules/@google/genai": { "version": "1.30.0", - "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.30.0.tgz", - "integrity": "sha512-3MRcgczBFbUat1wIlZoLJ0vCCfXgm7Qxjh59cZi2X08RgWLtm9hKOspzp7TOg1TV2e26/MLxR2GR5yD5GmBV2w==", "license": "Apache-2.0", "dependencies": { "google-auth-library": "^10.3.0", @@ -2350,8 +2127,6 @@ }, "node_modules/@google/generative-ai": { "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.21.0.tgz", - "integrity": "sha512-7XhUbtnlkSEZK15kN3t+tzIMxsbKm/dSkKBFalj+20NvPKe1kBY7mR2P7vuijEn+f06z5+A8bVGKO0v39cr6Wg==", "license": "Apache-2.0", "engines": { "node": ">=18.0.0" @@ -2359,8 +2134,6 @@ }, "node_modules/@grpc/grpc-js": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.1.tgz", - "integrity": "sha512-sPxgEWtPUR3EnRJCEtbGZG2iX8LQDUls2wUS3o27jg07KqJFMq6YDeWvMo1wfpmy3rqRdS0rivpLwhqQtEyCuQ==", "license": "Apache-2.0", "dependencies": { "@grpc/proto-loader": "^0.8.0", @@ -2372,8 +2145,6 @@ }, "node_modules/@grpc/proto-loader": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", - "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", "license": "Apache-2.0", "dependencies": { "lodash.camelcase": "^4.3.0", @@ -2496,8 +2267,6 @@ }, "node_modules/@heyputer/kv.js": { "version": "0.1.92", - "resolved": "https://registry.npmjs.org/@heyputer/kv.js/-/kv.js-0.1.92.tgz", - "integrity": "sha512-D+trimrG/V6mU5zeQrKyH476WotvvRn0McttxiFxEzWLiMqR6aBmQ5apeKrZAheglHmwf0D3FO5ykmU2lCuLvQ==", "license": "MIT", "dependencies": { "minimatch": "^9.0.0" @@ -2505,8 +2274,6 @@ }, "node_modules/@heyputer/kv.js/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -2514,8 +2281,6 @@ }, "node_modules/@heyputer/kv.js/node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -2529,8 +2294,6 @@ }, "node_modules/@heyputer/multest": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@heyputer/multest/-/multest-0.0.2.tgz", - "integrity": "sha512-Hr4U9Z2/oMIyCKv+cgO3pNzncA4PAlkS9RotZwoicfzR2BLLu2Rjjp3/HpcLmtE7UEt0hlRMYP+ImMZPYGNwkg==", "license": "UNLICENSED", "dependencies": { "append-field": "^1.0.0", @@ -2564,8 +2327,6 @@ }, "node_modules/@humanfs/core": { "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "license": "Apache-2.0", "engines": { "node": ">=18.18.0" @@ -2573,8 +2334,6 @@ }, "node_modules/@humanfs/node": { "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "license": "Apache-2.0", "dependencies": { "@humanfs/core": "^0.19.1", @@ -2586,8 +2345,6 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "license": "Apache-2.0", "engines": { "node": ">=12.22" @@ -2599,8 +2356,6 @@ }, "node_modules/@humanwhocodes/retry": { "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "license": "Apache-2.0", "engines": { "node": ">=18.18" @@ -2612,8 +2367,6 @@ }, "node_modules/@img/colour": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", - "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", "license": "MIT", "engines": { "node": ">=18" @@ -3035,14 +2788,10 @@ }, "node_modules/@ioredis/commands": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.4.0.tgz", - "integrity": "sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ==", "license": "MIT" }, "node_modules/@isaacs/cliui": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "license": "ISC", "dependencies": { "string-width": "^5.1.2", @@ -3058,8 +2807,6 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" @@ -3070,8 +2817,6 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "license": "MIT", "engines": { "node": ">=12" @@ -3082,14 +2827,10 @@ }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -3105,8 +2846,6 @@ }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -3120,8 +2859,6 @@ }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -3137,8 +2874,6 @@ }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "license": "ISC", "dependencies": { @@ -3154,8 +2889,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "license": "MIT", "dependencies": { @@ -3164,8 +2897,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "license": "MIT", "engines": { @@ -3174,8 +2905,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", "dependencies": { @@ -3188,8 +2917,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -3202,8 +2929,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", "dependencies": { @@ -3215,8 +2940,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", "dependencies": { @@ -3231,8 +2954,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", "dependencies": { @@ -3244,8 +2965,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", "engines": { @@ -3254,8 +2973,6 @@ }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, "license": "MIT", "engines": { @@ -3264,8 +2981,6 @@ }, "node_modules/@jimp/bmp": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.12.tgz", - "integrity": "sha512-aeI64HD0npropd+AR76MCcvvRaa+Qck6loCOS03CkkxGHN5/r336qTM5HPUdHKMDOGzqknuVPA8+kK1t03z12g==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", @@ -3277,8 +2992,6 @@ }, "node_modules/@jimp/core": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.12.tgz", - "integrity": "sha512-l0RR0dOPyzMKfjUW1uebzueFEDtCOj9fN6pyTYWWOM/VS4BciXQ1VVrJs8pO3kycGYZxncRKhCoygbNr8eEZQA==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", @@ -3293,8 +3006,6 @@ }, "node_modules/@jimp/core/node_modules/file-type": { "version": "16.5.4", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", - "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", "license": "MIT", "dependencies": { "readable-web-to-node-stream": "^3.0.0", @@ -3310,8 +3021,6 @@ }, "node_modules/@jimp/core/node_modules/peek-readable": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", - "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", "license": "MIT", "engines": { "node": ">=8" @@ -3323,8 +3032,6 @@ }, "node_modules/@jimp/core/node_modules/strtok3": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", - "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", "license": "MIT", "dependencies": { "@tokenizer/token": "^0.3.0", @@ -3340,8 +3047,6 @@ }, "node_modules/@jimp/core/node_modules/token-types": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", - "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", "license": "MIT", "dependencies": { "@tokenizer/token": "^0.3.0", @@ -3357,8 +3062,6 @@ }, "node_modules/@jimp/custom": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.12.tgz", - "integrity": "sha512-xcmww1O/JFP2MrlGUMd3Q78S3Qu6W3mYTXYuIqFq33EorgYHV/HqymHfXy9GjiCJ7OI+7lWx6nYFOzU7M4rd1Q==", "license": "MIT", "dependencies": { "@jimp/core": "^0.22.12" @@ -3366,8 +3069,6 @@ }, "node_modules/@jimp/gif": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.22.12.tgz", - "integrity": "sha512-y6BFTJgch9mbor2H234VSjd9iwAhaNf/t3US5qpYIs0TSbAvM02Fbc28IaDETj9+4YB4676sz4RcN/zwhfu1pg==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", @@ -3380,8 +3081,6 @@ }, "node_modules/@jimp/jpeg": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.22.12.tgz", - "integrity": "sha512-Rq26XC/uQWaQKyb/5lksCTCxXhtY01NJeBN+dQv5yNYedN0i7iYu+fXEoRsfaJ8xZzjoANH8sns7rVP4GE7d/Q==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", @@ -3393,8 +3092,6 @@ }, "node_modules/@jimp/plugin-blit": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.22.12.tgz", - "integrity": "sha512-xslz2ZoFZOPLY8EZ4dC29m168BtDx95D6K80TzgUi8gqT7LY6CsajWO0FAxDwHz6h0eomHMfyGX0stspBrTKnQ==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3405,8 +3102,6 @@ }, "node_modules/@jimp/plugin-blur": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.22.12.tgz", - "integrity": "sha512-S0vJADTuh1Q9F+cXAwFPlrKWzDj2F9t/9JAbUvaaDuivpyWuImEKXVz5PUZw2NbpuSHjwssbTpOZ8F13iJX4uw==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3417,8 +3112,6 @@ }, "node_modules/@jimp/plugin-circle": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.22.12.tgz", - "integrity": "sha512-SWVXx1yiuj5jZtMijqUfvVOJBwOifFn0918ou4ftoHgegc5aHWW5dZbYPjvC9fLpvz7oSlptNl2Sxr1zwofjTg==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3429,8 +3122,6 @@ }, "node_modules/@jimp/plugin-color": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.22.12.tgz", - "integrity": "sha512-xImhTE5BpS8xa+mAN6j4sMRWaUgUDLoaGHhJhpC+r7SKKErYDR0WQV4yCE4gP+N0gozD0F3Ka1LUSaMXrn7ZIA==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", @@ -3442,8 +3133,6 @@ }, "node_modules/@jimp/plugin-contain": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.22.12.tgz", - "integrity": "sha512-Eo3DmfixJw3N79lWk8q/0SDYbqmKt1xSTJ69yy8XLYQj9svoBbyRpSnHR+n9hOw5pKXytHwUW6nU4u1wegHNoQ==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3457,8 +3146,6 @@ }, "node_modules/@jimp/plugin-cover": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.22.12.tgz", - "integrity": "sha512-z0w/1xH/v/knZkpTNx+E8a7fnasQ2wHG5ze6y5oL2dhH1UufNua8gLQXlv8/W56+4nJ1brhSd233HBJCo01BXA==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3472,8 +3159,6 @@ }, "node_modules/@jimp/plugin-crop": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.22.12.tgz", - "integrity": "sha512-FNuUN0OVzRCozx8XSgP9MyLGMxNHHJMFt+LJuFjn1mu3k0VQxrzqbN06yIl46TVejhyAhcq5gLzqmSCHvlcBVw==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3484,8 +3169,6 @@ }, "node_modules/@jimp/plugin-displace": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.22.12.tgz", - "integrity": "sha512-qpRM8JRicxfK6aPPqKZA6+GzBwUIitiHaZw0QrJ64Ygd3+AsTc7BXr+37k2x7QcyCvmKXY4haUrSIsBug4S3CA==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3496,8 +3179,6 @@ }, "node_modules/@jimp/plugin-dither": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.22.12.tgz", - "integrity": "sha512-jYgGdSdSKl1UUEanX8A85v4+QUm+PE8vHFwlamaKk89s+PXQe7eVE3eNeSZX4inCq63EHL7cX580dMqkoC3ZLw==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3508,8 +3189,6 @@ }, "node_modules/@jimp/plugin-fisheye": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.12.tgz", - "integrity": "sha512-LGuUTsFg+fOp6KBKrmLkX4LfyCy8IIsROwoUvsUPKzutSqMJnsm3JGDW2eOmWIS/jJpPaeaishjlxvczjgII+Q==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3520,8 +3199,6 @@ }, "node_modules/@jimp/plugin-flip": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.22.12.tgz", - "integrity": "sha512-m251Rop7GN8W0Yo/rF9LWk6kNclngyjIJs/VXHToGQ6EGveOSTSQaX2Isi9f9lCDLxt+inBIb7nlaLLxnvHX8Q==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3533,8 +3210,6 @@ }, "node_modules/@jimp/plugin-gaussian": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.12.tgz", - "integrity": "sha512-sBfbzoOmJ6FczfG2PquiK84NtVGeScw97JsCC3rpQv1PHVWyW+uqWFF53+n3c8Y0P2HWlUjflEla2h/vWShvhg==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3545,8 +3220,6 @@ }, "node_modules/@jimp/plugin-invert": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.22.12.tgz", - "integrity": "sha512-N+6rwxdB+7OCR6PYijaA/iizXXodpxOGvT/smd/lxeXsZ/empHmFFFJ/FaXcYh19Tm04dGDaXcNF/dN5nm6+xQ==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3557,8 +3230,6 @@ }, "node_modules/@jimp/plugin-mask": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.22.12.tgz", - "integrity": "sha512-4AWZg+DomtpUA099jRV8IEZUfn1wLv6+nem4NRJC7L/82vxzLCgXKTxvNvBcNmJjT9yS1LAAmiJGdWKXG63/NA==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3569,8 +3240,6 @@ }, "node_modules/@jimp/plugin-normalize": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.22.12.tgz", - "integrity": "sha512-0So0rexQivnWgnhacX4cfkM2223YdExnJTTy6d06WbkfZk5alHUx8MM3yEzwoCN0ErO7oyqEWRnEkGC+As1FtA==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3581,8 +3250,6 @@ }, "node_modules/@jimp/plugin-print": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.22.12.tgz", - "integrity": "sha512-c7TnhHlxm87DJeSnwr/XOLjJU/whoiKYY7r21SbuJ5nuH+7a78EW1teOaj5gEr2wYEd7QtkFqGlmyGXY/YclyQ==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", @@ -3595,8 +3262,6 @@ }, "node_modules/@jimp/plugin-resize": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.22.12.tgz", - "integrity": "sha512-3NyTPlPbTnGKDIbaBgQ3HbE6wXbAlFfxHVERmrbqAi8R3r6fQPxpCauA8UVDnieg5eo04D0T8nnnNIX//i/sXg==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3607,8 +3272,6 @@ }, "node_modules/@jimp/plugin-rotate": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.22.12.tgz", - "integrity": "sha512-9YNEt7BPAFfTls2FGfKBVgwwLUuKqy+E8bDGGEsOqHtbuhbshVGxN2WMZaD4gh5IDWvR+emmmPPWGgaYNYt1gA==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3622,8 +3285,6 @@ }, "node_modules/@jimp/plugin-scale": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.22.12.tgz", - "integrity": "sha512-dghs92qM6MhHj0HrV2qAwKPMklQtjNpoYgAB94ysYpsXslhRTiPisueSIELRwZGEr0J0VUxpUY7HgJwlSIgGZw==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3635,8 +3296,6 @@ }, "node_modules/@jimp/plugin-shadow": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.22.12.tgz", - "integrity": "sha512-FX8mTJuCt7/3zXVoeD/qHlm4YH2bVqBuWQHXSuBK054e7wFRnRnbSLPUqAwSeYP3lWqpuQzJtgiiBxV3+WWwTg==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3649,8 +3308,6 @@ }, "node_modules/@jimp/plugin-threshold": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.22.12.tgz", - "integrity": "sha512-4x5GrQr1a/9L0paBC/MZZJjjgjxLYrqSmWd+e+QfAEPvmRxdRoQ5uKEuNgXnm9/weHQBTnQBQsOY2iFja+XGAw==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" @@ -3663,8 +3320,6 @@ }, "node_modules/@jimp/plugins": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.22.12.tgz", - "integrity": "sha512-yBJ8vQrDkBbTgQZLty9k4+KtUQdRjsIDJSPjuI21YdVeqZxYywifHl4/XWILoTZsjTUASQcGoH0TuC0N7xm3ww==", "license": "MIT", "dependencies": { "@jimp/plugin-blit": "^0.22.12", @@ -3696,8 +3351,6 @@ }, "node_modules/@jimp/png": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.22.12.tgz", - "integrity": "sha512-Mrp6dr3UTn+aLK8ty/dSKELz+Otdz1v4aAXzV5q53UDD2rbB5joKVJ/ChY310B+eRzNxIovbUF1KVrUsYdE8Hg==", "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", @@ -3709,8 +3362,6 @@ }, "node_modules/@jimp/tiff": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.22.12.tgz", - "integrity": "sha512-E1LtMh4RyJsoCAfAkBRVSYyZDTtLq9p9LUiiYP0vPtXyxX4BiYBUYihTLSBlCQg5nF2e4OpQg7SPrLdJ66u7jg==", "license": "MIT", "dependencies": { "utif2": "^4.0.1" @@ -3721,8 +3372,6 @@ }, "node_modules/@jimp/types": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.22.12.tgz", - "integrity": "sha512-wwKYzRdElE1MBXFREvCto5s699izFHNVvALUv79GXNbsOVqlwlOxlWJ8DuyOGIXoLP4JW/m30YyuTtfUJgMRMA==", "license": "MIT", "dependencies": { "@jimp/bmp": "^0.22.12", @@ -3738,8 +3387,6 @@ }, "node_modules/@jimp/utils": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.12.tgz", - "integrity": "sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.13.3" @@ -3747,8 +3394,6 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -3757,8 +3402,6 @@ }, "node_modules/@jridgewell/remapping": { "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3768,8 +3411,6 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "license": "MIT", "engines": { "node": ">=6.0.0" @@ -3777,8 +3418,6 @@ }, "node_modules/@jridgewell/source-map": { "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -3787,14 +3426,10 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3803,8 +3438,6 @@ }, "node_modules/@js-sdsl/ordered-map": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", "license": "MIT", "funding": { "type": "opencollective", @@ -3813,8 +3446,6 @@ }, "node_modules/@kwsites/file-exists": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", "license": "MIT", "dependencies": { "debug": "^4.1.1" @@ -3822,14 +3453,10 @@ }, "node_modules/@kwsites/promise-deferred": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", "license": "MIT" }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", "license": "BSD-3-Clause", "dependencies": { "detect-libc": "^2.0.0", @@ -3848,8 +3475,6 @@ }, "node_modules/@mistralai/mistralai": { "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.10.0.tgz", - "integrity": "sha512-tdIgWs4Le8vpvPiUEWne6tK0qbVc+jMenujnvTqOjogrJUsCSQhus0tHTU1avDDh5//Rq2dFgP9mWRAdIEoBqg==", "dependencies": { "zod": "^3.20.0", "zod-to-json-schema": "^3.24.1" @@ -3857,8 +3482,6 @@ }, "node_modules/@noble/hashes": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "license": "MIT", "engines": { "node": "^14.21.3 || >=16" @@ -3869,8 +3492,6 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -3882,8 +3503,6 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "license": "MIT", "engines": { "node": ">= 8" @@ -3891,8 +3510,6 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -3904,8 +3521,6 @@ }, "node_modules/@opentelemetry/api": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "license": "Apache-2.0", "engines": { "node": ">=8.0.0" @@ -3970,8 +3585,6 @@ }, "node_modules/@opentelemetry/propagation-utils": { "version": "0.30.16", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagation-utils/-/propagation-utils-0.30.16.tgz", - "integrity": "sha512-ZVQ3Z/PQ+2GQlrBfbMMMT0U7MzvYZLCPP800+ooyaBqm4hMvuQHfP028gB9/db0mwkmyEAMad9houukUVxhwcw==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -3982,8 +3595,6 @@ }, "node_modules/@opentelemetry/propagator-aws-xray": { "version": "1.26.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-aws-xray/-/propagator-aws-xray-1.26.2.tgz", - "integrity": "sha512-k43wxTjKYvwfce9L4eT8fFYy/ATmCfPHZPZsyT/6ABimf2KE1HafoOsIcxLOtmNSZt6dCvBIYCrXaOWta20xJg==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -3994,8 +3605,6 @@ }, "node_modules/@opentelemetry/redis-common": { "version": "0.36.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.36.2.tgz", - "integrity": "sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -4003,8 +3612,6 @@ }, "node_modules/@opentelemetry/resource-detector-aws": { "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-aws/-/resource-detector-aws-1.12.0.tgz", - "integrity": "sha512-Cvi7ckOqiiuWlHBdA1IjS0ufr3sltex2Uws2RK6loVp4gzIJyOijsddAI6IZ5kiO8h/LgCWe8gxPmwkTKImd+Q==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.0.0", @@ -4020,8 +3627,6 @@ }, "node_modules/@opentelemetry/resource-detector-aws/node_modules/@opentelemetry/core": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", - "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "1.28.0" @@ -4035,8 +3640,6 @@ }, "node_modules/@opentelemetry/resource-detector-aws/node_modules/@opentelemetry/semantic-conventions": { "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -4044,8 +3647,6 @@ }, "node_modules/@opentelemetry/resource-detector-gcp": { "version": "0.29.13", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-gcp/-/resource-detector-gcp-0.29.13.tgz", - "integrity": "sha512-vdotx+l3Q+89PeyXMgKEGnZ/CwzwMtuMi/ddgD9/5tKZ08DfDGB2Npz9m2oXPHRCjc4Ro6ifMqFlRyzIvgOjhg==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.0.0", @@ -4062,8 +3663,6 @@ }, "node_modules/@opentelemetry/resource-detector-gcp/node_modules/@opentelemetry/core": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", - "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "1.28.0" @@ -4077,8 +3676,6 @@ }, "node_modules/@opentelemetry/resource-detector-gcp/node_modules/@opentelemetry/semantic-conventions": { "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -4086,8 +3683,6 @@ }, "node_modules/@opentelemetry/resources": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", - "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "1.30.1", @@ -4102,8 +3697,6 @@ }, "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/core": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", - "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "1.28.0" @@ -4117,8 +3710,6 @@ }, "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions": { "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -4126,8 +3717,6 @@ }, "node_modules/@opentelemetry/sql-common": { "version": "0.40.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.40.1.tgz", - "integrity": "sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.1.0" @@ -4141,8 +3730,6 @@ }, "node_modules/@opentelemetry/sql-common/node_modules/@opentelemetry/core": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", - "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "1.28.0" @@ -4156,8 +3743,6 @@ }, "node_modules/@opentelemetry/sql-common/node_modules/@opentelemetry/semantic-conventions": { "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -4165,8 +3750,6 @@ }, "node_modules/@pagerduty/pdjs": { "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@pagerduty/pdjs/-/pdjs-2.2.4.tgz", - "integrity": "sha512-MMZvxos7PJnGJ8z3ijsu/gsMQLIfO8peeigKCjUDmviXk8FIaZZjX0X889NIKuFDhGirYbJVwGTaDYCEw4baLg==", "license": "Apache-2.0", "dependencies": { "browser-or-node": "^2.0.0", @@ -4178,8 +3761,6 @@ }, "node_modules/@paralleldrive/cuid2": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz", - "integrity": "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==", "license": "MIT", "dependencies": { "@noble/hashes": "^1.1.5" @@ -4187,8 +3768,6 @@ }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "license": "MIT", "engines": { "node": ">=14" @@ -4196,8 +3775,6 @@ }, "node_modules/@playwright/test": { "version": "1.57.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.57.0.tgz", - "integrity": "sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4212,39 +3789,27 @@ }, "node_modules/@polka/url": { "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", - "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", "dev": true, "license": "MIT" }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.1", @@ -4253,32 +3818,22 @@ }, "node_modules/@protobufjs/float": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "license": "BSD-3-Clause" }, "node_modules/@rollup/rollup-android-arm-eabi": { @@ -4311,8 +3866,6 @@ }, "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", - "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", "cpu": [ "arm64" ], @@ -4612,8 +4165,6 @@ }, "node_modules/@sindresorhus/merge-streams": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", - "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", "license": "MIT", "engines": { "node": ">=18" @@ -4624,8 +4175,6 @@ }, "node_modules/@sinonjs/commons": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" @@ -4633,8 +4182,6 @@ }, "node_modules/@sinonjs/commons/node_modules/type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "license": "MIT", "engines": { "node": ">=4" @@ -4649,8 +4196,6 @@ }, "node_modules/@sinonjs/samsam": { "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz", - "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==", "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.1", @@ -4659,14 +4204,10 @@ }, "node_modules/@sinonjs/text-encoding": { "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", - "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", "license": "(Unlicense OR Apache-2.0)" }, "node_modules/@smithy/abort-controller": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.5.tgz", - "integrity": "sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -4678,8 +4219,6 @@ }, "node_modules/@smithy/config-resolver": { "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.3.tgz", - "integrity": "sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.3.5", @@ -4695,8 +4234,6 @@ }, "node_modules/@smithy/core": { "version": "3.18.6", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.18.6.tgz", - "integrity": "sha512-8Q/ugWqfDUEU1Exw71+DoOzlONJ2Cn9QA8VeeDzLLjzO/qruh9UKFzbszy4jXcIYgGofxYiT0t1TT6+CT/GupQ==", "license": "Apache-2.0", "dependencies": { "@smithy/middleware-serde": "^4.2.6", @@ -4716,8 +4253,6 @@ }, "node_modules/@smithy/credential-provider-imds": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.5.tgz", - "integrity": "sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.3.5", @@ -4732,8 +4267,6 @@ }, "node_modules/@smithy/fetch-http-handler": { "version": "5.3.6", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.6.tgz", - "integrity": "sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg==", "license": "Apache-2.0", "dependencies": { "@smithy/protocol-http": "^5.3.5", @@ -4748,8 +4281,6 @@ }, "node_modules/@smithy/hash-node": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.5.tgz", - "integrity": "sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -4763,8 +4294,6 @@ }, "node_modules/@smithy/invalid-dependency": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.5.tgz", - "integrity": "sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -4776,8 +4305,6 @@ }, "node_modules/@smithy/is-array-buffer": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", - "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -4788,8 +4315,6 @@ }, "node_modules/@smithy/middleware-compression": { "version": "4.3.13", - "resolved": "https://registry.npmjs.org/@smithy/middleware-compression/-/middleware-compression-4.3.13.tgz", - "integrity": "sha512-U9xdmWcYs6p671ACd60pcmixV3pzj1Y+qk2BVetWnnXnrqmAHh+zIWAP+sypMEATAKMVpnlpKNqMHdB2tWXDqA==", "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.18.6", @@ -4809,8 +4334,6 @@ }, "node_modules/@smithy/middleware-content-length": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.5.tgz", - "integrity": "sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A==", "license": "Apache-2.0", "dependencies": { "@smithy/protocol-http": "^5.3.5", @@ -4823,8 +4346,6 @@ }, "node_modules/@smithy/middleware-endpoint": { "version": "4.3.13", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.3.13.tgz", - "integrity": "sha512-X4za1qCdyx1hEVVXuAWlZuK6wzLDv1uw1OY9VtaYy1lULl661+frY7FeuHdYdl7qAARUxH2yvNExU2/SmRFfcg==", "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.18.6", @@ -4842,8 +4363,6 @@ }, "node_modules/@smithy/middleware-retry": { "version": "4.4.13", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.13.tgz", - "integrity": "sha512-RzIDF9OrSviXX7MQeKOm8r/372KTyY8Jmp6HNKOOYlrguHADuM3ED/f4aCyNhZZFLG55lv5beBin7nL0Nzy1Dw==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.3.5", @@ -4862,8 +4381,6 @@ }, "node_modules/@smithy/middleware-serde": { "version": "4.2.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.6.tgz", - "integrity": "sha512-VkLoE/z7e2g8pirwisLz8XJWedUSY8my/qrp81VmAdyrhi94T+riBfwP+AOEEFR9rFTSonC/5D2eWNmFabHyGQ==", "license": "Apache-2.0", "dependencies": { "@smithy/protocol-http": "^5.3.5", @@ -4876,8 +4393,6 @@ }, "node_modules/@smithy/middleware-stack": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.5.tgz", - "integrity": "sha512-bYrutc+neOyWxtZdbB2USbQttZN0mXaOyYLIsaTbJhFsfpXyGWUxJpEuO1rJ8IIJm2qH4+xJT0mxUSsEDTYwdQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -4889,8 +4404,6 @@ }, "node_modules/@smithy/node-config-provider": { "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.5.tgz", - "integrity": "sha512-UTurh1C4qkVCtqggI36DGbLB2Kv8UlcFdMXDcWMbqVY2uRg0XmT9Pb4Vj6oSQ34eizO1fvR0RnFV4Axw4IrrAg==", "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^4.2.5", @@ -4904,8 +4417,6 @@ }, "node_modules/@smithy/node-http-handler": { "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.5.tgz", - "integrity": "sha512-CMnzM9R2WqlqXQGtIlsHMEZfXKJVTIrqCNoSd/QpAyp+Dw0a1Vps13l6ma1fH8g7zSPNsA59B/kWgeylFuA/lw==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.2.5", @@ -4920,8 +4431,6 @@ }, "node_modules/@smithy/property-provider": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.5.tgz", - "integrity": "sha512-8iLN1XSE1rl4MuxvQ+5OSk/Zb5El7NJZ1td6Tn+8dQQHIjp59Lwl6bd0+nzw6SKm2wSSriH2v/I9LPzUic7EOg==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -4933,8 +4442,6 @@ }, "node_modules/@smithy/protocol-http": { "version": "5.3.5", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.5.tgz", - "integrity": "sha512-RlaL+sA0LNMp03bf7XPbFmT5gN+w3besXSWMkA8rcmxLSVfiEXElQi4O2IWwPfxzcHkxqrwBFMbngB8yx/RvaQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -4946,8 +4453,6 @@ }, "node_modules/@smithy/querystring-builder": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.5.tgz", - "integrity": "sha512-y98otMI1saoajeik2kLfGyRp11e5U/iJYH/wLCh3aTV/XutbGT9nziKGkgCaMD1ghK7p6htHMm6b6scl9JRUWg==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -4960,8 +4465,6 @@ }, "node_modules/@smithy/querystring-parser": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.5.tgz", - "integrity": "sha512-031WCTdPYgiQRYNPXznHXof2YM0GwL6SeaSyTH/P72M1Vz73TvCNH2Nq8Iu2IEPq9QP2yx0/nrw5YmSeAi/AjQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -4973,8 +4476,6 @@ }, "node_modules/@smithy/service-error-classification": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.5.tgz", - "integrity": "sha512-8fEvK+WPE3wUAcDvqDQG1Vk3ANLR8Px979te96m84CbKAjBVf25rPYSzb4xU4hlTyho7VhOGnh5i62D/JVF0JQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0" @@ -4985,8 +4486,6 @@ }, "node_modules/@smithy/shared-ini-file-loader": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.0.tgz", - "integrity": "sha512-5WmZ5+kJgJDjwXXIzr1vDTG+RhF9wzSODQBfkrQ2VVkYALKGvZX1lgVSxEkgicSAFnFhPj5rudJV0zoinqS0bA==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -4998,8 +4497,6 @@ }, "node_modules/@smithy/signature-v4": { "version": "5.3.5", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.5.tgz", - "integrity": "sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.2.0", @@ -5017,8 +4514,6 @@ }, "node_modules/@smithy/smithy-client": { "version": "4.9.9", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.9.9.tgz", - "integrity": "sha512-SUnZJMMo5yCmgjopJbiNeo1vlr8KvdnEfIHV9rlD77QuOGdRotIVBcOrBuMr+sI9zrnhtDtLP054bZVbpZpiQA==", "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.18.6", @@ -5035,8 +4530,6 @@ }, "node_modules/@smithy/types": { "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.9.0.tgz", - "integrity": "sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5047,8 +4540,6 @@ }, "node_modules/@smithy/url-parser": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.5.tgz", - "integrity": "sha512-VaxMGsilqFnK1CeBX+LXnSuaMx4sTL/6znSZh2829txWieazdVxr54HmiyTsIbpOTLcf5nYpq9lpzmwRdxj6rQ==", "license": "Apache-2.0", "dependencies": { "@smithy/querystring-parser": "^4.2.5", @@ -5061,8 +4552,6 @@ }, "node_modules/@smithy/util-base64": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.0.tgz", - "integrity": "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.2.0", @@ -5075,8 +4564,6 @@ }, "node_modules/@smithy/util-body-length-browser": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.0.tgz", - "integrity": "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5087,8 +4574,6 @@ }, "node_modules/@smithy/util-body-length-node": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.1.tgz", - "integrity": "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5099,8 +4584,6 @@ }, "node_modules/@smithy/util-buffer-from": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.0.tgz", - "integrity": "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.2.0", @@ -5112,8 +4595,6 @@ }, "node_modules/@smithy/util-config-provider": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", - "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5124,8 +4605,6 @@ }, "node_modules/@smithy/util-defaults-mode-browser": { "version": "4.3.12", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.12.tgz", - "integrity": "sha512-TKc6FnOxFULKxLgTNHYjcFqdOYzXVPFFVm5JhI30F3RdhT7nYOtOsjgaOwfDRmA/3U66O9KaBQ3UHoXwayRhAg==", "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^4.2.5", @@ -5139,8 +4618,6 @@ }, "node_modules/@smithy/util-defaults-mode-node": { "version": "4.2.15", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.15.tgz", - "integrity": "sha512-94NqfQVo+vGc5gsQ9SROZqOvBkGNMQu6pjXbnn8aQvBUhc31kx49gxlkBEqgmaZQHUUfdRUin5gK/HlHKmbAwg==", "license": "Apache-2.0", "dependencies": { "@smithy/config-resolver": "^4.4.3", @@ -5157,8 +4634,6 @@ }, "node_modules/@smithy/util-endpoints": { "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.5.tgz", - "integrity": "sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.3.5", @@ -5171,8 +4646,6 @@ }, "node_modules/@smithy/util-hex-encoding": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.0.tgz", - "integrity": "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5183,8 +4656,6 @@ }, "node_modules/@smithy/util-middleware": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.5.tgz", - "integrity": "sha512-6Y3+rvBF7+PZOc40ybeZMcGln6xJGVeY60E7jy9Mv5iKpMJpHgRE6dKy9ScsVxvfAYuEX4Q9a65DQX90KaQ3bA==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.9.0", @@ -5196,8 +4667,6 @@ }, "node_modules/@smithy/util-retry": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.5.tgz", - "integrity": "sha512-GBj3+EZBbN4NAqJ/7pAhsXdfzdlznOh8PydUijy6FpNIMnHPSMO2/rP4HKu+UFeikJxShERk528oy7GT79YiJg==", "license": "Apache-2.0", "dependencies": { "@smithy/service-error-classification": "^4.2.5", @@ -5210,8 +4679,6 @@ }, "node_modules/@smithy/util-stream": { "version": "4.5.6", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.6.tgz", - "integrity": "sha512-qWw/UM59TiaFrPevefOZ8CNBKbYEP6wBAIlLqxn3VAIo9rgnTNc4ASbVrqDmhuwI87usnjhdQrxodzAGFFzbRQ==", "license": "Apache-2.0", "dependencies": { "@smithy/fetch-http-handler": "^5.3.6", @@ -5229,8 +4696,6 @@ }, "node_modules/@smithy/util-uri-escape": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.0.tgz", - "integrity": "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5241,8 +4706,6 @@ }, "node_modules/@smithy/util-utf8": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.0.tgz", - "integrity": "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.2.0", @@ -5254,8 +4717,6 @@ }, "node_modules/@smithy/util-waiter": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.5.tgz", - "integrity": "sha512-Dbun99A3InifQdIrsXZ+QLcC0PGBPAdrl4cj1mTgJvyc9N2zf7QSxg8TBkzsCmGJdE3TLbO9ycwpY0EkWahQ/g==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.2.5", @@ -5268,8 +4729,6 @@ }, "node_modules/@smithy/uuid": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.0.tgz", - "integrity": "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5280,8 +4739,6 @@ }, "node_modules/@so-ric/colorspace": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz", - "integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==", "license": "MIT", "dependencies": { "color": "^5.0.2", @@ -5290,21 +4747,15 @@ }, "node_modules/@socket.io/component-emitter": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", "license": "MIT" }, "node_modules/@standard-schema/spec": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", - "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", "dev": true, "license": "MIT" }, "node_modules/@stylistic/eslint-plugin": { "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.6.1.tgz", - "integrity": "sha512-JCs+MqoXfXrRPGbGmho/zGS/jMcn3ieKl/A8YImqib76C8kjgZwq5uUFzc30lJkMvcchuRn6/v8IApLxli3Jyw==", "dev": true, "license": "MIT", "dependencies": { @@ -5324,8 +4775,6 @@ }, "node_modules/@stylistic/eslint-plugin-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-4.4.1.tgz", - "integrity": "sha512-eLisyHvx7Sel8vcFZOEwDEBGmYsYM1SqDn81BWgmbqEXfXRf8oe6Rwp+ryM/8odNjlxtaaxp0Ihmt86CnLAxKg==", "license": "MIT", "dependencies": { "eslint-visitor-keys": "^4.2.0", @@ -5340,14 +4789,10 @@ }, "node_modules/@tokenizer/token": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", "license": "MIT" }, "node_modules/@trysound/sax": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", "license": "ISC", "engines": { "node": ">=10.13.0" @@ -5364,14 +4809,10 @@ }, "node_modules/@types/aws-lambda": { "version": "8.10.122", - "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.122.tgz", - "integrity": "sha512-vBkIh9AY22kVOCEKo5CJlyCgmSWvasC+SWUxL/x/vOwRobMpI/HG1xp/Ae3AqmSiZeLUbOhW0FCD3ZjqqUxmXw==", "license": "MIT" }, "node_modules/@types/body-parser": { "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "license": "MIT", "dependencies": { "@types/connect": "*", @@ -5380,8 +4821,6 @@ }, "node_modules/@types/bunyan": { "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-1.8.9.tgz", - "integrity": "sha512-ZqS9JGpBxVOvsawzmVt30sP++gSQMTejCkIAQ3VdadOcRE8izTyW66hufvwLeH+YEGP6Js2AW7Gz+RMyvrEbmw==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -5389,15 +4828,11 @@ }, "node_modules/@types/caseless": { "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", "license": "MIT", "optional": true }, "node_modules/@types/chai": { "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", "dependencies": { @@ -5407,8 +4842,6 @@ }, "node_modules/@types/chai/node_modules/assertion-error": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { @@ -5417,8 +4850,6 @@ }, "node_modules/@types/connect": { "version": "3.4.36", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", - "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -5444,8 +4875,6 @@ }, "node_modules/@types/cors": { "version": "2.8.19", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", - "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -5453,15 +4882,11 @@ }, "node_modules/@types/deep-eql": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, "license": "MIT" }, "node_modules/@types/eslint": { "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "license": "MIT", "dependencies": { "@types/estree": "*", @@ -5470,8 +4895,6 @@ }, "node_modules/@types/eslint-scope": { "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "license": "MIT", "dependencies": { "@types/eslint": "*", @@ -5480,14 +4903,10 @@ }, "node_modules/@types/estree": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, "node_modules/@types/express": { "version": "4.17.25", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", - "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", "license": "MIT", "dependencies": { "@types/body-parser": "*", @@ -5498,8 +4917,6 @@ }, "node_modules/@types/express-serve-static-core": { "version": "4.19.7", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", - "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -5510,8 +4927,6 @@ }, "node_modules/@types/glob": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, "license": "MIT", "dependencies": { @@ -5561,8 +4976,6 @@ }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", "dev": true, "license": "MIT" }, @@ -5574,8 +4987,6 @@ }, "node_modules/@types/http-errors": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", "license": "MIT" }, "node_modules/@types/ioredis4": { @@ -5590,14 +5001,10 @@ }, "node_modules/@types/json-schema": { "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, "node_modules/@types/jsonwebtoken": { "version": "9.0.10", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", - "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", "license": "MIT", "dependencies": { "@types/ms": "*", @@ -5646,15 +5053,11 @@ }, "node_modules/@types/long": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", "license": "MIT", "optional": true }, "node_modules/@types/memcached": { "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@types/memcached/-/memcached-2.2.10.tgz", - "integrity": "sha512-AM9smvZN55Gzs2wRrqeMHVP7KE8KWgCJO/XL5yCly2xF6EKa4YlbpK+cLSAH4NG/Ah64HrlegmGqW8kYws7Vxg==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -5662,8 +5065,6 @@ }, "node_modules/@types/mime": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "license": "MIT" }, "node_modules/@types/mime-db": { @@ -5672,23 +5073,22 @@ "integrity": "sha512-r2cqxAt/Eo5yWBOQie1lyM1JZFCiORa5xtLlhSZI0w8RJggBPKw8c4g/fgQCzWydaDR5bL4imnmix2d1n52iBw==", "license": "MIT" }, + "node_modules/@types/mime-types": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, "node_modules/@types/minimatch": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", "dev": true, "license": "MIT" }, "node_modules/@types/ms": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "license": "MIT" }, "node_modules/@types/mysql": { "version": "2.15.22", - "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.22.tgz", - "integrity": "sha512-wK1pzsJVVAjYCSZWQoWHziQZbNggXFDUEIGf54g4ZM/ERuP86uGdWeKZWMYlqTPMZfHJJvLPyogXGvCOg87yLQ==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -5696,8 +5096,6 @@ }, "node_modules/@types/node": { "version": "20.19.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", - "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -5705,8 +5103,6 @@ }, "node_modules/@types/node-fetch": { "version": "2.6.13", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", - "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -5715,8 +5111,6 @@ }, "node_modules/@types/pg": { "version": "8.6.1", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", - "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -5726,8 +5120,6 @@ }, "node_modules/@types/pg-pool": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.4.tgz", - "integrity": "sha512-qZAvkv1K3QbmHHFYSNRYPkRjOWRLBYrL4B9c+wG0GSVGBw0NtJwPcgx/DSddeDJvRGMHCEQ4VMEVfuJ/0gZ3XQ==", "license": "MIT", "dependencies": { "@types/pg": "*" @@ -5735,20 +5127,14 @@ }, "node_modules/@types/qs": { "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "license": "MIT" }, "node_modules/@types/request": { "version": "2.48.13", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.13.tgz", - "integrity": "sha512-FGJ6udDNUCjd19pp0Q3iTiDkwhYup7J8hpMW9c4k53NrccQFFWKRho6hvtPPEhnXWKvukfwAlB6DbDz4yhH5Gg==", "license": "MIT", "optional": true, "dependencies": { @@ -5760,8 +5146,6 @@ }, "node_modules/@types/request/node_modules/form-data": { "version": "2.5.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz", - "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==", "license": "MIT", "optional": true, "dependencies": { @@ -5778,8 +5162,6 @@ }, "node_modules/@types/send": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -5787,8 +5169,6 @@ }, "node_modules/@types/serve-static": { "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", - "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", "license": "MIT", "dependencies": { "@types/http-errors": "*", @@ -5798,8 +5178,6 @@ }, "node_modules/@types/serve-static/node_modules/@types/send": { "version": "0.17.6", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", - "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", "license": "MIT", "dependencies": { "@types/mime": "^1", @@ -5808,14 +5186,10 @@ }, "node_modules/@types/shimmer": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz", - "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==", "license": "MIT" }, "node_modules/@types/tedious": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", - "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -5823,15 +5197,11 @@ }, "node_modules/@types/tough-cookie": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "license": "MIT", "optional": true }, "node_modules/@types/triple-beam": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", "license": "MIT" }, "node_modules/@types/uuid": { @@ -5841,8 +5211,6 @@ }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.48.0.tgz", - "integrity": "sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5871,8 +5239,6 @@ }, "node_modules/@typescript-eslint/parser": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.0.tgz", - "integrity": "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5896,8 +5262,6 @@ }, "node_modules/@typescript-eslint/project-service": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.48.0.tgz", - "integrity": "sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw==", "dev": true, "license": "MIT", "dependencies": { @@ -5918,8 +5282,6 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.48.0.tgz", - "integrity": "sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5936,8 +5298,6 @@ }, "node_modules/@typescript-eslint/tsconfig-utils": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.48.0.tgz", - "integrity": "sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w==", "dev": true, "license": "MIT", "engines": { @@ -5953,8 +5313,6 @@ }, "node_modules/@typescript-eslint/type-utils": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.48.0.tgz", - "integrity": "sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw==", "dev": true, "license": "MIT", "dependencies": { @@ -5978,8 +5336,6 @@ }, "node_modules/@typescript-eslint/types": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.0.tgz", - "integrity": "sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA==", "dev": true, "license": "MIT", "engines": { @@ -5992,8 +5348,6 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.48.0.tgz", - "integrity": "sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6020,8 +5374,6 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6030,8 +5382,6 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -6046,8 +5396,6 @@ }, "node_modules/@typescript-eslint/utils": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.48.0.tgz", - "integrity": "sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6070,8 +5418,6 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.0.tgz", - "integrity": "sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg==", "dev": true, "license": "MIT", "dependencies": { @@ -6088,8 +5434,6 @@ }, "node_modules/@vitest/coverage-v8": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.14.tgz", - "integrity": "sha512-EYHLqN/BY6b47qHH7gtMxAg++saoGmsjWmAq9MlXxAz4M0NcHh9iOyKhBZyU4yxZqOd8Xnqp80/5saeitz4Cng==", "dev": true, "license": "MIT", "dependencies": { @@ -6120,8 +5464,6 @@ }, "node_modules/@vitest/coverage-v8/node_modules/istanbul-lib-source-maps": { "version": "5.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", - "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -6135,8 +5477,6 @@ }, "node_modules/@vitest/expect": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.14.tgz", - "integrity": "sha512-RHk63V3zvRiYOWAV0rGEBRO820ce17hz7cI2kDmEdfQsBjT2luEKB5tCOc91u1oSQoUOZkSv3ZyzkdkSLD7lKw==", "dev": true, "license": "MIT", "dependencies": { @@ -6153,8 +5493,6 @@ }, "node_modules/@vitest/expect/node_modules/chai": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.1.tgz", - "integrity": "sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==", "dev": true, "license": "MIT", "engines": { @@ -6163,8 +5501,6 @@ }, "node_modules/@vitest/mocker": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.14.tgz", - "integrity": "sha512-RzS5NujlCzeRPF1MK7MXLiEFpkIXeMdQ+rN3Kk3tDI9j0mtbr7Nmuq67tpkOJQpgyClbOltCXMjLZicJHsH5Cg==", "dev": true, "license": "MIT", "dependencies": { @@ -6190,8 +5526,6 @@ }, "node_modules/@vitest/pretty-format": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.14.tgz", - "integrity": "sha512-SOYPgujB6TITcJxgd3wmsLl+wZv+fy3av2PpiPpsWPZ6J1ySUYfScfpIt2Yv56ShJXR2MOA6q2KjKHN4EpdyRQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6203,8 +5537,6 @@ }, "node_modules/@vitest/runner": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.14.tgz", - "integrity": "sha512-BsAIk3FAqxICqREbX8SetIteT8PiaUL/tgJjmhxJhCsigmzzH8xeadtp7LRnTpCVzvf0ib9BgAfKJHuhNllKLw==", "dev": true, "license": "MIT", "dependencies": { @@ -6217,8 +5549,6 @@ }, "node_modules/@vitest/snapshot": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.14.tgz", - "integrity": "sha512-aQVBfT1PMzDSA16Y3Fp45a0q8nKexx6N5Amw3MX55BeTeZpoC08fGqEZqVmPcqN0ueZsuUQ9rriPMhZ3Mu19Ag==", "dev": true, "license": "MIT", "dependencies": { @@ -6232,8 +5562,6 @@ }, "node_modules/@vitest/spy": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.14.tgz", - "integrity": "sha512-JmAZT1UtZooO0tpY3GRyiC/8W7dCs05UOq9rfsUUgEZEdq+DuHLmWhPsrTt0TiW7WYeL/hXpaE07AZ2RCk44hg==", "dev": true, "license": "MIT", "funding": { @@ -6242,8 +5570,6 @@ }, "node_modules/@vitest/ui": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-4.0.14.tgz", - "integrity": "sha512-fvDz8o7SQpFLoSBo6Cudv+fE85/fPCkwTnLAN85M+Jv7k59w2mSIjT9Q5px7XwGrmYqqKBEYxh/09IBGd1E7AQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6264,15 +5590,11 @@ }, "node_modules/@vitest/ui/node_modules/fflate": { "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", "dev": true, "license": "MIT" }, "node_modules/@vitest/utils": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.14.tgz", - "integrity": "sha512-hLqXZKAWNg8pI+SQXyXxWCTOpA3MvsqcbVeNgSi8x/CSN2wi26dSzn1wrOhmCmFjEvN9p8/kLFRHa6PI8jHazw==", "dev": true, "license": "MIT", "dependencies": { @@ -6285,8 +5607,6 @@ }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", @@ -6295,26 +5615,18 @@ }, "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.13.2", @@ -6324,14 +5636,10 @@ }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6342,8 +5650,6 @@ }, "node_modules/@webassemblyjs/ieee754": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" @@ -6351,8 +5657,6 @@ }, "node_modules/@webassemblyjs/leb128": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" @@ -6360,14 +5664,10 @@ }, "node_modules/@webassemblyjs/utf8": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6382,8 +5682,6 @@ }, "node_modules/@webassemblyjs/wasm-gen": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6395,8 +5693,6 @@ }, "node_modules/@webassemblyjs/wasm-opt": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6407,8 +5703,6 @@ }, "node_modules/@webassemblyjs/wasm-parser": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6421,8 +5715,6 @@ }, "node_modules/@webassemblyjs/wast-printer": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6431,8 +5723,6 @@ }, "node_modules/@webpack-cli/configtest": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", "dev": true, "license": "MIT", "engines": { @@ -6445,8 +5735,6 @@ }, "node_modules/@webpack-cli/info": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", "dev": true, "license": "MIT", "engines": { @@ -6459,8 +5747,6 @@ }, "node_modules/@webpack-cli/serve": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", "dev": true, "license": "MIT", "engines": { @@ -6478,8 +5764,6 @@ }, "node_modules/@xterm/addon-fit": { "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz", - "integrity": "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==", "license": "MIT", "peerDependencies": { "@xterm/xterm": "^5.0.0" @@ -6487,8 +5771,6 @@ }, "node_modules/@xterm/addon-image": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.8.0.tgz", - "integrity": "sha512-b/dqpFn3jUad2pUP5UpF4scPIh0WdxRQL/1qyiahGfUI85XZTCXo0py9G6AcOR2QYUw8eJ8EowGspT7BQcgw6A==", "license": "MIT", "peerDependencies": { "@xterm/xterm": "^5.2.0" @@ -6496,32 +5778,22 @@ }, "node_modules/@xterm/xterm": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", - "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", "license": "MIT" }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "license": "Apache-2.0" }, "node_modules/abbrev": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "license": "ISC" }, "node_modules/abort-controller": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" @@ -6532,8 +5804,6 @@ }, "node_modules/accepts": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "license": "MIT", "dependencies": { "mime-types": "~2.1.34", @@ -6545,8 +5815,6 @@ }, "node_modules/accepts/node_modules/negotiator": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -6554,8 +5822,6 @@ }, "node_modules/acorn": { "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -6576,8 +5842,6 @@ }, "node_modules/acorn-import-phases": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "license": "MIT", "engines": { "node": ">=10.13.0" @@ -6588,8 +5852,6 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -6597,8 +5859,6 @@ }, "node_modules/agent-base": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "license": "MIT", "dependencies": { "debug": "4" @@ -6609,8 +5869,6 @@ }, "node_modules/agentkeepalive": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", - "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", "license": "MIT", "dependencies": { "humanize-ms": "^1.2.1" @@ -6621,8 +5879,6 @@ }, "node_modules/aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "license": "MIT", "dependencies": { @@ -6635,8 +5891,6 @@ }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -6651,8 +5905,6 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -6668,8 +5920,6 @@ }, "node_modules/ajv-formats/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -6684,14 +5934,10 @@ }, "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/ansi-colors": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "license": "MIT", "engines": { "node": ">=6" @@ -6699,8 +5945,6 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" @@ -6721,14 +5965,10 @@ }, "node_modules/any-base": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", - "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "license": "ISC", "dependencies": { @@ -6741,8 +5981,6 @@ }, "node_modules/anymatch/node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { @@ -6754,14 +5992,10 @@ }, "node_modules/append-field": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", - "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", "license": "MIT" }, "node_modules/append-transform": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", "dev": true, "license": "MIT", "dependencies": { @@ -6773,22 +6007,15 @@ }, "node_modules/aproba": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", - "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", "license": "ISC" }, "node_modules/archy": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true, "license": "MIT" }, "node_modules/are-we-there-yet": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "deprecated": "This package is no longer supported.", "license": "ISC", "dependencies": { "delegates": "^1.0.0", @@ -6800,8 +6027,6 @@ }, "node_modules/argle": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/argle/-/argle-1.1.2.tgz", - "integrity": "sha512-2sQZC5HeeSH9cQEwnZZhmHiKfvJkQ6ncpf8zl9Hv629aiMUsOw8jzYqOhpaMleQGzpQ7avCwrwyqSW1f4t7v0Q==", "license": "MIT", "dependencies": { "lodash.isfunction": "^3.0.8", @@ -6810,14 +6035,10 @@ }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, "node_modules/args": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz", - "integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==", "license": "MIT", "dependencies": { "camelcase": "5.0.0", @@ -6831,8 +6052,6 @@ }, "node_modules/args/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "license": "MIT", "dependencies": { "color-convert": "^1.9.0" @@ -6843,8 +6062,6 @@ }, "node_modules/args/node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", @@ -6857,8 +6074,6 @@ }, "node_modules/args/node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "license": "MIT", "dependencies": { "color-name": "1.1.3" @@ -6866,14 +6081,10 @@ }, "node_modules/args/node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "license": "MIT" }, "node_modules/args/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "license": "MIT", "engines": { "node": ">=0.8.0" @@ -6881,8 +6092,6 @@ }, "node_modules/args/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "license": "MIT", "engines": { "node": ">=4" @@ -6890,8 +6099,6 @@ }, "node_modules/args/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "license": "MIT", "dependencies": { "has-flag": "^3.0.0" @@ -6902,14 +6109,10 @@ }, "node_modules/array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "license": "MIT", "engines": { @@ -6918,8 +6121,6 @@ }, "node_modules/arrify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "license": "MIT", "optional": true, "engines": { @@ -6928,8 +6129,6 @@ }, "node_modules/asn1": { "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "license": "MIT", "dependencies": { "safer-buffer": "~2.1.0" @@ -6937,8 +6136,6 @@ }, "node_modules/assertion-error": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "license": "MIT", "engines": { "node": "*" @@ -6946,8 +6143,6 @@ }, "node_modules/ast-v8-to-istanbul": { "version": "0.3.8", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.8.tgz", - "integrity": "sha512-szgSZqUxI5T8mLKvS7WTjF9is+MVbOeLADU73IseOcrqhxr/VAvy6wfoVE39KnKzA7JRhjF5eUagNlHwvZPlKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6958,21 +6153,15 @@ }, "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true, "license": "MIT" }, "node_modules/async": { "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, "node_modules/async-retry": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", "license": "MIT", "optional": true, "dependencies": { @@ -6981,14 +6170,10 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/axios": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -6998,14 +6183,10 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -7024,8 +6205,6 @@ }, "node_modules/base64id": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", "license": "MIT", "engines": { "node": "^4.5.0 || >= 5.9" @@ -7033,8 +6212,6 @@ }, "node_modules/baseline-browser-mapping": { "version": "2.8.32", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.32.tgz", - "integrity": "sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" @@ -7042,8 +6219,6 @@ }, "node_modules/basic-auth": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "license": "MIT", "dependencies": { "safe-buffer": "5.1.2" @@ -7054,14 +6229,10 @@ }, "node_modules/basic-auth/node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, "node_modules/bcrypt": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", - "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -7074,8 +6245,6 @@ }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "license": "BSD-3-Clause", "dependencies": { "tweetnacl": "^0.14.3" @@ -7083,14 +6252,10 @@ }, "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "license": "Unlicense" }, "node_modules/better-sqlite3": { "version": "11.10.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.10.0.tgz", - "integrity": "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -7100,8 +6265,6 @@ }, "node_modules/bidi-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", - "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", "dev": true, "license": "MIT", "dependencies": { @@ -7110,8 +6273,6 @@ }, "node_modules/bignumber.js": { "version": "9.3.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", - "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", "license": "MIT", "engines": { "node": "*" @@ -7119,8 +6280,6 @@ }, "node_modules/binary-extensions": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "license": "MIT", "engines": { @@ -7132,8 +6291,6 @@ }, "node_modules/bindings": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "license": "MIT", "dependencies": { "file-uri-to-path": "1.0.0" @@ -7141,8 +6298,6 @@ }, "node_modules/bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -7152,14 +6307,10 @@ }, "node_modules/bmp-js": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", - "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==", "license": "MIT" }, "node_modules/body-parser": { "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -7182,8 +6333,6 @@ }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -7191,8 +6340,6 @@ }, "node_modules/body-parser/node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -7203,20 +6350,14 @@ }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/boolbase": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "license": "ISC" }, "node_modules/bowser": { "version": "2.13.1", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.13.1.tgz", - "integrity": "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==", "license": "MIT" }, "node_modules/brace-expansion": { @@ -7229,8 +6370,6 @@ }, "node_modules/braces": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -7239,19 +6378,8 @@ "node": ">=8" } }, - "node_modules/brotli": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", - "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", - "license": "MIT", - "dependencies": { - "base64-js": "^1.1.2" - } - }, "node_modules/brotli-dec-wasm": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/brotli-dec-wasm/-/brotli-dec-wasm-2.3.0.tgz", - "integrity": "sha512-CNck+1A1ofvHk1oyqsKCuoIHLgD2FYy9KTVGHQlV1AKr/v/7N/Owh62nBKEcJxS3YOk+iwWhCi2rcaLhz9VN5g==", "license": "MIT OR Apache-2.0", "dependencies": { "prettier": "^3.2.5" @@ -7262,21 +6390,15 @@ }, "node_modules/browser-or-node": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz", - "integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==", "license": "MIT" }, "node_modules/browser-stdout": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true, "license": "ISC" }, "node_modules/browserslist": { "version": "4.28.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", - "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", "funding": [ { "type": "opencollective", @@ -7306,19 +6428,8 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/bson": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", - "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.6.19" - } - }, "node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -7341,8 +6452,6 @@ }, "node_modules/buffer-equal": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -7350,20 +6459,14 @@ }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", "license": "BSD-3-Clause" }, "node_modules/buffer-from": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "license": "MIT" }, "node_modules/buildcheck": { "version": "0.0.7", - "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.7.tgz", - "integrity": "sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==", "optional": true, "engines": { "node": ">=10.0.0" @@ -7371,8 +6474,6 @@ }, "node_modules/bundle-name": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", "license": "MIT", "dependencies": { "run-applescript": "^7.0.0" @@ -7386,8 +6487,6 @@ }, "node_modules/busboy": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dependencies": { "streamsearch": "^1.1.0" }, @@ -7397,8 +6496,6 @@ }, "node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -7406,8 +6503,6 @@ }, "node_modules/caching-transform": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", "dev": true, "license": "MIT", "dependencies": { @@ -7422,8 +6517,6 @@ }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -7435,8 +6528,6 @@ }, "node_modules/call-bound": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -7451,8 +6542,6 @@ }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "license": "MIT", "engines": { "node": ">=6" @@ -7460,8 +6549,6 @@ }, "node_modules/camel-case": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "dev": true, "license": "MIT", "dependencies": { @@ -7471,8 +6558,6 @@ }, "node_modules/camelcase": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", "license": "MIT", "engines": { "node": ">=6" @@ -7480,8 +6565,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001757", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz", - "integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==", "funding": [ { "type": "opencollective", @@ -7500,8 +6583,6 @@ }, "node_modules/capture-console": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/capture-console/-/capture-console-1.0.2.tgz", - "integrity": "sha512-vQNTSFr0cmHAYXXG3KG7ZJQn0XxC3K2di/wUZVb6yII6gqSN/10Egd3vV4XqJ00yCRNHy2wkN4uWHE+rJstDrw==", "license": "MIT", "dependencies": { "argle": "~1.1.1", @@ -7511,8 +6592,6 @@ }, "node_modules/case-anything": { "version": "2.1.13", - "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.13.tgz", - "integrity": "sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==", "dev": true, "license": "MIT", "engines": { @@ -7524,8 +6603,6 @@ }, "node_modules/centra": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/centra/-/centra-2.7.0.tgz", - "integrity": "sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6" @@ -7533,8 +6610,6 @@ }, "node_modules/chai": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", - "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", @@ -7551,8 +6626,6 @@ }, "node_modules/chai-as-promised": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", - "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", "license": "WTFPL", "dependencies": { "check-error": "^1.0.2" @@ -7587,8 +6660,6 @@ }, "node_modules/check-error": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" @@ -7599,8 +6670,6 @@ }, "node_modules/chokidar": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -7624,8 +6693,6 @@ }, "node_modules/chokidar/node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "license": "ISC", "dependencies": { @@ -7637,8 +6704,6 @@ }, "node_modules/chownr": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "license": "ISC", "engines": { "node": ">=10" @@ -7646,8 +6711,6 @@ }, "node_modules/chrome-trace-event": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "license": "MIT", "engines": { "node": ">=6.0" @@ -7655,20 +6718,14 @@ }, "node_modules/chronokinesis": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/chronokinesis/-/chronokinesis-6.0.0.tgz", - "integrity": "sha512-NxGxNuzROLws2VVvSj9r1qrq0JK0AwR44FNk+sGfPZlG5EW3viz6z2elg6ZwE2YFCn6+Qg3sPqkfIYLyZ0wAtQ==", "license": "MIT" }, "node_modules/cjs-module-lexer": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", "license": "MIT" }, "node_modules/clean-css": { "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", "license": "MIT", "dependencies": { "source-map": "~0.6.0" @@ -7679,8 +6736,6 @@ }, "node_modules/clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, "license": "MIT", "engines": { @@ -7689,8 +6744,6 @@ }, "node_modules/cli-columns": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-columns/-/cli-columns-4.0.0.tgz", - "integrity": "sha512-XW2Vg+w+L9on9wtwKpyzluIPCWXjaBahI7mTcYjx+BVIYD9c3yqcv/yKC7CmdCZat4rq2yiE1UMSJC5ivKfMtQ==", "license": "MIT", "dependencies": { "string-width": "^4.2.3", @@ -7702,8 +6755,6 @@ }, "node_modules/cliui": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -7716,8 +6767,6 @@ }, "node_modules/clone": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "license": "MIT", "engines": { "node": ">=0.8" @@ -7725,8 +6774,6 @@ }, "node_modules/clone-deep": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7740,8 +6787,6 @@ }, "node_modules/clone-regexp": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-3.0.0.tgz", - "integrity": "sha512-ujdnoq2Kxb8s3ItNBtnYeXdm07FcU0u8ARAT1lQ2YdMwQC+cdiXX8KoqMVuglztILivceTtp4ivqGSmEmhBUJw==", "license": "MIT", "dependencies": { "is-regexp": "^3.0.0" @@ -7755,8 +6800,6 @@ }, "node_modules/cluster-key-slot": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", "license": "Apache-2.0", "engines": { "node": ">=0.10.0" @@ -7764,8 +6807,6 @@ }, "node_modules/color": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/color/-/color-5.0.3.tgz", - "integrity": "sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==", "license": "MIT", "dependencies": { "color-convert": "^3.1.3", @@ -7791,8 +6832,6 @@ }, "node_modules/color-string": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-2.1.4.tgz", - "integrity": "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==", "license": "MIT", "dependencies": { "color-name": "^2.0.0" @@ -7803,8 +6842,6 @@ }, "node_modules/color-string/node_modules/color-name": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz", - "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==", "license": "MIT", "engines": { "node": ">=12.20" @@ -7812,8 +6849,6 @@ }, "node_modules/color-support": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "license": "ISC", "bin": { "color-support": "bin.js" @@ -7821,8 +6856,6 @@ }, "node_modules/color/node_modules/color-convert": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz", - "integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==", "license": "MIT", "dependencies": { "color-name": "^2.0.0" @@ -7833,8 +6866,6 @@ }, "node_modules/color/node_modules/color-name": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz", - "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==", "license": "MIT", "engines": { "node": ">=12.20" @@ -7842,14 +6873,10 @@ }, "node_modules/colorette": { "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "license": "MIT" }, "node_modules/columnify": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", - "integrity": "sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==", "license": "MIT", "dependencies": { "strip-ansi": "^6.0.1", @@ -7861,8 +6888,6 @@ }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -7873,8 +6898,6 @@ }, "node_modules/commander": { "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "dev": true, "license": "MIT", "engines": { @@ -7891,21 +6914,15 @@ }, "node_modules/commondir": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true, "license": "MIT" }, "node_modules/composite-error": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/composite-error/-/composite-error-1.0.2.tgz", - "integrity": "sha512-kr6tZNUb15tHkSGhS6kNxxLHpgYguU6r5F+bUXcxbNYkLGIPX/Z2KKyXgli5t83FjGkBJ+GrludBoj3O8E/1Hw==", "license": "MIT" }, "node_modules/compressible": { "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" @@ -7916,8 +6933,6 @@ }, "node_modules/compression": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", - "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -7934,8 +6949,6 @@ }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -7943,14 +6956,10 @@ }, "node_modules/compression/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "license": "MIT" }, "node_modules/concat-stream": { @@ -7968,8 +6977,6 @@ }, "node_modules/concurrently": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", - "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", "dev": true, "license": "MIT", "dependencies": { @@ -7996,14 +7003,10 @@ }, "node_modules/console-control-strings": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "license": "ISC" }, "node_modules/console-table-printer": { "version": "2.15.0", - "resolved": "https://registry.npmjs.org/console-table-printer/-/console-table-printer-2.15.0.tgz", - "integrity": "sha512-SrhBq4hYVjLCkBVOWaTzceJalvn5K1Zq5aQA6wXC/cYjI3frKWNPEMK3sZsJfNNQApvCQmgBcc13ZKmFj8qExw==", "license": "MIT", "dependencies": { "simple-wcswidth": "^1.1.2" @@ -8011,8 +7014,6 @@ }, "node_modules/content-disposition": { "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -8023,8 +7024,6 @@ }, "node_modules/content-type": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -8032,8 +7031,6 @@ }, "node_modules/convert-hrtime": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz", - "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==", "license": "MIT", "engines": { "node": ">=12" @@ -8044,15 +7041,11 @@ }, "node_modules/convert-source-map": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true, "license": "MIT" }, "node_modules/convertapi": { "version": "1.15.0", - "resolved": "https://registry.npmjs.org/convertapi/-/convertapi-1.15.0.tgz", - "integrity": "sha512-wu1pJ27SuIc/mNlbjs8lP1hAsEN16AmKzMZNo9Qx/Z3CrH1ozGQYF2jGXaceXWSRNvKFoCuF0m5ek+vz8Nswrw==", "license": "MIT", "dependencies": { "axios": "^1.6.2" @@ -8060,8 +7053,6 @@ }, "node_modules/cookie": { "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -8069,8 +7060,6 @@ }, "node_modules/cookie-parser": { "version": "1.4.7", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz", - "integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==", "license": "MIT", "dependencies": { "cookie": "0.7.2", @@ -8082,14 +7071,10 @@ }, "node_modules/cookie-signature": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, "node_modules/copy-webpack-plugin": { "version": "12.0.2", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", - "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", "license": "MIT", "dependencies": { "fast-glob": "^3.3.2", @@ -8110,16 +7095,8 @@ "webpack": "^5.1.0" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "license": "MIT" - }, "node_modules/cors": { "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "license": "MIT", "dependencies": { "object-assign": "^4", @@ -8131,8 +7108,6 @@ }, "node_modules/corser": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", - "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", "dev": true, "license": "MIT", "engines": { @@ -8141,8 +7116,6 @@ }, "node_modules/cpu-features": { "version": "0.0.10", - "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", - "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", "hasInstallScript": true, "optional": true, "dependencies": { @@ -8155,8 +7128,6 @@ }, "node_modules/cross-fetch": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", - "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", "license": "MIT", "dependencies": { "node-fetch": "^2.7.0" @@ -8164,8 +7135,6 @@ }, "node_modules/cross-spawn": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -8178,8 +7147,6 @@ }, "node_modules/css-select": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -8195,8 +7162,6 @@ }, "node_modules/css-tree": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, "license": "MIT", "dependencies": { @@ -8209,8 +7174,6 @@ }, "node_modules/css-what": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", "license": "BSD-2-Clause", "engines": { "node": ">= 6" @@ -8221,8 +7184,6 @@ }, "node_modules/csso": { "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", "license": "MIT", "dependencies": { "css-tree": "~2.2.0" @@ -8234,8 +7195,6 @@ }, "node_modules/csso/node_modules/css-tree": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", "license": "MIT", "dependencies": { "mdn-data": "2.0.28", @@ -8248,14 +7207,10 @@ }, "node_modules/csso/node_modules/mdn-data": { "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", "license": "CC0-1.0" }, "node_modules/cssstyle": { "version": "5.3.3", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.3.tgz", - "integrity": "sha512-OytmFH+13/QXONJcC75QNdMtKpceNk3u8ThBjyyYjkEcy/ekBwR1mMAuNvi3gdBPW3N5TlCzQ0WZw8H0lN/bDw==", "dev": true, "license": "MIT", "dependencies": { @@ -8269,8 +7224,6 @@ }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "license": "MIT", "engines": { "node": ">= 12" @@ -8278,8 +7231,6 @@ }, "node_modules/data-urls": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.0.tgz", - "integrity": "sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==", "dev": true, "license": "MIT", "dependencies": { @@ -8292,8 +7243,6 @@ }, "node_modules/date-fns": { "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", "dev": true, "license": "MIT", "dependencies": { @@ -8309,8 +7258,6 @@ }, "node_modules/debug": { "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -8326,8 +7273,6 @@ }, "node_modules/decamelize": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, "license": "MIT", "engines": { @@ -8336,15 +7281,11 @@ }, "node_modules/decimal.js": { "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", "dev": true, "license": "MIT" }, "node_modules/decode-bmp": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/decode-bmp/-/decode-bmp-0.2.1.tgz", - "integrity": "sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==", "license": "MIT", "dependencies": { "@canvas/image-data": "^1.0.0", @@ -8356,8 +7297,6 @@ }, "node_modules/decode-ico": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/decode-ico/-/decode-ico-0.4.1.tgz", - "integrity": "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==", "license": "MIT", "dependencies": { "@canvas/image-data": "^1.0.0", @@ -8370,8 +7309,6 @@ }, "node_modules/decompress-response": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" @@ -8385,8 +7322,6 @@ }, "node_modules/dedent": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", - "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -8399,8 +7334,6 @@ }, "node_modules/deep-eql": { "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "license": "MIT", "dependencies": { "type-detect": "^4.0.0" @@ -8411,8 +7344,6 @@ }, "node_modules/deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "license": "MIT", "engines": { "node": ">=4.0.0" @@ -8420,14 +7351,10 @@ }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "license": "MIT" }, "node_modules/default-browser": { "version": "5.4.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.4.0.tgz", - "integrity": "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==", "license": "MIT", "dependencies": { "bundle-name": "^4.1.0", @@ -8442,8 +7369,6 @@ }, "node_modules/default-browser-id": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", - "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", "license": "MIT", "engines": { "node": ">=18" @@ -8454,8 +7379,6 @@ }, "node_modules/default-require-extensions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", "dev": true, "license": "MIT", "dependencies": { @@ -8470,8 +7393,6 @@ }, "node_modules/defaults": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "license": "MIT", "dependencies": { "clone": "^1.0.2" @@ -8482,8 +7403,6 @@ }, "node_modules/define-lazy-prop": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "license": "MIT", "engines": { "node": ">=12" @@ -8494,8 +7413,6 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -8503,14 +7420,10 @@ }, "node_modules/delegates": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", "license": "MIT" }, "node_modules/denque": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", "license": "Apache-2.0", "engines": { "node": ">=0.10" @@ -8518,8 +7431,6 @@ }, "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -8527,8 +7438,6 @@ }, "node_modules/destroy": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "license": "MIT", "engines": { "node": ">= 0.8", @@ -8537,8 +7446,6 @@ }, "node_modules/detect-libc": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "engines": { "node": ">=8" @@ -8550,8 +7457,6 @@ }, "node_modules/diff": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -8559,14 +7464,10 @@ }, "node_modules/diff-match-patch": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", - "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==", "license": "Apache-2.0" }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "license": "MIT", "dependencies": { @@ -8578,8 +7479,6 @@ }, "node_modules/dir-glob/node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, "license": "MIT", "engines": { @@ -8588,14 +7487,10 @@ }, "node_modules/dns2": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/dns2/-/dns2-2.1.0.tgz", - "integrity": "sha512-m27K11aQalRbmUs7RLaz6aPyceLjAoqjPRNTdE7qUouQpl+PC8Bi67O+i9SuJUPbQC8dxFrczAxfmTPuTKHNkw==", "license": "MIT" }, "node_modules/doctrine": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" @@ -8606,8 +7501,6 @@ }, "node_modules/dom-converter": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", "dev": true, "license": "MIT", "dependencies": { @@ -8616,8 +7509,6 @@ }, "node_modules/dom-serializer": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "dev": true, "license": "MIT", "dependencies": { @@ -8631,8 +7522,6 @@ }, "node_modules/dom-serializer/node_modules/entities": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true, "license": "BSD-2-Clause", "funding": { @@ -8640,14 +7529,10 @@ } }, "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + "version": "0.1.2" }, "node_modules/domelementtype": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "funding": [ { "type": "github", @@ -8658,8 +7543,6 @@ }, "node_modules/domhandler": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -8674,8 +7557,6 @@ }, "node_modules/domutils": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -8689,8 +7570,6 @@ }, "node_modules/dot-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dev": true, "license": "MIT", "dependencies": { @@ -8711,8 +7590,6 @@ }, "node_modules/dprint-node": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/dprint-node/-/dprint-node-1.0.8.tgz", - "integrity": "sha512-iVKnUtYfGrYcW1ZAlfR/F59cUVL8QIhWoBJoSjkkdua/dkWIgjZfiLMeTjiB06X0ZLkQ0M2C1VbUj/CxkIf1zg==", "dev": true, "license": "MIT", "dependencies": { @@ -8721,8 +7598,6 @@ }, "node_modules/dprint-node/node_modules/detect-libc": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -8734,8 +7609,6 @@ }, "node_modules/dunder-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -8748,8 +7621,6 @@ }, "node_modules/duplexify": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", - "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", "license": "MIT", "optional": true, "dependencies": { @@ -8761,14 +7632,10 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -8776,20 +7643,14 @@ }, "node_modules/ee-first": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, "node_modules/electron-to-chromium": { "version": "1.5.262", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.262.tgz", - "integrity": "sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ==", "license": "ISC" }, "node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/emulator": { @@ -8798,14 +7659,10 @@ }, "node_modules/enabled": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -8813,8 +7670,6 @@ }, "node_modules/end-of-stream": { "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "license": "MIT", "dependencies": { "once": "^1.4.0" @@ -8822,8 +7677,6 @@ }, "node_modules/engine.io": { "version": "6.6.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", - "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", "license": "MIT", "dependencies": { "@types/cors": "^2.8.12", @@ -8842,8 +7695,6 @@ }, "node_modules/engine.io-client": { "version": "6.6.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz", - "integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==", "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", @@ -8855,8 +7706,6 @@ }, "node_modules/engine.io-client/node_modules/debug": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -8872,8 +7721,6 @@ }, "node_modules/engine.io-client/node_modules/ws": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -8893,8 +7740,6 @@ }, "node_modules/engine.io-parser": { "version": "5.2.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", - "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -8902,8 +7747,6 @@ }, "node_modules/engine.io/node_modules/debug": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -8919,8 +7762,6 @@ }, "node_modules/engine.io/node_modules/ws": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -8940,8 +7781,6 @@ }, "node_modules/enhanced-resolve": { "version": "5.18.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", - "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -8953,8 +7792,6 @@ }, "node_modules/enquirer": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "license": "MIT", "dependencies": { "ansi-colors": "^4.1.1", @@ -8966,8 +7803,6 @@ }, "node_modules/entities": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -8979,8 +7814,6 @@ }, "node_modules/envinfo": { "version": "7.21.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", - "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", "dev": true, "license": "MIT", "bin": { @@ -8992,8 +7825,6 @@ }, "node_modules/es-define-property": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -9001,8 +7832,6 @@ }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -9010,14 +7839,10 @@ }, "node_modules/es-module-lexer": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", "license": "MIT" }, "node_modules/es-object-atoms": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -9028,8 +7853,6 @@ }, "node_modules/es-set-tostringtag": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -9043,15 +7866,11 @@ }, "node_modules/es6-error": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true, "license": "MIT" }, "node_modules/esbuild": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -9092,8 +7911,6 @@ }, "node_modules/escalade": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", "engines": { "node": ">=6" @@ -9101,14 +7918,10 @@ }, "node_modules/escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "license": "MIT", "engines": { "node": ">=10" @@ -9119,8 +7932,6 @@ }, "node_modules/eslint": { "version": "9.39.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", - "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", @@ -9178,8 +7989,6 @@ }, "node_modules/eslint-rule-composer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", - "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", "dev": true, "license": "MIT", "engines": { @@ -9188,8 +7997,6 @@ }, "node_modules/eslint-scope": { "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -9204,8 +8011,6 @@ }, "node_modules/eslint-visitor-keys": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -9216,8 +8021,6 @@ }, "node_modules/eslint/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" @@ -9225,8 +8028,6 @@ }, "node_modules/esm": { "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", "license": "MIT", "engines": { "node": ">=6" @@ -9234,8 +8035,6 @@ }, "node_modules/espree": { "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.15.0", @@ -9251,8 +8050,6 @@ }, "node_modules/esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, "license": "BSD-2-Clause", "bin": { @@ -9265,8 +8062,6 @@ }, "node_modules/esquery": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -9277,8 +8072,6 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" @@ -9289,8 +8082,6 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -9298,8 +8089,6 @@ }, "node_modules/estree-walker": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { @@ -9308,8 +8097,6 @@ }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" @@ -9317,8 +8104,6 @@ }, "node_modules/etag": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -9326,8 +8111,6 @@ }, "node_modules/event-target-shim": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "license": "MIT", "engines": { "node": ">=6" @@ -9335,29 +8118,21 @@ }, "node_modules/eventemitter3": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true, "license": "MIT" }, "node_modules/events": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", "engines": { "node": ">=0.8.x" } }, "node_modules/exif-parser": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", - "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==" + "version": "0.1.12" }, "node_modules/expand-template": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "license": "(MIT OR WTFPL)", "engines": { "node": ">=6" @@ -9365,8 +8140,6 @@ }, "node_modules/expect-type": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", - "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -9375,8 +8148,6 @@ }, "node_modules/express": { "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -9421,8 +8192,6 @@ }, "node_modules/express-xml-bodyparser": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/express-xml-bodyparser/-/express-xml-bodyparser-0.4.1.tgz", - "integrity": "sha512-PlojEEQXdwc68ofPiAanknPf4QBTrFWXPZ+5jDhfrXP/CdLaqEQxQuuzrCqnvy1kETciTxz6OFnDZW/rIxtmlQ==", "license": "MIT", "dependencies": { "xml2js": "^0.6.2" @@ -9433,8 +8202,6 @@ }, "node_modules/express/node_modules/cookie": { "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -9442,8 +8209,6 @@ }, "node_modules/express/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -9451,20 +8216,14 @@ }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/extend": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, "node_modules/farmhash-modern": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", - "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -9472,14 +8231,10 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -9494,8 +8249,6 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -9506,20 +8259,14 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "license": "MIT" }, "node_modules/fast-uri": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "funding": [ { "type": "github", @@ -9534,8 +8281,6 @@ }, "node_modules/fast-xml-parser": { "version": "5.2.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz", - "integrity": "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==", "funding": [ { "type": "github", @@ -9552,8 +8297,6 @@ }, "node_modules/fastest-levenshtein": { "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, "license": "MIT", "engines": { @@ -9562,8 +8305,6 @@ }, "node_modules/fastq": { "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -9571,8 +8312,6 @@ }, "node_modules/faye-websocket": { "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" @@ -9583,8 +8322,6 @@ }, "node_modules/fdir": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", "engines": { @@ -9601,14 +8338,10 @@ }, "node_modules/fecha": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", "license": "MIT" }, "node_modules/fetch-blob": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", "funding": [ { "type": "github", @@ -9630,14 +8363,10 @@ }, "node_modules/fflate": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.1.tgz", - "integrity": "sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ==", "license": "MIT" }, "node_modules/file-entry-cache": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "license": "MIT", "dependencies": { "flat-cache": "^4.0.0" @@ -9648,8 +8377,6 @@ }, "node_modules/file-stream-rotator": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz", - "integrity": "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==", "license": "MIT", "dependencies": { "moment": "^2.29.1" @@ -9657,8 +8384,6 @@ }, "node_modules/file-type": { "version": "18.7.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-18.7.0.tgz", - "integrity": "sha512-ihHtXRzXEziMrQ56VSgU7wkxh55iNchFkosu7Y9/S+tXHdKyrGjVK0ujbqNnsxzea+78MaLhN6PGmfYSAv1ACw==", "license": "MIT", "dependencies": { "readable-web-to-node-stream": "^3.0.2", @@ -9674,8 +8399,6 @@ }, "node_modules/file-uri-to-path": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "license": "MIT" }, "node_modules/file-walker": { @@ -9684,8 +8407,6 @@ }, "node_modules/fill-keys": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", - "integrity": "sha512-tcgI872xXjwFF4xgQmLxi76GnwJG3g/3isB1l4/G5Z4zrbddGpBjqZCO9oEAcB5wX0Hj/5iQB3toxfO7in1hHA==", "license": "MIT", "dependencies": { "is-object": "~1.0.1", @@ -9697,8 +8418,6 @@ }, "node_modules/fill-range": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -9709,8 +8428,6 @@ }, "node_modules/finalhandler": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -9727,8 +8444,6 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -9736,14 +8451,10 @@ }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/find-cache-dir": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "license": "MIT", "dependencies": { @@ -9760,8 +8471,6 @@ }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "license": "MIT", "dependencies": { "locate-path": "^6.0.0", @@ -9776,8 +8485,6 @@ }, "node_modules/firebase-admin": { "version": "13.6.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.6.0.tgz", - "integrity": "sha512-GdPA/t0+Cq8p1JnjFRBmxRxAGvF/kl2yfdhALl38PrRp325YxyQ5aNaHui0XmaKcKiGRFIJ/EgBNWFoDP0onjw==", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -9802,8 +8509,6 @@ }, "node_modules/firebase-admin/node_modules/@types/node": { "version": "22.19.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz", - "integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -9811,8 +8516,6 @@ }, "node_modules/firebase-admin/node_modules/google-auth-library": { "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", - "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", @@ -9828,8 +8531,6 @@ }, "node_modules/firebase-admin/node_modules/gtoken": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", "license": "MIT", "dependencies": { "gaxios": "^6.0.0", @@ -9841,8 +8542,6 @@ }, "node_modules/firebase-admin/node_modules/uuid": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -9854,8 +8553,6 @@ }, "node_modules/flat": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, "license": "BSD-3-Clause", "bin": { @@ -9864,8 +8561,6 @@ }, "node_modules/flat-cache": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "license": "MIT", "dependencies": { "flatted": "^3.2.9", @@ -9877,20 +8572,14 @@ }, "node_modules/flatted": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "license": "ISC" }, "node_modules/fn.name": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", "license": "MIT" }, "node_modules/follow-redirects": { "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", @@ -9909,8 +8598,6 @@ }, "node_modules/foreground-child": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", "dev": true, "license": "ISC", "dependencies": { @@ -9923,8 +8610,6 @@ }, "node_modules/form-data": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -9939,14 +8624,10 @@ }, "node_modules/form-data-encoder": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", - "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", "license": "MIT" }, "node_modules/formdata-node": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", - "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", "license": "MIT", "dependencies": { "node-domexception": "1.0.0", @@ -9958,8 +8639,6 @@ }, "node_modules/formdata-node/node_modules/web-streams-polyfill": { "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", "license": "MIT", "engines": { "node": ">= 14" @@ -9967,8 +8646,6 @@ }, "node_modules/formdata-polyfill": { "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", "license": "MIT", "dependencies": { "fetch-blob": "^3.1.2" @@ -9979,8 +8656,6 @@ }, "node_modules/forwarded": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -9988,8 +8663,6 @@ }, "node_modules/fresh": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -9997,8 +8670,6 @@ }, "node_modules/fromentries": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", "dev": true, "funding": [ { @@ -10018,8 +8689,6 @@ }, "node_modules/fs-constants": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "license": "MIT" }, "node_modules/fs-extra": { @@ -10037,8 +8706,6 @@ }, "node_modules/fs-minipass": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "license": "ISC", "dependencies": { "minipass": "^3.0.0" @@ -10049,8 +8716,6 @@ }, "node_modules/fs-minipass/node_modules/minipass": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -10061,22 +8726,15 @@ }, "node_modules/fs-mode-to-string": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/fs-mode-to-string/-/fs-mode-to-string-0.0.2.tgz", - "integrity": "sha512-8Pik0/TZnN1uuEO5TdmDoXkjTNA98BUD1uM3RWepPXDLAO9tbmiluyu+fVwWX7C4sKKxDX+64rWNwtNwDJA3Yg==", "license": "MIT" }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ @@ -10088,8 +8746,6 @@ }, "node_modules/function-bind": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10097,8 +8753,6 @@ }, "node_modules/function-timeout": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-0.1.1.tgz", - "integrity": "sha512-0NVVC0TaP7dSTvn1yMiy6d6Q8gifzbvQafO46RtLG/kHJUBNd+pVRGOBoK44wNBvtSPUJRfdVvkFdD3p0xvyZg==", "license": "MIT", "engines": { "node": ">=14.16" @@ -10109,16 +8763,11 @@ }, "node_modules/functional-red-black-tree": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "license": "MIT", "optional": true }, "node_modules/gauge": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "deprecated": "This package is no longer supported.", "license": "ISC", "dependencies": { "aproba": "^1.0.3 || ^2.0.0", @@ -10137,8 +8786,6 @@ }, "node_modules/gaxios": { "version": "6.7.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", - "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", @@ -10153,8 +8800,6 @@ }, "node_modules/gaxios/node_modules/agent-base": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "license": "MIT", "engines": { "node": ">= 14" @@ -10162,8 +8807,6 @@ }, "node_modules/gaxios/node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", "dependencies": { "agent-base": "^7.1.2", @@ -10175,8 +8818,6 @@ }, "node_modules/gcp-metadata": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", - "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", "license": "Apache-2.0", "dependencies": { "gaxios": "^6.1.1", @@ -10189,8 +8830,6 @@ }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "license": "MIT", "engines": { @@ -10203,8 +8842,6 @@ }, "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -10212,8 +8849,6 @@ }, "node_modules/get-func-name": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "license": "MIT", "engines": { "node": "*" @@ -10221,8 +8856,6 @@ }, "node_modules/get-intrinsic": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -10245,8 +8878,6 @@ }, "node_modules/get-package-type": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "license": "MIT", "engines": { "node": ">=8.0.0" @@ -10254,8 +8885,6 @@ }, "node_modules/get-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -10267,14 +8896,10 @@ }, "node_modules/getopts": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", - "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==", "license": "MIT" }, "node_modules/gifwrap": { "version": "0.10.1", - "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz", - "integrity": "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==", "license": "MIT", "dependencies": { "image-q": "^4.0.0", @@ -10283,14 +8908,10 @@ }, "node_modules/github-from-package": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "license": "MIT" }, "node_modules/gitignore-to-glob": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz", - "integrity": "sha512-mk74BdnK7lIwDHnotHddx1wsjMOFIThpLY3cPNniJ/2fA/tlLzHnFxIdR+4sLOu5KGgQJdij4kjJ2RoUNnCNMA==", "dev": true, "license": "MIT", "engines": { @@ -10299,9 +8920,6 @@ }, "node_modules/glob": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -10320,8 +8938,6 @@ }, "node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -10332,14 +8948,10 @@ }, "node_modules/glob-to-regexp": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "license": "BSD-2-Clause" }, "node_modules/glob/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10348,8 +8960,6 @@ }, "node_modules/glob/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "license": "ISC", "dependencies": { @@ -10361,8 +8971,6 @@ }, "node_modules/global": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", "license": "MIT", "dependencies": { "min-document": "^2.19.0", @@ -10382,8 +8990,6 @@ }, "node_modules/globby": { "version": "14.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", - "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", @@ -10402,8 +9008,6 @@ }, "node_modules/google-auth-library": { "version": "10.5.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz", - "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", @@ -10420,8 +9024,6 @@ }, "node_modules/google-auth-library/node_modules/agent-base": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "license": "MIT", "engines": { "node": ">= 14" @@ -10429,8 +9031,6 @@ }, "node_modules/google-auth-library/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -10438,8 +9038,6 @@ }, "node_modules/google-auth-library/node_modules/foreground-child": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", @@ -10454,8 +9052,6 @@ }, "node_modules/google-auth-library/node_modules/gaxios": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", - "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", @@ -10469,8 +9065,6 @@ }, "node_modules/google-auth-library/node_modules/gcp-metadata": { "version": "8.1.2", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", - "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", "license": "Apache-2.0", "dependencies": { "gaxios": "^7.0.0", @@ -10483,8 +9077,6 @@ }, "node_modules/google-auth-library/node_modules/glob": { "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -10503,8 +9095,6 @@ }, "node_modules/google-auth-library/node_modules/google-logging-utils": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", - "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -10512,8 +9102,6 @@ }, "node_modules/google-auth-library/node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", "dependencies": { "agent-base": "^7.1.2", @@ -10525,8 +9113,6 @@ }, "node_modules/google-auth-library/node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -10540,8 +9126,6 @@ }, "node_modules/google-auth-library/node_modules/minipass": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -10549,8 +9133,6 @@ }, "node_modules/google-auth-library/node_modules/node-fetch": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", @@ -10567,8 +9149,6 @@ }, "node_modules/google-auth-library/node_modules/rimraf": { "version": "5.0.10", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", - "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", "license": "ISC", "dependencies": { "glob": "^10.3.7" @@ -10582,8 +9162,6 @@ }, "node_modules/google-auth-library/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "license": "ISC", "engines": { "node": ">=14" @@ -10594,8 +9172,6 @@ }, "node_modules/google-gax": { "version": "4.6.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.6.1.tgz", - "integrity": "sha512-V6eky/xz2mcKfAd1Ioxyd6nmA61gao3n01C+YeuIwu3vzM9EDR6wcVzMSIbLMDXWeoi9SHYctXuKYC5uJUT3eQ==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -10618,8 +9194,6 @@ }, "node_modules/google-gax/node_modules/@grpc/proto-loader": { "version": "0.7.15", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", - "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -10637,8 +9211,6 @@ }, "node_modules/google-gax/node_modules/google-auth-library": { "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", - "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -10655,8 +9227,6 @@ }, "node_modules/google-gax/node_modules/gtoken": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", "license": "MIT", "optional": true, "dependencies": { @@ -10669,8 +9239,6 @@ }, "node_modules/google-logging-utils": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", - "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -10678,8 +9246,6 @@ }, "node_modules/gopd": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -10690,21 +9256,15 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true, "license": "MIT" }, "node_modules/groq-sdk": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/groq-sdk/-/groq-sdk-0.5.0.tgz", - "integrity": "sha512-RVmhW7qZ+XZoy5fIuSdx/LGQJONpL8MHgZEW7dFwTdgkzStub2XQx6OKv28CHogijdwH41J+Npj/z2jBPu3vmw==", "license": "Apache-2.0", "dependencies": { "@types/node": "^18.11.18", @@ -10719,8 +9279,6 @@ }, "node_modules/groq-sdk/node_modules/@types/node": { "version": "18.19.130", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", - "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", "license": "MIT", "dependencies": { "undici-types": "~5.26.4" @@ -10728,14 +9286,10 @@ }, "node_modules/groq-sdk/node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "license": "MIT" }, "node_modules/gtoken": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", - "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", "license": "MIT", "dependencies": { "gaxios": "^7.0.0", @@ -10747,8 +9301,6 @@ }, "node_modules/gtoken/node_modules/agent-base": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "license": "MIT", "engines": { "node": ">= 14" @@ -10756,8 +9308,6 @@ }, "node_modules/gtoken/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -10765,8 +9315,6 @@ }, "node_modules/gtoken/node_modules/foreground-child": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", @@ -10781,8 +9329,6 @@ }, "node_modules/gtoken/node_modules/gaxios": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", - "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", @@ -10796,8 +9342,6 @@ }, "node_modules/gtoken/node_modules/glob": { "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -10816,8 +9360,6 @@ }, "node_modules/gtoken/node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", "dependencies": { "agent-base": "^7.1.2", @@ -10829,8 +9371,6 @@ }, "node_modules/gtoken/node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -10844,8 +9384,6 @@ }, "node_modules/gtoken/node_modules/minipass": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -10853,8 +9391,6 @@ }, "node_modules/gtoken/node_modules/node-fetch": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", @@ -10871,8 +9407,6 @@ }, "node_modules/gtoken/node_modules/rimraf": { "version": "5.0.10", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", - "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", "license": "ISC", "dependencies": { "glob": "^10.3.7" @@ -10886,8 +9420,6 @@ }, "node_modules/gtoken/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "license": "ISC", "engines": { "node": ">=14" @@ -10898,8 +9430,6 @@ }, "node_modules/handlebars": { "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "license": "MIT", "dependencies": { "minimist": "^1.2.5", @@ -10926,8 +9456,6 @@ }, "node_modules/has-symbols": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -10938,8 +9466,6 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -10953,14 +9479,10 @@ }, "node_modules/has-unicode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "license": "ISC" }, "node_modules/hasha": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10976,8 +9498,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -10988,8 +9508,6 @@ }, "node_modules/he": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, "license": "MIT", "bin": { @@ -10998,8 +9516,6 @@ }, "node_modules/helmet": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.2.0.tgz", - "integrity": "sha512-ZRiwvN089JfMXokizgqEPXsl2Guk094yExfoDXR0cBYWxtBbaSww/w+vT4WEJsBW2iTUi1GgZ6swmoug3Oy4Xw==", "license": "MIT", "engines": { "node": ">=16.0.0" @@ -11007,8 +9523,6 @@ }, "node_modules/hi-base32": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", - "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==", "license": "MIT" }, "node_modules/html-encoding-sniffer": { @@ -11024,8 +9538,6 @@ }, "node_modules/html-entities": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", - "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", "funding": [ { "type": "github", @@ -11040,15 +9552,11 @@ }, "node_modules/html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true, "license": "MIT" }, "node_modules/html-minifier-terser": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", "dev": true, "license": "MIT", "dependencies": { @@ -11069,8 +9577,6 @@ }, "node_modules/html-webpack-plugin": { "version": "5.6.5", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.5.tgz", - "integrity": "sha512-4xynFbKNNk+WlzXeQQ+6YYsH2g7mpfPszQZUi3ovKlj+pDmngQ7vRXjrrmGROabmKwyQkcgcX5hqfOwHbFmK5g==", "dev": true, "license": "MIT", "dependencies": { @@ -11102,8 +9608,6 @@ }, "node_modules/htmlparser2": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", @@ -11122,8 +9626,6 @@ }, "node_modules/htmlparser2/node_modules/entities": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true, "license": "BSD-2-Clause", "funding": { @@ -11132,8 +9634,6 @@ }, "node_modules/http-errors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "license": "MIT", "dependencies": { "depd": "2.0.0", @@ -11148,14 +9648,10 @@ }, "node_modules/http-parser-js": { "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", "license": "MIT" }, "node_modules/http-proxy": { "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "license": "MIT", "dependencies": { @@ -11182,8 +9678,6 @@ }, "node_modules/http-server": { "version": "14.1.1", - "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", - "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", "dev": true, "license": "MIT", "dependencies": { @@ -11210,8 +9704,6 @@ }, "node_modules/http-server/node_modules/mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, "license": "MIT", "bin": { @@ -11223,8 +9715,6 @@ }, "node_modules/https-proxy-agent": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "license": "MIT", "dependencies": { "agent-base": "6", @@ -11236,8 +9726,6 @@ }, "node_modules/humanize-ms": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", "license": "MIT", "dependencies": { "ms": "^2.0.0" @@ -11245,8 +9733,6 @@ }, "node_modules/husky": { "version": "9.1.7", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", - "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", "dev": true, "license": "MIT", "bin": { @@ -11261,8 +9747,6 @@ }, "node_modules/ico-endec": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ico-endec/-/ico-endec-0.1.6.tgz", - "integrity": "sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==", "license": "MPL-2.0" }, "node_modules/iconv-lite": { @@ -11278,8 +9762,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -11298,8 +9780,6 @@ }, "node_modules/ignore": { "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "license": "MIT", "engines": { "node": ">= 4" @@ -11307,15 +9787,11 @@ }, "node_modules/ignore-by-default": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true, "license": "ISC" }, "node_modules/image-q": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", - "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==", "license": "MIT", "dependencies": { "@types/node": "16.9.1" @@ -11323,14 +9799,10 @@ }, "node_modules/image-q/node_modules/@types/node": { "version": "16.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", - "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==", "license": "MIT" }, "node_modules/import-fresh": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -11345,8 +9817,6 @@ }, "node_modules/import-local": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, "license": "MIT", "dependencies": { @@ -11365,8 +9835,6 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "license": "MIT", "engines": { "node": ">=0.8.19" @@ -11374,8 +9842,6 @@ }, "node_modules/indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, "license": "MIT", "engines": { @@ -11384,9 +9850,6 @@ }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -11395,26 +9858,14 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "license": "ISC" }, - "node_modules/int53": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/int53/-/int53-0.2.4.tgz", - "integrity": "sha512-a5jlKftS7HUOhkUyYD7j2sJ/ZnvWiNlZS1ldR+g1ifQ+/UuZXIE+YTc/lK1qGj/GwAU5F8Z0e1eVq2t1J5Ob2g==", - "license": "BSD-3-Clause" - }, "node_modules/interpret": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -11422,8 +9873,6 @@ }, "node_modules/ioredis": { "version": "5.8.2", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.8.2.tgz", - "integrity": "sha512-C6uC+kleiIMmjViJINWk80sOQw5lEzse1ZmvD+S/s8p8CWapftSaC+kocGTx6xrbrJ4WmYQGC08ffHLr6ToR6Q==", "license": "MIT", "dependencies": { "@ioredis/commands": "1.4.0", @@ -11446,8 +9895,6 @@ }, "node_modules/ip-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-5.0.0.tgz", - "integrity": "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==", "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -11458,8 +9905,6 @@ }, "node_modules/ipaddr.js": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -11467,8 +9912,6 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "license": "MIT", "dependencies": { @@ -11480,8 +9923,6 @@ }, "node_modules/is-core-module": { "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -11495,8 +9936,6 @@ }, "node_modules/is-docker": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "license": "MIT", "bin": { "is-docker": "cli.js" @@ -11510,8 +9949,6 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11519,8 +9956,6 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { "node": ">=8" @@ -11528,14 +9963,10 @@ }, "node_modules/is-function": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", "license": "MIT" }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -11546,8 +9977,6 @@ }, "node_modules/is-inside-container": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", "license": "MIT", "dependencies": { "is-docker": "^3.0.0" @@ -11564,8 +9993,6 @@ }, "node_modules/is-ip": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-5.0.1.tgz", - "integrity": "sha512-FCsGHdlrOnZQcp0+XT5a+pYowf33itBalCl+7ovNXC/7o5BhIpG14M3OrpPPdBSIQJCm+0M5+9mO7S9VVTTCFw==", "license": "MIT", "dependencies": { "ip-regex": "^5.0.0", @@ -11580,8 +10007,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "license": "MIT", "engines": { "node": ">=0.12.0" @@ -11589,8 +10014,6 @@ }, "node_modules/is-object": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11598,8 +10021,6 @@ }, "node_modules/is-plain-obj": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, "license": "MIT", "engines": { @@ -11608,8 +10029,6 @@ }, "node_modules/is-plain-object": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "license": "MIT", "dependencies": { @@ -11621,15 +10040,11 @@ }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true, "license": "MIT" }, "node_modules/is-regexp": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz", - "integrity": "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==", "license": "MIT", "engines": { "node": ">=12" @@ -11640,8 +10055,6 @@ }, "node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "license": "MIT", "engines": { "node": ">=8" @@ -11652,15 +10065,11 @@ }, "node_modules/is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true, "license": "MIT" }, "node_modules/is-unicode-supported": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "license": "MIT", "engines": { @@ -11672,8 +10081,6 @@ }, "node_modules/is-windows": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, "license": "MIT", "engines": { @@ -11682,8 +10089,6 @@ }, "node_modules/is-wsl": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "license": "MIT", "dependencies": { "is-inside-container": "^1.0.0" @@ -11695,16 +10100,8 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, "node_modules/isbot": { "version": "3.8.0", - "resolved": "https://registry.npmjs.org/isbot/-/isbot-3.8.0.tgz", - "integrity": "sha512-vne1mzQUTR+qsMLeCBL9+/tgnDXRyc2pygLGl/WsgA+EZKIiB5Ehu0CiVTHIIk30zhJ24uGz4M5Ppse37aR0Hg==", "license": "Unlicense", "engines": { "node": ">=12" @@ -11712,14 +10109,10 @@ }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, "node_modules/isobject": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "license": "MIT", "engines": { @@ -11728,8 +10121,6 @@ }, "node_modules/isomorphic-fetch": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", "license": "MIT", "dependencies": { "node-fetch": "^2.6.1", @@ -11738,8 +10129,6 @@ }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -11748,8 +10137,6 @@ }, "node_modules/istanbul-lib-hook": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -11761,8 +10148,6 @@ }, "node_modules/istanbul-lib-instrument": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -11777,8 +10162,6 @@ }, "node_modules/istanbul-lib-instrument/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -11787,8 +10170,6 @@ }, "node_modules/istanbul-lib-processinfo": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", "dev": true, "license": "ISC", "dependencies": { @@ -11805,8 +10186,6 @@ }, "node_modules/istanbul-lib-processinfo/node_modules/p-map": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, "license": "MIT", "dependencies": { @@ -11818,8 +10197,6 @@ }, "node_modules/istanbul-lib-processinfo/node_modules/uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "license": "MIT", "bin": { @@ -11828,8 +10205,6 @@ }, "node_modules/istanbul-lib-report": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -11843,8 +10218,6 @@ }, "node_modules/istanbul-lib-report/node_modules/make-dir": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "license": "MIT", "dependencies": { @@ -11859,8 +10232,6 @@ }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { @@ -11872,8 +10243,6 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -11887,8 +10256,6 @@ }, "node_modules/istanbul-reports": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -11901,8 +10268,6 @@ }, "node_modules/jackspeak": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -11916,8 +10281,6 @@ }, "node_modules/javascript-time-ago": { "version": "2.5.12", - "resolved": "https://registry.npmjs.org/javascript-time-ago/-/javascript-time-ago-2.5.12.tgz", - "integrity": "sha512-s8PPq2HQ3HIbSU0SjhNvTitf5VoXbQWof9q6k3gIX7F2il0ptjD5lONTDccpuKt/2U7RjbCp/TCHPK7eDwO7zQ==", "license": "MIT", "dependencies": { "relative-time-format": "^1.1.7" @@ -11925,8 +10288,6 @@ }, "node_modules/jest-worker": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -11939,8 +10300,6 @@ }, "node_modules/jimp": { "version": "0.22.12", - "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.22.12.tgz", - "integrity": "sha512-R5jZaYDnfkxKJy1dwLpj/7cvyjxiclxU3F4TrI/J4j2rS0niq6YDUMoPn5hs8GDpO+OZGo7Ky057CRtWesyhfg==", "license": "MIT", "dependencies": { "@jimp/custom": "^0.22.12", @@ -11964,8 +10323,6 @@ }, "node_modules/jose": { "version": "4.15.9", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", - "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -11973,14 +10330,10 @@ }, "node_modules/jpeg-js": { "version": "0.4.4", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", - "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", "license": "BSD-3-Clause" }, "node_modules/js-levenshtein": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11988,20 +10341,14 @@ }, "node_modules/js-sha256": { "version": "0.9.0", - "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", - "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==", "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -12012,8 +10359,6 @@ }, "node_modules/jsdom": { "version": "27.2.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.2.0.tgz", - "integrity": "sha512-454TI39PeRDW1LgpyLPyURtB4Zx1tklSr6+OFOipsxGUH1WMTvk6C65JQdrj455+DP2uJ1+veBEHTGFKWVLFoA==", "dev": true, "license": "MIT", "dependencies": { @@ -12052,8 +10397,6 @@ }, "node_modules/jsdom/node_modules/agent-base": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, "license": "MIT", "engines": { @@ -12062,8 +10405,6 @@ }, "node_modules/jsdom/node_modules/html-encoding-sniffer": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12075,8 +10416,6 @@ }, "node_modules/jsdom/node_modules/http-proxy-agent": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, "license": "MIT", "dependencies": { @@ -12089,8 +10428,6 @@ }, "node_modules/jsdom/node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, "license": "MIT", "dependencies": { @@ -12103,8 +10440,6 @@ }, "node_modules/jsdom/node_modules/whatwg-encoding": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12116,8 +10451,6 @@ }, "node_modules/jsesc": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -12128,8 +10461,6 @@ }, "node_modules/json-bigint": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", "license": "MIT", "dependencies": { "bignumber.js": "^9.0.0" @@ -12137,14 +10468,10 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "license": "MIT" }, "node_modules/json-colorizer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-colorizer/-/json-colorizer-3.0.1.tgz", - "integrity": "sha512-4YyRAbD6eHeRnJD9vo0zjiU5fyY9QR6T+iYuH5DpO0XPThKWozpD4MaeY/8nLZIkHC3yEQMFLL+6P94E+JekDw==", "license": "MIT", "dependencies": { "colorette": "^2.0.20" @@ -12152,22 +10479,16 @@ }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "license": "MIT" }, "node_modules/json-query": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/json-query/-/json-query-2.2.2.tgz", - "integrity": "sha512-y+IcVZSdqNmS4fO8t1uZF6RMMs0xh3SrTjJr9bp1X3+v0Q13+7Cyv12dSmKwDswp/H427BVtpkLWhGxYu3ZWRA==", "engines": { "node": "*" } }, "node_modules/json-schema-to-ts": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", - "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", @@ -12179,20 +10500,14 @@ }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -12214,8 +10529,6 @@ }, "node_modules/jsonwebtoken": { "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "license": "MIT", "dependencies": { "jws": "^3.2.2", @@ -12236,8 +10549,6 @@ }, "node_modules/jsonwebtoken/node_modules/jwa": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", - "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", "license": "MIT", "dependencies": { "buffer-equal-constant-time": "^1.0.1", @@ -12247,8 +10558,6 @@ }, "node_modules/jsonwebtoken/node_modules/jws": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", "license": "MIT", "dependencies": { "jwa": "^1.4.1", @@ -12257,8 +10566,6 @@ }, "node_modules/jssha": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.1.tgz", - "integrity": "sha512-VCMZj12FCFMQYcFLPRm/0lOBbLi8uM2BhXPTqw3U4YAfs4AZfiApOoBLoN8cQE60Z50m1MYMTQVCfgF/KaCVhQ==", "license": "BSD-3-Clause", "engines": { "node": "*" @@ -12266,14 +10573,10 @@ }, "node_modules/just-extend": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", - "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", "license": "MIT" }, "node_modules/jwa": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", "license": "MIT", "dependencies": { "buffer-equal-constant-time": "^1.0.1", @@ -12283,8 +10586,6 @@ }, "node_modules/jwks-rsa": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz", - "integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==", "license": "MIT", "dependencies": { "@types/express": "^4.17.20", @@ -12300,8 +10601,6 @@ }, "node_modules/jws": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", "license": "MIT", "dependencies": { "jwa": "^2.0.0", @@ -12314,8 +10613,6 @@ }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "license": "MIT", "dependencies": { "json-buffer": "3.0.1" @@ -12323,8 +10620,6 @@ }, "node_modules/kind-of": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, "license": "MIT", "engines": { @@ -12333,8 +10628,6 @@ }, "node_modules/knex": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/knex/-/knex-3.1.0.tgz", - "integrity": "sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==", "license": "MIT", "dependencies": { "colorette": "2.0.19", @@ -12384,14 +10677,10 @@ }, "node_modules/knex/node_modules/colorette": { "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "license": "MIT" }, "node_modules/knex/node_modules/commander": { "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "license": "MIT", "engines": { "node": ">=14" @@ -12399,8 +10688,6 @@ }, "node_modules/knex/node_modules/debug": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "license": "MIT", "dependencies": { "ms": "2.1.2" @@ -12416,14 +10703,10 @@ }, "node_modules/knex/node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "license": "MIT" }, "node_modules/knex/node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "license": "MIT", "engines": { "node": ">=8" @@ -12431,14 +10714,10 @@ }, "node_modules/kuler": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", "license": "MIT" }, "node_modules/leven": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12446,8 +10725,6 @@ }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", @@ -12459,8 +10736,6 @@ }, "node_modules/license-check-and-add": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/license-check-and-add/-/license-check-and-add-4.0.5.tgz", - "integrity": "sha512-FySnMi3Kf/vO5jka8tcbVF1FhDFb8PWsQ8pg5Y7U/zkQgta+fIrJGcGHO58WFjfKlgvhneG1uQ00Fpxzhau3QA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12476,8 +10751,6 @@ }, "node_modules/license-check-and-add/node_modules/ansi-regex": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "dev": true, "license": "MIT", "engines": { @@ -12486,8 +10759,6 @@ }, "node_modules/license-check-and-add/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "license": "MIT", "dependencies": { @@ -12499,8 +10770,6 @@ }, "node_modules/license-check-and-add/node_modules/cliui": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "license": "ISC", "dependencies": { @@ -12511,8 +10780,6 @@ }, "node_modules/license-check-and-add/node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "license": "MIT", "dependencies": { @@ -12521,22 +10788,16 @@ }, "node_modules/license-check-and-add/node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true, "license": "MIT" }, "node_modules/license-check-and-add/node_modules/emoji-regex": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true, "license": "MIT" }, "node_modules/license-check-and-add/node_modules/find-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "license": "MIT", "dependencies": { @@ -12548,8 +10809,6 @@ }, "node_modules/license-check-and-add/node_modules/fs-extra": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "license": "MIT", "dependencies": { @@ -12563,9 +10822,6 @@ }, "node_modules/license-check-and-add/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -12585,8 +10841,6 @@ }, "node_modules/license-check-and-add/node_modules/globby": { "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", "dev": true, "license": "MIT", "dependencies": { @@ -12605,8 +10859,6 @@ }, "node_modules/license-check-and-add/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -12615,8 +10867,6 @@ }, "node_modules/license-check-and-add/node_modules/is-fullwidth-code-point": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true, "license": "MIT", "engines": { @@ -12625,8 +10875,6 @@ }, "node_modules/license-check-and-add/node_modules/jsonfile": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "license": "MIT", "optionalDependencies": { @@ -12635,8 +10883,6 @@ }, "node_modules/license-check-and-add/node_modules/locate-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "license": "MIT", "dependencies": { @@ -12649,8 +10895,6 @@ }, "node_modules/license-check-and-add/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", "dependencies": { @@ -12665,8 +10909,6 @@ }, "node_modules/license-check-and-add/node_modules/p-locate": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12678,8 +10920,6 @@ }, "node_modules/license-check-and-add/node_modules/path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, "license": "MIT", "engines": { @@ -12688,8 +10928,6 @@ }, "node_modules/license-check-and-add/node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", "engines": { @@ -12698,8 +10936,6 @@ }, "node_modules/license-check-and-add/node_modules/string-width": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "license": "MIT", "dependencies": { @@ -12713,8 +10949,6 @@ }, "node_modules/license-check-and-add/node_modules/strip-ansi": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "license": "MIT", "dependencies": { @@ -12726,8 +10960,6 @@ }, "node_modules/license-check-and-add/node_modules/universalify": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, "license": "MIT", "engines": { @@ -12736,8 +10968,6 @@ }, "node_modules/license-check-and-add/node_modules/wrap-ansi": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "license": "MIT", "dependencies": { @@ -12751,15 +10981,11 @@ }, "node_modules/license-check-and-add/node_modules/y18n": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true, "license": "ISC" }, "node_modules/license-check-and-add/node_modules/yargs": { "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "license": "MIT", "dependencies": { @@ -12777,8 +11003,6 @@ }, "node_modules/license-check-and-add/node_modules/yargs-parser": { "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "license": "ISC", "dependencies": { @@ -12791,14 +11015,10 @@ "link": true }, "node_modules/limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + "version": "1.1.5" }, "node_modules/load-bmfont": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.2.tgz", - "integrity": "sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==", "license": "MIT", "dependencies": { "buffer-equal": "0.0.1", @@ -12813,8 +11033,6 @@ }, "node_modules/load-bmfont/node_modules/mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "license": "MIT", "bin": { "mime": "cli.js" @@ -12825,8 +11043,6 @@ }, "node_modules/loader-runner": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", - "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "license": "MIT", "engines": { "node": ">=6.11.5" @@ -12838,8 +11054,6 @@ }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "license": "MIT", "dependencies": { "p-locate": "^5.0.0" @@ -12853,99 +11067,67 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, "node_modules/lodash.camelcase": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "license": "MIT" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", "license": "MIT" }, "node_modules/lodash.defaults": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", "license": "MIT" }, "node_modules/lodash.flattendeep": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", "dev": true, "license": "MIT" }, "node_modules/lodash.includes": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", "license": "MIT" }, "node_modules/lodash.isarguments": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", "license": "MIT" }, "node_modules/lodash.isboolean": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", "license": "MIT" }, "node_modules/lodash.isfunction": { "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", "license": "MIT" }, "node_modules/lodash.isinteger": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", "license": "MIT" }, "node_modules/lodash.isnumber": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", "license": "MIT" }, "node_modules/lodash.isstring": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "license": "MIT" }, "node_modules/lodash.once": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "license": "MIT", "dependencies": { @@ -12961,8 +11143,6 @@ }, "node_modules/logform": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", - "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", "license": "MIT", "dependencies": { "@colors/colors": "1.6.0", @@ -12978,14 +11158,10 @@ }, "node_modules/long": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", "license": "Apache-2.0" }, "node_modules/lorem-ipsum": { "version": "2.0.8", - "resolved": "https://registry.npmjs.org/lorem-ipsum/-/lorem-ipsum-2.0.8.tgz", - "integrity": "sha512-5RIwHuCb979RASgCJH0VKERn9cQo/+NcAi2BMe9ddj+gp7hujl6BI+qdOG4nVsLDpwWEJwTVYXNKP6BGgbcoGA==", "license": "ISC", "dependencies": { "commander": "^9.3.0" @@ -13000,8 +11176,6 @@ }, "node_modules/lorem-ipsum/node_modules/commander": { "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "license": "MIT", "engines": { "node": "^12.20.0 || >=14" @@ -13009,8 +11183,6 @@ }, "node_modules/loupe": { "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" @@ -13018,8 +11190,6 @@ }, "node_modules/lower-case": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "dev": true, "license": "MIT", "dependencies": { @@ -13028,8 +11198,6 @@ }, "node_modules/lru-cache": { "version": "11.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", - "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" @@ -13037,8 +11205,6 @@ }, "node_modules/lru-memoizer": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", - "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", "license": "MIT", "dependencies": { "lodash.clonedeep": "^4.5.0", @@ -13047,8 +11213,6 @@ }, "node_modules/lru-memoizer/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -13057,28 +11221,8 @@ "node": ">=10" } }, - "node_modules/lzo": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/lzo/-/lzo-0.4.11.tgz", - "integrity": "sha512-apQHNoW2Alg72FMqaC/7pn03I7umdgSVFt2KRkCXXils4Z9u3QBh1uOtl2O5WmZIDLd9g6Lu4lIdOLmiSTFVCQ==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bindings": "~1.2.1" - } - }, - "node_modules/lzo/node_modules/bindings": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", - "integrity": "sha512-u4cBQNepWxYA55FunZSM7wMi55yQaN0otnhhilNoWHq0MfOfJeQx0v0mRRpolGOExPjZcl6FtB0BB8Xkb88F0g==", - "license": "MIT", - "optional": true - }, "node_modules/magic-string": { "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -13087,8 +11231,6 @@ }, "node_modules/magicast": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", - "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", "dev": true, "license": "MIT", "dependencies": { @@ -13099,8 +11241,6 @@ }, "node_modules/make-dir": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "license": "MIT", "dependencies": { "semver": "^6.0.0" @@ -13114,8 +11254,6 @@ }, "node_modules/make-dir/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -13123,8 +11261,6 @@ }, "node_modules/math-intrinsics": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -13132,15 +11268,11 @@ }, "node_modules/mdn-data": { "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", "dev": true, "license": "CC0-1.0" }, "node_modules/media-typer": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -13148,8 +11280,6 @@ }, "node_modules/merge-descriptors": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -13157,14 +11287,10 @@ }, "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "license": "MIT", "engines": { "node": ">= 8" @@ -13172,8 +11298,6 @@ }, "node_modules/methods": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -13181,8 +11305,6 @@ }, "node_modules/micromatch": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -13194,8 +11316,6 @@ }, "node_modules/micromatch/node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "license": "MIT", "engines": { "node": ">=8.6" @@ -13210,8 +11330,6 @@ }, "node_modules/mime": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", "license": "MIT", "optional": true, "bin": { @@ -13223,8 +11341,6 @@ }, "node_modules/mime-db": { "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -13232,8 +11348,6 @@ }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -13244,8 +11358,6 @@ }, "node_modules/mime-types/node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -13253,8 +11365,6 @@ }, "node_modules/mimic-response": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "license": "MIT", "engines": { "node": ">=10" @@ -13265,8 +11375,6 @@ }, "node_modules/min-document": { "version": "2.19.2", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.2.tgz", - "integrity": "sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==", "license": "MIT", "dependencies": { "dom-walk": "^0.1.0" @@ -13284,8 +11392,6 @@ }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -13293,8 +11399,6 @@ }, "node_modules/minipass": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "license": "ISC", "engines": { "node": ">=8" @@ -13302,8 +11406,6 @@ }, "node_modules/minizlib": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "license": "MIT", "dependencies": { "minipass": "^3.0.0", @@ -13315,8 +11417,6 @@ }, "node_modules/minizlib/node_modules/minipass": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -13327,8 +11427,6 @@ }, "node_modules/mkdirp": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" @@ -13339,14 +11437,10 @@ }, "node_modules/mkdirp-classic": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "license": "MIT" }, "node_modules/mocha": { "version": "10.8.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", - "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", "dev": true, "license": "MIT", "dependencies": { @@ -13381,8 +11475,6 @@ }, "node_modules/mocha/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -13391,8 +11483,6 @@ }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "license": "ISC", "dependencies": { @@ -13403,8 +11493,6 @@ }, "node_modules/mocha/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "license": "ISC", "dependencies": { @@ -13416,8 +11504,6 @@ }, "node_modules/mocha/node_modules/yargs": { "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "license": "MIT", "dependencies": { @@ -13435,8 +11521,6 @@ }, "node_modules/module-details-from-path": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", - "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", "license": "MIT" }, "node_modules/module-docgen": { @@ -13445,14 +11529,10 @@ }, "node_modules/module-not-found-error": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", - "integrity": "sha512-pEk4ECWQXV6z2zjhRZUongnLJNUeGQJ3w6OQ5ctGwD+i5o93qjRQUk2Rt6VdNeu3sEP0AB4LcfvdebpxBRVr4g==", "license": "MIT" }, "node_modules/moment": { "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "license": "MIT", "engines": { "node": "*" @@ -13460,8 +11540,6 @@ }, "node_modules/morgan": { "version": "1.10.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz", - "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==", "license": "MIT", "dependencies": { "basic-auth": "~2.0.1", @@ -13476,8 +11554,6 @@ }, "node_modules/morgan/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -13485,14 +11561,10 @@ }, "node_modules/morgan/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/morgan/node_modules/on-finished": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -13503,8 +11575,6 @@ }, "node_modules/mri": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz", - "integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==", "license": "MIT", "engines": { "node": ">=4" @@ -13512,8 +11582,6 @@ }, "node_modules/mrmime": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "dev": true, "license": "MIT", "engines": { @@ -13522,8 +11590,6 @@ }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/multer": { @@ -13544,8 +11610,6 @@ }, "node_modules/multer/node_modules/mkdirp": { "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "license": "MIT", "dependencies": { "minimist": "^1.2.6" @@ -13556,8 +11620,6 @@ }, "node_modules/multi-progress": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/multi-progress/-/multi-progress-4.0.0.tgz", - "integrity": "sha512-9zcjyOou3FFCKPXsmkbC3ethv51SFPoA4dJD6TscIp2pUmy26kBDZW6h9XofPELrzseSkuD7r0V+emGEeo39Pg==", "license": "MIT", "peerDependencies": { "progress": "^2.0.0" @@ -13565,14 +11627,10 @@ }, "node_modules/murmurhash": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/murmurhash/-/murmurhash-2.0.1.tgz", - "integrity": "sha512-5vQEh3y+DG/lMPM0mCGPDnyV8chYg/g7rl6v3Gd8WMF9S429ox3Xk8qrk174kWhG767KQMqqxLD1WnGd77hiew==", "license": "MIT" }, "node_modules/music-metadata": { "version": "7.14.0", - "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-7.14.0.tgz", - "integrity": "sha512-xrm3w7SV0Wk+OythZcSbaI8mcr/KHd0knJieu8bVpaPfMv/Agz5EooCAPz3OR5hbYMiUG6dgAPKZKnMzV+3amA==", "license": "MIT", "dependencies": { "@tokenizer/token": "^0.3.0", @@ -13593,8 +11651,6 @@ }, "node_modules/music-metadata/node_modules/file-type": { "version": "16.5.4", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", - "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", "license": "MIT", "dependencies": { "readable-web-to-node-stream": "^3.0.0", @@ -13610,8 +11666,6 @@ }, "node_modules/music-metadata/node_modules/peek-readable": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", - "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", "license": "MIT", "engines": { "node": ">=8" @@ -13623,8 +11677,6 @@ }, "node_modules/music-metadata/node_modules/strtok3": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", - "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", "license": "MIT", "dependencies": { "@tokenizer/token": "^0.3.0", @@ -13640,8 +11692,6 @@ }, "node_modules/music-metadata/node_modules/token-types": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", - "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", "license": "MIT", "dependencies": { "@tokenizer/token": "^0.3.0", @@ -13657,15 +11707,11 @@ }, "node_modules/nan": { "version": "2.23.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.1.tgz", - "integrity": "sha512-r7bBUGKzlqk8oPBDYxt6Z0aEdF1G1rwlMcLk8LCOMbOzf0mG+JUfUzG4fIMWwHWP0iyaLWEQZJmtB7nOHEm/qw==", "license": "MIT", "optional": true }, "node_modules/nanoid": { "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -13683,20 +11729,14 @@ }, "node_modules/napi-build-utils": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -13704,14 +11744,10 @@ }, "node_modules/neo-async": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "license": "MIT" }, "node_modules/nise": { "version": "5.1.9", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", - "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0", @@ -13723,14 +11759,10 @@ }, "node_modules/nise/node_modules/path-to-regexp": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "license": "MIT" }, "node_modules/no-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "dev": true, "license": "MIT", "dependencies": { @@ -13740,8 +11772,6 @@ }, "node_modules/node-abi": { "version": "3.85.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.85.0.tgz", - "integrity": "sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==", "license": "MIT", "dependencies": { "semver": "^7.3.5" @@ -13752,15 +11782,10 @@ }, "node_modules/node-addon-api": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", "license": "MIT" }, "node_modules/node-domexception": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", "funding": [ { "type": "github", @@ -13778,8 +11803,6 @@ }, "node_modules/node-fetch": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" @@ -13798,20 +11821,14 @@ }, "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, "node_modules/node-fetch/node_modules/webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "license": "MIT", "dependencies": { "tr46": "~0.0.3", @@ -13820,23 +11837,13 @@ }, "node_modules/node-forge": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz", - "integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==", "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "license": "MIT" - }, "node_modules/node-preload": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", "dev": true, "license": "MIT", "dependencies": { @@ -13848,8 +11855,6 @@ }, "node_modules/node-pty": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.0.0.tgz", - "integrity": "sha512-wtBMWWS7dFZm/VgqElrTvtfMq4GzJ6+edFI0Y0zyzygUSZMgZdraDUMUhCIvkjhJjme15qWmbyJbtAx4ot4uZA==", "hasInstallScript": true, "license": "MIT", "optional": true, @@ -13859,8 +11864,6 @@ }, "node_modules/node-releases": { "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "license": "MIT" }, "node_modules/nodemailer": { @@ -13899,8 +11902,6 @@ }, "node_modules/nodemon/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "license": "MIT", "engines": { @@ -13909,8 +11910,6 @@ }, "node_modules/nodemon/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "license": "MIT", "dependencies": { @@ -13922,8 +11921,6 @@ }, "node_modules/nopt": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", "license": "ISC", "dependencies": { "abbrev": "1" @@ -13937,8 +11934,6 @@ }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -13946,9 +11941,6 @@ }, "node_modules/npmlog": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "deprecated": "This package is no longer supported.", "license": "ISC", "dependencies": { "are-we-there-yet": "^2.0.0", @@ -13959,8 +11951,6 @@ }, "node_modules/nth-check": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" @@ -13971,8 +11961,6 @@ }, "node_modules/nyc": { "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", "dev": true, "license": "ISC", "dependencies": { @@ -14013,8 +12001,6 @@ }, "node_modules/nyc/node_modules/cliui": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, "license": "ISC", "dependencies": { @@ -14025,8 +12011,6 @@ }, "node_modules/nyc/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", "dependencies": { @@ -14039,9 +12023,6 @@ }, "node_modules/nyc/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -14061,8 +12042,6 @@ }, "node_modules/nyc/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", "dependencies": { @@ -14074,8 +12053,6 @@ }, "node_modules/nyc/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", "dependencies": { @@ -14090,8 +12067,6 @@ }, "node_modules/nyc/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", "dependencies": { @@ -14103,8 +12078,6 @@ }, "node_modules/nyc/node_modules/p-map": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, "license": "MIT", "dependencies": { @@ -14116,8 +12089,6 @@ }, "node_modules/nyc/node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", "engines": { @@ -14126,8 +12097,6 @@ }, "node_modules/nyc/node_modules/wrap-ansi": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "license": "MIT", "dependencies": { @@ -14141,15 +12110,11 @@ }, "node_modules/nyc/node_modules/y18n": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true, "license": "ISC" }, "node_modules/nyc/node_modules/yargs": { "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "license": "MIT", "dependencies": { @@ -14171,8 +12136,6 @@ }, "node_modules/nyc/node_modules/yargs-parser": { "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "license": "ISC", "dependencies": { @@ -14185,8 +12148,6 @@ }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14194,8 +12155,6 @@ }, "node_modules/object-hash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "license": "MIT", "optional": true, "engines": { @@ -14204,8 +12163,6 @@ }, "node_modules/object-inspect": { "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -14214,18 +12171,8 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-stream": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/object-stream/-/object-stream-0.0.1.tgz", - "integrity": "sha512-+NPJnRvX9RDMRY9mOWOo/NDppBjbZhXirNNSu2IBnuNboClC9h1ZGHXgHBLDbJMHsxeJDq922aVmG5xs24a/cA==", - "engines": { - "node": ">=0.10" - } - }, "node_modules/obug": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", @@ -14235,14 +12182,10 @@ }, "node_modules/omggif": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", - "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", "license": "MIT" }, "node_modules/on-finished": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -14253,8 +12196,6 @@ }, "node_modules/on-headers": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", - "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -14262,8 +12203,6 @@ }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "dependencies": { "wrappy": "1" @@ -14271,8 +12210,6 @@ }, "node_modules/one-time": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", "license": "MIT", "dependencies": { "fn.name": "1.x.x" @@ -14280,8 +12217,6 @@ }, "node_modules/open": { "version": "10.2.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", - "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", "license": "MIT", "dependencies": { "default-browser": "^5.2.1", @@ -14298,8 +12233,6 @@ }, "node_modules/openai": { "version": "6.9.1", - "resolved": "https://registry.npmjs.org/openai/-/openai-6.9.1.tgz", - "integrity": "sha512-vQ5Rlt0ZgB3/BNmTa7bIijYFhz3YBceAA3Z4JuoMSBftBF9YqFHIEhZakSs+O/Ad7EaoEimZvHxD5ylRjN11Lg==", "license": "Apache-2.0", "bin": { "openai": "bin/cli" @@ -14319,8 +12252,6 @@ }, "node_modules/opener": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true, "license": "(WTFPL OR MIT)", "bin": { @@ -14329,8 +12260,6 @@ }, "node_modules/opentype.js": { "version": "0.7.3", - "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-0.7.3.tgz", - "integrity": "sha512-Veui5vl2bLonFJ/SjX/WRWJT3SncgiZNnKUyahmXCc2sa1xXW15u3R/3TN5+JFiP7RsjK5ER4HA5eWaEmV9deA==", "license": "MIT", "dependencies": { "tiny-inflate": "^1.0.2" @@ -14341,8 +12270,6 @@ }, "node_modules/optionator": { "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "license": "MIT", "dependencies": { "deep-is": "^0.1.3", @@ -14358,8 +12285,6 @@ }, "node_modules/otpauth": { "version": "9.2.4", - "resolved": "https://registry.npmjs.org/otpauth/-/otpauth-9.2.4.tgz", - "integrity": "sha512-t0Nioq2Up2ZaT5AbpXZLTjrsNtLc/g/rVSaEThmKLErAuT9mrnAKJryiPOKc3rCH+3ycWBgKpRHYn+DHqfaPiQ==", "license": "MIT", "dependencies": { "jssha": "~3.3.1" @@ -14370,8 +12295,6 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -14385,8 +12308,6 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "license": "MIT", "dependencies": { "p-limit": "^3.0.2" @@ -14411,8 +12332,6 @@ }, "node_modules/p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "license": "MIT", "engines": { @@ -14421,8 +12340,6 @@ }, "node_modules/package-hash": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", "dev": true, "license": "ISC", "dependencies": { @@ -14437,20 +12354,14 @@ }, "node_modules/package-json-from-dist": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/pako": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "license": "(MIT AND Zlib)" }, "node_modules/param-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "dev": true, "license": "MIT", "dependencies": { @@ -14460,8 +12371,6 @@ }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -14470,43 +12379,16 @@ "node": ">=6" } }, - "node_modules/parquetjs": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/parquetjs/-/parquetjs-0.11.2.tgz", - "integrity": "sha512-Y6FOc3Oi2AxY4TzJPz7fhICCR8tQNL3p+2xGQoUAMbmlJBR7+JJmMrwuyMjIpDiM7G8Wj/8oqOH4UDUmu4I5ZA==", - "license": "MIT", - "dependencies": { - "brotli": "^1.3.0", - "bson": "^1.0.4", - "int53": "^0.2.4", - "object-stream": "0.0.1", - "snappyjs": "^0.6.0", - "thrift": "^0.11.0", - "varint": "^5.0.0" - }, - "engines": { - "node": ">=7.6" - }, - "optionalDependencies": { - "lzo": "^0.4.0" - } - }, "node_modules/parse-bmfont-ascii": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", - "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==", "license": "MIT" }, "node_modules/parse-bmfont-binary": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", - "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==", "license": "MIT" }, "node_modules/parse-bmfont-xml": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz", - "integrity": "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==", "license": "MIT", "dependencies": { "xml-parse-from-string": "^1.0.0", @@ -14515,8 +12397,6 @@ }, "node_modules/parse-bmfont-xml/node_modules/xml2js": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", "license": "MIT", "dependencies": { "sax": ">=0.6.0", @@ -14528,8 +12408,6 @@ }, "node_modules/parse-domain": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/parse-domain/-/parse-domain-8.2.2.tgz", - "integrity": "sha512-CoksenD3UDqphCHlXIcNh/TX0dsYLHo6dSAUC/QBcJRWJXcV5rc1mwsS4WbhYGu4LD4Uxc0v3ZzGo+OHCGsLcw==", "license": "MIT", "dependencies": { "is-ip": "^5.0.1" @@ -14540,14 +12418,10 @@ }, "node_modules/parse-headers": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.6.tgz", - "integrity": "sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==", "license": "MIT" }, "node_modules/parse5": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", - "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", "dev": true, "license": "MIT", "dependencies": { @@ -14559,8 +12433,6 @@ }, "node_modules/parseurl": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -14568,8 +12440,6 @@ }, "node_modules/pascal-case": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", "dev": true, "license": "MIT", "dependencies": { @@ -14579,14 +12449,10 @@ }, "node_modules/path-browserify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "license": "MIT" }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "license": "MIT", "engines": { "node": ">=8" @@ -14594,8 +12460,6 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14603,8 +12467,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "engines": { "node": ">=8" @@ -14612,14 +12474,10 @@ }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, "node_modules/path-scurry": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", @@ -14634,20 +12492,14 @@ }, "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, "node_modules/path-to-regexp": { "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, "node_modules/path-type": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", - "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", "license": "MIT", "engines": { "node": ">=18" @@ -14658,15 +12510,11 @@ }, "node_modules/pathe": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, "node_modules/pathval": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "license": "MIT", "engines": { "node": "*" @@ -14674,8 +12522,6 @@ }, "node_modules/peek-readable": { "version": "5.4.2", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.4.2.tgz", - "integrity": "sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==", "license": "MIT", "engines": { "node": ">=14.16" @@ -14687,14 +12533,10 @@ }, "node_modules/pg-connection-string": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", - "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==", "license": "MIT" }, "node_modules/pg-int8": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", "license": "ISC", "engines": { "node": ">=4.0.0" @@ -14702,14 +12544,10 @@ }, "node_modules/pg-protocol": { "version": "1.10.3", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", - "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", "license": "MIT" }, "node_modules/pg-types": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", "license": "MIT", "dependencies": { "pg-int8": "1.0.1", @@ -14724,9 +12562,6 @@ }, "node_modules/phin": { "version": "3.7.1", - "resolved": "https://registry.npmjs.org/phin/-/phin-3.7.1.tgz", - "integrity": "sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "license": "MIT", "dependencies": { "centra": "^2.7.0" @@ -14737,14 +12572,10 @@ }, "node_modules/picocolors": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/picomatch": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -14756,8 +12587,6 @@ }, "node_modules/pixelmatch": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", - "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", "license": "ISC", "dependencies": { "pngjs": "^3.0.0" @@ -14768,8 +12597,6 @@ }, "node_modules/pixelmatch/node_modules/pngjs": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", "license": "MIT", "engines": { "node": ">=4.0.0" @@ -14777,8 +12604,6 @@ }, "node_modules/pkg-dir": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "license": "MIT", "dependencies": { @@ -14790,8 +12615,6 @@ }, "node_modules/pkg-dir/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", "dependencies": { @@ -14804,8 +12627,6 @@ }, "node_modules/pkg-dir/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", "dependencies": { @@ -14817,8 +12638,6 @@ }, "node_modules/pkg-dir/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", "dependencies": { @@ -14833,8 +12652,6 @@ }, "node_modules/pkg-dir/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", "dependencies": { @@ -14846,8 +12663,6 @@ }, "node_modules/playwright": { "version": "1.57.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.57.0.tgz", - "integrity": "sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -14865,8 +12680,6 @@ }, "node_modules/playwright-core": { "version": "1.57.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.57.0.tgz", - "integrity": "sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -14878,10 +12691,7 @@ }, "node_modules/playwright/node_modules/fsevents": { "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ @@ -14893,8 +12703,6 @@ }, "node_modules/pngjs": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", "license": "MIT", "engines": { "node": ">=12.13.0" @@ -14902,8 +12710,6 @@ }, "node_modules/portfinder": { "version": "1.0.38", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.38.tgz", - "integrity": "sha512-rEwq/ZHlJIKw++XtLAO8PPuOQA/zaPJOZJ37BVuN97nLpMJeuDVLVGRwbFoBgLudgdTMP2hdRJP++H+8QOA3vg==", "dev": true, "license": "MIT", "dependencies": { @@ -14916,8 +12722,6 @@ }, "node_modules/postcss": { "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -14945,8 +12749,6 @@ }, "node_modules/postgres-array": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", "license": "MIT", "engines": { "node": ">=4" @@ -14954,8 +12756,6 @@ }, "node_modules/postgres-bytea": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14963,8 +12763,6 @@ }, "node_modules/postgres-date": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14972,8 +12770,6 @@ }, "node_modules/postgres-interval": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", "license": "MIT", "dependencies": { "xtend": "^4.0.0" @@ -14984,8 +12780,6 @@ }, "node_modules/prebuild-install": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", "license": "MIT", "dependencies": { "detect-libc": "^2.0.0", @@ -15010,8 +12804,6 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "license": "MIT", "engines": { "node": ">= 0.8.0" @@ -15019,8 +12811,6 @@ }, "node_modules/prettier": { "version": "3.7.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.3.tgz", - "integrity": "sha512-QgODejq9K3OzoBbuyobZlUhznP5SKwPqp+6Q6xw6o8gnhr4O85L2U915iM2IDcfF2NPXVaM9zlo9tdwipnYwzg==", "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" @@ -15034,8 +12824,6 @@ }, "node_modules/pretty-error": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", "dev": true, "license": "MIT", "dependencies": { @@ -15045,23 +12833,13 @@ }, "node_modules/process": { "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "license": "MIT", "engines": { "node": ">= 0.6.0" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "license": "MIT" - }, "node_modules/process-on-spawn": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.1.0.tgz", - "integrity": "sha512-JOnOPQ/8TZgjs1JIH/m9ni7FfimjNa/PRx7y/Wb5qdItsnhO0jE4AT7fC0HjC28DUQWDr50dwSYZLdRMlqDq3Q==", "dev": true, "license": "MIT", "dependencies": { @@ -15073,28 +12851,14 @@ }, "node_modules/progress": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "license": "MIT", "peer": true, "engines": { "node": ">=0.4.0" } }, - "node_modules/progress-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-2.0.0.tgz", - "integrity": "sha512-xJwOWR46jcXUq6EH9yYyqp+I52skPySOeHfkxOZ2IY1AiBi/sFJhbhAKHoV3OTw/omQ45KTio9215dRJ2Yxd3Q==", - "license": "BSD-2-Clause", - "dependencies": { - "speedometer": "~1.0.0", - "through2": "~2.0.3" - } - }, "node_modules/prompt-sync": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz", - "integrity": "sha512-BuEzzc5zptP5LsgV5MZETjDaKSWfchl5U9Luiu8SKp7iZWD5tZalOxvNcZRwv+d2phNFr8xlbxmFNcRKfJOzJw==", "license": "MIT", "dependencies": { "strip-ansi": "^5.0.0" @@ -15102,8 +12866,6 @@ }, "node_modules/prompt-sync/node_modules/ansi-regex": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "license": "MIT", "engines": { "node": ">=6" @@ -15111,8 +12873,6 @@ }, "node_modules/prompt-sync/node_modules/strip-ansi": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "license": "MIT", "dependencies": { "ansi-regex": "^4.1.0" @@ -15123,8 +12883,6 @@ }, "node_modules/proto3-json-serializer": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", - "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -15136,8 +12894,6 @@ }, "node_modules/protobufjs": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", - "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { @@ -15160,8 +12916,6 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -15173,14 +12927,10 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, "node_modules/proxyquire": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.3.tgz", - "integrity": "sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==", "license": "MIT", "dependencies": { "fill-keys": "^1.0.2", @@ -15190,15 +12940,11 @@ }, "node_modules/pstree.remy": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true, "license": "MIT" }, "node_modules/pump": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -15207,28 +12953,13 @@ }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", - "license": "MIT", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, "node_modules/qs": { "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" @@ -15242,8 +12973,6 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "funding": [ { "type": "github", @@ -15262,8 +12991,6 @@ }, "node_modules/randombytes": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" @@ -15271,8 +12998,6 @@ }, "node_modules/randomstring": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/randomstring/-/randomstring-1.3.1.tgz", - "integrity": "sha512-lgXZa80MUkjWdE7g2+PZ1xDLzc7/RokXVEQOv5NN2UOTChW1I8A9gha5a9xYBOqgaSoI6uJikDmCU8PyRdArRQ==", "license": "MIT", "dependencies": { "randombytes": "2.1.0" @@ -15286,8 +13011,6 @@ }, "node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -15295,8 +13018,6 @@ }, "node_modules/raw-body": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -15310,8 +13031,6 @@ }, "node_modules/raw-body/node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -15322,8 +13041,6 @@ }, "node_modules/rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", @@ -15337,8 +13054,6 @@ }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -15346,8 +13061,6 @@ }, "node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -15360,8 +13073,6 @@ }, "node_modules/readable-web-to-node-stream": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", - "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", "license": "MIT", "dependencies": { "readable-stream": "^4.7.0" @@ -15376,8 +13087,6 @@ }, "node_modules/readable-web-to-node-stream/node_modules/buffer": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -15400,8 +13109,6 @@ }, "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -15416,8 +13123,6 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "license": "MIT", "dependencies": { @@ -15429,8 +13134,6 @@ }, "node_modules/readdirp/node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { @@ -15442,8 +13145,6 @@ }, "node_modules/rechoir": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "license": "MIT", "dependencies": { "resolve": "^1.20.0" @@ -15454,8 +13155,6 @@ }, "node_modules/recursive-readdir": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "license": "MIT", "dependencies": { "minimatch": "^3.0.5" @@ -15466,8 +13165,6 @@ }, "node_modules/redis-errors": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", "license": "MIT", "engines": { "node": ">=4" @@ -15475,8 +13172,6 @@ }, "node_modules/redis-parser": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", "license": "MIT", "dependencies": { "redis-errors": "^1.0.0" @@ -15487,14 +13182,10 @@ }, "node_modules/regenerator-runtime": { "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", "license": "MIT" }, "node_modules/relateurl": { "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", "dev": true, "license": "MIT", "engines": { @@ -15503,14 +13194,10 @@ }, "node_modules/relative-time-format": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/relative-time-format/-/relative-time-format-1.1.11.tgz", - "integrity": "sha512-TH+oV/w77hjaB9xCzoFYJ/Icmr/12+02IAoCI/YGS2UBTbjCbBjHGEBxGnVy4EJvOR1qadGzyFRI6hGaJJG93Q==", "license": "MIT" }, "node_modules/release-zalgo": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", "dev": true, "license": "ISC", "dependencies": { @@ -15522,8 +13209,6 @@ }, "node_modules/renderkid": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", "dev": true, "license": "MIT", "dependencies": { @@ -15536,8 +13221,6 @@ }, "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -15545,8 +13228,6 @@ }, "node_modules/require-from-string": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -15554,8 +13235,6 @@ }, "node_modules/require-in-the-middle": { "version": "7.5.2", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", - "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", "license": "MIT", "dependencies": { "debug": "^4.3.5", @@ -15568,22 +13247,16 @@ }, "node_modules/require-main-filename": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true, "license": "ISC" }, "node_modules/requires-port": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true, "license": "MIT" }, "node_modules/resolve": { "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "license": "MIT", "dependencies": { "is-core-module": "^2.16.1", @@ -15602,8 +13275,6 @@ }, "node_modules/resolve-cwd": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "license": "MIT", "dependencies": { @@ -15615,8 +13286,6 @@ }, "node_modules/resolve-cwd/node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", "engines": { @@ -15625,8 +13294,6 @@ }, "node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "license": "MIT", "engines": { "node": ">=4" @@ -15634,8 +13301,6 @@ }, "node_modules/response-time": { "version": "2.3.4", - "resolved": "https://registry.npmjs.org/response-time/-/response-time-2.3.4.tgz", - "integrity": "sha512-fiyq1RvW5/Br6iAtT8jN1XrNY8WPu2+yEypLbaijWry8WDZmn12azG9p/+c+qpEebURLlQmqCB8BNSu7ji+xQQ==", "license": "MIT", "dependencies": { "depd": "~2.0.0", @@ -15647,8 +13312,6 @@ }, "node_modules/retry": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "license": "MIT", "optional": true, "engines": { @@ -15657,8 +13320,6 @@ }, "node_modules/retry-request": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", - "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", "license": "MIT", "optional": true, "dependencies": { @@ -15672,8 +13333,6 @@ }, "node_modules/reusify": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -15682,9 +13341,6 @@ }, "node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", "license": "ISC", "dependencies": { "glob": "^7.1.3" @@ -15698,9 +13354,6 @@ }, "node_modules/rimraf/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -15719,8 +13372,6 @@ }, "node_modules/rollup": { "version": "4.53.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", - "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", "dev": true, "license": "MIT", "dependencies": { @@ -15761,8 +13412,6 @@ }, "node_modules/run-applescript": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", - "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", "license": "MIT", "engines": { "node": ">=18" @@ -15773,8 +13422,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "funding": [ { "type": "github", @@ -15796,8 +13443,6 @@ }, "node_modules/rxjs": { "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -15806,8 +13451,6 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -15826,8 +13469,6 @@ }, "node_modules/safe-stable-stringify": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", - "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "license": "MIT", "engines": { "node": ">=10" @@ -15835,20 +13476,14 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, "node_modules/sax": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz", - "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==", "license": "BlueOak-1.0.0" }, "node_modules/saxes": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dev": true, "license": "ISC", "dependencies": { @@ -15860,8 +13495,6 @@ }, "node_modules/schema-utils": { "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", @@ -15879,8 +13512,6 @@ }, "node_modules/schema-utils/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -15895,8 +13526,6 @@ }, "node_modules/schema-utils/node_modules/ajv-keywords": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" @@ -15907,27 +13536,19 @@ }, "node_modules/schema-utils/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/secure-compare": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", - "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", "dev": true, "license": "MIT" }, "node_modules/seedrandom": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", - "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", "license": "MIT" }, "node_modules/semver": { "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -15938,8 +13559,6 @@ }, "node_modules/send": { "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -15962,8 +13581,6 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -15971,14 +13588,10 @@ }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -15986,8 +13599,6 @@ }, "node_modules/send/node_modules/mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "license": "MIT", "bin": { "mime": "cli.js" @@ -15998,8 +13609,6 @@ }, "node_modules/serialize-javascript": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" @@ -16007,8 +13616,6 @@ }, "node_modules/serve-static": { "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", @@ -16022,20 +13629,14 @@ }, "node_modules/set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "license": "ISC" }, "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, "node_modules/shallow-clone": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, "license": "MIT", "dependencies": { @@ -16087,8 +13688,6 @@ }, "node_modules/sharp-bmp": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/sharp-bmp/-/sharp-bmp-0.1.5.tgz", - "integrity": "sha512-IpWAy+AeTlWNHiBU8HH4atcKbztgKOXTuT4W8aFaeASPCeJwCVpoUymWMfEmwfvWSCOV1s7VmGTlKhcPLkt+Lw==", "license": "MIT", "dependencies": { "bmp-js": "*", @@ -16097,8 +13696,6 @@ }, "node_modules/sharp-ico": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/sharp-ico/-/sharp-ico-0.1.5.tgz", - "integrity": "sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==", "license": "MIT", "dependencies": { "decode-ico": "*", @@ -16108,8 +13705,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -16120,8 +13715,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "engines": { "node": ">=8" @@ -16129,8 +13722,6 @@ }, "node_modules/shell-quote": { "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", "dev": true, "license": "MIT", "engines": { @@ -16142,14 +13733,10 @@ }, "node_modules/shimmer": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", "license": "BSD-2-Clause" }, "node_modules/side-channel": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -16167,8 +13754,6 @@ }, "node_modules/side-channel-list": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -16183,8 +13768,6 @@ }, "node_modules/side-channel-map": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -16201,8 +13784,6 @@ }, "node_modules/side-channel-weakmap": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -16220,21 +13801,15 @@ }, "node_modules/siginfo": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, "node_modules/simple-concat": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "funding": [ { "type": "github", @@ -16253,8 +13828,6 @@ }, "node_modules/simple-get": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "funding": [ { "type": "github", @@ -16278,8 +13851,6 @@ }, "node_modules/simple-git": { "version": "3.30.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.30.0.tgz", - "integrity": "sha512-q6lxyDsCmEal/MEGhP1aVyQ3oxnagGlBDOVSIB4XUVLl1iZh0Pah6ebC9V4xBap/RfgP2WlI8EKs0WS0rMEJHg==", "license": "MIT", "dependencies": { "@kwsites/file-exists": "^1.1.1", @@ -16304,15 +13875,10 @@ }, "node_modules/simple-wcswidth": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/simple-wcswidth/-/simple-wcswidth-1.1.2.tgz", - "integrity": "sha512-j7piyCjAeTDSjzTSQ7DokZtMNwNlEAyxqSZeCS+CXH7fJ4jx3FuJ/mTW3mE+6JLs4VJBbcll0Kjn+KXI5t21Iw==", "license": "MIT" }, "node_modules/sinon": { "version": "15.2.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz", - "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==", - "deprecated": "16.1.1", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -16330,8 +13896,6 @@ }, "node_modules/sinon/node_modules/@sinonjs/fake-timers": { "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -16340,8 +13904,6 @@ }, "node_modules/sinon/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { @@ -16353,8 +13915,6 @@ }, "node_modules/sirv": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", - "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", "dev": true, "license": "MIT", "dependencies": { @@ -16368,8 +13928,6 @@ }, "node_modules/slash": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "license": "MIT", "engines": { "node": ">=14.16" @@ -16378,16 +13936,8 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/snappyjs": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/snappyjs/-/snappyjs-0.6.1.tgz", - "integrity": "sha512-YIK6I2lsH072UE0aOFxxY1dPDCS43I5ktqHpeAsuLNYWkE5pGxRGWfDM4/vSUfNzXjC1Ivzt3qx31PCLmc9yqg==", - "license": "MIT" - }, "node_modules/socket.io": { "version": "4.8.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", - "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", "license": "MIT", "dependencies": { "accepts": "~1.3.4", @@ -16404,8 +13954,6 @@ }, "node_modules/socket.io-adapter": { "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "license": "MIT", "dependencies": { "debug": "~4.3.4", @@ -16414,8 +13962,6 @@ }, "node_modules/socket.io-adapter/node_modules/debug": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -16431,8 +13977,6 @@ }, "node_modules/socket.io-adapter/node_modules/ws": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -16452,8 +13996,6 @@ }, "node_modules/socket.io-client": { "version": "4.8.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", - "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", @@ -16467,8 +14009,6 @@ }, "node_modules/socket.io-client/node_modules/debug": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -16484,8 +14024,6 @@ }, "node_modules/socket.io-parser": { "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", @@ -16497,8 +14035,6 @@ }, "node_modules/socket.io-parser/node_modules/debug": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -16514,8 +14050,6 @@ }, "node_modules/socket.io/node_modules/debug": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -16531,8 +14065,6 @@ }, "node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -16540,8 +14072,6 @@ }, "node_modules/source-map-js": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -16549,8 +14079,6 @@ }, "node_modules/source-map-support": { "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -16559,14 +14087,10 @@ }, "node_modules/spawn-command": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", - "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", "dev": true }, "node_modules/spawn-wrap": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", "dev": true, "license": "ISC", "dependencies": { @@ -16581,23 +14105,13 @@ "node": ">=8" } }, - "node_modules/speedometer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-1.0.0.tgz", - "integrity": "sha512-lgxErLl/7A5+vgIIXsh9MbeukOaCb2axgQ+bKCdIE+ibNT4XNYGNCR1qFEGq6F+YDASXK3Fh/c5FgtZchFolxw==", - "license": "MIT" - }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/ssh2": { "version": "1.17.0", - "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.17.0.tgz", - "integrity": "sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==", "hasInstallScript": true, "dependencies": { "asn1": "^0.2.6", @@ -16613,8 +14127,6 @@ }, "node_modules/stack-trace": { "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", "license": "MIT", "engines": { "node": "*" @@ -16622,21 +14134,15 @@ }, "node_modules/stackback": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, "license": "MIT" }, "node_modules/standard-as-callback": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", - "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", "license": "MIT" }, "node_modules/statuses": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -16644,15 +14150,11 @@ }, "node_modules/std-env": { "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", "dev": true, "license": "MIT" }, "node_modules/stream-events": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", "license": "MIT", "optional": true, "dependencies": { @@ -16661,23 +14163,17 @@ }, "node_modules/stream-shift": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", "license": "MIT", "optional": true }, "node_modules/streamsearch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "engines": { "node": ">=10.0.0" } }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -16685,14 +14181,10 @@ }, "node_modules/string-hash": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", - "integrity": "sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==", "license": "CC0-1.0" }, "node_modules/string-length": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-6.0.0.tgz", - "integrity": "sha512-1U361pxZHEQ+FeSjzqRpV+cu2vTzYeWeafXFLykiFlv4Vc0n3njgU8HrMbyik5uwm77naWMuVG8fhEF+Ovb1Kg==", "license": "MIT", "dependencies": { "strip-ansi": "^7.1.0" @@ -16706,8 +14198,6 @@ }, "node_modules/string-length/node_modules/ansi-regex": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" @@ -16718,8 +14208,6 @@ }, "node_modules/string-length/node_modules/strip-ansi": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -16737,8 +14225,6 @@ }, "node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -16752,8 +14238,6 @@ "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -16766,8 +14250,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -16779,8 +14261,6 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -16791,8 +14271,6 @@ }, "node_modules/strip-bom": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, "license": "MIT", "engines": { @@ -16801,8 +14279,6 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "license": "MIT", "engines": { "node": ">=8" @@ -16813,8 +14289,6 @@ }, "node_modules/strnum": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", - "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", "funding": [ { "type": "github", @@ -16825,8 +14299,6 @@ }, "node_modules/strtok3": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.1.1.tgz", - "integrity": "sha512-mKX8HA/cdBqMKUr0MMZAFssCkIGoZeSCMXgnt79yKxNFguMLVFgRe6wB+fsL0NmoHDbeyZXczy7vEPSoo3rkzg==", "license": "MIT", "dependencies": { "@tokenizer/token": "^0.3.0", @@ -16842,15 +14314,11 @@ }, "node_modules/stubs": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", "license": "MIT", "optional": true }, "node_modules/super-regex": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-0.2.0.tgz", - "integrity": "sha512-WZzIx3rC1CvbMDloLsVw0lkZVKJWbrkJ0k1ghKFmcnPrW1+jWbgTkTEWVtD9lMdmI4jZEz40+naBxl1dCUhXXw==", "license": "MIT", "dependencies": { "clone-regexp": "^3.0.0", @@ -16866,8 +14334,6 @@ }, "node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -16881,8 +14347,6 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -16893,8 +14357,6 @@ }, "node_modules/svg-captcha": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/svg-captcha/-/svg-captcha-1.4.0.tgz", - "integrity": "sha512-/fkkhavXPE57zRRCjNqAP3txRCSncpMx3NnNZL7iEoyAtYwUjPhJxW6FQTQPG5UPEmCrbFoXS10C3YdJlW7PDg==", "license": "MIT", "dependencies": { "opentype.js": "^0.7.3" @@ -16905,8 +14367,6 @@ }, "node_modules/svgo": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", "license": "MIT", "dependencies": { "@trysound/sax": "0.2.0", @@ -16930,8 +14390,6 @@ }, "node_modules/svgo/node_modules/commander": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "license": "MIT", "engines": { "node": ">= 10" @@ -16939,8 +14397,6 @@ }, "node_modules/svgo/node_modules/css-select": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", @@ -16955,8 +14411,6 @@ }, "node_modules/svgo/node_modules/css-tree": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "license": "MIT", "dependencies": { "mdn-data": "2.0.30", @@ -16968,8 +14422,6 @@ }, "node_modules/svgo/node_modules/dom-serializer": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", @@ -16982,8 +14434,6 @@ }, "node_modules/svgo/node_modules/domhandler": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" @@ -16997,8 +14447,6 @@ }, "node_modules/svgo/node_modules/domutils": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", @@ -17011,8 +14459,6 @@ }, "node_modules/svgo/node_modules/entities": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -17023,21 +14469,15 @@ }, "node_modules/svgo/node_modules/mdn-data": { "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "license": "CC0-1.0" }, "node_modules/symbol-tree": { "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true, "license": "MIT" }, "node_modules/tapable": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "license": "MIT", "engines": { "node": ">=6" @@ -17049,8 +14489,6 @@ }, "node_modules/tar": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "license": "ISC", "dependencies": { "chownr": "^2.0.0", @@ -17066,8 +14504,6 @@ }, "node_modules/tar-fs": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", - "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", "license": "MIT", "dependencies": { "chownr": "^1.1.1", @@ -17078,14 +14514,10 @@ }, "node_modules/tar-fs/node_modules/chownr": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "license": "ISC" }, "node_modules/tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "license": "MIT", "dependencies": { "bl": "^4.0.3", @@ -17100,8 +14532,6 @@ }, "node_modules/tarn": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", - "integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==", "license": "MIT", "engines": { "node": ">=8.0.0" @@ -17109,8 +14539,6 @@ }, "node_modules/teeny-request": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", - "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -17126,8 +14554,6 @@ }, "node_modules/terser": { "version": "5.44.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", - "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -17144,8 +14570,6 @@ }, "node_modules/terser-webpack-plugin": { "version": "5.3.14", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", - "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", @@ -17178,14 +14602,10 @@ }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "license": "MIT" }, "node_modules/test-exclude": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "license": "ISC", "dependencies": { @@ -17199,9 +14619,6 @@ }, "node_modules/test-exclude/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -17221,74 +14638,14 @@ }, "node_modules/text-hex": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", "license": "MIT" }, - "node_modules/thrift": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/thrift/-/thrift-0.11.0.tgz", - "integrity": "sha512-UpsBhOC45a45TpeHOXE4wwYwL8uD2apbHTbtBvkwtUU4dNwCjC7DpQTjw2Q6eIdfNtw+dKthdwq94uLXTJPfFw==", - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0", - "q": "^1.5.0", - "ws": ">= 2.2.3" - }, - "engines": { - "node": ">= 4.1.0" - } - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/through2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/tiktoken": { "version": "1.0.22", - "resolved": "https://registry.npmjs.org/tiktoken/-/tiktoken-1.0.22.tgz", - "integrity": "sha512-PKvy1rVF1RibfF3JlXBSP0Jrcw2uq3yXdgcEXtKTYn3QJ/cBRBHDnrJ5jHky+MENZ6DIPwNUGWpkVx+7joCpNA==", "license": "MIT" }, "node_modules/tildify": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", - "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", "license": "MIT", "engines": { "node": ">=8" @@ -17296,8 +14653,6 @@ }, "node_modules/time-span": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", - "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==", "license": "MIT", "dependencies": { "convert-hrtime": "^5.0.0" @@ -17311,40 +14666,28 @@ }, "node_modules/timm": { "version": "1.7.1", - "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", - "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==", "license": "MIT" }, "node_modules/tiny-inflate": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", - "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", "license": "MIT" }, "node_modules/tinybench": { "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, "node_modules/tinycolor2": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", "license": "MIT" }, "node_modules/tinyexec": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", "dev": true, "license": "MIT" }, "node_modules/tinyglobby": { "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { @@ -17360,8 +14703,6 @@ }, "node_modules/tinyrainbow": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", - "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", "dev": true, "license": "MIT", "engines": { @@ -17370,8 +14711,6 @@ }, "node_modules/tldts": { "version": "7.0.19", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.19.tgz", - "integrity": "sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==", "dev": true, "license": "MIT", "dependencies": { @@ -17383,21 +14722,15 @@ }, "node_modules/tldts-core": { "version": "7.0.19", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.19.tgz", - "integrity": "sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==", "dev": true, "license": "MIT" }, "node_modules/to-data-view": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz", - "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -17407,22 +14740,14 @@ } }, "node_modules/together-ai": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/together-ai/-/together-ai-0.29.0.tgz", - "integrity": "sha512-V4c6AVddCpFOlXCeP7J/lVWy5uyuk3bR1h8LAT2q9rJYx782h6dv8omATYMyCrDwWKjtROqmktsnWm7Imu2mvg==", + "version": "0.32.0", "license": "Apache-2.0", - "dependencies": { - "parquetjs": "^0.11.2", - "progress-stream": "^2.0.0" - }, "bin": { "together-ai": "bin/cli" } }, "node_modules/toidentifier": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "license": "MIT", "engines": { "node": ">=0.6" @@ -17434,8 +14759,6 @@ }, "node_modules/token-types": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", - "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", "license": "MIT", "dependencies": { "@tokenizer/token": "^0.3.0", @@ -17451,8 +14774,6 @@ }, "node_modules/totalist": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, "license": "MIT", "engines": { @@ -17461,8 +14782,6 @@ }, "node_modules/touch": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", - "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", "dev": true, "license": "ISC", "bin": { @@ -17471,8 +14790,6 @@ }, "node_modules/tough-cookie": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", - "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -17484,8 +14801,6 @@ }, "node_modules/tr46": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", - "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", "dev": true, "license": "MIT", "dependencies": { @@ -17497,8 +14812,6 @@ }, "node_modules/tree-kill": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true, "license": "MIT", "bin": { @@ -17507,8 +14820,6 @@ }, "node_modules/triple-beam": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", "license": "MIT", "engines": { "node": ">= 14.0.0" @@ -17516,14 +14827,10 @@ }, "node_modules/ts-algebra": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", - "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", "license": "MIT" }, "node_modules/ts-api-utils": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, "license": "MIT", "engines": { @@ -17535,8 +14842,6 @@ }, "node_modules/ts-poet": { "version": "6.12.0", - "resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-6.12.0.tgz", - "integrity": "sha512-xo+iRNMWqyvXpFTaOAvLPA5QAWO6TZrSUs5s4Odaya3epqofBu/fMLHEWl8jPmjhA0s9sgj9sNvF1BmaQlmQkA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -17545,8 +14850,6 @@ }, "node_modules/ts-proto": { "version": "2.8.3", - "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-2.8.3.tgz", - "integrity": "sha512-TdXInqG+61pj/TvORqITWjvjTTsL1EZxwX49iEj89+xFAcqPT8tjChpAGQXzfcF4MJwvNiuoCEbBOKqVf3ds3g==", "dev": true, "license": "ISC", "dependencies": { @@ -17561,8 +14864,6 @@ }, "node_modules/ts-proto-descriptors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ts-proto-descriptors/-/ts-proto-descriptors-2.0.0.tgz", - "integrity": "sha512-wHcTH3xIv11jxgkX5OyCSFfw27agpInAd6yh89hKG6zqIXnjW9SYqSER2CVQxdPj4czeOhGagNvZBEbJPy7qkw==", "dev": true, "license": "ISC", "dependencies": { @@ -17571,14 +14872,10 @@ }, "node_modules/tslib": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, "node_modules/tunnel-agent": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -17593,8 +14890,6 @@ }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" @@ -17605,8 +14900,6 @@ }, "node_modules/type-detect": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "license": "MIT", "engines": { "node": ">=4" @@ -17614,8 +14907,6 @@ }, "node_modules/type-fest": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -17624,8 +14915,6 @@ }, "node_modules/type-is": { "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "license": "MIT", "dependencies": { "media-typer": "0.3.0", @@ -17637,8 +14926,6 @@ }, "node_modules/type-is/node_modules/media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -17646,8 +14933,6 @@ }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, "license": "MIT", "dependencies": { @@ -17656,8 +14941,6 @@ }, "node_modules/typescript": { "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -17669,8 +14952,6 @@ }, "node_modules/ua-parser-js": { "version": "1.0.41", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz", - "integrity": "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==", "funding": [ { "type": "opencollective", @@ -17695,8 +14976,6 @@ }, "node_modules/uglify-js": { "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "license": "BSD-2-Clause", "bin": { "uglifyjs": "bin/uglifyjs" @@ -17707,21 +14986,15 @@ }, "node_modules/undefsafe": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true, "license": "MIT" }, "node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "license": "MIT" }, "node_modules/unicorn-magic": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", "license": "MIT", "engines": { "node": ">=18" @@ -17732,8 +15005,6 @@ }, "node_modules/union": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", - "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", "dev": true, "dependencies": { "qs": "^6.4.0" @@ -17752,8 +15023,6 @@ }, "node_modules/unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -17761,8 +15030,6 @@ }, "node_modules/update-browserslist-db": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", - "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", "funding": [ { "type": "opencollective", @@ -17791,8 +15058,6 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -17800,8 +15065,6 @@ }, "node_modules/url-join": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", "dev": true, "license": "MIT" }, @@ -17811,8 +15074,6 @@ }, "node_modules/utif2": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/utif2/-/utif2-4.1.0.tgz", - "integrity": "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==", "license": "MIT", "dependencies": { "pako": "^1.0.11" @@ -17820,21 +15081,15 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/utila": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", "dev": true, "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "license": "MIT", "engines": { "node": ">= 0.4.0" @@ -17842,8 +15097,6 @@ }, "node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -17855,23 +15108,13 @@ }, "node_modules/validator": { "version": "13.15.23", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.23.tgz", - "integrity": "sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==", "license": "MIT", "engines": { "node": ">= 0.10" } }, - "node_modules/varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", - "license": "MIT" - }, "node_modules/vary": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -17879,8 +15122,6 @@ }, "node_modules/vite": { "version": "7.2.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.6.tgz", - "integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==", "dev": true, "license": "MIT", "dependencies": { @@ -17972,8 +15213,6 @@ }, "node_modules/vitest": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.14.tgz", - "integrity": "sha512-d9B2J9Cm9dN9+6nxMnnNJKJCtcyKfnHj15N6YNJfaFHRLua/d3sRKU9RuKmO9mB0XdFtUizlxfz/VPbd3OxGhw==", "dev": true, "license": "MIT", "dependencies": { @@ -18050,8 +15289,6 @@ }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, "license": "MIT", "dependencies": { @@ -18063,8 +15300,6 @@ }, "node_modules/watchpack": { "version": "2.4.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", - "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", @@ -18076,8 +15311,6 @@ }, "node_modules/wcwidth": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "license": "MIT", "dependencies": { "defaults": "^1.0.3" @@ -18085,8 +15318,6 @@ }, "node_modules/web-streams-polyfill": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "license": "MIT", "engines": { "node": ">= 8" @@ -18094,8 +15325,6 @@ }, "node_modules/webidl-conversions": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.0.tgz", - "integrity": "sha512-n4W4YFyz5JzOfQeA8oN7dUYpR+MBP3PIUsn2jLjWXwK5ASUzt0Jc/A5sAUZoCYFJRGF0FBKJ+1JjN43rNdsQzA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -18104,8 +15333,6 @@ }, "node_modules/webpack": { "version": "5.103.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.103.0.tgz", - "integrity": "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==", "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", @@ -18152,8 +15379,6 @@ }, "node_modules/webpack-cli": { "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "license": "MIT", "dependencies": { @@ -18198,8 +15423,6 @@ }, "node_modules/webpack-cli/node_modules/commander": { "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, "license": "MIT", "engines": { @@ -18208,8 +15431,6 @@ }, "node_modules/webpack-cli/node_modules/interpret": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, "license": "MIT", "engines": { @@ -18218,8 +15439,6 @@ }, "node_modules/webpack-merge": { "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dev": true, "license": "MIT", "dependencies": { @@ -18233,8 +15452,6 @@ }, "node_modules/webpack-sources": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "license": "MIT", "engines": { "node": ">=10.13.0" @@ -18242,8 +15459,6 @@ }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -18255,8 +15470,6 @@ }, "node_modules/webpack/node_modules/estraverse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -18264,8 +15477,6 @@ }, "node_modules/websocket-driver": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", @@ -18278,8 +15489,6 @@ }, "node_modules/websocket-extensions": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "license": "Apache-2.0", "engines": { "node": ">=0.8.0" @@ -18298,14 +15507,10 @@ }, "node_modules/whatwg-fetch": { "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", "license": "MIT" }, "node_modules/whatwg-mimetype": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, "license": "MIT", "engines": { @@ -18314,8 +15519,6 @@ }, "node_modules/whatwg-url": { "version": "15.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", - "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", "dev": true, "license": "MIT", "dependencies": { @@ -18328,8 +15531,6 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -18343,15 +15544,11 @@ }, "node_modules/which-module": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", "dev": true, "license": "ISC" }, "node_modules/why-is-node-running": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { @@ -18367,8 +15564,6 @@ }, "node_modules/wide-align": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" @@ -18376,15 +15571,11 @@ }, "node_modules/wildcard": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true, "license": "MIT" }, "node_modules/winston": { "version": "3.18.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.18.3.tgz", - "integrity": "sha512-NoBZauFNNWENgsnC9YpgyYwOVrl2m58PpQ8lNHjV3kosGs7KJ7Npk9pCUE+WJlawVSe8mykWDKWFSVfs3QO9ww==", "license": "MIT", "dependencies": { "@colors/colors": "^1.6.0", @@ -18405,8 +15596,6 @@ }, "node_modules/winston-daily-rotate-file": { "version": "4.7.1", - "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.7.1.tgz", - "integrity": "sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==", "license": "MIT", "dependencies": { "file-stream-rotator": "^0.6.1", @@ -18423,8 +15612,6 @@ }, "node_modules/winston-daily-rotate-file/node_modules/object-hash": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", "license": "MIT", "engines": { "node": ">= 6" @@ -18432,8 +15619,6 @@ }, "node_modules/winston-transport": { "version": "4.9.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", - "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", "license": "MIT", "dependencies": { "logform": "^2.7.0", @@ -18446,8 +15631,6 @@ }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -18455,21 +15638,15 @@ }, "node_modules/wordwrap": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "license": "MIT" }, "node_modules/workerpool": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true, "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -18486,8 +15663,6 @@ "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -18503,14 +15678,10 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, "node_modules/write-file-atomic": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "license": "ISC", "dependencies": { @@ -18522,8 +15693,6 @@ }, "node_modules/ws": { "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -18543,8 +15712,6 @@ }, "node_modules/wsl-utils": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", - "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", "license": "MIT", "dependencies": { "is-wsl": "^3.1.0" @@ -18558,8 +15725,6 @@ }, "node_modules/xhr": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", "license": "MIT", "dependencies": { "global": "~4.4.0", @@ -18570,8 +15735,6 @@ }, "node_modules/xml-name-validator": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", "dev": true, "license": "Apache-2.0", "engines": { @@ -18580,14 +15743,10 @@ }, "node_modules/xml-parse-from-string": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", - "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==", "license": "MIT" }, "node_modules/xml2js": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", - "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", "license": "MIT", "dependencies": { "sax": ">=0.6.0", @@ -18599,8 +15758,6 @@ }, "node_modules/xmlbuilder": { "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", "license": "MIT", "engines": { "node": ">=4.0" @@ -18608,23 +15765,17 @@ }, "node_modules/xmlchars": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true, "license": "MIT" }, "node_modules/xmlhttprequest-ssl": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", - "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", "engines": { "node": ">=0.4.0" } }, "node_modules/xtend": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "license": "MIT", "engines": { "node": ">=0.4" @@ -18632,8 +15783,6 @@ }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "license": "ISC", "engines": { "node": ">=10" @@ -18641,14 +15790,10 @@ }, "node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "license": "ISC" }, "node_modules/yaml": { "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -18662,8 +15807,6 @@ }, "node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -18680,8 +15823,6 @@ }, "node_modules/yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "license": "ISC", "engines": { @@ -18690,8 +15831,6 @@ }, "node_modules/yargs-unparser": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "license": "MIT", "dependencies": { @@ -18706,8 +15845,6 @@ }, "node_modules/yargs-unparser/node_modules/camelcase": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "license": "MIT", "engines": { @@ -18719,8 +15856,6 @@ }, "node_modules/yargs-unparser/node_modules/decamelize": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, "license": "MIT", "engines": { @@ -18732,8 +15867,6 @@ }, "node_modules/yargs/node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "license": "ISC", "engines": { "node": ">=12" @@ -18741,8 +15874,6 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "license": "MIT", "engines": { "node": ">=10" @@ -18753,8 +15884,6 @@ }, "node_modules/zod": { "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -18762,8 +15891,6 @@ }, "node_modules/zod-to-json-schema": { "version": "3.25.0", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.0.tgz", - "integrity": "sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==", "license": "ISC", "peerDependencies": { "zod": "^3.25 || ^4" @@ -18848,7 +15975,7 @@ "svg-captcha": "^1.4.0", "svgo": "^3.0.2", "tiktoken": "^1.0.16", - "together-ai": "^0.29.0", + "together-ai": "^0.32.0", "tweetnacl": "^1.0.3", "ua-parser-js": "^1.0.38", "uglify-js": "^3.17.4", @@ -20512,8 +17639,6 @@ }, "src/backend/node_modules/@smithy/abort-controller": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.2.0.tgz", - "integrity": "sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^2.12.0", @@ -20525,8 +17650,6 @@ }, "src/backend/node_modules/@smithy/node-http-handler": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.5.0.tgz", - "integrity": "sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^2.2.0", @@ -20541,8 +17664,6 @@ }, "src/backend/node_modules/@smithy/protocol-http": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.3.0.tgz", - "integrity": "sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^2.12.0", @@ -20554,8 +17675,6 @@ }, "src/backend/node_modules/@smithy/querystring-builder": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.2.0.tgz", - "integrity": "sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^2.12.0", @@ -20568,8 +17687,6 @@ }, "src/backend/node_modules/@smithy/types": { "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz", - "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -20580,8 +17697,6 @@ }, "src/backend/node_modules/@smithy/util-uri-escape": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.2.0.tgz", - "integrity": "sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -20782,8 +17897,6 @@ }, "src/gui/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { @@ -20910,8 +18023,6 @@ }, "src/phoenix/node_modules/sinon": { "version": "17.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", - "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0", @@ -20928,8 +18039,6 @@ }, "src/phoenix/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -21001,8 +18110,6 @@ }, "tools/comment-parser/node_modules/assertion-error": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { @@ -21011,8 +18118,6 @@ }, "tools/comment-parser/node_modules/chai": { "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", "dev": true, "license": "MIT", "dependencies": { @@ -21028,8 +18133,6 @@ }, "tools/comment-parser/node_modules/check-error": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, "license": "MIT", "engines": { @@ -21038,8 +18141,6 @@ }, "tools/comment-parser/node_modules/deep-eql": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, "license": "MIT", "engines": { @@ -21048,15 +18149,11 @@ }, "tools/comment-parser/node_modules/loupe": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", "dev": true, "license": "MIT" }, "tools/comment-parser/node_modules/pathval": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", "engines": { @@ -21110,8 +18207,6 @@ }, "tools/migrations-test/node_modules/commander": { "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "license": "MIT", "engines": { "node": ">=18" diff --git a/package.json b/package.json index 78700fd0..c9844851 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@eslint/js": "^9.35.0", "@playwright/test": "^1.56.1", "@stylistic/eslint-plugin": "^5.3.1", + "@types/mime-types": "^3.0.1", "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^8.46.1", "@typescript-eslint/parser": "^8.46.1", @@ -53,7 +54,7 @@ "build": "npx eslint --quiet -c eslint/mandatory.eslint.config.js src/backend/src extensions && npm run build:ts && cd src/gui && node ./build.js", "check-translations": "node tools/check-translations.js", "prepare": "husky", - "build:ts": "tsc", + "build:ts": "tsc -p tsconfig.build.json", "gen": "./scripts/gen.sh" }, "workspaces": [ diff --git a/src/backend/exports.js b/src/backend/exports.js index adabae18..dc83e613 100644 --- a/src/backend/exports.js +++ b/src/backend/exports.js @@ -16,35 +16,34 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -const CoreModule = require('./src/CoreModule.js'); -const { Kernel } = require('./src/Kernel.js'); -const DatabaseModule = require('./src/DatabaseModule.js'); -const LocalDiskStorageModule = require('./src/LocalDiskStorageModule.js'); -const MemoryStorageModule = require('./src/MemoryStorageModule.js'); -const SelfHostedModule = require('./src/modules/selfhosted/SelfHostedModule.js'); -const { testlaunch } = require('./src/index.js'); -const BaseService = require('./src/services/BaseService.js'); -const { Context } = require('./src/util/context.js'); -const { TestDriversModule } = require('./src/modules/test-drivers/TestDriversModule.js'); -const { PuterAIModule } = require('./src/modules/puterai/PuterAIModule.js'); -const { BroadcastModule } = require('./src/modules/broadcast/BroadcastModule.js'); -const { WebModule } = require('./src/modules/web/WebModule.js'); -const { Core2Module } = require('./src/modules/core/Core2Module.js'); -const { TemplateModule } = require('./src/modules/template/TemplateModule.js'); -const { PuterFSModule } = require('./src/modules/puterfs/PuterFSModule.js'); -const { PerfMonModule } = require('./src/modules/perfmon/PerfMonModule.js'); -const { AppsModule } = require('./src/modules/apps/AppsModule.js'); -const { DevelopmentModule } = require('./src/modules/development/DevelopmentModule.js'); -const { HostOSModule } = require('./src/modules/hostos/HostOSModule.js'); -const { InternetModule } = require('./src/modules/internet/InternetModule.js'); -const { CaptchaModule } = require('./src/modules/captcha/CaptchaModule.js'); -const { EntityStoreModule } = require('./src/modules/entitystore/EntityStoreModule.js'); -const { KVStoreModule } = require('./src/modules/kvstore/KVStoreModule.js'); -const { DomainModule } = require('./src/modules/domain/DomainModule.js'); -const { DNSModule } = require('./src/modules/dns/DNSModule.js'); -const { TestConfigModule } = require('./src/modules/test-config/TestConfigModule.js'); +import CoreModule from './src/CoreModule.js'; +import DatabaseModule from './src/DatabaseModule.js'; +import { testlaunch } from './src/index.js'; +import { Kernel } from './src/Kernel.js'; +import LocalDiskStorageModule from './src/LocalDiskStorageModule.js'; +import MemoryStorageModule from './src/MemoryStorageModule.js'; +import { PuterAIModule } from './src/modules/ai/PuterAIChatModule.js'; +import { AppsModule } from './src/modules/apps/AppsModule.js'; +import { BroadcastModule } from './src/modules/broadcast/BroadcastModule.js'; +import { CaptchaModule } from './src/modules/captcha/CaptchaModule.js'; +import { Core2Module } from './src/modules/core/Core2Module.js'; +import { DevelopmentModule } from './src/modules/development/DevelopmentModule.js'; +import { DNSModule } from './src/modules/dns/DNSModule.js'; +import { DomainModule } from './src/modules/domain/DomainModule.js'; +import { EntityStoreModule } from './src/modules/entitystore/EntityStoreModule.js'; +import { HostOSModule } from './src/modules/hostos/HostOSModule.js'; +import { InternetModule } from './src/modules/internet/InternetModule.js'; +import { KVStoreModule } from './src/modules/kvstore/KVStoreModule.js'; +import { PerfMonModule } from './src/modules/perfmon/PerfMonModule.js'; +import { PuterFSModule } from './src/modules/puterfs/PuterFSModule.js'; +import SelfHostedModule from './src/modules/selfhosted/SelfHostedModule.js'; +import { TestConfigModule } from './src/modules/test-config/TestConfigModule.js'; +import { TestDriversModule } from './src/modules/test-drivers/TestDriversModule.js'; +import { WebModule } from './src/modules/web/WebModule.js'; +import BaseService from './src/services/BaseService.js'; +import { Context } from './src/util/context.js'; -module.exports = { +export default { helloworld: () => { console.log('Hello, World!'); process.exit(0); diff --git a/src/backend/package.json b/src/backend/package.json index 9cb396d2..7b49e15b 100644 --- a/src/backend/package.json +++ b/src/backend/package.json @@ -82,7 +82,7 @@ "svg-captcha": "^1.4.0", "svgo": "^3.0.2", "tiktoken": "^1.0.16", - "together-ai": "^0.29.0", + "together-ai": "^0.32.0", "tweetnacl": "^1.0.3", "ua-parser-js": "^1.0.38", "uglify-js": "^3.17.4", diff --git a/src/backend/src/Kernel.js b/src/backend/src/Kernel.js index 55a839cb..6b0db5f1 100644 --- a/src/backend/src/Kernel.js +++ b/src/backend/src/Kernel.js @@ -35,6 +35,7 @@ const readline = require('node:readline/promises'); const { RuntimeModuleRegistry } = require('./extension/RuntimeModuleRegistry'); const { RuntimeModule } = require('./extension/RuntimeModule'); const deep_proto_merge = require('./config/deep_proto_merge'); +const { kv } = require('./util/kvSingleton'); const { quot } = libs.string; @@ -63,8 +64,6 @@ class Kernel extends AdvancedBase { } _runtime_init (boot_parameters) { - const kvjs = require('@heyputer/kv.js'); - const kv = new kvjs(); global.kv = kv; global.cl = console.log; diff --git a/src/backend/src/api/APIError.js b/src/backend/src/api/APIError.js index 9a772313..0322c63b 100644 --- a/src/backend/src/api/APIError.js +++ b/src/backend/src/api/APIError.js @@ -26,7 +26,7 @@ const { quot } = require('@heyputer/putility').libs.string; * @property {string} message the error message * @property {object} source the source of the error */ -module.exports = class APIError { +class APIError { static codes = { // General 'unknown_error': { @@ -560,14 +560,14 @@ module.exports = class APIError { * * @static * @param {number|string} status - * @param {object} source + * @param {Error} source * @param {string|Error|object} fields one of the following: * - a string to use as the error message * - an Error object to use as the source of the error * - an object with a message property to use as the error message * @returns */ - static create (status, source, fields = {}) { + static create (status, source = {}, fields = {}) { // Just the error code if ( typeof status === 'string' ) { const code = this.codes[status]; @@ -669,3 +669,6 @@ module.exports = class APIError { return `APIError(${this.status}, ${this.message})`; } }; + +module.exports = APIError; +module.exports.APIError = APIError; \ No newline at end of file diff --git a/src/backend/src/api/filesystem/FSNodeParam.js b/src/backend/src/api/filesystem/FSNodeParam.js index d4c4e14a..d3097bc4 100644 --- a/src/backend/src/api/filesystem/FSNodeParam.js +++ b/src/backend/src/api/filesystem/FSNodeParam.js @@ -21,9 +21,8 @@ const { is_valid_uuid4 } = require('../../helpers'); const { Context } = require('../../util/context'); const { PathBuilder } = require('../../util/pathutil'); const APIError = require('../APIError'); -const _path = require('path'); -module.exports = class FSNodeParam { +class FSNodeParam { constructor (srckey, options) { this.srckey = srckey; this.options = options ?? {}; @@ -77,4 +76,7 @@ module.exports = class FSNodeParam { const resolved_path = PathBuilder.resolve(uidOrPath, { puterfs: true }); return await fs.node({ path: resolved_path }); } -}; \ No newline at end of file +}; + +module.exports = FSNodeParam; +module.exports.FSNodeParam = FSNodeParam; \ No newline at end of file diff --git a/src/backend/src/filesystem/definitions/ts/fsentry.js b/src/backend/src/filesystem/definitions/ts/fsentry.js index 83a21b4f..b72bb44e 100644 --- a/src/backend/src/filesystem/definitions/ts/fsentry.js +++ b/src/backend/src/filesystem/definitions/ts/fsentry.js @@ -1,8 +1,5 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.FSEntry = exports.protobufPackage = void 0; -const wire_1 = require("@bufbuild/protobuf/wire"); -exports.protobufPackage = ""; +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +export const protobufPackage = ""; function createBaseFSEntry() { return { uuid: "", @@ -19,8 +16,8 @@ function createBaseFSEntry() { size: 0, }; } -exports.FSEntry = { - encode(message, writer = new wire_1.BinaryWriter()) { +export const FSEntry = { + encode(message, writer = new BinaryWriter()) { if (message.uuid !== "") { writer.uint32(10).string(message.uuid); } @@ -60,7 +57,7 @@ exports.FSEntry = { return writer; }, decode(input, length) { - const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input); + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); const end = length === undefined ? reader.len : reader.pos + length; const message = createBaseFSEntry(); while (reader.pos < end) { @@ -215,7 +212,7 @@ exports.FSEntry = { return obj; }, create(base) { - return exports.FSEntry.fromPartial(base ?? {}); + return FSEntry.fromPartial(base ?? {}); }, fromPartial(object) { const message = createBaseFSEntry(); diff --git a/src/backend/src/modules/ai/PuterAIChatModule.js b/src/backend/src/modules/ai/PuterAIChatModule.js new file mode 100644 index 00000000..77ca70db --- /dev/null +++ b/src/backend/src/modules/ai/PuterAIChatModule.js @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +// METADATA // {"ai-commented":{"service":"claude"}} +import { AdvancedBase } from '@heyputer/putility'; +import config from '../../config.js'; +import { AIInterfaceService } from '../../services/ai/AIInterfaceService.js'; +import { AIChatService } from '../../services/ai/chat/AIChatService.js'; +import { GeminiImageGenerationService } from '../../services/ai/image/GeminiImageGenerationService.js'; +import { OpenAIImageGenerationService } from '../../services/ai/image/OpenAIImageGenerationService.js'; +import { TogetherImageGenerationService } from '../../services/ai/image/TogetherImageGenerationService.js'; +import { AWSTextractService } from '../../services/ai/ocr/AWSTextractService.js'; +import { ElevenLabsVoiceChangerService } from '../../services/ai/sts/ElevenLabsVoiceChangerService.js'; +import { OpenAISpeechToTextService } from '../../services/ai/stt/OpenAISpeechToTextService.js'; +import { AWSPollyService } from '../../services/ai/tts/AWSPollyService.js'; +import { ElevenLabsTTSService } from '../../services/ai/tts/ElevenLabsTTSService.js'; +import { OpenAITTSService } from '../../services/ai/tts/OpenAITTSService.js'; +import { OpenAIVideoGenerationService } from '../../services/ai/video/OpenAIVideoGenerationService.js'; +import { TogetherVideoGenerationService } from '../../services/ai/video/TogetherVideoGenerationService.js'; + +/** +* PuterAIModule class extends AdvancedBase to manage and register various AI services. +* This module handles the initialization and registration of multiple AI-related services +* including text processing, speech synthesis, chat completion, and image generation. +* Services are conditionally registered based on configuration settings, allowing for +* flexible deployment with different AI providers like AWS, OpenAI, Claude, Together AI, +* Mistral, Groq, and XAI. +* @extends AdvancedBase +*/ +export class PuterAIModule extends AdvancedBase { + /** + * Module for managing AI-related services in the Puter platform + * Extends AdvancedBase to provide core functionality + * Handles registration and configuration of various AI services like OpenAI, Claude, AWS services etc. + */ + async install (context) { + const services = context.get('services'); + + services.registerService('__ai-interfaces', AIInterfaceService); + + // completion ai service + services.registerService('ai-chat', AIChatService); + + // TODO DS: centralize other service types too + + // TODO: services should govern their own availability instead of the module deciding what to register + if ( config?.services?.['aws-textract']?.aws ) { + + services.registerService('aws-textract', AWSTextractService); + } + + if ( config?.services?.['aws-polly']?.aws ) { + + services.registerService('aws-polly', AWSPollyService); + } + + if ( config?.services?.['elevenlabs'] || config?.elevenlabs ) { + services.registerService('elevenlabs-tts', ElevenLabsTTSService); + + services.registerService('elevenlabs-voice-changer', ElevenLabsVoiceChangerService); + } + + if ( config?.services?.openai || config?.openai ) { + + services.registerService('openai-image-generation', OpenAIImageGenerationService); + + services.registerService('openai-video-generation', OpenAIVideoGenerationService); + + services.registerService('openai-tts', OpenAITTSService); + + services.registerService('openai-speech2txt', OpenAISpeechToTextService); + } + + if ( config?.services?.['together-ai'] ) { + + services.registerService('together-image-generation', TogetherImageGenerationService); + + services.registerService('together-video-generation', TogetherVideoGenerationService); + } + + if ( config?.services?.['gemini'] ) { + + services.registerService('gemini-image-generation', GeminiImageGenerationService); + } + } +} \ No newline at end of file diff --git a/src/backend/src/modules/puterai/AIChatService.js b/src/backend/src/modules/puterai/AIChatService.js deleted file mode 100644 index 5ea4b696..00000000 --- a/src/backend/src/modules/puterai/AIChatService.js +++ /dev/null @@ -1,792 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const { PassThrough } = require('stream'); -const APIError = require('../../api/APIError'); -const config = require('../../config'); -const BaseService = require('../../services/BaseService'); -const { DB_WRITE } = require('../../services/database/consts'); -const { TypedValue } = require('../../services/drivers/meta/Runtime'); -const { Context } = require('../../util/context'); -const { AsModeration } = require('./lib/AsModeration'); -const FunctionCalling = require('./lib/FunctionCalling'); -const Messages = require('./lib/Messages'); -const Streaming = require('./lib/Streaming'); - -// Maximum number of fallback attempts when a model fails, including the first attempt -const MAX_FALLBACKS = 3 + 1; // includes first attempt - -/** -* AIChatService class extends BaseService to provide AI chat completion functionality. -* Manages multiple AI providers, models, and fallback mechanisms for chat interactions. -* Handles model registration, usage tracking, cost calculation, content moderation, -* and implements the puter-chat-completion driver interface. Supports streaming responses -* and maintains detailed model information including pricing and capabilities. -*/ -class AIChatService extends BaseService { - static MODULES = { - kv: globalThis.kv, - uuidv4: require('uuid').v4, - cuid2: require('@paralleldrive/cuid2').createId, - }; - - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ - get meteringService () { - return this.services.get('meteringService').meteringService; - } - /** - * Initializes the service by setting up core properties. - * Creates empty arrays for providers and model lists, - * and initializes an empty object for the model map. - * Called during service instantiation. - * @private - */ - _construct () { - this.providers = []; - this.simple_model_list = []; - this.detail_model_list = []; - this.detail_model_map = {}; - } - - get_model_details (model_name, context) { - let model_details = this.detail_model_map[model_name]; - if ( Array.isArray(model_details) && context ) { - for ( const model of model_details ) { - if ( model.provider === context.service_used ) { - model_details = model; - break; - } - } - } - if ( Array.isArray(model_details) ) { - model_details = model_details[0]; - } - return model_details; - } - - /** - * Initializes the service by setting up empty arrays and maps for providers and models. - * This method is called during service construction to establish the initial state. - * Creates empty arrays for providers, simple model list, and detailed model list, - * as well as an empty object for the detailed model map. - * @private - */ - _init () { - this.kvkey = this.modules.uuidv4(); - - this.db = this.services.get('database').get(DB_WRITE, 'ai-usage'); - - const svc_apiErrpr = this.services.get('api-error'); - svc_apiErrpr.register({ - max_tokens_exceeded: { - status: 400, - message: ({ input_tokens, max_tokens }) => - 'Input exceeds maximum token count. ' + - `Input has ${input_tokens} tokens, ` + - `but the maximum is ${max_tokens}.`, - }, - }); - } - - /** - * Handles consolidation during service boot by registering service aliases - * and populating model lists/maps from providers. - * - * Registers each provider as an 'ai-chat' service alias and fetches their - * available models and pricing information. Populates: - * - simple_model_list: Basic list of supported models - * - detail_model_list: Detailed model info including costs - * - detail_model_map: Maps model IDs/aliases to their details - * - * @returns {Promise} - */ - async ['__on_boot.consolidation'] () { - { - const svc_driver = this.services.get('driver'); - for ( const provider of this.providers ) { - svc_driver.register_service_alias('ai-chat', - provider.service_name, - { iface: 'puter-chat-completion' }); - } - } - - for ( const provider of this.providers ) { - const delegate = this.services.get(provider.service_name) - .as('puter-chat-completion'); - - // Populate simple model list - { - /** - * Populates the simple model list by fetching available models from the delegate service. - * Wraps the delegate.list() call in a try-catch block to handle potential errors gracefully. - * If the call fails, logs the error and returns an empty array to avoid breaking the service. - * The fetched models are added to this.simple_model_list. - * - * @private - * @returns {Promise} - */ - const models = await (async () => { - try { - return await delegate.list() ?? []; - } catch (e) { - this.log.error(e); - return []; - } - })(); - this.simple_model_list.push(...models); - } - - // Populate detail model list and map - { - /** - * Populates the detail model list and map with model information from the provider. - * Fetches detailed model data including pricing and capabilities. - * Handles model aliases and potential conflicts by storing multiple models in arrays. - * Annotates models with their provider service name. - * Catches and logs any errors during model fetching. - * @private - */ - const models = await (async () => { - try { - return await delegate.models() ?? []; - } catch (e) { - this.log.error(e); - return []; - } - })(); - const annotated_models = []; - for ( const model of models ) { - annotated_models.push({ - ...model, - provider: provider.service_name, - }); - } - this.detail_model_list.push(...annotated_models); - /** - * Helper function to set or push a model into the detail_model_map. - * If there's no existing entry for the key, sets it directly. - * If there's a conflict, converts the entry to an array and pushes the new model. - * @param {string} key - The model ID or alias - * @param {Object} model - The model details to add - */ - const set_or_push = (key, model) => { - // Typical case: no conflict - if ( ! this.detail_model_map[key] ) { - this.detail_model_map[key] = model; - return; - } - - // Conflict: model name will map to an array - let array = this.detail_model_map[key]; - if ( ! Array.isArray(array) ) { - array = [array]; - this.detail_model_map[key] = array; - } - - array.push(model); - }; - for ( const model of annotated_models ) { - set_or_push(model.id, model); - - if ( ! model.aliases ) continue; - - for ( const alias of model.aliases ) { - set_or_push(alias, model); - } - } - } - } - } - - register_provider (spec) { - this.providers.push(spec); - } - - static IMPLEMENTS = { - ['driver-capabilities']: { - supports_test_mode (iface, method_name) { - return iface === 'puter-chat-completion' && - method_name === 'complete'; - }, - }, - /** - * Implements the 'puter-chat-completion' interface methods for AI chat functionality. - * Handles model selection, fallbacks, usage tracking, and moderation. - * Contains methods for listing available models, completing chat prompts, - * and managing provider interactions. - * - * @property {Object} models - Available AI models with details like costs - * @property {Object} list - Simplified list of available models - * @property {Object} complete - Main method for chat completion requests - * @param {Object} parameters - Chat completion parameters including model and messages - * @returns {Promise} Chat completion response with usage stats - * @throws {Error} If service is called directly or no fallback models available - */ - ['puter-chat-completion']: { - /** - * Returns list of available AI models with detailed information - * - * Delegates to the intended service's models() method if a delegate exists, - * otherwise returns the internal detail_model_list containing all available models - * across providers with their capabilities and pricing information. - * - * For an example of the expected model object structure, see the `async models_` - * private method at the bottom of any service with hard-coded model details such - * as ClaudeService or GroqAIService. - * - * @returns {Promise>} Array of model objects with details like id, provider, cost, etc. - */ - async models () { - const delegate = this.get_delegate(); - if ( ! delegate ) return await this.models_(); - return await delegate.models(); - }, - - /** - * Reports model names (including aliased names) only with no additional - * detail. - * @returns {Promise} Array of model objects with basic details - */ - async list () { - const delegate = this.get_delegate(); - if ( ! delegate ) return await this.list_(); - return await delegate.list(); - }, - - /** - * Completes a chat interaction using one of the available AI models - * - * This service registers itself under an alias for each other AI - * chat service, which results in DriverService always calling this - * `complete` implementaiton first, which delegates to the intended - * service. - * - * The return value may be anything that DriverService knows how to - * coerce to the intended result. When `options.stream` is FALSE, - * this is typically a raw object for the JSON response. When - * `options.stream` is TRUE, the result is an object with this - * structure: - * - * { - * stream: true, - * response: stream { - * content_type: 'application/x-ndjson', - * } - * } - * - * @param {Object} options - The completion options - * @param {Array} options.messages - Array of chat messages to process - * @param {boolean} options.stream - Whether to stream the response - * @param {string} options.model - The name of a model to use - * @returns {{stream: boolean, [k:string]: unknown}} Returns either an object with stream:true property or a completion object - */ - async complete (parameters) { - const client_driver_call = Context.get('client_driver_call'); - let { test_mode, intended_service, response_metadata } = client_driver_call; - - const completionId = this.modules.cuid2(); - this.log.noticeme('AIChatService.complete', { intended_service, test_mode }); - const svc_event = this.services.get('event'); - const event = { - actor: Context.get('actor'), - completionId, - allow: true, - intended_service, - parameters, - }; - await svc_event.emit('ai.prompt.validate', event); - if ( ! event.allow ) { - test_mode = true; - if ( event.custom ) parameters.custom = event.custom; - } - - if ( parameters.messages ) { - parameters.messages = - Messages.normalize_messages(parameters.messages); - } - - // Skip moderation for Ollama (local service) and other local services - const should_moderate = !test_mode && - intended_service !== 'ollama' && - !parameters.model?.startsWith('ollama:'); - - if ( should_moderate && !await this.moderate(parameters) ) { - test_mode = true; - throw APIError.create('moderation_failed'); - } - - // Only set moderated flag if we actually ran moderation - if ( !test_mode && should_moderate ) { - Context.set('moderated', true); - } - - if ( test_mode ) { - intended_service = 'fake-chat'; - if ( event.abuse ) { - parameters.model = 'abuse'; - } - } - - if ( parameters.tools ) { - FunctionCalling.normalize_tools_object(parameters.tools); - } - - if ( intended_service === this.service_name ) { - throw new Error('Calling ai-chat directly is not yet supported'); - } - - const svc_driver = this.services.get('driver'); - let ret, error; - let service_used = intended_service; - let model_used = this.get_model_from_request(parameters, { - intended_service, - }); - - // Updated: Check usage and get a boolean result instead of throwing error - const actor = Context.get('actor'); - const model_details = this.get_model_details(model_used, { - service_used, - }); - - if ( ! model_details ) { - // TODO (xiaochen): replace with a standard link - const available_models_url = `${this.global_config.origin }/puterai/chat/models`; - - throw APIError.create('field_invalid', null, { - key: 'model', - expected: `a valid model name from ${available_models_url}`, - got: model_used, - }); - } - - const model_input_cost = model_details.cost.input; - const model_output_cost = model_details.cost.output; - const model_max_tokens = model_details.max_tokens; - const text = Messages.extract_text(parameters.messages); - const approximate_input_cost = text.length / 4 * model_input_cost; // TODO DS: guesstimate tokens better, - const usageAllowed = await this.meteringService.hasEnoughCredits(actor, approximate_input_cost); - - // Handle usage limits reached case - if ( ! usageAllowed ) { - // The check_usage_ method has eady updated the intended_service to 'usage-limited-chat' - service_used = 'usage-limited-chat'; - model_used = 'usage-limited'; - // Update intended_service to match service_used - intended_service = service_used; - } - - // available is no longer defined, so use meteringService to get available credits - const availableCredits = await this.meteringService.getRemainingUsage(actor); - const max_allowed_output_amount = - availableCredits - approximate_input_cost; - - const max_allowed_output_tokens = - max_allowed_output_amount / model_output_cost; - - if ( model_max_tokens ) { - parameters.max_tokens = Math.floor(Math.min(parameters.max_tokens ?? Number.POSITIVE_INFINITY, - max_allowed_output_tokens, - model_max_tokens - (Math.ceil(text.length / 4)))); - if ( parameters.max_tokens < 1 ) { - parameters.max_tokens = undefined; - } - } - try { - ret = await svc_driver.call_new_({ - actor: Context.get('actor'), - service_name: intended_service, - skip_usage: true, - iface: 'puter-chat-completion', - method: 'complete', - args: parameters, - }); - } catch (e) { - const tried = []; - let model = model_used; - - // TODO: if conflict models exist, add service name - tried.push(model); - - error = e; - - // Distinguishing between user errors and service errors - // is very messy because of different conventions between - // services. This is a best-effort attempt to catch user - // errors and throw them as 400s. - const is_request_error = (() => { - if ( e instanceof APIError ) { - return true; - } - if ( e.type === 'invalid_request_error' ) { - return true; - } - let some_error = e; - while ( some_error ) { - if ( some_error.type === 'invalid_request_error' ) { - return true; - } - some_error = some_error.error ?? some_error.cause; - } - return false; - })(); - - if ( is_request_error ) { - console.log(e.stack); - throw APIError.create('error_400_from_delegate', e, { - delegate: intended_service, - message: e.message, - }); - } - console.error(e); - - if ( config.disable_fallback_mechanisms ) { - throw e; - } - - this.log.error('error calling service', { - intended_service, - model, - error: e, - }); - while ( error ) { - // No fallbacks for pseudo-models - if ( intended_service === 'fake-chat' ) { - break; - } - - const fallback = this.get_fallback_model({ - model, tried, - }); - - if ( ! fallback ) { - throw new Error('no fallback model available'); - } - - const { - fallback_service_name, - fallback_model_name, - } = fallback; - - this.log.warn('model fallback', { - intended_service, - fallback_service_name, - fallback_model_name, - }); - - // Check usage for fallback model too (with updated method) - const actor = Context.get('actor'); - const fallbackUsageAllowed = await this.meteringService.hasEnoughCredits(actor, 1); - - // If usage not allowed for fallback, use usage-limited-chat instead - if ( ! fallbackUsageAllowed ) { - // The check_usage_ method has already updated intended_service - service_used = 'usage-limited-chat'; - model_used = 'usage-limited'; - // Clear the error to exit the fallback loop - error = null; - - // Call the usage-limited service - ret = await svc_driver.call_new_({ - actor: Context.get('actor'), - service_name: 'usage-limited-chat', - skip_usage: true, - iface: 'puter-chat-completion', - method: 'complete', - args: parameters, - }); - } else { - // Normal fallback flow continues - try { - ret = await svc_driver.call_new_({ - actor: Context.get('actor'), - service_name: fallback_service_name, - skip_usage: true, - iface: 'puter-chat-completion', - method: 'complete', - args: { - ...parameters, - model: fallback_model_name, - }, - }); - error = null; - service_used = fallback_service_name; - model_used = fallback_model_name; - response_metadata.fallback = { - service: fallback_service_name, - model: fallback_model_name, - tried: tried, - }; - } catch (e) { - error = e; - tried.push(fallback_model_name); - this.log.error('error calling fallback', { - intended_service, - model, - error: e, - }); - } - } - } - } - - ret.result.via_ai_chat_service = true; - response_metadata.service_used = service_used; - - // Add flag if we're using the usage-limited service - if ( service_used === 'usage-limited-chat' ) { - response_metadata.usage_limited = true; - } - - const username = Context.get('actor').type?.user?.username; - - if ( ret.result.stream ) { - if ( ret.result.init_chat_stream ) { - const stream = new PassThrough(); - const retval = new TypedValue({ - $: 'stream', - content_type: 'application/x-ndjson', - chunked: true, - }, stream); - - const chatStream = new Streaming.AIChatStream({ - stream, - }); - - (async () => { - try { - await ret.result.init_chat_stream({ chatStream }); - } catch (e) { - this.errors.report('error during stream response', { - source: e, - }); - stream.write(`${JSON.stringify({ - type: 'error', - message: e.message, - }) }\n`); - stream.end(); - } finally { - if ( ret.result.finally_fn ) { - await ret.result.finally_fn(); - } - } - })(); - - return retval; - } - - return ret.result.response; - } - - await svc_event.emit('ai.prompt.complete', { - username, - intended_service, - parameters, - result: ret.result, - model_used, - service_used, - }); - - if ( parameters.response?.normalize ) { - ret.result.message = - Messages.normalize_single_message(ret.result.message); - ret.result = { - message: ret.result.message, - via_ai_chat_service: true, - normalized: true, - }; - } - - return ret.result; - }, - }, - }; - - /** - * Moderates chat messages for inappropriate content using OpenAI's moderation service - * - * @param {Object} params - The parameters object - * @param {Array} params.messages - Array of chat messages to moderate - * @returns {Promise} Returns true if content is appropriate, false if flagged - * - * @description - * Extracts text content from messages and checks each against OpenAI's moderation. - * Handles both string content and structured message objects. - * Returns false immediately if any message is flagged as inappropriate. - * Returns true if OpenAI service is unavailable or all messages pass moderation. - */ - async moderate ({ messages }) { - if ( process.env.TEST_MODERATION_FAILURE ) return false; - const fulltext = Messages.extract_text(messages); - let mod_last_error = null; - let mod_result = null; - try { - const svc_openai = this.services.get('openai-completion'); - mod_result = await svc_openai.check_moderation(fulltext); - if ( mod_result.flagged ) return false; - return true; - } catch (e) { - console.error(e); - mod_last_error = e; - } - try { - const svc_claude = this.services.get('claude'); - const chat = svc_claude.as('puter-chat-completion'); - const mod = new AsModeration({ - chat, - model: 'claude-3-haiku-20240307', - }); - if ( ! await mod.moderate(fulltext) ) { - return false; - } - mod_last_error = null; - return true; - } catch (e) { - console.error(e); - mod_last_error = e; - } - - if ( mod_last_error ) { - this.log.error('moderation error', { - fulltext, - mod_last_error, - }); - throw new Error('no working moderation service'); - } - return true; - } - - async models_ () { - return this.detail_model_list; - } - - /** - * Returns a list of available AI models with basic details - * @returns {Promise} Array of simple model objects containing basic model information - */ - async list_ () { - return this.simple_model_list; - } - - /** - * Gets the appropriate delegate service for handling chat completion requests. - * If the intended service is this service (ai-chat), returns undefined. - * Otherwise returns the intended service wrapped as a puter-chat-completion interface. - * - * @returns {Object|undefined} The delegate service or undefined if intended service is ai-chat - */ - get_delegate () { - const client_driver_call = Context.get('client_driver_call'); - if ( client_driver_call.intended_service === this.service_name ) { - return undefined; - } - console.log('getting service', client_driver_call.intended_service); - const service = this.services.get(client_driver_call.intended_service); - return service.as('puter-chat-completion'); - } - - /** - * Find an appropriate fallback model by sorting the list of models - * by the euclidean distance of the input/output prices and selecting - * the first one that is not in the tried list. - * - * @param {*} param0 - * @returns - */ - get_fallback_model ({ model, tried }) { - let target_model = this.detail_model_map[model]; - - if ( ! target_model ) { - this.log.error('could not find model', { model }); - throw new Error('could not find model'); - } - if ( Array.isArray(target_model) ) { - // TODO: better conflict resolution - this.log.noticeme('conflict exists', { model, target_model }); - target_model = target_model[0]; - } - - // First check KV for the sorted list - let potentialFallbacks = this.modules.kv.get(`${this.kvkey}:fallbacks:${model}`); - - if ( ! potentialFallbacks ) { - // Calculate the sorted list - const models = this.detail_model_list; - - let aiProvider, modelToSearch; - if ( target_model.id.startsWith('openrouter:') || target_model.id.startsWith('togetherai:') ) { - [aiProvider, modelToSearch] = target_model.id.replace('openrouter:', '').replace('togetherai:', '').toLowerCase().split('/'); - } else { - [aiProvider, modelToSearch] = target_model.provider.toLowerCase().replace('gemini', 'google').replace('openai-completion', 'openai'), target_model.id.toLowerCase(); - } - - const potentialMatches = models.filter(model => { - const possibleModelNames = [`openrouter:${aiProvider}/${modelToSearch}`, - `togetherai:${aiProvider}/${modelToSearch}`, ...(target_model.aliases?.map((alias) => [`openrouter:${aiProvider}/${alias}`, - `togetherai:${aiProvider}/${alias}`])?.flat() ?? [])]; - - return !!possibleModelNames.find(possibleName => model.id.toLowerCase() === possibleName); - }).slice(0, MAX_FALLBACKS); - - this.modules.kv.set(`${this.kvkey}:fallbacks:${model}`, potentialMatches); - potentialFallbacks = potentialMatches; - } - - for ( const model of potentialFallbacks ) { - if ( tried.includes(model.id) ) continue; - if ( model.provider === 'fake-chat' ) continue; - - return { - fallback_service_name: model.provider, - fallback_model_name: model.id, - }; - } - - // No fallbacks available - this.log.error('no fallbacks', { - potentialFallbacks, - tried, - }); - } - - get_model_from_request (parameters, modified_context = {}) { - const client_driver_call = Context.get('client_driver_call'); - let { intended_service } = client_driver_call; - - if ( modified_context.intended_service ) { - intended_service = modified_context.intended_service; - } - - let model = parameters.model; - if ( ! model ) { - const service = this.services.get(intended_service); - if ( ! service.get_default_model ) { - throw new Error('could not infer model from service'); - } - model = service.get_default_model(); - if ( ! model ) { - throw new Error('could not infer model from service'); - } - } - - return model; - } -} - -module.exports = { AIChatService }; diff --git a/src/backend/src/modules/puterai/AITestModeService.js b/src/backend/src/modules/puterai/AITestModeService.js deleted file mode 100644 index 60aee8f5..00000000 --- a/src/backend/src/modules/puterai/AITestModeService.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const BaseService = require('../../services/BaseService'); - -/** -* Service class that handles AI test mode functionality. -* Extends BaseService to register test services for AI chat completions. -* Used for testing and development of AI-related features by providing -* a mock implementation of the chat completion service. -*/ -class AITestModeService extends BaseService { - /** - * Service for managing AI test mode functionality - * @extends BaseService - */ - async _init () { - const svc_driver = this.services.get('driver'); - svc_driver.register_test_service('puter-chat-completion', 'ai-chat'); - } -} - -module.exports = { - AITestModeService, -}; diff --git a/src/backend/src/modules/puterai/ClaudeService.js b/src/backend/src/modules/puterai/ClaudeService.js deleted file mode 100644 index ea50d060..00000000 --- a/src/backend/src/modules/puterai/ClaudeService.js +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const { default: Anthropic, toFile } = require('@anthropic-ai/sdk'); -const BaseService = require('../../services/BaseService'); -const FunctionCalling = require('./lib/FunctionCalling'); -const Messages = require('./lib/Messages'); -const FSNodeParam = require('../../api/filesystem/FSNodeParam'); -const { LLRead } = require('../../filesystem/ll_operations/ll_read'); -const { Context } = require('../../util/context'); -const mime = require('mime-types'); - -/** -* ClaudeService class extends BaseService to provide integration with Anthropic's Claude AI models. -* Implements the puter-chat-completion interface for handling AI chat interactions. -* Manages message streaming, token limits, model selection, and API communication with Claude. -* Supports system prompts, message adaptation, and usage tracking. -* @extends BaseService -*/ -class ClaudeService extends BaseService { - - // Traits definitions - static IMPLEMENTS = { - ['puter-chat-completion']: { - async models () { - return this.models(); - }, - async list () { - return this.list(); - }, - async complete (...args) { - return this.complete(...args); - }, - }, - }; - - /** - * @type {import('@anthropic-ai/sdk').Anthropic} - */ - anthropic; - - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ - #meteringService; - - async _init () { - this.anthropic = new Anthropic({ - apiKey: this.config.apiKey, - // 10 minutes is the default; we need to override the timeout to - // disable an "aggressive" preemptive error that's thrown - // erroneously by the SDK. - // (https://github.com/anthropics/anthropic-sdk-typescript/issues/822) - timeout: 10 * 60 * 1001, - }); - - const svc_aiChat = this.services.get('ai-chat'); - svc_aiChat.register_provider({ - service_name: this.service_name, - alias: true, - }); - this.#meteringService = this.services.get('meteringService').meteringService; // TODO DS: move to proper extensions - } - - /** - * Returns the default model identifier for Claude API interactions - * @returns {string} The default model ID 'claude-3-5-sonnet-latest' - */ - get_default_model () { - return 'claude-3-5-sonnet-latest'; - } - - async list () { - const models = this.models(); - const model_names = []; - for ( const model of models ) { - model_names.push(model.id); - if ( model.aliases ) { - model_names.push(...model.aliases); - } - } - return model_names; - } - - /** - * - * @param {object} arg - * @param {Array} arg.messages - * @param {boolean} [arg.stream] - * @param {string} arg.model - * @param {Array} [arg.tools] - * @param {number} [arg.max_tokens] - * @param {number} [arg.temperature] - * @returns - */ - async complete ({ messages, stream, model, tools, max_tokens, temperature }) { - tools = FunctionCalling.make_claude_tools(tools); - - let system_prompts; - // unsure why system_prompts is an array but it always seems to only have exactly one element, - // and the real array of system_prompts seems to be the [0].content -- NS - [system_prompts, messages] = Messages.extract_and_remove_system_messages(messages); - - // Apply the cache control tag to all content blocks - if ( - system_prompts.length > 0 && - system_prompts[0].cache_control && - system_prompts[0]?.content - ) { - system_prompts[0].content = system_prompts[0].content.map(prompt => { - prompt.cache_control = system_prompts[0].cache_control; - return prompt; - }); - } - - messages = messages.map(message => { - if ( message.cache_control ) { - message.content[0].cache_control = message.cache_control; - } - delete message.cache_control; - return message; - }); - - const sdk_params = { - model: model ?? this.get_default_model(), - max_tokens: Math.floor(max_tokens) || - (( - model === 'claude-3-5-sonnet-20241022' - || model === 'claude-3-5-sonnet-20240620' - ) ? 8192 : this.models().filter(e => (e.name === model || e.aliases?.includes(model)))[0]?.max_tokens || 4096), //required - temperature: temperature || 0, // required - ...( (system_prompts && system_prompts[0]?.content) ? { - system: system_prompts[0]?.content, - } : {}), - tool_choice: { - type: 'auto', - disable_parallel_tool_use: true, - }, - messages, - ...(tools ? { tools } : {}), - }; - console.log(sdk_params.max_tokens); - - let beta_mode = false; - - // Perform file uploads - const file_delete_tasks = []; - const actor = Context.get('actor'); - const { user } = actor.type; - - const file_input_tasks = []; - for ( const message of messages ) { - // We can assume `message.content` is not undefined because - // Messages.normalize_single_message ensures this. - for ( const contentPart of message.content ) { - if ( ! contentPart.puter_path ) continue; - file_input_tasks.push({ - node: await (new FSNodeParam(contentPart.puter_path)).consolidate({ - req: { user }, - getParam: () => contentPart.puter_path, - }), - contentPart, - }); - } - } - - const promises = []; - for ( const task of file_input_tasks ) { - promises.push((async () => { - const ll_read = new LLRead(); - const stream = await ll_read.run({ - actor: Context.get('actor'), - fsNode: task.node, - }); - - const mimeType = mime.contentType(await task.node.get('name')); - - beta_mode = true; - const fileUpload = await this.anthropic.beta.files.upload({ - file: await toFile(stream, undefined, { type: mimeType }), - }, { - betas: ['files-api-2025-04-14'], - }); - - file_delete_tasks.push({ file_id: fileUpload.id }); - // We have to copy a table from the documentation here: - // https://docs.anthropic.com/en/docs/build-with-claude/files - const contentBlockTypeForFileBasedOnMime = (() => { - if ( mimeType.startsWith('image/') ) { - return 'image'; - } - if ( mimeType.startsWith('text/') ) { - return 'document'; - } - if ( mimeType === 'application/pdf' || mimeType === 'application/x-pdf' ) { - return 'document'; - } - return 'container_upload'; - })(); - - delete task.contentPart.puter_path, - task.contentPart.type = contentBlockTypeForFileBasedOnMime; - task.contentPart.source = { - type: 'file', - file_id: fileUpload.id, - }; - })()); - } - await Promise.all(promises); - - const cleanup_files = async () => { - const promises = []; - for ( const task of file_delete_tasks ) { - promises.push((async () => { - try { - await this.anthropic.beta.files.delete(task.file_id, - { betas: ['files-api-2025-04-14'] }); - } catch (e) { - this.errors.report('claude:file-delete-task', { - source: e, - trace: true, - alarm: true, - extra: { file_id: task.file_id }, - }); - } - })()); - } - await Promise.all(promises); - }; - - if ( beta_mode ) { - Object.assign(sdk_params, { betas: ['files-api-2025-04-14'] }); - } - const anthropic = beta_mode ? this.anthropic.beta : this.anthropic; - - if ( stream ) { - const init_chat_stream = async ({ chatStream }) => { - const completion = await anthropic.messages.stream(sdk_params); - const usageSum = {}; - - let message, contentBlock; - for await ( const event of completion ) { - - const usageObject = (event?.usage ?? event?.message?.usage ?? {}); - const meteredData = this.usageFormatterUtil(usageObject); - Object.keys(meteredData).forEach((key) => { - if ( ! usageSum[key] ) usageSum[key] = 0; - usageSum[key] += meteredData[key]; - }); - - if ( event.type === 'message_start' ) { - message = chatStream.message(); - continue; - } - if ( event.type === 'message_stop' ) { - message.end(); - message = null; - continue; - } - - if ( event.type === 'content_block_start' ) { - if ( event.content_block.type === 'tool_use' ) { - contentBlock = message.contentBlock({ - type: event.content_block.type, - id: event.content_block.id, - name: event.content_block.name, - }); - continue; - } - contentBlock = message.contentBlock({ - type: event.content_block.type, - }); - continue; - } - - if ( event.type === 'content_block_stop' ) { - contentBlock.end(); - contentBlock = null; - continue; - } - - if ( event.type === 'content_block_delta' ) { - if ( event.delta.type === 'input_json_delta' ) { - contentBlock.addPartialJSON(event.delta.partial_json); - continue; - } - if ( event.delta.type === 'text_delta' ) { - contentBlock.addText(event.delta.text); - continue; - } - } - } - chatStream.end(); - - this.#meteringService.utilRecordUsageObject(usageSum, actor, `claude:${this.models().find(m => [m.id, ...(m.aliases || [])].includes(model || this.get_default_model())).id}`); - }; - - return { - init_chat_stream, - stream: true, - finally_fn: cleanup_files, - }; - } - - const msg = await anthropic.messages.create(sdk_params); - await cleanup_files(); - - const usage = this.usageFormatterUtil(msg.usage); - this.#meteringService.utilRecordUsageObject(usage, actor, `claude:${this.models().find(m => [m.id, ...(m.aliases || [])].includes(model || this.get_default_model())).id}`); - - // TODO DS: cleanup old usage tracking - return { - message: msg, - usage: msg.usage, - finish_reason: 'stop', - }; - } - - /** @type {(usage: import("@anthropic-ai/sdk/resources/messages.js").Usage | import("@anthropic-ai/sdk/resources/beta/messages/messages.js").BetaUsage) => {}}) */ - usageFormatterUtil (usage) { - return { - input_tokens: usage?.input_tokens || 0, - ephemeral_5m_input_tokens: usage?.cache_creation?.ephemeral_5m_input_tokens || usage.cache_creation_input_tokens || 0, // this is because they're api is a bit inconsistent - ephemeral_1h_input_tokens: usage?.cache_creation?.ephemeral_1h_input_tokens || 0, - cache_read_input_tokens: usage?.cache_read_input_tokens || 0, - output_tokens: usage?.output_tokens || 0, - }; - }; - - /** - * Retrieves available Claude AI models and their specifications - * @returns Array of model objects containing: - * - id: Model identifier - * - name: Display name - * - aliases: Alternative names for the model - * - context: Maximum context window size - * - cost: Pricing details (currency, token counts, input/output costs) - * - qualitative_speed: Relative speed rating - * - max_output: Maximum output tokens - * - training_cutoff: Training data cutoff date - */ - models () { - return [ - { - id: 'claude-opus-4-5-20251101', - aliases: ['claude-opus-4-5-latest', 'claude-opus-4-5', 'claude-opus-4.5'], - name: 'Claude Opus 4.5', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 500, - output: 2500, - }, - context: 200000, - max_tokens: 64000, - }, - { - id: 'claude-haiku-4-5-20251001', - aliases: ['claude-haiku-4.5', 'claude-haiku-4-5'], - name: 'Claude Haiku 4.5', - context: 200000, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 100, - output: 500, - }, - max_tokens: 64000, - }, - { - id: 'claude-sonnet-4-5-20250929', - aliases: ['claude-sonnet-4.5', 'claude-sonnet-4-5'], - name: 'Claude Sonnet 4.5', - context: 200000, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 300, - output: 1500, - }, - max_tokens: 64000, - }, - { - id: 'claude-opus-4-1-20250805', - aliases: ['claude-opus-4-1'], - name: 'Claude Opus 4.1', - context: 200000, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 1500, - output: 7500, - }, - max_tokens: 32000, - }, - { - id: 'claude-opus-4-20250514', - aliases: ['claude-opus-4', 'claude-opus-4-latest'], - name: 'Claude Opus 4', - context: 200000, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 1500, - output: 7500, - }, - max_tokens: 32000, - }, - { - id: 'claude-sonnet-4-20250514', - aliases: ['claude-sonnet-4', 'claude-sonnet-4-latest'], - name: 'Claude Sonnet 4', - context: 200000, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 300, - output: 1500, - }, - max_tokens: 64000, - }, - { - id: 'claude-3-7-sonnet-20250219', - aliases: ['claude-3-7-sonnet-latest'], - succeeded_by: 'claude-sonnet-4-20250514', - context: 200000, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 300, - output: 1500, - }, - max_tokens: 8192, - }, - { - id: 'claude-3-5-sonnet-20241022', - name: 'Claude 3.5 Sonnet', - aliases: ['claude-3-5-sonnet-latest'], - context: 200000, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 300, - output: 1500, - }, - qualitative_speed: 'fast', - training_cutoff: '2024-04', - max_tokens: 8192, - }, - { - id: 'claude-3-5-sonnet-20240620', - succeeded_by: 'claude-3-5-sonnet-20241022', - context: 200000, // might be wrong - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 300, - output: 1500, - }, - max_tokens: 8192, - }, - { - id: 'claude-3-haiku-20240307', - context: 200000, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 25, - output: 125, - }, - qualitative_speed: 'fastest', - max_tokens: 4096, - }, - ]; - } -} - -module.exports = { - ClaudeService, -}; diff --git a/src/backend/src/modules/puterai/DeepSeekService.js b/src/backend/src/modules/puterai/DeepSeekService.js deleted file mode 100644 index d61a50d8..00000000 --- a/src/backend/src/modules/puterai/DeepSeekService.js +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const BaseService = require('../../services/BaseService'); -const { Context } = require('../../util/context'); -const OpenAIUtil = require('./lib/OpenAIUtil'); -const dedent = require('dedent'); - -/** -* DeepSeekService class - Provides integration with DeepSeek's API for chat completions -* Extends BaseService to implement the puter-chat-completion interface. -* Handles model management, message adaptation, streaming responses, -* and usage tracking for DeepSeek's language models like DeepSeek Chat and Reasoner. -* @extends BaseService -*/ -class DeepSeekService extends BaseService { - static MODULES = { - openai: require('openai'), - }; - - /** - * @type {import('../../services/MeteringService/MeteringService').MeteringService} - */ - meteringService; - /** - * Gets the system prompt used for AI interactions - * @returns {string} The base system prompt that identifies the AI as running on Puter - */ - adapt_model (model) { - return model; - } - - /** - * Initializes the XAI service by setting up the OpenAI client and registering with the AI chat provider - * @private - * @returns {Promise} Resolves when initialization is complete - */ - async _init () { - this.openai = new this.modules.openai.OpenAI({ - apiKey: this.global_config.services.deepseek.apiKey, - baseURL: 'https://api.deepseek.com', - }); - - const svc_aiChat = this.services.get('ai-chat'); - svc_aiChat.register_provider({ - service_name: this.service_name, - alias: true, - }); - this.meteringService = this.services.get('meteringService').meteringService; - } - - /** - * Returns the default model identifier for the DeepSeek service - * @returns {string} The default model ID 'deepseek-chat' - */ - get_default_model () { - return 'deepseek-chat'; - } - - static IMPLEMENTS = { - ['puter-chat-completion']: { - /** - * Returns a list of available models and their details. - * See AIChatService for more information. - * - * @returns Promise> Array of model details - */ - async models () { - return await this.models_(); - }, - /** - * Returns a list of available model names including their aliases - * @returns {Promise} Array of model identifiers and their aliases - * @description Retrieves all available model IDs and their aliases, - * flattening them into a single array of strings that can be used for model selection - */ - async list () { - const models = await this.models_(); - const model_names = []; - for ( const model of models ) { - model_names.push(model.id); - if ( model.aliases ) { - model_names.push(...model.aliases); - } - } - return model_names; - }, - - /** - * AI Chat completion method. - * See AIChatService for more details. - */ - async complete ({ messages, stream, model, tools, max_tokens, temperature }) { - model = this.adapt_model(model); - - messages = await OpenAIUtil.process_input_messages(messages); - for ( const message of messages ) { - // DeepSeek doesn't appreciate arrays here - if ( message.tool_calls && Array.isArray(message.content) ) { - message.content = ''; - } - } - - // Function calling is just broken on DeepSeek - it never awknowledges - // the tool results and instead keeps calling the function over and over. - // (see https://github.com/deepseek-ai/DeepSeek-V3/issues/15) - // To fix this, we inject a message that tells DeepSeek what happened. - const TOOL_TEXT = message => dedent(` - Hi DeepSeek V3, your tool calling is broken and you are not able to - obtain tool results in the expected way. That's okay, we can work - around this. - - Please do not repeat this tool call. - - We have provided the tool call results below: - - Tool call ${message.tool_call_id} returned: ${message.content}. - `); - for ( let i = messages.length - 1; i >= 0 ; i-- ) { - const message = messages[i]; - if ( message.role === 'tool' ) { - messages.splice(i + 1, 0, { - role: 'system', - content: [ - { - type: 'text', - text: TOOL_TEXT(message), - }, - ], - }); - } - } - - const completion = await this.openai.chat.completions.create({ - messages, - model: model ?? this.get_default_model(), - ...(tools ? { tools } : {}), - max_tokens: max_tokens || 1000, - temperature, // the default temperature is 1.0. suggested 0 for math/coding and 1.5 for creative poetry - stream, - ...(stream ? { - stream_options: { include_usage: true }, - } : {}), - }); - - // Metering integration now handled via usage_calculator in OpenAIUtil.handle_completion_output - const actor = Context.get('actor'); - const modelDetails = (await this.models_()).find(m => m.id === (model ?? this.get_default_model())); - - return OpenAIUtil.handle_completion_output({ - usage_calculator: ({ usage }) => { - const trackedUsage = OpenAIUtil.extractMeteredUsage(usage); - this.meteringService.utilRecordUsageObject(trackedUsage, actor, `deepseek:${modelDetails.id}`); - const legacyCostCalculator = OpenAIUtil.create_usage_calculator({ - model_details: modelDetails, - }); - return legacyCostCalculator({ usage }); - }, - stream, - completion, - }); - }, - }, - }; - - /** - * Retrieves available AI models and their specifications - * @returns {Promise} Array of model objects containing: - * - id: Model identifier string - * - name: Human readable model name - * - context: Maximum context window size - * - cost: Pricing information object with currency and rates - * @private - */ - async models_ () { - return [ - { - id: 'deepseek-chat', - name: 'DeepSeek Chat', - context: 128000, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 56, - output: 168, - }, - max_tokens: 8000, - }, - { - id: 'deepseek-reasoner', - name: 'DeepSeek Reasoner', - context: 128000, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 56, - output: 168, - }, - max_tokens: 64000, - }, - ]; - } -} - -module.exports = { - DeepSeekService, -}; diff --git a/src/backend/src/modules/puterai/FakeChatService.js b/src/backend/src/modules/puterai/FakeChatService.js deleted file mode 100644 index 873be15e..00000000 --- a/src/backend/src/modules/puterai/FakeChatService.js +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const { default: dedent } = require('dedent'); -const BaseService = require('../../services/BaseService'); -/** -* FakeChatService - A mock implementation of a chat service that extends BaseService. -* Provides fake chat completion responses using Lorem Ipsum text generation. -* Used for testing and development purposes when a real chat service is not needed. -* Implements the 'puter-chat-completion' interface with list() and complete() methods. -*/ -class FakeChatService extends BaseService { - /** - * Initializes the service and registers it as a provider with AIChatService - * @private - * @returns {Promise} - */ - async _init () { - const svc_aiChat = this.services.get('ai-chat'); - svc_aiChat.register_provider({ - service_name: this.service_name, - alias: true, - }); - } - - get_default_model () { - return 'fake'; - } - static IMPLEMENTS = { - ['puter-chat-completion']: { - /** - * Returns a list of available models with their details - * @returns {Promise} Array of model details including costs - * @description Returns detailed information about available models including - * their costs for input and output tokens - */ - async models () { - return [ - { - id: 'fake', - aliases: [], - cost: { - input: 0, - output: 0, - }, - }, - { - id: 'costly', - aliases: [], - cost: { - input: 1000, // 1000 microcents per million tokens (0.001 cents per 1000 tokens) - output: 2000, // 2000 microcents per million tokens (0.002 cents per 1000 tokens) - }, - max_tokens: 8192, - }, - { - id: 'abuse', - aliases: [], - cost: { - input: 0, - output: 0, - }, - }, - ]; - }, - - /** - * Returns a list of available model names including their aliases - * @returns {Promise} Array of model identifiers and their aliases - * @description Retrieves all available model IDs and their aliases, - * flattening them into a single array of strings that can be used for model selection - */ - async list () { - return ['fake', 'costly', 'abuse']; - }, - - /** - * Simulates a chat completion request by generating random Lorem Ipsum text - * @param {Object} params - The completion parameters - * @param {Array} params.messages - Array of chat messages - * @param {boolean} params.stream - Whether to stream the response (unused in fake implementation) - * @param {string} params.model - The model to use ('fake', 'costly', or 'abuse') - * @returns {Object} A simulated chat completion response with Lorem Ipsum content - */ - async complete ({ messages, stream, model, max_tokens, custom }) { - const { LoremIpsum } = require('lorem-ipsum'); - const li = new LoremIpsum({ - sentencesPerParagraph: { - max: 8, - min: 4, - }, - wordsPerSentence: { - max: 20, - min: 12, - }, - }); - - // Determine token counts based on messages and model - const usedModel = model || this.get_default_model(); - - // For the costly model, simulate actual token counting - const resp = this.get_response({ li, usedModel, custom, max_tokens, messages }); - - if ( stream ) { - return { - stream: true, - init_chat_stream: async ({ chatStream }) => { - await new Promise(rslv => setTimeout(rslv, 500)); - chatStream.stream.write(`${JSON.stringify({ - type: 'text', - text: resp.message.content[0].text, - }) }\n`); - chatStream.end(); - }, - }; - } - - return resp; - }, - }, - }; - - get_response ({ li, usedModel, messages, custom, max_tokens }) { - let inputTokens = 0; - let outputTokens = 0; - - if ( usedModel === 'costly' ) { - // Simple token estimation: roughly 4 chars per token for input - if ( messages && messages.length > 0 ) { - for ( const message of messages ) { - if ( typeof message.content === 'string' ) { - inputTokens += Math.ceil(message.content.length / 4); - } else if ( Array.isArray(message.content) ) { - for ( const content of message.content ) { - if ( content.type === 'text' ) { - inputTokens += Math.ceil(content.text.length / 4); - } - } - } - } - } - - // Generate random output token count between 50 and 200 - outputTokens = Math.floor(Math.min((Math.random() * 150) + 50, max_tokens)); - // outputTokens = Math.floor(Math.random() * 150) + 50; - } - - // Generate the response text - let responseText; - if ( usedModel === 'abuse' ) { - // responseText = dedent(` - // This is a message from ${ - // this.global_config.origin}. We have detected abuse of our services. - - // If you are seeing this on another website, please report it to ${ - // this.global_config.abuse_email ?? 'hi@puter.com'} - // `); - responseText = dedent(` -

Free AI and Cloud for everyone!


- Come on down to puter.com and try it out! - ${custom ?? ''} - `); - } else { - // Generate 1-3 paragraphs for both fake and costly models - responseText = li.generateParagraphs(Math.floor(Math.random() * 3) + 1); - } - - // Report usage based on model - const usage = { - 'input_tokens': usedModel === 'costly' ? inputTokens : 0, - 'output_tokens': usedModel === 'costly' ? outputTokens : 1, - }; - - return { - 'index': 0, - message: { - 'id': '00000000-0000-0000-0000-000000000000', - 'type': 'message', - 'role': 'assistant', - 'model': usedModel, - 'content': [ - { - 'type': 'text', - 'text': responseText, - }, - ], - 'stop_reason': 'end_turn', - 'stop_sequence': null, - 'usage': usage, - }, - 'usage': usage, - 'logprobs': null, - 'finish_reason': 'stop', - }; - } -} - -module.exports = { - FakeChatService, -}; diff --git a/src/backend/src/modules/puterai/GeminiService/GeminiService.mjs b/src/backend/src/modules/puterai/GeminiService/GeminiService.mjs deleted file mode 100644 index 179019c8..00000000 --- a/src/backend/src/modules/puterai/GeminiService/GeminiService.mjs +++ /dev/null @@ -1,114 +0,0 @@ -// Preamble: Before this we used Gemini's SDK directly and as we found out -// its actually kind of terrible. So we use the openai sdk now -import BaseService from '../../../services/BaseService.js'; -import openai from 'openai'; -import OpenAIUtil from '../lib/OpenAIUtil.js'; -import { Context } from '../../../util/context.js'; -import { models } from './models.mjs'; - - -export class GeminiService extends BaseService { - /** - * @type {import('../../services/MeteringService/MeteringService').MeteringService} - */ - meteringService = undefined; - - defaultModel = 'gemini-2.5-flash'; - - static IMPLEMENTS = { - ['puter-chat-completion']: { - async models () { - return await this.models(); - }, - async complete (...args) { - return await this.complete(...args); - }, - async list () { - return await this.list(); - }, - }, - }; - - async _init () { - this.openai = new openai.OpenAI({ - apiKey: this.config.apiKey, - baseURL: 'https://generativelanguage.googleapis.com/v1beta/openai/', - }); - - const svc_aiChat = this.services.get('ai-chat'); - svc_aiChat.register_provider({ - service_name: this.service_name, - alias: true, - }); - this.meteringService = this.services.get('meteringService').meteringService; - } - - get_default_model () { - return this.defaultModel; - } - - async models () { - return models; - } - async list () { - const model_names = []; - for ( const model of models ) { - model_names.push(model.id); - if ( model.aliases ) { - model_names.push(...model.aliases); - } - } - return model_names; - } - async complete ({ messages, stream, model, tools, max_tokens, temperature }) { - const actor = Context.get('actor'); - messages = await OpenAIUtil.process_input_messages(messages); - - // delete cache_control - messages = messages.map(m => { - delete m.cache_control; - return m; - }); - - const sdk_params = { - messages: messages, - model: model, - ...(tools ? { tools } : {}), - ...(max_tokens ? { max_completion_tokens: max_tokens } : {}), - ...(temperature ? { temperature } : {}), - stream, - ...(stream ? { - stream_options: { include_usage: true }, - } : {}), - }; - - let completion; - try { - completion = await this.openai.chat.completions.create(sdk_params); - } catch (e) { - console.error('Gemini completion error: ', e); - throw e; - } - - const modelDetails = (await this.models()).find(m => m.id === model); - return OpenAIUtil.handle_completion_output({ - usage_calculator: ({ usage }) => { - const trackedUsage = { - prompt_tokens: (usage.prompt_tokens ?? 0) - (usage.prompt_tokens_details?.cached_tokens ?? 0), - completion_tokens: usage.completion_tokens ?? 0, - cached_tokens: usage.prompt_tokens_details?.cached_tokens ?? 0, - }; - - this.meteringService.utilRecordUsageObject(trackedUsage, actor, `gemini:${modelDetails.id}`); - const legacyCostCalculator = OpenAIUtil.create_usage_calculator({ - model_details: modelDetails, - }); - - return legacyCostCalculator({ usage }); - }, - stream, - completion, - }); - - } -} diff --git a/src/backend/src/modules/puterai/GeminiService/models.mjs b/src/backend/src/modules/puterai/GeminiService/models.mjs deleted file mode 100644 index a918a23a..00000000 --- a/src/backend/src/modules/puterai/GeminiService/models.mjs +++ /dev/null @@ -1,86 +0,0 @@ -export const models = [ - { - id: 'gemini-1.5-flash', - name: 'Gemini 1.5 Flash', - context: 131072, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 7.5, - output: 30, - }, - max_tokens: 8192, - }, - { - id: 'gemini-2.0-flash', - name: 'Gemini 2.0 Flash', - context: 131072, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 10, - output: 40, - }, - max_tokens: 8192, - }, - { - id: 'gemini-2.0-flash-lite', - name: 'Gemini 2.0 Flash-Lite', - context: 1_048_576, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 8, - output: 32, - }, - max_tokens: 8192, - }, - { - id: 'gemini-2.5-flash', - name: 'Gemini 2.5 Flash', - context: 1_048_576, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 12, - output: 48, - }, - max_tokens: 65536, - }, - { - id: 'gemini-2.5-flash-lite', - name: 'Gemini 2.5 Flash-Lite', - context: 1_048_576, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 10, - output: 40, - }, - max_tokens: 65536, - }, - { - id: 'gemini-2.5-pro', - name: 'Gemini 2.5 Pro', - context: 1_048_576, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 15, - output: 60, - }, - max_tokens: 65536, - }, - { - id: 'gemini-3-pro-preview', - name: 'Gemini 3 Pro', - context: 1_048_576, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 25, - output: 100, - }, - max_tokens: 65536, - }, -]; \ No newline at end of file diff --git a/src/backend/src/modules/puterai/GroqAIService.js b/src/backend/src/modules/puterai/GroqAIService.js deleted file mode 100644 index ec1701cf..00000000 --- a/src/backend/src/modules/puterai/GroqAIService.js +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const BaseService = require('../../services/BaseService'); -const { Context } = require('../../util/context'); -const OpenAIUtil = require('./lib/OpenAIUtil'); - -/** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ - -/** -* Service class for integrating with Groq AI's language models. -* Extends BaseService to provide chat completion capabilities through the Groq API. -* Implements the puter-chat-completion interface for model management and text generation. -* Supports both streaming and non-streaming responses, handles multiple models including -* various versions of Llama, Mixtral, and Gemma, and manages usage tracking. -* @class GroqAIService -* @extends BaseService -*/ -class GroqAIService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ - meteringService; - static MODULES = { - Groq: require('groq-sdk'), - }; - - /** - * Initializes the GroqAI service by setting up the Groq client and registering with the AI chat provider - * @returns {Promise} - * @private - */ - async _init () { - const Groq = require('groq-sdk'); - this.client = new Groq({ - apiKey: this.config.apiKey, - }); - - const svc_aiChat = this.services.get('ai-chat'); - svc_aiChat.register_provider({ - service_name: this.service_name, - alias: true, - }); - this.meteringService = this.services.get('meteringService').meteringService; // TODO DS: move to proper extensions - } - - /** - * Returns the default model ID for the Groq AI service - * @returns {string} The default model ID 'llama-3.1-8b-instant' - */ - get_default_model () { - return 'llama-3.1-8b-instant'; - } - - static IMPLEMENTS = { - 'puter-chat-completion': { - /** - * Returns a list of available models and their details. - * See AIChatService for more information. - * - * @returns Promise> Array of model details - */ - async models () { - return await this.models_(); - }, - /** - * Returns a list of available model names including their aliases - * @returns {Promise} Array of model identifiers and their aliases - * @description Retrieves all available model IDs and their aliases, - * flattening them into a single array of strings that can be used for model selection - */ - async list () { - // They send: { "object": "list", data } - const funny_wrapper = await this.client.models.list(); - return funny_wrapper.data; - }, - /** - * Completes a chat interaction using the Groq API - * @param {Object} options - The completion options - * @param {Array} options.messages - Array of message objects containing the conversation history - * @param {string} [options.model] - The model ID to use for completion. Defaults to service's default model - * @param {boolean} [options.stream] - Whether to stream the response - * @returns {TypedValue|Object} Returns either a TypedValue with streaming response or completion object with usage stats - */ - async complete ({ messages, model, stream, tools, max_tokens, temperature }) { - model = model ?? this.get_default_model(); - - messages = await OpenAIUtil.process_input_messages(messages); - for ( const message of messages ) { - // Curiously, DeepSeek has the exact same deviation - if ( message.tool_calls && Array.isArray(message.content) ) { - message.content = ''; - } - } - - const actor = Context.get('actor'); - - const completion = await this.client.chat.completions.create({ - messages, - model, - stream, - tools, - max_completion_tokens: max_tokens, // max_tokens has been deprecated - temperature, - }); - - const modelDetails = (await this.models_()).find(m => m.id === model); - - return OpenAIUtil.handle_completion_output({ - deviations: { - index_usage_from_stream_chunk: chunk => - chunk.x_groq?.usage, - }, - usage_calculator: ({ usage }) => { - const trackedUsage = OpenAIUtil.extractMeteredUsage(usage); - this.meteringService.utilRecordUsageObject(trackedUsage, actor, `groq:${modelDetails.id}`); - // Still return legacy cost calculation for compatibility - const legacyCostCalculator = OpenAIUtil.create_usage_calculator({ - model_details: modelDetails, - }); - return legacyCostCalculator({ usage }); - }, - stream, - completion, - }); - }, - }, - }; - - /** - * Returns an array of available AI models with their specifications - * - * Each model object contains: - * - id: Unique identifier for the model - * - name: Human-readable name - * - context: Maximum context window size in tokens - * - cost: Pricing details including currency and token rates - * - * @returns {Array} Array of model specification objects - */ - models_ () { - return [ - { - id: 'gemma2-9b-it', - name: 'Gemma 2 9B 8k', - context: 8192, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 20, - output: 20, - }, - max_tokens: 8192, - }, - { - id: 'gemma-7b-it', - name: 'Gemma 7B 8k Instruct', - context: 8192, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 7, - output: 7, - }, - }, - { - id: 'llama3-groq-70b-8192-tool-use-preview', - name: 'Llama 3 Groq 70B Tool Use Preview 8k', - context: 8192, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 89, - output: 89, - }, - }, - { - id: 'llama3-groq-8b-8192-tool-use-preview', - name: 'Llama 3 Groq 8B Tool Use Preview 8k', - context: 8192, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 19, - output: 19, - }, - }, - { - 'id': 'llama-3.1-70b-versatile', - 'name': 'Llama 3.1 70B Versatile 128k', - 'context': 128000, - 'cost': { - 'currency': 'usd-cents', - 'tokens': 1000000, - 'input': 59, - 'output': 79, - }, - }, - { - // This was only available on their Discord, not - // on the pricing page. - 'id': 'llama-3.1-70b-specdec', - 'name': 'Llama 3.1 8B Instant 128k', - 'context': 128000, - 'cost': { - 'currency': 'usd-cents', - 'tokens': 1000000, - 'input': 59, - 'output': 99, - }, - }, - { - 'id': 'llama-3.1-8b-instant', - 'name': 'Llama 3.1 8B Instant 128k', - 'context': 131072, - 'cost': { - 'currency': 'usd-cents', - 'tokens': 1000000, - 'input': 5, - 'output': 8, - }, - max_tokens: 131072, - }, - { - id: 'meta-llama/llama-guard-4-12b', - name: 'Llama Guard 4 12B', - context: 131072, - cost: { - currency: 'usd-cents', - tokens: 1000000, - input: 20, - output: 20, - }, - max_tokens: 1024, - }, - { - id: 'meta-llama/llama-prompt-guard-2-86m', - name: 'Prompt Guard 2 86M', - context: 512, - cost: { - currency: 'usd-cents', - tokens: 1000000, - input: 4, - output: 4, - }, - max_tokens: 512, - }, - { - 'id': 'llama-3.2-1b-preview', - 'name': 'Llama 3.2 1B (Preview) 8k', - 'context': 128000, - 'cost': { - 'currency': 'usd-cents', - 'tokens': 1000000, - 'input': 4, - 'output': 4, - }, - }, - { - 'id': 'llama-3.2-3b-preview', - 'name': 'Llama 3.2 3B (Preview) 8k', - 'context': 128000, - 'cost': { - 'currency': 'usd-cents', - 'tokens': 1000000, - 'input': 6, - 'output': 6, - }, - }, - { - id: 'llama-3.2-11b-vision-preview', - name: 'Llama 3.2 11B Vision 8k (Preview)', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 18, - output: 18, - }, - }, - { - id: 'llama-3.2-90b-vision-preview', - name: 'Llama 3.2 90B Vision 8k (Preview)', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 90, - output: 90, - }, - }, - { - 'id': 'llama3-70b-8192', - 'name': 'Llama 3 70B 8k', - 'context': 8192, - 'cost': { - 'currency': 'usd-cents', - 'tokens': 1000000, - 'input': 59, - 'output': 79, - }, - }, - { - 'id': 'llama3-8b-8192', - 'name': 'Llama 3 8B 8k', - 'context': 8192, - 'cost': { - 'currency': 'usd-cents', - 'tokens': 1000000, - 'input': 5, - 'output': 8, - }, - }, - { - 'id': 'mixtral-8x7b-32768', - 'name': 'Mixtral 8x7B Instruct 32k', - 'context': 32768, - 'cost': { - 'currency': 'usd-cents', - 'tokens': 1000000, - 'input': 24, - 'output': 24, - }, - }, - { - 'id': 'llama-guard-3-8b', - 'name': 'Llama Guard 3 8B 8k', - 'context': 8192, - 'cost': { - 'currency': 'usd-cents', - 'tokens': 1000000, - 'input': 20, - 'output': 20, - }, - }, - ]; - } -} - -module.exports = { - GroqAIService, -}; diff --git a/src/backend/src/modules/puterai/MistralAIService.js b/src/backend/src/modules/puterai/MistralAIService.js deleted file mode 100644 index 1047f3da..00000000 --- a/src/backend/src/modules/puterai/MistralAIService.js +++ /dev/null @@ -1,621 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const BaseService = require('../../services/BaseService'); -const axios = require('axios'); -const OpenAIUtil = require('./lib/OpenAIUtil'); -const { Context } = require('../../util/context'); -const APIError = require('../../api/APIError'); -const mime = require('mime-types'); -const path = require('path'); - -/** -* MistralAIService class extends BaseService to provide integration with the Mistral AI API. -* Implements chat completion functionality with support for various Mistral models including -* mistral-large, pixtral, codestral, and ministral variants. Handles both streaming and -* non-streaming responses, token usage tracking, and model management. Provides cost information -* for different models and implements the puter-chat-completion interface. -*/ -class MistralAIService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ - meteringService; - static MODULES = { - '@mistralai/mistralai': require('@mistralai/mistralai'), - }; - /** - * Initializes the service's cost structure for different Mistral AI models. - * Sets up pricing information for various models including token costs for input/output. - * Each model entry specifies currency (usd-cents) and costs per million tokens. - * @private - */ - _construct () { - this.costs_ = { - 'mistral-large-latest': { - aliases: ['mistral-large-2411'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 200, - output: 600, - }, - max_tokens: 128000, - }, - 'pixtral-large-latest': { - aliases: ['pixtral-large-2411'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 200, - output: 600, - }, - max_tokens: 128000, - }, - 'mistral-small-latest': { - aliases: ['mistral-small-2506'], - license: 'Apache-2.0', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 20, - output: 60, - }, - max_tokens: 128000, - }, - 'codestral-latest': { - aliases: ['codestral-2501'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 30, - output: 90, - }, - max_tokens: 256000, - }, - 'ministral-8b-latest': { - aliases: ['ministral-8b-2410'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 10, - output: 10, - }, - max_tokens: 128000, - }, - 'ministral-3b-latest': { - aliases: ['ministral-3b-2410'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 4, - output: 4, - }, - max_tokens: 128000, - }, - 'pixtral-12b': { - aliases: ['pixtral-12b-2409'], - license: 'Apache-2.0', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 15, - output: 15, - }, - max_tokens: 128000, - }, - 'mistral-nemo': { - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 15, - output: 15, - }, - }, - 'open-mistral-7b': { - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 25, - output: 25, - }, - }, - 'open-mixtral-8x7b': { - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 7, - output: 7, - }, - }, - 'open-mixtral-8x22b': { - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 2, - output: 6, - }, - }, - 'magistral-medium-latest': { - aliases: ['magistral-medium-2506'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 200, - output: 500, - }, - max_tokens: 40000, - }, - 'magistral-small-latest': { - aliases: ['magistral-small-2506'], - license: 'Apache-2.0', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 10, - output: 10, - }, - max_tokens: 40000, - }, - 'mistral-medium-latest': { - aliases: ['mistral-medium-2505'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 40, - output: 200, - }, - max_tokens: 128000, - }, - 'mistral-moderation-latest': { - aliases: ['mistral-moderation-2411'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 10, - output: 10, - }, - max_tokens: 8000, - }, - 'devstral-small-latest': { - aliases: ['devstral-small-2505'], - license: 'Apache-2.0', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 10, - output: 10, - }, - max_tokens: 128000, - }, - 'mistral-saba-latest': { - aliases: ['mistral-saba-2502'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 20, - output: 60, - }, - }, - 'open-mistral-nemo': { - aliases: ['open-mistral-nemo-2407'], - license: 'Apache-2.0', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 10, - output: 10, - }, - }, - 'mistral-ocr-latest': { - aliases: ['mistral-ocr-2505'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 100, - output: 300, - }, - }, - }; - } - /** - * Initializes the service's cost structure for different Mistral AI models. - * Sets up pricing information for various models including token costs for input/output. - * Each model entry specifies currency (USD cents) and costs per million tokens. - * @private - */ - async _init () { - const require = this.require; - const { Mistral } = require('@mistralai/mistralai'); - this.api_base_url = 'https://api.mistral.ai/v1'; - this.client = new Mistral({ - apiKey: this.config.apiKey, - }); - - const svc_aiChat = this.services.get('ai-chat'); - svc_aiChat.register_provider({ - service_name: this.service_name, - alias: true, - }); - - this.meteringService = this.services.get('meteringService').meteringService; - - // TODO: make this event-driven so it doesn't hold up boot - await this.populate_models_(); - } - /** - * Populates the internal models array with available Mistral AI models and their configurations. - * Makes an API call to fetch model data, then processes and filters models based on cost information. - * Each model entry includes id, name, aliases, context window size, capabilities, and pricing. - * @private - * @returns {Promise} - */ - async populate_models_ () { - const resp = await axios({ - method: 'get', - url: `${this.api_base_url }/models`, - headers: { - Authorization: `Bearer ${this.config.apiKey}`, - }, - }); - - const response_json = resp.data; - const models = response_json.data; - this.models_array_ = []; - for ( const api_model of models ) { - - let cost = this.costs_[api_model.id]; - if ( ! cost ) { - for ( const alias of api_model.aliases ) { - cost = this.costs_[alias]; - if ( cost ) break; - } - } - if ( ! cost ) continue; - const model = { - ...cost, - id: api_model.id, - name: api_model.description, - aliases: api_model.aliases, - context: api_model.max_context_length, - capabilities: api_model.capabilities, - vision: api_model.capabilities.vision, - }; - - this.models_array_.push(model); - } - // return resp.data; - } - /** - * Populates the internal models array with available Mistral AI models and their metadata - * Fetches model data from the API, filters based on cost configuration, and stores - * model objects containing ID, name, aliases, context length, capabilities, and pricing - * @private - * @async - * @returns {void} - */ - get_default_model () { - return 'mistral-large-latest'; - } - static IMPLEMENTS = { - 'driver-capabilities': { - supports_test_mode (iface, method_name) { - return iface === 'puter-ocr' && method_name === 'recognize'; - }, - }, - 'puter-ocr': { - async recognize ({ - source, - model, - pages, - includeImageBase64, - imageLimit, - imageMinSize, - bboxAnnotationFormat, - documentAnnotationFormat, - test_mode, - }) { - if ( test_mode ) { - return this._sampleOcrResponse(); - } - if ( ! source ) { - throw APIError.create('missing_required_argument', { - interface_name: 'puter-ocr', - method_name: 'recognize', - arg_name: 'source', - }); - } - - const document = await this._buildDocumentChunkFromSource(source); - const payload = { - model: model ?? 'mistral-ocr-latest', - document, - }; - if ( Array.isArray(pages) ) { - payload.pages = pages; - } - if ( typeof includeImageBase64 === 'boolean' ) { - payload.includeImageBase64 = includeImageBase64; - } - if ( typeof imageLimit === 'number' ) { - payload.imageLimit = imageLimit; - } - if ( typeof imageMinSize === 'number' ) { - payload.imageMinSize = imageMinSize; - } - if ( bboxAnnotationFormat !== undefined ) { - payload.bboxAnnotationFormat = bboxAnnotationFormat; - } - if ( documentAnnotationFormat !== undefined ) { - payload.documentAnnotationFormat = documentAnnotationFormat; - } - - const response = await this.client.ocr.process(payload); - const annotationsRequested = ( - payload.documentAnnotationFormat !== undefined || - payload.bboxAnnotationFormat !== undefined - ); - this._recordOcrUsage(response, payload.model, { - annotationsRequested, - }); - return this._normalizeOcrResponse(response); - }, - }, - 'puter-chat-completion': { - /** - * Returns a list of available models and their details. - * See AIChatService for more information. - * - * @returns Promise> Array of model details - */ - async models () { - return this.models_array_; - }, - - /** - * Returns a list of available model names including their aliases - * @returns {Promise} Array of model identifiers and their aliases - * @description Retrieves all available model IDs and their aliases, - * flattening them into a single array of strings that can be used for model selection - */ - async list () { - return this.models_array_.map(m => m.id); - }, - - /** - * AI Chat completion method. - * See AIChatService for more details. - */ - async complete ({ messages, stream, model, tools, max_tokens, temperature }) { - - messages = await OpenAIUtil.process_input_messages(messages); - for ( const message of messages ) { - if ( message.tool_calls ) { - message.toolCalls = message.tool_calls; - delete message.tool_calls; - } - if ( message.tool_call_id ) { - message.toolCallId = message.tool_call_id; - delete message.tool_call_id; - } - } - - console.log('MESSAGES TO MISTRAL', messages); - - const actor = Context.get('actor'); - const completion = await this.client.chat[ - stream ? 'stream' : 'complete' - ]({ - model: model ?? this.get_default_model(), - ...(tools ? { tools } : {}), - messages, - max_tokens: max_tokens, - temperature, - }); - - const modelDetails = this.models_array_.find(m => m.id === (model ?? this.get_default_model())); - - return await OpenAIUtil.handle_completion_output({ - deviations: { - index_usage_from_stream_chunk: chunk => { - if ( ! chunk.usage ) return; - - const snake_usage = {}; - for ( const key in chunk.usage ) { - const snakeKey = key.replace(/([A-Z])/g, '_$1').toLowerCase(); - snake_usage[snakeKey] = chunk.usage[key]; - } - - return snake_usage; - }, - chunk_but_like_actually: chunk => chunk.data, - index_tool_calls_from_stream_choice: choice => choice.delta.toolCalls, - coerce_completion_usage: completion => ({ - prompt_tokens: completion.usage.promptTokens, - completion_tokens: completion.usage.completionTokens, - }), - }, - completion, - stream, - usage_calculator: ({ usage }) => { - const trackedUsage = OpenAIUtil.extractMeteredUsage(usage); - this.meteringService.utilRecordUsageObject(trackedUsage, actor, `mistral:${modelDetails.id}`); - // Still return legacy cost calculation for compatibility - const legacyCostCalculator = OpenAIUtil.create_usage_calculator({ - model_details: modelDetails, - }); - return legacyCostCalculator({ usage }); - }, - }); - }, - }, - }; - - async _buildDocumentChunkFromSource (fileFacade) { - const dataUrl = await this._safeFileValue(fileFacade, 'data_url'); - const webUrl = await this._safeFileValue(fileFacade, 'web_url'); - const filePath = await this._safeFileValue(fileFacade, 'path'); - const fsNode = await this._safeFileValue(fileFacade, 'fs-node'); - const fileName = filePath ? path.basename(filePath) : fsNode?.name; - const inferredMime = this._inferMimeFromName(fileName); - - if ( webUrl ) { - return this._chunkFromUrl(webUrl, fileName, inferredMime); - } - if ( dataUrl ) { - const mimeFromUrl = this._extractMimeFromDataUrl(dataUrl) ?? inferredMime; - return this._chunkFromUrl(dataUrl, fileName, mimeFromUrl); - } - - const buffer = await this._safeFileValue(fileFacade, 'buffer'); - if ( ! buffer ) { - throw APIError.create('field_invalid', null, { - key: 'source', - expected: 'file, data URL, or web URL', - }); - } - const mimeType = inferredMime ?? 'application/octet-stream'; - const generatedDataUrl = this._createDataUrl(buffer, mimeType); - return this._chunkFromUrl(generatedDataUrl, fileName, mimeType); - } - - async _safeFileValue (fileFacade, key) { - if ( !fileFacade || typeof fileFacade.get !== 'function' ) return undefined; - const maybeCache = fileFacade.values?.values; - if ( maybeCache && Object.prototype.hasOwnProperty.call(maybeCache, key) ) { - return maybeCache[key]; - } - try { - return await fileFacade.get(key); - } catch (e) { - return undefined; - } - } - - _chunkFromUrl (url, fileName, mimeType) { - const lowerName = fileName?.toLowerCase(); - const urlLooksPdf = /\.pdf($|\?)/i.test(url); - const mimeLooksPdf = mimeType?.includes('pdf'); - const isPdf = mimeLooksPdf || urlLooksPdf || (lowerName ? lowerName.endsWith('.pdf') : false); - - if ( isPdf ) { - const chunk = { - type: 'document_url', - documentUrl: url, - }; - if ( fileName ) { - chunk.documentName = fileName; - } - return chunk; - } - - return { - type: 'image_url', - imageUrl: { - url, - }, - }; - } - - _inferMimeFromName (name) { - if ( ! name ) return undefined; - return mime.lookup(name) || undefined; - } - - _extractMimeFromDataUrl (url) { - if ( typeof url !== 'string' ) return undefined; - const match = url.match(/^data:([^;,]+)[;,]/); - return match ? match[1] : undefined; - } - - _createDataUrl (buffer, mimeType) { - return `data:${mimeType || 'application/octet-stream'};base64,${buffer.toString('base64')}`; - } - - _normalizeOcrResponse (response) { - if ( ! response ) return {}; - const normalized = { - model: response.model, - pages: response.pages ?? [], - usage_info: response.usageInfo, - }; - const blocks = []; - if ( Array.isArray(response.pages) ) { - for ( const page of response.pages ) { - if ( typeof page?.markdown !== 'string' ) continue; - const lines = page.markdown.split('\n').map(line => line.trim()).filter(Boolean); - for ( const line of lines ) { - blocks.push({ - type: 'text/mistral:LINE', - text: line, - page: page.index, - }); - } - } - } - normalized.blocks = blocks; - if ( blocks.length ) { - normalized.text = blocks.map(block => block.text).join('\n'); - } else if ( Array.isArray(response.pages) ) { - normalized.text = response.pages.map(page => page?.markdown || '').join('\n\n').trim(); - } - return normalized; - } - - _recordOcrUsage (response, model, { annotationsRequested } = {}) { - try { - if ( ! this.meteringService ) return; - const actor = Context.get('actor'); - if ( ! actor ) return; - const pagesProcessed = - response?.usageInfo?.pagesProcessed ?? - (Array.isArray(response?.pages) ? response.pages.length : 1); - this.meteringService.incrementUsage(actor, 'mistral-ocr:ocr:page', pagesProcessed); - if ( annotationsRequested ) { - this.meteringService.incrementUsage(actor, 'mistral-ocr:annotations:page', pagesProcessed); - } - } catch (e) { - // ignore metering failures to avoid blocking OCR results - } - } - - _sampleOcrResponse () { - const markdown = 'Sample OCR output (test mode).'; - return { - model: 'mistral-ocr-latest', - pages: [ - { - index: 0, - markdown, - images: [], - dimensions: null, - }, - ], - blocks: [ - { - type: 'text/mistral:LINE', - text: markdown, - page: 0, - }, - ], - text: markdown, - }; - } -} - -module.exports = { MistralAIService }; diff --git a/src/backend/src/modules/puterai/OllamaService.js b/src/backend/src/modules/puterai/OllamaService.js deleted file mode 100644 index f2985c6f..00000000 --- a/src/backend/src/modules/puterai/OllamaService.js +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const BaseService = require('../../services/BaseService'); -const OpenAIUtil = require('./lib/OpenAIUtil'); -const { Context } = require('../../util/context'); -const openai = require('openai'); -const uuidv4 = require('uuid').v4; -const axios = require('axios'); -/** -* OllamaService class - Provides integration with Ollama's API for chat completions -* Extends BaseService to implement the puter-chat-completion interface. -* Handles model management, message adaptation, streaming responses, -* and usage tracking for Ollama's language models. -* @extends BaseService -*/ -class OllamaService extends BaseService { - static MODULES = { - kv: globalThis.kv, - }; - - /** - * Gets the system prompt used for AI interactions - * @returns {string} The base system prompt that identifies the AI as running on Puter - */ - adapt_model (model) { - return model; - } - - /** - * Initializes the Ollama service by setting up the Ollama client and registering with the AI chat provider - * @private - * @returns {Promise} Resolves when initialization is complete - */ - async _init () { - // Ollama typically runs on HTTP, not HTTPS - this.api_base_url = this.config?.api_base_url || 'http://localhost:11434'; - - // OpenAI SDK is used to interact with the Ollama API - this.openai = new openai.OpenAI({ - apiKey: 'ollama', // Ollama doesn't use an API key, it uses the "ollama" string - baseURL: `${this.api_base_url }/v1`, - }); - this.kvkey = uuidv4(); - - const svc_aiChat = this.services.get('ai-chat'); - svc_aiChat.register_provider({ - service_name: this.service_name, - alias: true, - }); - // We don't need to meter usage for Ollama because it's a local service - } - - /** - * Returns the default model identifier for the Ollama service - * @returns {string} The default model ID 'gpt-oss:20b' - */ - get_default_model () { - return 'gpt-oss:20b'; - } - - static IMPLEMENTS = { - 'puter-chat-completion': { - /** - * Returns a list of available models and their details. - * See AIChatService for more information. - * - * @returns Promise> Array of model details - */ - async models () { - return await this.models_(); - }, - /** - * Returns a list of available model names including their aliases - * @returns {Promise} Array of model identifiers and their aliases - * @description Retrieves all available model IDs and their aliases, - * flattening them into a single array of strings that can be used for model selection - */ - async list () { - const models = await this.models_(); - const model_names = []; - for ( const model of models ) { - model_names.push(model.id); - } - return model_names; - }, - - /** - * AI Chat completion method. - * See AIChatService for more details. - */ - async complete ({ messages, stream, model, tools, max_tokens, temperature }) { - model = this.adapt_model(model); - - if ( model.startsWith('ollama:') ) { - model = model.slice('ollama:'.length); - } - - const actor = Context.get('actor'); - - messages = await OpenAIUtil.process_input_messages(messages); - const sdk_params = { - messages, - model: model ?? this.get_default_model(), - ...(tools ? { tools } : {}), - max_tokens, - temperature: temperature, // default to 1.0 - stream, - ...(stream ? { - stream_options: { include_usage: true }, - } : {}), - }; - - const completion = await this.openai.chat.completions.create(sdk_params); - - const modelDetails = (await this.models_()).find(m => m.id === `ollama:${model}`); - return OpenAIUtil.handle_completion_output({ - usage_calculator: ({ usage }) => { - - const trackedUsage = { - prompt: (usage.prompt_tokens ?? 1 ) - (usage.prompt_tokens_details?.cached_tokens ?? 0), - completion: usage.completion_tokens ?? 1, - input_cache_read: usage.prompt_tokens_details?.cached_tokens ?? 0, - }; - const costOverwrites = Object.fromEntries(Object.keys(trackedUsage).map((k) => { - return [k, 0]; // override to 0 since local is free - })); - this.meteringService.utilRecordUsageObject(trackedUsage, actor, modelDetails.id, { costOverwrites }); - const legacyCostCalculator = OpenAIUtil.create_usage_calculator({ - model_details: modelDetails, - }); - return legacyCostCalculator({ usage }); - }, - stream, - completion, - }); - }, - }, - }; - - /** - * Retrieves available AI models and their specifications - * @returns Array of model objects containing: - * - id: Model identifier string - * - name: Human readable model name - * - context: Maximum context window size - * - cost: Pricing information object with currency and rates - * @private - */ - async models_ (_rawPriceKeys = false) { - - let models = this.modules.kv.get(`${this.kvkey}:models`); - if ( ! models ) { - try { - const resp = await axios.request({ - method: 'GET', - url: `${this.api_base_url}/api/tags`, - }); - models = resp.data.models || []; - if ( models.length > 0 ) { - this.modules.kv.set(`${this.kvkey}:models`, models); - } - } catch ( error ) { - this.log.error('Failed to fetch models from Ollama:', error.message); - // Return empty array if Ollama is not available - return []; - } - } - - if ( !models || models.length === 0 ) { - return []; - } - - const coerced_models = []; - for ( const model of models ) { - // Ollama API returns models with 'name' property, not 'model' - const modelName = model.name || model.model || 'unknown'; - const microcentCosts = { - input: 0, - output: 0, - }; - coerced_models.push({ - id: `ollama:${ modelName}`, - name: `${modelName} (Ollama)`, - max_tokens: model.size || model.max_context || 8192, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - ...microcentCosts, - }, - }); - } - console.log('coerced_models', coerced_models); - return coerced_models; - } -} - -module.exports = { - OllamaService, -}; diff --git a/src/backend/src/modules/puterai/OpenAiCompletionService/index.mjs b/src/backend/src/modules/puterai/OpenAiCompletionService/index.mjs deleted file mode 100644 index 2f6f8c3b..00000000 --- a/src/backend/src/modules/puterai/OpenAiCompletionService/index.mjs +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} - -import BaseService from '../../../services/BaseService.js'; -import { OpenAICompletionService } from './OpenAICompletionService.mjs'; - -export class OpenAICompletionServiceWrapper extends BaseService { - /** @type {OpenAICompletionService} */ - openAICompletionService; - - _init () { - this.openAICompletionService = new OpenAICompletionService({ - serviceName: this.service_name, - config: this.config, - globalConfig: this.global_config, - aiChatService: this.services.get('ai-chat'), - meteringService: this.services.get('meteringService').meteringService, - }); - } - - async check_moderation (text) { - return await this.openAICompletionService.checkModeration(text); - } - - get_default_model () { - return this.openAICompletionService.get_default_model(); - } - - static IMPLEMENTS = { - ['puter-chat-completion']: Object.getOwnPropertyNames(OpenAICompletionService.prototype) - .filter(n => n !== 'constructor') - .reduce((acc, fn) => ({ - ...acc, - [fn]: async function (...a) { - return await this.openAICompletionService[fn](...a); - }, - }), {}), - }; -} \ No newline at end of file diff --git a/src/backend/src/modules/puterai/OpenAiCompletionService/models.mjs b/src/backend/src/modules/puterai/OpenAiCompletionService/models.mjs deleted file mode 100644 index 5de33c4b..00000000 --- a/src/backend/src/modules/puterai/OpenAiCompletionService/models.mjs +++ /dev/null @@ -1,206 +0,0 @@ -// TODO DS: centralize somewhere - -export const OPEN_AI_MODELS = [ - { - id: 'gpt-5.1', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 125, - output: 1000, - }, - max_tokens: 128000, - }, - { - id: 'gpt-5.1-codex', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 125, - output: 1000, - }, - max_tokens: 128000, - }, - { - id: 'gpt-5.1-codex-mini', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 25, - output: 200, - }, - max_tokens: 128000, - }, - { - id: 'gpt-5.1-chat-latest', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 125, - output: 1000, - }, - max_tokens: 16384, - }, - { - id: 'gpt-5-2025-08-07', - aliases: ['gpt-5'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 125, - output: 1000, - }, - max_tokens: 128000, - }, - { - id: 'gpt-5-mini-2025-08-07', - aliases: ['gpt-5-mini'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 25, - output: 200, - }, - max_tokens: 128000, - }, - { - id: 'gpt-5-nano-2025-08-07', - aliases: ['gpt-5-nano'], - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 5, - output: 40, - }, - max_tokens: 128000, - }, - { - id: 'gpt-5-chat-latest', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 125, - output: 1000, - }, - max_tokens: 16384, - }, - { - id: 'gpt-4o', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 250, - output: 1000, - }, - max_tokens: 16384, - }, - { - id: 'gpt-4o-mini', - max_tokens: 16384, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 15, - output: 60, - }, - }, - { - id: 'o1', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 1500, - output: 6000, - }, - max_tokens: 100000, - }, - { - id: 'o1-mini', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 300, - output: 1200, - }, - max_tokens: 65536, - }, - { - id: 'o1-pro', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 15000, - output: 60000, - }, - max_tokens: 100000, - }, - { - id: 'o3', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 1000, - output: 4000, - }, - max_tokens: 100000, - }, - { - id: 'o3-mini', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 110, - output: 440, - }, - max_tokens: 100000, - }, - { - id: 'o4-mini', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 110, - output: 440, - }, - max_tokens: 100000, - }, - { - id: 'gpt-4.1', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 200, - output: 800, - }, - max_tokens: 32768, - }, - { - id: 'gpt-4.1-mini', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 40, - output: 160, - }, - max_tokens: 32768, - }, - { - id: 'gpt-4.1-nano', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 10, - output: 40, - }, - max_tokens: 32768, - }, - { - id: 'gpt-4.5-preview', - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 7500, - output: 15000, - }, - }, -]; diff --git a/src/backend/src/modules/puterai/OpenRouterService.js b/src/backend/src/modules/puterai/OpenRouterService.js deleted file mode 100644 index 9db62cbc..00000000 --- a/src/backend/src/modules/puterai/OpenRouterService.js +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const APIError = require('../../api/APIError'); -const BaseService = require('../../services/BaseService'); -const OpenAIUtil = require('./lib/OpenAIUtil'); -const { Context } = require('../../util/context'); -const openai = require('openai'); -const uuidv4 = require('uuid').v4; -const axios = require('axios'); -/** -* XAIService class - Provides integration with X.AI's API for chat completions -* Extends BaseService to implement the puter-chat-completion interface. -* Handles model management, message adaptation, streaming responses, -* and usage tracking for X.AI's language models like Grok. -* @extends BaseService -*/ -class OpenRouterService extends BaseService { - static MODULES = { - kv: globalThis.kv, - }; - - // TODO DS: extract this into driver wrapper like openAiService - static IMPLEMENTS = { - ['puter-chat-completion']: { - async models () { - return await this.models(); - }, - async list () { - return await this.list(); - }, - async complete (...params) { - return await this.complete(...params); - }, - }, - }; - - /** - * Gets the system prompt used for AI interactions - * @returns {string} The base system prompt that identifies the AI as running on Puter - */ - adapt_model (model) { - return model; - } - - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ - meteringService; - - /** - * Initializes the XAI service by setting up the OpenAI client and registering with the AI chat provider - * @private - * @returns {Promise} Resolves when initialization is complete - */ - async _init () { - this.api_base_url = 'https://openrouter.ai/api/v1'; - this.openai = new openai.OpenAI({ - apiKey: this.config.apiKey, - baseURL: this.api_base_url, - }); - this.kvkey = uuidv4(); - - const svc_aiChat = this.services.get('ai-chat'); - svc_aiChat.register_provider({ - service_name: this.service_name, - alias: true, - }); - this.meteringService = this.services.get('meteringService').meteringService; // TODO DS: move to proper extensions - } - - /** - * Returns the default model identifier for the XAI service - * @returns {string} The default model ID 'grok-beta' - */ - get_default_model () { - } - /** - * Returns a list of available model names including their aliases - * @returns {Promise} Array of model identifiers and their aliases - * @description Retrieves all available model IDs and their aliases, - * flattening them into a single array of strings that can be used for model selection - */ - async list () { - const models = await this.models(); - const model_names = []; - for ( const model of models ) { - model_names.push(model.id); - } - return model_names; - } - - /** - * AI Chat completion method. - * See AIChatService for more details. - */ - async complete ({ messages, stream, model, tools, max_tokens, temperature }) { - model = this.adapt_model(model); - - if ( model.startsWith('openrouter:') ) { - model = model.slice('openrouter:'.length); - } - - if ( model === 'openrouter/auto' ) { - throw APIError.create('field_invalid', null, { - key: 'model', - expected: 'allowed model', - got: 'disallowed model', - }); - } - - const actor = Context.get('actor'); - - messages = await OpenAIUtil.process_input_messages(messages); - - const completion = await this.openai.chat.completions.create({ - messages, - model: model ?? this.get_default_model(), - ...(tools ? { tools } : {}), - max_tokens, - temperature: temperature, // default to 1.0 - stream, - ...(stream ? { - stream_options: { include_usage: true }, - } : {}), - usage: { include: true }, - }); - - const modelDetails = (await this.models()).find(m => m.id === `openrouter:${ model}`); - const rawPriceModelDetails = (await this.models(true)).find(m => m.id === `openrouter:${ model}`); - return OpenAIUtil.handle_completion_output({ - usage_calculator: ({ usage }) => { - // custom open router logic because they're pricing are weird - const trackedUsage = { - prompt: (usage.prompt_tokens ?? 0 ) - (usage.prompt_tokens_details?.cached_tokens ?? 0), - completion: usage.completion_tokens ?? 0, - input_cache_read: usage.prompt_tokens_details?.cached_tokens ?? 0, - }; - const costOverwrites = Object.fromEntries(Object.keys(trackedUsage).map((k) => { - return [k, rawPriceModelDetails.cost[k] * trackedUsage[k]]; - })); - this.meteringService.utilRecordUsageObject(trackedUsage, actor, modelDetails.id, costOverwrites); - const legacyCostCalculator = OpenAIUtil.create_usage_calculator({ - model_details: modelDetails, - }); - return legacyCostCalculator({ usage }); - }, - stream, - completion, - }); - } - - /** - * Retrieves available AI models and their specifications - * @returns Array of model objects containing: - * - id: Model identifier string - * - name: Human readable model name - * - context: Maximum context window size - * - cost: Pricing information object with currency and rates - */ - async models (rawPriceKeys = false) { - let models = this.modules.kv.get(`${this.kvkey}:models`); - if ( ! models ) { - try { - const resp = await axios.request({ - method: 'GET', - url: `${this.api_base_url}/models`, - }); - - models = resp.data.data; - this.modules.kv.set(`${this.kvkey}:models`, models); - } catch (e) { - console.log(e); - } - } - const coerced_models = []; - for ( const model of models ) { - const microcentCosts = rawPriceKeys ? Object.fromEntries(Object.entries(model.pricing).map(([k, v]) => [k, Math.round(v * 1_000_000 * 100)])) : { - input: Math.round(model.pricing.prompt * 1_000_000 * 100), - output: Math.round(model.pricing.completion * 1_000_000 * 100), - }; - coerced_models.push({ - id: `openrouter:${ model.id}`, - name: `${model.name } (OpenRouter)`, - max_tokens: model.top_provider.max_completion_tokens, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - ...microcentCosts, - }, - }); - } - return coerced_models; - } -} - -module.exports = { - OpenRouterService, -}; diff --git a/src/backend/src/modules/puterai/PuterAIModule.js b/src/backend/src/modules/puterai/PuterAIModule.js deleted file mode 100644 index e0dc8974..00000000 --- a/src/backend/src/modules/puterai/PuterAIModule.js +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const { AdvancedBase } = require('@heyputer/putility'); -const config = require('../../config'); - -/** -* PuterAIModule class extends AdvancedBase to manage and register various AI services. -* This module handles the initialization and registration of multiple AI-related services -* including text processing, speech synthesis, chat completion, and image generation. -* Services are conditionally registered based on configuration settings, allowing for -* flexible deployment with different AI providers like AWS, OpenAI, Claude, Together AI, -* Mistral, Groq, and XAI. -* @extends AdvancedBase -*/ -class PuterAIModule extends AdvancedBase { - /** - * Module for managing AI-related services in the Puter platform - * Extends AdvancedBase to provide core functionality - * Handles registration and configuration of various AI services like OpenAI, Claude, AWS services etc. - */ - async install (context) { - const services = context.get('services'); - - const { AIInterfaceService } = require('./AIInterfaceService'); - services.registerService('__ai-interfaces', AIInterfaceService); - - // TODO: services should govern their own availability instead of - // the module deciding what to register - - if ( config?.services?.['aws-textract']?.aws ) { - const { AWSTextractService } = require('./AWSTextractService'); - services.registerService('aws-textract', AWSTextractService); - } - - if ( config?.services?.['aws-polly']?.aws ) { - const { AWSPollyService } = require('./AWSPollyService'); - services.registerService('aws-polly', AWSPollyService); - } - - if ( config?.services?.['elevenlabs'] || config?.elevenlabs ) { - const { ElevenLabsTTSService } = require('./ElevenLabsTTSService'); - services.registerService('elevenlabs-tts', ElevenLabsTTSService); - - const { ElevenLabsVoiceChangerService } = require('./ElevenLabsVoiceChangerService'); - services.registerService('elevenlabs-voice-changer', ElevenLabsVoiceChangerService); - } - - if ( config?.services?.openai || config?.openai ) { - const { OpenAICompletionServiceWrapper } = require('./OpenAiCompletionService/index.mjs'); - services.registerService('openai-completion', OpenAICompletionServiceWrapper); - - const { OpenAIImageGenerationService } = require('./OpenAIImageGenerationService'); - services.registerService('openai-image-generation', OpenAIImageGenerationService); - - const { OpenAIVideoGenerationService } = require('./OpenAIVideoGenerationService'); - services.registerService('openai-video-generation', OpenAIVideoGenerationService); - - const { OpenAITTSService } = require('./OpenAITTSService'); - services.registerService('openai-tts', OpenAITTSService); - - const { OpenAISpeechToTextService } = require('./OpenAISpeechToTextService'); - services.registerService('openai-speech2txt', OpenAISpeechToTextService); - } - - if ( config?.services?.claude ) { - const { ClaudeService } = require('./ClaudeService'); - services.registerService('claude', ClaudeService); - } - - if ( config?.services?.['together-ai'] ) { - const { TogetherAIService } = require('./TogetherAIService'); - services.registerService('together-ai', TogetherAIService); - - const { TogetherImageGenerationService } = require('./TogetherImageGenerationService'); - services.registerService('together-image-generation', TogetherImageGenerationService); - - const { TogetherVideoGenerationService } = require('./TogetherVideoGenerationService'); - services.registerService('together-video-generation', TogetherVideoGenerationService); - } - - if ( config?.services?.['mistral'] ) { - const { MistralAIService } = require('./MistralAIService'); - services.registerService('mistral', MistralAIService); - } - - if ( config?.services?.['groq'] ) { - const { GroqAIService } = require('./GroqAIService'); - services.registerService('groq', GroqAIService); - } - - if ( config?.services?.['xai'] ) { - const { XAIService } = require('./XAIService'); - services.registerService('xai', XAIService); - } - - if ( config?.services?.['deepseek'] ) { - const { DeepSeekService } = require('./DeepSeekService'); - services.registerService('deepseek', DeepSeekService); - } - if ( config?.services?.['gemini'] ) { - const { GeminiService } = require('./GeminiService/GeminiService.mjs'); - const { GeminiImageGenerationService } = require('./GeminiImageGenerationService'); - - services.registerService('gemini', GeminiService); - services.registerService('gemini-image-generation', GeminiImageGenerationService); - } - if ( config?.services?.['openrouter'] ) { - const { OpenRouterService } = require('./OpenRouterService'); - services.registerService('openrouter', OpenRouterService); - } - - // Autodiscover Ollama service and then check if its disabled in the config - // if config.services.ollama.enabled is undefined, it means the user hasn't set it, so we should default to true - const ollama_available = await fetch('http://localhost:11434/api/tags').then(resp => resp.json()).then(_data => { - const ollama_enabled = config?.services?.['ollama']?.enabled; - if ( ollama_enabled === undefined ) { - return true; - } - return ollama_enabled; - }).catch(_err => { - return false; - }); - // User can disable ollama in the config, but by default it should be enabled if discovery is successful - if ( ollama_available || config?.services?.['ollama']?.enabled ) { - console.log('Local AI support detected! Registering Ollama'); - const { OllamaService } = require('./OllamaService'); - services.registerService('ollama', OllamaService); - } - - const { AIChatService } = require('./AIChatService'); - services.registerService('ai-chat', AIChatService); - - const { FakeChatService } = require('./FakeChatService'); - services.registerService('fake-chat', FakeChatService); - - const { AITestModeService } = require('./AITestModeService'); - services.registerService('ai-test-mode', AITestModeService); - - const { UsageLimitedChatService } = require('./UsageLimitedChatService'); - services.registerService('usage-limited-chat', UsageLimitedChatService); - } -} - -module.exports = { - PuterAIModule, -}; diff --git a/src/backend/src/modules/puterai/TogetherAIService.js b/src/backend/src/modules/puterai/TogetherAIService.js deleted file mode 100644 index ef8b050d..00000000 --- a/src/backend/src/modules/puterai/TogetherAIService.js +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const { PassThrough } = require('stream'); -const BaseService = require('../../services/BaseService'); -const { TypedValue } = require('../../services/drivers/meta/Runtime'); -const { nou } = require('../../util/langutil'); -const { Together } = require('together-ai'); -const OpenAIUtil = require('./lib/OpenAIUtil'); -const { Context } = require('../../util/context'); - -/** -* TogetherAIService class provides integration with Together AI's language models. -* Extends BaseService to implement chat completion functionality through the -* puter-chat-completion interface. Manages model listings, chat completions, -* and streaming responses while handling usage tracking and model fallback testing. -* @extends BaseService -*/ -class TogetherAIService extends BaseService { - /** - * @type {import('../../services/MeteringService/MeteringService').MeteringService} - */ - meteringService; - static MODULES = { - kv: globalThis.kv, - uuidv4: require('uuid').v4, - }; - - /** - * Initializes the TogetherAI service by setting up the API client and registering as a chat provider - * @async - * @returns {Promise} - * @private - */ - async _init () { - this.together = new Together({ - apiKey: this.config.apiKey, - }); - this.kvkey = this.modules.uuidv4(); - - const svc_aiChat = this.services.get('ai-chat'); - svc_aiChat.register_provider({ - service_name: this.service_name, - alias: true, - }); - this.meteringService = this.services.get('meteringService').meteringService; - } - - /** - * Returns the default model ID for the Together AI service - * @returns {string} The ID of the default model (meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo) - */ - get_default_model () { - return 'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo'; - } - - static IMPLEMENTS = { - ['puter-chat-completion']: { - /** - * Returns a list of available models and their details. - * See AIChatService for more information. - * - * @returns Promise> Array of model details - */ - async models () { - return await this.models_(); - }, - - /** - * Returns a list of available model names including their aliases - * @returns {Promise} Array of model identifiers and their aliases - * @description Retrieves all available model IDs and their aliases, - * flattening them into a single array of strings that can be used for model selection - */ - async list () { - let models = this.modules.kv.get(`${this.kvkey}:models`); - if ( ! models ) models = await this.models_(); - return models.map(model => model.id); - }, - /** - * AI Chat completion method. - * See AIChatService for more details. - */ - async complete ({ messages, stream, model }) { - if ( model === 'model-fallback-test-1' ) { - throw new Error('Model Fallback Test 1'); - } - - /** @type {import('together-ai/streaming.mjs').Stream} */ - const completion = await this.together.chat.completions.create({ - model: model ?? this.get_default_model(), - messages: messages, - stream, - }); - - // Metering integration - const actor = Context.get('actor'); - - const modelDetails = (await this.models_()).find(m => m.id === model || m.aliases?.include(model)); - const modelId = modelDetails ?? this.get_default_model(); - - if ( stream ) { - const stream = new PassThrough(); - const retval = new TypedValue({ - $: 'stream', - content_type: 'application/x-ndjson', - chunked: true, - }, stream); - (async () => { - for await ( const chunk of completion ) { - // DRY: same as openai - if ( chunk.usage ) { - // Metering: record usage for streamed chunks - const trackedUsage = OpenAIUtil.extractMeteredUsage(chunk.usage); - const costOverrides = { - prompt_tokens: trackedUsage.prompt_tokens * (modelDetails?.cost?.input ?? 0), - completion_tokens: trackedUsage.completion_tokens * (modelDetails?.cost?.output ?? 0), - }; - this.meteringService.utilRecordUsageObject(trackedUsage, actor, modelId, costOverrides); - } - - if ( chunk.choices.length < 1 ) continue; - if ( chunk.choices[0].finish_reason ) { - stream.end(); - break; - } - if ( nou(chunk.choices[0].delta.content) ) continue; - const str = JSON.stringify({ - text: chunk.choices[0].delta.content, - }); - stream.write(`${str }\n`); - } - stream.end(); - })(); - - return { - stream: true, - response: retval, - }; - } - - const ret = completion.choices[0]; - - ret.usage = { - input_tokens: completion.usage.prompt_tokens, - output_tokens: completion.usage.completion_tokens, - }; - - const trackedUsage = OpenAIUtil.extractMeteredUsage(completion.usage); - const costOverrides = { - prompt_tokens: trackedUsage.prompt_tokens * (modelDetails?.cost?.input ?? 0), - completion_tokens: trackedUsage.completion_tokens * (modelDetails?.cost?.output ?? 0), - }; - // Metering: record usage for non-streamed completion - this.meteringService.utilRecordUsageObject(completion.usage, actor, modelId, costOverrides); - - return ret; - }, - }, - }; - - /** - * Fetches and caches available AI models from Together API - * @private - * @returns Array of model objects containing id, name, context length, - * description and pricing information - * @remarks Models are cached for 5 minutes in KV store - */ - async models_ () { - let models = this.modules.kv.get(`${this.kvkey}:models`); - if ( models ) return models; - const api_models = await this.together.models.list(); - models = []; - for ( const model of api_models ) { - models.push({ - id: `togetherai:${model.id}`, - aliases: [model.id], - name: model.display_name, - context: model.context_length, - description: model.description, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: model.pricing.input, - output: model.pricing.output, - }, - }); - } - models.push({ - id: 'model-fallback-test-1', - name: 'Model Fallback Test 1', - context: 1000, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 10, - output: 10, - }, - }); - this.modules.kv.set(`${this.kvkey}:models`, models, { EX: 5 * 60 }); - return models; - } -} - -module.exports = { - TogetherAIService, -}; diff --git a/src/backend/src/modules/puterai/UsageLimitedChatService.js b/src/backend/src/modules/puterai/UsageLimitedChatService.js deleted file mode 100644 index 0df931ee..00000000 --- a/src/backend/src/modules/puterai/UsageLimitedChatService.js +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const { default: dedent } = require('dedent'); -const BaseService = require('../../services/BaseService'); -const { PassThrough } = require('stream'); -const Streaming = require('./lib/Streaming'); - -/** -* UsageLimitedChatService - A specialized chat service that returns resource exhaustion messages. -* Extends BaseService to provide responses indicating the user has exceeded their usage limits. -* Follows the same response format as real AI providers but with a custom message about upgrading. -* Can handle both streaming and non-streaming requests consistently. -*/ -class UsageLimitedChatService extends BaseService { - get_default_model () { - return 'usage-limited'; - } - - static IMPLEMENTS = { - ['puter-chat-completion']: { - /** - * Returns a list of available model names - * @returns {Promise} Array containing the single model identifier - */ - async list () { - return ['usage-limited']; - }, - - /** - * Returns model details for the usage-limited model - * @returns {Promise} Array containing the model details - */ - async models () { - return [{ - id: 'usage-limited', - name: 'Usage Limited', - context: 16384, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 0, - output: 0, - }, - }]; - }, - - /** - * Simulates a chat completion request with a usage limit message - * @param {Object} params - The completion parameters - * @param {Array} params.messages - Array of chat messages (unused) - * @param {boolean} params.stream - Whether to stream the response - * @param {string} params.model - The model to use (unused) - * @returns {Object|TypedValue} A chat completion response or streamed response - */ - async complete ({ stream, customLimitMessage }) { - const limitMessage = customLimitMessage || dedent(` - You have reached your AI usage limit for this account. - `); - - // If streaming is requested, return a streaming response - if ( stream ) { - const streamObj = new PassThrough(); - - const chatStream = new Streaming.AIChatStream({ - stream: streamObj, - }); - - // Schedule the streaming response - setTimeout(() => { - chatStream.write({ - type: 'content_block_start', - index: 0, - }); - - chatStream.write({ - type: 'content_block_delta', - index: 0, - delta: { - type: 'text', - text: limitMessage, - }, - }); - - chatStream.write({ - type: 'content_block_stop', - index: 0, - }); - - chatStream.write({ - type: 'message_stop', - stop_reason: 'end_turn', - }); - - chatStream.end(); - }, 10); - - return { - stream: true, - init_chat_stream: async ({ chatStream: cs }) => { - // Copy contents from our stream to the provided one - chatStream.stream.pipe(cs.stream); - }, - }; - } - - // Non-streaming response - return { - 'index': 0, - message: { - 'id': '00000000-0000-0000-0000-000000000000', - 'type': 'message', - 'role': 'assistant', - 'model': 'usage-limited', - 'content': [ - { - 'type': 'text', - 'text': limitMessage, - }, - ], - 'stop_reason': 'end_turn', - 'stop_sequence': null, - 'usage': { - 'input_tokens': 0, - 'output_tokens': 1, - }, - }, - 'usage': { - 'input_tokens': 0, - 'output_tokens': 1, - }, - 'logprobs': null, - 'finish_reason': 'stop', - }; - }, - }, - }; -} - -module.exports = { - UsageLimitedChatService, -}; \ No newline at end of file diff --git a/src/backend/src/modules/puterai/XAIService.js b/src/backend/src/modules/puterai/XAIService.js deleted file mode 100644 index cdb9b770..00000000 --- a/src/backend/src/modules/puterai/XAIService.js +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// METADATA // {"ai-commented":{"service":"claude"}} -const BaseService = require('../../services/BaseService'); -const { Context } = require('../../util/context'); -const OpenAIUtil = require('./lib/OpenAIUtil'); - -/** -* XAIService class - Provides integration with X.AI's API for chat completions -* Extends BaseService to implement the puter-chat-completion interface. -* Handles model management, message adaptation, streaming responses, -* and usage tracking for X.AI's language models like Grok. -* @extends BaseService -*/ -class XAIService extends BaseService { - static MODULES = { - openai: require('openai'), - }; - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ - meteringService; - - adapt_model (model) { - return model; - } - - /** - * Initializes the XAI service by setting up the OpenAI client and registering with the AI chat provider - * @private - * @returns {Promise} Resolves when initialization is complete - */ - async _init () { - this.openai = new this.modules.openai.OpenAI({ - apiKey: this.global_config.services.xai.apiKey, - baseURL: 'https://api.x.ai/v1', - }); - - const svc_aiChat = this.services.get('ai-chat'); - svc_aiChat.register_provider({ - service_name: this.service_name, - alias: true, - }); - this.meteringService = this.services.get('meteringService').meteringService; // TODO DS: move to proper extensions - } - - /** - * Returns the default model identifier for the XAI service - * @returns {string} The default model ID 'grok-beta' - */ - get_default_model () { - return 'grok-beta'; - } - - static IMPLEMENTS = { - ['puter-chat-completion']: { - /** - * Returns a list of available models and their details. - * See AIChatService for more information. - * - * @returns Array Array of model details - */ - models () { - return this.models_(); - }, - /** - * Returns a list of available model names including their aliases - * @returns {Promise} Array of model identifiers and their aliases - * @description Retrieves all available model IDs and their aliases, - * flattening them into a single array of strings that can be used for model selection - */ - async list () { - const models = await this.models_(); - const model_names = []; - for ( const model of models ) { - model_names.push(model.id); - if ( model.aliases ) { - model_names.push(...model.aliases); - } - } - return model_names; - }, - - /** - * AI Chat completion method. - * See AIChatService for more details. - */ - async complete ({ messages, stream, model, tools }) { - model = this.adapt_model(model); - - messages = await OpenAIUtil.process_input_messages(messages); - - const completion = await this.openai.chat.completions.create({ - messages, - model: model ?? this.get_default_model(), - ...(tools ? { tools } : {}), - max_tokens: 1000, - stream, - ...(stream ? { - stream_options: { include_usage: true }, - } : {}), - }); - - // Metering integration - const actor = Context.get('actor'); - - return OpenAIUtil.handle_completion_output({ - usage_calculator: ({ usage }) => { - const modelDetails = this.models().find(m => m.id === model || m.aliases?.includes(model)); - const trackedUsage = { - prompt_tokens: (usage.prompt_tokens ?? 0) - (usage.prompt_tokens_details?.cached_tokens ?? 0), - completion_tokens: usage.completion_tokens ?? 0, - cached_tokens: usage.prompt_tokens_details?.cached_tokens ?? 0, - }; - - this.meteringService.utilRecordUsageObject(trackedUsage, actor, `openai:${modelDetails.id}`); - const legacyCostCalculator = OpenAIUtil.create_usage_calculator({ - model_details: modelDetails, - }); - - return legacyCostCalculator({ usage }); - }, - stream, - completion, - }); - }, - }, - }; - - /** - * Retrieves available AI models and their specifications - * @returns Array of model objects containing: - * - id: Model identifier string - * - name: Human readable model name - * - context: Maximum context window size - * - cost: Pricing information object with currency and rates - * @private - */ - models_ () { - return [ - { - id: 'grok-beta', - name: 'Grok Beta', - context: 131072, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 500, - output: 1500, - }, - }, - { - id: 'grok-vision-beta', - name: 'Grok Vision Beta', - context: 8192, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 500, - output: 1500, - image: 1000, - }, - }, - { - id: 'grok-3', - name: 'Grok 3', - context: 131072, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 300, - output: 1500, - }, - }, - { - id: 'grok-3-fast', - name: 'Grok 3 Fast', - context: 131072, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 500, - output: 2500, - }, - }, - { - id: 'grok-3-mini', - name: 'Grok 3 Mini', - context: 131072, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 30, - output: 50, - }, - }, - { - id: 'grok-3-mini-fast', - name: 'Grok 3 Mini', - context: 131072, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 60, - output: 400, - }, - }, - { - id: 'grok-2-vision', - name: 'Grok 2 Vision', - context: 8192, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 200, - output: 1000, - }, - }, - { - id: 'grok-2', - name: 'Grok 2', - context: 131072, - cost: { - currency: 'usd-cents', - tokens: 1_000_000, - input: 200, - output: 1000, - }, - }, - ]; - } -} - -module.exports = { - XAIService, -}; diff --git a/src/backend/src/modules/puterai/experiment/stream_claude.js b/src/backend/src/modules/puterai/experiment/stream_claude.js deleted file mode 100644 index e63379dc..00000000 --- a/src/backend/src/modules/puterai/experiment/stream_claude.js +++ /dev/null @@ -1,58 +0,0 @@ -const { nou } = require('../../../util/langutil'); -const Streaming = require('../lib/Streaming'); -// const claude_sample = require('../samples/claude-1'); -const claude_sample = require('../samples/claude-tools-1'); - -const echo_stream = { - write: data => { - console.log(data); - }, -}; - -const chatStream = new Streaming.AIChatStream({ stream: echo_stream }); - -let message; -let contentBlock; -for ( const event of claude_sample ) { - if ( event.type === 'message_start' ) { - message = chatStream.message(); - continue; - } - if ( event.type === 'message_stop' ) { - message.end(); - message = null; - continue; - } - - if ( event.type === 'content_block_start' ) { - if ( event.content_block.type === 'tool_use' ) { - contentBlock = message.contentBlock({ - type: event.content_block.type, - id: event.content_block.id, - name: event.content_block.name, - }); - continue; - } - contentBlock = message.contentBlock({ - type: event.content_block.type, - }); - continue; - } - - if ( event.type === 'content_block_stop' ) { - contentBlock.end(); - contentBlock = null; - continue; - } - - if ( event.type === 'content_block_delta' ) { - if ( event.delta.type === 'input_json_delta' ) { - contentBlock.addPartialJSON(event.delta.partial_json); - continue; - } - if ( event.delta.type === 'text_delta' ) { - contentBlock.addText(event.delta.text); - continue; - } - } -} diff --git a/src/backend/src/modules/puterai/experiment/stream_openai.js b/src/backend/src/modules/puterai/experiment/stream_openai.js deleted file mode 100644 index ef651ca5..00000000 --- a/src/backend/src/modules/puterai/experiment/stream_openai.js +++ /dev/null @@ -1,61 +0,0 @@ -const { nou } = require('../../../util/langutil'); -const FunctionCalling = require('../lib/FunctionCalling'); -const Streaming = require('../lib/Streaming'); -const openai_fish = require('../samples/openai-tools-1'); - -const echo_stream = { - write: data => { - console.log(data); - }, -}; - -const chatStream = new Streaming.AIChatStream({ - stream: echo_stream, -}); - -const message = chatStream.message(); -let textblock = message.contentBlock({ type: 'text' }); -let toolblock = null; -let mode = 'text'; - -const tool_call_blocks = []; - -for ( const chunk of openai_fish ) { - if ( chunk.usage ) continue; - if ( chunk.choices.length < 1 ) continue; - - const choice = chunk.choices[0]; - - if ( ! nou(choice.delta.content) ) { - if ( mode === 'tool' ) { - toolblock.end(); - mode = 'text'; - textblock = message.contentBlock({ type: 'text' }); - } - textblock.addText(choice.delta.content); - continue; - } - - if ( ! nou(choice.delta.tool_calls) ) { - if ( mode === 'text' ) { - mode = 'tool'; - textblock.end(); - } - for ( const tool_call of choice.delta.tool_calls ) { - if ( ! tool_call_blocks[tool_call.index] ) { - toolblock = message.contentBlock({ - type: 'tool_use', - id: tool_call.function.name, - }); - tool_call_blocks[tool_call.index] = toolblock; - } else { - toolblock = tool_call_blocks[tool_call.index]; - } - toolblock.addPartialJSON(tool_call.function.arguments); - } - } -} - -if ( mode === 'text' ) textblock.end(); -if ( mode === 'tool' ) toolblock.end(); -message.end(); diff --git a/src/backend/src/modules/puterai/lib/FunctionCalling.js b/src/backend/src/modules/puterai/lib/FunctionCalling.js deleted file mode 100644 index f71801f6..00000000 --- a/src/backend/src/modules/puterai/lib/FunctionCalling.js +++ /dev/null @@ -1,122 +0,0 @@ -module.exports = class FunctionCalling { - /** - * Normalizes the 'tools' object in-place. - * - * This function will accept an array of tools provided by the - * user, and produce a normalized object that can then be - * converted to the apprpriate representation for another - * service. - * - * We will accept conventions from either service that a user - * might expect to work, prioritizing the OpenAI convention - * when conflicting conventions are present. - * - * @param {*} tools - */ - static normalize_tools_object (tools) { - for ( let i = 0 ; i < tools.length ; i++ ) { - const tool = tools[i]; - let normalized_tool = {}; - - const normalize_function = fn => { - const normal_fn = {}; - let parameters = - fn.parameters || - fn.input_schema; - - normal_fn.parameters = parameters ?? { - type: 'object', - }; - - if ( parameters.properties ) { - parameters = this.normalize_json_schema(parameters); - } - - if ( fn.name ) { - normal_fn.name = fn.name; - } - - if ( fn.description ) { - normal_fn.description = fn.description; - } - - return normal_fn; - }; - - if ( tool.input_schema ) { - normalized_tool = { - type: 'function', - function: normalize_function(tool), - }; - } else if ( tool.type === 'function' ) { - normalized_tool = { - type: 'function', - function: normalize_function(tool.function), - }; - } else { - normalized_tool = { - type: 'function', - function: normalize_function(tool), - }; - } - - tools[i] = normalized_tool; - } - return tools; - } - - static normalize_json_schema (schema) { - if ( ! schema ) return schema; - - if ( schema.type === 'object' ) { - if ( ! schema.properties ) { - return schema; - } - - const keys = Object.keys(schema.properties); - for ( const key of keys ) { - schema.properties[key] = this.normalize_json_schema(schema.properties[key]); - } - } - - if ( schema.type === 'array' ) { - if ( ! schema.items ) { - schema.items = {}; - } else { - schema.items = this.normalize_json_schema(schema.items); - } - } - - return schema; - } - - /** - * This function will convert a normalized tools object to the - * format expected by OpenAI. - * - * @param {*} tools - * @returns - */ - static make_openai_tools (tools) { - return tools; - } - - /** - * This function will convert a normalized tools object to the - * format expected by Claude. - * - * @param {*} tools - * @returns - */ - static make_claude_tools (tools) { - if ( ! tools ) return undefined; - return tools.map(tool => { - const { name, description, parameters } = tool.function; - return { - name, - description, - input_schema: parameters, - }; - }); - } -}; diff --git a/src/backend/src/modules/puterai/lib/Messages.js b/src/backend/src/modules/puterai/lib/Messages.js deleted file mode 100644 index 16c6307c..00000000 --- a/src/backend/src/modules/puterai/lib/Messages.js +++ /dev/null @@ -1,186 +0,0 @@ -const { whatis } = require('../../../util/langutil'); - -module.exports = class Messages { - /** - * Normalizes a single message into a standardized format with role and content array. - * Converts string messages to objects, ensures content is an array of content blocks, - * transforms tool_calls into tool_use content blocks, and coerces content items into objects. - * - * @param {string|Object} message - The message to normalize, either a string or message object - * @param {Object} params - Optional parameters including default role - * @returns {Object} Normalized message with role and content array - * @throws {Error} If message is not a string or object - * @throws {Error} If message has no content property and no tool_calls - * @throws {Error} If any content item is not a string or object - */ - static normalize_single_message (message, params = {}) { - params = Object.assign({ - role: 'user', - }, params); - - if ( typeof message === 'string' ) { - message = { - content: [message], - }; - } - if ( whatis(message) !== 'object' ) { - throw new Error('each message must be a string or object'); - } - if ( ! message.role ) { - message.role = params.role; - } - if ( ! message.content ) { - if ( message.tool_calls ) { - message.content = []; - for ( let i = 0 ; i < message.tool_calls.length ; i++ ) { - const tool_call = message.tool_calls[i]; - message.content.push({ - type: 'tool_use', - id: tool_call.id, - name: tool_call.function.name, - input: tool_call.function.arguments, - }); - } - delete message.tool_calls; - } else { - throw new Error('each message must have a \'content\' property'); - } - } - if ( whatis(message.content) !== 'array' ) { - message.content = [message.content]; - } - // Coerce each content block into an object - for ( let i = 0 ; i < message.content.length ; i++ ) { - if ( whatis(message.content[i]) === 'string' ) { - message.content[i] = { - type: 'text', - text: message.content[i], - }; - } - if ( whatis(message.content[i]) !== 'object' ) { - throw new Error('each message content item must be a string or object'); - } - if ( typeof message.content[i].text === 'string' && !message.content[i].type ) { - message.content[i].type = 'text'; - } - } - - // Remove "text" properties from content blocks with type=tool_result - for ( let i = 0 ; i < message.content.length ; i++ ) { - if ( message.content[i].type !== 'tool_use' ) { - continue; - } - if ( message.content[i].hasOwnProperty('text') ) { - delete message.content[i].text; - } - } - - return message; - } - - /** - * Normalizes an array of messages by applying normalize_single_message to each, - * then splits messages with multiple content blocks into separate messages, - * and finally merges consecutive messages from the same role. - * - * @param {Array} messages - Array of messages to normalize - * @param {Object} params - Optional parameters passed to normalize_single_message - * @returns {Array} Normalized and merged array of messages - */ - static normalize_messages (messages, params = {}) { - for ( let i = 0 ; i < messages.length ; i++ ) { - messages[i] = this.normalize_single_message(messages[i], params); - } - - // Split messages with tool_use content into separate messages - // TODO: unit test this - messages = [...messages]; - for ( let i = 0 ; i < messages.length ; i++ ) { - let message = messages[i]; - let separated_messages = []; - for ( let j = 0 ; j < message.content.length ; j++ ) { - if ( message.content[j].type === 'tool_result' ) { - separated_messages.push({ - ...message, - content: [message.content[j]], - }); - } else { - separated_messages.push({ - ...message, - content: [message.content[j]], - }); - } - } - messages.splice(i, 1, ...separated_messages); - } - - // If multiple messages are from the same role, merge them - let merged_messages = []; - let current_role = null; - for ( let i = 0 ; i < messages.length ; i++ ) { - if ( current_role === messages[i].role ) { - merged_messages[merged_messages.length - 1].content.push(...messages[i].content); - } else { - merged_messages.push(messages[i]); - current_role = messages[i].role; - } - } - - return merged_messages; - } - - /** - * Separates system messages from other messages in the array. - * - * @param {Array} messages - Array of messages to process - * @returns {Array} Tuple containing [system_messages, non_system_messages] - */ - static extract_and_remove_system_messages (messages) { - let system_messages = []; - let new_messages = []; - for ( let i = 0 ; i < messages.length ; i++ ) { - if ( messages[i].role === 'system' ) { - system_messages.push(messages[i]); - } else { - new_messages.push(messages[i]); - } - } - return [system_messages, new_messages]; - } - - /** - * Extracts all text content from messages, handling various message formats. - * Processes strings, objects with content arrays, and nested content structures, - * joining all text with spaces. - * - * @param {Array} messages - Array of messages to extract text from - * @returns {string} Concatenated text content from all messages - * @throws {Error} If text content is not a string - */ - static extract_text (messages) { - return messages.map(m => { - if ( whatis(m) === 'string' ) { - return m; - } - if ( whatis(m) !== 'object' ) { - return ''; - } - if ( whatis(m.content) === 'array' ) { - return m.content.map(c => c.text).join(' '); - } - if ( whatis(m.content) === 'string' ) { - return m.content; - } else { - const is_text_type = m.content.type === 'text' || - !m.content.hasOwnProperty('type'); - if ( is_text_type ) { - if ( whatis(m.content.text) !== 'string' ) { - throw new Error('text content must be a string'); - } - return m.content.text; - } - return ''; - } - }).join(' '); - } -}; \ No newline at end of file diff --git a/src/backend/src/modules/puterai/samples/claude-1.js b/src/backend/src/modules/puterai/samples/claude-1.js deleted file mode 100644 index 675d5772..00000000 --- a/src/backend/src/modules/puterai/samples/claude-1.js +++ /dev/null @@ -1,65 +0,0 @@ -module.exports = [ - { - type: 'message_start', - message: { - id: 'msg_01KKQeaUDpMzNovH9utP5qJc', - type: 'message', - role: 'assistant', - model: 'claude-3-5-sonnet-20241022', - content: [], - stop_reason: null, - stop_sequence: null, - usage: { - input_tokens: 82, - cache_creation_input_tokens: 0, - cache_read_input_tokens: 0, - output_tokens: 1, - }, - }, - }, - { - type: 'content_block_start', - index: 0, - content_block: { type: 'text', text: '' }, - }, - { - type: 'content_block_delta', - index: 0, - delta: { type: 'text_delta', text: 'Some' }, - }, - { - type: 'content_block_delta', - index: 0, - delta: { type: 'text_delta', text: ' species of fish, like the electric' }, - }, - { - type: 'content_block_delta', - index: 0, - delta: { - type: 'text_delta', - text: ' eel, can generate powerful electrical', - }, - }, - { - type: 'content_block_delta', - index: 0, - delta: { type: 'text_delta', text: ' charges of up to 860 ' }, - }, - { - type: 'content_block_delta', - index: 0, - delta: { type: 'text_delta', text: 'volts to stun prey an' }, - }, - { - type: 'content_block_delta', - index: 0, - delta: { type: 'text_delta', text: 'd defend themselves.' }, - }, - { type: 'content_block_stop', index: 0 }, - { - type: 'message_delta', - delta: { stop_reason: 'end_turn', stop_sequence: null }, - usage: { output_tokens: 35 }, - }, - { type: 'message_stop' }, -]; \ No newline at end of file diff --git a/src/backend/src/modules/puterai/samples/claude-tools-1.js b/src/backend/src/modules/puterai/samples/claude-tools-1.js deleted file mode 100644 index c1ff69da..00000000 --- a/src/backend/src/modules/puterai/samples/claude-tools-1.js +++ /dev/null @@ -1,76 +0,0 @@ -module.exports = [ - { - type: 'message_start', - message: { - id: 'msg_01GAy4THpFyFJcpxqWXBMrvx', - type: 'message', - role: 'assistant', - model: 'claude-3-5-sonnet-20241022', - content: [], - stop_reason: null, - stop_sequence: null, - usage: { - input_tokens: 458, - cache_creation_input_tokens: 0, - cache_read_input_tokens: 0, - output_tokens: 1, - }, - }, - }, - { - type: 'content_block_start', - index: 0, - content_block: { type: 'text', text: '' }, - }, - { - type: 'content_block_delta', - index: 0, - delta: { type: 'text_delta', text: 'I' }, - }, - { - type: 'content_block_delta', - index: 0, - delta: { - type: 'text_delta', - text: "'ll check the weather in Vancouver for you.", - }, - }, - { type: 'content_block_stop', index: 0 }, - { - type: 'content_block_start', - index: 1, - content_block: { - type: 'tool_use', - id: 'toolu_01E12jeyCenTtntPBk1j7rgc', - name: 'get_weather', - input: {}, - }, - }, - { - type: 'content_block_delta', - index: 1, - delta: { type: 'input_json_delta', partial_json: '' }, - }, - { - type: 'content_block_delta', - index: 1, - delta: { type: 'input_json_delta', partial_json: '{"location"' }, - }, - { - type: 'content_block_delta', - index: 1, - delta: { type: 'input_json_delta', partial_json: ': "Van' }, - }, - { - type: 'content_block_delta', - index: 1, - delta: { type: 'input_json_delta', partial_json: 'couver"}' }, - }, - { type: 'content_block_stop', index: 1 }, - { - type: 'message_delta', - delta: { stop_reason: 'tool_use', stop_sequence: null }, - usage: { output_tokens: 64 }, - }, - { type: 'message_stop' }, -]; diff --git a/src/backend/src/modules/puterai/samples/openai-1.js b/src/backend/src/modules/puterai/samples/openai-1.js deleted file mode 100644 index 3dab0dd9..00000000 --- a/src/backend/src/modules/puterai/samples/openai-1.js +++ /dev/null @@ -1,46 +0,0 @@ -module.exports = [ - { - id: 'chatcmpl-AvspmQTvFBBjKsFhHYhyiphFmKMY8', - object: 'chat.completion.chunk', - created: 1738358842, - model: 'gpt-4o-mini-2024-07-18', - service_tier: 'default', - system_fingerprint: 'fp_bd83329f63', - choices: [ - { - index: 0, - delta: { - role: 'assistant', - content: '', - refusal: null, - }, - logprobs: null, - finish_reason: null, - }, - ], - usage: null, - }, - ...[ - 'Fish', ' are', ' diverse', ' aquatic', ' creatures', ' that', ' play', - ' a', ' crucial', ' role', ' in', ' marine', ' ecosystems', ' and', - ' human', ' diets', '.', - ].map(str => ({ - id: 'chatcmpl-AvspmQTvFBBjKsFhHYhyiphFmKMY8', - object: 'chat.completion.chunk', - created: 1738358842, - model: 'gpt-4o-mini-2024-07-18', - service_tier: 'default', - system_fingerprint: 'fp_bd83329f63', - choices: [ - { - index: 0, - delta: { - content: str, - }, - logprobs: null, - finish_reason: null, - }, - ], - usage: null, - })), -]; diff --git a/src/backend/src/modules/puterai/samples/openai-tools-1.js b/src/backend/src/modules/puterai/samples/openai-tools-1.js deleted file mode 100644 index 72847302..00000000 --- a/src/backend/src/modules/puterai/samples/openai-tools-1.js +++ /dev/null @@ -1,102 +0,0 @@ -module.exports = [ - { - id: 'chatcmpl-Avqr6AwmQoEFLXuwf1llkKknIR4Ry', - object: 'chat.completion.chunk', - created: 1738351236, - model: 'gpt-4o-mini-2024-07-18', - service_tier: 'default', - system_fingerprint: 'fp_72ed7ab54c', - choices: [ - { - index: 0, - delta: { - role: 'assistant', - content: null, - tool_calls: [ - { - index: 0, - id: 'call_ULl8cRKFQbYeJSIZ3giLAg6r', - type: 'function', - function: { - name: 'get_weather', - arguments: '', - }, - }, - ], - refusal: null, - }, - logprobs: null, - finish_reason: null, - }, - ], - usage: null, - }, - ...[ - '{"', 'location', '":"', - 'V', 'ancouver', - '"}', - ].map(str => ({ - id: 'chatcmpl-Avqr6AwmQoEFLXuwf1llkKknIR4Ry', - object: 'chat.completion.chunk', - created: 1738351236, - model: 'gpt-4o-mini-2024-07-18', - service_tier: 'default', - system_fingerprint: 'fp_72ed7ab54c', - choices: [ - { - index: 0, - delta: { - tool_calls: [ - { - index: 0, - function: { - arguments: str, - }, - }, - ], - }, - logprobs: null, - finish_reason: null, - }, - ], - usage: null, - })), - { - id: 'chatcmpl-Avqr6AwmQoEFLXuwf1llkKknIR4Ry', - object: 'chat.completion.chunk', - created: 1738351236, - model: 'gpt-4o-mini-2024-07-18', - service_tier: 'default', - system_fingerprint: 'fp_72ed7ab54c', - choices: [ - { - index: 0, - delta: {}, - logprobs: null, - finish_reason: 'tool_calls', - }, - ], - usage: null, - }, - { - id: 'chatcmpl-Avqr6AwmQoEFLXuwf1llkKknIR4Ry', - object: 'chat.completion.chunk', - created: 1738351236, - model: 'gpt-4o-mini-2024-07-18', - service_tier: 'default', - system_fingerprint: 'fp_72ed7ab54c', - choices: [], - usage: { - prompt_tokens: 62, - completion_tokens: 16, - total_tokens: 78, - prompt_tokens_details: { cached_tokens: 0, audio_tokens: 0 }, - completion_tokens_details: { - reasoning_tokens: 0, - audio_tokens: 0, - accepted_prediction_tokens: 0, - rejected_prediction_tokens: 0, - }, - }, - }, -]; diff --git a/src/backend/src/modules/test-core/TestCoreModule.js b/src/backend/src/modules/test-core/TestCoreModule.js index 4809c6ba..ce6e7cf7 100644 --- a/src/backend/src/modules/test-core/TestCoreModule.js +++ b/src/backend/src/modules/test-core/TestCoreModule.js @@ -1,19 +1,30 @@ -const { AnomalyService } = require('../../services/AnomalyService'); -const { GroupService } = require('../../services/auth/GroupService'); -const { PermissionService } = require('../../services/auth/PermissionService'); -const { CommandService } = require('../../services/CommandService'); -const { SqliteDatabaseAccessService } = require('../../services/database/SqliteDatabaseAccessService'); -const { DetailProviderService } = require('../../services/DetailProviderService'); -const { EventService } = require('../../services/EventService'); -const { GetUserService } = require('../../services/GetUserService'); -const { MeteringServiceWrapper } = require('../../services/MeteringService/MeteringServiceWrapper.mjs'); -const { DBKVServiceWrapper } = require('../../services/repositories/DBKVStore/index.mjs'); -const { SUService } = require('../../services/SUService'); -const { TraceService } = require('../../services/TraceService'); -const { AlarmService } = require('../core/AlarmService'); -const APIErrorService = require('../web/APIErrorService'); +import { FilesystemService } from '../../filesystem/FilesystemService'; +import { AnomalyService } from '../../services/AnomalyService'; +import { AuthService } from '../../services/auth/AuthService'; +import { GroupService } from '../../services/auth/GroupService'; +import { PermissionService } from '../../services/auth/PermissionService'; +import { TokenService } from '../../services/auth/TokenService'; +import { CommandService } from '../../services/CommandService'; +import { SqliteDatabaseAccessService } from '../../services/database/SqliteDatabaseAccessService'; +import { DetailProviderService } from '../../services/DetailProviderService'; +import { EventService } from '../../services/EventService'; +import { FeatureFlagService } from '../../services/FeatureFlagService'; +import { GetUserService } from '../../services/GetUserService'; +import { InformationService } from '../../services/information/InformationService'; +import { MeteringServiceWrapper } from '../../services/MeteringService/MeteringServiceWrapper.mjs'; +import { NotificationService } from '../../services/NotificationService'; +import { RegistrantService } from '../../services/RegistrantService'; +import { RegistryService } from '../../services/RegistryService'; +import { DBKVServiceWrapper } from '../../services/repositories/DBKVStore/index.mjs'; +import { ScriptService } from '../../services/ScriptService'; +import { SessionService } from '../../services/SessionService'; +import { SUService } from '../../services/SUService'; +import { SystemValidationService } from '../../services/SystemValidationService'; +import { TraceService } from '../../services/TraceService'; +import { AlarmService } from '../core/AlarmService'; +import APIErrorService from '../web/APIErrorService'; -class TestCoreModule { +export class TestCoreModule { async install (context) { const services = context.get('services'); services.registerService('whoami', DetailProviderService); @@ -30,9 +41,16 @@ class TestCoreModule { services.registerService('group', GroupService); services.registerService('anomaly', AnomalyService); services.registerService('api-error', APIErrorService); + services.registerService('system-validation', SystemValidationService); + services.registerService('registry', RegistryService); + services.registerService('__registrant', RegistrantService); + services.registerService('feature-flag', FeatureFlagService); + services.registerService('token', TokenService); + services.registerService('information', InformationService); + services.registerService('auth', AuthService); + services.registerService('session', SessionService); + services.registerService('notification', NotificationService); + services.registerService('script', ScriptService); + services.registerService('filesystem', FilesystemService); } } - -module.exports = { - TestCoreModule, -}; diff --git a/src/backend/src/om/entitystorage/BaseES.js b/src/backend/src/om/entitystorage/BaseES.js index b8b879b1..d6e5270c 100644 --- a/src/backend/src/om/entitystorage/BaseES.js +++ b/src/backend/src/om/entitystorage/BaseES.js @@ -18,7 +18,6 @@ */ const { AdvancedBase } = require('@heyputer/putility'); const { WeakConstructorFeature } = require('../../traits/WeakConstructorFeature'); -const { Context } = require('../../util/context'); /** * BaseES is a base class for Entity Store classes. @@ -82,11 +81,6 @@ class BaseES extends AdvancedBase { this[k] = this.impl_methods[k]; } - - this.log = Context.get('services').get('log-service') - .create(`ES:${this.entity_name}:${this.constructor.name}`, { - concern: 'es', - }); } async provide_context ( args ) { @@ -97,9 +91,6 @@ class BaseES extends AdvancedBase { if ( this._on_context_provided ) { await this._on_context_provided(args); } - - this.log = Context.get('services').get('log-service') - .create(`ES:${this.entity_name}:${this.constructor.name}`); } async read (uid) { let entity = await this.call_on_impl_('read', uid); diff --git a/src/backend/src/om/entitystorage/SubdomainES.js b/src/backend/src/om/entitystorage/SubdomainES.js index 06798b94..93d1ebfb 100644 --- a/src/backend/src/om/entitystorage/SubdomainES.js +++ b/src/backend/src/om/entitystorage/SubdomainES.js @@ -27,59 +27,57 @@ const { BaseES } = require('./BaseES'); const PERM_READ_ALL_SUBDOMAINS = 'read-all-subdomains'; class SubdomainES extends BaseES { - static METHODS = { - async _on_context_provided () { - const services = this.context.get('services'); - this.db = services.get('database').get(DB_READ, 'subdomains'); - }, - async create_predicate (id) { - if ( id === 'user-can-edit' ) { - return new Eq({ - key: 'owner', - value: Context.get('user').id, - }); - } - }, - async upsert (entity, extra) { - if ( ! extra.old_entity ) { - await this._check_max_subdomains(); - } + async _on_context_provided () { + const services = this.context.get('services'); + this.db = services.get('database').get(DB_READ, 'subdomains'); + } + async create_predicate (id) { + if ( id === 'user-can-edit' ) { + return new Eq({ + key: 'owner', + value: Context.get('user').id, + }); + } + } + async upsert (entity, extra) { + if ( ! extra.old_entity ) { + await this._check_max_subdomains(); + } - return await this.upstream.upsert(entity, extra); - }, - async select (options) { - const actor = Context.get('actor'); - const user = actor.type.user; + return await this.upstream.upsert(entity, extra); + } + async select (options) { + const actor = Context.get('actor'); + const user = actor.type.user; - // Note: we don't need to worry about read; - // non-owner users don't have permission to list - // but they still have permission to read. - const svc_permission = this.context.get('services').get('permission'); - const has_permission_to_read_all = await svc_permission.check(Context.get('actor'), PERM_READ_ALL_SUBDOMAINS); + // Note: we don't need to worry about read; + // non-owner users don't have permission to list + // but they still have permission to read. + const svc_permission = this.context.get('services').get('permission'); + const has_permission_to_read_all = await svc_permission.check(Context.get('actor'), PERM_READ_ALL_SUBDOMAINS); - if ( ! has_permission_to_read_all ) { - options.predicate = options.predicate.and(new Eq({ - key: 'owner', - value: user.id, - })); - } + if ( ! has_permission_to_read_all ) { + options.predicate = options.predicate.and(new Eq({ + key: 'owner', + value: user.id, + })); + } - return await this.upstream.select(options); - }, - async _check_max_subdomains () { - const user = Context.get('user'); + return await this.upstream.select(options); + } + async _check_max_subdomains () { + const user = Context.get('user'); - let cnt = await this.db.read('SELECT COUNT(id) AS subdomain_count FROM subdomains WHERE user_id = ?', - [user.id]); + let cnt = await this.db.read('SELECT COUNT(id) AS subdomain_count FROM subdomains WHERE user_id = ?', + [user.id]); - const max_subdomains = user.max_subdomains ?? config.max_subdomains_per_user; + const max_subdomains = user.max_subdomains ?? config.max_subdomains_per_user; - if ( max_subdomains && cnt[0].subdomain_count >= max_subdomains ) { - throw APIError.create('subdomain_limit_reached', null, { - limit: max_subdomains, - }); - } - }, + if ( max_subdomains && cnt[0].subdomain_count >= max_subdomains ) { + throw APIError.create('subdomain_limit_reached', null, { + limit: max_subdomains, + }); + } }; } diff --git a/src/backend/src/routers/get-launch-apps.test.js b/src/backend/src/routers/get-launch-apps.test.js index 8c61bed9..3bbddf6c 100644 --- a/src/backend/src/routers/get-launch-apps.test.js +++ b/src/backend/src/routers/get-launch-apps.test.js @@ -18,7 +18,7 @@ */ import { describe, it, expect, beforeEach, vi } from 'vitest'; -const kvjs = require('@heyputer/kv.js'); +import { kv } from '../util/kvSingleton'; const uuid = require('uuid'); const proxyquire = require('proxyquire'); @@ -156,7 +156,7 @@ const get_mock_context = () => { }; describe('GET /launch-apps', () => { - globalThis.kv = new kvjs(); + globalThis.kv = kv; it('should return expected format', async () => { // First call @@ -165,52 +165,6 @@ describe('GET /launch-apps', () => { req_mock.query = {}; await get_launch_apps(req_mock, res_mock); - // TODO: bring this back, figure out what it's testing, - // document why it needs to be here (if it does) - // or remove it. - if ( false ) { - - expect(res_mock.send).toHaveBeenCalledOnce(); - - const call = res_mock.send.mock.calls[0]; - const response = call[0]; - console.log('response', response); - - expect(response).toBeTypeOf('object'); - - expect(response).toHaveProperty('recommended'); - expect(response.recommended).toBeInstanceOf(Array); - expect(response.recommended).toHaveLength(apps_names_expected_to_exist.length); - expect(response.recommended).toEqual( - data_mockapps - .filter(app => apps_names_expected_to_exist.includes(app.name)) - .map(app => ({ - uuid: app.uid, - name: app.name, - title: app.title, - icon: app.icon, - godmode: app.godmode, - maximize_on_start: app.maximize_on_start, - index_url: app.index_url, - }))); - - expect(response).toHaveProperty('recent'); - expect(response.recent).toBeInstanceOf(Array); - expect(response.recent).toHaveLength(data_appopens.length); - expect(response.recent).toEqual( - data_mockapps - .filter(app => data_appopens.map(app_open => app_open.app_uid).includes(app.uid)) - .map(app => ({ - uuid: app.uid, - name: app.name, - title: app.title, - icon: app.icon, - godmode: app.godmode, - maximize_on_start: app.maximize_on_start, - index_url: app.index_url, - }))); - } - // << HOW TO FIX >> // If you updated the list of recommended apps, // you can simply update this number to match the new length diff --git a/src/backend/src/services/BaseService.d.ts b/src/backend/src/services/BaseService.d.ts index 7c85431c..3cf6cf29 100644 --- a/src/backend/src/services/BaseService.d.ts +++ b/src/backend/src/services/BaseService.d.ts @@ -8,11 +8,11 @@ export interface ServiceResources { export type EventHandler = (id: string, ...args: any[]) => any; -export type Logger = { +export interface Logger { debug: (...args: any[]) => any; info: (...args: any[]) => any; [key: string]: any; -}; +} export class BaseService { constructor (service_resources: ServiceResources, ...a: any[]); @@ -26,7 +26,7 @@ export class BaseService { log: Logger; errors: any; - as(interfaceName: string): Record; + as (interfaceName: string): Record; run_as_early_as_possible (): Promise; construct (): Promise; diff --git a/src/backend/src/services/ChatAPIService.js b/src/backend/src/services/ChatAPIService.js index 1762e9e2..71564037 100644 --- a/src/backend/src/services/ChatAPIService.js +++ b/src/backend/src/services/ChatAPIService.js @@ -75,7 +75,7 @@ class ChatAPIService extends BaseService { const models = await svc_su.sudo(async () => { const svc_aiChat = this.services.get('ai-chat'); // Return the simple model list which contains basic model information - return svc_aiChat.simple_model_list; + return svc_aiChat.list(); }); // Return the list of models @@ -98,7 +98,7 @@ class ChatAPIService extends BaseService { const models = await svc_su.sudo(async () => { const svc_aiChat = this.services.get('ai-chat'); // Return the detailed model list which includes cost and capability information - return svc_aiChat.detail_model_list; + return svc_aiChat.models(); }); // Return the detailed list of models diff --git a/src/backend/src/services/ChatAPIService.test.js b/src/backend/src/services/ChatAPIService.test.js index b608cd82..520de195 100644 --- a/src/backend/src/services/ChatAPIService.test.js +++ b/src/backend/src/services/ChatAPIService.test.js @@ -51,8 +51,8 @@ describe('ChatAPIService', () => { beforeEach(() => { // Mock AIChatService mockAIChatService = { - simple_model_list: ['model1', 'model2'], - detail_model_list: [ + list: () => ['model1', 'model2'], + models: () => [ { id: 'model1', name: 'Model 1', cost: { input: 1, output: 2 } }, { id: 'model2', name: 'Model 2', cost: { input: 3, output: 4 } }, ], @@ -159,7 +159,7 @@ describe('ChatAPIService', () => { // Verify expect(mockSUService.sudo).toHaveBeenCalled(); expect(mockRes.json).toHaveBeenCalledWith({ - models: mockAIChatService.simple_model_list, + models: mockAIChatService.list(), }); }); }); @@ -179,7 +179,7 @@ describe('ChatAPIService', () => { // Verify expect(mockSUService.sudo).toHaveBeenCalled(); expect(mockRes.json).toHaveBeenCalledWith({ - models: mockAIChatService.detail_model_list, + models: mockAIChatService.models(), }); }); }); diff --git a/src/backend/src/services/MeteringService/MeteringService.ts b/src/backend/src/services/MeteringService/MeteringService.ts index 7952b3ad..6627b13c 100644 --- a/src/backend/src/services/MeteringService/MeteringService.ts +++ b/src/backend/src/services/MeteringService/MeteringService.ts @@ -514,7 +514,7 @@ export class MeteringService { const currentMonth = this.#getMonthYearString(); const keyPrefix = `${METRICS_PREFIX}:puter:`; return this.#superUserService.sudo(async () => { - const keys = []; + const keys: string[] = []; for ( let shard = 0; shard < MeteringService.GLOBAL_SHARD_COUNT; shard++ ) { keys.push(`${keyPrefix}${shard}:${currentMonth}`); } diff --git a/src/backend/src/services/MeteringService/costMaps/fileSystemCostMap.ts b/src/backend/src/services/MeteringService/costMaps/fileSystemCostMap.ts index 6d6f3297..f34367f4 100644 --- a/src/backend/src/services/MeteringService/costMaps/fileSystemCostMap.ts +++ b/src/backend/src/services/MeteringService/costMaps/fileSystemCostMap.ts @@ -1,4 +1,4 @@ -import { toMicroCents } from '../utils'; +import { toMicroCents } from '../utils.js'; export const FILE_SYSTEM_COST_MAP = { 'filesystem:ingress:bytes': 0, diff --git a/src/backend/src/services/MeteringService/costMaps/index.ts b/src/backend/src/services/MeteringService/costMaps/index.ts index 9c18fb3c..0bab195e 100644 --- a/src/backend/src/services/MeteringService/costMaps/index.ts +++ b/src/backend/src/services/MeteringService/costMaps/index.ts @@ -1,19 +1,19 @@ -import { AWS_POLLY_COST_MAP } from './awsPollyCostMap'; -import { AWS_TEXTRACT_COST_MAP } from './awsTextractCostMap'; -import { CLAUDE_COST_MAP } from './claudeCostMap'; -import { DEEPSEEK_COST_MAP } from './deepSeekCostMap'; -import { FILE_SYSTEM_COST_MAP } from './fileSystemCostMap'; -import { GEMINI_COST_MAP } from './geminiCostMap'; -import { GROQ_COST_MAP } from './groqCostMap'; -import { KV_COST_MAP } from './kvCostMap'; -import { MISTRAL_COST_MAP } from './mistralCostMap'; -import { OPENAI_COST_MAP } from './openAiCostMap'; -import { OPENAI_IMAGE_COST_MAP } from './openaiImageCostMap'; -import { OPENROUTER_COST_MAP } from './openrouterCostMap'; -import { OPENAI_VIDEO_COST_MAP } from './openaiVideoCostMap'; -import { TOGETHER_COST_MAP } from './togetherCostMap'; -import { XAI_COST_MAP } from './xaiCostMap'; -import { ELEVENLABS_COST_MAP } from './elevenlabsCostMap'; +import { AWS_POLLY_COST_MAP } from './awsPollyCostMap.js'; +import { AWS_TEXTRACT_COST_MAP } from './awsTextractCostMap.js'; +import { CLAUDE_COST_MAP } from './claudeCostMap.js'; +import { DEEPSEEK_COST_MAP } from './deepSeekCostMap.js'; +import { FILE_SYSTEM_COST_MAP } from './fileSystemCostMap.js'; +import { GEMINI_COST_MAP } from './geminiCostMap.js'; +import { GROQ_COST_MAP } from './groqCostMap.js'; +import { KV_COST_MAP } from './kvCostMap.js'; +import { MISTRAL_COST_MAP } from './mistralCostMap.js'; +import { OPENAI_COST_MAP } from './openAiCostMap.js'; +import { OPENAI_IMAGE_COST_MAP } from './openaiImageCostMap.js'; +import { OPENROUTER_COST_MAP } from './openrouterCostMap.js'; +import { OPENAI_VIDEO_COST_MAP } from './openaiVideoCostMap.js'; +import { TOGETHER_COST_MAP } from './togetherCostMap.js'; +import { XAI_COST_MAP } from './xaiCostMap.js'; +import { ELEVENLABS_COST_MAP } from './elevenlabsCostMap.js'; export const COST_MAPS = { ...AWS_POLLY_COST_MAP, diff --git a/src/backend/src/services/MeteringService/costMaps/openaiImageCostMap.ts b/src/backend/src/services/MeteringService/costMaps/openaiImageCostMap.ts index fc1c4a11..0aed3875 100644 --- a/src/backend/src/services/MeteringService/costMaps/openaiImageCostMap.ts +++ b/src/backend/src/services/MeteringService/costMaps/openaiImageCostMap.ts @@ -3,7 +3,7 @@ // All costs are in microcents (1/1,000,000th of a cent). Example: 1,000,000 microcents = $0.01 USD.// // Naming pattern: "openai:{model}:{size}" or "openai:{model}:hd:{size}" for HD images -import { toMicroCents } from '../utils'; +import { toMicroCents } from '../utils.js'; export const OPENAI_IMAGE_COST_MAP = { // DALL-E 3 diff --git a/src/backend/src/services/MeteringService/costMaps/openaiVideoCostMap.ts b/src/backend/src/services/MeteringService/costMaps/openaiVideoCostMap.ts index d4fda85a..f7ed45e6 100644 --- a/src/backend/src/services/MeteringService/costMaps/openaiVideoCostMap.ts +++ b/src/backend/src/services/MeteringService/costMaps/openaiVideoCostMap.ts @@ -1,4 +1,4 @@ -import { toMicroCents } from '../utils'; +import { toMicroCents } from '../utils.js'; // Prices are per generated video-second. export const OPENAI_VIDEO_COST_MAP = { diff --git a/src/backend/src/services/MeteringService/subPolicies/index.ts b/src/backend/src/services/MeteringService/subPolicies/index.ts index 4d1ee717..6db83db8 100644 --- a/src/backend/src/services/MeteringService/subPolicies/index.ts +++ b/src/backend/src/services/MeteringService/subPolicies/index.ts @@ -1,5 +1,5 @@ -import { REGISTERED_USER_FREE } from './registeredUserFreePolicy'; -import { TEMP_USER_FREE } from './tempUserFreePolicy'; +import { REGISTERED_USER_FREE } from './registeredUserFreePolicy.js'; +import { TEMP_USER_FREE } from './tempUserFreePolicy.js'; export const SUB_POLICIES = [ TEMP_USER_FREE, diff --git a/src/backend/src/services/MeteringService/subPolicies/registeredUserFreePolicy.ts b/src/backend/src/services/MeteringService/subPolicies/registeredUserFreePolicy.ts index 6c2a5369..59a99d91 100644 --- a/src/backend/src/services/MeteringService/subPolicies/registeredUserFreePolicy.ts +++ b/src/backend/src/services/MeteringService/subPolicies/registeredUserFreePolicy.ts @@ -1,4 +1,4 @@ -import { toMicroCents } from '../utils'; +import { toMicroCents } from '../utils.js'; export const REGISTERED_USER_FREE = { id: 'user_free', diff --git a/src/backend/src/services/MeteringService/subPolicies/tempUserFreePolicy.ts b/src/backend/src/services/MeteringService/subPolicies/tempUserFreePolicy.ts index 73f80da4..5754674f 100644 --- a/src/backend/src/services/MeteringService/subPolicies/tempUserFreePolicy.ts +++ b/src/backend/src/services/MeteringService/subPolicies/tempUserFreePolicy.ts @@ -1,4 +1,4 @@ -import { toMicroCents } from '../utils'; +import { toMicroCents } from '../utils.js'; export const TEMP_USER_FREE = { id: 'temp_free', diff --git a/src/backend/src/services/RegistryService.js b/src/backend/src/services/RegistryService.js index d16e0088..a9cac4b8 100644 --- a/src/backend/src/services/RegistryService.js +++ b/src/backend/src/services/RegistryService.js @@ -19,6 +19,8 @@ */ const { AdvancedBase } = require('@heyputer/putility'); const BaseService = require('./BaseService'); +const { kv } = require('../util/kvSingleton'); +const uuidv4 = require('uuid').v4; /** * @class MapCollection @@ -29,10 +31,6 @@ const BaseService = require('./BaseService'); * This class provides methods for basic CRUD operations (create, read, update, delete) on the key-value pairs, as well as methods for checking the existence of a key and retrieving all keys in the collection. */ class MapCollection extends AdvancedBase { - static MODULES = { - kv: globalThis.kv, - uuidv4: require('uuid').v4, - }; /** * @method MapCollection#_mk_key * @description Creates a unique key for the map collection. @@ -43,7 +41,7 @@ class MapCollection extends AdvancedBase { super(); // We use kvjs instead of a plain object because it doesn't // have a limit on the number of keys it can store. - this.map_id = this.modules.uuidv4(); + this.map_id = uuidv4(); this.kv = kv; } diff --git a/src/backend/src/services/RegistryService.test.ts b/src/backend/src/services/RegistryService.test.ts index 68ae2e24..367d5e9b 100644 --- a/src/backend/src/services/RegistryService.test.ts +++ b/src/backend/src/services/RegistryService.test.ts @@ -5,21 +5,21 @@ import { RegistryService } from './RegistryService'; describe('RegistryService', async () => { // Initialize globalThis.kv for testing beforeAll(() => { - if (!globalThis.kv) { + if ( ! globalThis.kv ) { globalThis.kv = new Map(); - globalThis.kv.set = function(key, value) { + globalThis.kv.set = function (key, value) { return Map.prototype.set.call(this, key, value); }; - globalThis.kv.get = function(key) { + globalThis.kv.get = function (key) { return Map.prototype.get.call(this, key); }; - globalThis.kv.exists = function(key) { + globalThis.kv.exists = function (key) { return this.has(key); }; - globalThis.kv.del = function(key) { + globalThis.kv.del = function (key) { return this.delete(key); }; - globalThis.kv.keys = function(pattern) { + globalThis.kv.keys = function (pattern) { const prefix = pattern.replace('*', ''); return Array.from(this.keys()).filter(k => k.startsWith(prefix)); }; @@ -72,27 +72,27 @@ describe('RegistryService', async () => { it('should allow checking existence in collection', () => { const collection = registryService.register_collection('exists-collection'); collection.set('existing-key', 'value'); - expect(collection.exists('existing-key')).toBe(true); - expect(collection.exists('non-existing-key')).toBe(false); + expect(collection.exists('existing-key')).toBeTruthy(); + expect(collection.exists('non-existing-key')).toBeFalsy(); }); - it('should allow deleting from collection', () => { + it('should allow deleting from collection', async () => { const collection = registryService.register_collection('delete-collection'); collection.set('delete-key', 'value'); - expect(collection.exists('delete-key')).toBe(true); + const res = collection.exists('delete-key'); + expect(collection.exists('delete-key')).toBeTruthy(); collection.del('delete-key'); - expect(collection.exists('delete-key')).toBe(false); + expect(collection.exists('delete-key')).toBeFalsy(); }); it('should support multiple independent collections', () => { const collection1 = registryService.register_collection('coll1'); const collection2 = registryService.register_collection('coll2'); - + collection1.set('key', 'value1'); collection2.set('key', 'value2'); - + expect(collection1.get('key')).toBe('value1'); expect(collection2.get('key')).toBe('value2'); }); }); - diff --git a/src/backend/src/services/SUService.d.ts b/src/backend/src/services/SUService.d.ts deleted file mode 100644 index 908c25b9..00000000 --- a/src/backend/src/services/SUService.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Actor } from './auth/Actor'; - -export class SUService { - _construct (): void; - get_system_actor (): Promise; - sudo(callback: () => Promise): Promise; - sudo(actorOrCallback: Actor, callback: () => Promise): Promise; -} \ No newline at end of file diff --git a/src/backend/src/services/SUService.js b/src/backend/src/services/SUService.js index ebc1880c..0e99ae98 100644 --- a/src/backend/src/services/SUService.js +++ b/src/backend/src/services/SUService.js @@ -18,10 +18,10 @@ */ // METADATA // {"ai-commented":{"service":"openai-completion","model":"gpt-4o-mini"}} -const { Context } = require('../util/context'); -const { TeePromise } = require('@heyputer/putility').libs.promise; -const { Actor, UserActorType } = require('./auth/Actor'); -const BaseService = require('./BaseService'); +import { TeePromise } from '@heyputer/putility/src/libs/promise.js'; +import { Context } from '../util/context.js'; +import { Actor, UserActorType } from './auth/Actor.js'; +import BaseService from './BaseService.js'; /** * "SUS"-Service (Super-User Service) @@ -33,7 +33,7 @@ const BaseService = require('./BaseService'); * instances, providing methods to retrieve the system actor * and perform actions with elevated privileges. */ -class SUService extends BaseService { +export class SUService extends BaseService { /** * Initializes the SUService instance, creating promises for system user * and system actor. This method does not take any parameters and does @@ -110,8 +110,4 @@ class SUService extends BaseService { user: actor.type.user, }).arun(callback); } -} - -module.exports = { - SUService, -}; +} \ No newline at end of file diff --git a/src/backend/src/services/User.d.ts b/src/backend/src/services/User.d.ts index 4b3f8aba..cf6a764b 100644 --- a/src/backend/src/services/User.d.ts +++ b/src/backend/src/services/User.d.ts @@ -4,7 +4,7 @@ export interface IUser { id: number, uuid: string, username: string, - email: string, + email?: string, subscription?: (typeof SUB_POLICIES)[number]['id'], metadata?: Record & { hasDevAccountAccess?: boolean } } \ No newline at end of file diff --git a/src/backend/src/modules/puterai/AIInterfaceService.js b/src/backend/src/services/ai/AIInterfaceService.js similarity index 99% rename from src/backend/src/modules/puterai/AIInterfaceService.js rename to src/backend/src/services/ai/AIInterfaceService.js index 0efb09be..988d1964 100644 --- a/src/backend/src/modules/puterai/AIInterfaceService.js +++ b/src/backend/src/services/ai/AIInterfaceService.js @@ -18,7 +18,7 @@ */ // METADATA // {"ai-commented":{"service":"claude"}} -const BaseService = require('../../services/BaseService'); +const BaseService = require('../BaseService'); /** * Service class that manages AI interface registrations and configurations. diff --git a/src/backend/src/modules/puterai/README.md b/src/backend/src/services/ai/README.md similarity index 100% rename from src/backend/src/modules/puterai/README.md rename to src/backend/src/services/ai/README.md diff --git a/src/backend/src/services/ai/chat/.gitignore b/src/backend/src/services/ai/chat/.gitignore new file mode 100644 index 00000000..aa4a6da2 --- /dev/null +++ b/src/backend/src/services/ai/chat/.gitignore @@ -0,0 +1,2 @@ +*.js +*.js.map \ No newline at end of file diff --git a/src/backend/src/services/ai/chat/AIChatService.ts b/src/backend/src/services/ai/chat/AIChatService.ts new file mode 100644 index 00000000..d7eef48b --- /dev/null +++ b/src/backend/src/services/ai/chat/AIChatService.ts @@ -0,0 +1,652 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +// METADATA // {"ai-commented":{"service":"claude"}} +import { createId as cuid2 } from '@paralleldrive/cuid2'; +import { PassThrough } from 'stream'; +import { APIError } from '../../../api/APIError.js'; +import { ErrorService } from '../../../modules/core/ErrorService.js'; +import { Context } from '../../../util/context.js'; +import { kv } from '../../../util/kvSingleton.js'; +import BaseService from '../../BaseService.js'; +import { BaseDatabaseAccessService } from '../../database/BaseDatabaseAccessService.js'; +import { DB_WRITE } from '../../database/consts.js'; +import { DriverService } from '../../drivers/DriverService.js'; +import { TypedValue } from '../../drivers/meta/Runtime.js'; +import { EventService } from '../../EventService.js'; +import { MeteringService } from '../../MeteringService/MeteringService.js'; +import { AsModeration } from '../moderation/AsModeration.js'; +import { normalize_tools_object } from '../utils/FunctionCalling.js'; +import { extract_text, normalize_messages, normalize_single_message } from '../utils/Messages.js'; +import Streaming from '../utils/Streaming.js'; +import { ClaudeProvider } from './providers/ClaudeProvider/ClaudeProvider.js'; +import { FakeChatProvider } from './providers/FakeChatProvider.js'; +import { GeminiChatProvider } from './providers/GeminiProvider/GeminiChatProvider.js'; +import { GroqAIProvider } from './providers/GroqAiProvider/GroqAIProvider.js'; +import { MistralAIProvider } from './providers/MistralAiProvider/MistralAiProvider.js'; +import { OpenAiChatProvider } from './providers/OpenAiProvider/OpenAiChatProvider.js'; +import { IChatModel, IChatProvider, ICompleteArguments } from './providers/types.js'; +import { UsageLimitedChatProvider } from './providers/UsageLimitedChatProvider.js'; +import { OllamaChatProvider } from './providers/OllamaProvider.js'; +import { DeepSeekProvider } from './providers/DeepSeekProvider/DeepSeekProvider.js'; +import { XAIProvider } from './providers/XAIProvider/XAIProvider.js'; +import { TogetherAIProvider } from './providers/TogetherAiProvider/TogetherAIProvider.js'; +import { OpenRouterProvider } from './providers/OpenRouterProvider/OpenRouterProvider.js'; + +// Maximum number of fallback attempts when a model fails, including the first attempt +const MAX_FALLBACKS = 3 + 1; // includes first attempt + +export class AIChatService extends BaseService { + + static SERVICE_NAME = 'ai-chat'; + + static DEFAULT_PROVIDER = 'openai-completion'; + + get meteringService (): MeteringService { + return this.services.get('meteringService').meteringService; + } + + get db (): BaseDatabaseAccessService { + return this.services.get('database').get(DB_WRITE, 'ai-service'); + } + + get errorService (): ErrorService { + return this.services.get('error-service'); + } + + get eventService (): EventService { + return this.services.get('event'); + } + + get driverService (): DriverService { + return this.services.get('driver'); + } + + getProvider (name: string): IChatProvider | undefined { + return this.#providers[name]; + } + + #providers: Record = {}; + #modelIdMap: Record = {}; + + /** Driver interfaces */ + static IMPLEMENTS = { + ['driver-capabilities']: { + supports_test_mode (iface: string, method_name: string) { + return iface === 'puter-chat-completion' && + method_name === 'complete'; + }, + }, + ['puter-chat-completion']: { + + async models () { + return await (this as unknown as AIChatService).models(); + }, + + async list () { + return await (this as unknown as AIChatService).list(); + }, + + async complete (...parameters: Parameters) { + return await (this as unknown as AIChatService).complete(...parameters); + }, + }, + }; + + getModel ({ modelId, provider}: { modelId: string, provider?: string }) { + const models = this.#modelIdMap[modelId]; + + if ( ! models ) { + throw new Error(`Model not found, please try one of the following models: ${ Object.keys(this.#modelIdMap).join(', ')}`); + } + if ( ! provider ) { + return models[0]; + } + const model = models.find(m => m.provider === provider); + return model ?? models[0]; + } + + private async registerProviders () { + const claudeConfig = this.config.providers?.['claude'] || this.global_config?.services?.['claude']; + if ( claudeConfig && claudeConfig.apiKey ) { + this.#providers['claude'] = new ClaudeProvider(this.meteringService, claudeConfig, this.errorService); + } + const openAiConfig = this.config.providers?.['openai-completion'] || this.global_config?.services?.['openai-completion'] || this.global_config?.openai; + if ( openAiConfig && (openAiConfig.apiKey || openAiConfig.secret_key) ) { + this.#providers['openai-completion'] = new OpenAiChatProvider(this.meteringService, openAiConfig); + } + const geminiConfig = this.config.providers?.['gemini'] || this.global_config?.services?.['gemini']; + if ( geminiConfig && geminiConfig.apiKey ) { + this.#providers['gemini'] = new GeminiChatProvider(this.meteringService, geminiConfig); + } + const groqConfig = this.config.providers?.['groq'] || this.global_config?.services?.['groq']; + if ( groqConfig && groqConfig.apiKey ) { + this.#providers['groq'] = new GroqAIProvider(groqConfig, this.meteringService); + } + const deepSeekConfig = this.config.providers?.['deepseek'] || this.global_config?.services?.['deepseek']; + if ( deepSeekConfig && deepSeekConfig.apiKey ) { + this.#providers['deepseek'] = new DeepSeekProvider(deepSeekConfig, this.meteringService); + } + const mistralConfig = this.config.providers?.['mistral'] || this.global_config?.services?.['mistral']; + if ( mistralConfig && mistralConfig.apiKey ) { + this.#providers['mistral'] = new MistralAIProvider(mistralConfig, this.meteringService); + } + const xaiConfig = this.config.providers?.['xai'] || this.global_config?.services?.['xai']; + if ( xaiConfig && xaiConfig.apiKey ) { + this.#providers['xai'] = new XAIProvider(xaiConfig, this.meteringService); + } + const togetherConfig = this.config.providers?.['together-ai'] || this.global_config?.services?.['together-ai']; + if ( togetherConfig && togetherConfig.apiKey ) { + this.#providers['together-ai'] = new TogetherAIProvider(togetherConfig, this.meteringService); + } + const openrouterConfig = this.config.providers?.['openrouter'] || this.global_config?.services?.['openrouter']; + if ( openrouterConfig && openrouterConfig.apiKey ) { + this.#providers['openrouter'] = new OpenRouterProvider(openrouterConfig, this.meteringService); + } + + // ollama if local instance detected + + // Autodiscover Ollama service and then check if its disabled in the config + // if config.services.ollama.enabled is undefined, it means the user hasn't set it, so we should default to true + const ollamaConfig = this.config.providers?.['ollama'] || this.global_config?.services?.ollama; + const ollama_available = await fetch('http://localhost:11434/api/tags').then(resp => resp.json()).then(_data => { + if ( ollamaConfig?.enabled === undefined ) { + return true; + } + return ollamaConfig?.enabled; + }).catch(_err => { + return false; + }); + // User can disable ollama in the config, but by default it should be enabled if discovery is successful + if ( ollama_available || ollamaConfig?.enabled ) { + console.log('Local AI support detected! Registering Ollama'); + this.#providers['ollama'] = new OllamaChatProvider(ollamaConfig, this.meteringService); + } + + // fake and usage-limited providers last + this.#providers['fake-chat'] = new FakeChatProvider(); + this.#providers['usage-limited-chat'] = new UsageLimitedChatProvider(); + + // emit event for extensions to add providers + const extensionProviders = {} as Record; + await this.eventService.emit('ai.chat.registerProviders', extensionProviders); + for ( const providerName in extensionProviders ) { + if ( this.#providers[providerName] ) { + console.warn('AIChatService: provider name conflict for ', providerName, ' registering with -extension suffix'); + this.#providers[`${providerName}-extension`] = extensionProviders[providerName]; + continue; + } + this.#providers[providerName] = extensionProviders[providerName]; + } + } + + protected async '__on_boot.consolidation' () { + // register chat providers here + await this.registerProviders(); + + // build model id map + for ( const providerName in this.#providers ) { + const provider = this.#providers[providerName]; + + // alias all driver requests to go here to support legacy routing + this.driverService.register_service_alias(AIChatService.SERVICE_NAME, + providerName, + { iface: 'puter-chat-completion' }); + + // build model id map + for ( const model of await provider.models() ) { + model.id = model.id.trim().toLowerCase(); + if ( ! this.#modelIdMap[model.id] ) { + this.#modelIdMap[model.id] = []; + } + this.#modelIdMap[model.id].push({ ...model, provider: providerName }); + if ( model.aliases ) { + for ( let alias of model.aliases ) { + alias = alias.trim().toLowerCase(); + // join arrays which are aliased the same + if ( ! this.#modelIdMap[alias] ) { + this.#modelIdMap[alias] = this.#modelIdMap[model.id]; + continue; + } + if ( this.#modelIdMap[alias] !== this.#modelIdMap[model.id] ) { + this.#modelIdMap[alias].push({ ...model, provider: providerName }); + this.#modelIdMap[model.id] = this.#modelIdMap[alias]; + continue; + } + } + } + this.#modelIdMap[model.id].sort((a, b) => { + if ( a.costs[a.input_cost_key || 'input_tokens'] === b.costs[b.input_cost_key || 'input_tokens'] ) { + return a.id.length - b.id.length; // use shorter id since its likely the official one + } + return a.costs[a.input_cost_key || 'input_tokens'] - b.costs[b.input_cost_key || 'input_tokens']; + }); + } + } + } + + models () { + const seen = new Set(); + return Object.entries(this.#modelIdMap) + .map(([_, models]) => models) + .flat() + .filter(model => { + if ( seen.has(model.id) ) { + return false; + } + seen.add(model.id); + return true; + }) + .sort((a, b) => { + if ( a.provider === b.provider ) { + return a.id.localeCompare(b.id); + } + return a.provider!.localeCompare(b.provider!); + }); + } + + list () { + return this.models().map(m => m.id).sort(); + } + + async complete (parameters: ICompleteArguments) { + const clientDriverCall = Context.get('client_driver_call'); + let { test_mode: testMode, response_metadata: resMetadata, intended_service: legacyProviderName } = clientDriverCall as { test_mode?: boolean; response_metadata: Record; intended_service?: string }; + const actor = Context.get('actor'); + + let intendedProvider = parameters.provider || legacyProviderName === AIChatService.SERVICE_NAME ? '' : legacyProviderName ; // should now all go through here + + if ( !parameters.model && !intendedProvider ) { + intendedProvider = AIChatService.DEFAULT_PROVIDER; + } + if ( !parameters.model && intendedProvider ) { + parameters.model = this.#providers[intendedProvider].getDefaultModel(); + } + let model = this.getModel({ modelId: parameters.model, provider: intendedProvider }) || this.getFallbackModel(parameters.model, [], []); + const abuseModel = this.getModel({ modelId: 'abuse' }); + const usageLimitedModel = this.getModel({ modelId: 'usage-limited' }); + + const completionId = cuid2(); + const event = { + actor, + completionId, + allow: true, + intended_service: intendedProvider || '', + parameters, + } as Record; + await this.eventService.emit('ai.prompt.validate', event); + if ( ! event.allow ) { + testMode = true; + if ( event.custom ) parameters.custom = event.custom; + } + + if ( parameters.messages ) { + parameters.messages = + normalize_messages(parameters.messages); + } + + // Skip moderation for Ollama (local service) and other local services + const should_moderate = !testMode && + parameters.provider !== 'ollama'; + + if ( should_moderate && !await this.moderate(parameters) ) { + testMode = true; + throw APIError.create('moderation_failed'); + } + + // Only set moderated flag if we actually ran moderation + if ( !testMode && should_moderate ) { + Context.set('moderated', true); + } + + if ( testMode ) { + if ( event.abuse ) { + model = abuseModel; + } + } + + if ( parameters.tools ) { + normalize_tools_object(parameters.tools); + } + + if ( ! model ) { + // TODO DS: route them to new endpoints once ready + const availableModelsUrl = `${this.global_config.origin }/puterai/chat/models`; + + throw APIError.create('field_invalid', undefined, { + key: 'model', + expected: `a valid model name from ${availableModelsUrl}`, + got: model, + }); + } + + const inputTokenCost = model.costs[model.input_cost_key || 'input_tokens'] as number; + const outputTokenCost = model.costs[model.output_cost_key || 'output_tokens'] as number; + const maxTokens = model.max_tokens; + const text = extract_text(parameters.messages); + const approximateTokenCount = Math.floor(((text.length / 4) + (text.split(/\s+/).length * (4 / 3))) / 2); // see https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them + const approximateInputCost = approximateTokenCount * inputTokenCost; + const usageAllowed = await this.meteringService.hasEnoughCredits(actor, approximateInputCost); + + // Handle usage limits reached case + if ( ! usageAllowed ) { + model = usageLimitedModel; + } + + const availableCredits = await this.meteringService.getRemainingUsage(actor); + const maxAllowedOutput = + availableCredits - approximateInputCost; + + const maxAllowedOutputTokens = + maxAllowedOutput / outputTokenCost; + + if ( maxAllowedOutputTokens ) { + parameters.max_tokens = Math.floor(Math.min(parameters.max_tokens ?? Number.POSITIVE_INFINITY, + maxAllowedOutputTokens, + maxTokens - approximateTokenCount)); + if ( parameters.max_tokens < 1 ) { + parameters.max_tokens = undefined; + } + } + + // call model provider; + let res: Awaited>; + const provider = this.#providers[model.provider!]; + if ( ! provider ) { + throw new Error(`no provider found for model ${model.id}`); + } + try { + res = await provider.complete({ + ...parameters, + model: model.id, + provider: model.provider, + }); + } catch (e) { + const tried: string[] = []; + const triedProviders: string[] = []; + + tried.push(model.id); + triedProviders.push(model.provider!); + + let error = e as Error; + + while ( error ) { + + // TODO: simplify our error handling + // Distinguishing between user errors and service errors + // is very messy because of different conventions between + // services. This is a best-effort attempt to catch user + // errors and throw them as 400s. + const isRequestError = (() => { + if ( error instanceof APIError ) { + return true; + } + if ( (error as unknown as { type: string }).type === 'invalid_request_error' ) { + return true; + } + })(); + + if ( isRequestError ) { + console.error((error as Error)); + throw APIError.create('error_400_from_delegate', error as Error, { + delegate: model.provider, + message: (error as Error).message, + }); + } + + if ( this.config.disable_fallback_mechanisms ) { + console.error((error as Error)); + throw error; + } + + console.error('error calling ai chat provider for model: ', model, '\n trying fallbacks...'); + + // No fallbacks for pseudo-models + if ( model.provider === 'fake-chat' ) { + break; + } + + const fallback = this.getFallbackModel(model.id, tried, triedProviders); + + if ( ! fallback ) { + throw new Error('no fallback model available'); + } + + const { + fallbackModelId, + fallbackProvider, + } = fallback; + + console.warn('model fallback', { + fallbackModelId, + fallbackProvider, + }); + + let fallBackModel = this.getModel({ modelId: fallbackModelId, provider: fallbackProvider }); + + const fallbackUsageAllowed = await this.meteringService.hasEnoughCredits(actor, 1); // we checked earlier, assume same costs + + if ( ! fallbackUsageAllowed ) { + fallBackModel = usageLimitedModel; + } + + const provider = this.#providers[fallBackModel.provider!]; + if ( ! provider ) { + throw new Error(`no provider found for model ${fallBackModel.id}`); + } + try { + res = await provider.complete({ + ...parameters, + model: fallBackModel.id, + provider: fallBackModel.provider, + }); + model = fallBackModel; + break; // success + } catch (e) { + console.error('error during fallback selection: ', e); + error = e as Error; + } + } + } + + resMetadata.service_used = model.provider; // legacy field + resMetadata.providerUsed = model.id; + + // Add flag if we're using the usage-limited service + if ( model.provider === 'usage-limited-chat' ) { + resMetadata.usage_limited = true; + } + + const username = actor.type?.user?.username; + + if ( ! res! ) { + throw new Error('No response from AI chat provider'); + } + + res.via_ai_chat_service = true; // legacy field always true now + if ( res.stream ) { + if ( res.init_chat_stream ) { + const stream = new PassThrough(); + // TODO DS: simplify how we handle streaming responses and remove custom runtime types + const retval = new TypedValue({ + $: 'stream', + content_type: 'application/x-ndjson', + chunked: true, + }, stream); + + const chatStream = new Streaming.AIChatStream({ + stream, + }); + + (async () => { + try { + await res.init_chat_stream({ chatStream }); + } catch (e) { + this.errors.report('error during stream response', { + source: e, + }); + stream.write(`${JSON.stringify({ + type: 'error', + message: (e as Error).message, + }) }\n`); + stream.end(); + } finally { + if ( res.finally_fn ) { + await res.finally_fn(); + } + } + })(); + + return retval; + } + + return res; + } + await this.eventService.emit('ai.prompt.complete', { + username, + intended_service: intendedProvider, + parameters, + result: res, + model_used: model.id, + service_used: model.provider, + }); + + if ( parameters.response?.normalize ) { + res = { + ...res, + message: normalize_single_message(res.message), + normalized: true, + }; + } + return res; + + } + + async moderate ({ messages }: { messages: Array; }) { + if ( process.env.TEST_MODERATION_FAILURE ) return false; + const fulltext = extract_text(messages); + let mod_last_error; + let mod_result: Awaited>; + try { + const openaiProvider = this.#providers['openai-completion']; + mod_result = await openaiProvider.checkModeration(fulltext); + if ( mod_result.flagged ) return false; + return true; + } catch (e) { + console.error(e); + mod_last_error = e; + } + try { + const claudeChatProvider = this.#providers['claude']; + const mod = new AsModeration({ + chatProvider: claudeChatProvider, + model: 'claude-3-haiku-20240307', + }); + if ( ! await mod.moderate(fulltext) ) { + return false; + } + mod_last_error = null; + return true; + } catch (e) { + console.error(e); + mod_last_error = e; + } + + if ( mod_last_error ) { + this.log.error('moderation error', { + fulltext, + mod_last_error, + }); + throw new Error('no working moderation service'); + } + return true; + } + + /** + * Find an appropriate fallback model by sorting the list of models + * by the euclidean distance of the input/output prices and selecting + * the first one that is not in the tried list. + * + * @param {*} param0 + * @returns + */ + getFallbackModel (modelId: string, triedIds: string[], triedProviders: string[]) { + const models = this.#modelIdMap[modelId]; + + if ( ! models ) { + this.log.error('could not find model', { modelId }); + throw new Error('could not find model'); + } + + const targetModel = models[0]; + + // First see if any models with the same id but different provider exist + for ( const model of models ) { + if ( triedProviders.includes(model.provider!) ) continue; + if ( model.provider === 'fake-chat' ) continue; + return { + fallbackProvider: model.provider, + fallbackModelId: model.id, + }; + } + + // First check KV for the sorted list + let potentialFallbacks = kv.get(`aichat:fallbacks:${targetModel.id}`); + + if ( ! potentialFallbacks ) { + // Calculate the sorted list + const models = this.models(); + + let aiProvider, modelToSearch; + if ( targetModel.id.startsWith('openrouter:') || targetModel.id.startsWith('togetherai:') ) { + [aiProvider, modelToSearch] = targetModel.id.replace('openrouter:', '').replace('togetherai:', '').toLowerCase().split('/'); + } else { + [aiProvider, modelToSearch] = targetModel.provider!.toLowerCase().replace('gemini', 'google').replace('openai-completion', 'openai'), targetModel.id.toLowerCase(); + } + + const potentialMatches = models.filter(model => { + const possibleModelNames = [`openrouter:${aiProvider}/${modelToSearch}`, + `togetherai:${aiProvider}/${modelToSearch}`, ...(targetModel.aliases?.map((alias) => [`openrouter:${aiProvider}/${alias}`, + `togetherai:${aiProvider}/${alias}`])?.flat() ?? [])]; + + return !!possibleModelNames.find(possibleName => model.id.toLowerCase() === possibleName); + }).slice(0, MAX_FALLBACKS); + + kv.set(`aichat:fallbacks:${modelId}`, potentialMatches); + potentialFallbacks = potentialMatches; + } + + for ( const model of potentialFallbacks ) { + if ( triedIds.includes(model.id) ) continue; + if ( model.provider === 'fake-chat' ) continue; + + return { + fallbackProvider: model.provider, + fallbackModelId: model.id, + }; + } + + // No fallbacks available + console.error('no fallbacks', { + potentialFallbacks, + triedIds, + triedProviders, + }); + } +} diff --git a/src/backend/src/services/ai/chat/providers/ChatProvider.ts b/src/backend/src/services/ai/chat/providers/ChatProvider.ts new file mode 100644 index 00000000..78c40094 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/ChatProvider.ts @@ -0,0 +1,26 @@ +import { ModerationCreateResponse } from 'openai/resources/moderations.js'; +import { IChatModel, IChatProvider, ICompleteArguments } from './types'; + +/** + * Abstract base class for AI chat providers, and default hollow implementation; + */ +export class ChatProvider implements IChatProvider { + getDefaultModel (): string { + return ''; + } + models (): IChatModel[] | Promise { + return []; + } + list (): string[] | Promise { + return []; + } + async checkModeration (_text: string): ReturnType { + return { + flagged: false, + results: {} as ModerationCreateResponse, + }; + } + async complete (_arg: ICompleteArguments): ReturnType { + throw new Error('Method not implemented.'); + } +} \ No newline at end of file diff --git a/src/backend/src/modules/puterai/ClaudeService.test.ts b/src/backend/src/services/ai/chat/providers/ClaudeProvider/ClaudeProvider.test.ts similarity index 70% rename from src/backend/src/modules/puterai/ClaudeService.test.ts rename to src/backend/src/services/ai/chat/providers/ClaudeProvider/ClaudeProvider.test.ts index fccccdc7..ea77051b 100644 --- a/src/backend/src/modules/puterai/ClaudeService.test.ts +++ b/src/backend/src/services/ai/chat/providers/ClaudeProvider/ClaudeProvider.test.ts @@ -1,33 +1,25 @@ import { describe, expect, it, test } from 'vitest'; -import { createTestKernel } from '../../../tools/test.mjs'; -import { COST_MAPS } from '../../services/MeteringService/costMaps'; -import { SUService } from '../../services/SUService'; -import { AIChatService } from './AIChatService'; -import { ClaudeService } from './ClaudeService'; +import { createTestKernel } from '../../../../../../tools/test.mjs'; +import { COST_MAPS } from '../../../../MeteringService/costMaps/index.js'; +import { SUService } from '../../../../SUService.js'; +import { ClaudeProvider } from './ClaudeProvider.js'; -describe('ClaudeService ', async () => { +describe('ClaudeProvider ', async () => { const testKernel = await createTestKernel({ - serviceMap: { - 'claude': ClaudeService, - 'ai-chat': AIChatService, - }, initLevelString: 'init', testCore: true, serviceConfigOverrideMap: { 'database': { path: ':memory:', }, - 'claude': { - apiKey: process.env.PUTER_CLAUDE_API_KEY, - }, }, }); - const target = testKernel.services!.get('claude') as ClaudeService; + const target = new ClaudeProvider(testKernel.services!.get('meteringService'), { apiKey: process.env.PUTER_CLAUDE_API_KEY || '' }, testKernel.services?.get('error-service')); const su = testKernel.services!.get('su') as SUService; it('should have all models mapped in cost maps', async () => { - const models = await target.models(); + const models = target.models(); for ( const model of models ) { const entry = Object.entries(COST_MAPS).find(([key, _value]) => key.startsWith('claude') && key.includes(model.id)); diff --git a/src/backend/src/services/ai/chat/providers/ClaudeProvider/ClaudeProvider.ts b/src/backend/src/services/ai/chat/providers/ClaudeProvider/ClaudeProvider.ts new file mode 100644 index 00000000..24bce237 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/ClaudeProvider/ClaudeProvider.ts @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +// METADATA // {"ai-commented":{"service":"claude"}} +import Anthropic, { toFile } from '@anthropic-ai/sdk'; +import { Message } from '@anthropic-ai/sdk/resources'; +import { BetaUsage } from '@anthropic-ai/sdk/resources/beta.js'; +import { MessageCreateParams as BetaMessageCreateParams } from '@anthropic-ai/sdk/resources/beta/messages/messages.js'; +import { MessageCreateParams, Usage } from '@anthropic-ai/sdk/resources/messages.js'; +import mime from 'mime-types'; +import FSNodeParam from '../../../../../api/filesystem/FSNodeParam.js'; +import { LLRead } from '../../../../../filesystem/ll_operations/ll_read.js'; +import { ErrorService } from '../../../../../modules/core/ErrorService.js'; +import { Context } from '../../../../../util/context.js'; +import { MeteringService } from '../../../../MeteringService/MeteringService.js'; +import { make_claude_tools } from '../../../utils/FunctionCalling.js'; +import { extract_and_remove_system_messages } from '../../../utils/Messages.js'; +import { AIChatStream, AIChatTextStream, AIChatToolUseStream } from '../../../utils/Streaming.js'; +import { IChatProvider, ICompleteArguments } from '../types.js'; +import { CLAUDE_MODELS } from './models.js'; +export class ClaudeProvider implements IChatProvider { + anthropic: Anthropic; + + #meteringService: MeteringService; + + errorService: ErrorService; + + constructor (meteringService: MeteringService, config: { apiKey: string }, errorService: ErrorService) { + + this.#meteringService = meteringService; + this.errorService = errorService; + this.anthropic = new Anthropic({ + apiKey: config.apiKey, + // 10 minutes is the default; we need to override the timeout to + // disable an "aggressive" preemptive error that's thrown + // erroneously by the SDK. + // (https://github.com/anthropics/anthropic-sdk-typescript/issues/822) + timeout: 10 * 60 * 1001, + }); + } + getDefaultModel () { + return 'claude-haiku-4-5-20251001'; + } + + async list () { + const models = this.models(); + const model_names: string[] = []; + for ( const model of models ) { + model_names.push(model.id); + if ( model.aliases ) { + model_names.push(...model.aliases); + } + } + return model_names; + } + + async complete ({ messages, stream, model, tools, max_tokens, temperature }: ICompleteArguments): ReturnType { + tools = make_claude_tools(tools); + + let system_prompts: string | any[]; + // unsure why system_prompts is an array but it always seems to only have exactly one element, + // and the real array of system_prompts seems to be the [0].content -- NS + [system_prompts, messages] = extract_and_remove_system_messages(messages); + + // Apply the cache control tag to all content blocks + if ( + system_prompts.length > 0 && + system_prompts[0].cache_control && + system_prompts[0]?.content + ) { + system_prompts[0].content = system_prompts[0].content.map((prompt: { cache_control: unknown }) => { + prompt.cache_control = system_prompts[0].cache_control; + return prompt; + }); + } + + messages = messages.map(message => { + if ( message.cache_control ) { + message.content[0].cache_control = message.cache_control; + } + delete message.cache_control; + return message; + }); + + const modelUsed = this.models().find(m => [m.id, ...(m.aliases || [])].includes(model)) || this.models().find(m => m.id === this.getDefaultModel())!; + const sdkParams: MessageCreateParams = { + model: modelUsed.id, + max_tokens: Math.floor(max_tokens || + (( + model === 'claude-3-5-sonnet-20241022' + || model === 'claude-3-5-sonnet-20240620' + ) ? 8192 : this.models().filter(e => (e.name === model || e.aliases?.includes(model)))[0]?.max_tokens || 4096)), //required + temperature: temperature || 0, // required + ...( (system_prompts && system_prompts[0]?.content) ? { + system: system_prompts[0]?.content, + } : {}), + tool_choice: { + type: 'auto', + disable_parallel_tool_use: true, + }, + messages, + ...(tools ? { tools } : {}), + } as MessageCreateParams; + + let beta_mode = false; + + // Perform file uploads + const file_delete_tasks: { file_id: string }[] = []; + const actor = Context.get('actor'); + const { user } = actor.type; + + const file_input_tasks: any[] = []; + for ( const message of messages ) { + // We can assume `message.content` is not undefined because + // Messages.normalize_single_message ensures this. + for ( const contentPart of message.content ) { + if ( ! contentPart.puter_path ) continue; + file_input_tasks.push({ + node: await (new FSNodeParam(contentPart.puter_path)).consolidate({ + req: { user }, + getParam: () => contentPart.puter_path, + }), + contentPart, + }); + } + } + + const promises: Promise[] = []; + for ( const task of file_input_tasks ) { + promises.push((async () => { + const ll_read = new LLRead(); + const stream = await ll_read.run({ + actor: Context.get('actor'), + fsNode: task.node, + }); + + const mimeType = mime.contentType(await task.node.get('name')); + + beta_mode = true; + const fileUpload = await this.anthropic.beta.files.upload({ + file: await toFile(stream, undefined, { type: mimeType as string }), + }, { + betas: ['files-api-2025-04-14'], + } as Parameters[1]); + + file_delete_tasks.push({ file_id: fileUpload.id }); + // We have to copy a table from the documentation here: + // https://docs.anthropic.com/en/docs/build-with-claude/files + const contentBlockTypeForFileBasedOnMime = (() => { + if ( mimeType && mimeType.startsWith('image/') ) { + return 'image'; + } + if ( mimeType && mimeType.startsWith('text/') ) { + return 'document'; + } + if ( mimeType && mimeType === 'application/pdf' || mimeType === 'application/x-pdf' ) { + return 'document'; + } + return 'container_upload'; + })(); + + delete task.contentPart.puter_path, + task.contentPart.type = contentBlockTypeForFileBasedOnMime; + task.contentPart.source = { + type: 'file', + file_id: fileUpload.id, + }; + })()); + } + await Promise.all(promises); + + const cleanup_files = async () => { + const promises: Promise[] = []; + for ( const task of file_delete_tasks ) { + promises.push((async () => { + try { + await this.anthropic.beta.files.delete(task.file_id, + { betas: ['files-api-2025-04-14'] }); + } catch (e) { + this.errorService.report('claude:file-delete-task', { + source: e, + trace: true, + alarm: true, + extra: { file_id: task.file_id }, + }); + } + })()); + } + await Promise.all(promises); + }; + + if ( beta_mode ) { + (sdkParams as BetaMessageCreateParams).betas = ['files-api-2025-04-14']; + } + const anthropic = (beta_mode ? this.anthropic.beta : this.anthropic) as Anthropic; + + if ( stream ) { + const init_chat_stream = async ({ chatStream }: { chatStream: AIChatStream }) => { + const completion = await anthropic.messages.stream(sdkParams as MessageCreateParams); + const usageSum: Record = {}; + + let message, contentBlock; + for await ( const event of completion ) { + + if ( event.type === 'message_delta' ) { + const usageObject = (event?.usage ?? {}); + const meteredData = this.#usageFormatterUtil(usageObject as Usage | BetaUsage); + + for ( const key in meteredData ) { + if ( ! usageSum[key] ) usageSum[key] = 0; + usageSum[key] += meteredData[key as keyof typeof meteredData]; + } + } + + if ( event.type === 'message_start' ) { + message = chatStream.message(); + continue; + } + if ( event.type === 'message_stop' ) { + message!.end(); + message = null; + continue; + } + + if ( event.type === 'content_block_start' ) { + if ( event.content_block.type === 'tool_use' ) { + contentBlock = message!.contentBlock({ + type: event.content_block.type, + id: event.content_block.id, + name: event.content_block.name, + }); + continue; + } + contentBlock = message!.contentBlock({ + type: event.content_block.type, + }); + continue; + } + + if ( event.type === 'content_block_stop' ) { + contentBlock!.end(); + contentBlock = null; + continue; + } + + if ( event.type === 'content_block_delta' ) { + if ( event.delta.type === 'input_json_delta' ) { + (contentBlock as AIChatToolUseStream)!.addPartialJSON(event.delta.partial_json); + continue; + } + if ( event.delta.type === 'text_delta' ) { + (contentBlock as AIChatTextStream)!.addText(event.delta.text); + continue; + } + } + } + chatStream.end(usageSum); + const costsOverrideFromModel = Object.fromEntries(Object.entries(usageSum).map(([k, v]) => { + return [k, v * (modelUsed.costs[k] || 0)]; + })); + this.#meteringService.utilRecordUsageObject(usageSum, actor, `claude:${modelUsed.id}`, costsOverrideFromModel); + }; + + return { + init_chat_stream, + stream: true, + finally_fn: cleanup_files, + }; + } + + const msg = await anthropic.messages.create(sdkParams); + await cleanup_files(); + + const usage = this.#usageFormatterUtil((msg as Message).usage as Usage | BetaUsage); + const costsOverrideFromModel = Object.fromEntries(Object.entries(usage).map(([k, v]) => { + return [k, v * (modelUsed.costs[k] || 0)]; + })); + this.#meteringService.utilRecordUsageObject(usage, actor, `claude:${modelUsed.id}`, costsOverrideFromModel); + + // TODO DS: cleanup old usage tracking + return { + message: msg, + usage: usage, + finish_reason: 'stop', + }; + } + + #usageFormatterUtil (usage: Usage | BetaUsage) { + return { + input_tokens: usage?.input_tokens || 0, + ephemeral_5m_input_tokens: usage?.cache_creation?.ephemeral_5m_input_tokens || usage.cache_creation_input_tokens || 0, // this is because they're api is a bit inconsistent + ephemeral_1h_input_tokens: usage?.cache_creation?.ephemeral_1h_input_tokens || 0, + cache_read_input_tokens: usage?.cache_read_input_tokens || 0, + output_tokens: usage?.output_tokens || 0, + }; + }; + + models () { + return CLAUDE_MODELS; + } + + checkModeration (_text: string): ReturnType { + throw new Error('CheckModeration Not provided.'); + } +} \ No newline at end of file diff --git a/src/backend/src/services/ai/chat/providers/ClaudeProvider/models.ts b/src/backend/src/services/ai/chat/providers/ClaudeProvider/models.ts new file mode 100644 index 00000000..5dfc8281 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/ClaudeProvider/models.ts @@ -0,0 +1,184 @@ +import { IChatModel } from '../types'; + +export const CLAUDE_MODELS: IChatModel[] = [ + { + id: 'claude-opus-4-5-20251101', + aliases: ['claude-opus-4-5-latest', 'claude-opus-4-5', 'claude-opus-4.5'], + name: 'Claude Opus 4.5', + costs_currency: 'usd-cents', + input_cost_key: 'input_tokens', + output_cost_key: 'output_tokens', + costs: { + tokens: 1_000_000, + input_tokens: 500, + ephemeral_5m_input_tokens: 500 * 1.25, + ephemeral_1h_input_tokens: 500 * 2, + cache_read_input_tokens: 500 * 0.1, + output_tokens: 2500, + }, + context: 200000, + max_tokens: 64000, + }, + { + id: 'claude-haiku-4-5-20251001', + aliases: ['claude-haiku-4.5', 'claude-haiku-4-5', 'claude-4-5-haiku'], + name: 'Claude Haiku 4.5', + costs_currency: 'usd-cents', + input_cost_key: 'input_tokens', + output_cost_key: 'output_tokens', + costs: { + tokens: 1_000_000, + input_tokens: 100, + ephemeral_5m_input_tokens: 100 * 1.25, + ephemeral_1h_input_tokens: 100 * 2, + cache_read_input_tokens: 100 * 0.1, + output_tokens: 500, + }, + context: 200000, + max_tokens: 64000, + }, + { + id: 'claude-sonnet-4-5-20250929', + aliases: ['claude-sonnet-4.5', 'claude-sonnet-4-5'], + name: 'Claude Sonnet 4.5', + costs_currency: 'usd-cents', + input_cost_key: 'input_tokens', + output_cost_key: 'output_tokens', + costs: { + tokens: 1_000_000, + input_tokens: 300, + ephemeral_5m_input_tokens: 300 * 1.25, + ephemeral_1h_input_tokens: 300 * 2, + cache_read_input_tokens: 300 * 0.1, + output_tokens: 1500, + }, + context: 200000, + max_tokens: 64000, + }, + { + id: 'claude-opus-4-1-20250805', + aliases: ['claude-opus-4-1'], + name: 'Claude Opus 4.1', + costs_currency: 'usd-cents', + input_cost_key: 'input_tokens', + output_cost_key: 'output_tokens', + costs: { + tokens: 1_000_000, + input_tokens: 1500, + ephemeral_5m_input_tokens: 1500 * 1.25, + ephemeral_1h_input_tokens: 1500 * 2, + cache_read_input_tokens: 1500 * 0.1, + output_tokens: 7500, + }, + context: 200000, + max_tokens: 32000, + }, + { + id: 'claude-opus-4-20250514', + aliases: ['claude-opus-4', 'claude-opus-4-latest'], + name: 'Claude Opus 4', + costs_currency: 'usd-cents', + input_cost_key: 'input_tokens', + output_cost_key: 'output_tokens', + costs: { + tokens: 1_000_000, + input_tokens: 1500, + ephemeral_5m_input_tokens: 1500 * 1.25, + ephemeral_1h_input_tokens: 1500 * 2, + cache_read_input_tokens: 1500 * 0.1, + output_tokens: 7500, + }, + context: 200000, + max_tokens: 32000, + }, + { + id: 'claude-sonnet-4-20250514', + aliases: ['claude-sonnet-4', 'claude-sonnet-4-latest'], + name: 'Claude Sonnet 4', + costs_currency: 'usd-cents', + input_cost_key: 'input_tokens', + output_cost_key: 'output_tokens', + costs: { + tokens: 1_000_000, + input_tokens: 300, + ephemeral_5m_input_tokens: 300 * 1.25, + ephemeral_1h_input_tokens: 300 * 2, + cache_read_input_tokens: 300 * 0.1, + output_tokens: 1500, + }, + context: 200000, + max_tokens: 64000, + }, + { + id: 'claude-3-7-sonnet-20250219', + aliases: ['claude-3-7-sonnet-latest'], + succeeded_by: 'claude-sonnet-4-20250514', + costs_currency: 'usd-cents', + input_cost_key: 'input_tokens', + output_cost_key: 'output_tokens', + costs: { + tokens: 1_000_000, + input_tokens: 300, + ephemeral_5m_input_tokens: 300 * 1.25, + ephemeral_1h_input_tokens: 300 * 2, + cache_read_input_tokens: 300 * 0.1, + output_tokens: 1500, + }, + context: 200000, + max_tokens: 8192, + }, + { + id: 'claude-3-5-sonnet-20241022', + name: 'Claude 3.5 Sonnet', + aliases: ['claude-3-5-sonnet-latest'], + costs_currency: 'usd-cents', + input_cost_key: 'input_tokens', + output_cost_key: 'output_tokens', + costs: { + tokens: 1_000_000, + input_tokens: 300, + ephemeral_5m_input_tokens: 300 * 1.25, + ephemeral_1h_input_tokens: 300 * 2, + cache_read_input_tokens: 300 * 0.1, + output_tokens: 1500, + }, + qualitative_speed: 'fast', + training_cutoff: '2024-04', + context: 200000, + max_tokens: 8192, + }, + { + id: 'claude-3-5-sonnet-20240620', + succeeded_by: 'claude-3-5-sonnet-20241022', + costs_currency: 'usd-cents', + input_cost_key: 'input_tokens', + output_cost_key: 'output_tokens', + costs: { + tokens: 1_000_000, + input_tokens: 300, + ephemeral_5m_input_tokens: 300 * 1.25, + ephemeral_1h_input_tokens: 300 * 2, + cache_read_input_tokens: 300 * 0.1, + output_tokens: 1500, + }, + context: 200000, // might be wrong + max_tokens: 8192, + }, + { + id: 'claude-3-haiku-20240307', + costs_currency: 'usd-cents', + input_cost_key: 'input_tokens', + output_cost_key: 'output_tokens', + costs: { + tokens: 1_000_000, + input_tokens: 25, + ephemeral_5m_input_tokens: 25 * 1.25, + ephemeral_1h_input_tokens: 25 * 2, + cache_read_input_tokens: 25 * 0.1, + output_tokens: 125, + }, + qualitative_speed: 'fastest', + context: 200000, + max_tokens: 4096, + }, +]; diff --git a/src/backend/src/services/ai/chat/providers/DeepSeekProvider/DeepSeekProvider.ts b/src/backend/src/services/ai/chat/providers/DeepSeekProvider/DeepSeekProvider.ts new file mode 100644 index 00000000..7c162476 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/DeepSeekProvider/DeepSeekProvider.ts @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import dedent from 'dedent'; +import { OpenAI } from 'openai'; +import { ChatCompletionCreateParams } from 'openai/resources/index.js'; +import { Context } from '../../../../../util/context.js'; +import { MeteringService } from '../../../../MeteringService/MeteringService.js'; +import * as OpenAIUtil from '../../../utils/OpenAIUtil.js'; +import { IChatProvider, ICompleteArguments } from '../types.js'; +import { DEEPSEEK_MODELS } from './models.js'; + +export class DeepSeekProvider implements IChatProvider { + #openai: OpenAI; + + #meteringService: MeteringService; + + constructor (config: { apiKey: string }, meteringService: MeteringService) { + this.#openai = new OpenAI({ + apiKey: config.apiKey, + baseURL: 'https://api.deepseek.com', + }); + this.#meteringService = meteringService; + } + + getDefaultModel () { + return 'deepseek-chat'; + } + + models () { + return DEEPSEEK_MODELS; + } + + async list () { + const models = this.models(); + const modelNames: string[] = []; + for ( const model of models ) { + modelNames.push(model.id); + if ( model.aliases ) { + modelNames.push(...model.aliases); + } + } + return modelNames; + } + + async complete ({ messages, stream, model, tools, max_tokens, temperature }: ICompleteArguments): ReturnType { + const actor = Context.get('actor'); + const availableModels = this.models(); + const modelUsed = availableModels.find(m => [m.id, ...(m.aliases || [])].includes(model)) || availableModels.find(m => m.id === this.getDefaultModel())!; + + messages = await OpenAIUtil.process_input_messages(messages); + for ( const message of messages ) { + // DeepSeek doesn't accept string arrays alongside tool calls + if ( message.tool_calls && Array.isArray(message.content) ) { + message.content = ''; + } + } + + // Function calling currently loops unless we inject the tool result as a system message. + const TOOL_TEXT = (message: { tool_call_id: string; content: string }) => dedent(` + Hi DeepSeek V3, your tool calling is broken and you are not able to + obtain tool results in the expected way. That's okay, we can work + around this. + + Please do not repeat this tool call. + + We have provided the tool call results below: + + Tool call ${message.tool_call_id} returned: ${message.content}. + `); + for ( let i = messages.length - 1; i >= 0; i-- ) { + const message = messages[i]; + if ( message.role === 'tool' ) { + messages.splice(i + 1, 0, { + role: 'system', + content: [ + { + type: 'text', + text: TOOL_TEXT(message), + }, + ], + }); + } + } + + const completion = await this.#openai.chat.completions.create({ + messages, + model: modelUsed.id, + ...(tools ? { tools } : {}), + max_tokens: max_tokens || 1000, + temperature, + stream, + ...(stream ? { + stream_options: { include_usage: true }, + } : {}), + } as ChatCompletionCreateParams); + + return OpenAIUtil.handle_completion_output({ + usage_calculator: ({ usage }) => { + const trackedUsage = OpenAIUtil.extractMeteredUsage(usage); + const costsOverrideFromModel = Object.fromEntries(Object.entries(trackedUsage).map(([k, v]) => { + return [k, v * (modelUsed.costs[k] || 0)]; + })); + this.#meteringService.utilRecordUsageObject(trackedUsage, actor, `deepseek:${modelUsed.id}`, costsOverrideFromModel); + return trackedUsage; + }, + stream, + completion, + }); + } + + checkModeration (_text: string): ReturnType { + throw new Error('Method not implemented.'); + } +} diff --git a/src/backend/src/services/ai/chat/providers/DeepSeekProvider/models.ts b/src/backend/src/services/ai/chat/providers/DeepSeekProvider/models.ts new file mode 100644 index 00000000..f93e3bbf --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/DeepSeekProvider/models.ts @@ -0,0 +1,36 @@ +import { IChatModel } from '../types.js'; + +export const DEEPSEEK_MODELS: IChatModel[] = [ + { + id: 'deepseek-chat', + name: 'DeepSeek Chat', + aliases: [], + context: 128000, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 56, + completion_tokens: 168, + cached_tokens: 0, + }, + max_tokens: 8000, + }, + { + id: 'deepseek-reasoner', + name: 'DeepSeek Reasoner', + aliases: [], + context: 128000, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 56, + completion_tokens: 168, + cached_tokens: 0, + }, + max_tokens: 64000, + }, +]; diff --git a/src/backend/src/services/ai/chat/providers/FakeChatProvider.ts b/src/backend/src/services/ai/chat/providers/FakeChatProvider.ts new file mode 100644 index 00000000..733e7609 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/FakeChatProvider.ts @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +// METADATA // {"ai-commented":{"service":"claude"}} + +import dedent from 'dedent'; +import { LoremIpsum } from 'lorem-ipsum'; +import { AIChatStream } from '../../utils/Streaming'; +import { IChatProvider, ICompleteArguments } from './types'; + +export class FakeChatProvider implements IChatProvider { + checkModeration (_text: string): ReturnType { + throw new Error('Method not implemented.'); + } + + getDefaultModel () { + return 'fake'; + } + + async models () { + return [ + { + id: 'fake', + aliases: [], + costs_currency: 'usd-cents', + costs: { + 'input-tokens': 0, + 'output-tokens': 0, + }, + max_tokens: 8192, + + }, + { + id: 'costly', + aliases: [], + costs_currency: 'usd-cents', + costs: { + 'input-tokens': 1000, // 1000 microcents per million tokens (0.001 cents per 1000 tokens) + 'output-tokens': 2000, // 2000 microcents per million tokens (0.002 cents per 1000 tokens) + }, + max_tokens: 8192, + }, + { + id: 'abuse', + aliases: [], + costs_currency: 'usd-cents', + costs: { + 'input-tokens': 0, + 'output-tokens': 0, + }, + max_tokens: 8192, + }, + ]; + } + async list () { + return ['fake', 'costly', 'abuse']; + } + async complete ({ messages, stream, model, max_tokens, custom }: ICompleteArguments): ReturnType { + + // Determine token counts based on messages and model + const usedModel = model || this.getDefaultModel(); + + // For the costly model, simulate actual token counting + const resp = this.getFakeResponse(usedModel, custom, messages, max_tokens); + + if ( stream ) { + return { + init_chat_stream: async ({ chatStream }: { chatStream: AIChatStream }) => { + await new Promise(rslv => setTimeout(rslv, 500)); + chatStream.stream.write(`${JSON.stringify({ + type: 'text', + text: (await resp).message.content[0].text, + }) }\n`); + chatStream.end(); + }, + stream: true, + finally_fn: async () => { + // no op + }, + }; + } + + return resp; + } + async getFakeResponse (modelId: string, custom: unknown, messages: any[], maxTokens: number = 8192): ReturnType { + let inputTokens = 0; + let outputTokens = 0; + + if ( modelId === 'costly' ) { + // Simple token estimation: roughly 4 chars per token for input + if ( messages && messages.length > 0 ) { + for ( const message of messages ) { + if ( typeof message.content === 'string' ) { + inputTokens += Math.ceil(message.content.length / 4); + } else if ( Array.isArray(message.content) ) { + for ( const content of message.content ) { + if ( content.type === 'text' ) { + inputTokens += Math.ceil(content.text.length / 4); + } + } + } + } + } + + // Generate random output token count between 50 and 200 + outputTokens = Math.floor(Math.min((Math.random() * 150) + 50, maxTokens)); + // outputTokens = Math.floor(Math.random() * 150) + 50; + } + + // Generate the response text + let responseText; + if ( modelId === 'abuse' ) { + responseText = dedent(` +

Free AI and Cloud for everyone!


+ Come on down to puter.com and try it out! + ${custom ?? ''} + `); + } else { + // Generate 1-3 paragraphs for both fake and costly models + responseText = new LoremIpsum({ + sentencesPerParagraph: { + max: 8, + min: 4, + }, + wordsPerSentence: { + max: 20, + min: 12, + }, + }).generateParagraphs(Math.floor(Math.random() * 3) + 1); + } + + // Report usage based on model + const usage = { + 'input_tokens': modelId === 'costly' ? inputTokens : 0, + 'output_tokens': modelId === 'costly' ? outputTokens : 1, + }; + + return { + message: { + 'id': '00000000-0000-0000-0000-000000000000', + 'type': 'message', + 'role': 'assistant', + 'model': modelId, + 'content': [ + { + 'type': 'text', + 'text': responseText, + }, + ], + 'stop_reason': 'end_turn', + 'stop_sequence': null, + 'usage': usage, + }, + 'usage': usage, + 'finish_reason': 'stop', + }; + } +} diff --git a/src/backend/src/services/ai/chat/providers/GeminiProvider/GeminiChatProvider.ts b/src/backend/src/services/ai/chat/providers/GeminiProvider/GeminiChatProvider.ts new file mode 100644 index 00000000..ce92192b --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/GeminiProvider/GeminiChatProvider.ts @@ -0,0 +1,94 @@ +// Preamble: Before this we used Gemini's SDK directly and as we found out +// its actually kind of terrible. So we use the openai sdk now +import openai, { OpenAI } from 'openai'; +import { Context } from '../../../../../util/context.js'; +import { MeteringService } from '../../../../MeteringService/MeteringService.js'; +import { handle_completion_output, process_input_messages } from '../../../utils/OpenAIUtil.js'; +import { IChatProvider, ICompleteArguments } from '../types.js'; +import { GEMINI_MODELS } from './models.js'; +import { ChatCompletionCreateParams } from 'openai/resources/index.js'; + +export class GeminiChatProvider implements IChatProvider { + + meteringService: MeteringService; + openai: OpenAI; + + defaultModel = 'gemini-2.5-flash'; + + constructor ( meteringService: MeteringService, config: { apiKey: string }) + { + this.meteringService = meteringService; + this.openai = new openai.OpenAI({ + apiKey: config.apiKey, + baseURL: 'https://generativelanguage.googleapis.com/v1beta/openai/', + }); + } + + getDefaultModel () { + return this.defaultModel; + } + + async models () { + return GEMINI_MODELS; + } + async list () { + return (await this.models()).map(m => [m.id, ... (m.aliases || [])]).flat(); + } + + async complete ({ messages, stream, model, tools, max_tokens, temperature }: ICompleteArguments): ReturnType { + + const actor = Context.get('actor'); + messages = await process_input_messages(messages); + + // delete cache_control + messages = messages.map(m => { + delete m.cache_control; + return m; + }); + + const modelUsed = (await this.models()).find(m => [m.id, ...(m.aliases || [])].includes(model)) || (await this.models()).find(m => m.id === this.getDefaultModel())!; + const sdk_params: ChatCompletionCreateParams = { + messages: messages, + model: modelUsed.id, + ...(tools ? { tools } : {}), + ...(max_tokens ? { max_completion_tokens: max_tokens } : {}), + ...(temperature ? { temperature } : {}), + stream, + ...(stream ? { + stream_options: { include_usage: true }, + } : {}), + } as ChatCompletionCreateParams; + + let completion; + try { + completion = await this.openai.chat.completions.create(sdk_params); + } catch (e) { + console.error('Gemini completion error: ', e); + throw e; + } + + return handle_completion_output({ + usage_calculator: ({ usage }) => { + const trackedUsage = { + prompt_tokens: (usage.prompt_tokens ?? 0) - (usage.prompt_tokens_details?.cached_tokens ?? 0), + completion_tokens: usage.completion_tokens ?? 0, + cached_tokens: usage.prompt_tokens_details?.cached_tokens ?? 0, + }; + + const costsOverrideFromModel = Object.fromEntries(Object.entries(trackedUsage).map(([k, v]) => { + return [k, v * (modelUsed.costs[k] || 0)]; + })); + this.meteringService.utilRecordUsageObject(trackedUsage, actor, `gemini:${modelUsed?.id}`), costsOverrideFromModel; + + return trackedUsage; + }, + stream, + completion, + }); + + } + + checkModeration (_text: string): ReturnType { + throw new Error('No moderation logic.'); + } +} diff --git a/src/backend/src/services/ai/chat/providers/GeminiProvider/models.ts b/src/backend/src/services/ai/chat/providers/GeminiProvider/models.ts new file mode 100644 index 00000000..ed7c70e8 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/GeminiProvider/models.ts @@ -0,0 +1,94 @@ +import { IChatModel } from '../types'; + +export const GEMINI_MODELS: IChatModel[] = [ + { + id: 'gemini-2.0-flash', + name: 'Gemini 2.0 Flash', + context: 131072, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 10, + completion_tokens: 40, + cached_tokens: 3, + + }, + max_tokens: 8192, + }, + { + id: 'gemini-2.0-flash-lite', + name: 'Gemini 2.0 Flash-Lite', + context: 1_048_576, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 8, + completion_tokens: 30, + }, + max_tokens: 8192, + }, + { + id: 'gemini-2.5-flash', + name: 'Gemini 2.5 Flash', + context: 1_048_576, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 30, + completion_tokens: 250, + cached_tokens: 3, + }, + max_tokens: 65536, + }, + { + id: 'gemini-2.5-flash-lite', + name: 'Gemini 2.5 Flash-Lite', + context: 1_048_576, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 10, + completion_tokens: 40, + cached_tokens: 1, + }, + max_tokens: 65536, + }, + { + id: 'gemini-2.5-pro', + name: 'Gemini 2.5 Pro', + context: 1_048_576, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 125, + completion_tokens: 1000, + cached_tokens: 13, + }, + max_tokens: 200_000, + }, + { + id: 'gemini-3-pro-preview', + name: 'Gemini 3 Pro', + context: 1_048_576, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 200, + completion_tokens: 1200, + cached_tokens: 20, + }, + max_tokens: 200_000, + }, +]; diff --git a/src/backend/src/services/ai/chat/providers/GroqAiProvider/GroqAIProvider.ts b/src/backend/src/services/ai/chat/providers/GroqAiProvider/GroqAIProvider.ts new file mode 100644 index 00000000..309b4e2a --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/GroqAiProvider/GroqAIProvider.ts @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import Groq from 'groq-sdk'; +import { ChatCompletionCreateParams } from 'groq-sdk/resources/chat/completions.mjs'; +import { CompletionUsage } from 'openai/resources'; +import { Context } from '../../../../../util/context.js'; +import { MeteringService } from '../../../../MeteringService/MeteringService.js'; +import * as OpenAIUtil from '../../../utils/OpenAIUtil.js'; +import { IChatProvider, ICompleteArguments } from '../types.js'; +import { GROQ_MODELS } from './models.js'; + +export class GroqAIProvider implements IChatProvider { + #client: Groq; + + #meteringService: MeteringService; + + constructor (config: { apiKey: string }, meteringService: MeteringService) { + this.#client = new Groq({ + apiKey: config.apiKey, + }); + this.#meteringService = meteringService; + } + + getDefaultModel () { + return 'llama-3.1-8b-instant'; + } + + models () { + return GROQ_MODELS; + } + + async list () { + const models = this.models(); + const modelNames: string[] = []; + for ( const model of models ) { + modelNames.push(model.id); + if ( model.aliases ) { + modelNames.push(...model.aliases); + } + } + return modelNames; + } + + async complete ({ messages, model, stream, tools, max_tokens, temperature }: ICompleteArguments): ReturnType { + const actor = Context.get('actor'); + const availableModels = this.models(); + const modelUsed = availableModels.find(m => [m.id, ...(m.aliases || [])].includes(model)) || availableModels.find(m => m.id === this.getDefaultModel())!; + + messages = await OpenAIUtil.process_input_messages(messages); + for ( const message of messages ) { + if ( message.tool_calls && Array.isArray(message.content) ) { + message.content = ''; + } + } + + const completion = await this.#client.chat.completions.create({ + messages, + model: modelUsed.id, + stream, + tools, + max_completion_tokens: max_tokens, + temperature, + } as ChatCompletionCreateParams); + + return OpenAIUtil.handle_completion_output({ + deviations: { + index_usage_from_stream_chunk: chunk => + // x_groq contains usage details for streamed responses + (chunk as { x_groq?: { usage?: CompletionUsage } }).x_groq?.usage, + }, + usage_calculator: ({ usage }) => { + const trackedUsage = OpenAIUtil.extractMeteredUsage(usage); + const costsOverride = Object.fromEntries(Object.entries(trackedUsage).map(([k, v]) => { + return [k, v * (modelUsed.costs[k] || 0)]; + })); + this.#meteringService.utilRecordUsageObject(trackedUsage, actor, `groq:${modelUsed.id}`, costsOverride); + return trackedUsage; + }, + stream, + completion, + }); + } + + checkModeration (_text: string): ReturnType { + throw new Error('Method not implemented.'); + } +} diff --git a/src/backend/src/services/ai/chat/providers/GroqAiProvider/models.ts b/src/backend/src/services/ai/chat/providers/GroqAiProvider/models.ts new file mode 100644 index 00000000..edecb95b --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/GroqAiProvider/models.ts @@ -0,0 +1,156 @@ +import { IChatModel } from '../types.js'; + +const makeModel = ({ + id, + name, + context, + input, + output, + max_tokens, +}: { + id: string; + name: string; + context?: number; + input: number; + output: number; + max_tokens?: number; +}): IChatModel => ({ + id, + name, + context, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: input, + completion_tokens: output, + cached_tokens: 0, + }, + max_tokens: max_tokens ?? context ?? 8192, +}); + +export const GROQ_MODELS: IChatModel[] = [ + makeModel({ + id: 'gemma2-9b-it', + name: 'Gemma 2 9B 8k', + context: 8192, + input: 20, + output: 20, + }), + makeModel({ + id: 'gemma-7b-it', + name: 'Gemma 7B 8k Instruct', + context: 8192, + input: 7, + output: 7, + }), + makeModel({ + id: 'llama3-groq-70b-8192-tool-use-preview', + name: 'Llama 3 Groq 70B Tool Use Preview 8k', + context: 8192, + input: 89, + output: 89, + }), + makeModel({ + id: 'llama3-groq-8b-8192-tool-use-preview', + name: 'Llama 3 Groq 8B Tool Use Preview 8k', + context: 8192, + input: 19, + output: 19, + }), + makeModel({ + id: 'llama-3.1-70b-versatile', + name: 'Llama 3.1 70B Versatile 128k', + context: 128000, + input: 59, + output: 79, + }), + makeModel({ + id: 'llama-3.1-70b-specdec', + name: 'Llama 3.1 8B Instant 128k', + context: 128000, + input: 59, + output: 99, + }), + makeModel({ + id: 'llama-3.1-8b-instant', + name: 'Llama 3.1 8B Instant 128k', + context: 131072, + input: 5, + output: 8, + max_tokens: 131072, + }), + makeModel({ + id: 'meta-llama/llama-guard-4-12b', + name: 'Llama Guard 4 12B', + context: 131072, + input: 20, + output: 20, + max_tokens: 1024, + }), + makeModel({ + id: 'meta-llama/llama-prompt-guard-2-86m', + name: 'Prompt Guard 2 86M', + context: 512, + input: 4, + output: 4, + max_tokens: 512, + }), + makeModel({ + id: 'llama-3.2-1b-preview', + name: 'Llama 3.2 1B (Preview) 8k', + context: 128000, + input: 4, + output: 4, + }), + makeModel({ + id: 'llama-3.2-3b-preview', + name: 'Llama 3.2 3B (Preview) 8k', + context: 128000, + input: 6, + output: 6, + }), + makeModel({ + id: 'llama-3.2-11b-vision-preview', + name: 'Llama 3.2 11B Vision 8k (Preview)', + context: 8000, + input: 18, + output: 18, + }), + makeModel({ + id: 'llama-3.2-90b-vision-preview', + name: 'Llama 3.2 90B Vision 8k (Preview)', + context: 8000, + input: 90, + output: 90, + }), + makeModel({ + id: 'llama3-70b-8192', + name: 'Llama 3 70B 8k', + context: 8192, + input: 59, + output: 79, + }), + makeModel({ + id: 'llama3-8b-8192', + name: 'Llama 3 8B 8k', + context: 8192, + input: 5, + output: 8, + }), + makeModel({ + id: 'mixtral-8x7b-32768', + name: 'Mixtral 8x7B Instruct 32k', + context: 32768, + input: 24, + output: 24, + }), + makeModel({ + id: 'llama-guard-3-8b', + name: 'Llama Guard 3 8B 8k', + context: 8192, + input: 20, + output: 20, + }), +]; diff --git a/src/backend/src/services/ai/chat/providers/MistralAiProvider/MistralAiProvider.ts b/src/backend/src/services/ai/chat/providers/MistralAiProvider/MistralAiProvider.ts new file mode 100644 index 00000000..f676a7a4 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/MistralAiProvider/MistralAiProvider.ts @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { Mistral } from '@mistralai/mistralai'; +import { ChatCompletionResponse } from '@mistralai/mistralai/models/components/chatcompletionresponse.js'; +import { Context } from '../../../../../util/context.js'; +import { MeteringService } from '../../../../MeteringService/MeteringService.js'; +import * as OpenAIUtil from '../../../utils/OpenAIUtil.js'; +import { IChatProvider, ICompleteArguments } from '../types.js'; +import { MISTRAL_MODELS } from './models.js'; + +export class MistralAIProvider implements IChatProvider { + #client: Mistral; + + #meteringService: MeteringService; + + constructor (config: { apiKey: string }, meteringService: MeteringService) { + this.#client = new Mistral({ + apiKey: config.apiKey, + }); + this.#meteringService = meteringService; + } + + getDefaultModel () { + return 'mistral-small-2506'; + } + + async models () { + return MISTRAL_MODELS; + } + + async list () { + const models = await this.models(); + const ids: string[] = []; + for ( const model of models ) { + ids.push(model.id); + if ( model.aliases ) { + ids.push(...model.aliases); + } + } + return ids; + } + + async complete ({ messages, stream, model, tools, max_tokens, temperature }: ICompleteArguments): ReturnType { + + messages = await OpenAIUtil.process_input_messages(messages); + for ( const message of messages ) { + if ( message.tool_calls ) { + message.toolCalls = message.tool_calls; + delete message.tool_calls; + } + if ( message.tool_call_id ) { + message.toolCallId = message.tool_call_id; + delete message.tool_call_id; + } + } + + const selectedModel = (await this.models()).find(m => [m.id, ...(m.aliases || [])].includes(model)) || (await this.models()).find(m => m.id === this.getDefaultModel())!; + const actor = Context.get('actor'); + const completion = await this.#client.chat[ + stream ? 'stream' : 'complete' + ]({ + model: selectedModel.id, + ...(tools ? { tools: tools as any[] } : {}), + messages, + maxTokens: max_tokens, + temperature, + }); + + return await OpenAIUtil.handle_completion_output({ + deviations: { + index_usage_from_stream_chunk: chunk => { + if ( ! chunk.usage ) return; + + const snake_usage = {}; + for ( const key in chunk.usage ) { + const snakeKey = key.replace(/([A-Z])/g, '_$1').toLowerCase(); + snake_usage[snakeKey] = chunk.usage[key]; + } + + return snake_usage; + }, + chunk_but_like_actually: chunk => (chunk as any).data, + index_tool_calls_from_stream_choice: choice => (choice.delta as any).toolCalls, + coerce_completion_usage: (completion: ChatCompletionResponse) => ({ + prompt_tokens: completion.usage.promptTokens, + completion_tokens: completion.usage.completionTokens, + }), + }, + completion: completion as ChatCompletionResponse, + stream, + usage_calculator: ({ usage }) => { + const trackedUsage = OpenAIUtil.extractMeteredUsage(usage); + this.#meteringService.utilRecordUsageObject(trackedUsage, actor, `mistral:${selectedModel.id}`); + // Still return legacy cost calculation for compatibility + + return trackedUsage; + }, + }); + } + + checkModeration (_text: string): ReturnType { + throw new Error('Method not implemented.'); + } +} diff --git a/src/backend/src/services/ai/chat/providers/MistralAiProvider/models.ts b/src/backend/src/services/ai/chat/providers/MistralAiProvider/models.ts new file mode 100644 index 00000000..54b58f94 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/MistralAiProvider/models.ts @@ -0,0 +1,299 @@ +import { IChatModel } from '../types'; + +export const MISTRAL_MODELS: IChatModel[] = [ + { + id: 'mistral-medium-2508', + name: 'mistral-medium-2508', + aliases: [ + 'mistral-medium-latest', + 'mistral-medium', + ], + max_tokens: 131072, + description: 'Update on Mistral Medium 3 with improved capabilities.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 40, + completion_tokens: 200, + }, + }, + { + id: 'open-mistral-7b', + name: 'open-mistral-7b', + aliases: [ + 'mistral-tiny', + 'mistral-tiny-2312', + ], + max_tokens: 32768, + description: 'Our first dense model released September 2023.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 25, + completion_tokens: 25, + }, + }, + { + id: 'open-mistral-nemo', + name: 'open-mistral-nemo', + aliases: [ + 'open-mistral-nemo-2407', + 'mistral-tiny-2407', + 'mistral-tiny-latest', + ], + max_tokens: 131072, + description: 'Our best multilingual open source model released July 2024.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 15, + completion_tokens: 15, + }, + }, + { + id: 'pixtral-large-2411', + name: 'pixtral-large-2411', + aliases: [ + 'pixtral-large-latest', + 'mistral-large-pixtral-2411', + ], + max_tokens: 131072, + description: 'Official pixtral-large-2411 Mistral AI model', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 200, + completion_tokens: 600, + }, + }, + { + id: 'codestral-2508', + name: 'codestral-2508', + aliases: [ + 'codestral-latest', + ], + max_tokens: 256000, + description: 'Our cutting-edge language model for coding released August 2025.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 30, + completion_tokens: 90, + }, + }, + { + id: 'devstral-small-2507', + name: 'devstral-small-2507', + aliases: [ + 'devstral-small-latest', + ], + max_tokens: 131072, + description: 'Our small open-source code-agentic model.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 10, + completion_tokens: 30, + cached_tokens: 0, + }, + }, + { + id: 'devstral-medium-2507', + name: 'devstral-medium-2507', + aliases: [ + 'devstral-medium-latest', + ], + max_tokens: 131072, + description: 'Our medium code-agentic model.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 40, + completion_tokens: 200, + cached_tokens: 0, + }, + }, + { + id: 'mistral-small-2506', + name: 'mistral-small-2506', + aliases: [ + 'mistral-small-latest', + ], + max_tokens: 131072, + description: 'Our latest enterprise-grade small model with the latest version released June 2025.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 10, + completion_tokens: 30, + }, + }, + { + id: 'magistral-medium-2509', + name: 'magistral-medium-2509', + aliases: [ + 'magistral-medium-latest', + ], + max_tokens: 131072, + description: 'Our frontier-class reasoning model release candidate September 2025.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 200, + completion_tokens: 500, + }, + }, + { + id: 'magistral-small-2509', + name: 'magistral-small-2509', + aliases: [ + 'magistral-small-latest', + ], + max_tokens: 131072, + description: 'Our efficient reasoning model released September 2025.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 50, + completion_tokens: 150, + }, + }, + { + id: 'voxtral-mini-2507', + name: 'voxtral-mini-2507', + aliases: [ + 'voxtral-mini-latest', + ], + max_tokens: 32768, + description: 'A mini audio understanding model released in July 2025', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 4, + completion_tokens: 4, + }, + }, + { + id: 'voxtral-small-2507', + name: 'voxtral-small-2507', + aliases: [ + 'voxtral-small-latest', + ], + max_tokens: 32768, + description: 'A small audio understanding model released in July 2025', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 10, + completion_tokens: 30, + }, + }, + { + id: 'mistral-large-latest', + name: 'mistral-large-2512', + aliases: [ + 'mistral-large-2512', + ], + max_tokens: 262144, + description: 'Official mistral-large-2512 Mistral AI model', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 50, + completion_tokens: 150, + }, + }, + { + id: 'ministral-3b-2512', + name: 'ministral-3b-2512', + aliases: [ + 'ministral-3b-latest', + ], + max_tokens: 131072, + description: 'Ministral 3 (a.k.a. Tinystral) 3B Instruct.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 10, + completion_tokens: 10, + }, + }, + { + id: 'ministral-8b-2512', + name: 'ministral-8b-2512', + aliases: [ + 'ministral-8b-latest', + ], + max_tokens: 262144, + description: 'Ministral 3 (a.k.a. Tinystral) 8B Instruct.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 15, + completion_tokens: 15, + }, + }, + { + id: 'ministral-14b-2512', + name: 'ministral-14b-2512', + aliases: [ + 'ministral-14b-latest', + ], + max_tokens: 262144, + description: 'Ministral 3 (a.k.a. Tinystral) 14B Instruct.', + provider: 'mistral', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1000000, + prompt_tokens: 20, + completion_tokens: 20, + }, + }, +]; \ No newline at end of file diff --git a/src/backend/src/services/ai/chat/providers/OllamaProvider.ts b/src/backend/src/services/ai/chat/providers/OllamaProvider.ts new file mode 100644 index 00000000..6937833d --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/OllamaProvider.ts @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +// METADATA // {"ai-commented":{"service":"claude"}} +import axios from 'axios'; +import { default as openai, default as OpenAI } from 'openai'; +import { Context } from '../../../../util/context.js'; +import { kv } from '../../../../util/kvSingleton.js'; +import * as OpenAIUtil from '../../utils/OpenAIUtil.js'; +import { IChatModel, IChatProvider, ICompleteArguments } from './types'; +import { MeteringService } from '../../../MeteringService/MeteringService'; +import { ChatCompletionCreateParams } from 'openai/resources/index.js'; +/** +* OllamaService class - Provides integration with Ollama's API for chat completions +* Extends BaseService to implement the puter-chat-completion interface. +* Handles model management, message adaptation, streaming responses, +* and usage tracking for Ollama's language models. +* @extends BaseService +*/ +export class OllamaChatProvider implements IChatProvider { + + #apiBaseUrl: string; + + #openai: OpenAI; + + #meteringService: MeteringService; + + constructor (config: { api_base_url?: string } | undefined, meteringService: MeteringService) { + // Ollama typically runs on HTTP, not HTTPS + this.#apiBaseUrl = config?.api_base_url || 'http://localhost:11434'; + + // OpenAI SDK is used to interact with the Ollama API + this.#openai = new openai.OpenAI({ + apiKey: 'ollama', // Ollama doesn't use an API key, it uses the "ollama" string + baseURL: `${config?.api_base_url }/v1`, + }); + + this.#meteringService = meteringService; + } + + async models () { + let models = kv.get('ollamaChat:models'); + if ( ! models ) { + try { + const resp = await axios.request({ + method: 'GET', + url: `${this.#apiBaseUrl}/api/tags`, + }); + models = resp.data.models || []; + if ( models.length > 0 ) { + kv.set('ollamaChat:models', models); + } + } catch ( error ) { + console.error('Failed to fetch models from Ollama:', (error as Error).message); + // Return empty array if Ollama is not available + return []; + } + } + + if ( !models || models.length === 0 ) { + return []; + } + + const coerced_models: IChatModel[] = []; + for ( const model of models ) { + // Ollama API returns models with 'name' property, not 'model' + const modelName = model.name || model.model || 'unknown'; + coerced_models.push({ + id: `ollama:${ modelName}`, + name: `${modelName} (Ollama)`, + max_tokens: model.size || model.max_context || 8192, + costs_currency: 'usd-cents', + costs: { + tokens: 1_000_000, + input_token: 0, + output_token: 0, + }, + }); + } + console.log('coerced_models', coerced_models); + return coerced_models; + } + async list () { + const models = await this.models(); + const model_names: string[] = []; + for ( const model of models ) { + model_names.push(model.id); + } + return model_names; + } + async complete ({ messages, stream, model, tools, max_tokens, temperature }: ICompleteArguments): ReturnType { + + if ( model.startsWith('ollama:') ) { + model = model.slice('ollama:'.length); + } + + const actor = Context.get('actor'); + + messages = await OpenAIUtil.process_input_messages(messages); + + const completion = await this.#openai.chat.completions.create({ + messages, + model: model ?? this.getDefaultModel(), + ...(tools ? { tools } : {}), + max_tokens, + temperature: temperature, // default to 1.0 + stream: !!stream, + ...(stream ? { + stream_options: { include_usage: true }, + } : {}), + } as ChatCompletionCreateParams) ; + + const modelDetails = (await this.models()).find(m => m.id === `ollama:${model}`); + return OpenAIUtil.handle_completion_output({ + usage_calculator: ({ usage }) => { + + const trackedUsage = { + prompt: (usage.prompt_tokens ?? 1 ) - (usage.prompt_tokens_details?.cached_tokens ?? 0), + completion: usage.completion_tokens ?? 1, + input_cache_read: usage.prompt_tokens_details?.cached_tokens ?? 0, + }; + const costOverwrites = Object.fromEntries(Object.keys(trackedUsage).map((k) => { + return [k, 0]; // override to 0 since local is free + })); + this.#meteringService.utilRecordUsageObject(trackedUsage, actor, modelDetails!.id, costOverwrites); + return trackedUsage; + }, + stream, + completion, + }); + } + checkModeration (_text: string): ReturnType { + throw new Error('Method not implemented.'); + } + + /** + * Returns the default model identifier for the Ollama service + * @returns {string} The default model ID 'gpt-oss:20b' + */ + getDefaultModel () { + return 'gpt-oss:20b'; + } +} \ No newline at end of file diff --git a/src/backend/src/modules/puterai/OpenAiCompletionService/OpenAICompletionService.mjs b/src/backend/src/services/ai/chat/providers/OpenAiProvider/OpenAiChatProvider.ts similarity index 62% rename from src/backend/src/modules/puterai/OpenAiCompletionService/OpenAICompletionService.mjs rename to src/backend/src/services/ai/chat/providers/OpenAiProvider/OpenAiChatProvider.ts index 5ca5c32b..6e72bee6 100644 --- a/src/backend/src/modules/puterai/OpenAiCompletionService/OpenAICompletionService.mjs +++ b/src/backend/src/services/ai/chat/providers/OpenAiProvider/OpenAiChatProvider.ts @@ -19,12 +19,18 @@ import mime from 'mime-types'; import { OpenAI } from 'openai'; -import FSNodeParam from '../../../api/filesystem/FSNodeParam.js'; -import { LLRead } from '../../../filesystem/ll_operations/ll_read.js'; -import { Context } from '../../../util/context.js'; -import { stream_to_buffer } from '../../../util/streamutil.js'; -import OpenAIUtil from '../lib/OpenAIUtil.js'; -import { OPEN_AI_MODELS } from './models.mjs'; +import { ChatCompletionCreateParams } from 'openai/resources/index.js'; +import { FSNodeParam } from '../../../../../api/filesystem/FSNodeParam.js'; +import { LLRead } from '../../../../../filesystem/ll_operations/ll_read.js'; +import { Context } from '../../../../../util/context.js'; +import { stream_to_buffer } from '../../../../../util/streamutil.js'; +import { MeteringService } from '../../../../MeteringService/MeteringService.js'; +import * as OpenAiUtil from '../../../utils/OpenAIUtil.js'; +import { IChatProvider, ICompleteArguments } from '../types.js'; +import { OPEN_AI_MODELS } from './models.js'; + +; + // METADATA // {"ai-commented":{"service":"claude"}} // We're capping at 5MB, which sucks, but Chat Completions doesn't suuport @@ -38,100 +44,200 @@ const MAX_FILE_SIZE = 5 * 1_000_000; * OpenAI API interactions with support for multiple models including GPT-4 variants. * Handles usage tracking, spending records, and content moderation. */ -export class OpenAICompletionService { +export class OpenAiChatProvider implements IChatProvider { /** * @type {import('openai').OpenAI} */ - #openAi; + #openAi: OpenAI; - #defaultModel; + #defaultModel = 'gpt-5-nano'; - #models; + #meteringService: MeteringService; - /** @type {import('../../../services/MeteringService/MeteringService.js').MeteringService} */ - #meteringService; + constructor ( + meteringService: MeteringService, + config: { apiKey?: string, secret_key?: string }) { - constructor ({ serviceName, config, globalConfig, aiChatService, meteringService, models = OPEN_AI_MODELS, defaultModel = 'gpt-5-nano' }) { - this.#models = models; - this.#defaultModel = defaultModel; this.#meteringService = meteringService; - let apiKey = - config?.services?.openai?.apiKey ?? - globalConfig?.services?.openai?.apiKey; + let apiKey = config.apiKey; // Fallback to the old format for backward compatibility if ( ! apiKey ) { - apiKey = - config?.openai?.secret_key ?? - globalConfig?.openai?.secret_key; + apiKey = config?.secret_key; // Log a warning to inform users about the deprecated format console.warn('The `openai.secret_key` configuration format is deprecated. ' + 'Please use `services.openai.apiKey` instead.'); } - if ( ! apiKey ) { throw new Error('OpenAI API key is missing in configuration.'); } - this.#openAi = new OpenAI({ apiKey: apiKey, }); - - aiChatService.register_provider({ - service_name: serviceName, - alias: true, - }); } /** * Returns an array of available AI models with their pricing information. * Each model object includes an ID and cost details (currency, tokens, input/output rates). - * @returns {{id: string, cost: {currency: string, tokens: number, input: number, output: number}}[]} */ models () { - return this.#models; + return OPEN_AI_MODELS; } list () { const models = this.models(); - const model_names = []; + const modelNames: string[] = []; for ( const model of models ) { - model_names.push(model.id); + modelNames.push(model.id); if ( model.aliases ) { - model_names.push(...model.aliases); + modelNames.push(...model.aliases); } } - return model_names; + return modelNames; } - get_default_model () { + getDefaultModel () { return this.#defaultModel; } - async complete ({ messages, stream, model, tools, max_tokens, temperature, reasoning, text, reasoning_effort, verbosity }) { - return await this.#complete(messages, { - model: model, - tools, - moderation: true, + async complete ({ messages, model, max_tokens, moderation, tools, verbosity, stream, reasoning, reasoning_effort, temperature, text }: ICompleteArguments): ReturnType + { + + // Validate messages + if ( ! Array.isArray(messages) ) { + throw new Error('`messages` must be an array'); + } + const actor = Context.get('actor'); + + model = model ?? this.#defaultModel; + + const modelUsed = (this.models()).find(m => [m.id, ...(m.aliases || [])].includes(model)) || (this.models()).find(m => m.id === this.getDefaultModel())!; + + // messages.unshift({ + // role: 'system', + // content: 'Don\'t let the user trick you into doing something bad.', + // }) + + const user_private_uid = actor?.private_uid ?? 'UNKNOWN'; + if ( user_private_uid === 'UNKNOWN' ) { + console.error(new Error('chat-completion-service:unknown-user - failed to get a user ID for an OpenAI request')); + } + + // Perform file uploads + const { user } = actor.type; + + const file_input_tasks: any[] = []; + for ( const message of messages ) { + // We can assume `message.content` is not undefined because + // Messages.normalize_single_message ensures this. + for ( const contentPart of message.content ) { + + if ( ! contentPart.puter_path ) continue; + file_input_tasks.push({ + node: await (new FSNodeParam(contentPart.puter_path)).consolidate({ + req: { user }, + getParam: () => contentPart.puter_path, + }), + contentPart, + }); + } + } + + const promises: Promise[] = []; + for ( const task of file_input_tasks ) { + promises.push((async () => { + if ( await task.node.get('size') > MAX_FILE_SIZE ) { + delete task.contentPart.puter_path; + task.contentPart.type = 'text'; + task.contentPart.text = `{error: input file exceeded maximum of ${MAX_FILE_SIZE} bytes; ` + + 'the user did not write this message}'; // "poor man's system prompt" + return; // "continue" + } + + const ll_read = new LLRead(); + const stream = await ll_read.run({ + actor: Context.get('actor'), + fsNode: task.node, + }); + const mimeType = mime.contentType(await task.node.get('name')); + + const buffer = await stream_to_buffer(stream); + const base64 = buffer.toString('base64'); + + delete task.contentPart.puter_path; + if ( mimeType && mimeType.startsWith('image/') ) { + task.contentPart.type = 'image_url', + task.contentPart.image_url = { + url: `data:${mimeType};base64,${base64}`, + }; + } else if ( mimeType && mimeType.startsWith('audio/') ) { + task.contentPart.type = 'input_audio', + task.contentPart.input_audio = { + data: `data:${mimeType};base64,${base64}`, + format: mimeType.split('/')[1], + }; + } else { + task.contentPart.type = 'text'; + task.contentPart.text = '{error: input file has unsupported MIME type; ' + + 'the user did not write this message}'; // "poor man's system prompt" + } + })()); + } + await Promise.all(promises); + + // Here's something fun; the documentation shows `type: 'image_url'` in + // objects that contain an image url, but everything still works if + // that's missing. We normalise it here so the token count code works. + messages = await OpenAiUtil.process_input_messages(messages); + + const requestedReasoningEffort = reasoning_effort ?? reasoning?.effort; + const requestedVerbosity = verbosity ?? text?.verbosity; + const supportsReasoningControls = typeof model === 'string' && model.startsWith('gpt-5'); + + const completionParams: ChatCompletionCreateParams = { + user: user_private_uid, + messages: messages, + model: modelUsed.id, + ...(tools ? { tools } : {}), + ...(max_tokens ? { max_completion_tokens: max_tokens } : {}), + ...(temperature ? { temperature } : {}), + stream: !!stream, + ...(stream ? { + stream_options: { include_usage: true }, + } : {}), + ...(supportsReasoningControls ? {} : + { + ...(requestedReasoningEffort ? { reasoning_effort: requestedReasoningEffort } : {}), + ...(requestedVerbosity ? { verbosity: requestedVerbosity } : {}), + } + ), + } as ChatCompletionCreateParams; + + const completion = await this.#openAi.chat.completions.create(completionParams); + + return OpenAiUtil.handle_completion_output({ + usage_calculator: ({ usage }) => { + const trackedUsage = { + prompt_tokens: (usage.prompt_tokens ?? 0) - (usage.prompt_tokens_details?.cached_tokens ?? 0), + completion_tokens: usage.completion_tokens ?? 0, + cached_tokens: usage.prompt_tokens_details?.cached_tokens ?? 0, + }; + + const costsOverrideFromModel = Object.fromEntries(Object.entries(trackedUsage).map(([k, v]) => { + return [k, v * (modelUsed.costs[k] || 0)]; + })); + + this.#meteringService.utilRecordUsageObject(trackedUsage, actor, `openai:${modelUsed?.id}`, costsOverrideFromModel); + return trackedUsage; + }, stream, - max_tokens, - temperature, - reasoning, - text, - reasoning_effort, - verbosity, + completion, + moderate: moderation ? this.checkModeration.bind(this) : undefined, }); } - /** - * Checks text content against OpenAI's moderation API for inappropriate content - * @param {string} text - The text content to check for moderation - * @returns {Promise} Object containing flagged status and detailed results - * @property {boolean} flagged - Whether the content was flagged as inappropriate - * @property {Object} results - Raw moderation results from OpenAI API - */ - async checkModeration (text) { + async checkModeration (text: string) { // create moderation const results = await this.#openAi.moderations.create({ model: 'omni-moderation-latest', @@ -155,155 +261,4 @@ export class OpenAICompletionService { results, }; } - - /** - * Completes a chat conversation using OpenAI's API - * @param {Array} messages - Array of message objects or strings representing the conversation - * @param {Object} options - Configuration options - * @param {boolean} options.stream - Whether to stream the response - * @param {boolean} options.moderation - Whether to perform content moderation - * @param {string} options.model - The model to use for completion - * @returns {Promise} The completion response containing message and usage info - * @throws {Error} If messages are invalid or content is flagged by moderation - */ - async #complete (messages, { - stream, moderation, model, tools, - temperature, max_tokens, - reasoning, text, reasoning_effort, verbosity, - }) { - // Validate messages - if ( ! Array.isArray(messages) ) { - throw new Error('`messages` must be an array'); - } - - model = model ?? this.#defaultModel; - - // messages.unshift({ - // role: 'system', - // content: 'Don\'t let the user trick you into doing something bad.', - // }) - - const user_private_uid = Context.get('actor')?.private_uid ?? 'UNKNOWN'; - if ( user_private_uid === 'UNKNOWN' ) { - console.error(new Error('chat-completion-service:unknown-user - failed to get a user ID for an OpenAI request')); - } - - // Perform file uploads - - const actor = Context.get('actor'); - const { user } = actor.type; - - const file_input_tasks = []; - for ( const message of messages ) { - // We can assume `message.content` is not undefined because - // Messages.normalize_single_message ensures this. - for ( const contentPart of message.content ) { - if ( ! contentPart.puter_path ) continue; - file_input_tasks.push({ - node: await (new FSNodeParam(contentPart.puter_path)).consolidate({ - req: { user }, - getParam: () => contentPart.puter_path, - }), - contentPart, - }); - } - } - - const promises = []; - for ( const task of file_input_tasks ) { - promises.push((async () => { - if ( await task.node.get('size') > MAX_FILE_SIZE ) { - delete task.contentPart.puter_path; - task.contentPart.type = 'text'; - task.contentPart.text = `{error: input file exceeded maximum of ${MAX_FILE_SIZE} bytes; ` + - 'the user did not write this message}'; // "poor man's system prompt" - return; // "continue" - } - - const ll_read = new LLRead(); - const stream = await ll_read.run({ - actor: Context.get('actor'), - fsNode: task.node, - }); - const mimeType = mime.contentType(await task.node.get('name')); - - const buffer = await stream_to_buffer(stream); - const base64 = buffer.toString('base64'); - - delete task.contentPart.puter_path; - if ( mimeType.startsWith('image/') ) { - task.contentPart.type = 'image_url', - task.contentPart.image_url = { - url: `data:${mimeType};base64,${base64}`, - }; - } else if ( mimeType.startsWith('audio/') ) { - task.contentPart.type = 'input_audio', - task.contentPart.input_audio = { - data: `data:${mimeType};base64,${base64}`, - format: mimeType.split('/')[1], - }; - } else { - task.contentPart.type = 'text'; - task.contentPart.text = '{error: input file has unsupported MIME type; ' + - 'the user did not write this message}'; // "poor man's system prompt" - } - })()); - } - await Promise.all(promises); - - // Here's something fun; the documentation shows `type: 'image_url'` in - // objects that contain an image url, but everything still works if - // that's missing. We normalise it here so the token count code works. - messages = await OpenAIUtil.process_input_messages(messages); - - const requestedReasoningEffort = reasoning_effort ?? reasoning?.effort; - const requestedVerbosity = verbosity ?? text?.verbosity; - const supportsReasoningControls = typeof model === 'string' && model.startsWith('gpt-5'); - - const completionParams = { - user: user_private_uid, - messages: messages, - model: model, - ...(tools ? { tools } : {}), - ...(max_tokens ? { max_completion_tokens: max_tokens } : {}), - ...(temperature ? { temperature } : {}), - stream, - ...(stream ? { - stream_options: { include_usage: true }, - } : {}), - }; - - if ( supportsReasoningControls ) { - if ( requestedReasoningEffort ) { - completionParams.reasoning_effort = requestedReasoningEffort; - } - if ( requestedVerbosity ) { - completionParams.verbosity = requestedVerbosity; - } - } - - const completion = await this.#openAi.chat.completions.create(completionParams); - // TODO DS: simplify this logic for all the ai services, each service should handle its cost calculation in the service - // for now I'm overloading this usage calculator to handle the future promise resolution... - return OpenAIUtil.handle_completion_output({ - usage_calculator: ({ usage }) => { - const modelDetails = this.models().find(m => m.id === model || m.aliases?.includes(model)); - const trackedUsage = { - prompt_tokens: (usage.prompt_tokens ?? 0) - (usage.prompt_tokens_details?.cached_tokens ?? 0), - completion_tokens: usage.completion_tokens ?? 0, - cached_tokens: usage.prompt_tokens_details?.cached_tokens ?? 0, - }; - - this.#meteringService.utilRecordUsageObject(trackedUsage, actor, `openai:${modelDetails.id}`); - const legacyCostCalculator = OpenAIUtil.create_usage_calculator({ - model_details: modelDetails, - }); - - return legacyCostCalculator({ usage }); - }, - stream, - completion, - moderate: moderation && this.checkModeration.bind(this), - }); - } } diff --git a/src/backend/src/services/ai/chat/providers/OpenAiProvider/models.ts b/src/backend/src/services/ai/chat/providers/OpenAiProvider/models.ts new file mode 100644 index 00000000..36aeb165 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/OpenAiProvider/models.ts @@ -0,0 +1,265 @@ +// TODO DS: centralize somewhere + +import { IChatModel } from '../types'; + +export const OPEN_AI_MODELS: IChatModel[] = [ + { + id: 'gpt-5.1', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 125, + cached_tokens: 13, + completion_tokens: 1000, + }, + max_tokens: 128000, + }, + { + id: 'gpt-5.1-codex', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 125, + cached_tokens: 13, + completion_tokens: 1000, + }, + max_tokens: 128000, + }, + { + id: 'gpt-5.1-codex-mini', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 25, + cached_tokens: 3, + completion_tokens: 200, + }, + max_tokens: 128000, + }, + { + id: 'gpt-5.1-chat-latest', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 125, + cached_tokens: 13, + completion_tokens: 1000, + }, + max_tokens: 16384, + }, + { + id: 'gpt-5-2025-08-07', + aliases: ['gpt-5'], + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 125, + cached_tokens: 13, + completion_tokens: 1000, + }, + max_tokens: 128000, + }, + { + id: 'gpt-5-mini-2025-08-07', + aliases: ['gpt-5-mini'], + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 25, + cached_tokens: 3, + completion_tokens: 200, + }, + max_tokens: 128000, + }, + { + id: 'gpt-5-nano-2025-08-07', + aliases: ['gpt-5-nano'], + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 5, + cached_tokens: 1, + completion_tokens: 40, + }, + max_tokens: 128000, + }, + { + id: 'gpt-5-chat-latest', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 125, + cached_tokens: 13, + completion_tokens: 1000, + }, + max_tokens: 16384, + }, + { + id: 'gpt-4o', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 250, + cached_tokens: 125, + completion_tokens: 1000, + }, + max_tokens: 16384, + }, + { + id: 'gpt-4o-mini', + max_tokens: 16384, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 15, + cached_tokens: 8, + completion_tokens: 60, + }, + }, + { + id: 'o1', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 1500, + cached_tokens: 750, + completion_tokens: 6000, + }, + max_tokens: 100000, + }, + { + id: 'o1-mini', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 110, + completion_tokens: 440, + }, + max_tokens: 65536, + }, + { + id: 'o1-pro', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 15000, + completion_tokens: 60000, + }, + max_tokens: 100000, + }, + { + id: 'o3', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 200, + cached_tokens: 50, + completion_tokens: 800, + }, + max_tokens: 100000, + }, + { + id: 'o3-mini', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 110, + cached_tokens: 55, + completion_tokens: 440, + }, + max_tokens: 100000, + }, + { + id: 'o4-mini', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 110, + completion_tokens: 440, + }, + max_tokens: 100000, + }, + { + id: 'gpt-4.1', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 200, + cached_tokens: 50, + completion_tokens: 800, + }, + max_tokens: 32768, + }, + { + id: 'gpt-4.1-mini', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 40, + cached_tokens: 10, + completion_tokens: 160, + }, + max_tokens: 32768, + }, + { + id: 'gpt-4.1-nano', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 10, + cached_tokens: 2, + completion_tokens: 40, + }, + max_tokens: 32768, + }, + { + id: 'gpt-4.5-preview', + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 7500, + completion_tokens: 15000, + }, + max_tokens: 32768, + }, +]; diff --git a/src/backend/src/services/ai/chat/providers/OpenRouterProvider/OpenRouterProvider.ts b/src/backend/src/services/ai/chat/providers/OpenRouterProvider/OpenRouterProvider.ts new file mode 100644 index 00000000..73e32b72 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/OpenRouterProvider/OpenRouterProvider.ts @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +// METADATA // {"ai-commented":{"service":"claude"}} +import axios from 'axios'; +import { OpenAI } from 'openai'; +import { ChatCompletionCreateParams } from 'openai/resources'; +import APIError from '../../../../../api/APIError.js'; +import { Context } from '../../../../../util/context.js'; +import { kv } from '../../../../../util/kvSingleton.js'; +import { MeteringService } from '../../../../MeteringService/MeteringService.js'; +import * as OpenAIUtil from '../../../utils/OpenAIUtil.js'; +import { IChatModel, IChatProvider } from '../types.js'; + +export class OpenRouterProvider implements IChatProvider { + + #meteringService: MeteringService; + + #openai: OpenAI; + + #apiBaseUrl: string = 'https://openrouter.ai/api/v1'; + + constructor (config: { apiBaseUrl?: string, apiKey: string }, meteringService: MeteringService) { + this.#apiBaseUrl = config.apiBaseUrl || 'https://openrouter.ai/api/v1'; + this.#openai = new OpenAI({ + apiKey: config.apiKey, + baseURL: this.#apiBaseUrl, + }); + this.#meteringService = meteringService; + } + + getDefaultModel () { + return 'openrouter:openai/gpt-5-nano'; + } + /** + * Returns a list of available model names including their aliases + * @returns {Promise} Array of model identifiers and their aliases + * @description Retrieves all available model IDs and their aliases, + * flattening them into a single array of strings that can be used for model selection + */ + async list () { + const models = await this.models(); + const model_names: string[] = []; + for ( const model of models ) { + model_names.push(model.id); + } + return model_names; + } + + /** + * AI Chat completion method. + * See AIChatService for more details. + */ + async complete ({ messages, stream, model, tools, max_tokens, temperature }) { + + const modelUsed = (await this.models()).find(m => [m.id, ...(m.aliases || [])].includes(model)) || (await this.models()).find(m => m.id === this.getDefaultModel())!; + + const modelIdForParams = modelUsed.id.startsWith('openrouter:') ? modelUsed.id.slice('openrouter:'.length) : modelUsed.id; + + if ( model === 'openrouter/auto' ) { + throw APIError.create('field_invalid', undefined, { + key: 'model', + expected: 'allowed model', + got: 'disallowed model', + }); + } + + const actor = Context.get('actor'); + + messages = await OpenAIUtil.process_input_messages(messages); + + const completion = await this.#openai.chat.completions.create({ + messages, + model: modelIdForParams, + ...(tools ? { tools } : {}), + max_tokens, + temperature: temperature, // default to 1.0 + stream, + ...(stream ? { + stream_options: { include_usage: true }, + } : {}), + usage: { include: true }, + } as ChatCompletionCreateParams); + + return OpenAIUtil.handle_completion_output({ + usage_calculator: ({ usage }) => { + // custom open router logic because they're pricing are weird + const trackedUsage = { + prompt: (usage.prompt_tokens ?? 0 ) - (usage.prompt_tokens_details?.cached_tokens ?? 0), + completion: usage.completion_tokens ?? 0, + input_cache_read: usage.prompt_tokens_details?.cached_tokens ?? 0, + }; + const costOverwrites = Object.fromEntries(Object.keys(trackedUsage).map((k) => { + return [k, (modelUsed.costs[k] || 0) * trackedUsage[k]]; + })); + this.#meteringService.utilRecordUsageObject(trackedUsage, actor, modelUsed.id, costOverwrites); + return trackedUsage; + }, + stream, + completion, + }); + } + + async models () { + let models = kv.get('openrouterChat:models'); + if ( ! models ) { + try { + const resp = await axios.request({ + method: 'GET', + url: `${this.#apiBaseUrl}/models`, + }); + + models = resp.data.data; + kv.set('openrouterChat:models', models); + } catch (e) { + console.log(e); + } + } + const coerced_models: IChatModel[] = []; + for ( const model of models ) { + const microcentCosts = Object.fromEntries(Object.entries(model.pricing).map(([k, v]) => [k, Math.round((v as number) * 1_000_000 * 100)])) ; + coerced_models.push({ + id: `openrouter:${model.id}`, + name: `${model.name} (OpenRouter)`, + aliases: [model.id, model.name, `openrouter/${model.id}`, model.id.split('/').slice(1).join('/')], + max_tokens: model.top_provider.max_completion_tokens, + costs_currency: 'usd-cents', + input_cost_key: 'prompt', + output_cost_key: 'completion', + costs: { + tokens: 1_000_000, + ...microcentCosts, + }, + }); + } + return coerced_models; + } + checkModeration (_text: string): ReturnType { + throw new Error('Method not implemented.'); + } +} \ No newline at end of file diff --git a/src/backend/src/services/ai/chat/providers/TogetherAiProvider/TogetherAIProvider.ts b/src/backend/src/services/ai/chat/providers/TogetherAiProvider/TogetherAIProvider.ts new file mode 100644 index 00000000..f6fc0eae --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/TogetherAiProvider/TogetherAIProvider.ts @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { Together } from 'together-ai'; +import { Context } from '../../../../../util/context.js'; +import { kv } from '../../../../../util/kvSingleton.js'; +import { MeteringService } from '../../../../MeteringService/MeteringService.js'; +import * as OpenAIUtil from '../../../utils/OpenAIUtil.js'; +import { IChatModel, IChatProvider, ICompleteArguments } from '../types.js'; + +export class TogetherAIProvider implements IChatProvider { + #together: Together; + + #meteringService: MeteringService; + + #kvKey = 'togetherai:models'; + + constructor (config: { apiKey: string }, meteringService: MeteringService) { + this.#together = new Together({ + apiKey: config.apiKey, + }); + this.#meteringService = meteringService; + } + + getDefaultModel () { + return 'togetherai:meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo'; + } + + async models () { + let models: IChatModel[] | undefined = kv.get(this.#kvKey); + if ( models ) return models; + + const api_models = await this.#together.models.list(); + models = []; + for ( const model of api_models ) { + if ( model.type === 'chat' || model.type === 'code' || model.type === 'language' || model.type === 'moderation' ) { + models.push({ + id: `togetherai:${model.id}`, + aliases: [model.id, `togetherai/${model.id}`, model.id.split('/').slice(1).join('/')], + name: model.display_name, + context: model.context_length, + description: model.display_name, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + ...model.pricing, + }, + max_tokens: model.context_length ?? 8000, + }); + } + } + + models.push({ + id: 'model-fallback-test-1', + name: 'Model Fallback Test 1', + context: 1000, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: 10, + completion_tokens: 10, + }, + max_tokens: 1000, + }); + kv.set(this.#kvKey, models, { EX: 5 * 60 }); + return models; + } + + async list () { + const models = await this.models(); + const modelIds: string[] = []; + for ( const model of models ) { + modelIds.push(model.id); + if ( model.aliases ) { + modelIds.push(...model.aliases); + } + } + return modelIds; + } + + async complete ({ messages, stream, model, tools, max_tokens, temperature }: ICompleteArguments): ReturnType { + if ( model === 'model-fallback-test-1' ) { + throw new Error('Model Fallback Test 1'); + } + + const actor = Context.get('actor'); + const models = await this.models(); + const modelUsed = models.find(m => [m.id, ...(m.aliases || [])].includes(model)) || models.find(m => m.id === this.getDefaultModel())!; + const modelIdForParams = modelUsed.id.startsWith('togetherai:') ? modelUsed.id.slice('togetherai:'.length) : modelUsed.id; + + messages = await OpenAIUtil.process_input_messages(messages); + + const completion = await this.#together.chat.completions.create({ + model: modelIdForParams, + messages, + stream, + ...(tools ? { tools } : {}), + ...(max_tokens ? { max_tokens } : {}), + ...(temperature ? { temperature } : {}), + ...(stream ? { stream_options: { include_usage: true } } : {}), + } as Together.Chat.Completions.CompletionCreateParamsNonStreaming); + + return OpenAIUtil.handle_completion_output({ + usage_calculator: ({ usage }) => { + const trackedUsage = OpenAIUtil.extractMeteredUsage(usage); + const costsOverride = Object.fromEntries(Object.entries(trackedUsage).map(([k, v]) => { + return [k, v * (modelUsed.costs[k] || 0)]; + })); + this.#meteringService.utilRecordUsageObject(trackedUsage, actor, `togetherai:${modelIdForParams}`, costsOverride); + return trackedUsage; + }, + stream, + completion, + }); + } + + checkModeration (_text: string): ReturnType { + throw new Error('Method not implemented.'); + } +} diff --git a/src/backend/src/services/ai/chat/providers/UsageLimitedChatProvider.ts b/src/backend/src/services/ai/chat/providers/UsageLimitedChatProvider.ts new file mode 100644 index 00000000..e26cb17c --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/UsageLimitedChatProvider.ts @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +// METADATA // {"ai-commented":{"service":"claude"}} + +import dedent from 'dedent'; +import { PassThrough } from 'stream'; +import Streaming from '../../utils/Streaming.js'; +import { IChatProvider, ICompleteArguments } from './types.js'; + +/** +* UsageLimitedChatService - A specialized chat service that returns resource exhaustion messages. +* Extends BaseService to provide responses indicating the user has exceeded their usage limits. +* Follows the same response format as real AI providers but with a custom message about upgrading. +* Can handle both streaming and non-streaming requests consistently. +*/ +export class UsageLimitedChatProvider implements IChatProvider { + + models (): ReturnType { + return [{ + id: 'usage-limited', + name: 'Usage Limited', + context: 16384, + costs_currency: 'usd-cents', + input_cost_key: 'input', + output_cost_key: 'output', + max_tokens: 16384, + costs: { + tokens: 1_000_000, + input: 0, + output: 0, + }, + }]; + } + list () { + return ['usage-limited']; + } + async complete ({ stream, customLimitMessage }: ICompleteArguments): ReturnType { + const limitMessage = customLimitMessage || dedent(` + You have reached your AI usage limit for this account. + `); + + // If streaming is requested, return a streaming response + if ( stream ) { + const streamObj = new PassThrough(); + + const chatStream = new Streaming.AIChatStream({ + stream: streamObj, + }); + + // Schedule the streaming response + setTimeout(() => { + chatStream.write({ + type: 'content_block_start', + index: 0, + }); + + chatStream.write({ + type: 'content_block_delta', + index: 0, + delta: { + type: 'text', + text: limitMessage, + }, + }); + + chatStream.write({ + type: 'content_block_stop', + index: 0, + }); + + chatStream.write({ + type: 'message_stop', + stop_reason: 'end_turn', + }); + + chatStream.end(); + }, 10); + + return { + stream: true, + init_chat_stream: async ({ chatStream: cs }) => { + // Copy contents from our stream to the provided one + chatStream.stream.pipe(cs.stream); + }, + finally_fn: async () => { + // No-op + }, + }; + } + + // Non-streaming response + return { + message: { + id: '00000000-0000-0000-0000-000000000000', + type: 'message', + role: 'assistant', + model: 'usage-limited', + content: [ + { + 'type': 'text', + 'text': limitMessage, + }, + ], + stop_reason: 'end_turn', + stop_sequence: null, + usage: { + 'input_tokens': 0, + 'output_tokens': 1, + }, + }, + usage: { + 'input_tokens': 0, + 'output_tokens': 1, + }, + finish_reason: 'stop', + }; + } + checkModeration (_text: string): ReturnType { + throw new Error('Method not implemented.'); + } + + getDefaultModel () { + return 'usage-limited'; + } +} \ No newline at end of file diff --git a/src/backend/src/services/ai/chat/providers/XAIProvider/XAIProvider.ts b/src/backend/src/services/ai/chat/providers/XAIProvider/XAIProvider.ts new file mode 100644 index 00000000..97327cc1 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/XAIProvider/XAIProvider.ts @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { OpenAI } from 'openai'; +import { ChatCompletionCreateParams } from 'openai/resources/index.js'; +import { Context } from '../../../../../util/context.js'; +import { MeteringService } from '../../../../MeteringService/MeteringService.js'; +import * as OpenAIUtil from '../../../utils/OpenAIUtil.js'; +import { IChatProvider, ICompleteArguments } from '../types.js'; +import { XAI_MODELS } from './models.js'; + +export class XAIProvider implements IChatProvider { + #openai: OpenAI; + + #meteringService: MeteringService; + + constructor (config: { apiKey: string }, meteringService: MeteringService) { + this.#openai = new OpenAI({ + apiKey: config.apiKey, + baseURL: 'https://api.x.ai/v1', + }); + this.#meteringService = meteringService; + } + + getDefaultModel () { + return 'grok-beta'; + } + + models () { + return XAI_MODELS; + } + + async list () { + const models = this.models(); + const modelNames: string[] = []; + for ( const model of models ) { + modelNames.push(model.id); + if ( model.aliases ) { + modelNames.push(...model.aliases); + } + } + return modelNames; + } + + async complete ({ messages, stream, model, tools }: ICompleteArguments): ReturnType { + const actor = Context.get('actor'); + const availableModels = this.models(); + const modelUsed = availableModels.find(m => [m.id, ...(m.aliases || [])].includes(model)) || availableModels.find(m => m.id === this.getDefaultModel())!; + + messages = await OpenAIUtil.process_input_messages(messages); + + const completion = await this.#openai.chat.completions.create({ + messages, + model: modelUsed.id, + ...(tools ? { tools } : {}), + max_tokens: 1000, + stream, + ...(stream ? { + stream_options: { include_usage: true }, + } : {}), + } as ChatCompletionCreateParams); + + return OpenAIUtil.handle_completion_output({ + usage_calculator: ({ usage }) => { + const trackedUsage = OpenAIUtil.extractMeteredUsage(usage); + const costsOverride = Object.fromEntries(Object.entries(trackedUsage).map(([k, v]) => { + return [k, v * (modelUsed.costs[k] || 0)]; + })); + this.#meteringService.utilRecordUsageObject(trackedUsage, actor, `xai:${modelUsed.id}`, costsOverride); + return trackedUsage; + }, + stream, + completion, + }); + } + + checkModeration (_text: string): ReturnType { + throw new Error('Method not implemented.'); + } +} diff --git a/src/backend/src/services/ai/chat/providers/XAIProvider/models.ts b/src/backend/src/services/ai/chat/providers/XAIProvider/models.ts new file mode 100644 index 00000000..a77f0153 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/XAIProvider/models.ts @@ -0,0 +1,87 @@ +import { IChatModel } from '../types.js'; + +const makeModel = ({ + id, + name, + context, + input, + output, +}: { + id: string; + name: string; + context: number; + input: number; + output: number; +}): IChatModel => ({ + id, + name, + context, + costs_currency: 'usd-cents', + input_cost_key: 'prompt_tokens', + output_cost_key: 'completion_tokens', + costs: { + tokens: 1_000_000, + prompt_tokens: input, + completion_tokens: output, + }, + max_tokens: context, +}); + +export const XAI_MODELS: IChatModel[] = [ + makeModel({ + id: 'grok-beta', + name: 'Grok Beta', + context: 131072, + input: 500, + output: 1500, + }), + makeModel({ + id: 'grok-vision-beta', + name: 'Grok Vision Beta', + context: 8192, + input: 500, + output: 1500, + }), + makeModel({ + id: 'grok-3', + name: 'Grok 3', + context: 131072, + input: 300, + output: 1500, + }), + makeModel({ + id: 'grok-3-fast', + name: 'Grok 3 Fast', + context: 131072, + input: 500, + output: 2500, + }), + makeModel({ + id: 'grok-3-mini', + name: 'Grok 3 Mini', + context: 131072, + input: 30, + output: 50, + }), + makeModel({ + id: 'grok-3-mini-fast', + name: 'Grok 3 Mini Fast', + context: 131072, + input: 60, + output: 400, + }), + makeModel({ + id: 'grok-2-vision', + name: 'Grok 2 Vision', + context: 8192, + input: 200, + output: 1000, + }), + makeModel({ + id: 'grok-2', + name: 'Grok 2', + context: 131072, + input: 200, + output: 1000, + }), +]; diff --git a/src/backend/src/services/ai/chat/providers/types.ts b/src/backend/src/services/ai/chat/providers/types.ts new file mode 100644 index 00000000..977fbb85 --- /dev/null +++ b/src/backend/src/services/ai/chat/providers/types.ts @@ -0,0 +1,70 @@ +import { Message } from 'openai/resources/conversations/conversations.js'; +import { ModerationCreateResponse } from 'openai/resources/moderations.js'; +import { AIChatStream } from '../../utils/Streaming'; + +type ModelCost = Record; + +export interface IChatModel extends Record { + id: string, + provider?: string, + aliases?: string[] + costs_currency: string, + input_cost_key?: keyof T, + output_cost_key?: keyof T, + costs: T, + context?: number, + max_tokens: number, +} + +export type PuterMessage = Message | any; // TODO DS: type this more strictly +export interface ICompleteArguments { + messages: PuterMessage[]; + provider?: string; + stream?: boolean; + model: string; + tools?: unknown[]; + max_tokens?: number; + temperature?: number; + reasoning?: { effort: 'low' | 'medium' | 'high' } | undefined; + text?: string & { verbosity?: 'concise' | 'detailed' | undefined }; + reasoning_effort?: 'low' | 'medium' | 'high' | undefined; + verbosity?: 'concise' | 'detailed' | undefined; + moderation?: boolean; + custom?: unknown; + response?: { + normalize?: boolean; + }; + customLimitMessage?: string; +} + +export interface IChatProvider { + models(): IChatModel[] | Promise + list(): string[] | Promise + checkModeration (text: string): Promise<{ + flagged: boolean; + results: ModerationCreateResponse & { + _request_id?: string | null; + }; + }> + getDefaultModel(): string; + complete (arg: ICompleteArguments): Promise<{ + init_chat_stream: ({ chatStream }: { + chatStream: AIChatStream; + }) => Promise; + stream: true; + finally_fn: () => Promise; + message?: never; + usage?: never; + finish_reason?: never; + via_ai_chat_service?: true, // legacy field always true now + } | { + message: PuterMessage; + usage: Record; + finish_reason: string; + init_chat_stream?: never; + stream?: never; + finally_fn?: never; + normalized?: boolean; + via_ai_chat_service?: true, // legacy field always true now + }> +} diff --git a/src/backend/src/modules/puterai/doc/README.md b/src/backend/src/services/ai/docs/README.md similarity index 100% rename from src/backend/src/modules/puterai/doc/README.md rename to src/backend/src/services/ai/docs/README.md diff --git a/src/backend/src/modules/puterai/doc/ai-services-config.md b/src/backend/src/services/ai/docs/ai-services-config.md similarity index 100% rename from src/backend/src/modules/puterai/doc/ai-services-config.md rename to src/backend/src/services/ai/docs/ai-services-config.md diff --git a/src/backend/src/modules/puterai/doc/api_examples.md b/src/backend/src/services/ai/docs/api_examples.md similarity index 100% rename from src/backend/src/modules/puterai/doc/api_examples.md rename to src/backend/src/services/ai/docs/api_examples.md diff --git a/src/backend/src/modules/puterai/doc/config.md b/src/backend/src/services/ai/docs/config.md similarity index 100% rename from src/backend/src/modules/puterai/doc/config.md rename to src/backend/src/services/ai/docs/config.md diff --git a/src/backend/src/modules/puterai/doc/contributors/ai_usage_testing.md b/src/backend/src/services/ai/docs/contributors/ai_usage_testing.md similarity index 100% rename from src/backend/src/modules/puterai/doc/contributors/ai_usage_testing.md rename to src/backend/src/services/ai/docs/contributors/ai_usage_testing.md diff --git a/src/backend/src/modules/puterai/GeminiImageGenerationService.js b/src/backend/src/services/ai/image/GeminiImageGenerationService.js similarity index 96% rename from src/backend/src/modules/puterai/GeminiImageGenerationService.js rename to src/backend/src/services/ai/image/GeminiImageGenerationService.js index 4d1b3371..05fafb30 100644 --- a/src/backend/src/modules/puterai/GeminiImageGenerationService.js +++ b/src/backend/src/services/ai/image/GeminiImageGenerationService.js @@ -18,10 +18,10 @@ */ // METADATA // {"ai-commented":{"service":"claude"}} -const APIError = require('../../api/APIError'); -const BaseService = require('../../services/BaseService'); -const { TypedValue } = require('../../services/drivers/meta/Runtime'); -const { Context } = require('../../util/context'); +const APIError = require('../../../api/APIError'); +const BaseService = require('../../BaseService'); +const { TypedValue } = require('../../drivers/meta/Runtime'); +const { Context } = require('../../../util/context'); const { GoogleGenAI } = require('@google/genai'); /** @@ -30,7 +30,7 @@ const { GoogleGenAI } = require('@google/genai'); * the puter-image-generation interface. */ class GeminiImageGenerationService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ + /** @type {import('../../MeteringService/MeteringService').MeteringService} */ get meteringService () { return this.services.get('meteringService').meteringService; } @@ -225,7 +225,7 @@ class GeminiImageGenerationService extends BaseService { * @returns {Array} Array of valid ratio objects * @private */ - _getValidRatios(model) { + _getValidRatios (model) { if ( model === 'gemini-2.5-flash-image-preview' || model === 'gemini-3-pro-image-preview' diff --git a/src/backend/src/modules/puterai/OpenAIImageGenerationService.js b/src/backend/src/services/ai/image/OpenAIImageGenerationService.js similarity index 97% rename from src/backend/src/modules/puterai/OpenAIImageGenerationService.js rename to src/backend/src/services/ai/image/OpenAIImageGenerationService.js index e04504f8..fed48730 100644 --- a/src/backend/src/modules/puterai/OpenAIImageGenerationService.js +++ b/src/backend/src/services/ai/image/OpenAIImageGenerationService.js @@ -18,10 +18,10 @@ */ // METADATA // {"ai-commented":{"service":"claude"}} -const APIError = require('../../api/APIError'); -const BaseService = require('../../services/BaseService'); -const { TypedValue } = require('../../services/drivers/meta/Runtime'); -const { Context } = require('../../util/context'); +const APIError = require('../../../api/APIError'); +const BaseService = require('../../BaseService'); +const { TypedValue } = require('../../drivers/meta/Runtime'); +const { Context } = require('../../../util/context'); /** * Service class for generating images using OpenAI's DALL-E API. @@ -31,7 +31,7 @@ const { Context } = require('../../util/context'); * validation, and spending tracking. */ class OpenAIImageGenerationService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ + /** @type {import('../../MeteringService/MeteringService').MeteringService} */ get meteringService () { return this.services.get('meteringService').meteringService; } diff --git a/src/backend/src/modules/puterai/TogetherImageGenerationService.js b/src/backend/src/services/ai/image/TogetherImageGenerationService.js similarity index 59% rename from src/backend/src/modules/puterai/TogetherImageGenerationService.js rename to src/backend/src/services/ai/image/TogetherImageGenerationService.js index d2bfe001..156830ca 100644 --- a/src/backend/src/modules/puterai/TogetherImageGenerationService.js +++ b/src/backend/src/services/ai/image/TogetherImageGenerationService.js @@ -18,11 +18,11 @@ */ // METADATA // {"ai-commented":{"service":"claude"}} -const APIError = require('../../api/APIError'); -const BaseService = require('../../services/BaseService'); -const { TypedValue } = require('../../services/drivers/meta/Runtime'); -const { Context } = require('../../util/context'); -const { Together } = require('together-ai'); +import { Context } from '../../../util/context.js'; +import { Together } from 'together-ai'; +import { APIError } from 'openai'; +import BaseService from '../../BaseService.js'; +import { TypedValue } from '../../drivers/meta/Runtime.js'; /** * Service class for generating images using Together AI models. @@ -30,14 +30,21 @@ const { Together } = require('together-ai'); * puter-image-generation interface. Handles authentication, request validation, * and metering integration. */ -class TogetherImageGenerationService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ + +export class TogetherImageGenerationService extends BaseService { + DEFAULT_MODEL = 'black-forest-labs/FLUX.1-schnell'; + DEFAULT_RATIO = { w: 1024, h: 1024 }; + CONDITION_IMAGE_MODELS = [ + 'black-forest-labs/flux.1-kontext-dev', + 'black-forest-labs/flux.1-kontext-pro', + 'black-forest-labs/flux.1-kontext-max', + ]; + + /** @type {import('../../MeteringService/MeteringService.js').MeteringService} */ get meteringService () { return this.services.get('meteringService').meteringService; } - static MODULES = {}; - async _init () { const apiKey = this.config?.apiKey ?? @@ -58,103 +65,98 @@ class TogetherImageGenerationService extends BaseService { }, }, ['puter-image-generation']: { - /** - * Generates an image using Together AI image models - * @param {object} params - Generation parameters - * @param {string} params.prompt - Prompt describing the desired image - * @param {string} [params.model] - Together AI model identifier - * @param {object} [params.ratio] - Width/height ratio object (e.g., { w: 1024, h: 1024 }) - * @param {number} [params.width] - Explicit width override - * @param {number} [params.height] - Explicit height override - * @param {string} [params.aspect_ratio] - Aspect ratio string (e.g., "16:9") - * @param {number} [params.steps] - Diffusion step count - * @param {number} [params.seed] - Seed for reproducibility - * @param {string} [params.negative_prompt] - Negative prompt text - * @param {number} [params.n] - Number of images to generate (default 1) - * @param {string} [params.image_url] - Reference image URL for image-to-image - * @param {string} [params.image_base64] - Base64 encoded reference image - * @param {boolean} [params.disable_safety_checker] - Disable Together AI safety checker - * @param {boolean} [params.test_mode] - Enable Puter test mode shortcut - * @returns {Promise} TypedValue containing the generated image URL or data URI - */ - async generate (params) { - const { - prompt, - test_mode, - ratio, - model, - width, - height, - aspect_ratio, - steps, - seed, - negative_prompt, - n, - image_url, - image_base64, - mask_image_url, - mask_image_base64, - prompt_strength, - disable_safety_checker, - response_format, - } = params; - - const svc_event = this.services.get('event'); - svc_event.emit('ai.log.image', { actor: Context.get('actor'), parameters: params, completionId: '0', intended_service: params.model }); - - if ( test_mode ) { - return new TypedValue({ - $: 'string:url:web', - content_type: 'image', - }, 'https://puter-sample-data.puter.site/image_example.png'); - } - - const url = await this.generate(prompt, { - ratio, - model, - width, - height, - aspect_ratio, - steps, - seed, - negative_prompt, - n, - image_url, - image_base64, - mask_image_url, - mask_image_base64, - prompt_strength, - disable_safety_checker, - response_format, - }); - - const isDataUrl = url.startsWith('data:'); - return new TypedValue({ - $: isDataUrl ? 'string:url:data' : 'string:url:web', - content_type: 'image', - }, url); + async generate (...args) { + return this.generate(...args); }, }, + ['models']: { + + }, }; - static DEFAULT_MODEL = 'black-forest-labs/FLUX.1-schnell'; - static DEFAULT_RATIO = { w: 1024, h: 1024 }; - static CONDITION_IMAGE_MODELS = [ - 'black-forest-labs/flux.1-kontext-dev', - 'black-forest-labs/flux.1-kontext-pro', - 'black-forest-labs/flux.1-kontext-max', - ]; - /** - * Generates an image using Together AI client - * @private + * Generates an image using Together AI image models + * @param {object} params - Generation parameters + * @param {string} params.prompt - Prompt describing the desired image + * @param {string} [params.model] - Together AI model identifier + * @param {object} [params.ratio] - Width/height ratio object (e.g., { w: 1024, h: 1024 }) + * @param {number} [params.width] - Explicit width override + * @param {number} [params.height] - Explicit height override + * @param {string} [params.aspect_ratio] - Aspect ratio string (e.g., "16:9") + * @param {number} [params.steps] - Diffusion step count + * @param {number} [params.seed] - Seed for reproducibility + * @param {string} [params.negative_prompt] - Negative prompt text + * @param {number} [params.n] - Number of images to generate (default 1) + * @param {string} [params.image_url] - Reference image URL for image-to-image + * @param {string} [params.image_base64] - Base64 encoded reference image + * @param {boolean} [params.disable_safety_checker] - Disable Together AI safety checker + * @param {boolean} [params.test_mode] - Enable Puter test mode shortcut + * @returns {Promise} TypedValue containing the generated image URL or data URI */ - async generate (prompt, options) { + async generate (params) { + const { + prompt, + test_mode, + ratio, + model, + width, + height, + aspect_ratio, + steps, + seed, + negative_prompt, + n, + image_url, + image_base64, + mask_image_url, + mask_image_base64, + prompt_strength, + disable_safety_checker, + response_format, + } = params; + + const svc_event = this.services.get('event'); + svc_event.emit('ai.log.image', { actor: Context.get('actor'), parameters: params, completionId: '0', intended_service: params.model }); + + if ( test_mode ) { + return new TypedValue({ + $: 'string:url:web', + content_type: 'image', + }, 'https://puter-sample-data.puter.site/image_example.png'); + } + + const url = await this.#generate(prompt, { + ratio, + model, + width, + height, + aspect_ratio, + steps, + seed, + negative_prompt, + n, + image_url, + image_base64, + mask_image_url, + mask_image_base64, + prompt_strength, + disable_safety_checker, + response_format, + }); + + const isDataUrl = url.startsWith('data:'); + return new TypedValue({ + $: isDataUrl ? 'string:url:data' : 'string:url:web', + content_type: 'image', + }, url); + } + + async #generate (prompt, options) { if ( typeof prompt !== 'string' || prompt.trim().length === 0 ) { throw new Error('`prompt` must be a non-empty string'); } - const request = this._buildRequest(prompt, options); + const request = this.#buildRequest(prompt, options); const actor = Context.get('actor'); if ( ! actor ) { @@ -187,9 +189,8 @@ class TogetherImageGenerationService extends BaseService { /** * Normalizes Together AI image generation request parameters - * @private */ - _buildRequest (prompt, options = {}) { + #buildRequest (prompt, options = {}) { const { ratio, model, @@ -215,13 +216,13 @@ class TogetherImageGenerationService extends BaseService { model: model ?? this.constructor.DEFAULT_MODEL, }; const requiresConditionImage = - this.constructor._modelRequiresConditionImage(request.model); + this.#modelRequiresConditionImage(request.model); const ratioWidth = (ratio && ratio.w !== undefined) ? Number(ratio.w) : undefined; const ratioHeight = (ratio && ratio.h !== undefined) ? Number(ratio.h) : undefined; - const normalizedWidth = this._normalizeDimension(width !== undefined ? Number(width) : (ratioWidth ?? this.constructor.DEFAULT_RATIO.w)); - const normalizedHeight = this._normalizeDimension(height !== undefined ? Number(height) : (ratioHeight ?? this.constructor.DEFAULT_RATIO.h)); + const normalizedWidth = this.#normalizeDimension(width !== undefined ? Number(width) : (ratioWidth ?? this.constructor.DEFAULT_RATIO.w)); + const normalizedHeight = this.#normalizeDimension(height !== undefined ? Number(height) : (ratioHeight ?? this.constructor.DEFAULT_RATIO.h)); if ( aspect_ratio ) { request.aspect_ratio = aspect_ratio; @@ -269,14 +270,14 @@ class TogetherImageGenerationService extends BaseService { return request; } - _normalizeDimension (value) { + #normalizeDimension (value) { if ( typeof value !== 'number' ) return undefined; const rounded = Math.max(64, Math.round(value)); // Flux models expect multiples of 8. Snap to the nearest multiple without going below 64. return Math.max(64, Math.round(rounded / 8) * 8); } - static _modelRequiresConditionImage (model) { + #modelRequiresConditionImage (model) { if ( typeof model !== 'string' || model.trim() === '' ) { return false; } @@ -284,8 +285,4 @@ class TogetherImageGenerationService extends BaseService { const normalized = model.toLowerCase(); return this.CONDITION_IMAGE_MODELS.some(required => normalized === required); } -} - -module.exports = { - TogetherImageGenerationService, -}; +} \ No newline at end of file diff --git a/src/backend/src/modules/puterai/lib/AsModeration.js b/src/backend/src/services/ai/moderation/AsModeration.js similarity index 82% rename from src/backend/src/modules/puterai/lib/AsModeration.js rename to src/backend/src/services/ai/moderation/AsModeration.js index 7b58d63c..f15a89d4 100644 --- a/src/backend/src/modules/puterai/lib/AsModeration.js +++ b/src/backend/src/services/ai/moderation/AsModeration.js @@ -20,9 +20,21 @@ const { default: dedent } = require('dedent'); class AsModeration { - constructor ({ chat, model }) { - this.chat = chat; - this.model = model; + + /** @type {import('../chat/providers/ChatProvider').IChatProvider} */ + #chatProvider; + + /** @type {string} */ + #model; + + /** + * @param {object} args + * @param {import('../chat/providers/ChatProvider').IChatProvider} args.chatProvider + * @param {string} args.model + */ + constructor ({ chatProvider, model }) { + this.#chatProvider = chatProvider; + this.#model = model; } async moderate (text) { @@ -51,10 +63,7 @@ class AsModeration { Message: - ${text - .replace('<', '<') - .replace('>', '>') - } + ${text.replace('<', '<').replace('>', '>')} Unsafe Categories: @@ -70,17 +79,15 @@ class AsModeration { }} `); - const result = await this.chat.complete({ + const result = await this.#chatProvider.complete({ messages: [ { role: 'user', content: assessment_prompt, }, ], + model: this.#model, }); - - console.log('result???', require('util').inspect(result, { depth: null })); - const str = result.message?.content?.[0]?.text ?? result.messages?.[0]?.content?.[0]?.text ?? '{ "violation": true }'; diff --git a/src/backend/src/modules/puterai/AWSTextractService.js b/src/backend/src/services/ai/ocr/AWSTextractService.js similarity index 97% rename from src/backend/src/modules/puterai/AWSTextractService.js rename to src/backend/src/services/ai/ocr/AWSTextractService.js index e6778351..1a547c6b 100644 --- a/src/backend/src/modules/puterai/AWSTextractService.js +++ b/src/backend/src/services/ai/ocr/AWSTextractService.js @@ -20,9 +20,9 @@ // METADATA // {"ai-commented":{"service":"claude"}} const { TextractClient, AnalyzeDocumentCommand, InvalidS3ObjectException } = require('@aws-sdk/client-textract'); -const BaseService = require('../../services/BaseService'); -const APIError = require('../../api/APIError'); -const { Context } = require('../../util/context'); +const BaseService = require('../../BaseService'); +const APIError = require('../../../api/APIError'); +const { Context } = require('../../../util/context'); /** * AWSTextractService class - Provides OCR (Optical Character Recognition) functionality using AWS Textract @@ -31,7 +31,7 @@ const { Context } = require('../../util/context'); * Handles both S3-stored and buffer-based document processing with automatic region management. */ class AWSTextractService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ + /** @type {import('../../MeteringService/MeteringService').MeteringService} */ get meteringService () { return this.services.get('meteringService').meteringService; } diff --git a/src/backend/src/services/ai/ocr/MistralOCRService.js b/src/backend/src/services/ai/ocr/MistralOCRService.js new file mode 100644 index 00000000..be45b3aa --- /dev/null +++ b/src/backend/src/services/ai/ocr/MistralOCRService.js @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +// METADATA // {"ai-commented":{"service":"claude"}} +import { Context } from '@heyputer/putility/src/libs/context.js'; +import { Mistral } from '@mistralai/mistralai'; +import mime from 'mime-types'; +import { APIError } from 'openai'; +import path from 'path'; +import BaseService from '../../BaseService.js'; + +/** +* MistralAIService class extends BaseService to provide integration with the Mistral AI API. +* Implements chat completion functionality with support for various Mistral models including +* mistral-large, pixtral, codestral, and ministral variants. Handles both streaming and +* non-streaming responses, token usage tracking, and model management. Provides cost information +* for different models and implements the puter-chat-completion interface. +*/ +export class MistralOCRService extends BaseService { + /** @type {import('../../MeteringService/MeteringService.js').MeteringService} */ + meteringService; + /** + * Initializes the service's cost structure for different Mistral AI models. + * Sets up pricing information for various models including token costs for input/output. + * Each model entry specifies currency (usd-cents) and costs per million tokens. + * @private + */ + + models = [ + { id: 'mistral-ocr-latest', + aliases: ['mistral-ocr-2505', 'mistral-ocr'], + cost: { + currency: 'usd-cents', + pages: 1000, + input: 100, + output: 300, + }, + }, + ]; + + static IMPLEMENTS = { + 'driver-capabilities': { + supports_test_mode (iface, method_name) { + return iface === 'puter-ocr' && method_name === 'recognize'; + }, + }, + 'puter-ocr': { + async recognize (...params) { + return this.recognize(...params); + }, + }, + }; + + /** + * Initializes the service's cost structure for different Mistral AI models. + * Sets up pricing information for various models including token costs for input/output. + * Each model entry specifies currency (USD cents) and costs per million tokens. + * @private + */ + async _init () { + this.api_base_url = 'https://api.mistral.ai/v1'; + this.client = new Mistral({ + apiKey: this.config.apiKey, + }); + + const svc_aiChat = this.services.get('ai-chat'); + svc_aiChat.register_provider({ + service_name: this.service_name, + alias: true, + }); + + this.meteringService = this.services.get('meteringService').meteringService; + } + + async recognize ({ + source, + model, + pages, + includeImageBase64, + imageLimit, + imageMinSize, + bboxAnnotationFormat, + documentAnnotationFormat, + test_mode, + }) { + if ( test_mode ) { + return this.#sampleOcrResponse(); + } + if ( ! source ) { + throw APIError.create('missing_required_argument', { + interface_name: 'puter-ocr', + method_name: 'recognize', + arg_name: 'source', + }); + } + + const document = await this._buildDocumentChunkFromSource(source); + const payload = { + model: model ?? 'mistral-ocr-latest', + document, + }; + if ( Array.isArray(pages) ) { + payload.pages = pages; + } + if ( typeof includeImageBase64 === 'boolean' ) { + payload.includeImageBase64 = includeImageBase64; + } + if ( typeof imageLimit === 'number' ) { + payload.imageLimit = imageLimit; + } + if ( typeof imageMinSize === 'number' ) { + payload.imageMinSize = imageMinSize; + } + if ( bboxAnnotationFormat !== undefined ) { + payload.bboxAnnotationFormat = bboxAnnotationFormat; + } + if ( documentAnnotationFormat !== undefined ) { + payload.documentAnnotationFormat = documentAnnotationFormat; + } + + const response = await this.client.ocr.process(payload); + const annotationsRequested = ( + payload.documentAnnotationFormat !== undefined || + payload.bboxAnnotationFormat !== undefined + ); + this.#recordOcrUsage(response, payload.model, { + annotationsRequested, + }); + return this.#normalizeOcrResponse(response); + } + + async _buildDocumentChunkFromSource (fileFacade) { + const dataUrl = await this._safeFileValue(fileFacade, 'data_url'); + const webUrl = await this._safeFileValue(fileFacade, 'web_url'); + const filePath = await this._safeFileValue(fileFacade, 'path'); + const fsNode = await this._safeFileValue(fileFacade, 'fs-node'); + const fileName = filePath ? path.basename(filePath) : fsNode?.name; + const inferredMime = this._inferMimeFromName(fileName); + + if ( webUrl ) { + return this._chunkFromUrl(webUrl, fileName, inferredMime); + } + if ( dataUrl ) { + const mimeFromUrl = this._extractMimeFromDataUrl(dataUrl) ?? inferredMime; + return this._chunkFromUrl(dataUrl, fileName, mimeFromUrl); + } + + const buffer = await this._safeFileValue(fileFacade, 'buffer'); + if ( ! buffer ) { + throw APIError.create('field_invalid', null, { + key: 'source', + expected: 'file, data URL, or web URL', + }); + } + const mimeType = inferredMime ?? 'application/octet-stream'; + const generatedDataUrl = this._createDataUrl(buffer, mimeType); + return this._chunkFromUrl(generatedDataUrl, fileName, mimeType); + } + + async _safeFileValue (fileFacade, key) { + if ( !fileFacade || typeof fileFacade.get !== 'function' ) return undefined; + const maybeCache = fileFacade.values?.values; + if ( maybeCache && Object.prototype.hasOwnProperty.call(maybeCache, key) ) { + return maybeCache[key]; + } + try { + return await fileFacade.get(key); + } catch (e) { + return undefined; + } + } + + _chunkFromUrl (url, fileName, mimeType) { + const lowerName = fileName?.toLowerCase(); + const urlLooksPdf = /\.pdf($|\?)/i.test(url); + const mimeLooksPdf = mimeType?.includes('pdf'); + const isPdf = mimeLooksPdf || urlLooksPdf || (lowerName ? lowerName.endsWith('.pdf') : false); + + if ( isPdf ) { + const chunk = { + type: 'document_url', + documentUrl: url, + }; + if ( fileName ) { + chunk.documentName = fileName; + } + return chunk; + } + + return { + type: 'image_url', + imageUrl: { + url, + }, + }; + } + + _inferMimeFromName (name) { + if ( ! name ) return undefined; + return mime.lookup(name) || undefined; + } + + _extractMimeFromDataUrl (url) { + if ( typeof url !== 'string' ) return undefined; + const match = url.match(/^data:([^;,]+)[;,]/); + return match ? match[1] : undefined; + } + + _createDataUrl (buffer, mimeType) { + return `data:${mimeType || 'application/octet-stream'};base64,${buffer.toString('base64')}`; + } + + #normalizeOcrResponse (response) { + if ( ! response ) return {}; + const normalized = { + model: response.model, + pages: response.pages ?? [], + usage_info: response.usageInfo, + }; + const blocks = []; + if ( Array.isArray(response.pages) ) { + for ( const page of response.pages ) { + if ( typeof page?.markdown !== 'string' ) continue; + const lines = page.markdown.split('\n').map(line => line.trim()).filter(Boolean); + for ( const line of lines ) { + blocks.push({ + type: 'text/mistral:LINE', + text: line, + page: page.index, + }); + } + } + } + normalized.blocks = blocks; + if ( blocks.length ) { + normalized.text = blocks.map(block => block.text).join('\n'); + } else if ( Array.isArray(response.pages) ) { + normalized.text = response.pages.map(page => page?.markdown || '').join('\n\n').trim(); + } + return normalized; + } + + #recordOcrUsage (response, model, { annotationsRequested } = {}) { + try { + if ( ! this.meteringService ) return; + const actor = Context.get('actor'); + if ( ! actor ) return; + const pagesProcessed = + response?.usageInfo?.pagesProcessed ?? + (Array.isArray(response?.pages) ? response.pages.length : 1); + this.meteringService.incrementUsage(actor, 'mistral-ocr:ocr:page', pagesProcessed); + if ( annotationsRequested ) { + this.meteringService.incrementUsage(actor, 'mistral-ocr:annotations:page', pagesProcessed); + } + } catch (e) { + // ignore metering failures to avoid blocking OCR results + } + } + + #sampleOcrResponse () { + const markdown = 'Sample OCR output (test mode).'; + return { + model: 'mistral-ocr-latest', + pages: [ + { + index: 0, + markdown, + images: [], + dimensions: null, + }, + ], + blocks: [ + { + type: 'text/mistral:LINE', + text: markdown, + page: 0, + }, + ], + text: markdown, + }; + } +} diff --git a/src/backend/src/modules/puterai/ElevenLabsVoiceChangerService.js b/src/backend/src/services/ai/sts/ElevenLabsVoiceChangerService.js similarity index 94% rename from src/backend/src/modules/puterai/ElevenLabsVoiceChangerService.js rename to src/backend/src/services/ai/sts/ElevenLabsVoiceChangerService.js index 31978c65..78e2752f 100644 --- a/src/backend/src/modules/puterai/ElevenLabsVoiceChangerService.js +++ b/src/backend/src/services/ai/sts/ElevenLabsVoiceChangerService.js @@ -18,11 +18,11 @@ */ const { Readable } = require('stream'); -const APIError = require('../../api/APIError'); -const BaseService = require('../../services/BaseService'); -const { TypedValue } = require('../../services/drivers/meta/Runtime'); -const { FileFacade } = require('../../services/drivers/FileFacade'); -const { Context } = require('../../util/context'); +const APIError = require('../../../api/APIError'); +const BaseService = require('../../BaseService'); +const { TypedValue } = require('../../drivers/meta/Runtime'); +const { FileFacade } = require('../../drivers/FileFacade'); +const { Context } = require('../../../util/context'); const DEFAULT_MODEL = 'eleven_multilingual_sts_v2'; const DEFAULT_VOICE_ID = '21m00Tcm4TlvDq8ikWAM'; @@ -34,7 +34,7 @@ const DEFAULT_OUTPUT_FORMAT = 'mp3_44100_128'; * ElevenLabs voice changer (speech-to-speech). */ class ElevenLabsVoiceChangerService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ + /** @type {import('../../MeteringService/MeteringService').MeteringService} */ get meteringService () { return this.services.get('meteringService').meteringService; } @@ -68,7 +68,7 @@ class ElevenLabsVoiceChangerService extends BaseService { this.defaultVoiceId = svcConfig?.defaultVoiceId ?? svcConfig?.voiceId ?? DEFAULT_VOICE_ID; this.defaultModelId = svcConfig?.speechToSpeechModelId ?? svcConfig?.stsModelId ?? DEFAULT_MODEL; - if ( !this.apiKey ) { + if ( ! this.apiKey ) { throw new Error('ElevenLabs API key not configured'); } } @@ -99,11 +99,11 @@ class ElevenLabsVoiceChangerService extends BaseService { }, SAMPLE_AUDIO_URL); } - if ( !audio ) { + if ( ! audio ) { throw APIError.create('field_required', null, { key: 'audio' }); } - if ( !(audio instanceof FileFacade) ) { + if ( ! (audio instanceof FileFacade) ) { throw APIError.create('field_invalid', null, { key: 'audio', expected: 'file reference', @@ -120,14 +120,14 @@ class ElevenLabsVoiceChangerService extends BaseService { const modelId = model_id || model || this.defaultModelId || DEFAULT_MODEL; const selectedVoiceId = voice_id || voiceId || voice || this.defaultVoiceId; - if ( !selectedVoiceId ) { + if ( ! selectedVoiceId ) { throw APIError.create('field_required', null, { key: 'voice' }); } const actor = Context.get('actor'); const usageKey = `elevenlabs:${modelId}:second`; const usageAllowed = await this.meteringService.hasEnoughCreditsFor(actor, usageKey, estimatedSeconds); - if ( !usageAllowed ) { + if ( ! usageAllowed ) { throw APIError.create('insufficient_funds'); } @@ -182,7 +182,7 @@ class ElevenLabsVoiceChangerService extends BaseService { body: formData, }); - if ( !response.ok ) { + if ( ! response.ok ) { let detail = null; try { detail = await response.json(); diff --git a/src/backend/src/modules/puterai/OpenAISpeechToTextService.js b/src/backend/src/services/ai/stt/OpenAISpeechToTextService.js similarity index 97% rename from src/backend/src/modules/puterai/OpenAISpeechToTextService.js rename to src/backend/src/services/ai/stt/OpenAISpeechToTextService.js index d70e26fc..5aa8418e 100644 --- a/src/backend/src/modules/puterai/OpenAISpeechToTextService.js +++ b/src/backend/src/services/ai/stt/OpenAISpeechToTextService.js @@ -17,10 +17,10 @@ * along with this program. If not, see . */ -const BaseService = require('../../services/BaseService'); -const APIError = require('../../api/APIError'); -const { Context } = require('../../util/context'); -const { FileFacade } = require('../../services/drivers/FileFacade'); +const BaseService = require('../../BaseService'); +const APIError = require('../../../api/APIError'); +const { Context } = require('../../../util/context'); +const { FileFacade } = require('../../drivers/FileFacade'); const MAX_AUDIO_FILE_SIZE = 25 * 1024 * 1024; // 25 MB per OpenAI limits const DEFAULT_TRANSCRIBE_MODEL = 'gpt-4o-mini-transcribe'; @@ -63,7 +63,7 @@ const TRANSCRIPTION_MODEL_CAPABILITIES = { }; class OpenAISpeechToTextService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ + /** @type {import('../../MeteringService/MeteringService').MeteringService} */ get meteringService () { return this.services.get('meteringService').meteringService; } diff --git a/src/backend/src/modules/puterai/AWSPollyService.js b/src/backend/src/services/ai/tts/AWSPollyService.js similarity index 97% rename from src/backend/src/modules/puterai/AWSPollyService.js rename to src/backend/src/services/ai/tts/AWSPollyService.js index bb86e990..a7d11fee 100644 --- a/src/backend/src/modules/puterai/AWSPollyService.js +++ b/src/backend/src/services/ai/tts/AWSPollyService.js @@ -19,10 +19,10 @@ // METADATA // {"ai-commented":{"service":"claude"}} const { PollyClient, SynthesizeSpeechCommand, DescribeVoicesCommand } = require('@aws-sdk/client-polly'); -const BaseService = require('../../services/BaseService'); -const { TypedValue } = require('../../services/drivers/meta/Runtime'); -const APIError = require('../../api/APIError'); -const { Context } = require('../../util/context'); +const BaseService = require('../../BaseService'); +const { TypedValue } = require('../../drivers/meta/Runtime'); +const APIError = require('../../../api/APIError'); +const { Context } = require('../../../util/context'); // Polly price calculation per engine const ENGINE_PRICING = { @@ -45,7 +45,7 @@ const VALID_ENGINES = ['standard', 'neural', 'long-form', 'generative']; */ class AWSPollyService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ + /** @type {import('../../MeteringService/MeteringService').MeteringService} */ get meteringService () { return this.services.get('meteringService').meteringService; } diff --git a/src/backend/src/modules/puterai/ElevenLabsTTSService.js b/src/backend/src/services/ai/tts/ElevenLabsTTSService.js similarity index 94% rename from src/backend/src/modules/puterai/ElevenLabsTTSService.js rename to src/backend/src/services/ai/tts/ElevenLabsTTSService.js index b6bb7a35..0144d8aa 100644 --- a/src/backend/src/modules/puterai/ElevenLabsTTSService.js +++ b/src/backend/src/services/ai/tts/ElevenLabsTTSService.js @@ -18,10 +18,10 @@ */ const { Readable } = require('stream'); -const APIError = require('../../api/APIError'); -const BaseService = require('../../services/BaseService'); -const { TypedValue } = require('../../services/drivers/meta/Runtime'); -const { Context } = require('../../util/context'); +const APIError = require('../../../api/APIError'); +const BaseService = require('../../BaseService'); +const { TypedValue } = require('../../drivers/meta/Runtime'); +const { Context } = require('../../../util/context'); const DEFAULT_MODEL = 'eleven_multilingual_v2'; const DEFAULT_VOICE_ID = '21m00Tcm4TlvDq8ikWAM'; // Common public "Rachel" sample voice @@ -41,7 +41,7 @@ const ELEVENLABS_TTS_MODELS = [ * using ElevenLabs voices. */ class ElevenLabsTTSService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ + /** @type {import('../../MeteringService/MeteringService').MeteringService} */ get meteringService () { return this.services.get('meteringService').meteringService; } @@ -72,7 +72,7 @@ class ElevenLabsTTSService extends BaseService { this.baseUrl = svcThere?.baseUrl ?? 'https://api.elevenlabs.io'; this.defaultVoiceId = svcThere?.defaultVoiceId ?? svcThere?.voiceId ?? DEFAULT_VOICE_ID; - if ( !this.apiKey ) { + if ( ! this.apiKey ) { throw new Error('ElevenLabs API key not configured'); } } @@ -158,7 +158,7 @@ class ElevenLabsTTSService extends BaseService { const actor = Context.get('actor'); const usageKey = `elevenlabs:${modelId}:character`; const usageAllowed = await this.meteringService.hasEnoughCreditsFor(actor, usageKey, text.length); - if ( !usageAllowed ) { + if ( ! usageAllowed ) { throw APIError.create('insufficient_funds'); } diff --git a/src/backend/src/modules/puterai/OpenAITTSService.js b/src/backend/src/services/ai/tts/OpenAITTSService.js similarity index 95% rename from src/backend/src/modules/puterai/OpenAITTSService.js rename to src/backend/src/services/ai/tts/OpenAITTSService.js index 68e8f656..d93592d3 100644 --- a/src/backend/src/modules/puterai/OpenAITTSService.js +++ b/src/backend/src/services/ai/tts/OpenAITTSService.js @@ -18,10 +18,10 @@ */ const { Readable } = require('stream'); -const APIError = require('../../api/APIError'); -const BaseService = require('../../services/BaseService'); -const { TypedValue } = require('../../services/drivers/meta/Runtime'); -const { Context } = require('../../util/context'); +const APIError = require('../../../api/APIError'); +const BaseService = require('../../BaseService'); +const { TypedValue } = require('../../drivers/meta/Runtime'); +const { Context } = require('../../../util/context'); const DEFAULT_MODEL = 'gpt-4o-mini-tts'; const DEFAULT_VOICE = 'alloy'; @@ -73,7 +73,7 @@ const OPENAI_TTS_MODELS = [ * the AWS Polly implementation. */ class OpenAITTSService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ + /** @type {import('../../MeteringService/MeteringService').MeteringService} */ get meteringService () { return this.services.get('meteringService').meteringService; } diff --git a/src/backend/src/services/ai/utils/FunctionCalling.js b/src/backend/src/services/ai/utils/FunctionCalling.js new file mode 100644 index 00000000..ad8df58b --- /dev/null +++ b/src/backend/src/services/ai/utils/FunctionCalling.js @@ -0,0 +1,120 @@ +/** + * Normalizes the 'tools' object in-place. + * + * This function will accept an array of tools provided by the + * user, and produce a normalized object that can then be + * converted to the apprpriate representation for another + * service. + * + * We will accept conventions from either service that a user + * might expect to work, prioritizing the OpenAI convention + * when conflicting conventions are present. + * + * @param {*} tools + */ +export const normalize_tools_object = (tools) => { + for ( let i = 0 ; i < tools.length ; i++ ) { + const tool = tools[i]; + let normalized_tool = {}; + + const normalize_function = fn => { + const normal_fn = {}; + let parameters = + fn.parameters || + fn.input_schema; + + normal_fn.parameters = parameters ?? { + type: 'object', + }; + + if ( parameters.properties ) { + parameters = this.normalize_json_schema(parameters); + } + + if ( fn.name ) { + normal_fn.name = fn.name; + } + + if ( fn.description ) { + normal_fn.description = fn.description; + } + + return normal_fn; + }; + + if ( tool.input_schema ) { + normalized_tool = { + type: 'function', + function: normalize_function(tool), + }; + } else if ( tool.type === 'function' ) { + normalized_tool = { + type: 'function', + function: normalize_function(tool.function), + }; + } else { + normalized_tool = { + type: 'function', + function: normalize_function(tool), + }; + } + + tools[i] = normalized_tool; + } + return tools; +}; + +export const normalize_json_schema = (schema) => { + if ( ! schema ) return schema; + + if ( schema.type === 'object' ) { + if ( ! schema.properties ) { + return schema; + } + + const keys = Object.keys(schema.properties); + for ( const key of keys ) { + schema.properties[key] = this.normalize_json_schema(schema.properties[key]); + } + } + + if ( schema.type === 'array' ) { + if ( ! schema.items ) { + schema.items = {}; + } else { + schema.items = this.normalize_json_schema(schema.items); + } + } + + return schema; +}; + +/** + * This function will convert a normalized tools object to the + * format expected by OpenAI. + * + * @param {*} tools + * @returns + */ +export const make_openai_tools = (tools) => { + return tools; +}; + +/** + * This function will convert a normalized tools object to the + * format expected by Claude. + * + * @param {*} tools + * @returns + */ +export const make_claude_tools = (tools) => { + if ( ! tools ) return undefined; + return tools.map(tool => { + const { name, description, parameters } = tool.function; + return { + name, + description, + input_schema: parameters, + }; + }); +}; diff --git a/src/backend/src/services/ai/utils/Messages.js b/src/backend/src/services/ai/utils/Messages.js new file mode 100644 index 00000000..7f0dae88 --- /dev/null +++ b/src/backend/src/services/ai/utils/Messages.js @@ -0,0 +1,184 @@ +import { whatis } from '../../../util/langutil.js'; + +/** + * Normalizes a single message into a standardized format with role and content array. + * Converts string messages to objects, ensures content is an array of content blocks, + * transforms tool_calls into tool_use content blocks, and coerces content items into objects. + * + * @param {string|Object} message - The message to normalize, either a string or message object + * @param {Object} params - Optional parameters including default role + * @returns {Object} Normalized message with role and content array + * @throws {Error} If message is not a string or object + * @throws {Error} If message has no content property and no tool_calls + * @throws {Error} If any content item is not a string or object + */ +export const normalize_single_message = (message, params = {}) => { + params = Object.assign({ + role: 'user', + }, params); + + if ( typeof message === 'string' ) { + message = { + content: [message], + }; + } + if ( whatis(message) !== 'object' ) { + throw new Error('each message must be a string or object'); + } + if ( ! message.role ) { + message.role = params.role; + } + if ( ! message.content ) { + if ( message.tool_calls ) { + message.content = []; + for ( let i = 0 ; i < message.tool_calls.length ; i++ ) { + const tool_call = message.tool_calls[i]; + message.content.push({ + type: 'tool_use', + id: tool_call.id, + name: tool_call.function.name, + input: tool_call.function.arguments, + }); + } + delete message.tool_calls; + } else { + throw new Error('each message must have a \'content\' property'); + } + } + if ( whatis(message.content) !== 'array' ) { + message.content = [message.content]; + } + // Coerce each content block into an object + for ( let i = 0 ; i < message.content.length ; i++ ) { + if ( whatis(message.content[i]) === 'string' ) { + message.content[i] = { + type: 'text', + text: message.content[i], + }; + } + if ( whatis(message.content[i]) !== 'object' ) { + throw new Error('each message content item must be a string or object'); + } + if ( typeof message.content[i].text === 'string' && !message.content[i].type ) { + message.content[i].type = 'text'; + } + } + + // Remove "text" properties from content blocks with type=tool_result + for ( let i = 0 ; i < message.content.length ; i++ ) { + if ( message.content[i].type !== 'tool_use' ) { + continue; + } + if ( Object.prototype.hasOwnProperty.call(message.content[i], 'text') ) { + delete message.content[i].text; + } + } + + return message; +}; + +/** + * Normalizes an array of messages by applying normalize_single_message to each, + * then splits messages with multiple content blocks into separate messages, + * and finally merges consecutive messages from the same role. + * + * @param {Array} messages - Array of messages to normalize + * @param {Object} params - Optional parameters passed to normalize_single_message + * @returns {Array} Normalized and merged array of messages + */ +export const normalize_messages = (messages, params = {}) => { + for ( let i = 0 ; i < messages.length ; i++ ) { + messages[i] = normalize_single_message(messages[i], params); + } + + // Split messages with tool_use content into separate messages + // TODO: unit test this + messages = [...messages]; + for ( let i = 0 ; i < messages.length ; i++ ) { + let message = messages[i]; + let separated_messages = []; + for ( let j = 0 ; j < message.content.length ; j++ ) { + if ( message.content[j].type === 'tool_result' ) { + separated_messages.push({ + ...message, + content: [message.content[j]], + }); + } else { + separated_messages.push({ + ...message, + content: [message.content[j]], + }); + } + } + messages.splice(i, 1, ...separated_messages); + } + + // If multiple messages are from the same role, merge them + let merged_messages = []; + let current_role = null; + for ( let i = 0 ; i < messages.length ; i++ ) { + if ( current_role === messages[i].role ) { + merged_messages[merged_messages.length - 1].content.push(...messages[i].content); + } else { + merged_messages.push(messages[i]); + current_role = messages[i].role; + } + } + + return merged_messages; +}; + +/** + * Separates system messages from other messages in the array. + * + * @param {Array} messages - Array of messages to process + * @returns {Array} Tuple containing [system_messages, non_system_messages] + */ +export const extract_and_remove_system_messages = (messages) => { + let system_messages = []; + let new_messages = []; + for ( let i = 0 ; i < messages.length ; i++ ) { + if ( messages[i].role === 'system' ) { + system_messages.push(messages[i]); + } else { + new_messages.push(messages[i]); + } + } + return [system_messages, new_messages]; +}; + +/** + * Extracts all text content from messages, handling various message formats. + * Processes strings, objects with content arrays, and nested content structures, + * joining all text with spaces. + * + * @param {Array} messages - Array of messages to extract text from + * @returns {string} Concatenated text content from all messages + * @throws {Error} If text content is not a string + */ +export const extract_text = (messages) => { + return messages.map(m => { + if ( whatis(m) === 'string' ) { + return m; + } + if ( whatis(m) !== 'object' ) { + return ''; + } + if ( whatis(m.content) === 'array' ) { + return m.content.map(c => c.text).join(' '); + } + if ( whatis(m.content) === 'string' ) { + return m.content; + } else { + const is_text_type = m.content.type === 'text' || + !Object.prototype.hasOwnProperty.call(m.content, 'type'); + if ( is_text_type ) { + if ( whatis(m.content.text) !== 'string' ) { + throw new Error('text content must be a string'); + } + return m.content.text; + } + return ''; + } + }).join(' '); +}; \ No newline at end of file diff --git a/src/backend/src/services/ai/utils/OpenAIUtil.d.ts b/src/backend/src/services/ai/utils/OpenAIUtil.d.ts new file mode 100644 index 00000000..1cd7bad6 --- /dev/null +++ b/src/backend/src/services/ai/utils/OpenAIUtil.d.ts @@ -0,0 +1,116 @@ +import type { + ChatCompletion, + ChatCompletionChunk, + ChatCompletionContentPart, + ChatCompletionMessageParam, + ChatCompletionMessageToolCall, +} from 'openai/resources/chat/completions'; +import type { CompletionUsage } from 'openai/resources/completions'; +import { IChatModel, IChatProvider } from '../chat/providers/types'; + +export interface ToolUseContent { + type: 'tool_use'; + id: string; + name: string; + input: unknown; + extra_content?: unknown; +} + +export interface ToolResultContent { + type: 'tool_result'; + tool_use_id: string; + content: unknown; +} + +export type NormalizedContent = + | ChatCompletionContentPart + | ToolUseContent + | ToolResultContent + | ({ type?: 'image_url'; image_url: unknown; [key: string]: unknown }); + +export interface NormalizedMessage extends Partial { + role?: ChatCompletionMessageParam['role'] | string; + content?: NormalizedContent[] | null; + tool_calls?: ChatCompletionMessageToolCall[]; + tool_call_id?: string; + [key: string]: unknown; +} + +export type UsageCalculator = (args: { usage: CompletionUsage }) => Record; + +export interface ChatStream { + message(): { + contentBlock: (params: { type: 'text' } | { type: 'tool_use'; id: string; name: string; extra_content?: unknown }) => { + addText?(text: string): void; + addReasoning?(reasoning: string): void; + addExtraContent?(extra_content: unknown): void; + addPartialJSON?(partial_json: string): void; + end(): void; + }; + end(): void; + }; + end(): void; +} + +export type StreamingToolCall = ChatCompletionChunk.Choice.Delta.ToolCall & { extra_content?: unknown }; + +export type CompletionChunk = Omit & { + choices: Array< + Omit & { + delta: ChatCompletionChunk['choices'][number]['delta'] & { + reasoning_content?: string | null; + reasoning?: string | null; + extra_content?: unknown; + tool_calls?: StreamingToolCall[]; + }; + } + >; + usage?: CompletionUsage | null; +}; + +export interface StreamDeviations { + index_usage_from_stream_chunk?: (chunk: CompletionChunk) => Partial | null | undefined; + chunk_but_like_actually?: (chunk: CompletionChunk) => Partial; + index_tool_calls_from_stream_choice?: (choice: CompletionChunk['choices'][number]) => StreamingToolCall[] | undefined; +} + +export interface CompletionDeviations { + coerce_completion_usage?: (completion: TCompletion) => Partial; + chunk_but_like_actually?: (chunk: CompletionChunk) => Partial; + index_tool_calls_from_stream_choice?: (choice: CompletionChunk['choices'][number]) => StreamingToolCall[] | undefined; + index_usage_from_stream_chunk?: (chunk: CompletionChunk) => Partial | null | undefined; + +} + +export function process_input_messages (messages: TMessage[]): Promise; + +export function create_usage_calculator (params: { model_details: IChatModel }): UsageCalculator; + +export function extractMeteredUsage (usage: { + prompt_tokens?: number | null; + completion_tokens?: number | null; + prompt_tokens_details?: { cached_tokens?: number | null } | null; +}): { + prompt_tokens: number; + completion_tokens: number; + cached_tokens: number; +}; + +export function create_chat_stream_handler (params: { + deviations?: StreamDeviations; + completion: AsyncIterable; + usage_calculator?: UsageCalculator; +}): (args: { chatStream: ChatStream }) => Promise; + +type CompletionChoice = TCompletion extends { choices: Array } + ? Choice + : ChatCompletion['choices'][number]; + +export function handle_completion_output (params: { + deviations?: CompletionDeviations; + stream?: boolean; + completion: AsyncIterable | TCompletion; + moderate?: (text: string) => Promise<{ flagged: boolean }>; + usage_calculator?: UsageCalculator; + finally_fn?: () => Promise; +}): ReturnType; diff --git a/src/backend/src/modules/puterai/lib/OpenAIUtil.js b/src/backend/src/services/ai/utils/OpenAIUtil.js similarity index 89% rename from src/backend/src/modules/puterai/lib/OpenAIUtil.js rename to src/backend/src/services/ai/utils/OpenAIUtil.js index 24942ff4..96772355 100644 --- a/src/backend/src/modules/puterai/lib/OpenAIUtil.js +++ b/src/backend/src/services/ai/utils/OpenAIUtil.js @@ -5,7 +5,7 @@ * @param {Array} messages - array of normalized messages * @returns {Array} - array of messages in OpenAI format */ -const process_input_messages = async (messages) => { +export const process_input_messages = async (messages) => { for ( const msg of messages ) { if ( ! msg.content ) continue; if ( typeof msg.content !== 'object' ) continue; @@ -35,7 +35,7 @@ const process_input_messages = async (messages) => { name: content_block.name, arguments: JSON.stringify(content_block.input), }, - ...(content_block.extra_content?{extra_content: content_block.extra_content}:{}) + ...(content_block.extra_content ? { extra_content: content_block.extra_content } : {}), }); content.splice(i, 1); } @@ -57,7 +57,7 @@ const process_input_messages = async (messages) => { return messages; }; -const create_usage_calculator = ({ model_details }) => { +export const create_usage_calculator = ({ model_details }) => { return ({ usage }) => { const tokens = []; @@ -79,7 +79,7 @@ const create_usage_calculator = ({ model_details }) => { }; }; -const extractMeteredUsage = (usage) => { +export const extractMeteredUsage = (usage) => { return { prompt_tokens: usage.prompt_tokens ?? 0, completion_tokens: usage.completion_tokens ?? 0, @@ -87,7 +87,7 @@ const extractMeteredUsage = (usage) => { }; }; -const create_chat_stream_handler = ({ +export const create_chat_stream_handler = ({ deviations, completion, usage_calculator, @@ -132,9 +132,9 @@ const create_chat_stream_handler = ({ continue; } - if (choice.delta.extra_content) { + if ( choice.delta.extra_content ) { // Gemini specific thing for metadata, we will basically be appending onto the current message by abusing .addText a little - // Apps have to choose to handle extra_content themselves, it doesn't seem like theres a way we can do it in a backwards + // Apps have to choose to handle extra_content themselves, it doesn't seem like theres a way we can do it in a backwards // compatible fashion since most streaming apps will handle chat history by continuously updating content themselves // This doesn't present us a chance to add in an extra object for gemini's chat continuing features textblock.addExtraContent(choice.delta.extra_content); @@ -152,7 +152,7 @@ const create_chat_stream_handler = ({ type: 'tool_use', id: tool_call.id, name: tool_call.function.name, - ...(tool_call.extra_content ? {extra_content: tool_call.extra_content}: {}) + ...(tool_call.extra_content ? { extra_content: tool_call.extra_content } : {}), }); tool_call_blocks[tool_call.index] = toolblock; } else { @@ -164,12 +164,13 @@ const create_chat_stream_handler = ({ } // TODO DS: this is a bit too abstracted... this is basically just doing the metering now - usage_calculator({ usage: last_usage }); + const usage = usage_calculator({ usage: last_usage }); if ( mode === 'text' ) textblock.end(); if ( mode === 'tool' ) toolblock.end(); + message.end(); - chatStream.end(); + chatStream.end(usage); }; /** @@ -178,7 +179,7 @@ const create_chat_stream_handler = ({ * @param {(args: {usage: import("openai/resources/completions.mjs").CompletionUsage})=> unknown } params.usage_calculator * @returns */ -const handle_completion_output = async ({ +export const handle_completion_output = async ({ deviations, stream, completion, @@ -233,17 +234,5 @@ const handle_completion_output = async ({ input_tokens: completion_usage.prompt_tokens, output_tokens: completion_usage.completion_tokens, }; - // TODO: turn these into toggle logs - // console.log('ORIGINAL COMPLETION', completion); - // console.log('COMPLETION USAGE', completion_usage); - // console.log('RETURN VALUE', ret); return ret; }; - -module.exports = { - process_input_messages, - create_usage_calculator, - create_chat_stream_handler, - handle_completion_output, - extractMeteredUsage, -}; \ No newline at end of file diff --git a/src/backend/src/modules/puterai/lib/Streaming.js b/src/backend/src/services/ai/utils/Streaming.js similarity index 78% rename from src/backend/src/modules/puterai/lib/Streaming.js rename to src/backend/src/services/ai/utils/Streaming.js index b46fe27b..a8e8bfc5 100644 --- a/src/backend/src/modules/puterai/lib/Streaming.js +++ b/src/backend/src/services/ai/utils/Streaming.js @@ -1,4 +1,4 @@ -class AIChatConstructStream { +export class AIChatConstructStream { constructor (chatStream, params) { this.chatStream = chatStream; if ( this._start ) this._start(params); @@ -7,7 +7,7 @@ class AIChatConstructStream { } } -class AIChatTextStream extends AIChatConstructStream { +export class AIChatTextStream extends AIChatConstructStream { addText (text, extra_content) { const json = JSON.stringify({ type: 'text', @@ -33,7 +33,7 @@ class AIChatTextStream extends AIChatConstructStream { } } -class AIChatToolUseStream extends AIChatConstructStream { +export class AIChatToolUseStream extends AIChatConstructStream { _start (params) { this.contentBlock = params; this.buffer = ''; @@ -56,7 +56,7 @@ class AIChatToolUseStream extends AIChatConstructStream { } } -class AIChatMessageStream extends AIChatConstructStream { +export class AIChatMessageStream extends AIChatConstructStream { contentBlock ({ type, ...params }) { if ( type === 'tool_use' ) { return new AIChatToolUseStream(this.chatStream, params); @@ -68,20 +68,28 @@ class AIChatMessageStream extends AIChatConstructStream { } } -class AIChatStream { +export class AIChatStream { + stream; constructor ({ stream }) { this.stream = stream; } - end () { + end (/** @type {Record} */ usage) { + this.stream.write(`${JSON.stringify({ + type: 'usage', + usage, + }) }\n`); this.stream.end(); } message () { return new AIChatMessageStream(this); } + write (...args) { + return this.stream.write(...args); + } } -module.exports = class Streaming { +export default class Streaming { static AIChatStream = AIChatStream; }; diff --git a/src/backend/src/modules/puterai/lib/messages.test.js b/src/backend/src/services/ai/utils/messages.test.js similarity index 98% rename from src/backend/src/modules/puterai/lib/messages.test.js rename to src/backend/src/services/ai/utils/messages.test.js index 0cee56ca..fb16fcb9 100644 --- a/src/backend/src/modules/puterai/lib/messages.test.js +++ b/src/backend/src/services/ai/utils/messages.test.js @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; -const Messages = require('./Messages.js'); -const OpenAIUtil = require('./OpenAIUtil.js'); +import * as Messages from './Messages.js'; +import * as OpenAIUtil from './OpenAIUtil.js'; describe('Messages', () => { describe('normalize_single_message', () => { diff --git a/src/backend/src/modules/puterai/OpenAIVideoGenerationService.js b/src/backend/src/services/ai/video/OpenAIVideoGenerationService.js similarity index 96% rename from src/backend/src/modules/puterai/OpenAIVideoGenerationService.js rename to src/backend/src/services/ai/video/OpenAIVideoGenerationService.js index ee2b135a..94c85ca0 100644 --- a/src/backend/src/modules/puterai/OpenAIVideoGenerationService.js +++ b/src/backend/src/services/ai/video/OpenAIVideoGenerationService.js @@ -18,10 +18,10 @@ */ // METADATA // {"ai-commented":{"service":"claude"}} -const APIError = require('../../api/APIError'); -const BaseService = require('../../services/BaseService'); -const { TypedValue } = require('../../services/drivers/meta/Runtime'); -const { Context } = require('../../util/context'); +const APIError = require('../../../api/APIError'); +const BaseService = require('../../BaseService'); +const { TypedValue } = require('../../drivers/meta/Runtime'); +const { Context } = require('../../../util/context'); const { Readable } = require('stream'); const DEFAULT_TEST_VIDEO_URL = 'https://assets.puter.site/txt2vid.mp4'; @@ -33,7 +33,7 @@ const ALLOWED_SIZES = new Set(['720x1280', '1280x720', '1024x1792', '1792x1024'] const ALLOWED_SECONDS = new Set(['4', '8', '12']); class OpenAIVideoGenerationService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ + /** @type {import('../../MeteringService/MeteringService').MeteringService} */ get meteringService () { return this.services.get('meteringService').meteringService; } diff --git a/src/backend/src/modules/puterai/TogetherVideoGenerationService.js b/src/backend/src/services/ai/video/TogetherVideoGenerationService.js similarity index 96% rename from src/backend/src/modules/puterai/TogetherVideoGenerationService.js rename to src/backend/src/services/ai/video/TogetherVideoGenerationService.js index 0aa26e02..c6d0e4be 100644 --- a/src/backend/src/modules/puterai/TogetherVideoGenerationService.js +++ b/src/backend/src/services/ai/video/TogetherVideoGenerationService.js @@ -18,10 +18,10 @@ */ // METADATA // {"ai-commented":{"service":"claude"}} -const APIError = require('../../api/APIError'); -const BaseService = require('../../services/BaseService'); -const { TypedValue } = require('../../services/drivers/meta/Runtime'); -const { Context } = require('../../util/context'); +const APIError = require('../../../api/APIError'); +const BaseService = require('../../BaseService'); +const { TypedValue } = require('../../drivers/meta/Runtime'); +const { Context } = require('../../../util/context'); const { Together } = require('together-ai'); const DEFAULT_TEST_VIDEO_URL = 'https://assets.puter.site/txt2vid.mp4'; @@ -32,7 +32,7 @@ const DEFAULT_DURATION_SECONDS = 6; const DEFAULT_USAGE_KEY = 'together-video:default'; class TogetherVideoGenerationService extends BaseService { - /** @type {import('../../services/MeteringService/MeteringService').MeteringService} */ + /** @type {import('../../MeteringService/MeteringService').MeteringService} */ get meteringService () { return this.services.get('meteringService').meteringService; } diff --git a/src/backend/src/services/auth/Actor.d.ts b/src/backend/src/services/auth/Actor.d.ts index ec74e7c6..55f6790e 100644 --- a/src/backend/src/services/auth/Actor.d.ts +++ b/src/backend/src/services/auth/Actor.d.ts @@ -1,17 +1,78 @@ import { IUser } from '../User'; +export interface ActorLogFields { + uid: string; + username?: string; +} + export class SystemActorType { + constructor (o?: Record); get uid (): string; get_related_type (type_class: unknown): SystemActorType; } +export class UserActorType { + constructor (params: { user: IUser }); + user: IUser; + get uid (): string; + get_related_type (type_class: unknown): UserActorType; +} + +export class AppUnderUserActorType { + constructor (params: { user: IUser, app: { uid: string } }); + user: IUser; + app: { uid: string }; + get uid (): string; + get_related_type (type_class: unknown): UserActorType | AppUnderUserActorType; +} + +export class AccessTokenActorType { + constructor (params: { authorizer: Actor, authorized?: Actor, token: string }); + authorizer: Actor; + authorized?: Actor; + token: string; + get uid (): string; + get_related_actor (): never; +} + +export class SiteActorType { + constructor (params: { site: { name: string } }); + site: { name: string }; + get uid (): string; +} + +export type ActorType = + | SystemActorType + | UserActorType + | AppUnderUserActorType + | AccessTokenActorType + | SiteActorType; + +export interface ActorInit { + type: ActorType; +} + export class Actor { + constructor (init: ActorInit); type: { app: { uid: string, timestamp?: Date } user: IUser }; get uid (): string; + get private_uid (): string; + toLogFields (): ActorLogFields; clone (): Actor; + get_related_actor (type_class: unknown): Actor; + static create ( + type: new (params?: Record) => ActorType, + params?: { + user_uid?: string; + app_uid?: string; + user?: IUser; + app?: { uid: string }; + [key: string]: unknown; + }, + ): Promise; static get_system_actor (): Actor; - static adapt (actor?: Actor): Actor; -} \ No newline at end of file + static adapt (actor?: Actor | { username?: string, uuid?: string }): Actor; +} diff --git a/src/backend/src/services/auth/Actor.js b/src/backend/src/services/auth/Actor.js index fc4d6642..f86c3fa8 100644 --- a/src/backend/src/services/auth/Actor.js +++ b/src/backend/src/services/auth/Actor.js @@ -17,23 +17,24 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -const { AdvancedBase } = require('../../../../putility'); -const { Context } = require('../../util/context'); -const { get_user, get_app } = require('../../helpers'); -const config = require('../../config'); - +import { AdvancedBase } from '../../../../putility/index.js'; +import { Context } from '../../util/context.js'; +import { get_user, get_app } from '../../helpers.js'; +import * as config from '../../config.js'; +import { v5 as uuidv5 } from 'uuid'; +import crypto from 'crypto'; // TODO: add these to configuration; production deployments should change these! const PRIVATE_UID_NAMESPACE = config.private_uid_namespace - ?? require('crypto').randomUUID(); + ?? crypto.randomUUID(); const PRIVATE_UID_SECRET = config.private_uid_secret - ?? require('crypto').randomBytes(24).toString('hex'); + ?? crypto.randomBytes(24).toString('hex'); /** * Base class for all actor types in the system. * Provides common initialization functionality for actor type instances. */ -class ActorType { +export class ActorType { /** * Initializes the ActorType with the provided properties. * @@ -52,7 +53,7 @@ class ActorType { * represents a system-level entity and provides methods for UID retrieval * and related type management. */ -class SystemActorType extends ActorType { +export class SystemActorType extends ActorType { /** * Gets the unique identifier for the system actor. * @@ -83,15 +84,10 @@ class SystemActorType extends ActorType { * creating new actors, generating unique identifiers, and handling related types * that represent different roles within the context of the application. */ -class Actor extends AdvancedBase { +export class Actor extends AdvancedBase { /** @type {ActorType} */ type; - static MODULES = { - uuidv5: require('uuid').v5, - crypto: require('crypto'), - }; - static system_actor_ = null; /** @@ -182,7 +178,7 @@ class Actor extends AdvancedBase { get private_uid () { // Pass the UUID through SHA-2 first because UUIDv5 // is not cryptographically secure (it uses SHA-1) - const hmac = this.modules.crypto.createHmac('sha256', PRIVATE_UID_SECRET) + const hmac = crypto.createHmac('sha256', PRIVATE_UID_SECRET) .update(this.uid) .digest('hex'); @@ -190,7 +186,7 @@ class Actor extends AdvancedBase { // Note: this effectively does an additional SHA-1 hash, // but this is done only to format the result as a UUID // and not for cryptographic purposes - let str = this.modules.uuidv5(hmac, PRIVATE_UID_NAMESPACE); + let str = uuidv5(hmac, PRIVATE_UID_NAMESPACE); // Uppercase UUID to avoid inference of what uuid library is being used str = (`${str}`).toUpperCase(); @@ -226,7 +222,7 @@ class Actor extends AdvancedBase { * specific to user actors. This class extends the base functionality to uniquely identify * user actors and define how they relate to other types of actors within the system. */ -class UserActorType extends ActorType { +export class UserActorType extends ActorType { /** * Gets the unique identifier for the user actor. * @@ -257,7 +253,7 @@ class UserActorType extends ActorType { * retrieving related actor types. It extends the base actor type functionality * to cater to user-specific needs. */ -class AppUnderUserActorType extends ActorType { +export class AppUnderUserActorType extends ActorType { /** * Gets the unique identifier for the app-under-user actor. * @@ -290,7 +286,7 @@ class AppUnderUserActorType extends ActorType { * An AccessTokenActorType associates an authorizer and an authorized actor * with a string token, facilitating permission checks and identity management. */ -class AccessTokenActorType extends ActorType { +export class AccessTokenActorType extends ActorType { // authorizer: an Actor who authorized the token // authorized: an Actor who is authorized by the token // token: a string @@ -326,7 +322,7 @@ class AccessTokenActorType extends ActorType { * This class is used to manage details related to the site and implement functionalities * pertinent to site-level operations and interactions in the actor framework. */ -class SiteActorType { +export class SiteActorType { /** * Constructor for the SiteActorType class. * Initializes a new instance of SiteActorType with the provided properties. @@ -376,13 +372,4 @@ Actor.adapt = function (actor) { } return actor; -}; - -module.exports = { - Actor, - SystemActorType, - UserActorType, - AppUnderUserActorType, - AccessTokenActorType, - SiteActorType, -}; +}; \ No newline at end of file diff --git a/src/backend/src/services/database/consts.js b/src/backend/src/services/database/consts.js index 235d1529..1a93d25b 100644 --- a/src/backend/src/services/database/consts.js +++ b/src/backend/src/services/database/consts.js @@ -17,23 +17,5 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -module.exports = { - // Douglas Crockford doesn't like Symbol - // https://youtu.be/XFTOG895C7c?t=1469 - // I think for this use case his argument would - // be "just use { label: 'DB_READ' } instead" - // but I've been using object references like - // that for years and it's refreshing not to - // need to assign an arbitrary property name - // to my debugging label. - // This is a pretty long comment for such a small - // file but nothing else is going to go in this - // file so it might as well have a long comment - // in it because if somebody is reading this file - // they're probably looking to find some secret - // undocumented constants and there aren't any - // so this comment will hopefully counter-balance - // the disappointment from that. - DB_READ: Symbol('DB_READ'), - DB_WRITE: Symbol('DB_WRITE'), -}; +export const DB_READ = Symbol('DB_READ'); +export const DB_WRITE = Symbol('DB_WRITE'); diff --git a/src/backend/src/services/drivers/DriverService.js b/src/backend/src/services/drivers/DriverService.js index 7f7adeba..7d5371d2 100644 --- a/src/backend/src/services/drivers/DriverService.js +++ b/src/backend/src/services/drivers/DriverService.js @@ -253,7 +253,6 @@ class DriverService extends BaseService { return await this._call(o); } catch ( e ) { this.log.error(`Driver error response: ${ e.toString()}`); - console.error(e); if ( ! (e instanceof APIError) ) { this.errors.report('driver', { source: e, diff --git a/src/backend/src/services/repositories/DBKVStore/DBKVStore.test.ts b/src/backend/src/services/repositories/DBKVStore/DBKVStore.test.ts index cd3a6489..647c3428 100644 --- a/src/backend/src/services/repositories/DBKVStore/DBKVStore.test.ts +++ b/src/backend/src/services/repositories/DBKVStore/DBKVStore.test.ts @@ -3,6 +3,7 @@ import { createTestKernel } from '../../../../tools/test.mjs'; import * as config from '../../../config'; import { Actor } from '../../auth/Actor'; import { DBKVServiceWrapper } from './index.mjs'; +import { SUService } from '../../SUService'; describe('DBKVStore', async () => { @@ -27,7 +28,7 @@ describe('DBKVStore', async () => { const kvServiceWrapper = testKernel.services!.get('puter-kvstore') as DBKVServiceWrapper; const kvStore = kvServiceWrapper.kvStore; - const su = testKernel.services!.get('su'); + const su = testKernel.services!.get('su') as SUService; const makeActor = (userId: number | string, appUid?: string) => ({ type: { diff --git a/src/backend/src/services/repositories/DBKVStore/DBKVStore.ts b/src/backend/src/services/repositories/DBKVStore/DBKVStore.ts index 3f05bdaa..b8a52b34 100644 --- a/src/backend/src/services/repositories/DBKVStore/DBKVStore.ts +++ b/src/backend/src/services/repositories/DBKVStore/DBKVStore.ts @@ -151,7 +151,7 @@ export class DBKVStore implements IDBKVStore { key_hash, key, JSON.stringify(value), - expireAt ?? null, + expireAt ?? undefined, ...this.#db.case({ mysql: [value], otherwise: [] }), ]); } catch ( e: unknown ) { @@ -213,7 +213,7 @@ export class DBKVStore implements IDBKVStore { as = as || 'entries'; if ( ! ['keys', 'values', 'entries'].includes(as) ) { - throw APIError.create('field_invalid', null, { + throw APIError.create('field_invalid', undefined, { key: 'as', expected: '"keys", "values", or "entries"', }); @@ -250,7 +250,7 @@ export class DBKVStore implements IDBKVStore { async expireAt ({ key, timestamp }: { key: string, timestamp: number }) { if ( key === '' ) { - throw APIError.create('field_empty', null, { + throw APIError.create('field_empty', undefined, { key: 'key', }); } @@ -262,7 +262,7 @@ export class DBKVStore implements IDBKVStore { async expire ({ key, ttl }: { key: string, ttl: number }) { if ( key === '' ) { - throw APIError.create('field_empty', null, { + throw APIError.create('field_empty', undefined, { key: 'key', }); } @@ -351,7 +351,7 @@ export class DBKVStore implements IDBKVStore { app?.uid ?? GLOBAL_APP_KEY, key_hash, key, - null, // empty value + undefined, // empty value timestamp, ...this.#db.case({ mysql: [timestamp], otherwise: [] }), ]); diff --git a/src/backend/src/util/context.js b/src/backend/src/util/context.js index 67153fd1..6c3d27aa 100644 --- a/src/backend/src/util/context.js +++ b/src/backend/src/util/context.js @@ -16,10 +16,15 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -const { AsyncLocalStorage } = require('async_hooks'); -const context_config = {}; +import { AsyncLocalStorage } from 'async_hooks'; +import { randomUUID } from 'crypto'; +import { v4 as uuidv4 } from 'uuid'; + +export const context_config = {}; + +export class Context { + static testId = randomUUID(); -class Context { static USE_NAME_FALLBACK = {}; static next_name_ = 0; static other_next_names_ = {}; @@ -224,9 +229,7 @@ class Context { } } -const uuidv4 = require('uuid').v4; - -class ContextExpressMiddleware { +export class ContextExpressMiddleware { constructor ({ parent }) { this.parent_ = parent; } @@ -245,10 +248,4 @@ class ContextExpressMiddleware { next(); }); } -} - -module.exports = { - Context, - ContextExpressMiddleware, - context_config, -}; +} \ No newline at end of file diff --git a/src/backend/src/util/kvSingleton.js b/src/backend/src/util/kvSingleton.js new file mode 100644 index 00000000..ae9eb5b2 --- /dev/null +++ b/src/backend/src/util/kvSingleton.js @@ -0,0 +1,3 @@ +import kvjs from '@heyputer/kv.js'; + +export const kv = new kvjs(); \ No newline at end of file diff --git a/src/backend/tools/test.mjs b/src/backend/tools/test.mjs index 2e9802d4..a8ffd5d6 100644 --- a/src/backend/tools/test.mjs +++ b/src/backend/tools/test.mjs @@ -132,15 +132,20 @@ export class TestKernel extends AdvancedBase { const mod_install_root_context = Context.get(); for ( const module of this.modules ) { - const mod_context = this._create_mod_context(mod_install_root_context, - { - name: module.constructor.name, - ['module']: module, - external: false, - }); - await this.root_context.arun(async () => { - await module.install(mod_context); - }); + try { + const mod_context = this._create_mod_context(mod_install_root_context, + { + name: module.constructor.name, + ['module']: module, + external: false, + }); + await this.root_context.arun(async () => { + await module.install(mod_context); + }); + } catch (e) { + console.log(e); + throw e; + } } // Real kernel initializes services here, but in this test kernel @@ -282,6 +287,7 @@ export const createTestKernel = async ({ testCore = false, serviceConfigOverrideMap = {}, globalConfigOverrideMap = {}, + serviceMapArgs = {}, }) => { const initLevelMap = { CONSTRUCT: 1, INIT: 2 }; @@ -293,7 +299,7 @@ export const createTestKernel = async ({ testKernel.add_module({ install: context => { const services = context.get('services'); - services.registerService(name, service); + services.registerService(name, service, serviceMapArgs[name] || undefined); }, }); } diff --git a/src/backend/vitest.config.ts b/src/backend/vitest.config.ts index 2bd6734f..0a2b2931 100644 --- a/src/backend/vitest.config.ts +++ b/src/backend/vitest.config.ts @@ -9,7 +9,7 @@ export default defineConfig(({ mode }) => ({ coverage: { provider: 'v8', reporter: ['text', 'json', 'json-summary', 'html', 'lcov'], - include: ['src/**/*.{js,mjs,ts}'], + include: ['src/**/*.{js,mjs,ts,mts}'], exclude: [ 'src/**/types/**', 'src/**/constants/**', diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 00000000..a133b43e --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "moduleResolution": "bundler", + "rootDir": "./src/backend", + "strict": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "sourceMap": true, + "removeComments": true, + "noEmitOnError": true, + "noImplicitAny": false + } +} \ No newline at end of file diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 00000000..df1db7fd --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,23 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "allowJs": false, + "checkJs": false, + "noEmit": false + }, + "include": ["./src/backend"], + "exclude": [ + "**/*.test.ts", + "**/*.test.mts", + "**/vitest.config.ts", + "**/vitest.config.mts", + "**/*.spec.ts", + "**/*.spec.mts", + "**/tests/**", + "node_modules", + "dist", + "volatile", + "extensions", + "src/backend/src/services/worker/template/puter-portable.js" + ] +} diff --git a/tsconfig.json b/tsconfig.json index 429d670d..a0b76604 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,11 @@ { + "extends": "./tsconfig.base.json", "compilerOptions": { - "target": "ES2024", - "module": "node16", - "moduleResolution": "node16", - "rootDir": ".", - "strict": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "skipLibCheck": true, - "sourceMap": true, - "removeComments": true, - "noEmitOnError": true, + "allowJs": true, + "checkJs": false, + "noEmit": true }, + "include": ["./src/backend"], "exclude": [ "**/*.test.ts", "**/*.test.mts", @@ -23,6 +17,7 @@ "node_modules", "dist", "volatile", - "extensions" + "extensions", + "src/backend/src/services/worker/template/puter-portable.js" ] -} \ No newline at end of file +} diff --git a/ws-debug.mjs b/ws-debug.mjs new file mode 100644 index 00000000..c530a81c --- /dev/null +++ b/ws-debug.mjs @@ -0,0 +1,53 @@ +import { createTestKernel } from './src/backend/tools/test.mjs'; +import { WorkerService } from '@heyputer/backend/src/services/worker/WorkerService.js'; +import { EntityStoreService } from './src/backend/src/services/EntityStoreService.js'; +import { AppLimitedES } from './src/backend/src/om/entitystorage/AppLimitedES.js'; +import { ESBuilder } from './src/backend/src/om/entitystorage/ESBuilder.js'; +import MaxLimitES from './src/backend/src/om/entitystorage/MaxLimitES.js'; +import SQLES from './src/backend/src/om/entitystorage/SQLES.js'; +import { SetOwnerES } from './src/backend/src/om/entitystorage/SetOwnerES.js'; +import SubdomainES from './src/backend/src/om/entitystorage/SubdomainES.js'; +import ValidationES from './src/backend/src/om/entitystorage/ValidationES.js'; +import WriteByOwnerOnlyES from './src/backend/src/om/entitystorage/WriteByOwnerOnlyES.js'; +import { Actor, UserActorType } from './src/backend/src/services/auth/Actor.js'; + +trying(); + +async function trying() { + const tk = await createTestKernel({ + serviceMap: { worker: WorkerService, 'es:subdomain': EntityStoreService }, + serviceMapArgs: { + 'es:subdomain': { + entity: 'subdomain', + upstream: ESBuilder.create([ + SQLES, + { table: 'subdomains', debug: true }, + SubdomainES, + AppLimitedES, + WriteByOwnerOnlyES, + ValidationES, + SetOwnerES, + MaxLimitES, { max: 5000 }, + ]), + }, + }, + serviceConfigOverrideMap: { + worker: { loggingUrl: 'x' }, + database: { path: ':memory:' }, + }, + initLevelString: 'init', + testCore: true, + globalConfigOverrideMap: { + worker: { reserved_words: [] }, + }, + }); + + const su = tk.services.get('su'); + const ws = tk.services.get('worker'); + const actor = new Actor({ type: new UserActorType({ user: { id: 1, uuid: 'u1', username: 'test' } }) }); + + globalThis.services = tk.services; + + const res = await tk.root_context.arun(() => su.sudo(actor, () => ws.create({ filePath: '/worker.js', workerName: 'MyWorker', authorization: 'auth' }))); + console.log('result', res); +}