diff --git a/.eslintignore b/.eslintignore index acd0aa3..095c412 100644 --- a/.eslintignore +++ b/.eslintignore @@ -45,6 +45,8 @@ version-bump.mjs versions.json package.json manifest.json +compile-migration.js +import-meta-url-shim.js # Obsidian .obsidian \ No newline at end of file diff --git a/.gitignore b/.gitignore index e09a007..61ccc0f 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,4 @@ main.js data.json # Exclude macOS Finder (System Explorer) View States -.DS_Store +.DS_Store \ No newline at end of file diff --git a/__mocks__/obsidian.ts b/__mocks__/obsidian.ts new file mode 100644 index 0000000..adedbe3 --- /dev/null +++ b/__mocks__/obsidian.ts @@ -0,0 +1,6 @@ +export const App = jest.fn() +export const Editor = jest.fn() +export const MarkdownView = jest.fn() +export const TFile = jest.fn() +export const TFolder = jest.fn() +export const Vault = jest.fn() diff --git a/compile-migration.js b/compile-migration.js new file mode 100644 index 0000000..241124d --- /dev/null +++ b/compile-migration.js @@ -0,0 +1,12 @@ +const { readMigrationFiles } = require('drizzle-orm/migrator') +const fs = require('node:fs/promises') + +async function compileMigrations() { + const migrations = readMigrationFiles({ migrationsFolder: './drizzle/' }) + + await fs.writeFile('./src/db/migrations.json', JSON.stringify(migrations)) + + console.log('Migrations compiled!') +} + +compileMigrations().catch(console.error) diff --git a/drizzle.config.ts b/drizzle.config.ts new file mode 100644 index 0000000..7cf0a6d --- /dev/null +++ b/drizzle.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from 'drizzle-kit' + +export default defineConfig({ + dialect: 'postgresql', + schema: './src/db/schema.ts', +}) diff --git a/drizzle/0000_add_vector_extension.sql b/drizzle/0000_add_vector_extension.sql new file mode 100644 index 0000000..d79fc23 --- /dev/null +++ b/drizzle/0000_add_vector_extension.sql @@ -0,0 +1,2 @@ +-- Custom SQL migration file, put you code below! -- +CREATE EXTENSION IF NOT EXISTS vector; \ No newline at end of file diff --git a/drizzle/0001_create_vector_data_tables.sql b/drizzle/0001_create_vector_data_tables.sql new file mode 100644 index 0000000..3791792 --- /dev/null +++ b/drizzle/0001_create_vector_data_tables.sql @@ -0,0 +1,19 @@ +CREATE TABLE IF NOT EXISTS "vector_data_text_embedding_3_small" ( + "id" serial PRIMARY KEY NOT NULL, + "path" text NOT NULL, + "mtime" bigint NOT NULL, + "content" text NOT NULL, + "embedding" vector(1536), + "metadata" jsonb NOT NULL +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "vector_data_text_embedding_3_large" ( + "id" serial PRIMARY KEY NOT NULL, + "path" text NOT NULL, + "mtime" bigint NOT NULL, + "content" text NOT NULL, + "embedding" vector(3072), + "metadata" jsonb NOT NULL +); +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS "embeddingIndex_text_embedding_3_small" ON "vector_data_text_embedding_3_small" USING hnsw ("embedding" vector_cosine_ops); \ No newline at end of file diff --git a/drizzle/meta/0000_snapshot.json b/drizzle/meta/0000_snapshot.json new file mode 100644 index 0000000..f918eab --- /dev/null +++ b/drizzle/meta/0000_snapshot.json @@ -0,0 +1,16 @@ +{ + "id": "8344dba7-b655-4009-9c56-894062c17ea6", + "prevId": "00000000-0000-0000-0000-000000000000", + "version": "7", + "dialect": "postgresql", + "tables": {}, + "enums": {}, + "schemas": {}, + "views": {}, + "sequences": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/drizzle/meta/0001_snapshot.json b/drizzle/meta/0001_snapshot.json new file mode 100644 index 0000000..51305b8 --- /dev/null +++ b/drizzle/meta/0001_snapshot.json @@ -0,0 +1,128 @@ +{ + "id": "1084161a-8de5-4452-ba8b-6ffc3549d411", + "prevId": "8344dba7-b655-4009-9c56-894062c17ea6", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.vector_data_text_embedding_3_small": { + "name": "vector_data_text_embedding_3_small", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mtime": { + "name": "mtime", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "embedding": { + "name": "embedding", + "type": "vector(1536)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "embeddingIndex_text_embedding_3_small": { + "name": "embeddingIndex_text_embedding_3_small", + "columns": [ + { + "expression": "embedding", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "vector_cosine_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "hnsw", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "public.vector_data_text_embedding_3_large": { + "name": "vector_data_text_embedding_3_large", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mtime": { + "name": "mtime", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "embedding": { + "name": "embedding", + "type": "vector(3072)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json new file mode 100644 index 0000000..e3bd512 --- /dev/null +++ b/drizzle/meta/_journal.json @@ -0,0 +1,20 @@ +{ + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1729509950412, + "tag": "0000_add_vector_extension", + "breakpoints": true + }, + { + "idx": 1, + "version": "7", + "when": 1729509994653, + "tag": "0001_create_vector_data_tables", + "breakpoints": true + } + ] +} diff --git a/esbuild.config.mjs b/esbuild.config.mjs index adb1d92..8f61b23 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -1,3 +1,4 @@ +import path from 'path' import esbuild from 'esbuild' import process from 'process' import builtins from 'builtin-modules' @@ -14,7 +15,7 @@ const context = await esbuild.context({ banner: { js: banner, }, - entryPoints: ['src/main.ts'], // Change this line + entryPoints: ['src/main.ts'], bundle: true, external: [ 'obsidian', @@ -33,12 +34,19 @@ const context = await esbuild.context({ ...builtins, ], format: 'cjs', - target: 'es2018', + define: { + 'import.meta.url': 'import_meta_url', + process: '{}', + 'process.env.NODE_ENV': JSON.stringify(prod ? 'production' : 'development'), + }, + inject: [path.resolve('import-meta-url-shim.js')], + target: 'es2020', logLevel: 'info', sourcemap: prod ? false : 'inline', treeShaking: true, - outfile: 'main.js', // Changed back to main.js + outfile: 'main.js', minify: prod, + // logLevel: 'debug', }) if (prod) { diff --git a/import-meta-url-shim.js b/import-meta-url-shim.js new file mode 100644 index 0000000..7877b62 --- /dev/null +++ b/import-meta-url-shim.js @@ -0,0 +1,7 @@ +const import_meta_url = + typeof document === 'undefined' + ? require('url').pathToFileURL(__filename).href + : (document.currentScript && document.currentScript.src) || + new URL('main.js', document.baseURI).href + +export { import_meta_url } diff --git a/package-lock.json b/package-lock.json index 2b929ae..17e23fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,33 +1,41 @@ { "name": "obsidian-smart-composer", - "version": "0.1.1", + "version": "0.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "obsidian-smart-composer", - "version": "0.1.1", + "version": "0.1.2", "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "^0.27.3", + "@electric-sql/pglite": "^0.2.12", "@lexical/react": "^0.17.1", "@radix-ui/react-dropdown-menu": "^2.1.2", + "@radix-ui/react-tooltip": "^1.1.3", "@tanstack/react-query": "^5.56.2", "diff": "^7.0.0", + "drizzle-orm": "^0.35.2", + "exponential-backoff": "^3.1.1", "fuzzysort": "^3.1.0", "groq-sdk": "^0.7.0", + "js-tiktoken": "^1.0.15", + "langchain": "^0.3.2", "lexical": "^0.17.1", "lodash.debounce": "^4.0.8", "lodash.isequal": "^4.5.0", "lucide-react": "^0.447.0", "openai": "^4.65.0", + "p-limit": "^6.1.0", "parse5": "^7.1.2", "react": "^18.3.1", "react-dom": "^18.3.1", "react-markdown": "^9.0.1", "react-syntax-highlighter": "^15.5.0", "remark-gfm": "^4.0.0", - "uuid": "^10.0.0" + "uuid": "^10.0.0", + "zod": "^3.23.8" }, "devDependencies": { "@types/diff": "^5.2.3", @@ -42,6 +50,7 @@ "@typescript-eslint/eslint-plugin": "5.29.0", "@typescript-eslint/parser": "5.29.0", "builtin-modules": "3.3.0", + "drizzle-kit": "^0.26.2", "esbuild": "0.17.3", "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", @@ -658,13 +667,36 @@ "w3c-keyname": "^2.2.4" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.3", + "node_modules/@drizzle-team/brocli": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@drizzle-team/brocli/-/brocli-0.10.1.tgz", + "integrity": "sha512-AHy0vjc+n/4w/8Mif+w86qpppHuF3AyXbcWW+R/W7GNA3F5/p2nuhlkCJaTXSLZheB4l1rtHzOfr9A7NwoR/Zg==", + "dev": true + }, + "node_modules/@electric-sql/pglite": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@electric-sql/pglite/-/pglite-0.2.12.tgz", + "integrity": "sha512-J/X42ujcoFEbOkgRyoNqZB5qcqrnJRWVlwpH3fKYoJkTz49N91uAK/rDSSG/85WRas9nC9mdV4FnMTxnQWE/rw==" + }, + "node_modules/@esbuild-kit/core-utils": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz", + "integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==", + "deprecated": "Merged into tsx: https://tsx.is", + "dev": true, + "dependencies": { + "esbuild": "~0.18.20", + "source-map-support": "^0.5.21" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -673,781 +705,1411 @@ "node": ">=12" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", + "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=12" }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/@esbuild-kit/core-utils/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==", "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", + "node_modules/@esbuild-kit/esm-loader": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz", + "integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==", + "deprecated": "Merged into tsx: https://tsx.is", "dev": true, - "license": "MIT", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "@esbuild-kit/core-utils": "^3.3.2", + "get-tsconfig": "^4.7.0" } }, - "node_modules/@eslint/js": { - "version": "8.57.1", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@floating-ui/core": { - "version": "1.6.8", - "license": "MIT", - "dependencies": { - "@floating-ui/utils": "^0.2.8" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.6.11", - "license": "MIT", - "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.8" - } - }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.2", - "license": "MIT", - "dependencies": { - "@floating-ui/dom": "^1.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "node": ">=12" } }, - "node_modules/@floating-ui/utils": { - "version": "0.2.8", - "license": "MIT" - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=10.10.0" + "node": ">=12" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=12" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.3", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@jest/console": { - "version": "29.7.0", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/core": { - "version": "29.7.0", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "node": ">=12" } }, - "node_modules/@jest/environment": { - "version": "29.7.0", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/expect": { - "version": "29.7.0", + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/globals": { - "version": "29.7.0", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/reporters": { - "version": "29.7.0", + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "node": ">=12" } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/source-map": { - "version": "29.6.3", + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/@jest/test-result": { - "version": "29.7.0", + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@jest/test-sequencer": { - "version": "29.7.0", + "node_modules/@eslint-community/regexpp": { + "version": "4.11.1", "dev": true, "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@jest/transform": { - "version": "29.7.0", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@jest/types": { - "version": "29.6.3", + "node_modules/@eslint/js": { + "version": "8.57.1", "dev": true, "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "dev": true, + "node_modules/@floating-ui/core": { + "version": "1.6.8", "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" + "@floating-ui/utils": "^0.2.8" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "dev": true, + "node_modules/@floating-ui/dom": { + "version": "1.6.11", "license": "MIT", - "engines": { - "node": ">=6.0.0" + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.8" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "dev": true, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", "license": "MIT", - "engines": { - "node": ">=6.0.0" + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "dev": true, + "node_modules/@floating-ui/utils": { + "version": "0.2.8", "license": "MIT" }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" } }, - "node_modules/@lexical/clipboard": { - "version": "0.17.1", - "license": "MIT", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "dev": true, + "license": "ISC", "dependencies": { - "@lexical/html": "0.17.1", - "@lexical/list": "0.17.1", - "@lexical/selection": "0.17.1", - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@lexical/code": { - "version": "0.17.1", + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/utils": "0.17.1", - "lexical": "0.17.1", - "prismjs": "^1.27.0" + "sprintf-js": "~1.0.2" } }, - "node_modules/@lexical/devtools-core": { - "version": "0.17.1", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/html": "0.17.1", - "@lexical/link": "0.17.1", - "@lexical/mark": "0.17.1", - "@lexical/table": "0.17.1", - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, - "peerDependencies": { - "react": ">=17.x", - "react-dom": ">=17.x" + "engines": { + "node": ">=8" } }, - "node_modules/@lexical/dragon": { - "version": "0.17.1", + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "dev": true, "license": "MIT", "dependencies": { - "lexical": "0.17.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@lexical/hashtag": { - "version": "0.17.1", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@lexical/history": { - "version": "0.17.1", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@lexical/html": { - "version": "0.17.1", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/selection": "0.17.1", - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@lexical/link": { - "version": "0.17.1", + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, "license": "MIT", - "dependencies": { - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" + "engines": { + "node": ">=8" } }, - "node_modules/@lexical/list": { - "version": "0.17.1", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, "license": "MIT", - "dependencies": { - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" + "engines": { + "node": ">=8" } }, - "node_modules/@lexical/mark": { - "version": "0.17.1", + "node_modules/@jest/console": { + "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@lexical/markdown": { - "version": "0.17.1", + "node_modules/@jest/core": { + "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/code": "0.17.1", - "@lexical/link": "0.17.1", - "@lexical/list": "0.17.1", - "@lexical/rich-text": "0.17.1", - "@lexical/text": "0.17.1", - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" - } - }, - "node_modules/@lexical/offset": { - "version": "0.17.1", - "license": "MIT", - "dependencies": { - "lexical": "0.17.1" - } - }, - "node_modules/@lexical/overflow": { - "version": "0.17.1", - "license": "MIT", - "dependencies": { - "lexical": "0.17.1" - } - }, - "node_modules/@lexical/plain-text": { - "version": "0.17.1", - "license": "MIT", - "dependencies": { - "@lexical/clipboard": "0.17.1", - "@lexical/selection": "0.17.1", - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@lexical/react": { - "version": "0.17.1", + "node_modules/@jest/environment": { + "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/clipboard": "0.17.1", - "@lexical/code": "0.17.1", - "@lexical/devtools-core": "0.17.1", - "@lexical/dragon": "0.17.1", - "@lexical/hashtag": "0.17.1", - "@lexical/history": "0.17.1", - "@lexical/link": "0.17.1", - "@lexical/list": "0.17.1", - "@lexical/mark": "0.17.1", - "@lexical/markdown": "0.17.1", - "@lexical/overflow": "0.17.1", - "@lexical/plain-text": "0.17.1", - "@lexical/rich-text": "0.17.1", - "@lexical/selection": "0.17.1", - "@lexical/table": "0.17.1", - "@lexical/text": "0.17.1", - "@lexical/utils": "0.17.1", - "@lexical/yjs": "0.17.1", - "lexical": "0.17.1", - "react-error-boundary": "^3.1.4" + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" }, - "peerDependencies": { - "react": ">=17.x", - "react-dom": ">=17.x" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@lexical/rich-text": { - "version": "0.17.1", + "node_modules/@jest/expect": { + "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/clipboard": "0.17.1", - "@lexical/selection": "0.17.1", - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@lexical/selection": { - "version": "0.17.1", + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { - "lexical": "0.17.1" + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@lexical/table": { - "version": "0.17.1", + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/utils": "0.17.1", - "lexical": "0.17.1" + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@lexical/text": { - "version": "0.17.1", + "node_modules/@jest/globals": { + "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { - "lexical": "0.17.1" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@lexical/utils": { - "version": "0.17.1", + "node_modules/@jest/reporters": { + "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/list": "0.17.1", - "@lexical/selection": "0.17.1", - "@lexical/table": "0.17.1", - "lexical": "0.17.1" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@lexical/yjs": { - "version": "0.17.1", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { - "@lexical/offset": "0.17.1", - "lexical": "0.17.1" + "@sinclair/typebox": "^0.27.8" }, - "peerDependencies": { - "yjs": ">=13.5.22" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", + "node_modules/@jest/source-map": { + "version": "29.6.3", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", + "node_modules/@jest/test-result": { + "version": "29.7.0", "dev": true, "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@radix-ui/primitive": { - "version": "1.1.0", - "license": "MIT" - }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.1.0", + "node_modules/@jest/transform": { + "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@langchain/core": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.3.11.tgz", + "integrity": "sha512-Mhwf0jkALxeQvEdcxEMD1IiNRhXF8pJqvvAh1LpvBTScTrprNVOYQHR4pujZ6z1SV54u4hULokDWJVVjfEf23w==", + "peer": true, + "dependencies": { + "ansi-styles": "^5.0.0", + "camelcase": "6", + "decamelize": "1.2.0", + "js-tiktoken": "^1.0.12", + "langsmith": "^0.1.65", + "mustache": "^4.2.0", + "p-queue": "^6.6.2", + "p-retry": "4", + "uuid": "^10.0.0", + "zod": "^3.22.4", + "zod-to-json-schema": "^3.22.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@langchain/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@langchain/core/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@langchain/openai": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@langchain/openai/-/openai-0.3.7.tgz", + "integrity": "sha512-3Jhyy2uKkymYu1iVK18sG2ASZVg0EQcmtTuEPVnrrFGYJ0EIPufejm6bE1ebOHZRc50kSxQwRFCAGrMatNtUiQ==", + "dependencies": { + "js-tiktoken": "^1.0.12", + "openai": "^4.67.2", + "zod": "^3.22.4", + "zod-to-json-schema": "^3.22.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/core": ">=0.2.26 <0.4.0" + } + }, + "node_modules/@langchain/textsplitters": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@langchain/textsplitters/-/textsplitters-0.1.0.tgz", + "integrity": "sha512-djI4uw9rlkAb5iMhtLED+xJebDdAG935AdP4eRTB02R7OB/act55Bj9wsskhZsvuyQRpO4O1wQOp85s6T6GWmw==", + "dependencies": { + "js-tiktoken": "^1.0.12" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/core": ">=0.2.21 <0.4.0" + } + }, + "node_modules/@lexical/clipboard": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/html": "0.17.1", + "@lexical/list": "0.17.1", + "@lexical/selection": "0.17.1", + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/code": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/utils": "0.17.1", + "lexical": "0.17.1", + "prismjs": "^1.27.0" + } + }, + "node_modules/@lexical/devtools-core": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/html": "0.17.1", + "@lexical/link": "0.17.1", + "@lexical/mark": "0.17.1", + "@lexical/table": "0.17.1", + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + }, + "peerDependencies": { + "react": ">=17.x", + "react-dom": ">=17.x" + } + }, + "node_modules/@lexical/dragon": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/hashtag": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/history": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/html": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/selection": "0.17.1", + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/link": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/list": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/mark": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/markdown": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/code": "0.17.1", + "@lexical/link": "0.17.1", + "@lexical/list": "0.17.1", + "@lexical/rich-text": "0.17.1", + "@lexical/text": "0.17.1", + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/offset": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/overflow": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/plain-text": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/clipboard": "0.17.1", + "@lexical/selection": "0.17.1", + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/react": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/clipboard": "0.17.1", + "@lexical/code": "0.17.1", + "@lexical/devtools-core": "0.17.1", + "@lexical/dragon": "0.17.1", + "@lexical/hashtag": "0.17.1", + "@lexical/history": "0.17.1", + "@lexical/link": "0.17.1", + "@lexical/list": "0.17.1", + "@lexical/mark": "0.17.1", + "@lexical/markdown": "0.17.1", + "@lexical/overflow": "0.17.1", + "@lexical/plain-text": "0.17.1", + "@lexical/rich-text": "0.17.1", + "@lexical/selection": "0.17.1", + "@lexical/table": "0.17.1", + "@lexical/text": "0.17.1", + "@lexical/utils": "0.17.1", + "@lexical/yjs": "0.17.1", + "lexical": "0.17.1", + "react-error-boundary": "^3.1.4" + }, + "peerDependencies": { + "react": ">=17.x", + "react-dom": ">=17.x" + } + }, + "node_modules/@lexical/rich-text": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/clipboard": "0.17.1", + "@lexical/selection": "0.17.1", + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/selection": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/table": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/utils": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/text": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/utils": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/list": "0.17.1", + "@lexical/selection": "0.17.1", + "@lexical/table": "0.17.1", + "lexical": "0.17.1" + } + }, + "node_modules/@lexical/yjs": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "@lexical/offset": "0.17.1", + "lexical": "0.17.1" + }, + "peerDependencies": { + "yjs": ">=13.5.22" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.2", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-menu": "2.1.2", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, @@ -1460,14 +2122,26 @@ } } }, - "node_modules/@radix-ui/react-collection": { + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.1", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { "version": "1.1.0", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0" + "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -1484,9 +2158,12 @@ } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-context": { + "node_modules/@radix-ui/react-id": { "version": "1.1.0", "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -1497,33 +2174,75 @@ } } }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.0", + "node_modules/@radix-ui/react-menu": { + "version": "2.1.2", "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.1", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.2", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.6.0" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-context": { - "version": "1.1.1", + "node_modules/@radix-ui/react-popper": { + "version": "1.2.0", "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-direction": { + "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-context": { "version": "1.1.0", "license": "MIT", "peerDependencies": { @@ -1536,15 +2255,84 @@ } } }, - "node_modules/@radix-ui/react-dismissable-layer": { + "node_modules/@radix-ui/react-portal": { + "version": "1.1.2", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { "version": "1.1.1", "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.0", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" + "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -1561,17 +2349,52 @@ } } }, - "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.1.2", + "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.1.0", "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.3.tgz", + "integrity": "sha512-Z4w1FIS0BqVFI2c1jZvb/uDVJijJjJ2ZMuPV81oVgTZ7g3BZxobplnMVvXtFWgtozdvYJ+MFWtwkM5S2HnAong==", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.1", "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-menu": "2.1.2", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.2", + "@radix-ui/react-presence": "1.1.1", "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-controllable-state": "1.1.0" + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -1588,8 +2411,53 @@ } } }, - "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.1", + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1601,30 +2469,23 @@ } } }, - "node_modules/@radix-ui/react-focus-scope": { + "node_modules/@radix-ui/react-use-rect": { "version": "1.1.0", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0" + "@radix-ui/rect": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true - }, - "@types/react-dom": { - "optional": true } } }, - "node_modules/@radix-ui/react-id": { + "node_modules/@radix-ui/react-use-size": { "version": "1.1.0", "license": "MIT", "dependencies": { @@ -1640,28 +2501,12 @@ } } }, - "node_modules/@radix-ui/react-menu": { - "version": "2.1.2", - "license": "MIT", + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", + "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.1", - "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-roving-focus": "1.1.0", - "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.6.0" + "@radix-ui/react-primitive": "2.0.0" }, "peerDependencies": { "@types/react": "*", @@ -1678,924 +2523,1261 @@ } } }, - "node_modules/@radix-ui/react-popper": { - "version": "1.2.0", + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.56.2", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.56.2", "license": "MIT", "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-use-rect": "1.1.0", - "@radix-ui/react-use-size": "1.1.0", - "@radix-ui/rect": "1.1.0" + "@tanstack/query-core": "5.56.2" }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "peerDependencies": { + "react": "^18 || ^19" } }, - "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-context": { - "version": "1.1.0", + "node_modules/@types/babel__core": { + "version": "7.20.5", + "dev": true, "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/codemirror": { + "version": "5.60.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/tern": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/diff": { + "version": "5.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.13", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.10", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash.debounce": { + "version": "4.0.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.isequal": { + "version": "4.5.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash": "*" } }, - "node_modules/@radix-ui/react-portal": { - "version": "1.1.2", + "node_modules/@types/mdast": { + "version": "4.0.4", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "@types/unist": "*" } }, - "node_modules/@radix-ui/react-presence": { - "version": "1.1.1", + "node_modules/@types/ms": { + "version": "0.7.34", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "16.18.111", + "license": "MIT" + }, + "node_modules/@types/node-fetch": { + "version": "2.6.11", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "@types/node": "*", + "form-data": "^4.0.0" } }, - "node_modules/@radix-ui/react-primitive": { - "version": "2.0.0", + "node_modules/@types/prop-types": { + "version": "15.7.13", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.10", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "@types/prop-types": "*", + "csstype": "^3.0.2" } }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.0", + "node_modules/@types/react-dom": { + "version": "18.3.0", + "devOptional": true, "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "@types/react": "*" } }, - "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-context": { - "version": "1.1.0", + "node_modules/@types/react-syntax-highlighter": { + "version": "15.5.13", + "dev": true, "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "dependencies": { + "@types/react": "*" } }, - "node_modules/@radix-ui/react-slot": { - "version": "1.1.0", + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/tern": { + "version": "0.23.9", + "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "@types/estree": "*" } }, - "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.0", + "node_modules/@types/unist": { + "version": "3.0.3", + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "dev": true, "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "dependencies": { + "@types/yargs-parser": "*" } }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.1.0", + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.29.0", + "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/type-utils": "5.29.0", + "@typescript-eslint/utils": "5.29.0", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { - "@types/react": { + "typescript": { "optional": true } } }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.1.0", - "license": "MIT", + "node_modules/@typescript-eslint/parser": { + "version": "5.29.0", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/typescript-estree": "5.29.0", + "debug": "^4.3.4" }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.0", - "license": "MIT", "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { - "@types/react": { + "typescript": { "optional": true } } }, - "node_modules/@radix-ui/react-use-rect": { - "version": "1.1.0", + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.29.0", + "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/rect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/visitor-keys": "5.29.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@radix-ui/react-use-size": { - "version": "1.1.0", + "node_modules/@typescript-eslint/type-utils": { + "version": "5.29.0", + "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.0" + "@typescript-eslint/utils": "5.29.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "eslint": "*" }, "peerDependenciesMeta": { - "@types/react": { + "typescript": { "optional": true } } }, - "node_modules/@radix-ui/rect": { - "version": "1.1.0", - "license": "MIT" - }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "dev": true, - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", + "node_modules/@typescript-eslint/types": { + "version": "5.29.0", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.29.0", "dev": true, - "license": "BSD-3-Clause", + "license": "BSD-2-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@tanstack/query-core": { - "version": "5.56.2", - "license": "MIT", + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/visitor-keys": "5.29.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@tanstack/react-query": { - "version": "5.56.2", + "node_modules/@typescript-eslint/utils": { + "version": "5.29.0", + "dev": true, "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.56.2" + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/typescript-estree": "5.29.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "react": "^18 || ^19" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@types/babel__core": { - "version": "7.20.5", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.29.0", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "@typescript-eslint/types": "5.29.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "license": "ISC" }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "dev": true, + "node_modules/abort-controller": { + "version": "3.0.0", "license": "MIT", "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" } }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", + "node_modules/acorn": { + "version": "8.12.1", "dev": true, "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, - "node_modules/@types/codemirror": { - "version": "5.60.8", + "node_modules/acorn-jsx": { + "version": "5.3.2", "dev": true, "license": "MIT", - "dependencies": { - "@types/tern": "*" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@types/debug": { - "version": "4.1.12", + "node_modules/agentkeepalive": { + "version": "4.5.0", "license": "MIT", "dependencies": { - "@types/ms": "*" + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" } }, - "node_modules/@types/diff": { - "version": "5.2.3", + "node_modules/ajv": { + "version": "6.12.6", "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "license": "MIT" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.5", "license": "MIT", "dependencies": { - "@types/estree": "*" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", + "node_modules/ansi-escapes": { + "version": "4.3.2", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/hast": { - "version": "3.0.4", - "license": "MIT", - "dependencies": { - "@types/unist": "*" + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", + "node_modules/ansi-regex": { + "version": "5.0.1", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", + "node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, "license": "MIT", "dependencies": { - "@types/istanbul-lib-coverage": "*" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", + "node_modules/anymatch": { + "version": "3.1.3", "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "license": "Python-2.0" + }, + "node_modules/aria-hidden": { + "version": "1.2.4", "license": "MIT", "dependencies": { - "@types/istanbul-lib-report": "*" + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@types/jest": { - "version": "29.5.13", + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", "dev": true, "license": "MIT", "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/lodash": { - "version": "4.17.10", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/lodash.debounce": { - "version": "4.0.9", + "node_modules/array-includes": { + "version": "3.1.8", "dev": true, "license": "MIT", "dependencies": { - "@types/lodash": "*" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/lodash.isequal": { - "version": "4.5.8", + "node_modules/array-union": { + "version": "2.1.0", "dev": true, "license": "MIT", - "dependencies": { - "@types/lodash": "*" + "engines": { + "node": ">=8" } }, - "node_modules/@types/mdast": { - "version": "4.0.4", + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "dev": true, "license": "MIT", "dependencies": { - "@types/unist": "*" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/ms": { - "version": "0.7.34", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "16.18.111", - "license": "MIT" - }, - "node_modules/@types/node-fetch": { - "version": "2.6.11", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/prop-types": { - "version": "15.7.13", - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "18.3.10", + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "dev": true, "license": "MIT", "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/react-dom": { - "version": "18.3.0", - "devOptional": true, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "dev": true, "license": "MIT", "dependencies": { - "@types/react": "*" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/react-syntax-highlighter": { - "version": "15.5.13", + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", "dev": true, "license": "MIT", "dependencies": { - "@types/react": "*" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tern": { - "version": "0.23.9", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "*" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/unist": { - "version": "3.0.3", + "node_modules/async": { + "version": "3.2.6", + "dev": true, "license": "MIT" }, - "node_modules/@types/uuid": { - "version": "10.0.0", - "dev": true, + "node_modules/asynckit": { + "version": "0.4.0", "license": "MIT" }, - "node_modules/@types/yargs": { - "version": "17.0.33", + "node_modules/available-typed-arrays": { + "version": "1.0.7", "dev": true, "license": "MIT", "dependencies": { - "@types/yargs-parser": "*" + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.29.0", + "node_modules/babel-jest": { + "version": "29.7.0", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "5.29.0", - "@typescript-eslint/type-utils": "5.29.0", - "@typescript-eslint/utils": "5.29.0", - "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": ">=8" } }, - "node_modules/@typescript-eslint/parser": { - "version": "5.29.0", + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", "dev": true, - "license": "BSD-2-Clause", + "license": "BSD-3-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "5.29.0", - "@typescript-eslint/types": "5.29.0", - "@typescript-eslint/typescript-estree": "5.29.0", - "debug": "^4.3.4" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=8" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.29.0", + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.29.0", - "@typescript-eslint/visitor-keys": "5.29.0" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.29.0", + "node_modules/babel-preset-current-node-syntax": { + "version": "1.1.0", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "5.29.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@babel/core": "^7.0.0" } }, - "node_modules/@typescript-eslint/types": { - "version": "5.29.0", + "node_modules/babel-preset-jest": { + "version": "29.6.3", "dev": true, "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.29.0", + "node_modules/balanced-match": { + "version": "1.0.2", "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.29.0", - "@typescript-eslint/visitor-keys": "5.29.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true + "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", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } + ] + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@typescript-eslint/utils": { - "version": "5.29.0", + "node_modules/braces": { + "version": "3.0.3", "dev": true, "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.29.0", - "@typescript-eslint/types": "5.29.0", - "@typescript-eslint/typescript-estree": "5.29.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "fill-range": "^7.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.0", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "bin": { + "browserslist": "cli.js" }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.29.0", + "node_modules/bs-logger": { + "version": "0.2.6", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.29.0", - "eslint-visitor-keys": "^3.3.0" + "fast-json-stable-stringify": "2.x" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">= 6" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "license": "ISC" + "node_modules/bser": { + "version": "2.1.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } }, - "node_modules/abort-controller": { - "version": "3.0.0", + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "dev": true, "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, "engines": { - "node": ">=6.5" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/acorn": { - "version": "8.12.1", + "node_modules/call-bind": { + "version": "1.0.7", "dev": true, "license": "MIT", - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" }, "engines": { - "node": ">=0.4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", + "node_modules/callsites": { + "version": "3.1.0", "dev": true, "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "engines": { + "node": ">=6" } }, - "node_modules/agentkeepalive": { - "version": "4.5.0", + "node_modules/camelcase": { + "version": "5.3.1", + "dev": true, "license": "MIT", - "dependencies": { - "humanize-ms": "^1.2.1" - }, "engines": { - "node": ">= 8.0.0" + "node": ">=6" } }, - "node_modules/ajv": { - "version": "6.12.6", + "node_modules/caniuse-lite": { + "version": "1.0.30001667", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, "funding": { "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", + "node_modules/chalk": { + "version": "4.1.2", "dev": true, "license": "MIT", "dependencies": { - "type-fest": "^0.21.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", + "node_modules/char-regex": { + "version": "1.0.2", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", "engines": { "node": ">=10" - }, + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "license": "MIT", "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, + "node_modules/character-entities-html4": { + "version": "2.1.0", "license": "MIT", - "engines": { - "node": ">=8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/anymatch": { - "version": "3.1.3", + "node_modules/cjs-module-lexer": { + "version": "1.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", "dev": true, "license": "ISC", "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">= 8" + "node": ">=12" } }, - "node_modules/argparse": { - "version": "2.0.1", + "node_modules/co": { + "version": "4.6.0", "dev": true, - "license": "Python-2.0" - }, - "node_modules/aria-hidden": { - "version": "1.2.4", "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, "engines": { - "node": ">=10" + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" } }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=7.0.0" } }, - "node_modules/array-includes": { - "version": "3.1.8", + "node_modules/color-name": { + "version": "1.1.4", "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">= 0.4" - }, + "node": ">= 0.8" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "license": "MIT", "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/array-union": { - "version": "2.1.0", + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "engines": { + "node": ">=14" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/create-jest": { + "version": "29.7.0", "dev": true, "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", + "node_modules/cross-spawn": { + "version": "7.0.3", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 8" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", + "node_modules/csstype": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "call-bind": "^1.0.6", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "is-data-view": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -2604,15 +3786,14 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", + "node_modules/data-view-byte-length": { + "version": "1.0.1", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -2621,15 +3802,14 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", + "node_modules/data-view-byte-offset": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -2638,57 +3818,75 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.4", - "dev": true, + "node_modules/debug": { + "version": "4.3.7", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" + "ms": "^2.1.3" }, "engines": { - "node": ">= 0.4" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "dev": true, + "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==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "character-entities": "^2.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/async": { - "version": "3.2.6", + "node_modules/dedent": { + "version": "1.5.3", "dev": true, - "license": "MIT" + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, - "node_modules/asynckit": { - "version": "0.4.0", + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, "license": "MIT" }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", + "node_modules/deepmerge": { + "version": "4.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", "dev": true, "license": "MIT", "dependencies": { - "possible-typed-array-names": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -2697,568 +3895,816 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/babel-jest": { - "version": "29.7.0", + "node_modules/define-properties": { + "version": "1.2.1", "dev": true, "license": "MIT", "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.8.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", + "node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/detect-node-es": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "license": "MIT", "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "dequal": "^2.0.0" }, - "engines": { - "node": ">=8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node_modules/diff": { + "version": "7.0.0", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" } }, - "node_modules/babel-plugin-jest-hoist": { + "node_modules/diff-sequences": { "version": "29.6.3", "dev": true, "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.1.0", + "node_modules/dir-glob": { + "version": "3.0.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" + "path-type": "^4.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", + "node_modules/doctrine": { + "version": "3.0.0", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" + "esutils": "^2.0.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node": ">=6.0.0" } }, - "node_modules/balanced-match": { - "version": "1.0.2", + "node_modules/drizzle-kit": { + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.26.2.tgz", + "integrity": "sha512-cMq8omEKywjIy5KcqUo6LvEFxkl8/zYHsgYjFVXjmPWWtuW4blcz+YW9+oIhoaALgs2ebRjzXwsJgN9i6P49Dw==", "dev": true, - "license": "MIT" + "dependencies": { + "@drizzle-team/brocli": "^0.10.1", + "@esbuild-kit/esm-loader": "^2.5.5", + "esbuild": "^0.19.7", + "esbuild-register": "^3.5.0" + }, + "bin": { + "drizzle-kit": "bin.cjs" + } }, - "node_modules/brace-expansion": { - "version": "1.1.11", + "node_modules/drizzle-kit/node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, - "node_modules/braces": { - "version": "3.0.3", + "node_modules/drizzle-kit/node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/browserslist": { - "version": "4.24.0", + "node_modules/drizzle-kit/node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } + "optional": true, + "os": [ + "android" ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001663", - "electron-to-chromium": "^1.5.28", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">=12" } }, - "node_modules/bs-logger": { - "version": "0.2.6", + "node_modules/drizzle-kit/node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 6" + "node": ">=12" } }, - "node_modules/bser": { - "version": "2.1.1", + "node_modules/drizzle-kit/node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" } }, - "node_modules/buffer-from": { - "version": "1.1.2", + "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/builtin-modules": { - "version": "3.3.0", + "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/call-bind": { - "version": "1.0.7", + "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/callsites": { - "version": "3.1.0", + "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/camelcase": { - "version": "5.3.1", + "node_modules/drizzle-kit/node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001667", + "node_modules/drizzle-kit/node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } + "optional": true, + "os": [ + "linux" ], - "license": "CC-BY-4.0" - }, - "node_modules/ccount": { - "version": "2.0.1", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "engines": { + "node": ">=12" } }, - "node_modules/chalk": { - "version": "4.1.2", + "node_modules/drizzle-kit/node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=12" } }, - "node_modules/char-regex": { - "version": "1.0.2", + "node_modules/drizzle-kit/node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/character-entities": { - "version": "2.0.2", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/drizzle-kit/node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/drizzle-kit/node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/drizzle-kit/node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" } }, - "node_modules/ci-info": { - "version": "3.9.0", + "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } + "optional": true, + "os": [ + "openbsd" ], - "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/cjs-module-lexer": { - "version": "1.4.1", + "node_modules/drizzle-kit/node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/cliui": { - "version": "8.0.1", + "node_modules/drizzle-kit/node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">=12" } }, - "node_modules/co": { - "version": "4.6.0", + "node_modules/drizzle-kit/node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "node": ">=12" } }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", + "node_modules/drizzle-kit/node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/color-convert": { - "version": "2.0.1", + "node_modules/drizzle-kit/node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" }, "engines": { - "node": ">=7.0.0" + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/drizzle-orm": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.35.2.tgz", + "integrity": "sha512-bLQtRchl8QvRo2MyG6kcZC90UDzR7Ubir4YwOHV3cZPdJbF+4jU/Yt0QOczsoXe25wLRt6CtCWLXtSDQKft3yg==", + "peerDependencies": { + "@aws-sdk/client-rds-data": ">=3", + "@cloudflare/workers-types": ">=3", + "@electric-sql/pglite": ">=0.1.1", + "@libsql/client": ">=0.10.0", + "@neondatabase/serverless": ">=0.1", + "@op-engineering/op-sqlite": ">=2", + "@opentelemetry/api": "^1.4.1", + "@planetscale/database": ">=1", + "@prisma/client": "*", + "@tidbcloud/serverless": "*", + "@types/better-sqlite3": "*", + "@types/pg": "*", + "@types/react": ">=18", + "@types/sql.js": "*", + "@vercel/postgres": ">=0.8.0", + "@xata.io/client": "*", + "better-sqlite3": ">=7", + "bun-types": "*", + "expo-sqlite": ">=13.2.0", + "knex": "*", + "kysely": "*", + "mysql2": ">=2", + "pg": ">=8", + "postgres": ">=3", + "react": ">=18", + "sql.js": ">=1", + "sqlite3": ">=5" + }, + "peerDependenciesMeta": { + "@aws-sdk/client-rds-data": { + "optional": true + }, + "@cloudflare/workers-types": { + "optional": true + }, + "@electric-sql/pglite": { + "optional": true + }, + "@libsql/client": { + "optional": true + }, + "@neondatabase/serverless": { + "optional": true + }, + "@op-engineering/op-sqlite": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@prisma/client": { + "optional": true + }, + "@tidbcloud/serverless": { + "optional": true + }, + "@types/better-sqlite3": { + "optional": true + }, + "@types/pg": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "@types/sql.js": { + "optional": true + }, + "@vercel/postgres": { + "optional": true + }, + "@xata.io/client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "bun-types": { + "optional": true + }, + "expo-sqlite": { + "optional": true + }, + "knex": { + "optional": true + }, + "kysely": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "postgres": { + "optional": true + }, + "prisma": { + "optional": true + }, + "react": { + "optional": true + }, + "sql.js": { + "optional": true + }, + "sqlite3": { + "optional": true + } } }, - "node_modules/color-name": { - "version": "1.1.4", + "node_modules/ejs": { + "version": "3.1.10", "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "delayed-stream": "~1.0.0" + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" }, "engines": { - "node": ">= 0.8" + "node": ">=0.10.0" } }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", + "node_modules/electron-to-chromium": { + "version": "1.5.32", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "dev": true, "license": "MIT", + "engines": { + "node": ">=12" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/concat-map": { - "version": "0.0.1", + "node_modules/emoji-regex": { + "version": "8.0.0", "dev": true, "license": "MIT" }, - "node_modules/convert-source-map": { - "version": "2.0.0", + "node_modules/entities": { + "version": "4.5.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } }, - "node_modules/create-jest": { - "version": "29.7.0", + "node_modules/es-abstract": { + "version": "1.23.3", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", + "node_modules/es-define-property": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "get-intrinsic": "^1.2.4" }, "engines": { - "node": ">= 8" + "node": ">= 0.4" } }, - "node_modules/csstype": { - "version": "3.1.3", - "license": "MIT" - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", + "node_modules/es-errors": { + "version": "1.3.0", "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", + "node_modules/es-iterator-helpers": { + "version": "1.1.0", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.4", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.3", + "safe-array-concat": "^1.1.2" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/data-view-byte-offset": { + "node_modules/es-object-atoms": { "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/debug": { - "version": "4.3.7", + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 0.4" } }, - "node_modules/decode-named-character-reference": { + "node_modules/es-shim-unscopables": { "version": "1.0.2", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dedent": { - "version": "1.5.3", - "dev": true, - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "hasown": "^2.0.0" } }, - "node_modules/define-data-property": { - "version": "1.1.4", + "node_modules/es-to-primitive": { + "version": "1.2.1", "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -3267,333 +4713,388 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/define-properties": { - "version": "1.2.1", + "node_modules/esbuild": { + "version": "0.17.3", "dev": true, + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "bin": { + "esbuild": "bin/esbuild" }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "@esbuild/android-arm": "0.17.3", + "@esbuild/android-arm64": "0.17.3", + "@esbuild/android-x64": "0.17.3", + "@esbuild/darwin-arm64": "0.17.3", + "@esbuild/darwin-x64": "0.17.3", + "@esbuild/freebsd-arm64": "0.17.3", + "@esbuild/freebsd-x64": "0.17.3", + "@esbuild/linux-arm": "0.17.3", + "@esbuild/linux-arm64": "0.17.3", + "@esbuild/linux-ia32": "0.17.3", + "@esbuild/linux-loong64": "0.17.3", + "@esbuild/linux-mips64el": "0.17.3", + "@esbuild/linux-ppc64": "0.17.3", + "@esbuild/linux-riscv64": "0.17.3", + "@esbuild/linux-s390x": "0.17.3", + "@esbuild/linux-x64": "0.17.3", + "@esbuild/netbsd-x64": "0.17.3", + "@esbuild/openbsd-x64": "0.17.3", + "@esbuild/sunos-x64": "0.17.3", + "@esbuild/win32-arm64": "0.17.3", + "@esbuild/win32-ia32": "0.17.3", + "@esbuild/win32-x64": "0.17.3" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "license": "MIT", - "engines": { - "node": ">=0.4.0" + "node_modules/esbuild-register": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz", + "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "peerDependencies": { + "esbuild": ">=0.12 <1" } }, - "node_modules/dequal": { - "version": "2.0.3", - "license": "MIT", + "node_modules/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.3.tgz", + "integrity": "sha512-1Mlz934GvbgdDmt26rTLmf03cAgLg5HyOgJN+ZGCeP3Q9ynYTNMn2/LQxIl7Uy+o4K6Rfi2OuLsr12JQQR8gNg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/detect-newline": { - "version": "3.1.0", + "node_modules/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.3.tgz", + "integrity": "sha512-XvJsYo3dO3Pi4kpalkyMvfQsjxPWHYjoX4MDiB/FUM4YMfWcXa5l4VCwFWVYI1+92yxqjuqrhNg0CZg3gSouyQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/detect-node-es": { - "version": "1.1.0", - "license": "MIT" + "node_modules/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.3.tgz", + "integrity": "sha512-nuV2CmLS07Gqh5/GrZLuqkU9Bm6H6vcCspM+zjp9TdQlxJtIe+qqEXQChmfc7nWdyr/yz3h45Utk1tUn8Cz5+A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/devlop": { - "version": "1.1.0", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.3.tgz", + "integrity": "sha512-Eo2gq0Q/er2muf8Z83X21UFoB7EU6/m3GNKvrhACJkjVThd0uA+8RfKpfNhuMCl1bKRfBzKOk6xaYKQZ4lZqvA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" } }, - "node_modules/diff": { - "version": "7.0.0", - "license": "BSD-3-Clause", + "node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.3.tgz", + "integrity": "sha512-CN62ESxaquP61n1ZjQP/jZte8CE09M6kNn3baos2SeUfdVBkWN5n6vGp2iKyb/bm/x4JQzEvJgRHLGd5F5b81w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=0.3.1" + "node": ">=12" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", + "node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.3.tgz", + "integrity": "sha512-feq+K8TxIznZE+zhdVurF3WNJ/Sa35dQNYbaqM/wsCbWdzXr5lyq+AaTUSER2cUR+SXPnd/EY75EPRjf4s1SLg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/dir-glob": { - "version": "3.0.1", + "node_modules/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.3.tgz", + "integrity": "sha512-CLP3EgyNuPcg2cshbwkqYy5bbAgK+VhyfMU7oIYyn+x4Y67xb5C5ylxsNUjRmr8BX+MW3YhVNm6Lq6FKtRTWHQ==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/doctrine": { - "version": "3.0.0", + "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.3.tgz", + "integrity": "sha512-JHeZXD4auLYBnrKn6JYJ0o5nWJI9PhChA/Nt0G4MvLaMrvXuWnY93R3a7PiXeJQphpL1nYsaMcoV2QtuvRnF/g==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.0.0" + "node": ">=12" } }, - "node_modules/ejs": { - "version": "3.1.10", + "node_modules/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.3.tgz", + "integrity": "sha512-FyXlD2ZjZqTFh0sOQxFDiWG1uQUEOLbEh9gKN/7pFxck5Vw0qjWSDqbn6C10GAa1rXJpwsntHcmLqydY9ST9ZA==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/electron-to-chromium": { - "version": "1.5.32", - "dev": true, - "license": "ISC" - }, - "node_modules/emittery": { - "version": "0.13.1", + "node_modules/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.3.tgz", + "integrity": "sha512-OrDGMvDBI2g7s04J8dh8/I7eSO+/E7nMDT2Z5IruBfUO/RiigF1OF6xoH33Dn4W/OwAWSUf1s2nXamb28ZklTA==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", + "node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.3.tgz", + "integrity": "sha512-DcnUpXnVCJvmv0TzuLwKBC2nsQHle8EIiAJiJ+PipEVC16wHXaPEKP0EqN8WnBe0TPvMITOUlP2aiL5YMld+CQ==", + "cpu": [ + "mips64el" + ], "dev": true, - "license": "MIT" - }, - "node_modules/entities": { - "version": "4.5.0", - "license": "BSD-2-Clause", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "node": ">=12" } }, - "node_modules/error-ex": { - "version": "1.3.2", + "node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.3.tgz", + "integrity": "sha512-BDYf/l1WVhWE+FHAW3FzZPtVlk9QsrwsxGzABmN4g8bTjmhazsId3h127pliDRRu5674k1Y2RWejbpN46N9ZhQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/es-abstract": { - "version": "1.23.3", + "node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.3.tgz", + "integrity": "sha512-WViAxWYMRIi+prTJTyV1wnqd2mS2cPqJlN85oscVhXdb/ZTFJdrpaqm/uDsZPGKHtbg5TuRX/ymKdOSk41YZow==", + "cpu": [ + "riscv64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/es-define-property": { - "version": "1.0.0", + "node_modules/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.3.tgz", + "integrity": "sha512-Iw8lkNHUC4oGP1O/KhumcVy77u2s6+KUjieUqzEU3XuWJqZ+AY7uVMrrCbAiwWTkpQHkr00BuXH5RpC6Sb/7Ug==", + "cpu": [ + "s390x" + ], "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/es-errors": { - "version": "1.3.0", + "node_modules/esbuild/node_modules/@esbuild/linux-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.3.tgz", + "integrity": "sha512-0AGkWQMzeoeAtXQRNB3s4J1/T2XbigM2/Mn2yU1tQSmQRmHIZdkGbVq2A3aDdNslPyhb9/lH0S5GMTZ4xsjBqg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/es-iterator-helpers": { - "version": "1.1.0", + "node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.3.tgz", + "integrity": "sha512-4+rR/WHOxIVh53UIQIICryjdoKdHsFZFD4zLSonJ9RRw7bhKzVyXbnRPsWSfwybYqw9sB7ots/SYyufL1mBpEg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.4", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.3", - "safe-array-concat": "^1.1.2" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/es-object-atoms": { - "version": "1.0.0", + "node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.3.tgz", + "integrity": "sha512-cVpWnkx9IYg99EjGxa5Gc0XmqumtAwK3aoz7O4Dii2vko+qXbkHoujWA68cqXjhh6TsLaQelfDO4MVnyr+ODeA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", + "node_modules/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.3.tgz", + "integrity": "sha512-RxmhKLbTCDAY2xOfrww6ieIZkZF+KBqG7S2Ako2SljKXRFi+0863PspK74QQ7JpmWwncChY25JTJSbVBYGQk2Q==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", + "node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.3.tgz", + "integrity": "sha512-0r36VeEJ4efwmofxVJRXDjVRP2jTmv877zc+i+Pc7MNsIr38NfsjkQj23AfF7l0WbB+RQ7VUb+LDiqC/KY/M/A==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", + "node_modules/esbuild/node_modules/@esbuild/win32-ia32": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.3.tgz", + "integrity": "sha512-wgO6rc7uGStH22nur4aLFcq7Wh86bE9cOFmfTr/yxN3BXvDEdCSXyKkO+U5JIt53eTOgC47v9k/C1bITWL/Teg==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/esbuild": { + "node_modules/esbuild/node_modules/@esbuild/win32-x64": { "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.3.tgz", + "integrity": "sha512-FdVl64OIuiKjgXBjwZaJLKp0eaEckifbhn10dXWhysMJkWblg3OEEGKSIyhiD5RSgAya8WzP3DNkngtIg3Nt7g==", + "cpu": [ + "x64" + ], "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.17.3", - "@esbuild/android-arm64": "0.17.3", - "@esbuild/android-x64": "0.17.3", - "@esbuild/darwin-arm64": "0.17.3", - "@esbuild/darwin-x64": "0.17.3", - "@esbuild/freebsd-arm64": "0.17.3", - "@esbuild/freebsd-x64": "0.17.3", - "@esbuild/linux-arm": "0.17.3", - "@esbuild/linux-arm64": "0.17.3", - "@esbuild/linux-ia32": "0.17.3", - "@esbuild/linux-loong64": "0.17.3", - "@esbuild/linux-mips64el": "0.17.3", - "@esbuild/linux-ppc64": "0.17.3", - "@esbuild/linux-riscv64": "0.17.3", - "@esbuild/linux-s390x": "0.17.3", - "@esbuild/linux-x64": "0.17.3", - "@esbuild/netbsd-x64": "0.17.3", - "@esbuild/openbsd-x64": "0.17.3", - "@esbuild/sunos-x64": "0.17.3", - "@esbuild/win32-arm64": "0.17.3", - "@esbuild/win32-ia32": "0.17.3", - "@esbuild/win32-x64": "0.17.3" } }, "node_modules/escalade": { @@ -4010,6 +5511,11 @@ "node": ">=6" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/execa": { "version": "5.1.1", "dev": true, @@ -4054,6 +5560,11 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==" + }, "node_modules/extend": { "version": "3.0.2", "license": "MIT" @@ -4385,6 +5896,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "dev": true, @@ -5348,6 +6871,33 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-changed-files/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==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-changed-files/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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jest-circus": { "version": "29.7.0", "dev": true, @@ -5378,6 +6928,33 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-circus/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==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus/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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jest-cli": { "version": "29.7.0", "dev": true, @@ -5686,6 +7263,33 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-runner/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==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-runner/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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jest-runtime": { "version": "29.7.0", "dev": true, @@ -5845,13 +7449,20 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-tiktoken": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.15.tgz", + "integrity": "sha512-65ruOWWXDEZHHbAo7EjOcNxOGasQKbL4Fq3jEr2xsCqSsoOo6VVSqzWQb6PRIqypFSDcma4jO90YP0w5X8qVXQ==", + "dependencies": { + "base64-js": "^1.5.1" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -5902,6 +7513,14 @@ "json5": "lib/cli.js" } }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "dev": true, @@ -5932,6 +7551,106 @@ "node": ">=6" } }, + "node_modules/langchain": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/langchain/-/langchain-0.3.2.tgz", + "integrity": "sha512-kd2kz1cS/PIVrLEDFlrZsAasQfPLbY1UqCZbRKa3/QcpB33/n6xPDvXSMfBuKhvNj0bjW6MXDR9HZTduXjJBgg==", + "dependencies": { + "@langchain/openai": ">=0.1.0 <0.4.0", + "@langchain/textsplitters": ">=0.0.0 <0.2.0", + "js-tiktoken": "^1.0.12", + "js-yaml": "^4.1.0", + "jsonpointer": "^5.0.1", + "langsmith": "^0.1.56-rc.1", + "openapi-types": "^12.1.3", + "p-retry": "4", + "uuid": "^10.0.0", + "yaml": "^2.2.1", + "zod": "^3.22.4", + "zod-to-json-schema": "^3.22.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/anthropic": "*", + "@langchain/aws": "*", + "@langchain/cohere": "*", + "@langchain/core": ">=0.2.21 <0.4.0", + "@langchain/google-genai": "*", + "@langchain/google-vertexai": "*", + "@langchain/groq": "*", + "@langchain/mistralai": "*", + "@langchain/ollama": "*", + "axios": "*", + "cheerio": "*", + "handlebars": "^4.7.8", + "peggy": "^3.0.2", + "typeorm": "*" + }, + "peerDependenciesMeta": { + "@langchain/anthropic": { + "optional": true + }, + "@langchain/aws": { + "optional": true + }, + "@langchain/cohere": { + "optional": true + }, + "@langchain/google-genai": { + "optional": true + }, + "@langchain/google-vertexai": { + "optional": true + }, + "@langchain/groq": { + "optional": true + }, + "@langchain/mistralai": { + "optional": true + }, + "@langchain/ollama": { + "optional": true + }, + "axios": { + "optional": true + }, + "cheerio": { + "optional": true + }, + "handlebars": { + "optional": true + }, + "peggy": { + "optional": true + }, + "typeorm": { + "optional": true + } + } + }, + "node_modules/langsmith": { + "version": "0.1.65", + "resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.1.65.tgz", + "integrity": "sha512-+aBft8/jUQbVPv3MWVwFwW/rMxyyA8xSRIsjWl773Nc7LDniczuf2rxZEUslV02RB36EIBgCJPNX7jz2L5YsIQ==", + "dependencies": { + "@types/uuid": "^10.0.0", + "commander": "^10.0.1", + "p-queue": "^6.6.2", + "p-retry": "4", + "semver": "^7.6.3", + "uuid": "^10.0.0" + }, + "peerDependencies": { + "openai": "*" + }, + "peerDependenciesMeta": { + "openai": { + "optional": true + } + } + }, "node_modules/leven": { "version": "3.1.0", "dev": true, @@ -6930,6 +8649,15 @@ "version": "2.1.3", "license": "MIT" }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "peer": true, + "bin": { + "mustache": "bin/mustache" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, @@ -7139,8 +8867,9 @@ } }, "node_modules/openai": { - "version": "4.65.0", - "license": "Apache-2.0", + "version": "4.67.3", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.67.3.tgz", + "integrity": "sha512-HT2tZgjLgRqbLQNKmYtjdF/4TQuiBvg1oGvTDhwpSEQzxo6/oM1us8VQ53vBK2BiKvCxFuq6gKGG70qfwrNhKg==", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", @@ -7169,6 +8898,11 @@ "undici-types": "~5.26.4" } }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==" + }, "node_modules/optionator": { "version": "0.9.4", "dev": true, @@ -7185,15 +8919,23 @@ "node": ">= 0.8.0" } }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "engines": { + "node": ">=4" + } + }, "node_modules/p-limit": { - "version": "3.1.0", - "dev": true, - "license": "MIT", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.1.0.tgz", + "integrity": "sha512-H0jc0q1vOzlEk0TqAKXKZxdl7kX3OFUzCnNVUnq5Pc3DGo0kpeaMuPqxQn235HibwBEb0/pm9dgKTjXy66fBkg==", "dependencies": { - "yocto-queue": "^0.1.0" + "yocto-queue": "^1.1.1" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -7213,6 +8955,71 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-locate/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==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-try": { "version": "2.2.0", "dev": true, @@ -7938,6 +9745,15 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/resolve.exports": { "version": "2.0.2", "dev": true, @@ -7946,6 +9762,14 @@ "node": ">=10" } }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, "node_modules/reusify": { "version": "1.0.4", "dev": true, @@ -8033,7 +9857,6 @@ }, "node_modules/semver": { "version": "7.6.3", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -9030,6 +10853,17 @@ "dev": true, "license": "ISC" }, + "node_modules/yaml": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", + "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", "dev": true, @@ -9072,16 +10906,32 @@ } }, "node_modules/yocto-queue": { - "version": "0.1.0", - "dev": true, - "license": "MIT", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", "engines": { - "node": ">=10" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.23.3", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.23.3.tgz", + "integrity": "sha512-TYWChTxKQbRJp5ST22o/Irt9KC5nj7CdBKYB/AosCRdj/wxEMvv4NNaj9XVUHDOIp53ZxArGhnw5HMZziPFjog==", + "peerDependencies": { + "zod": "^3.23.3" + } + }, "node_modules/zwitch": { "version": "2.0.4", "license": "MIT", diff --git a/package.json b/package.json index 922121b..81bec00 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,9 @@ "lint:check": "(prettier --check --cache --cache-strategy content --cache-location node_modules/.cache/.prettiercache .) && (eslint .)", "lint:fix": "(prettier --write --cache --cache-strategy content --cache-location node_modules/.cache/.prettiercache .) && (eslint --fix .)", "type:check": "tsc --noEmit", - "test": "jest" + "test": "jest", + "migrate:generate": "npx drizzle-kit generate", + "migrate:compile": "node compile-migration.js" }, "keywords": [], "author": "", @@ -28,6 +30,7 @@ "@typescript-eslint/eslint-plugin": "5.29.0", "@typescript-eslint/parser": "5.29.0", "builtin-modules": "3.3.0", + "drizzle-kit": "^0.26.2", "esbuild": "0.17.3", "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", @@ -43,23 +46,31 @@ }, "dependencies": { "@anthropic-ai/sdk": "^0.27.3", + "@electric-sql/pglite": "^0.2.12", "@lexical/react": "^0.17.1", "@radix-ui/react-dropdown-menu": "^2.1.2", + "@radix-ui/react-tooltip": "^1.1.3", "@tanstack/react-query": "^5.56.2", "diff": "^7.0.0", + "drizzle-orm": "^0.35.2", + "exponential-backoff": "^3.1.1", "fuzzysort": "^3.1.0", "groq-sdk": "^0.7.0", + "js-tiktoken": "^1.0.15", + "langchain": "^0.3.2", "lexical": "^0.17.1", "lodash.debounce": "^4.0.8", "lodash.isequal": "^4.5.0", "lucide-react": "^0.447.0", "openai": "^4.65.0", + "p-limit": "^6.1.0", "parse5": "^7.1.2", "react": "^18.3.1", "react-dom": "^18.3.1", "react-markdown": "^9.0.1", "react-syntax-highlighter": "^15.5.0", "remark-gfm": "^4.0.0", - "uuid": "^10.0.0" + "uuid": "^10.0.0", + "zod": "^3.23.8" } -} \ No newline at end of file +} diff --git a/src/ChatView.tsx b/src/ChatView.tsx index 70cba8b..514f1b7 100644 --- a/src/ChatView.tsx +++ b/src/ChatView.tsx @@ -8,6 +8,7 @@ import { CHAT_VIEW_TYPE } from './constants' import { AppProvider } from './contexts/app-context' import { DarkModeProvider } from './contexts/dark-mode-context' import { LLMProvider } from './contexts/llm-context' +import { RAGProvider } from './contexts/rag-context' import { SettingsProvider } from './contexts/settings-context' import SmartCopilotPlugin from './main' import { MentionableBlockData } from './types/mentionable' @@ -41,7 +42,7 @@ export class ChatView extends ItemView { } async onOpen() { - this.render() + await this.render() // Consume chatProps this.initialChatProps = undefined @@ -51,12 +52,13 @@ export class ChatView extends ItemView { this.root?.unmount() } - render() { + async render() { if (!this.root) { this.root = createRoot(this.containerEl.children[1]) } const queryClient = new QueryClient() + const ragEngine = await this.plugin.getRAGEngine() this.root.render( @@ -69,11 +71,13 @@ export class ChatView extends ItemView { > - - - - - + + + + + + + diff --git a/src/components/chat-view/Chat.tsx b/src/components/chat-view/Chat.tsx index fb4564c..214aa79 100644 --- a/src/components/chat-view/Chat.tsx +++ b/src/components/chat-view/Chat.tsx @@ -6,6 +6,7 @@ import { useCallback, useEffect, useImperativeHandle, + useMemo, useRef, useState, } from 'react' @@ -15,11 +16,11 @@ import { ApplyViewState } from '../../ApplyView' import { APPLY_VIEW_TYPE } from '../../constants' import { useApp } from '../../contexts/app-context' import { useLLM } from '../../contexts/llm-context' +import { useRAG } from '../../contexts/rag-context' import { useSettings } from '../../contexts/settings-context' import { useChatHistory } from '../../hooks/useChatHistory' import { OpenSettingsModal } from '../../OpenSettingsModal' import { ChatMessage, ChatUserMessage } from '../../types/chat' -import { RequestMessage } from '../../types/llm/request' import { MentionableBlock, MentionableBlockData, @@ -31,11 +32,12 @@ import { LLMAPIKeyNotSetException, } from '../../utils/llm/exception' import { readTFileContent } from '../../utils/obsidian' -import { parseRequestMessages } from '../../utils/prompt' +import { PromptGenerator } from '../../utils/promptGenerator' import ChatUserInput, { ChatUserInputRef } from './chat-input/ChatUserInput' import { editorStateToPlainText } from './chat-input/utils/editor-state-to-plain-text' import { ChatListDropdown } from './ChatListDropdown' +import QueryProgress, { QueryProgressState } from './QueryProgress' import ReactMarkdown from './ReactMarkdown' // Add an empty line here @@ -43,6 +45,7 @@ const getNewInputMessage = (app: App): ChatUserMessage => { return { role: 'user', content: null, + promptContent: null, id: uuidv4(), mentionables: [ { @@ -65,6 +68,7 @@ export type ChatProps = { const Chat = forwardRef((props, ref) => { const app = useApp() const { settings } = useSettings() + const { ragEngine } = useRAG() const { createOrUpdateConversation, @@ -74,6 +78,13 @@ const Chat = forwardRef((props, ref) => { } = useChatHistory() const { generateResponse, streamResponse } = useLLM() + const promptGenerator: PromptGenerator | null = useMemo(() => { + if (!ragEngine) { + return null + } + return new PromptGenerator(ragEngine, app, settings) + }, [ragEngine, app, settings]) + const [inputMessage, setInputMessage] = useState(() => { const newMessage = getNewInputMessage(app) if (props.selectedBlock) { @@ -91,6 +102,9 @@ const Chat = forwardRef((props, ref) => { const [focusedMessageId, setFocusedMessageId] = useState(null) const [currentConversationId, setCurrentConversationId] = useState(uuidv4()) + const [queryProgress, setQueryProgress] = useState({ + type: 'idle', + }) const activeStreamAbortControllersRef = useRef([]) const chatUserInputRefs = useRef>(new Map()) const chatMessagesRef = useRef(null) @@ -133,6 +147,9 @@ const Chat = forwardRef((props, ref) => { const newInputMessage = getNewInputMessage(app) setInputMessage(newInputMessage) setFocusedMessageId(newInputMessage.id) + setQueryProgress({ + type: 'idle', + }) } catch (error) { new Notice('Failed to load conversation') console.error('Failed to load conversation', error) @@ -145,12 +162,28 @@ const Chat = forwardRef((props, ref) => { const newInputMessage = getNewInputMessage(app) setInputMessage(newInputMessage) setFocusedMessageId(newInputMessage.id) + setQueryProgress({ + type: 'idle', + }) abortActiveStreams() } const submitMutation = useMutation({ - mutationFn: async (newChatHistory: ChatMessage[]) => { + mutationFn: async ({ + newChatHistory, + useVaultSearch, + }: { + newChatHistory: ChatMessage[] + useVaultSearch?: boolean + }) => { abortActiveStreams() + setQueryProgress({ + type: 'idle', + }) + + if (!promptGenerator) { + throw new Error('Prompt generator is not initialized') + } const responseMessageId = uuidv4() setChatMessages([ @@ -162,15 +195,24 @@ const Chat = forwardRef((props, ref) => { const abortController = new AbortController() activeStreamAbortControllersRef.current.push(abortController) - const requestMessages = await parseRequestMessages( - newChatHistory, - app.vault, - ) - + const { requestMessages, compiledMessages } = + await promptGenerator.generateRequestMessages({ + messages: newChatHistory, + useVaultSearch, + onQueryProgressChange: setQueryProgress, + }) + setQueryProgress({ + type: 'idle', + }) + + setChatMessages([ + ...compiledMessages, + { role: 'assistant', content: '', id: responseMessageId }, + ]) const stream = await streamResponse( { model: settings.chatModel, - messages: requestMessages as RequestMessage[], + messages: requestMessages, stream: true, }, { @@ -198,6 +240,9 @@ const Chat = forwardRef((props, ref) => { } }, onError: (error) => { + setQueryProgress({ + type: 'idle', + }) if ( error instanceof LLMAPIKeyNotSetException || error instanceof LLMAPIKeyInvalidException @@ -215,8 +260,11 @@ const Chat = forwardRef((props, ref) => { }, }) - const handleSubmit = (newChatHistory: ChatMessage[]) => { - submitMutation.mutate(newChatHistory) + const handleSubmit = ( + newChatHistory: ChatMessage[], + useVaultSearch?: boolean, + ) => { + submitMutation.mutate({ newChatHistory, useVaultSearch }) } const applyMutation = useMutation({ @@ -434,15 +482,18 @@ const Chat = forwardRef((props, ref) => { ), ) }} - onSubmit={(content) => { + onSubmit={(content, useVaultSearch) => { if (editorStateToPlainText(content).trim() === '') return - handleSubmit([ - ...chatMessages.slice(0, index), - { - ...message, - content, - }, - ]) + handleSubmit( + [ + ...chatMessages.slice(0, index), + { + ...message, + content, + }, + ], + useVaultSearch, + ) chatUserInputRefs.current.get(inputMessage.id)?.focus() }} onFocus={() => { @@ -469,6 +520,7 @@ const Chat = forwardRef((props, ref) => { ), )} + ((props, ref) => { content, })) }} - onSubmit={(content) => { + onSubmit={(content, useVaultSearch) => { if (editorStateToPlainText(content).trim() === '') return - handleSubmit([...chatMessages, { ...inputMessage, content }]) + handleSubmit( + [...chatMessages, { ...inputMessage, content }], + useVaultSearch, + ) chatUserInputRefs.current.get(inputMessage.id)?.clear() setInputMessage(getNewInputMessage(app)) handleScrollToBottom() diff --git a/src/components/chat-view/MarkdownCodeComponent.tsx b/src/components/chat-view/MarkdownCodeComponent.tsx index 6fe99c2..a7034f2 100644 --- a/src/components/chat-view/MarkdownCodeComponent.tsx +++ b/src/components/chat-view/MarkdownCodeComponent.tsx @@ -1,13 +1,10 @@ import { Check, CopyIcon, Loader2 } from 'lucide-react' -import { PropsWithChildren, memo, useMemo, useState } from 'react' -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' -import { - oneDark, - oneLight, -} from 'react-syntax-highlighter/dist/esm/styles/prism' +import { PropsWithChildren, useMemo, useState } from 'react' import { useDarkModeContext } from '../../contexts/dark-mode-context' +import { MemoizedSyntaxHighlighterWrapper } from './SyntaxHighlighterWrapper' + export default function MarkdownCodeComponent({ onApply, isApplying, @@ -86,48 +83,3 @@ export default function MarkdownCodeComponent({ ) } - -function SyntaxHighlighterWrapper({ - isDarkMode, - language, - hasFilename, - wrapLines, - children, -}: { - isDarkMode: boolean - language: string | undefined - hasFilename: boolean - wrapLines: boolean - children: string -}) { - return ( - - {children} - - ) -} - -const MemoizedSyntaxHighlighterWrapper = memo(SyntaxHighlighterWrapper) diff --git a/src/components/chat-view/MarkdownReferenceBlock.tsx b/src/components/chat-view/MarkdownReferenceBlock.tsx new file mode 100644 index 0000000..bad20c1 --- /dev/null +++ b/src/components/chat-view/MarkdownReferenceBlock.tsx @@ -0,0 +1,96 @@ +import { MarkdownView } from 'obsidian' +import { PropsWithChildren, useEffect, useMemo, useState } from 'react' + +import { useApp } from '../../contexts/app-context' +import { useDarkModeContext } from '../../contexts/dark-mode-context' +import { readTFileContent } from '../../utils/obsidian' + +import { MemoizedSyntaxHighlighterWrapper } from './SyntaxHighlighterWrapper' + +export default function MarkdownReferenceBlock({ + filename, + startLine, + endLine, + language, +}: PropsWithChildren<{ + filename: string + startLine: number + endLine: number + language?: string +}>) { + const app = useApp() + const { isDarkMode } = useDarkModeContext() + const [blockContent, setBlockContent] = useState(null) + + const wrapLines = useMemo(() => { + return !language || ['markdown'].includes(language) + }, [language]) + + useEffect(() => { + async function fetchBlockContent() { + const file = app.vault.getFileByPath(filename) + if (!file) { + setBlockContent(null) + return + } + const fileContent = await readTFileContent(file, app.vault) + const content = fileContent + .split('\n') + .slice(startLine - 1, endLine) + .join('\n') + setBlockContent(content) + } + + fetchBlockContent() + }, [filename, startLine, endLine, app.vault]) + + const handleClick = () => { + const file = app.vault.getFileByPath(filename) + if (!file) return + + const existingLeaf = app.workspace + .getLeavesOfType('markdown') + .find( + (leaf) => + leaf.view instanceof MarkdownView && + leaf.view.file?.path === file.path, + ) + + if (existingLeaf) { + app.workspace.setActiveLeaf(existingLeaf, { focus: true }) + const view = existingLeaf.view as MarkdownView + view.setEphemeralState({ line: startLine }) + } else { + const leaf = app.workspace.getLeaf('tab') + leaf.openFile(file, { + eState: { line: startLine }, + }) + } + } + + // TODO: Update styles + return ( + blockContent && ( +
+
+ {filename && ( +
+ {filename} +
+ )} +
+ + {blockContent} + +
+ ) + ) +} diff --git a/src/components/chat-view/QueryProgress.tsx b/src/components/chat-view/QueryProgress.tsx new file mode 100644 index 0000000..bb5bd34 --- /dev/null +++ b/src/components/chat-view/QueryProgress.tsx @@ -0,0 +1,85 @@ +import { SelectVector } from '../../db/schema' + +export type QueryProgressState = + | { + type: 'reading-mentionables' + } + | { + type: 'indexing' + indexProgress: IndexProgress + } + | { + type: 'querying' + } + | { + type: 'querying-done' + queryResult: (Omit & { similarity: number })[] + } + | { + type: 'idle' + } + +export type IndexProgress = { + completedChunks: number + totalChunks: number + totalFiles: number +} + +// TODO: Update style +export default function QueryProgress({ + state, +}: { + state: QueryProgressState +}) { + switch (state.type) { + case 'idle': + return null + case 'reading-mentionables': + return ( +
+

+ Reading mentioned files + +

+
+ ) + case 'indexing': + return ( +
+

+ {`Indexing ${state.indexProgress.totalFiles} file`} + +

+

{`${state.indexProgress.completedChunks}/${state.indexProgress.totalChunks} chunks indexed`}

+
+ ) + case 'querying': + return ( +
+

+ Querying the vault + +

+
+ ) + case 'querying-done': + return ( +
+

+ Reading related files + +

+ {state.queryResult.map((result) => ( +
+

{result.path}

+

{result.similarity}

+
+ ))} +
+ ) + } +} + +function DotLoader() { + return +} diff --git a/src/components/chat-view/ReactMarkdown.tsx b/src/components/chat-view/ReactMarkdown.tsx index 0cd206c..3f27306 100644 --- a/src/components/chat-view/ReactMarkdown.tsx +++ b/src/components/chat-view/ReactMarkdown.tsx @@ -7,6 +7,7 @@ import { } from '../../utils/parse-smtcmp-block' import MarkdownCodeComponent from './MarkdownCodeComponent' +import MarkdownReferenceBlock from './MarkdownReferenceBlock' function ReactMarkdown({ onApply, @@ -29,6 +30,13 @@ function ReactMarkdown({ {block.content} + ) : block.startLine && block.endLine && block.filename ? ( + ) : ( + {children} + + ) +} + +export const MemoizedSyntaxHighlighterWrapper = memo(SyntaxHighlighterWrapper) diff --git a/src/components/chat-view/chat-input/ChatUserInput.tsx b/src/components/chat-view/chat-input/ChatUserInput.tsx index 99233cd..9116991 100644 --- a/src/components/chat-view/chat-input/ChatUserInput.tsx +++ b/src/components/chat-view/chat-input/ChatUserInput.tsx @@ -39,6 +39,7 @@ import OnMutationPlugin, { import UpdaterPlugin, { UpdaterPluginRef, } from './plugins/updater/UpdaterPlugin' +import { VaultSearchButton } from './VaultSearchButton' export type ChatUserInputRef = { focus: () => void @@ -48,7 +49,7 @@ export type ChatUserInputRef = { export type ChatUserInputProps = { message: SerializedEditorState | null // TODO: fix name to initialContent onChange: (content: SerializedEditorState) => void - onSubmit: (content: SerializedEditorState) => void + onSubmit: (content: SerializedEditorState, useVaultSearch?: boolean) => void onFocus: () => void mentionables: Mentionable[] setMentionables: (mentionables: Mentionable[]) => void @@ -103,7 +104,7 @@ const ChatUserInput = forwardRef( // eslint-disable-next-line react-hooks/exhaustive-deps }, []) - const searchFilesByQuery = useCallback( + const searchResultByQuery = useCallback( (query: string) => fuzzySearch(app, query), [app], ) @@ -196,6 +197,11 @@ const ChatUserInput = forwardRef( }) } + const handleSubmit = (useVaultSearch?: boolean) => { + const content = editorRef.current?.getEditorState()?.toJSON() + content && onSubmit(content, useVaultSearch) + } + return (
{mentionables.length > 0 && ( @@ -235,7 +241,7 @@ const ChatUserInput = forwardRef( {autoFocus && } ( /> { + onEnter={(evt, useVaultSearch?: boolean) => { evt.preventDefault() evt.stopPropagation() - const content = editorRef.current?.getEditorState()?.toJSON() - content && onSubmit(content) + handleSubmit(useVaultSearch) }} /> ( - +
+ + { + handleSubmit(true) + }} + /> +
) }, diff --git a/src/components/chat-view/chat-input/MentionableBadge.tsx b/src/components/chat-view/chat-input/MentionableBadge.tsx index 1e6a6ac..8a129b4 100644 --- a/src/components/chat-view/chat-input/MentionableBadge.tsx +++ b/src/components/chat-view/chat-input/MentionableBadge.tsx @@ -6,8 +6,12 @@ import { MentionableBlock, MentionableCurrentFile, MentionableFile, + MentionableFolder, + MentionableVault, } from '../../../types/mentionable' +import { getMentionableIcon } from './utils/get-metionable-icon' + function BadgeBase({ children, onDelete, @@ -34,15 +38,71 @@ function FileBadge({ mentionable: MentionableFile onDelete: () => void }) { + const Icon = getMentionableIcon(mentionable) return (
+ {Icon && ( + + )} {mentionable.file.name}
) } +function FolderBadge({ + mentionable, + onDelete, +}: { + mentionable: MentionableFolder + onDelete: () => void +}) { + const Icon = getMentionableIcon(mentionable) + return ( + + {/* TODO: Update style */} +
+ {Icon && ( + + )} + {mentionable.folder.name} +
+
+ ) +} + +function VaultBadge({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + mentionable, + onDelete, +}: { + mentionable: MentionableVault + onDelete: () => void +}) { + const Icon = getMentionableIcon(mentionable) + return ( + + {/* TODO: Update style */} +
+ {Icon && ( + + )} + Vault +
+
+ ) +} + function CurrentFileBadge({ mentionable, onDelete, @@ -50,9 +110,16 @@ function CurrentFileBadge({ mentionable: MentionableCurrentFile onDelete: () => void }) { + const Icon = getMentionableIcon(mentionable) return mentionable.file ? (
+ {Icon && ( + + )} {`${mentionable.file.name}`}
@@ -69,9 +136,16 @@ function BlockBadge({ mentionable: MentionableBlock onDelete: () => void }) { + const Icon = getMentionableIcon(mentionable) return (
+ {Icon && ( + + )} {`${mentionable.file.name}`}
@@ -91,6 +165,10 @@ export default function MentionableBadge({ switch (mentionable.type) { case 'file': return + case 'folder': + return + case 'vault': + return case 'current-file': return case 'block': diff --git a/src/components/chat-view/chat-input/VaultSearchButton.tsx b/src/components/chat-view/chat-input/VaultSearchButton.tsx new file mode 100644 index 0000000..152b1a3 --- /dev/null +++ b/src/components/chat-view/chat-input/VaultSearchButton.tsx @@ -0,0 +1,41 @@ +import * as Tooltip from '@radix-ui/react-tooltip' +import { + ArrowBigUp, + ChevronUp, + Command, + CornerDownLeftIcon, +} from 'lucide-react' +import { Platform } from 'obsidian' + +export function VaultSearchButton({ onClick }: { onClick: () => void }) { + return ( + <> + + + + + + + + Search through your entire vault + + + + + + ) +} diff --git a/src/components/chat-view/chat-input/plugins/mention/MentionPlugin.tsx b/src/components/chat-view/chat-input/plugins/mention/MentionPlugin.tsx index 28dab41..4826dae 100644 --- a/src/components/chat-view/chat-input/plugins/mention/MentionPlugin.tsx +++ b/src/components/chat-view/chat-input/plugins/mention/MentionPlugin.tsx @@ -10,13 +10,14 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { $createTextNode, COMMAND_PRIORITY_NORMAL, TextNode } from 'lexical' -import { TFile } from 'obsidian' import { useCallback, useMemo, useState } from 'react' import { createPortal } from 'react-dom' import { serializeMentionable } from 'src/utils/mentionable' -import { Mentionable, MentionableFile } from '../../../../../types/mentionable' +import { Mentionable } from '../../../../../types/mentionable' +import { SearchableMentionable } from '../../../../../utils/fuzzy-search' import { getMentionableName } from '../../../../../utils/mentionable' +import { getMentionableIcon } from '../../utils/get-metionable-icon' import { MenuOption, MenuTextMatch } from '../shared/LexicalMenu' import { LexicalTypeaheadMenuPlugin, @@ -101,12 +102,27 @@ function getPossibleQueryMatch(text: string): MenuTextMatch | null { class MentionTypeaheadOption extends MenuOption { name: string - file: TFile - - constructor(file: TFile) { - super(file.path) - this.name = file.name - this.file = file + mentionable: Mentionable + icon: React.ReactNode + + constructor(result: SearchableMentionable) { + switch (result.type) { + case 'file': + super(result.file.path) + this.name = result.file.name + this.mentionable = result + break + case 'folder': + super(result.folder.path) + this.name = result.folder.name + this.mentionable = result + break + case 'vault': + super('vault') + this.name = 'Vault' + this.mentionable = result + break + } } } @@ -127,6 +143,8 @@ function MentionsTypeaheadMenuItem({ if (isSelected) { className += ' selected' } + + const Icon = getMentionableIcon(option.mentionable) return (
  • + {Icon && } {option.name}
  • ) } export default function NewMentionsPlugin({ - searchFilesByQuery, + searchResultByQuery, onAddMention, }: { - searchFilesByQuery: (query: string) => TFile[] + searchResultByQuery: (query: string) => SearchableMentionable[] onAddMention: (mentionable: Mentionable) => void }): JSX.Element | null { const [editor] = useLexicalComposerContext() @@ -157,8 +176,8 @@ export default function NewMentionsPlugin({ const results = useMemo(() => { if (queryString == null) return [] - return searchFilesByQuery(queryString) - }, [queryString, searchFilesByQuery]) + return searchResultByQuery(queryString) + }, [queryString, searchResultByQuery]) const checkForSlashTriggerMatch = useBasicTypeaheadTriggerMatch('/', { minLength: 0, @@ -178,14 +197,10 @@ export default function NewMentionsPlugin({ nodeToReplace: TextNode | null, closeMenu: () => void, ) => { - const mentionable: MentionableFile = { - type: 'file', - file: selectedOption.file, - } editor.update(() => { const mentionNode = $createMentionNode( - getMentionableName(mentionable), - serializeMentionable(mentionable), + getMentionableName(selectedOption.mentionable), + serializeMentionable(selectedOption.mentionable), ) if (nodeToReplace) { nodeToReplace.replace(mentionNode) @@ -198,7 +213,7 @@ export default function NewMentionsPlugin({ closeMenu() }) - onAddMention(mentionable) + onAddMention(selectedOption.mentionable) }, [editor, onAddMention], ) diff --git a/src/components/chat-view/chat-input/plugins/on-enter/OnEnterPlugin.tsx b/src/components/chat-view/chat-input/plugins/on-enter/OnEnterPlugin.tsx index 06deeb0..899fa08 100644 --- a/src/components/chat-view/chat-input/plugins/on-enter/OnEnterPlugin.tsx +++ b/src/components/chat-view/chat-input/plugins/on-enter/OnEnterPlugin.tsx @@ -1,11 +1,12 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { COMMAND_PRIORITY_LOW, KEY_ENTER_COMMAND } from 'lexical' +import { Platform } from 'obsidian' import { useEffect } from 'react' export default function OnEnterPlugin({ onEnter, }: { - onEnter: (evt: KeyboardEvent) => void + onEnter: (evt: KeyboardEvent, useVaultSearch?: boolean) => void }) { const [editor] = useLexicalComposerContext() @@ -14,9 +15,13 @@ export default function OnEnterPlugin({ KEY_ENTER_COMMAND, (evt: KeyboardEvent) => { if (evt.shiftKey) { + if (Platform.isMacOS ? evt.metaKey : evt.ctrlKey) { + onEnter(evt, true) + return true + } return false } - onEnter(evt) + onEnter(evt, false) return true }, COMMAND_PRIORITY_LOW, diff --git a/src/components/chat-view/chat-input/utils/get-metionable-icon.ts b/src/components/chat-view/chat-input/utils/get-metionable-icon.ts new file mode 100644 index 0000000..3d31e9f --- /dev/null +++ b/src/components/chat-view/chat-input/utils/get-metionable-icon.ts @@ -0,0 +1,18 @@ +import { FileIcon, FolderClosedIcon, FoldersIcon } from 'lucide-react' + +import { Mentionable } from '../../../../types/mentionable' + +export const getMentionableIcon = (mentionable: Mentionable) => { + switch (mentionable.type) { + case 'file': + return FileIcon + case 'folder': + return FolderClosedIcon + case 'vault': + return FoldersIcon + case 'current-file': + return FileIcon + default: + return null + } +} diff --git a/src/constants.ts b/src/constants.ts index cbb6d11..031a2c7 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,16 +1,6 @@ -import { SmartCopilotSettings } from './types/settings' - export const CHAT_VIEW_TYPE = 'smtcmp-chat-view' export const APPLY_VIEW_TYPE = 'smtcmp-apply-view' -export const DEFAULT_SETTINGS: SmartCopilotSettings = { - openAIApiKey: '', - groqApiKey: '', - anthropicApiKey: '', - chatModel: 'claude-3-5-sonnet-20240620', - applyModel: 'gpt-4o-mini', -} - export const CHAT_MODEL_OPTIONS = [ { name: 'claude-3.5-sonnet (Recommended)', @@ -48,3 +38,19 @@ export const APPLY_MODEL_OPTIONS = [ value: 'llama-3.1-70b-versatile', }, ] + +// Update table exports in src/db/schema.ts when updating this +export const EMBEDDING_MODEL_OPTIONS = [ + { + name: 'text-embedding-3-small (Recommended)', + value: 'text-embedding-3-small', + dimension: 1536, + }, + { + name: 'text-embedding-3-large', + value: 'text-embedding-3-large', + dimension: 3072, + }, +] + +export const PGLITE_DB_PATH = '.smtcmp_vector_db.tar.gz' diff --git a/src/contexts/rag-context.tsx b/src/contexts/rag-context.tsx new file mode 100644 index 0000000..777d39c --- /dev/null +++ b/src/contexts/rag-context.tsx @@ -0,0 +1,26 @@ +import { PropsWithChildren, createContext, useContext } from 'react' + +import { RAGEngine } from '../utils/ragEngine' + +export type RAGContextType = { + ragEngine: RAGEngine | null +} + +const RAGContext = createContext(null) + +export function RAGProvider({ + ragEngine, + children, +}: PropsWithChildren<{ ragEngine: RAGEngine | null }>) { + return ( + {children} + ) +} + +export function useRAG() { + const context = useContext(RAGContext) + if (!context) { + throw new Error('useRAG must be used within a RAGProvider') + } + return context +} diff --git a/src/db/migrations.json b/src/db/migrations.json new file mode 100644 index 0000000..1aded28 --- /dev/null +++ b/src/db/migrations.json @@ -0,0 +1,20 @@ +[ + { + "sql": [ + "-- Custom SQL migration file, put you code below! --\nCREATE EXTENSION IF NOT EXISTS vector;" + ], + "bps": true, + "folderMillis": 1729509950412, + "hash": "6c20ce195f8fc8f8ccb136af42a856f90c3e62e0727ad2e9cd1f01e59efc3a86" + }, + { + "sql": [ + "CREATE TABLE IF NOT EXISTS \"vector_data_text_embedding_3_small\" (\n\t\"id\" serial PRIMARY KEY NOT NULL,\n\t\"path\" text NOT NULL,\n\t\"mtime\" bigint NOT NULL,\n\t\"content\" text NOT NULL,\n\t\"embedding\" vector(1536),\n\t\"metadata\" jsonb NOT NULL\n);\n", + "\nCREATE TABLE IF NOT EXISTS \"vector_data_text_embedding_3_large\" (\n\t\"id\" serial PRIMARY KEY NOT NULL,\n\t\"path\" text NOT NULL,\n\t\"mtime\" bigint NOT NULL,\n\t\"content\" text NOT NULL,\n\t\"embedding\" vector(3072),\n\t\"metadata\" jsonb NOT NULL\n);\n", + "\nCREATE INDEX IF NOT EXISTS \"embeddingIndex_text_embedding_3_small\" ON \"vector_data_text_embedding_3_small\" USING hnsw (\"embedding\" vector_cosine_ops);" + ], + "bps": true, + "folderMillis": 1729509994653, + "hash": "30520313039892c9c07b13185b6e4aa0b0f9a09b851db96e0f6e400303560aec" + } +] diff --git a/src/db/schema.ts b/src/db/schema.ts new file mode 100644 index 0000000..88a4b92 --- /dev/null +++ b/src/db/schema.ts @@ -0,0 +1,57 @@ +import { + bigint, + index, + jsonb, + pgTable, + serial, + text, + vector, +} from 'drizzle-orm/pg-core' + +import { EMBEDDING_MODEL_OPTIONS } from '../constants' +import { EmbeddingModelName } from '../types/embedding' + +const createVectorTable = (name: string, dimension: number) => { + const sanitizedName = name.replace(/[^a-zA-Z0-9]/g, '_') + return pgTable( + `vector_data_${sanitizedName}`, + { + id: serial('id').primaryKey(), + path: text('path').notNull(), + mtime: bigint('mtime', { mode: 'number' }).notNull(), + content: text('content').notNull(), + embedding: vector('embedding', { dimensions: dimension }), + metadata: jsonb('metadata').notNull().$type(), + }, + dimension <= 2000 // pgvector only supports hnsw for dimensions <= 2000 + ? (table) => ({ + embeddingIndex: index(`embeddingIndex_${sanitizedName}`).using( + 'hnsw', + table.embedding.op('vector_cosine_ops'), + ), + }) + : undefined, + ) +} + +export const vectorTables = EMBEDDING_MODEL_OPTIONS.reduce< + Record> +>((acc, modelOption) => { + acc[modelOption.value] = createVectorTable( + modelOption.value, + modelOption.dimension, + ) + return acc +}, {}) + +export type VectorTable = (typeof vectorTables)[M] +export type SelectVector = VectorTable['$inferSelect'] +export type InsertVector = VectorTable['$inferInsert'] +export type VectorMetaData = { + startLine: number + endLine: number +} + +// 'npx drizzle-kit generate' requires individual table exports to generate correct migration files +export const vectorTable0 = vectorTables[EMBEDDING_MODEL_OPTIONS[0].value] +export const vectorTable1 = vectorTables[EMBEDDING_MODEL_OPTIONS[1].value] diff --git a/src/hooks/useChatHistory.ts b/src/hooks/useChatHistory.ts index cee12e0..94a5e6c 100644 --- a/src/hooks/useChatHistory.ts +++ b/src/hooks/useChatHistory.ts @@ -23,6 +23,7 @@ const serializeChatMessage = (message: ChatMessage): SerializedChatMessage => { return { role: 'user', content: message.content, + promptContent: message.promptContent, id: message.id, mentionables: message.mentionables.map(serializeMentionable), } @@ -44,6 +45,7 @@ const deserializeChatMessage = ( return { role: 'user', content: message.content, + promptContent: message.promptContent, id: message.id, mentionables: message.mentionables .map((m) => deserializeMentionable(m, app)) diff --git a/src/main.ts b/src/main.ts index 16eb010..02dbcc4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,18 +1,23 @@ -import { Editor, MarkdownView, Plugin } from 'obsidian' +import { Editor, MarkdownView, Notice, Plugin } from 'obsidian' import { ApplyView } from './ApplyView' import { ChatView } from './ChatView' import { ChatProps } from './components/chat-view/Chat' -import { APPLY_VIEW_TYPE, CHAT_VIEW_TYPE, DEFAULT_SETTINGS } from './constants' +import { APPLY_VIEW_TYPE, CHAT_VIEW_TYPE } from './constants' import { SmartCopilotSettingTab } from './settings/SettingTab' -import { SmartCopilotSettings } from './types/settings' +import { + SmartCopilotSettings, + parseSmartCopilotSettings, +} from './types/settings' import { getMentionableBlockData } from './utils/obsidian' +import { RAGEngine } from './utils/ragEngine' // Remember to rename these classes and interfaces! export default class SmartCopilotPlugin extends Plugin { settings: SmartCopilotSettings initialChatProps?: ChatProps // TODO: change this to use view state like ApplyView settingsChangeListeners: ((newSettings: SmartCopilotSettings) => void)[] = [] + ragEngine: RAGEngine | null = null async onload() { await this.loadSettings() @@ -40,6 +45,68 @@ export default class SmartCopilotPlugin extends Plugin { }, }) + this.addCommand({ + id: 'rebuild-vault-index', + name: 'Rebuild entire vault index', + callback: async () => { + const notice = new Notice('Rebuilding vault index...', 0) + try { + const ragEngine = await this.getRAGEngine() + await ragEngine.updateVaultIndex( + { reindexAll: true }, + (queryProgress) => { + if (queryProgress.type === 'indexing') { + const { completedChunks, totalChunks } = + queryProgress.indexProgress + notice.setMessage( + `Indexing chunks: ${completedChunks} / ${totalChunks}`, + ) + } + }, + ) + notice.setMessage('Rebuilding vault index complete') + } catch (error) { + console.error(error) + notice.setMessage('Rebuilding vault index failed') + } finally { + setTimeout(() => { + notice.hide() + }, 1000) + } + }, + }) + + this.addCommand({ + id: 'update-vault-index', + name: 'Update index for modified files', + callback: async () => { + const notice = new Notice('Updating vault index...', 0) + try { + const ragEngine = await this.getRAGEngine() + await ragEngine.updateVaultIndex( + { reindexAll: false }, + (queryProgress) => { + if (queryProgress.type === 'indexing') { + const { completedChunks, totalChunks } = + queryProgress.indexProgress + notice.setMessage( + `Indexing chunks: ${completedChunks} / ${totalChunks}`, + ) + } + }, + ) + notice.setMessage('Vault index updated') + } catch (error) { + console.error(error) + notice.setMessage('Vault index update failed') + } finally { + setTimeout(() => { + notice.hide() + }, 1000) + } + }, + }) + // This adds a settings tab so the user can configure various aspects of the plugin this.addSettingTab(new SmartCopilotSettingTab(this.app, this)) } @@ -47,12 +114,13 @@ export default class SmartCopilotPlugin extends Plugin { onunload() {} async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()) + this.settings = parseSmartCopilotSettings(await this.loadData()) } async setSettings(newSettings: SmartCopilotSettings) { this.settings = newSettings await this.saveData(newSettings) + this.ragEngine?.setSettings(newSettings) this.settingsChangeListeners.forEach((listener) => listener(newSettings)) } @@ -116,4 +184,11 @@ export default class SmartCopilotPlugin extends Plugin { chatView.addSelectionToChat(data) chatView.focusMessage() } + + async getRAGEngine(): Promise { + if (!this.ragEngine) { + this.ragEngine = await RAGEngine.create(this.app, this.settings) + } + return this.ragEngine + } } diff --git a/src/settings/SettingTab.tsx b/src/settings/SettingTab.tsx index e96b567..ff9cfc2 100644 --- a/src/settings/SettingTab.tsx +++ b/src/settings/SettingTab.tsx @@ -1,6 +1,10 @@ import { App, PluginSettingTab, Setting } from 'obsidian' -import { APPLY_MODEL_OPTIONS, CHAT_MODEL_OPTIONS } from '../constants' +import { + APPLY_MODEL_OPTIONS, + CHAT_MODEL_OPTIONS, + EMBEDDING_MODEL_OPTIONS, +} from '../constants' import SmartCopilotPlugin from '../main' export class SmartCopilotSettingTab extends PluginSettingTab { @@ -111,5 +115,122 @@ export class SmartCopilotSettingTab extends PluginSettingTab { }) }), ) + + new Setting(containerEl) + .setName('Embedding Model') + .setDesc('Choose the model you want to use for embeddings') + .addDropdown((dropdown) => + dropdown + .addOptions( + EMBEDDING_MODEL_OPTIONS.reduce>( + (acc, option) => { + acc[option.value] = option.name + return acc + }, + {}, + ), + ) + .setValue(this.plugin.settings.embeddingModel) + .onChange(async (value) => { + await this.plugin.setSettings({ + ...this.plugin.settings, + embeddingModel: value, + }) + }), + ) + + new Setting(containerEl).setHeading().setName('RAG Options') + + new Setting(containerEl) + .setName('Chunk Size') + .setDesc( + 'Set the chunk size for text splitting. After changing this, please re-index the vault using the "Rebuild entire vault index" command.', + ) + .addText((text) => + text + .setPlaceholder('1000') + .setValue(String(this.plugin.settings.ragOptions.chunkSize)) + .onChange(async (value) => { + const chunkSize = parseInt(value, 10) + if (!isNaN(chunkSize)) { + await this.plugin.setSettings({ + ...this.plugin.settings, + ragOptions: { + ...this.plugin.settings.ragOptions, + chunkSize, + }, + }) + } + }), + ) + + new Setting(containerEl) + .setName('Threshold Tokens') + .setDesc( + 'Maximum number of tokens before switching to RAG. If the total tokens from mentioned files exceed this, RAG will be used instead of including all file contents.', + ) + .addText((text) => + text + .setPlaceholder('8192') + .setValue(String(this.plugin.settings.ragOptions.thresholdTokens)) + .onChange(async (value) => { + const thresholdTokens = parseInt(value, 10) + if (!isNaN(thresholdTokens)) { + await this.plugin.setSettings({ + ...this.plugin.settings, + ragOptions: { + ...this.plugin.settings.ragOptions, + thresholdTokens, + }, + }) + } + }), + ) + + new Setting(containerEl) + .setName('Minimum Similarity') + .setDesc( + 'Minimum similarity score for RAG results. Higher values return more relevant but potentially fewer results.', + ) + .addText((text) => + text + .setPlaceholder('0.0') + .setValue(String(this.plugin.settings.ragOptions.minSimilarity)) + .onChange(async (value) => { + const minSimilarity = parseFloat(value) + if (!isNaN(minSimilarity)) { + await this.plugin.setSettings({ + ...this.plugin.settings, + ragOptions: { + ...this.plugin.settings.ragOptions, + minSimilarity, + }, + }) + } + }), + ) + + new Setting(containerEl) + .setName('Limit') + .setDesc( + 'Maximum number of RAG results to include in the prompt. Higher values provide more context but increase token usage.', + ) + .addText((text) => + text + .setPlaceholder('10') + .setValue(String(this.plugin.settings.ragOptions.limit)) + .onChange(async (value) => { + const limit = parseInt(value, 10) + if (!isNaN(limit)) { + await this.plugin.setSettings({ + ...this.plugin.settings, + ragOptions: { + ...this.plugin.settings.ragOptions, + limit, + }, + }) + } + }), + ) } } diff --git a/src/types/chat.ts b/src/types/chat.ts index 9717933..acca208 100644 --- a/src/types/chat.ts +++ b/src/types/chat.ts @@ -5,6 +5,7 @@ import { Mentionable, SerializedMentionable } from './mentionable' export type ChatUserMessage = { role: 'user' content: SerializedEditorState | null + promptContent: string | null id: string mentionables: Mentionable[] } @@ -18,6 +19,7 @@ export type ChatMessage = ChatUserMessage | ChatAssistantMessage export type SerializedChatUserMessage = { role: 'user' content: SerializedEditorState | null + promptContent: string | null id: string mentionables: SerializedMentionable[] } diff --git a/src/types/embedding.ts b/src/types/embedding.ts new file mode 100644 index 0000000..07a6a05 --- /dev/null +++ b/src/types/embedding.ts @@ -0,0 +1,9 @@ +export type EmbeddingModelName = + | 'text-embedding-3-small' + | 'text-embedding-3-large' + +export type EmbeddingModel = { + name: EmbeddingModelName + dimension: number + getEmbedding: (text: string) => Promise +} diff --git a/src/types/mentionable.ts b/src/types/mentionable.ts index fa40fc0..05c4d46 100644 --- a/src/types/mentionable.ts +++ b/src/types/mentionable.ts @@ -1,9 +1,16 @@ -import { TFile } from 'obsidian' +import { TFile, TFolder } from 'obsidian' export type MentionableFile = { type: 'file' file: TFile } +export type MentionableFolder = { + type: 'folder' + folder: TFolder +} +export type MentionableVault = { + type: 'vault' +} export type MentionableCurrentFile = { type: 'current-file' file: TFile | null @@ -19,6 +26,8 @@ export type MentionableBlock = MentionableBlockData & { } export type Mentionable = | MentionableFile + | MentionableFolder + | MentionableVault | MentionableCurrentFile | MentionableBlock @@ -26,6 +35,13 @@ export type SerializedMentionableFile = { type: 'file' file: string } +export type SerializedMentionableFolder = { + type: 'folder' + folder: string +} +export type SerializedMentionableVault = { + type: 'vault' +} export type SerializedMentionableCurrentFile = { type: 'current-file' file: string | null @@ -39,5 +55,7 @@ export type SerializedMentionableBlock = { } export type SerializedMentionable = | SerializedMentionableFile + | SerializedMentionableFolder + | SerializedMentionableVault | SerializedMentionableCurrentFile | SerializedMentionableBlock diff --git a/src/types/settings.ts b/src/types/settings.ts index 7f8f1e5..1679e4e 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -1,7 +1,24 @@ -export type SmartCopilotSettings = { - openAIApiKey: string - groqApiKey: string - anthropicApiKey: string - chatModel: string - applyModel: string +import { z } from 'zod' + +const smartCopilotSettingsSchema = z.object({ + openAIApiKey: z.string().default(''), + groqApiKey: z.string().default(''), + anthropicApiKey: z.string().default(''), + chatModel: z.string().default('claude-3-5-sonnet-20240620'), + applyModel: z.string().default('gpt-4o-mini'), + embeddingModel: z.string().default('text-embedding-3-small'), + ragOptions: z + .object({ + chunkSize: z.number().default(1000), + thresholdTokens: z.number().default(8192), + minSimilarity: z.number().default(0.0), + limit: z.number().default(10), + }) + .default({}), +}) + +export type SmartCopilotSettings = z.infer + +export function parseSmartCopilotSettings(data: unknown): SmartCopilotSettings { + return smartCopilotSettingsSchema.parse(data) } diff --git a/src/utils/embedding.ts b/src/utils/embedding.ts new file mode 100644 index 0000000..31b8318 --- /dev/null +++ b/src/utils/embedding.ts @@ -0,0 +1,49 @@ +import { OpenAI } from 'openai' + +import { EmbeddingModel } from '../types/embedding' + +export const getEmbeddingModel = ( + name: string, + apiKeys: { + openAIApiKey: string + }, +): EmbeddingModel => { + switch (name) { + case 'text-embedding-3-small': { + const openai = new OpenAI({ + apiKey: apiKeys.openAIApiKey, + dangerouslyAllowBrowser: true, + }) + return { + name: 'text-embedding-3-small', + dimension: 1536, + getEmbedding: async (text: string) => { + const embedding = await openai.embeddings.create({ + model: 'text-embedding-3-small', + input: text, + }) + return embedding.data[0].embedding + }, + } + } + case 'text-embedding-3-large': { + const openai = new OpenAI({ + apiKey: apiKeys.openAIApiKey, + dangerouslyAllowBrowser: true, + }) + return { + name: 'text-embedding-3-large', + dimension: 3072, + getEmbedding: async (text: string) => { + const embedding = await openai.embeddings.create({ + model: 'text-embedding-3-large', + input: text, + }) + return embedding.data[0].embedding + }, + } + } + default: + throw new Error('Invalid embedding model') + } +} diff --git a/src/utils/fuzzy-search.ts b/src/utils/fuzzy-search.ts index a7858e3..95df5af 100644 --- a/src/utils/fuzzy-search.ts +++ b/src/utils/fuzzy-search.ts @@ -1,9 +1,26 @@ import fuzzysort from 'fuzzysort' -import { App, TFile } from 'obsidian' +import { App, TFile, TFolder } from 'obsidian' + +import { + MentionableFile, + MentionableFolder, + MentionableVault, +} from '../types/mentionable' import { calculateFileDistance, getOpenFiles } from './obsidian' +export type SearchableMentionable = + | MentionableFile + | MentionableFolder + | MentionableVault + +type VaultSearchItem = { + type: 'vault' + path: string +} + type FileWithMetadata = { + type: 'file' path: string file: TFile opened: boolean @@ -11,47 +28,69 @@ type FileWithMetadata = { daysSinceLastModified: number } -function scoreFnWithBoost(score: number, fileWithMetadata: FileWithMetadata) { - let boost = 1 - const { opened, distance, daysSinceLastModified } = fileWithMetadata +type FolderWithMetadata = { + type: 'folder' + path: string + folder: TFolder +} - // Boost for open files - if (opened) boost = Math.max(boost, 3) +type SearchItem = FolderWithMetadata | FileWithMetadata | VaultSearchItem - // Boost for recently modified files - if (daysSinceLastModified < 30) { - const recentBoost = 1 + 2 / (daysSinceLastModified + 2) - boost = Math.max(boost, recentBoost) - } +function scoreFnWithBoost(score: number, searchItem: SearchItem) { + switch (searchItem.type) { + case 'file': { + let boost = 1 + const { opened, distance, daysSinceLastModified } = searchItem - // Boost for nearby files - if (distance !== null && distance > 0 && distance <= 5) { - const nearbyBoost = 1 + 0.5 / Math.max(distance - 1, 1) - boost = Math.max(boost, nearbyBoost) - } + // Boost for open files + if (opened) boost = Math.max(boost, 3) + + // Boost for recently modified files + if (daysSinceLastModified < 30) { + const recentBoost = 1 + 2 / (daysSinceLastModified + 2) + boost = Math.max(boost, recentBoost) + } - // Normalize the boost - const normalizedBoost = - boost > 1 ? Math.log(boost * score + 1) / Math.log(boost + 1) : score - return normalizedBoost + // Boost for nearby files + if (distance !== null && distance > 0 && distance <= 5) { + const nearbyBoost = 1 + 0.5 / Math.max(distance - 1, 1) + boost = Math.max(boost, nearbyBoost) + } + + // Normalize the boost + const normalizedBoost = + boost > 1 ? Math.log(boost * score + 1) / Math.log(boost + 1) : score + return normalizedBoost + } + // TODO: Implement scoring logic for folders + case 'folder': { + return score + } + // TODO: Implement scoring logic for vault + case 'vault': { + return score + } + } } function getEmptyQueryResult( - allFilesWithMetadata: FileWithMetadata[], + searchItems: SearchItem[], limit: number, -) { +): SearchableMentionable[] { // Sort files based on a custom scoring function - const sortedFiles = allFilesWithMetadata.sort((a, b) => { + const sortedFiles = searchItems.sort((a, b) => { const scoreA = scoreFnWithBoost(0.5, a) // Use 0.5 as a base score const scoreB = scoreFnWithBoost(0.5, b) return scoreB - scoreA // Sort in descending order }) // Return only the top 'limit' files - return sortedFiles.slice(0, limit).map((file) => file.file) + return sortedFiles + .slice(0, limit) + .map((item) => searchItemToMentionable(item)) } -export function fuzzySearch(app: App, query: string): TFile[] { +export function fuzzySearch(app: App, query: string): SearchableMentionable[] { const currentFile = app.workspace.getActiveFile() const openFiles = getOpenFiles(app) @@ -60,26 +99,43 @@ export function fuzzySearch(app: App, query: string): TFile[] { return extension === 'md' }) - const allFilesWithMetadata: FileWithMetadata[] = allSupportedFiles.map( - (file) => ({ - path: file.path, - file, - opened: openFiles.some((f) => f.path === file.path), - distance: currentFile - ? currentFile === file - ? null - : calculateFileDistance(currentFile, file) - : null, - daysSinceLastModified: - (Date.now() - file.stat.mtime) / (1000 * 60 * 60 * 24), - }), - ) + const allFilesWithMetadata: SearchItem[] = allSupportedFiles.map((file) => ({ + type: 'file', + path: file.path, + file, + opened: openFiles.some((f) => f.path === file.path), + distance: currentFile + ? currentFile === file + ? null + : calculateFileDistance(currentFile, file) + : null, + daysSinceLastModified: + (Date.now() - file.stat.mtime) / (1000 * 60 * 60 * 24), + })) + + const allFolders = app.vault.getAllFolders() + const allFoldersWithMetadata: SearchItem[] = allFolders.map((folder) => ({ + type: 'folder', + path: folder.path, + folder, + })) + + const vaultItem: VaultSearchItem = { + type: 'vault', + path: 'vault', + } + + const searchItems: SearchItem[] = [ + ...allFilesWithMetadata, + ...allFoldersWithMetadata, + vaultItem, + ] if (!query) { - return getEmptyQueryResult(allFilesWithMetadata, 20) + return getEmptyQueryResult(searchItems, 20) } - const results = fuzzysort.go(query, allFilesWithMetadata, { + const results = fuzzysort.go(query, searchItems, { keys: ['path'], threshold: 0.2, limit: 20, @@ -87,5 +143,24 @@ export function fuzzySearch(app: App, query: string): TFile[] { scoreFn: (result) => scoreFnWithBoost(result.score, result.obj), }) - return results.map((result) => result.obj.file) + return results.map((result) => searchItemToMentionable(result.obj)) +} + +function searchItemToMentionable(item: SearchItem): SearchableMentionable { + switch (item.type) { + case 'file': + return { + type: 'file', + file: item.file, + } + case 'folder': + return { + type: 'folder', + folder: item.folder, + } + case 'vault': + return { + type: 'vault', + } + } } diff --git a/src/utils/mentionable.ts b/src/utils/mentionable.ts index 9b63bd4..9af612f 100644 --- a/src/utils/mentionable.ts +++ b/src/utils/mentionable.ts @@ -11,6 +11,15 @@ export const serializeMentionable = ( type: 'file', file: mentionable.file.path, } + case 'folder': + return { + type: 'folder', + folder: mentionable.folder.path, + } + case 'vault': + return { + type: 'vault', + } case 'current-file': return { type: 'current-file', @@ -43,6 +52,20 @@ export const deserializeMentionable = ( file: file, } } + case 'folder': { + const folder = app.vault.getFolderByPath(mentionable.folder) + if (!folder) { + return null + } + return { + type: 'folder', + folder: folder, + } + } + case 'vault': + return { + type: 'vault', + } case 'current-file': { if (!mentionable.file) { return { @@ -80,6 +103,10 @@ export function getMentionableKey(mentionable: SerializedMentionable): string { switch (mentionable.type) { case 'file': return `file:${mentionable.file}` + case 'folder': + return `folder:${mentionable.folder}` + case 'vault': + return 'vault' case 'current-file': return `current-file:${mentionable.file ?? 'current'}` case 'block': @@ -91,6 +118,10 @@ export function getMentionableName(mentionable: Mentionable): string { switch (mentionable.type) { case 'file': return mentionable.file.name + case 'folder': + return mentionable.folder.name + case 'vault': + return 'Vault' case 'current-file': return mentionable.file?.name ?? 'Current File' case 'block': diff --git a/src/utils/obsidian.ts b/src/utils/obsidian.ts index d12d9d7..0d8ca19 100644 --- a/src/utils/obsidian.ts +++ b/src/utils/obsidian.ts @@ -1,4 +1,4 @@ -import { App, Editor, MarkdownView, TFile, Vault } from 'obsidian' +import { App, Editor, MarkdownView, TFile, TFolder, Vault } from 'obsidian' import { MentionableBlockData } from '../types/mentionable' @@ -18,6 +18,18 @@ export async function readMultipleTFiles( return await Promise.all(readPromises) } +export function getNestedFiles(folder: TFolder, vault: Vault): TFile[] { + const files: TFile[] = [] + for (const child of folder.children) { + if (child instanceof TFile) { + files.push(child) + } else if (child instanceof TFolder) { + files.push(...getNestedFiles(child, vault)) + } + } + return files +} + export async function getMentionableBlockData( editor: Editor, view: MarkdownView, diff --git a/src/utils/parse-smtcmp-block.test.ts b/src/utils/parse-smtcmp-block.test.ts index 6b40152..b98f80c 100644 --- a/src/utils/parse-smtcmp-block.test.ts +++ b/src/utils/parse-smtcmp-block.test.ts @@ -155,4 +155,20 @@ Some text after without closing tag`, const result = parsesmtcmpBlocks(input) expect(result).toEqual(expected) }) + + it('should handle smtcmp_block with startline and endline attributes', () => { + const input = `` + const expected: ParsedSmtcmpBlock[] = [ + { + type: 'smtcmp_block', + content: '', + language: 'markdown', + startLine: 2, + endLine: 5, + }, + ] + + const result = parsesmtcmpBlocks(input) + expect(result).toEqual(expected) + }) }) diff --git a/src/utils/parse-smtcmp-block.ts b/src/utils/parse-smtcmp-block.ts index 8b895ff..07d531c 100644 --- a/src/utils/parse-smtcmp-block.ts +++ b/src/utils/parse-smtcmp-block.ts @@ -7,6 +7,8 @@ export type ParsedSmtcmpBlock = content: string language?: string filename?: string + startLine?: number + endLine?: number } export function parsesmtcmpBlocks(input: string): ParsedSmtcmpBlock[] { @@ -35,6 +37,10 @@ export function parsesmtcmpBlocks(input: string): ParsedSmtcmpBlock[] { const filename = node.attrs.find( (attr) => attr.name === 'filename', )?.value + const startLine = node.attrs.find( + (attr) => attr.name === 'startline', + )?.value + const endLine = node.attrs.find((attr) => attr.name === 'endline')?.value const children = node.childNodes if (children.length === 0) { @@ -43,6 +49,8 @@ export function parsesmtcmpBlocks(input: string): ParsedSmtcmpBlock[] { content: '', language, filename, + startLine: startLine ? parseInt(startLine) : undefined, + endLine: endLine ? parseInt(endLine) : undefined, }) } else { const innerContentStartOffset = @@ -57,6 +65,8 @@ export function parsesmtcmpBlocks(input: string): ParsedSmtcmpBlock[] { content: input.slice(innerContentStartOffset, innerContentEndOffset), language, filename, + startLine: startLine ? parseInt(startLine) : undefined, + endLine: endLine ? parseInt(endLine) : undefined, }) } lastEndOffset = endOffset diff --git a/src/utils/prompt.ts b/src/utils/prompt.ts deleted file mode 100644 index 5001796..0000000 --- a/src/utils/prompt.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { TFile, Vault } from 'obsidian' -import { ChatCompletionMessageParam } from 'openai/resources' - -import { editorStateToPlainText } from '../components/chat-view/chat-input/utils/editor-state-to-plain-text' -import { ChatMessage, ChatUserMessage } from '../types/chat' -import { MentionableBlock, MentionableFile } from '../types/mentionable' - -import { readMultipleTFiles, readTFileContent } from './obsidian' - -const getCurrentFileMessage = async ( - currentFile: TFile, - vault: Vault, -): Promise => { - const fileContent = await readTFileContent(currentFile, vault) - return { - role: 'user', - content: `# Inputs -## Current File -Here is the file I'm looking at. -\`\`\`${currentFile.path} -${fileContent} -\`\`\`\n\n`, - } -} - -const parseUserMessage = async ( - message: ChatUserMessage, - vault: Vault, -): Promise => { - const files = message.mentionables - .filter((m): m is MentionableFile => m.type === 'file') - .map((m) => m.file) - const fileContents = await readMultipleTFiles(files, vault) - const filePrompt = files - .map((file, index) => { - return `\`\`\`${file.path}\n${fileContents[index]}\n\`\`\`\n` - }) - .join('') - - const blocks = message.mentionables.filter( - (m): m is MentionableBlock => m.type === 'block', - ) - const blocksPrompt = blocks - .map(({ file, content }) => { - return `\`\`\`${file.path}\n${content}\n\`\`\`\n` - }) - .join('') - - return `${filePrompt}${blocksPrompt}\n\n${message.content ? editorStateToPlainText(message.content) : ''}\n\n` -} - -export const parseRequestMessages = async ( - messages: ChatMessage[], - vault: Vault, -): Promise => { - if (messages.length === 0) { - throw new Error('No messages provided') - } - const lastUserMessage = messages[messages.length - 1] - if (lastUserMessage.role !== 'user') { - throw new Error('Last message is not a user message') - } - - const systemMessage = { - role: 'system', - content: `You are an intelligent assistant to help answer any questions that the user has, particularly about editing and organizing markdown files in Obsidian. - -1. Please keep your response as concise as possible. Avoid being verbose. - -2. When the user is asking for edits to their markdown, please provide a simplified version of the markdown block emphasizing only the changes. Use comments to show where unchanged content has been skipped. Wrap the markdown block with tags. Add filename and language attributes to the tags. For example: - - -{{ edit_1 }} - -{{ edit_2 }} - - -The user has full access to the file, so they prefer seeing only the changes in the markdown. Often this will mean that the start/end of the file will be skipped, but that's okay! Rewrite the entire file only if specifically requested. Always provide a brief explanation of the updates, except when the user specifically asks for just the content. - -3. Do not lie or make up facts. - -4. Respond in the same language as the user's message. - -5. Format your response in markdown. - -6. When writing out new markdown blocks, also wrap them with tags. For example: - -{{ content }} - - -7. When providing markdown blocks for an existing file, add the filename and language attributes to the tags. Restate the relevant section or heading, so the user knows which part of the file you are editing. For example: - -## Section Title -... -{{ content }} -... -`, - } - - const currentFile = lastUserMessage.mentionables.find( - (m) => m.type === 'current-file', - )?.file - - const currentFileMessage = currentFile - ? await getCurrentFileMessage(currentFile, vault) - : undefined - - const parsedMessages = await Promise.all( - messages.map(async (message) => - message.role === 'user' - ? { role: 'user', content: await parseUserMessage(message, vault) } - : { role: 'assistant', content: message.content }, - ), - ) - - return [ - systemMessage, - ...(currentFileMessage ? [currentFileMessage] : []), - ...parsedMessages.filter((message) => !!message.content), - ] as ChatCompletionMessageParam[] -} diff --git a/src/utils/promptGenerator.ts b/src/utils/promptGenerator.ts new file mode 100644 index 0000000..4a01036 --- /dev/null +++ b/src/utils/promptGenerator.ts @@ -0,0 +1,329 @@ +import { App, TFile } from 'obsidian' + +import { editorStateToPlainText } from '../components/chat-view/chat-input/utils/editor-state-to-plain-text' +import { QueryProgressState } from '../components/chat-view/QueryProgress' +import { ChatMessage, ChatUserMessage } from '../types/chat' +import { RequestMessage } from '../types/llm/request' +import { + MentionableBlock, + MentionableFile, + MentionableFolder, + MentionableVault, +} from '../types/mentionable' +import { SmartCopilotSettings } from '../types/settings' + +import { + getNestedFiles, + readMultipleTFiles, + readTFileContent, +} from './obsidian' +import { RAGEngine } from './ragEngine' +import { tokenCount } from './token' + +export class PromptGenerator { + private ragEngine: RAGEngine + private app: App + private settings: SmartCopilotSettings + + constructor(ragEngine: RAGEngine, app: App, settings: SmartCopilotSettings) { + this.ragEngine = ragEngine + this.app = app + this.settings = settings + } + + public async generateRequestMessages({ + messages, + useVaultSearch, + onQueryProgressChange, + }: { + messages: ChatMessage[] + useVaultSearch?: boolean + onQueryProgressChange?: (queryProgress: QueryProgressState) => void + }): Promise<{ + requestMessages: RequestMessage[] + compiledMessages: ChatMessage[] + }> { + if (messages.length === 0) { + throw new Error('No messages provided') + } + const lastUserMessage = messages[messages.length - 1] + if (lastUserMessage.role !== 'user') { + throw new Error('Last message is not a user message') + } + + const { promptContent, shouldUseRAG } = await this.compileUserMessagePrompt( + { + message: lastUserMessage, + useVaultSearch, + onQueryProgressChange: onQueryProgressChange, + }, + ) + let compiledMessages = [ + ...messages.slice(0, -1), + { + ...lastUserMessage, + promptContent: promptContent, + }, + ] + + // Safeguard: ensure all user messages have parsed content + compiledMessages = await Promise.all( + compiledMessages.map(async (message) => { + if (message.role === 'user' && !message.promptContent) { + const { promptContent } = await this.compileUserMessagePrompt({ + message, + }) + return { + ...message, + promptContent: promptContent, + } + } + return message + }), + ) + + const systemMessage = this.getSystemMessage(shouldUseRAG) + + const currentFile = lastUserMessage.mentionables.find( + (m) => m.type === 'current-file', + )?.file + const currentFileMessage = currentFile + ? await this.getCurrentFileMessage(currentFile) + : undefined + + const requestMessages: RequestMessage[] = [ + systemMessage, + ...(currentFileMessage ? [currentFileMessage] : []), + ...compiledMessages.map((message): RequestMessage => { + if (message.role === 'user') { + return { + role: 'user', + content: message.promptContent ?? '', + } + } else { + return { + role: 'assistant', + content: message.content, + } + } + }), + ...(shouldUseRAG ? [this.getRagInstructionMessage()] : []), + ] + + return { + requestMessages, + compiledMessages, + } + } + + private async compileUserMessagePrompt({ + message, + useVaultSearch, + onQueryProgressChange, + }: { + message: ChatUserMessage + useVaultSearch?: boolean + onQueryProgressChange?: (queryProgress: QueryProgressState) => void + }): Promise<{ + promptContent: string + shouldUseRAG: boolean + }> { + if (!this.ragEngine) { + throw new Error('RAG engine not initialized') + } + if (!message.content) { + return { + promptContent: '', + shouldUseRAG: false, + } + } + const query = editorStateToPlainText(message.content) + + useVaultSearch = + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + useVaultSearch || + message.mentionables.some( + (m): m is MentionableVault => m.type === 'vault', + ) + + onQueryProgressChange?.({ + type: 'reading-mentionables', + }) + const files = message.mentionables + .filter((m): m is MentionableFile => m.type === 'file') + .map((m) => m.file) + const folders = message.mentionables + .filter((m): m is MentionableFolder => m.type === 'folder') + .map((m) => m.folder) + const nestedFiles = folders.flatMap((folder) => + getNestedFiles(folder, this.app.vault), + ) + const allFiles = [...files, ...nestedFiles] + const fileContents = await readMultipleTFiles(allFiles, this.app.vault) + + // Count tokens incrementally to avoid long processing times on large content sets + const exceedsTokenThreshold = async () => { + let accTokenCount = 0 + for (const content of fileContents) { + const count = await tokenCount(content) + accTokenCount += count + if (accTokenCount > this.settings.ragOptions.thresholdTokens) { + return true + } + } + return false + } + const shouldUseRAG = useVaultSearch || (await exceedsTokenThreshold()) + + let filePrompt: string + if (shouldUseRAG) { + const results = useVaultSearch + ? await this.ragEngine.processQuery({ + query, + onQueryProgressChange: onQueryProgressChange, + }) // TODO: Add similarity boosting for mentioned files or folders + : await this.ragEngine.processQuery({ + query, + scope: { + files: files.map((f) => f.path), + folders: folders.map((f) => f.path), + }, + onQueryProgressChange: onQueryProgressChange, + }) + filePrompt = `## Potentially Relevant Snippets from the current vault +${results + .map(({ path, content, metadata }) => { + const contentWithLineNumbers = this.addLineNumbersToContent({ + content, + startLine: metadata.startLine, + }) + return `\`\`\`${path}\n${contentWithLineNumbers}\n\`\`\`\n` + }) + .join('')}\n` + } else { + filePrompt = allFiles + .map((file, index) => { + return `\`\`\`${file.path}\n${fileContents[index]}\n\`\`\`\n` + }) + .join('') + } + + const blocks = message.mentionables.filter( + (m): m is MentionableBlock => m.type === 'block', + ) + const blockPrompt = blocks + .map(({ file, content }) => { + return `\`\`\`${file.path}\n${content}\n\`\`\`\n` + }) + .join('') + + return { + promptContent: `${filePrompt}${blockPrompt}\n\n${query}\n\n`, + shouldUseRAG, + } + } + + private getSystemMessage(shouldUseRAG: boolean): RequestMessage { + const systemPrompt = `You are an intelligent assistant to help answer any questions that the user has, particularly about editing and organizing markdown files in Obsidian. + +1. Please keep your response as concise as possible. Avoid being verbose. + +2. When the user is asking for edits to their markdown, please provide a simplified version of the markdown block emphasizing only the changes. Use comments to show where unchanged content has been skipped. Wrap the markdown block with tags. Add filename and language attributes to the tags. For example: + + +{{ edit_1 }} + +{{ edit_2 }} + + +The user has full access to the file, so they prefer seeing only the changes in the markdown. Often this will mean that the start/end of the file will be skipped, but that's okay! Rewrite the entire file only if specifically requested. Always provide a brief explanation of the updates, except when the user specifically asks for just the content. + +3. Do not lie or make up facts. + +4. Respond in the same language as the user's message. + +5. Format your response in markdown. + +6. When writing out new markdown blocks, also wrap them with tags. For example: + +{{ content }} + + +7. When providing markdown blocks for an existing file, add the filename and language attributes to the tags. Restate the relevant section or heading, so the user knows which part of the file you are editing. For example: + +## Section Title +... +{{ content }} +... +` + + const systemPromptRAG = `You are an intelligent assistant to help answer any questions that the user has, particularly about editing and organizing markdown files in Obsidian. You will be given your conversation history with them and potentially relevant blocks of markdown content from the current vault. + +1. Do not lie or make up facts. + +2. Respond in the same language as the user's message. + +3. Format your response in markdown. + +4. When referencing markdown blocks in your answer, keep the following guidelines in mind: + + a. Never include line numbers in the output markdown. + + b. Wrap the markdown block with tags. Include language attribute. For example: + + {{ content }} + + + c. When providing markdown blocks for an existing file, also include the filename attribute to the tags. For example: + + {{ content }} + + + d. When referencing a markdown block the user gives you, only add the startLine and endLine attributes to the tags. Write related content outside of the tags. The content inside the tags will be ignored and replaced with the actual content of the markdown block. For example: + ` + + return { + role: 'system', + content: shouldUseRAG ? systemPromptRAG : systemPrompt, + } + } + + private async getCurrentFileMessage( + currentFile: TFile, + ): Promise { + const fileContent = await readTFileContent(currentFile, this.app.vault) + return { + role: 'user', + content: `# Inputs +## Current File +Here is the file I'm looking at. +\`\`\`${currentFile.path} +${fileContent} +\`\`\`\n\n`, + } + } + + private getRagInstructionMessage(): RequestMessage { + return { + role: 'user', + content: `If you need to reference any of the markdown blocks I gave you, add the startLine and endLine attributes to the tags without any content inside. For example: + + +When writing out new markdown blocks, remember not to include "line_number|" at the beginning of each line.`, + } + } + + private addLineNumbersToContent({ + content, + startLine, + }: { + content: string + startLine: number + }): string { + const lines = content.split('\n') + const linesWithNumbers = lines.map((line, index) => { + return `${startLine + index}|${line}` + }) + return linesWithNumbers.join('\n') + } +} diff --git a/src/utils/ragEngine.ts b/src/utils/ragEngine.ts new file mode 100644 index 0000000..9c43026 --- /dev/null +++ b/src/utils/ragEngine.ts @@ -0,0 +1,115 @@ +import { App } from 'obsidian' + +import { QueryProgressState } from '../components/chat-view/QueryProgress' +import { SelectVector } from '../db/schema' +import { EmbeddingModel } from '../types/embedding' +import { SmartCopilotSettings } from '../types/settings' + +import { getEmbeddingModel } from './embedding' +import { VectorDbManager } from './vector-db/manager' + +export class RAGEngine { + private app: App + private settings: SmartCopilotSettings + private vectorDbManager: VectorDbManager + private embeddingModel: EmbeddingModel | null = null + + constructor(app: App, settings: SmartCopilotSettings) { + this.app = app + this.settings = settings + } + + static async create( + app: App, + settings: SmartCopilotSettings, + ): Promise { + const ragEngine = new RAGEngine(app, settings) + ragEngine.vectorDbManager = await VectorDbManager.create(app) + ragEngine.embeddingModel = getEmbeddingModel(settings.embeddingModel, { + openAIApiKey: settings.openAIApiKey, + }) + return ragEngine + } + + setSettings(settings: SmartCopilotSettings) { + this.settings = settings + this.embeddingModel = getEmbeddingModel(settings.embeddingModel, { + openAIApiKey: settings.openAIApiKey, + }) + } + + // TODO: Implement automatic vault re-indexing when settings are changed. + // Currently, users must manually re-index the vault. + async updateVaultIndex( + options: { reindexAll: boolean } = { + reindexAll: false, + }, + onQueryProgressChange?: (queryProgress: QueryProgressState) => void, + ): Promise { + if (!this.embeddingModel) { + throw new Error('Embedding model is not set') + } + await this.vectorDbManager.updateVaultIndex( + this.embeddingModel, + { + chunkSize: this.settings.ragOptions.chunkSize, + reindexAll: options.reindexAll, + }, + (indexProgress) => { + onQueryProgressChange?.({ + type: 'indexing', + indexProgress, + }) + }, + ) + } + + async processQuery({ + query, + scope, + onQueryProgressChange, + }: { + query: string + scope?: { + files: string[] + folders: string[] + } + onQueryProgressChange?: (queryProgress: QueryProgressState) => void + }): Promise< + (Omit & { + similarity: number + })[] + > { + if (!this.embeddingModel) { + throw new Error('Embedding model is not set') + } + // TODO: Decide the vault index update strategy. + // Current approach: Update on every query. + await this.updateVaultIndex({ reindexAll: false }, onQueryProgressChange) + const queryEmbedding = await this.getQueryEmbedding(query) + onQueryProgressChange?.({ + type: 'querying', + }) + const queryResult = await this.vectorDbManager.performSimilaritySearch( + queryEmbedding, + this.embeddingModel, + { + minSimilarity: this.settings.ragOptions.minSimilarity, + limit: this.settings.ragOptions.limit, + scope, + }, + ) + onQueryProgressChange?.({ + type: 'querying-done', + queryResult, + }) + return queryResult + } + + private async getQueryEmbedding(query: string): Promise { + if (!this.embeddingModel) { + throw new Error('Embedding model is not set') + } + return this.embeddingModel.getEmbedding(query) + } +} diff --git a/src/utils/token.ts b/src/utils/token.ts new file mode 100644 index 0000000..751536a --- /dev/null +++ b/src/utils/token.ts @@ -0,0 +1,11 @@ +import { getEncoding } from 'js-tiktoken' + +// TODO: Replace js-tiktoken with tiktoken library for better performance +// Note: tiktoken uses WebAssembly, requiring esbuild configuration + +// Caution: tokenCount is computationally expensive for large inputs. +// Frequent use, especially on large files, may significantly impact performance. +export async function tokenCount(text: string): Promise { + const encoder = getEncoding('cl100k_base') + return encoder.encode(text).length +} diff --git a/src/utils/vector-db/manager.ts b/src/utils/vector-db/manager.ts new file mode 100644 index 0000000..958ba38 --- /dev/null +++ b/src/utils/vector-db/manager.ts @@ -0,0 +1,225 @@ +import { backOff } from 'exponential-backoff' +import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter' +import { App, TFile, normalizePath } from 'obsidian' +import pLimit from 'p-limit' + +import { IndexProgress } from '../../components/chat-view/QueryProgress' +import { PGLITE_DB_PATH } from '../../constants' +import { InsertVector, SelectVector } from '../../db/schema' +import { EmbeddingModel } from '../../types/embedding' + +import { VectorDbRepository } from './repository' + +export class VectorDbManager { + private app: App + private repository: VectorDbRepository + + constructor(app: App) { + this.app = app + } + + static async create(app: App): Promise { + const manager = new VectorDbManager(app) + const dbPath = normalizePath(PGLITE_DB_PATH) + manager.repository = await VectorDbRepository.create(app, dbPath) + return manager + } + + async performSimilaritySearch( + queryVector: number[], + embeddingModel: EmbeddingModel, + options: { + minSimilarity: number + limit: number + scope?: { + files: string[] + folders: string[] + } + }, + ): Promise< + (Omit & { + similarity: number + })[] + > { + return await this.repository.performSimilaritySearch( + queryVector, + embeddingModel, + options, + ) + } + + async updateVaultIndex( + embeddingModel: EmbeddingModel, + options: { + chunkSize: number + reindexAll?: boolean + }, + updateProgress?: (indexProgress: IndexProgress) => void, + ): Promise { + let filesToIndex: TFile[] + if (options.reindexAll) { + filesToIndex = this.app.vault.getMarkdownFiles() + await this.repository.clearAllVectors(embeddingModel) + } else { + await this.deleteVectorsForDeletedFiles(embeddingModel) + filesToIndex = await this.getFilesToIndex(embeddingModel) + await this.repository.deleteVectorsForMultipleFiles( + filesToIndex.map((file) => file.path), + embeddingModel, + ) + } + + if (filesToIndex.length === 0) { + return + } + + const textSplitter = RecursiveCharacterTextSplitter.fromLanguage( + 'markdown', + { + chunkSize: options.chunkSize, + // TODO: Use token-based chunking after migrating to WebAssembly-based tiktoken + // Current token counting method is too slow for practical use + // lengthFunction: async (text) => { + // return await tokenCount(text) + // }, + }, + ) + + const contentChunks: InsertVector[] = ( + await Promise.all( + filesToIndex.map(async (file) => { + const fileContent = await this.app.vault.cachedRead(file) + const fileDocuments = await textSplitter.createDocuments([ + fileContent, + ]) + return fileDocuments.map((chunk): InsertVector => { + return { + path: file.path, + mtime: file.stat.mtime, + content: chunk.pageContent, + metadata: { + startLine: chunk.metadata.loc.lines.from as number, + endLine: chunk.metadata.loc.lines.to as number, + }, + } + }) + }), + ) + ).flat() + + updateProgress?.({ + completedChunks: 0, + totalChunks: contentChunks.length, + totalFiles: filesToIndex.length, + }) + + const embeddingProgress = { completed: 0, inserted: 0 } + const embeddingChunks: InsertVector[] = [] + const batchSize = 100 + const limit = pLimit(50) + const tasks = contentChunks.map((chunk) => + limit(async () => { + await backOff( + async () => { + const embedding = await embeddingModel.getEmbedding(chunk.content) + const embeddedChunk = { + path: chunk.path, + mtime: chunk.mtime, + content: chunk.content, + embedding, + metadata: chunk.metadata, + } + embeddingChunks.push(embeddedChunk) + embeddingProgress.completed++ + updateProgress?.({ + completedChunks: embeddingProgress.completed, + totalChunks: contentChunks.length, + totalFiles: filesToIndex.length, + }) + + // Insert vectors in batches + if ( + embeddingChunks.length >= + embeddingProgress.inserted + batchSize || + embeddingChunks.length === contentChunks.length + ) { + await this.repository.insertVectors( + embeddingChunks.slice( + embeddingProgress.inserted, + embeddingProgress.inserted + batchSize, + ), + embeddingModel, + ) + embeddingProgress.inserted += batchSize + } + }, + { + numOfAttempts: 5, + startingDelay: 1000, + timeMultiple: 1.5, + jitter: 'full', + retry: (error) => { + console.error(error) + const isRateLimitError = + error.status === 429 && + error.message.toLowerCase().includes('rate limit') + return !!isRateLimitError // retry only for rate limit errors + }, + }, + ) + }), + ) + + try { + await Promise.all(tasks) + } catch (error) { + console.error('Error embedding chunks:', error) + throw error + } finally { + await this.repository.save() + } + } + + private async deleteVectorsForDeletedFiles(embeddingModel: EmbeddingModel) { + const indexedFilePaths = + await this.repository.getIndexedFilePaths(embeddingModel) + for (const filePath of indexedFilePaths) { + if (!this.app.vault.getAbstractFileByPath(filePath)) { + await this.repository.deleteVectorsForMultipleFiles( + [filePath], + embeddingModel, + ) + } + } + } + + private async getFilesToIndex( + embeddingModel: EmbeddingModel, + ): Promise { + const markdownFiles = this.app.vault.getMarkdownFiles() + const filesToIndex = await Promise.all( + markdownFiles.map(async (file) => { + const fileChunks = await this.repository.getVectorsByFilePath( + file.path, + embeddingModel, + ) + if (fileChunks.length === 0) { + // File is not indexed, so we need to index it + const fileContent = await this.app.vault.cachedRead(file) + if (fileContent.length === 0) { + // Ignore empty files + return null + } + return file + } + const outOfDate = file.stat.mtime > fileChunks[0].mtime + if (outOfDate) { + // File has changed, so we need to re-index it + return file + } + return null + }), + ).then((files) => files.filter(Boolean) as TFile[]) + return filesToIndex + } +} diff --git a/src/utils/vector-db/repository.ts b/src/utils/vector-db/repository.ts new file mode 100644 index 0000000..a67c461 --- /dev/null +++ b/src/utils/vector-db/repository.ts @@ -0,0 +1,270 @@ +import { PGlite } from '@electric-sql/pglite' +import { + SQL, + and, + cosineDistance, + desc, + eq, + getTableColumns, + gt, + inArray, + like, + or, + sql, +} from 'drizzle-orm' +import { PgliteDatabase, drizzle } from 'drizzle-orm/pglite' +import { App } from 'obsidian' + +import migrations from '../../db/migrations.json' +import { InsertVector, SelectVector, vectorTables } from '../../db/schema' + +export class VectorDbRepository { + private app: App + private pgClient: PGlite | null = null + private db: PgliteDatabase | null = null + private dbPath: string + + constructor(app: App, dbPath: string) { + this.app = app + this.dbPath = dbPath + } + + static async create(app: App, dbPath: string): Promise { + const repo = new VectorDbRepository(app, dbPath) + repo.db = await repo.loadExistingDatabase() + if (!repo.db) { + repo.db = await repo.createNewDatabase() + } + await repo.migrateDatabase() + await repo.save() + console.log('Smart composer database initialized.') + return repo + } + + async getIndexedFilePaths(embeddingModel: { + name: string + }): Promise { + if (!this.db) { + throw new Error('Database not initialized') + } + const vectors = vectorTables[embeddingModel.name] + const indexedFiles = await this.db + .select({ + path: vectors.path, + }) + .from(vectors) + return indexedFiles.map((row) => row.path) + } + + async getVectorsByFilePath( + filePath: string, + embeddingModel: { name: string }, + ): Promise { + if (!this.db) { + throw new Error('Database not initialized') + } + const vectors = vectorTables[embeddingModel.name] + const fileVectors = await this.db + .select() + .from(vectors) + .where(eq(vectors.path, filePath)) + return fileVectors + } + + async deleteVectorsForSingleFile( + filePath: string, + embeddingModel: { name: string }, + ): Promise { + if (!this.db) { + throw new Error('Database not initialized') + } + const vectors = vectorTables[embeddingModel.name] + await this.db.delete(vectors).where(eq(vectors.path, filePath)) + } + + async deleteVectorsForMultipleFiles( + filePaths: string[], + embeddingModel: { name: string }, + ): Promise { + if (!this.db) { + throw new Error('Database not initialized') + } + const vectors = vectorTables[embeddingModel.name] + await this.db.delete(vectors).where(inArray(vectors.path, filePaths)) + } + + async clearAllVectors(embeddingModel: { name: string }): Promise { + if (!this.db) { + throw new Error('Database not initialized') + } + const vectors = vectorTables[embeddingModel.name] + await this.db.delete(vectors) + } + + async insertVectors( + data: InsertVector[], + embeddingModel: { name: string }, + ): Promise { + if (!this.db) { + throw new Error('Database not initialized') + } + const vectors = vectorTables[embeddingModel.name] + await this.db.insert(vectors).values(data) + } + + async performSimilaritySearch( + queryVector: number[], + embeddingModel: { name: string }, + options: { + minSimilarity: number + limit: number + scope?: { + files: string[] + folders: string[] + } + }, + ): Promise< + (Omit & { + similarity: number + })[] + > { + if (!this.db) { + throw new Error('Database not initialized') + } + const vectors = vectorTables[embeddingModel.name] + + const similarity = sql`1 - (${cosineDistance(vectors.embedding, queryVector)})` + const similarityCondition = gt(similarity, options.minSimilarity) + + const getScopeCondition = (): SQL | undefined => { + if (!options.scope) { + return undefined + } + const conditions: (SQL | undefined)[] = [] + if (options.scope.files.length > 0) { + conditions.push(inArray(vectors.path, options.scope.files)) + } + if (options.scope.folders.length > 0) { + conditions.push( + or( + ...options.scope.folders.map((folder) => + like(vectors.path, `${folder}/%`), + ), + ), + ) + } + if (conditions.length === 0) { + return undefined + } + return or(...conditions) + } + const scopeCondition = getScopeCondition() + + const similaritySearchResult = await this.db + .select({ + ...(() => { + const { embedding, ...rest } = getTableColumns(vectors) + return rest + })(), + similarity, + }) + .from(vectors) + .where(and(similarityCondition, scopeCondition)) + .orderBy((t) => desc(t.similarity)) + .limit(options.limit) + + return similaritySearchResult + } + + async save(): Promise { + if (!this.pgClient) { + return + } + try { + const blob: Blob = await this.pgClient.dumpDataDir('gzip') + await this.app.vault.adapter.writeBinary( + this.dbPath, + Buffer.from(await blob.arrayBuffer()), + ) + } catch (error) { + console.error('Error saving database:', error) + } + } + + private async createNewDatabase() { + const { fsBundle, wasmModule, vectorExtensionBundlePath } = + await this.loadPGliteResources() + this.pgClient = await PGlite.create({ + fsBundle: fsBundle, + wasmModule: wasmModule, + extensions: { + vector: vectorExtensionBundlePath, + }, + }) + const db = drizzle(this.pgClient) + return db + } + + private async loadExistingDatabase(): Promise { + try { + const fileBuffer = await this.app.vault.adapter.readBinary(this.dbPath) + const fileBlob = new Blob([fileBuffer], { type: 'application/x-gzip' }) + const { fsBundle, wasmModule, vectorExtensionBundlePath } = + await this.loadPGliteResources() + this.pgClient = await PGlite.create({ + loadDataDir: fileBlob, + fsBundle: fsBundle, + wasmModule: wasmModule, + extensions: { + vector: vectorExtensionBundlePath, + }, + }) + return drizzle(this.pgClient) + } catch (error) { + console.error('Error loading database:', error) + return null + } + } + + private async migrateDatabase(): Promise { + // Workaround for running Drizzle migrations in a browser environment + // This method uses an undocumented API to perform migrations + // See: https://github.com/drizzle-team/drizzle-orm/discussions/2532#discussioncomment-10780523 + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await this.db.dialect.migrate(migrations, this.db.session, { + migrationsTable: 'drizzle_migrations', + }) + } + + // TODO: This function is a temporary workaround chosen due to the difficulty of bundling postgres.wasm and postgres.data from node_modules into a single JS file. The ultimate goal is to bundle everything into one JS file in the future. + private async loadPGliteResources(): Promise<{ + fsBundle: Blob + wasmModule: WebAssembly.Module + vectorExtensionBundlePath: URL + }> { + const [fsBundleResponse, wasmResponse] = await Promise.all([ + fetch('https://unpkg.com/@electric-sql/pglite/dist/postgres.data'), + fetch('https://unpkg.com/@electric-sql/pglite/dist/postgres.wasm'), + ]) + + if (!fsBundleResponse.ok || !wasmResponse.ok) { + throw new Error('Failed to fetch PGlite resources') + } + + const [fsBundleArrayBuffer, wasmArrayBuffer] = await Promise.all([ + fsBundleResponse.arrayBuffer(), + wasmResponse.arrayBuffer(), + ]) + + const fsBundle = new Blob([fsBundleArrayBuffer], { + type: 'application/octet-stream', + }) + const wasmModule = await WebAssembly.compile(wasmArrayBuffer) + const vectorExtensionBundlePath = new URL( + 'https://unpkg.com/@electric-sql/pglite/dist/vector.tar.gz', + ) + + return { fsBundle, wasmModule, vectorExtensionBundlePath } + } +} diff --git a/styles.css b/styles.css index abce5a2..4bf51ba 100644 --- a/styles.css +++ b/styles.css @@ -209,6 +209,41 @@ button:not(.clickable-icon).smtcmp-chat-list-dropdown { padding-bottom: var(--size-4-1); } +.smtcmp-chat-user-input-controls { + display: flex; + flex-direction: row; + gap: var(--size-4-1); + justify-content: space-between; + align-items: center; + height: var(--size-4-4); +} + +.smtcmp-chat-user-input-controls .smtcmp-chat-user-input-vault-search-button { + display: flex; + align-items: center; + gap: var(--size-2-3); + font-size: var(--font-smallest); + color: var(--text-muted); + background-color: transparent; + border: none; + box-shadow: none; + padding: 0 var(--size-2-1); + border-radius: var(--radius-s); + height: var(--size-4-4); + cursor: pointer; + transition: color 0.15s ease-in-out; + + &:hover { + color: var(--text-normal); + } + + .smtcmp-chat-user-input-vault-search-button-icons { + display: flex; + align-items: center; + gap: 0.5px; + } +} + .smtcmp-chat-user-input-file-badge { display: flex; align-items: center; @@ -235,6 +270,11 @@ button:not(.clickable-icon).smtcmp-chat-list-dropdown { gap: var(--size-2-1); flex-grow: 1; overflow: hidden; + align-items: center; +} + +.smtcmp-chat-user-input-file-badge-name-icon { + color: var(--text-muted); } .smtcmp-chat-user-input-file-badge-name span { @@ -306,7 +346,7 @@ button:not(.clickable-icon).smtcmp-chat-list-dropdown { .smtcmp-popover ul li { margin: 0; min-width: 180px; - font-size: 14px; + font-size: var(--font-ui-smaller); outline: none; cursor: pointer; border-radius: 0; @@ -337,8 +377,8 @@ button:not(.clickable-icon).smtcmp-chat-list-dropdown { border: 0; min-height: 20px; align-items: center; - justify-content: space-between; - gap: 2rem; + gap: var(--size-4-1); + align-items: start; } .smtcmp-chat-list-dropdown-empty { @@ -358,17 +398,18 @@ button:not(.clickable-icon).smtcmp-chat-list-dropdown { background-color: var(--background-modifier-hover); } -.smtcmp-popover li .icon { +.smtcmp-popover-item-icon { display: flex; - width: 20px; - height: 20px; user-select: none; - margin-right: 8px; line-height: 16px; background-size: contain; background-repeat: no-repeat; background-position: center; - width: 250px; + height: 14px; + padding-top: 1px; + align-items: center; + color: var(--text-muted); + min-width: fit-content; } .smtcmp-popover li:hover { @@ -421,6 +462,7 @@ button:not(.clickable-icon).smtcmp-chat-list-dropdown { border-bottom: 1px solid var(--background-modifier-border); background-color: var(--background-primary); border-radius: var(--radius-s) var(--radius-s) 0 0; + height: calc(var(--size-4-8) - var(--size-4-1)); } .smtcmp-code-block.has-filename:hover .smtcmp-code-block-header { @@ -452,6 +494,7 @@ button:not(.clickable-icon).smtcmp-chat-list-dropdown { gap: 0; overflow: hidden; min-width: fit-content; + height: 100%; } .smtcmp-code-block.has-filename .smtcmp-code-block-header-button button { @@ -461,6 +504,8 @@ button:not(.clickable-icon).smtcmp-chat-list-dropdown { border-radius: 0; background-color: var(--background-primary); font-size: var(--font-medium); + height: 100%; + cursor: pointer; &:hover { background-color: var(--background-modifier-hover); @@ -622,3 +667,58 @@ button.smtcmp-chat-input-model-select { color: var(--text-normal); } } + +.smtcmp-query-progress { + font-size: var(--font-ui-smaller); + color: var(--text-muted); +} + +.smtcmp-query-progress-detail { + font-size: var(--font-smallest); + color: var(--text-faint); +} + +.smtcmp-dot-loader { + display: inline-block; + text-align: left; +} + +.smtcmp-dot-loader::after { + content: '...'; + animation: dotFade 0.75s steps(4, end) infinite; + color: var(--text-muted); +} + +@keyframes dotFade { + 0%, + 100% { + content: ''; + } + 25% { + content: '.'; + } + 50% { + content: '..'; + } + 75% { + content: '...'; + } +} + +.smtcmp-tooltip-content { + background-color: var(--background-primary); + border: 1px solid var(--background-modifier-border); + border-radius: var(--radius-s); + padding: var(--size-4-1) var(--size-4-2); + font-size: var(--font-smallest); + animation: fadeIn 0.1s ease-in-out; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} diff --git a/tsconfig.json b/tsconfig.json index 990eb5a..d42f94b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,8 @@ "lib": ["DOM", "ES5", "ES6", "ES7"], "jsx": "react-jsx", "allowSyntheticDefaultImports": true, - "skipLibCheck": true + "skipLibCheck": true, + "resolveJsonModule": true }, - "include": ["src/**/*.ts", "src/**/*.tsx"] + "include": ["src/**/*.ts", "src/**/*.tsx", "drizzle.config.ts", "__mocks__"] }