diff options
| author | yxshv <[email protected]> | 2024-04-14 00:32:04 +0530 |
|---|---|---|
| committer | yxshv <[email protected]> | 2024-04-14 00:32:04 +0530 |
| commit | e0461696fc9732c240f48d5be6e824a1d5fced44 (patch) | |
| tree | 92e3e91099119db07398b1419f37d144c1d78ccc /apps | |
| parent | fix relaod bug (diff) | |
| parent | fix build fail (diff) | |
| download | supermemory-e0461696fc9732c240f48d5be6e824a1d5fced44.tar.xz supermemory-e0461696fc9732c240f48d5be6e824a1d5fced44.zip | |
Merge branch 'main' of https://github.com/dhravya/supermemory
Diffstat (limited to 'apps')
27 files changed, 1075 insertions, 3597 deletions
diff --git a/apps/cf-ai-backend/src/env.d.ts b/apps/cf-ai-backend/src/env.d.ts index e760cba3..e4ae9a1b 100644 --- a/apps/cf-ai-backend/src/env.d.ts +++ b/apps/cf-ai-backend/src/env.d.ts @@ -6,6 +6,7 @@ interface Env { GOOGLE_AI_API_KEY: string; MY_QUEUE: Queue<TweetData[]>; KV: KVNamespace; + MYBROWSER: BrowserWorker; } interface TweetData { diff --git a/apps/cf-ai-backend/src/routes.ts b/apps/cf-ai-backend/src/routes.ts index 0349c397..ff1218e8 100644 --- a/apps/cf-ai-backend/src/routes.ts +++ b/apps/cf-ai-backend/src/routes.ts @@ -4,6 +4,7 @@ import * as apiQuery from './routes/query'; import * as apiAsk from './routes/ask'; import * as apiChat from './routes/chat'; import * as apiBatchUploadTweets from './routes/batchUploadTweets'; +import * as apiGetPageContent from './routes/getPageContent'; import { OpenAIEmbeddings } from './OpenAIEmbedder'; import { GenerativeModel } from '@google/generative-ai'; import { Request } from '@cloudflare/workers-types'; @@ -28,6 +29,7 @@ routeMap.set('/ask', apiAsk); routeMap.set('/chat', apiChat); routeMap.set('/batchUploadTweets', apiBatchUploadTweets); +routeMap.set('/getPageContent', apiGetPageContent); // Add more route mappings as needed // routeMap.set('/api/otherRoute', { ... }); diff --git a/apps/cf-ai-backend/src/routes/chat.ts b/apps/cf-ai-backend/src/routes/chat.ts index 7603667f..4dfcde5d 100644 --- a/apps/cf-ai-backend/src/routes/chat.ts +++ b/apps/cf-ai-backend/src/routes/chat.ts @@ -2,6 +2,8 @@ import { Content, GenerativeModel } from '@google/generative-ai'; import { OpenAIEmbeddings } from '../OpenAIEmbedder'; import { CloudflareVectorizeStore } from '@langchain/cloudflare'; import { Request } from '@cloudflare/workers-types'; +import { AiTextGenerationOutput } from '@cloudflare/ai/dist/ai/tasks/text-generation'; +import { Ai } from '@cloudflare/ai'; export async function POST(request: Request, _: CloudflareVectorizeStore, embeddings: OpenAIEmbeddings, model: GenerativeModel, env?: Env) { const queryparams = new URL(request.url).searchParams; @@ -112,28 +114,40 @@ export async function POST(request: Request, _: CloudflareVectorizeStore, embedd }, ] as Content[]; - const chat = model.startChat({ - history: [...defaultHistory, ...(body.chatHistory ?? [])], - }); + // const chat = model.startChat({ + // history: [...defaultHistory, ...(body.chatHistory ?? [])], + // }); const prompt = `Context:\n${preparedContext ?? ''}\n\nQuestion: ${query}\nAnswer:`; - const output = await chat.sendMessageStream(prompt); - - const response = new Response( - new ReadableStream({ - async start(controller) { - const converter = new TextEncoder(); - for await (const chunk of output.stream) { - const chunkText = await chunk.text(); - const encodedChunk = converter.encode('data: ' + JSON.stringify({ response: chunkText }) + '\n\n'); - controller.enqueue(encodedChunk); - } - const doneChunk = converter.encode('data: [DONE]'); - controller.enqueue(doneChunk); - controller.close(); - }, - }), - ); - return response; + // const output = await chat.sendMessageStream(prompt); + + // const response = new Response( + // new ReadableStream({ + // async start(controller) { + // const converter = new TextEncoder(); + // for await (const chunk of output.stream) { + // const chunkText = await chunk.text(); + // const encodedChunk = converter.encode('data: ' + JSON.stringify({ response: chunkText }) + '\n\n'); + // controller.enqueue(encodedChunk); + // } + // const doneChunk = converter.encode('data: [DONE]'); + // controller.enqueue(doneChunk); + // controller.close(); + // }, + // }), + // ); + // return response; + const ai = new Ai(env?.AI); + // @ts-ignore + const output: AiTextGenerationOutput = (await ai.run('@hf/mistralai/mistral-7b-instruct-v0.2', { + prompt, + stream: true, + })) as ReadableStream; + + return new Response(output, { + headers: { + 'content-type': 'text/event-stream', + }, + }); } diff --git a/apps/cf-ai-backend/src/routes/getPageContent.ts b/apps/cf-ai-backend/src/routes/getPageContent.ts new file mode 100644 index 00000000..d380657e --- /dev/null +++ b/apps/cf-ai-backend/src/routes/getPageContent.ts @@ -0,0 +1,31 @@ +import { GenerativeModel } from '@google/generative-ai'; +import { OpenAIEmbeddings } from '../OpenAIEmbedder'; +import { CloudflareVectorizeStore } from '@langchain/cloudflare'; +import { Request } from '@cloudflare/workers-types'; +import puppeteer from '@cloudflare/puppeteer'; + +export async function GET(request: Request, _: CloudflareVectorizeStore, embeddings: OpenAIEmbeddings, model: GenerativeModel, env?: Env) { + const { searchParams } = new URL(request.url); + let url = searchParams.get('url'); + let img: Buffer; + if (url) { + url = new URL(url).toString(); // normalize + const browser = await puppeteer.launch(env?.MYBROWSER); + const page = await browser.newPage(); + await page.goto(url); + + // Innertext of content + const contentElement = await page.$('body'); + const content = await page.evaluate((element) => element.innerText, contentElement); + + await browser.close(); + + return new Response(content, { + headers: { + 'content-type': 'text/html', + }, + }); + } else { + return new Response('Please add an ?url=https://example.com/ parameter'); + } +} diff --git a/apps/cf-ai-backend/wrangler.toml b/apps/cf-ai-backend/wrangler.toml index e1fc018a..832d9e0d 100644 --- a/apps/cf-ai-backend/wrangler.toml +++ b/apps/cf-ai-backend/wrangler.toml @@ -1,6 +1,7 @@ name = "cf-ai-backend" main = "src/index.ts" compatibility_date = "2024-02-23" +compatibility_flags = ['nodejs_compat'] [[vectorize]] binding = "VECTORIZE_INDEX" @@ -19,6 +20,13 @@ binding = "AI" [[kv_namespaces]] binding = "KV" id = "37a90353da63401e84e20e71165531d0" +preview_id = "c58b6202814f4224acea97627d0c18aa" + +[browser] +binding = "MYBROWSER" + +[placement] +mode = "smart" # Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) # Note: Use secrets to store sensitive data. diff --git a/apps/extension/manifest.json b/apps/extension/manifest.json index 561ca8fe..5cf05298 100644 --- a/apps/extension/manifest.json +++ b/apps/extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "SuperMemory", - "version": "1.0.0", + "version": "2.0.0", "action": { "default_popup": "index.html" }, diff --git a/apps/extension/pnpm-lock.yaml b/apps/extension/pnpm-lock.yaml deleted file mode 100644 index ad6c187d..00000000 --- a/apps/extension/pnpm-lock.yaml +++ /dev/null @@ -1,2713 +0,0 @@ -lockfileVersion: '6.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -dependencies: - '@radix-ui/react-dialog': - specifier: ^1.0.5 - version: 1.0.5(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-dropdown-menu': - specifier: ^2.0.6 - version: 2.0.6(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-popover': - specifier: ^1.0.7 - version: 1.0.7(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-tooltip': - specifier: ^1.0.7 - version: 1.0.7(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - cmdk: - specifier: ^1.0.0 - version: 1.0.0(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0([email protected]) - -devDependencies: - '@types/node': - specifier: ^20.11.22 - version: 20.12.7 - '@types/react': - specifier: ^18.2.56 - version: 18.2.75 - '@types/react-dom': - specifier: ^18.2.19 - version: 18.2.24 - '@typescript-eslint/eslint-plugin': - specifier: ^7.0.2 - '@typescript-eslint/parser': - specifier: ^7.0.2 - version: 7.6.0([email protected])([email protected]) - '@vitejs/plugin-react': - specifier: ^4.2.1 - version: 4.2.1([email protected]) - eslint: - specifier: ^8.56.0 - version: 8.57.0 - eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0([email protected]) - eslint-plugin-react-refresh: - specifier: ^0.4.5 - version: 0.4.6([email protected]) - typescript: - specifier: ^5.2.2 - version: 5.4.5 - vite: - specifier: ^5.1.4 - version: 5.2.8(@types/[email protected]) - -packages: - - /@aashutoshrathi/[email protected]: - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} - dev: true - - /@ampproject/[email protected]: - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.24.2 - picocolors: 1.0.0 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.4 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.23.3(@babel/[email protected]) - '@babel/helpers': 7.24.4 - '@babel/parser': 7.24.4 - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.1 - '@babel/types': 7.24.0 - convert-source-map: 2.0.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.24.0 - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 2.5.2 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/compat-data': 7.24.4 - '@babel/helper-validator-option': 7.23.5 - browserslist: 4.23.0 - lru-cache: 5.1.1 - semver: 6.3.1 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.24.0 - '@babel/types': 7.24.0 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.24.0 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.24.0 - dev: true - - /@babel/[email protected](@babel/[email protected]): - resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.24.4 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.20 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.24.0 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.24.0 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.1 - '@babel/types': 7.24.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 - picocolors: 1.0.0 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.24.0 - dev: true - - /@babel/[email protected](@babel/[email protected]): - resolution: {integrity: sha512-kDJgnPujTmAZ/9q2CN4m2/lRsUUPDvsG3+tSHWUJIzMGTt5U/b/fwWd3RO3n+5mjLrsBrVa5eKFRVSQbi3dF1w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 - dev: true - - /@babel/[email protected](@babel/[email protected]): - resolution: {integrity: sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.1 - dev: false - - /@babel/[email protected]: - resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.24.2 - '@babel/parser': 7.24.4 - '@babel/types': 7.24.0 - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.4 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.24.4 - '@babel/types': 7.24.0 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/[email protected]: - resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.24.1 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 - dev: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/[email protected]: - resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@eslint-community/[email protected]([email protected]): - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 8.57.0 - eslint-visitor-keys: 3.4.3 - dev: true - - /@eslint-community/[email protected]: - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true - - /@eslint/[email protected]: - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@eslint/[email protected]: - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /@floating-ui/[email protected]: - resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} - dependencies: - '@floating-ui/utils': 0.2.1 - dev: false - - /@floating-ui/[email protected]: - resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==} - dependencies: - '@floating-ui/core': 1.6.0 - '@floating-ui/utils': 0.2.1 - dev: false - - resolution: {integrity: sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' - dependencies: - '@floating-ui/dom': 1.6.3 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - /@floating-ui/[email protected]: - resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} - dev: false - - /@humanwhocodes/[email protected]: - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@humanwhocodes/[email protected]: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - dev: true - - /@humanwhocodes/[email protected]: - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - dev: true - - /@jridgewell/[email protected]: - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.25 - dev: true - - /@jridgewell/[email protected]: - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/[email protected]: - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/[email protected]: - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true - - /@jridgewell/[email protected]: - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - - /@nodelib/[email protected]: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - dev: true - - /@nodelib/[email protected]: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - dev: true - - /@nodelib/[email protected]: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 - dev: true - - /@radix-ui/[email protected]: - resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} - dependencies: - '@babel/runtime': 7.24.4 - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-context': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-slot': 1.0.2(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-context': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-focus-guards': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-focus-scope': 1.0.4(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-id': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-portal': 1.0.4(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-presence': 1.0.1(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-slot': 1.0.2(@types/[email protected])([email protected]) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - aria-hidden: 1.2.4 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - react-remove-scroll: 2.5.5(@types/[email protected])([email protected]) - dev: false - - resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-use-escape-keydown': 1.0.3(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-context': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-id': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-menu': 2.0.6(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-context': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-direction': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-focus-guards': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-focus-scope': 1.0.4(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-id': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-popper': 1.1.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-portal': 1.0.4(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-presence': 1.0.1(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-roving-focus': 1.0.4(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-slot': 1.0.2(@types/[email protected])([email protected]) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - aria-hidden: 1.2.4 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - react-remove-scroll: 2.5.5(@types/[email protected])([email protected]) - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-context': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-focus-guards': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-focus-scope': 1.0.4(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-id': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-popper': 1.1.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-portal': 1.0.4(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-presence': 1.0.1(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-slot': 1.0.2(@types/[email protected])([email protected]) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - aria-hidden: 1.2.4 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - react-remove-scroll: 2.5.5(@types/[email protected])([email protected]) - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@floating-ui/react-dom': 2.0.8([email protected])([email protected]) - '@radix-ui/react-arrow': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-context': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-use-rect': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-use-size': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/rect': 1.0.1 - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-slot': 1.0.2(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-context': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-direction': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-id': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-context': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-id': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-popper': 1.1.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-portal': 1.0.4(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-presence': 1.0.1(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-slot': 1.0.2(@types/[email protected])([email protected]) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/[email protected])([email protected]) - '@radix-ui/react-visually-hidden': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/rect': 1.0.1 - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/[email protected])([email protected]) - '@types/react': 18.2.75 - react: 18.2.0 - dev: false - - /@radix-ui/[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.4 - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@types/react': 18.2.75 - '@types/react-dom': 18.2.24 - react: 18.2.0 - react-dom: 18.2.0([email protected]) - dev: false - - /@radix-ui/[email protected]: - resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==} - dependencies: - '@babel/runtime': 7.24.4 - dev: false - - /@rollup/[email protected]: - resolution: {integrity: sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==} - cpu: [ppc64le] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@rollup/[email protected]: - resolution: {integrity: sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@types/[email protected]: - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - dependencies: - '@babel/parser': 7.24.4 - '@babel/types': 7.24.0 - '@types/babel__generator': 7.6.8 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.5 - dev: true - - /@types/[email protected]: - resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} - dependencies: - '@babel/types': 7.24.0 - dev: true - - /@types/[email protected]: - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - dependencies: - '@babel/parser': 7.24.4 - '@babel/types': 7.24.0 - dev: true - - /@types/[email protected]: - resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} - dependencies: - '@babel/types': 7.24.0 - dev: true - - /@types/[email protected]: - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - dev: true - - /@types/[email protected]: - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - dev: true - - /@types/[email protected]: - resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} - dependencies: - undici-types: 5.26.5 - dev: true - - /@types/[email protected]: - resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} - - /@types/[email protected]: - resolution: {integrity: sha512-cN6upcKd8zkGy4HU9F1+/s98Hrp6D4MOcippK4PoE8OZRngohHZpbJn1GsaDLz87MqvHNoT13nHvNqM9ocRHZg==} - dependencies: - '@types/react': 18.2.75 - - /@types/[email protected]: - resolution: {integrity: sha512-+DNnF7yc5y0bHkBTiLKqXFe+L4B3nvOphiMY3tuA5X10esmjqk7smyBZzbGTy2vsiy/Bnzj8yFIBL8xhRacoOg==} - dependencies: - '@types/prop-types': 15.7.12 - csstype: 3.1.3 - - /@types/[email protected]: - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - dev: true - - /@typescript-eslint/[email protected](@typescript-eslint/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-gKmTNwZnblUdnTIJu3e9kmeRRzV2j1a/LUO27KNNAnIC5zjy1aSvXSRp4rVNlmAoHlQ7HzX42NbKpcSr4jF80A==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.6.0([email protected])([email protected]) - '@typescript-eslint/scope-manager': 7.6.0 - '@typescript-eslint/type-utils': 7.6.0([email protected])([email protected]) - '@typescript-eslint/utils': 7.6.0([email protected])([email protected]) - '@typescript-eslint/visitor-keys': 7.6.0 - debug: 4.3.4 - eslint: 8.57.0 - graphemer: 1.4.0 - ignore: 5.3.1 - natural-compare: 1.4.0 - semver: 7.6.0 - ts-api-utils: 1.3.0([email protected]) - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - dev: true - - resolution: {integrity: sha512-usPMPHcwX3ZoPWnBnhhorc14NJw9J4HpSXQX4urF2TPKG0au0XhJoZyX62fmvdHONUkmyUe74Hzm1//XA+BoYg==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 7.6.0 - '@typescript-eslint/types': 7.6.0 - '@typescript-eslint/typescript-estree': 7.6.0([email protected]) - '@typescript-eslint/visitor-keys': 7.6.0 - debug: 4.3.4 - eslint: 8.57.0 - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/[email protected]: - resolution: {integrity: sha512-ngttyfExA5PsHSx0rdFgnADMYQi+Zkeiv4/ZxGYUWd0nLs63Ha0ksmp8VMxAIC0wtCFxMos7Lt3PszJssG/E6w==} - engines: {node: ^18.18.0 || >=20.0.0} - dependencies: - '@typescript-eslint/types': 7.6.0 - '@typescript-eslint/visitor-keys': 7.6.0 - dev: true - - resolution: {integrity: sha512-NxAfqAPNLG6LTmy7uZgpK8KcuiS2NZD/HlThPXQRGwz6u7MDBWRVliEEl1Gj6U7++kVJTpehkhZzCJLMK66Scw==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 7.6.0([email protected]) - '@typescript-eslint/utils': 7.6.0([email protected])([email protected]) - debug: 4.3.4 - eslint: 8.57.0 - ts-api-utils: 1.3.0([email protected]) - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/[email protected]: - resolution: {integrity: sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==} - engines: {node: ^18.18.0 || >=20.0.0} - dev: true - - /@typescript-eslint/[email protected]([email protected]): - resolution: {integrity: sha512-+7Y/GP9VuYibecrCQWSKgl3GvUM5cILRttpWtnAu8GNL9j11e4tbuGZmZjJ8ejnKYyBRb2ddGQ3rEFCq3QjMJw==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 7.6.0 - '@typescript-eslint/visitor-keys': 7.6.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.4 - semver: 7.6.0 - ts-api-utils: 1.3.0([email protected]) - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - dev: true - - resolution: {integrity: sha512-x54gaSsRRI+Nwz59TXpCsr6harB98qjXYzsRxGqvA5Ue3kQH+FxS7FYU81g/omn22ML2pZJkisy6Q+ElK8pBCA==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0([email protected]) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 7.6.0 - '@typescript-eslint/types': 7.6.0 - '@typescript-eslint/typescript-estree': 7.6.0([email protected]) - eslint: 8.57.0 - semver: 7.6.0 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/[email protected]: - resolution: {integrity: sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==} - engines: {node: ^18.18.0 || >=20.0.0} - dependencies: - '@typescript-eslint/types': 7.6.0 - eslint-visitor-keys: 3.4.3 - dev: true - - /@ungap/[email protected]: - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - dev: true - - /@vitejs/[email protected]([email protected]): - resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - vite: ^4.2.0 || ^5.0.0 - dependencies: - '@babel/core': 7.24.4 - '@babel/plugin-transform-react-jsx-self': 7.24.1(@babel/[email protected]) - '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/[email protected]) - '@types/babel__core': 7.20.5 - react-refresh: 0.14.0 - vite: 5.2.8(@types/[email protected]) - transitivePeerDependencies: - - supports-color - dev: true - - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.11.3 - dev: true - - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - dev: true - - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: true - - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - dev: true - - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - dev: true - - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true - - resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} - engines: {node: '>=10'} - dependencies: - tslib: 2.6.2 - dev: false - - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - dev: true - - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - dev: true - - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - dev: true - - resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001608 - electron-to-chromium: 1.4.733 - node-releases: 2.0.14 - update-browserslist-db: 1.0.13([email protected]) - dev: true - - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - dev: true - - resolution: {integrity: sha512-cjUJTQkk9fQlJR2s4HMuPMvTiRggl0rAVMtthQuyOlDWuqHXqN8azLq+pi8B2TjwKJ32diHjUqRIKeFX4z1FoA==} - dev: true - - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - dev: true - - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - - /[email protected](@types/[email protected])(@types/[email protected])([email protected])([email protected]): - resolution: {integrity: sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - dependencies: - '@radix-ui/react-dialog': 1.0.5(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - '@radix-ui/react-primitive': 1.0.3(@types/[email protected])(@types/[email protected])([email protected])([email protected]) - react: 18.2.0 - react-dom: 18.2.0([email protected]) - transitivePeerDependencies: - - '@types/react' - - '@types/react-dom' - dev: false - - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - dev: true - - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - dev: true - - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true - - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true - - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true - - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true - - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: true - - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true - - resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - dev: false - - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: true - - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dependencies: - esutils: 2.0.3 - dev: true - - resolution: {integrity: sha512-gUI9nhI2iBGF0OaYYLKOaOtliFMl+Bt1rY7VmEjwxOxqoYLub/D9xmduPEhbw2imE6gYkJKhIE5it+KE2ulVxQ==} - dev: true - - resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/aix-ppc64': 0.20.2 - '@esbuild/android-arm': 0.20.2 - '@esbuild/android-arm64': 0.20.2 - '@esbuild/android-x64': 0.20.2 - '@esbuild/darwin-arm64': 0.20.2 - '@esbuild/darwin-x64': 0.20.2 - '@esbuild/freebsd-arm64': 0.20.2 - '@esbuild/freebsd-x64': 0.20.2 - '@esbuild/linux-arm': 0.20.2 - '@esbuild/linux-arm64': 0.20.2 - '@esbuild/linux-ia32': 0.20.2 - '@esbuild/linux-loong64': 0.20.2 - '@esbuild/linux-mips64el': 0.20.2 - '@esbuild/linux-ppc64': 0.20.2 - '@esbuild/linux-riscv64': 0.20.2 - '@esbuild/linux-s390x': 0.20.2 - '@esbuild/linux-x64': 0.20.2 - '@esbuild/netbsd-x64': 0.20.2 - '@esbuild/openbsd-x64': 0.20.2 - '@esbuild/sunos-x64': 0.20.2 - '@esbuild/win32-arm64': 0.20.2 - '@esbuild/win32-ia32': 0.20.2 - '@esbuild/win32-x64': 0.20.2 - dev: true - - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} - dev: true - - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - dev: true - - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - dev: true - - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - dependencies: - eslint: 8.57.0 - dev: true - - resolution: {integrity: sha512-NjGXdm7zgcKRkKMua34qVO9doI7VOxZ6ancSvBELJSSoX97jyndXcSoa8XBh69JoB31dNz3EEzlMcizZl7LaMA==} - peerDependencies: - eslint: '>=7' - dependencies: - eslint: 8.57.0 - dev: true - - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - dev: true - - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - dependencies: - '@eslint-community/eslint-utils': 4.4.0([email protected]) - '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.0 - '@humanwhocodes/config-array': 0.11.14 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.1 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.3 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - dev: true - - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2([email protected]) - eslint-visitor-keys: 3.4.3 - dev: true - - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} - dependencies: - estraverse: 5.3.0 - dev: true - - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - dependencies: - estraverse: 5.3.0 - dev: true - - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - dev: true - - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - dev: true - - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true - - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true - - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true - - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - dependencies: - reusify: 1.0.4 - dev: true - - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flat-cache: 3.2.0 - dev: true - - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - dev: true - - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flatted: 3.3.1 - keyv: 4.5.4 - rimraf: 3.0.2 - dev: true - - resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - dev: true - - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true - - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true - optional: true - - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true - - resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} - engines: {node: '>=6'} - dev: false - - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - dev: true - - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - dependencies: - is-glob: 4.0.3 - dev: true - - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true - - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.20.2 - dev: true - - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 3.0.0 - dev: true - - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - dev: true - - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - dev: true - - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true - - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} - engines: {node: '>= 4'} - dev: true - - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - dev: true - - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true - - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - dev: true - - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true - - resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} - dependencies: - loose-envify: 1.4.0 - dev: false - - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true - - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true - - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - dev: true - - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true - - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - dependencies: - argparse: 2.0.1 - dev: true - - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true - - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - dev: true - - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true - - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true - - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - dev: true - - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - dependencies: - json-buffer: 3.0.1 - dev: true - - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - dev: true - - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - dependencies: - p-locate: 5.0.0 - dev: true - - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true - - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - dependencies: - js-tokens: 4.0.0 - dev: false - - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - dependencies: - yallist: 3.1.1 - dev: true - - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - dev: true - - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true - - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - dev: true - - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - dev: true - - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - dev: true - - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true - - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - dev: true - - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true - - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} - dev: true - - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - dev: true - - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} - engines: {node: '>= 0.8.0'} - dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - dev: true - - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - dependencies: - yocto-queue: 0.1.0 - dev: true - - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - dependencies: - p-limit: 3.1.0 - dev: true - - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - dependencies: - callsites: 3.1.0 - dev: true - - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true - - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true - - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: true - - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true - - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true - - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true - - resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} - engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.0 - source-map-js: 1.2.0 - dev: true - - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - dev: true - - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - dev: true - - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true - - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} - peerDependencies: - react: ^18.2.0 - dependencies: - loose-envify: 1.4.0 - react: 18.2.0 - scheduler: 0.23.0 - dev: false - - resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} - engines: {node: '>=0.10.0'} - dev: true - - resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 18.2.75 - react: 18.2.0 - react-style-singleton: 2.2.1(@types/[email protected])([email protected]) - tslib: 2.6.2 - dev: false - - resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 18.2.75 - react: 18.2.0 - react-remove-scroll-bar: 2.3.6(@types/[email protected])([email protected]) - react-style-singleton: 2.2.1(@types/[email protected])([email protected]) - tslib: 2.6.2 - use-callback-ref: 1.3.2(@types/[email protected])([email protected]) - use-sidecar: 1.1.2(@types/[email protected])([email protected]) - dev: false - - resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 18.2.75 - get-nonce: 1.0.1 - invariant: 2.2.4 - react: 18.2.0 - tslib: 2.6.2 - dev: false - - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} - engines: {node: '>=0.10.0'} - dependencies: - loose-envify: 1.4.0 - dev: false - - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - dev: false - - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - dev: true - - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true - - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - - resolution: {integrity: sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - dependencies: - '@types/estree': 1.0.5 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.14.1 - '@rollup/rollup-android-arm64': 4.14.1 - '@rollup/rollup-darwin-arm64': 4.14.1 - '@rollup/rollup-darwin-x64': 4.14.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.14.1 - '@rollup/rollup-linux-arm64-gnu': 4.14.1 - '@rollup/rollup-linux-arm64-musl': 4.14.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.14.1 - '@rollup/rollup-linux-riscv64-gnu': 4.14.1 - '@rollup/rollup-linux-s390x-gnu': 4.14.1 - '@rollup/rollup-linux-x64-gnu': 4.14.1 - '@rollup/rollup-linux-x64-musl': 4.14.1 - '@rollup/rollup-win32-arm64-msvc': 4.14.1 - '@rollup/rollup-win32-ia32-msvc': 4.14.1 - '@rollup/rollup-win32-x64-msvc': 4.14.1 - fsevents: 2.3.3 - dev: true - - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - dependencies: - queue-microtask: 1.2.3 - dev: true - - resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} - dependencies: - loose-envify: 1.4.0 - dev: false - - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - dev: true - - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - dev: true - - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - dev: true - - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true - - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} - engines: {node: '>=0.10.0'} - dev: true - - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - dev: true - - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true - - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - dev: true - - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - dev: true - - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - dev: true - - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true - - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - dev: true - - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} - engines: {node: '>=16'} - peerDependencies: - typescript: '>=4.2.0' - dependencies: - typescript: 5.4.5 - dev: true - - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - dev: false - - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - dev: true - - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - dev: true - - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} - engines: {node: '>=14.17'} - hasBin: true - dev: true - - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true - - resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.23.0 - escalade: 3.1.2 - picocolors: 1.0.0 - dev: true - - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - dependencies: - punycode: 2.3.1 - dev: true - - resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 18.2.75 - react: 18.2.0 - tslib: 2.6.2 - dev: false - - resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 18.2.75 - detect-node-es: 1.1.0 - react: 18.2.0 - tslib: 2.6.2 - dev: false - - /[email protected](@types/[email protected]): - resolution: {integrity: sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - '@types/node': 20.12.7 - esbuild: 0.20.2 - postcss: 8.4.38 - rollup: 4.14.1 - optionalDependencies: - fsevents: 2.3.3 - dev: true - - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true - - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true - - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true - - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true diff --git a/apps/extension/src/SideBar.tsx b/apps/extension/src/SideBar.tsx index 677d6bf4..385c0f22 100644 --- a/apps/extension/src/SideBar.tsx +++ b/apps/extension/src/SideBar.tsx @@ -47,13 +47,12 @@ function SideBar({ jwt }: { jwt: string }) { // } // }); - const [savedWebsites, setSavedWebsites] = useState<string[]>([]); const [isSendingData, setIsSendingData] = useState(false); - const [loading, setLoading] = useState(false) - const [spaces, setSpaces] = useState<Space[]>(); + const [loading, setLoading] = useState(false); + const [spaces, setSpaces] = useState<Space[]>(); const [selectedSpaces, setSelectedSpaces] = useState<number[]>([]); const [isImportingTweets, setIsImportingTweets] = useState(false); @@ -77,14 +76,14 @@ function SideBar({ jwt }: { jwt: string }) { }); } - const fetchSpaces = async () => { - setLoading(true) + const fetchSpaces = async () => { + setLoading(true); chrome.runtime.sendMessage({ type: "fetchSpaces" }, (resp) => { - console.log('response',resp) - setSpaces(resp) - setLoading(false) - }); - } + console.log("response", resp); + setSpaces(resp); + setLoading(false); + }); + }; const fetchBookmarks = () => { const tweets: TweetData[] = []; // Initialize an empty array to hold all tweet elements @@ -266,7 +265,7 @@ function SideBar({ jwt }: { jwt: string }) { ) : ( <></> )} - <Dialog onOpenChange={open => open === true && fetchSpaces()}> + <Dialog onOpenChange={(open) => open === true && fetchSpaces()}> <Tooltip delayDuration={300}> <TooltipTrigger className="anycontext-bg-transparent @@ -326,7 +325,7 @@ function SideBar({ jwt }: { jwt: string }) { </DialogHeader> <FilterSpaces - loading={loading} + loading={loading} className="anycontext-mr-auto" selectedSpaces={selectedSpaces} setSelectedSpaces={setSelectedSpaces} @@ -335,18 +334,20 @@ function SideBar({ jwt }: { jwt: string }) { /> <DialogFooter className="anycontext-w-full anycontext-text-sm"> <DialogClose - onClick={() => { - sendUrlToAPI(selectedSpaces); - setIsSendingData(true); - setTimeout(() => { - setIsSendingData(false); - setSavedWebsites([ - ...savedWebsites, - window.location.href, - ]); - }, 1000); - }} - >Add</DialogClose> + onClick={() => { + sendUrlToAPI(selectedSpaces); + setIsSendingData(true); + setTimeout(() => { + setIsSendingData(false); + setSavedWebsites([ + ...savedWebsites, + window.location.href, + ]); + }, 1000); + }} + > + Add + </DialogClose> <DialogClose>Cancel</DialogClose> </DialogFooter> </DialogContent> diff --git a/apps/extension/src/background.ts b/apps/extension/src/background.ts index 86f324cd..d2f8759e 100644 --- a/apps/extension/src/background.ts +++ b/apps/extension/src/background.ts @@ -1,5 +1,5 @@ import { getEnv } from "./util"; -import { Space } from "./types/memory" +import { Space } from "./types/memory"; const backendUrl = getEnv() === "development" @@ -47,53 +47,49 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { return true; } else if (request.type === "urlChange") { - const content = request.content; const url = request.url; - const spaces = request.spaces - - (async () => { - chrome.storage.local.get(["jwt"], ({ jwt }) => { - if (!jwt) { - console.error("No JWT found"); - return; - } - fetch(`${backendUrl}/api/store`, { - method: "POST", - headers: { - Authorization: `Bearer ${jwt}`, - }, - body: JSON.stringify({ pageContent: content, url, spaces }), - }).then((ers) => console.log(ers.status)); - }); - })(); + const spaces = request.spaces( + // eslint-disable-next-line no-unexpected-multiline + async () => { + chrome.storage.local.get(["jwt"], ({ jwt }) => { + if (!jwt) { + console.error("No JWT found"); + return; + } + fetch(`${backendUrl}/api/store`, { + method: "POST", + headers: { + Authorization: `Bearer ${jwt}`, + }, + body: JSON.stringify({ pageContent: content, url, spaces }), + }).then((ers) => console.log(ers.status)); + }); + }, + )(); } else if (request.type === "fetchSpaces") { + chrome.storage.local.get(["jwt"], async ({ jwt }) => { + if (!jwt) { + console.error("No JWT found"); + return; + } + const resp = await fetch(`${backendUrl}/api/spaces`, { + headers: { + Authorization: `Bearer ${jwt}`, + }, + }); - chrome.storage.local.get(["jwt"], async ({ jwt }) => { - if (!jwt) { - console.error("No JWT found"); - return; - } - const resp = await fetch(`${backendUrl}/api/spaces`, { - headers: { - Authorization: `Bearer ${jwt}`, - }, - }) - - const data: { - message: "OK" | string; - data: Space[] | undefined; - } = await resp.json(); - - if (data.message === "OK" && data.data) { - sendResponse(data.data) - } - - }); - - return true; + const data: { + message: "OK" | string; + data: Space[] | undefined; + } = await resp.json(); + if (data.message === "OK" && data.data) { + sendResponse(data.data); + } + }); + return true; } else if (request.type === "queryApi") { const input = request.input; const jwt = request.jwt; diff --git a/apps/extension/src/components/FilterCombobox.tsx b/apps/extension/src/components/FilterCombobox.tsx index 1ff49d38..3c8779b6 100644 --- a/apps/extension/src/components/FilterCombobox.tsx +++ b/apps/extension/src/components/FilterCombobox.tsx @@ -1,7 +1,11 @@ import * as React from "react"; import { PlusCircleIcon, X } from "lucide-react"; import { Space } from "../types/memory"; -import { DropdownMenu, DropdownMenuContent, DropdownMenuItem } from "./ui/dropdown-menu"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, +} from "./ui/dropdown-menu"; import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu"; export interface Props extends React.ButtonHTMLAttributes<HTMLButtonElement> { @@ -11,57 +15,76 @@ export interface Props extends React.ButtonHTMLAttributes<HTMLButtonElement> { ) => void; name: string; spaces: Space[]; - loading: boolean; + loading: boolean; } export function FilterSpaces({ - loading, + loading, selectedSpaces, setSelectedSpaces, spaces, }: Props) { - console.log(selectedSpaces, spaces); - const filteredSpaces = spaces.filter(space => selectedSpaces.includes(space.id)) - const leftSpaces = spaces.filter(space => !selectedSpaces.includes(space.id)) + const filteredSpaces = spaces.filter((space) => + selectedSpaces.includes(space.id), + ); + const leftSpaces = spaces.filter( + (space) => !selectedSpaces.includes(space.id), + ); - if (loading) { - return "Loading..." - } + if (loading) { + return "Loading..."; + } return ( <div className="anycontext-flex anycontext-flex-wrap anycontext-gap-1 anycontext-text-sm anycontext-"> - {filteredSpaces.length < 1 && "Add to a space"} - {filteredSpaces.map((space) => ( - <SpaceItem {...space} key={space.id} onRemove={() => setSelectedSpaces(prev => prev.filter(s => s !== space.id))} /> + {filteredSpaces.length < 1 && "Add to a space"} + {filteredSpaces.map((space) => ( + <SpaceItem + {...space} + key={space.id} + onRemove={() => + setSelectedSpaces((prev) => prev.filter((s) => s !== space.id)) + } + /> ))} - {leftSpaces.length > 0 && ( - <DropdownMenu> - <DropdownMenuTrigger className="anycontext-rounded-full"> - <PlusCircleIcon className="anycontext-w-5 anycontext-h-5 [--anycontext-icon-stroke:white] dark:[--anycontext-icon-stroke:black]" stroke='var(--anycontext-icon-stroke)' fill='currentColor' /> - </DropdownMenuTrigger> - <DropdownMenuContent> - {leftSpaces.map(space => ( - <> - {loading && "Loading..."} - <DropdownMenuItem onClick={() => setSelectedSpaces(prev => [...prev, space.id])}> - {space.name} - </DropdownMenuItem> - </> - ))} - </DropdownMenuContent> - </DropdownMenu> - )} + {leftSpaces.length > 0 && ( + <DropdownMenu> + <DropdownMenuTrigger className="anycontext-rounded-full"> + <PlusCircleIcon + className="anycontext-w-5 anycontext-h-5 [--anycontext-icon-stroke:white] dark:[--anycontext-icon-stroke:black]" + stroke="var(--anycontext-icon-stroke)" + fill="currentColor" + /> + </DropdownMenuTrigger> + <DropdownMenuContent> + {leftSpaces.map((space) => ( + <> + {loading && "Loading..."} + <DropdownMenuItem + onClick={() => + setSelectedSpaces((prev) => [...prev, space.id]) + } + > + {space.name} + </DropdownMenuItem> + </> + ))} + </DropdownMenuContent> + </DropdownMenu> + )} </div> ); - } -function SpaceItem({ name, onRemove }: { onRemove: () => void } & Space) { +function SpaceItem({ name, onRemove }: Space & { onRemove: () => void }) { return ( <div className="anycontext-flex anycontext-justify-center anycontext-items-center anycontext-gap-2 anycontext-p-1 anycontext-pl-2 anycontext-pr-3 anycontext-rounded-full anycontext-bg-black/5 dark:anycontext-bg-white/5 anycontext-border-white/20 dark:anycontext-border-black/20 border"> - <button onClick={onRemove} className="anycontext-flex hover:anycontext-bg-transparent anycontext-justify-center anycontext-scale-110 anycontext-items-center focus-visible:anycontext-outline-none anycontext-rounded-full anycontext-w-3 anycontext-bg-black/5 dark:anycontext-bg-white/5 anycontext-h-3 anycontext-text-transparent hover:anycontext-text-black dark:hover:anycontext-text-white"> + <button + onClick={onRemove} + className="anycontext-flex hover:anycontext-bg-transparent anycontext-justify-center anycontext-scale-110 anycontext-items-center focus-visible:anycontext-outline-none anycontext-rounded-full anycontext-w-3 anycontext-bg-black/5 dark:anycontext-bg-white/5 anycontext-h-3 anycontext-text-transparent hover:anycontext-text-black dark:hover:anycontext-text-white" + > <X className="anycontext-w-3 anycontext-h-3" /> </button> {name} diff --git a/apps/extension/src/components/ui/dropdown-menu.tsx b/apps/extension/src/components/ui/dropdown-menu.tsx index 2e9a95b8..fcc1edb2 100644 --- a/apps/extension/src/components/ui/dropdown-menu.tsx +++ b/apps/extension/src/components/ui/dropdown-menu.tsx @@ -1,25 +1,25 @@ -import * as React from "react" -import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" -import { Check, ChevronRight, Circle } from "lucide-react" +import * as React from "react"; +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"; +import { Check, ChevronRight, Circle } from "lucide-react"; -import { cn } from "../../lib/utils" +import { cn } from "../../lib/utils"; -const DropdownMenu = DropdownMenuPrimitive.Root +const DropdownMenu = DropdownMenuPrimitive.Root; -const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger; -const DropdownMenuGroup = DropdownMenuPrimitive.Group +const DropdownMenuGroup = DropdownMenuPrimitive.Group; -const DropdownMenuPortal = DropdownMenuPrimitive.Portal +const DropdownMenuPortal = DropdownMenuPrimitive.Portal; -const DropdownMenuSub = DropdownMenuPrimitive.Sub +const DropdownMenuSub = DropdownMenuPrimitive.Sub; -const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup; const DropdownMenuSubTrigger = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>, React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & { - inset?: boolean + inset?: boolean; } >(({ className, inset, children, ...props }, ref) => ( <DropdownMenuPrimitive.SubTrigger @@ -27,16 +27,16 @@ const DropdownMenuSubTrigger = React.forwardRef< className={cn( "anycontext-flex anycontext-cursor-default anycontext-select-none anycontext-items-center anycontext-rounded-sm anycontext-px-2 anycontext-py-1.5 anycontext-text-sm anycontext-outline-none focus:anycontext-bg-stone-100 data-[state=open]:anycontext-bg-stone-100 dark:focus:anycontext-bg-stone-800 dark:data-[state=open]:anycontext-bg-stone-800", inset && "anycontext-pl-8", - className + className, )} {...props} > {children} <ChevronRight className="anycontext-ml-auto anycontext-h-4 anycontext-w-4" /> </DropdownMenuPrimitive.SubTrigger> -)) +)); DropdownMenuSubTrigger.displayName = - DropdownMenuPrimitive.SubTrigger.displayName + DropdownMenuPrimitive.SubTrigger.displayName; const DropdownMenuSubContent = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitive.SubContent>, @@ -46,13 +46,13 @@ const DropdownMenuSubContent = React.forwardRef< ref={ref} className={cn( "anycontext-z-50 anycontext-min-w-[8rem] anycontext-overflow-hidden anycontext-rounded-md anycontext-border anycontext-border-stone-200 anycontext-bg-white anycontext-p-1 anycontext-text-stone-950 anycontext-shadow-lg data-[state=open]:anycontext-animate-in data-[state=closed]:anycontext-animate-out data-[state=closed]:anycontext-fade-out-0 data-[state=open]:anycontext-fade-in-0 data-[state=closed]:anycontext-zoom-out-95 data-[state=open]:anycontext-zoom-in-95 data-[side=bottom]:anycontext-slide-in-from-top-2 data-[side=left]:anycontext-slide-in-from-right-2 data-[side=right]:anycontext-slide-in-from-left-2 data-[side=top]:anycontext-slide-in-from-bottom-2 dark:anycontext-border-stone-800 dark:anycontext-bg-stone-950 dark:anycontext-text-stone-50", - className + className, )} {...props} /> -)) +)); DropdownMenuSubContent.displayName = - DropdownMenuPrimitive.SubContent.displayName + DropdownMenuPrimitive.SubContent.displayName; const DropdownMenuContent = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitive.Content>, @@ -64,18 +64,18 @@ const DropdownMenuContent = React.forwardRef< sideOffset={sideOffset} className={cn( "anycontext-z-50 anycontext-min-w-[8rem] anycontext-overflow-hidden anycontext-rounded-md anycontext-border anycontext-border-stone-200 anycontext-bg-white anycontext-p-1 anycontext-text-stone-950 anycontext-shadow-md data-[state=open]:anycontext-animate-in data-[state=closed]:anycontext-animate-out data-[state=closed]:anycontext-fade-out-0 data-[state=open]:anycontext-fade-in-0 data-[state=closed]:anycontext-zoom-out-95 data-[state=open]:anycontext-zoom-in-95 data-[side=bottom]:anycontext-slide-in-from-top-2 data-[side=left]:anycontext-slide-in-from-right-2 data-[side=right]:anycontext-slide-in-from-left-2 data-[side=top]:anycontext-slide-in-from-bottom-2 dark:anycontext-border-stone-800 dark:anycontext-bg-stone-950 dark:anycontext-text-stone-50", - className + className, )} {...props} /> </DropdownMenuPrimitive.Portal> -)) -DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName +)); +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName; const DropdownMenuItem = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitive.Item>, React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & { - inset?: boolean + inset?: boolean; } >(({ className, inset, ...props }, ref) => ( <DropdownMenuPrimitive.Item @@ -83,12 +83,12 @@ const DropdownMenuItem = React.forwardRef< className={cn( "anycontext-relative anycontext-flex anycontext-cursor-default anycontext-select-none anycontext-items-center anycontext-rounded-sm anycontext-px-2 anycontext-py-1.5 anycontext-text-sm anycontext-outline-none anycontext-transition-colors focus:anycontext-bg-stone-100 focus:anycontext-text-stone-900 data-[disabled]:anycontext-pointer-events-none data-[disabled]:anycontext-opacity-50 dark:focus:anycontext-bg-stone-800 dark:focus:anycontext-text-stone-50", inset && "anycontext-pl-8", - className + className, )} {...props} /> -)) -DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName +)); +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName; const DropdownMenuCheckboxItem = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>, @@ -98,7 +98,7 @@ const DropdownMenuCheckboxItem = React.forwardRef< ref={ref} className={cn( "anycontext-relative anycontext-flex anycontext-cursor-default anycontext-select-none anycontext-items-center anycontext-rounded-sm anycontext-py-1.5 anycontext-pl-8 anycontext-pr-2 anycontext-text-sm anycontext-outline-none anycontext-transition-colors focus:anycontext-bg-stone-100 focus:anycontext-text-stone-900 data-[disabled]:anycontext-pointer-events-none data-[disabled]:anycontext-opacity-50 dark:focus:anycontext-bg-stone-800 dark:focus:anycontext-text-stone-50", - className + className, )} checked={checked} {...props} @@ -110,9 +110,9 @@ const DropdownMenuCheckboxItem = React.forwardRef< </span> {children} </DropdownMenuPrimitive.CheckboxItem> -)) +)); DropdownMenuCheckboxItem.displayName = - DropdownMenuPrimitive.CheckboxItem.displayName + DropdownMenuPrimitive.CheckboxItem.displayName; const DropdownMenuRadioItem = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>, @@ -122,7 +122,7 @@ const DropdownMenuRadioItem = React.forwardRef< ref={ref} className={cn( "anycontext-relative anycontext-flex anycontext-cursor-default anycontext-select-none anycontext-items-center anycontext-rounded-sm anycontext-py-1.5 anycontext-pl-8 anycontext-pr-2 anycontext-text-sm anycontext-outline-none anycontext-transition-colors focus:anycontext-bg-stone-100 focus:anycontext-text-stone-900 data-[disabled]:anycontext-pointer-events-none data-[disabled]:anycontext-opacity-50 dark:focus:anycontext-bg-stone-800 dark:focus:anycontext-text-stone-50", - className + className, )} {...props} > @@ -133,13 +133,13 @@ const DropdownMenuRadioItem = React.forwardRef< </span> {children} </DropdownMenuPrimitive.RadioItem> -)) -DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName +)); +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName; const DropdownMenuLabel = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitive.Label>, React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & { - inset?: boolean + inset?: boolean; } >(({ className, inset, ...props }, ref) => ( <DropdownMenuPrimitive.Label @@ -147,12 +147,12 @@ const DropdownMenuLabel = React.forwardRef< className={cn( "anycontext-px-2 anycontext-py-1.5 anycontext-text-sm anycontext-font-semibold", inset && "anycontext-pl-8", - className + className, )} {...props} /> -)) -DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName +)); +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName; const DropdownMenuSeparator = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitive.Separator>, @@ -160,11 +160,14 @@ const DropdownMenuSeparator = React.forwardRef< >(({ className, ...props }, ref) => ( <DropdownMenuPrimitive.Separator ref={ref} - className={cn("anycontext--mx-1 anycontext-my-1 anycontext-h-px anycontext-bg-stone-100 dark:anycontext-bg-stone-800", className)} + className={cn( + "anycontext--mx-1 anycontext-my-1 anycontext-h-px anycontext-bg-stone-100 dark:anycontext-bg-stone-800", + className, + )} {...props} /> -)) -DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName +)); +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName; const DropdownMenuShortcut = ({ className, @@ -172,12 +175,15 @@ const DropdownMenuShortcut = ({ }: React.HTMLAttributes<HTMLSpanElement>) => { return ( <span - className={cn("anycontext-ml-auto anycontext-text-xs anycontext-tracking-widest anycontext-opacity-60", className)} + className={cn( + "anycontext-ml-auto anycontext-text-xs anycontext-tracking-widest anycontext-opacity-60", + className, + )} {...props} /> - ) -} -DropdownMenuShortcut.displayName = "DropdownMenuShortcut" + ); +}; +DropdownMenuShortcut.displayName = "DropdownMenuShortcut"; export { DropdownMenu, @@ -195,4 +201,4 @@ export { DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup, -} +}; diff --git a/apps/web/src/actions/db.ts b/apps/web/src/actions/db.ts index 66fbc830..cd54c1bd 100644 --- a/apps/web/src/actions/db.ts +++ b/apps/web/src/actions/db.ts @@ -6,66 +6,79 @@ import { sessions, StoredContent, storedContent, - StoredSpace, + StoredSpace, users, - space, + space, } from "@/server/db/schema"; import { SearchResult } from "@/contexts/MemoryContext"; import { like, eq, and, sql, exists, asc, notExists } from "drizzle-orm"; -import { union } from "drizzle-orm/sqlite-core" +import { union } from "drizzle-orm/sqlite-core"; // @todo: (future) pagination not yet needed -export async function searchMemoriesAndSpaces(query: string, opts?: { filter?: { memories?: boolean, spaces?: boolean }, range?: { offset: number, limit: number } }): Promise<SearchResult[]> { - - const user = await getUser() - - if (!user) { - return [] - } - - try { - const searchMemoriesQuery = db.select({ - type: sql<string>`'memory'`, - space: sql`NULL`, - memory: storedContent as any - }).from(storedContent).where(and( - eq(storedContent.user, user.id), - like(storedContent.title, `%${query}%`) - )).orderBy(asc(storedContent.savedAt)); - - const searchSpacesQuery = db.select({ - type: sql<string>`'space'`, - space: space as any, - memory: sql`NULL`, - }).from(space).where( - and( - eq(space.user, user.id), - like(space.name, `%${query}%`) - ) - ).orderBy(asc(space.name)); - - let queries = []; - - console.log('adding'); - - [undefined, true].includes(opts?.filter?.memories) && queries.push(searchMemoriesQuery); - [undefined, true].includes(opts?.filter?.spaces) && queries.push(searchSpacesQuery); - - if (opts?.range) { - queries = queries.map(q => q.offset(opts.range!.offset).limit(opts.range!.limit)) - } else { - queries = queries.map(q => q.all()) - } - - const data = await Promise.all(queries) - - console.log('resp', data) - - return data.reduce((acc, i) => [...acc, ...i]) as SearchResult[] - } catch { - return [] - } +export async function searchMemoriesAndSpaces( + query: string, + opts?: { + filter?: { memories?: boolean; spaces?: boolean }; + range?: { offset: number; limit: number }; + }, +): Promise<SearchResult[]> { + const user = await getUser(); + + if (!user) { + return []; + } + try { + const searchMemoriesQuery = db + .select({ + type: sql<string>`'memory'`, + space: sql`NULL`, + memory: storedContent as any, + }) + .from(storedContent) + .where( + and( + eq(storedContent.user, user.id), + like(storedContent.title, `%${query}%`), + ), + ) + .orderBy(asc(storedContent.savedAt)); + + const searchSpacesQuery = db + .select({ + type: sql<string>`'space'`, + space: space as any, + memory: sql`NULL`, + }) + .from(space) + .where(and(eq(space.user, user.id), like(space.name, `%${query}%`))) + .orderBy(asc(space.name)); + + let queries = []; + + console.log("adding"); + + [undefined, true].includes(opts?.filter?.memories) && + queries.push(searchMemoriesQuery); + [undefined, true].includes(opts?.filter?.spaces) && + queries.push(searchSpacesQuery); + + if (opts?.range) { + queries = queries.map((q) => + q.offset(opts.range!.offset).limit(opts.range!.limit), + ); + } else { + queries = queries.map((q) => q.all()); + } + + const data = await Promise.all(queries); + + console.log("resp", data); + + return data.reduce((acc, i) => [...acc, ...i]) as SearchResult[]; + } catch { + return []; + } } async function getUser() { @@ -76,7 +89,7 @@ async function getUser() { headers().get("Authorization")?.replace("Bearer ", ""); if (!token) { - return null + return null; } const session = await db @@ -85,7 +98,7 @@ async function getUser() { .where(eq(sessions.sessionToken, token!)); if (!session || session.length === 0) { - return null + return null; } const [userData] = await db @@ -95,17 +108,17 @@ async function getUser() { .limit(1); if (!userData) { - return null + return null; } - return userData + return userData; } export async function getMemory(title: string) { const user = await getUser(); if (!user) { - return null + return null; } return await db @@ -119,34 +132,39 @@ export async function getMemory(title: string) { ); } - export async function addSpace(name: string, memories: number[]) { + const user = await getUser(); - const user = await getUser(); - - if (!user) { - return null - } - - const [addedSpace] = await db - .insert(space) - .values({ - name: name, - user: user.id - }).returning(); - - const addedMemories = memories.length > 0 ? await db.insert(contentToSpace) - .values(memories.map(m => ({ - contentId: m, - spaceId: addedSpace.id - }))).returning() : [] - - return { - space: addedSpace, - addedMemories - } -} + if (!user) { + return null; + } + const [addedSpace] = await db + .insert(space) + .values({ + name: name, + user: user.id, + }) + .returning(); + + const addedMemories = + memories.length > 0 + ? await db + .insert(contentToSpace) + .values( + memories.map((m) => ({ + contentId: m, + spaceId: addedSpace.id, + })), + ) + .returning() + : []; + + return { + space: addedSpace, + addedMemories, + }; +} export async function fetchContentForSpace( spaceId: number, @@ -155,115 +173,127 @@ export async function fetchContentForSpace( limit: number; }, ) { - const query = db .select() .from(storedContent) .where( exists( - db.select().from(contentToSpace).where(and(eq(contentToSpace.spaceId, spaceId), eq(contentToSpace.contentId, storedContent.id))), + db + .select() + .from(contentToSpace) + .where( + and( + eq(contentToSpace.spaceId, spaceId), + eq(contentToSpace.contentId, storedContent.id), + ), + ), ), - ).orderBy(asc(storedContent.savedAt)) + ) + .orderBy(asc(storedContent.savedAt)); - return range ? await query.limit(range.limit).offset(range.offset) : await query.all() + return range + ? await query.limit(range.limit).offset(range.offset) + : await query.all(); } -export async function fetchFreeMemories( - range?: { - offset: number; - limit: number; - } -) { - - const user = await getUser() +export async function fetchFreeMemories(range?: { + offset: number; + limit: number; +}) { + const user = await getUser(); - if (!user) { - return [] - } + if (!user) { + return []; + } - const query = db + const query = db .select() .from(storedContent) .where( - and( - notExists( - db.select().from(contentToSpace).where(eq(contentToSpace.contentId, storedContent.id)), - ), - eq(storedContent.user, user.id), - ) - - ).orderBy(asc(storedContent.savedAt)) - - return range ? await query.limit(range.limit).offset(range.offset) : await query.all() + and( + notExists( + db + .select() + .from(contentToSpace) + .where(eq(contentToSpace.contentId, storedContent.id)), + ), + eq(storedContent.user, user.id), + ), + ) + .orderBy(asc(storedContent.savedAt)); + return range + ? await query.limit(range.limit).offset(range.offset) + : await query.all(); } -export async function addMemory(content: typeof storedContent.$inferInsert, spaces: number[]) { - - const user = await getUser() - - if (!user) { - return null - } - - const [addedMemory] = await db.insert(storedContent) - .values({ - user: user.id, - ...content - }) - .returning(); - - const addedToSpaces = spaces.length > 0 ? await db.insert(contentToSpace) - .values(spaces.map(s => ({ - contentId: addedMemory.id, - spaceId: s, - }))) - .returning() : []; +export async function addMemory( + content: typeof storedContent.$inferInsert, + spaces: number[], +) { + const user = await getUser(); - return { - memory: addedMemory, - addedToSpaces - } + if (!user) { + return null; + } + const [addedMemory] = await db + .insert(storedContent) + .values({ + user: user.id, + ...content, + }) + .returning(); + + const addedToSpaces = + spaces.length > 0 + ? await db + .insert(contentToSpace) + .values( + spaces.map((s) => ({ + contentId: addedMemory.id, + spaceId: s, + })), + ) + .returning() + : []; + + return { + memory: addedMemory, + addedToSpaces, + }; } export async function deleteSpace(id: number) { + const user = await getUser(); - const user = await getUser() - - if (!user) { - return null - } - - await db.delete(contentToSpace) - .where(eq(contentToSpace.spaceId, id)); - - const [deleted] = await db.delete(space) - .where(and(eq(space.user, user.id), eq(space.id, id))) - .returning(); + if (!user) { + return null; + } + await db.delete(contentToSpace).where(eq(contentToSpace.spaceId, id)); - return deleted + const [deleted] = await db + .delete(space) + .where(and(eq(space.user, user.id), eq(space.id, id))) + .returning(); + return deleted; } - export async function deleteMemory(id: number) { + const user = await getUser(); + if (!user) { + return null; + } - const user = await getUser() - - if (!user) { - return null - } - - await db.delete(contentToSpace) - .where(eq(contentToSpace.contentId, id)); - - const [deleted] = await db.delete(storedContent) - .where(and(eq(storedContent.user, user.id), eq(storedContent.id, id))) - .returning(); + await db.delete(contentToSpace).where(eq(contentToSpace.contentId, id)); - return deleted + const [deleted] = await db + .delete(storedContent) + .where(and(eq(storedContent.user, user.id), eq(storedContent.id, id))) + .returning(); + return deleted; } diff --git a/apps/web/src/app/api/spaces/route.ts b/apps/web/src/app/api/spaces/route.ts index 3fe95870..d2685e9f 100644 --- a/apps/web/src/app/api/spaces/route.ts +++ b/apps/web/src/app/api/spaces/route.ts @@ -3,13 +3,7 @@ import { sessions, space, users } from "@/server/db/schema"; import { eq } from "drizzle-orm"; import { NextRequest, NextResponse } from "next/server"; -<<<<<<< HEAD -export const runtime = "edge" - -export async function GET(req: NextRequest) { -======= export const runtime = "edge"; ->>>>>>> 7648bdaa8cbe42a90f05865f8c555c9a3911af9b export async function GET(req: NextRequest) { const token = @@ -40,7 +34,6 @@ export async function GET(req: NextRequest) { .from(sessions) .where(eq(sessions.sessionToken, token!)); - if (!sessionData || sessionData.length === 0) { return new Response( JSON.stringify({ message: "Invalid Key, session not found." }), @@ -63,27 +56,11 @@ export async function GET(req: NextRequest) { const user = userData[0]; -<<<<<<< HEAD - const spaces = await db - .select() - .from(space) - .where(eq(space.user, user.id)) - .all(); - - - console.log('data', spaces) - - return NextResponse.json({ - message: "OK", - data: spaces - }, { status: 200 }) -======= const spaces = await db .select() .from(space) .where(eq(space.user, user.id)) .all(); ->>>>>>> 7648bdaa8cbe42a90f05865f8c555c9a3911af9b return NextResponse.json( { diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx index 7f3abfee..1cc21adf 100644 --- a/apps/web/src/app/page.tsx +++ b/apps/web/src/app/page.tsx @@ -1,6 +1,6 @@ import { db } from "@/server/db"; import { - ChachedSpaceContent, + ChachedSpaceContent, contentToSpace, sessions, space, @@ -57,37 +57,36 @@ export default async function Home() { .select() .from(space) .where(eq(space.user, userData.id)) - .all(); + .all(); - console.log(collectedSpaces) + console.log(collectedSpaces); // Fetch only first 3 content of each spaces let contents: ChachedSpaceContent[] = []; - //console.log(await db.select().from(storedContent).) - + //console.log(await db.select().from(storedContent).) + await Promise.all([ collectedSpaces.forEach(async (space) => { - console.log("fetching ") - const data = (await fetchContentForSpace(space.id, { - offset: 0, - limit: 3, - })).map(data => ({ - ...data, - space: space.id - })) - contents = [ - ...contents, + console.log("fetching "); + const data = ( + await fetchContentForSpace(space.id, { + offset: 0, + limit: 3, + }) + ).map((data) => ({ ...data, - ]; + space: space.id, + })); + contents = [...contents, ...data]; }), ]); - console.log(contents) + console.log(contents); // freeMemories const freeMemories = await fetchFreeMemories(userData.id); - console.log('free',freeMemories) + console.log("free", freeMemories); return ( <MemoryProvider diff --git a/apps/web/src/app/privacy/page.tsx b/apps/web/src/app/privacy/page.tsx index 8d126dff..5e40cbe9 100644 --- a/apps/web/src/app/privacy/page.tsx +++ b/apps/web/src/app/privacy/page.tsx @@ -2,6 +2,8 @@ import React from "react"; import Markdown from "react-markdown"; import { policy } from "./privacy"; +export const runtime = "edge"; + function Page() { return ( <div> diff --git a/apps/web/src/components/Main.tsx b/apps/web/src/components/Main.tsx index 3c883b67..e6b31de5 100644 --- a/apps/web/src/components/Main.tsx +++ b/apps/web/src/components/Main.tsx @@ -380,7 +380,10 @@ export function Chat({ loading={i === chatHistory.length - 1 ? isLoading : false} sources={msg.answer.sources} > - {msg.answer.parts.map((part) => part.text).join(" ")} + {msg.answer.parts + .map((part) => part.text) + .join("") + .replace("</s>", "")} </ChatAnswer> </ChatMessage> ))} diff --git a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx index f21a9683..39f088e3 100644 --- a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx +++ b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx @@ -15,7 +15,7 @@ import { useMemory } from "@/contexts/MemoryContext"; import { Loader, Plus, X } from "lucide-react"; import { StoredContent } from "@/server/db/schema"; import { cleanUrl } from "@/lib/utils"; -import { motion } from "framer-motion" +import { motion } from "framer-motion"; import { getMetaData } from "@/server/helpers"; export function AddMemoryPage({ closeDialog }: { closeDialog: () => void }) { @@ -39,29 +39,29 @@ export function AddMemoryPage({ closeDialog }: { closeDialog: () => void }) { placeholder="Enter the URL of the page" type="url" data-modal-autofocus - className="disabled:opacity-70 disabled:cursor-not-allowed bg-rgray-4 mt-2 w-full" + className="bg-rgray-4 mt-2 w-full disabled:cursor-not-allowed disabled:opacity-70" value={url} onChange={(e) => setUrl(e.target.value)} - disabled={loading} + disabled={loading} /> <DialogFooter> <FilterSpaces selectedSpaces={selectedSpacesId} setSelectedSpaces={setSelectedSpacesId} - className="disabled:opacity-70 disabled:cursor-not-allowed hover:bg-rgray-5 mr-auto bg-white/5" + className="hover:bg-rgray-5 mr-auto bg-white/5 disabled:cursor-not-allowed disabled:opacity-70" name={"Spaces"} - disabled={loading} + disabled={loading} /> <button type={"submit"} - disabled={loading} + disabled={loading} onClick={async () => { - setLoading(true) - const metadata = await getMetaData(url) + setLoading(true); + const metadata = await getMetaData(url); await addMemory( { title: metadata.title, - description: metadata.description, + description: metadata.description, content: "", type: "page", url: url, @@ -70,28 +70,28 @@ export function AddMemoryPage({ closeDialog }: { closeDialog: () => void }) { }, selectedSpacesId, ); - closeDialog() + closeDialog(); }} - className="relative disabled:opacity-70 disabled:cursor-not-allowed bg-rgray-4 hover:bg-rgray-5 focus-visible:bg-rgray-5 focus-visible:ring-rgray-7 rounded-md px-4 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2" + className="bg-rgray-4 hover:bg-rgray-5 focus-visible:bg-rgray-5 focus-visible:ring-rgray-7 relative rounded-md px-4 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-70" > - <motion.div - initial={{ x: '-50%', y: '-100%' }} - animate={loading && { y: '-50%', x: '-50%', opacity: 1 }} - className="opacity-0 absolute top-1/2 left-1/2 translate-y-[-100%] -translate-x-1/2" - > - <Loader className="w-5 h-5 animate-spin text-rgray-11" /> - </motion.div> - <motion.div - initial={{ y: '0%' }} - animate={loading && { opacity: 0, y: '30%' }} - > - Add - </motion.div> + <motion.div + initial={{ x: "-50%", y: "-100%" }} + animate={loading && { y: "-50%", x: "-50%", opacity: 1 }} + className="absolute left-1/2 top-1/2 -translate-x-1/2 translate-y-[-100%] opacity-0" + > + <Loader className="text-rgray-11 h-5 w-5 animate-spin" /> + </motion.div> + <motion.div + initial={{ y: "0%" }} + animate={loading && { opacity: 0, y: "30%" }} + > + Add + </motion.div> </button> <DialogClose - disabled={loading} - className="disabled:opacity-70 disabled:cursor-not-allowed hover:bg-rgray-4 focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 rounded-md px-3 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2" - > + disabled={loading} + className="hover:bg-rgray-4 focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 rounded-md px-3 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-70" + > Cancel </DialogClose> </DialogFooter> @@ -100,8 +100,7 @@ export function AddMemoryPage({ closeDialog }: { closeDialog: () => void }) { } export function NoteAddPage({ closeDialog }: { closeDialog: () => void }) { - - const { addMemory } = useMemory() + const { addMemory } = useMemory(); const [selectedSpacesId, setSelectedSpacesId] = useState<number[]>([]); @@ -142,7 +141,7 @@ export function NoteAddPage({ closeDialog }: { closeDialog: () => void }) { placeholder="Title of the note" data-modal-autofocus value={name} - disabled={loading} + disabled={loading} onChange={(e) => setName(e.target.value)} /> <Editor @@ -165,39 +164,41 @@ export function NoteAddPage({ closeDialog }: { closeDialog: () => void }) { <button onClick={() => { if (check()) { - setLoading(true) - addMemory({ - content, - title: name, - type: "note", - url: "https://notes.supermemory.dhr.wtf/", - image: '', - savedAt: new Date() - }, selectedSpacesId).then(closeDialog) + setLoading(true); + addMemory( + { + content, + title: name, + type: "note", + url: "https://notes.supermemory.dhr.wtf/", + image: "", + savedAt: new Date(), + }, + selectedSpacesId, + ).then(closeDialog); } }} - disabled={loading} - className="relative disabled:opacity-70 disabled:cursor-not-allowed bg-rgray-4 hover:bg-rgray-5 focus-visible:bg-rgray-5 focus-visible:ring-rgray-7 rounded-md px-4 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2" + disabled={loading} + className="bg-rgray-4 hover:bg-rgray-5 focus-visible:bg-rgray-5 focus-visible:ring-rgray-7 relative rounded-md px-4 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-70" > - - <motion.div - initial={{ x: '-50%', y: '-100%' }} - animate={loading && { y: '-50%', x: '-50%', opacity: 1 }} - className="opacity-0 absolute top-1/2 left-1/2 translate-y-[-100%] -translate-x-1/2" - > - <Loader className="w-5 h-5 animate-spin text-rgray-11" /> - </motion.div> - <motion.div - initial={{ y: '0%' }} - animate={loading && { opacity: 0, y: '30%' }} - > - Add - </motion.div> + <motion.div + initial={{ x: "-50%", y: "-100%" }} + animate={loading && { y: "-50%", x: "-50%", opacity: 1 }} + className="absolute left-1/2 top-1/2 -translate-x-1/2 translate-y-[-100%] opacity-0" + > + <Loader className="text-rgray-11 h-5 w-5 animate-spin" /> + </motion.div> + <motion.div + initial={{ y: "0%" }} + animate={loading && { opacity: 0, y: "30%" }} + > + Add + </motion.div> </button> <DialogClose type={undefined} - disabled={loading} - className="disabled:opacity-70 disabled:cursor-not-allowed hover:bg-rgray-4 focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 rounded-md px-3 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2" + disabled={loading} + className="hover:bg-rgray-4 focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 rounded-md px-3 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-70" > Cancel </DialogClose> @@ -207,16 +208,14 @@ export function NoteAddPage({ closeDialog }: { closeDialog: () => void }) { } export function SpaceAddPage({ closeDialog }: { closeDialog: () => void }) { - - const { addSpace } = useMemory() + const { addSpace } = useMemory(); const inputRef = useRef<HTMLInputElement>(null); const [name, setName] = useState(""); const [loading, setLoading] = useState(false); - const [selected, setSelected] = useState<StoredContent[]>([]); - + const [selected, setSelected] = useState<StoredContent[]>([]); function check(): boolean { const data = { @@ -247,65 +246,73 @@ export function SpaceAddPage({ closeDialog }: { closeDialog: () => void }) { </DialogHeader> <Label className="mt-5 block">Name</Label> <Input - ref={inputRef} + ref={inputRef} placeholder="Enter the name of the space" type="url" data-modal-autofocus - value={name} - disabled={loading} - onChange={e => setName(e.target.value)} - className="bg-rgray-4 mt-2 w-full focus-visible:data-[error=true]:ring-red-500/10 data-[error=true]:placeholder:text-red-400 placeholder:transition placeholder:duration-500" + value={name} + disabled={loading} + onChange={(e) => setName(e.target.value)} + className="bg-rgray-4 mt-2 w-full placeholder:transition placeholder:duration-500 data-[error=true]:placeholder:text-red-400 focus-visible:data-[error=true]:ring-red-500/10" /> {selected.length > 0 && ( - <> - <Label className="mt-5 block">Add Memories</Label> - <div className="flex min-h-5 py-2 flex-col justify-center items-center"> - {selected.map(i => ( - <MemorySelectedItem - key={i.id} - onRemove={() => setSelected(prev => prev.filter(p => p.id !== i.id))} - {...i} - /> - ))} - </div> - </> - )} + <> + <Label className="mt-5 block">Add Memories</Label> + <div className="flex min-h-5 flex-col items-center justify-center py-2"> + {selected.map((i) => ( + <MemorySelectedItem + key={i.id} + onRemove={() => + setSelected((prev) => prev.filter((p) => p.id !== i.id)) + } + {...i} + /> + ))} + </div> + </> + )} <DialogFooter> - <FilterMemories - selected={selected} - setSelected={setSelected} - disabled={loading} - className="mr-auto bg-white/5 hover:bg-rgray-4 focus-visible:bg-rgray-4 disabled:opacity-70 disabled:cursor-not-allowed" - > - <Plus className="w-5 h-5" /> - Memory - </FilterMemories> + <FilterMemories + selected={selected} + setSelected={setSelected} + disabled={loading} + className="hover:bg-rgray-4 focus-visible:bg-rgray-4 mr-auto bg-white/5 disabled:cursor-not-allowed disabled:opacity-70" + > + <Plus className="h-5 w-5" /> + Memory + </FilterMemories> <button type={undefined} - onClick={() => { - if (check()) { - setLoading(true) - addSpace(name, selected.map(s => s.id)).then(() => closeDialog()) - } - }} - disabled={loading} - className="relative disabled:opacity-70 disabled:cursor-not-allowed bg-rgray-4 hover:bg-rgray-5 focus-visible:bg-rgray-5 focus-visible:ring-rgray-7 rounded-md px-4 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2" + onClick={() => { + if (check()) { + setLoading(true); + addSpace( + name, + selected.map((s) => s.id), + ).then(() => closeDialog()); + } + }} + disabled={loading} + className="bg-rgray-4 hover:bg-rgray-5 focus-visible:bg-rgray-5 focus-visible:ring-rgray-7 relative rounded-md px-4 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-70" > - <motion.div - initial={{ x: '-50%', y: '-100%' }} - animate={loading && { y: '-50%', x: '-50%', opacity: 1 }} - className="opacity-0 absolute top-1/2 left-1/2 translate-y-[-100%] -translate-x-1/2" - > - <Loader className="w-5 h-5 animate-spin text-rgray-11" /> - </motion.div> - <motion.div - initial={{ y: '0%' }} - animate={loading && { opacity: 0, y: '30%' }} - > - Add - </motion.div> + <motion.div + initial={{ x: "-50%", y: "-100%" }} + animate={loading && { y: "-50%", x: "-50%", opacity: 1 }} + className="absolute left-1/2 top-1/2 -translate-x-1/2 translate-y-[-100%] opacity-0" + > + <Loader className="text-rgray-11 h-5 w-5 animate-spin" /> + </motion.div> + <motion.div + initial={{ y: "0%" }} + animate={loading && { opacity: 0, y: "30%" }} + > + Add + </motion.div> </button> - <DialogClose disabled={loading} className="disabled:opacity-70 disabled:cursor-not-allowed hover:bg-rgray-4 focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 rounded-md px-3 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2"> + <DialogClose + disabled={loading} + className="hover:bg-rgray-4 focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 rounded-md px-3 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-70" + > Cancel </DialogClose> </DialogFooter> @@ -313,15 +320,33 @@ export function SpaceAddPage({ closeDialog }: { closeDialog: () => void }) { ); } -export function MemorySelectedItem({ id, title, url, type, image, onRemove }: StoredContent & { onRemove: () => void; }) { - return ( - <div className="flex justify-start gap-2 p-1 px-2 w-full items-center text-sm rounded-md hover:bg-rgray-4 focus-within-bg-rgray-4 [&:hover>[data-icon]]:block [&:hover>img]:hidden"> - <img src={type === 'note'? '/note.svg' : image ?? "/icons/logo_without_bg.png"} className="h-5 w-5" /> - <button onClick={onRemove} data-icon className="w-5 h-5 p-0 m-0 hidden focus-visible:outline-none"> - <X className="w-5 h-5 scale-90" /> - </button> - <span>{title}</span> - <span className="ml-auto block opacity-50">{type ==='note' ? 'Note' : cleanUrl(url)}</span> - </div> - ) +export function MemorySelectedItem({ + id, + title, + url, + type, + image, + onRemove, +}: StoredContent & { onRemove: () => void }) { + return ( + <div className="hover:bg-rgray-4 focus-within-bg-rgray-4 flex w-full items-center justify-start gap-2 rounded-md p-1 px-2 text-sm [&:hover>[data-icon]]:block [&:hover>img]:hidden"> + <img + src={ + type === "note" ? "/note.svg" : image ?? "/icons/logo_without_bg.png" + } + className="h-5 w-5" + /> + <button + onClick={onRemove} + data-icon + className="m-0 hidden h-5 w-5 p-0 focus-visible:outline-none" + > + <X className="h-5 w-5 scale-90" /> + </button> + <span>{title}</span> + <span className="ml-auto block opacity-50"> + {type === "note" ? "Note" : cleanUrl(url)} + </span> + </div> + ); } diff --git a/apps/web/src/components/Sidebar/FilterCombobox.tsx b/apps/web/src/components/Sidebar/FilterCombobox.tsx index de2d5fe8..f93ae710 100644 --- a/apps/web/src/components/Sidebar/FilterCombobox.tsx +++ b/apps/web/src/components/Sidebar/FilterCombobox.tsx @@ -24,7 +24,8 @@ import { SearchResult, useMemory } from "@/contexts/MemoryContext"; import { useDebounce } from "@/hooks/useDebounce"; import { StoredContent } from "@/server/db/schema"; -export interface FilterSpacesProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { +export interface FilterSpacesProps + extends React.ButtonHTMLAttributes<HTMLButtonElement> { side?: "top" | "bottom"; align?: "end" | "start" | "center"; onClose?: () => void; @@ -153,7 +154,7 @@ export type FilterMemoriesProps = { onClose?: () => void; selected: StoredContent[]; setSelected: React.Dispatch<React.SetStateAction<StoredContent[]>>; -} & React.ButtonHTMLAttributes<HTMLButtonElement> +} & React.ButtonHTMLAttributes<HTMLButtonElement>; export function FilterMemories({ className, @@ -164,40 +165,39 @@ export function FilterMemories({ setSelected, ...props }: FilterMemoriesProps) { - - const { search } = useMemory(); + const { search } = useMemory(); const [open, setOpen] = React.useState(false); - const [searchQuery, setSearchQuery] = React.useState(""); - const query = useDebounce(searchQuery, 500) + const [searchQuery, setSearchQuery] = React.useState(""); + const query = useDebounce(searchQuery, 500); - const [searchResults, setSearchResults] = React.useState<SearchResult[]>([]); - const [isSearching, setIsSearching] = React.useState(false) + const [searchResults, setSearchResults] = React.useState<SearchResult[]>([]); + const [isSearching, setIsSearching] = React.useState(false); - const results = React.useMemo(() => { - return searchResults.map(r => r.memory) - }, [searchResults]) + const results = React.useMemo(() => { + return searchResults.map((r) => r.memory); + }, [searchResults]); - console.log('memoized', results) + console.log("memoized", results); - React.useEffect(() => { - const q = query.trim() - if (q.length > 0) { - setIsSearching(true); - (async () => { - const results = await search(q, { - filter: { - memories: true, - spaces: false - } - }) - setSearchResults(results) - setIsSearching(false) - })(); - } else { - setSearchResults([]) - } - }, [query]) + React.useEffect(() => { + const q = query.trim(); + if (q.length > 0) { + setIsSearching(true); + (async () => { + const results = await search(q, { + filter: { + memories: true, + spaces: false, + }, + }); + setSearchResults(results); + setIsSearching(false); + })(); + } else { + setSearchResults([]); + } + }, [query]); React.useEffect(() => { if (!open) { @@ -205,7 +205,7 @@ export function FilterMemories({ } }, [open]); - console.log(searchResults); + console.log(searchResults); return ( <AnimatePresence mode="popLayout"> <LayoutGroup> @@ -220,7 +220,7 @@ export function FilterMemories({ )} {...props} > - {props.children} + {props.children} </button> </PopoverTrigger> <PopoverContent @@ -229,43 +229,58 @@ export function FilterMemories({ side={side} className="w-[200px] p-0" > - <Command - shouldFilter={false} - > - <CommandInput isSearching={isSearching} value={searchQuery} onValueChange={setSearchQuery} placeholder="Filter memories..." /> + <Command shouldFilter={false}> + <CommandInput + isSearching={isSearching} + value={searchQuery} + onValueChange={setSearchQuery} + placeholder="Filter memories..." + /> <CommandList> - <CommandGroup> - <CommandEmpty className="text-rgray-11 text-sm text-center py-5">{isSearching ? "Searching..." : query.trim().length > 0 ? "Nothing Found" : "Search something"}</CommandEmpty> - {results.map((m) => ( - <CommandItem - key={m.id} - value={m.id.toString()} - onSelect={(val) => { - setSelected((prev) => - prev.find(p => p.id === parseInt(val)) - ? prev.filter((v) => v.id !== parseInt(val)) - : [...prev, m], - ); - }} - asChild - > - <div - className="text-rgray-11" - > - <img src={m.type === 'note' ? '/note.svg' : m.image ?? "/icons/logo_without_bg.png"} className="mr-2 h-4 w-4" /> - {m.title} - <Check - data-state-on={selected.find(i => i.id === m.id) !== undefined} - className={cn( - "on:opacity-100 ml-auto h-4 w-4 opacity-0", - )} - /> - </div> - </CommandItem> - ))} - - </CommandGroup> - </CommandList> + <CommandGroup> + <CommandEmpty className="text-rgray-11 py-5 text-center text-sm"> + {isSearching + ? "Searching..." + : query.trim().length > 0 + ? "Nothing Found" + : "Search something"} + </CommandEmpty> + {results.map((m) => ( + <CommandItem + key={m.id} + value={m.id.toString()} + onSelect={(val) => { + setSelected((prev) => + prev.find((p) => p.id === parseInt(val)) + ? prev.filter((v) => v.id !== parseInt(val)) + : [...prev, m], + ); + }} + asChild + > + <div className="text-rgray-11"> + <img + src={ + m.type === "note" + ? "/note.svg" + : m.image ?? "/icons/logo_without_bg.png" + } + className="mr-2 h-4 w-4" + /> + {m.title} + <Check + data-state-on={ + selected.find((i) => i.id === m.id) !== undefined + } + className={cn( + "on:opacity-100 ml-auto h-4 w-4 opacity-0", + )} + /> + </div> + </CommandItem> + ))} + </CommandGroup> + </CommandList> </Command> </PopoverContent> </Popover> diff --git a/apps/web/src/components/Sidebar/MemoriesBar.tsx b/apps/web/src/components/Sidebar/MemoriesBar.tsx index f474262a..6c640e26 100644 --- a/apps/web/src/components/Sidebar/MemoriesBar.tsx +++ b/apps/web/src/components/Sidebar/MemoriesBar.tsx @@ -44,7 +44,7 @@ import { DialogTrigger } from "@radix-ui/react-dialog"; import { AddMemoryPage, NoteAddPage, SpaceAddPage } from "./AddMemoryDialog"; import { ExpandedSpace } from "./ExpandedSpace"; import { StoredContent, StoredSpace } from "@/server/db/schema"; -import Image from "next/image" +import Image from "next/image"; import { useDebounce } from "@/hooks/useDebounce"; export function MemoriesBar() { @@ -57,11 +57,11 @@ export function MemoriesBar() { >(null); const [expandedSpace, setExpandedSpace] = useState<number | null>(null); - const [searchQuery, setSearcyQuery] = useState(""); - const [searchLoading, setSearchLoading] = useState(false) - const query = useDebounce(searchQuery, 500) + const [searchQuery, setSearcyQuery] = useState(""); + const [searchLoading, setSearchLoading] = useState(false); + const query = useDebounce(searchQuery, 500); - const [searchResults, setSearchResults] = useState<SearchResult[]>([]) + const [searchResults, setSearchResults] = useState<SearchResult[]>([]); if (expandedSpace) { return ( @@ -72,20 +72,20 @@ export function MemoriesBar() { ); } - useEffect(() => { - const q = query.trim() - if (q.length < 1) { - setSearchResults([]) - return - } + useEffect(() => { + const q = query.trim(); + if (q.length < 1) { + setSearchResults([]); + return; + } - setSearchLoading(true); + setSearchLoading(true); - (async () => { - setSearchResults(await search(q)) - setSearchLoading(false) - })(); - }, [query]) + (async () => { + setSearchResults(await search(q)); + setSearchLoading(false); + })(); + }, [query]); return ( <div className="text-rgray-11 flex w-full flex-col items-start py-8 text-left"> @@ -93,10 +93,16 @@ export function MemoriesBar() { <h1 className="w-full text-2xl">Your Memories</h1> <InputWithIcon placeholder="Search" - icon={searchLoading ? <Loader className="text-rgray-11 h-5 w-5 opacity-50 animate-spin" /> : <Search className="text-rgray-11 h-5 w-5 opacity-50" />} + icon={ + searchLoading ? ( + <Loader className="text-rgray-11 h-5 w-5 animate-spin opacity-50" /> + ) : ( + <Search className="text-rgray-11 h-5 w-5 opacity-50" /> + ) + } className="bg-rgray-4 mt-2 w-full" - value={searchQuery} - onChange={(e) => setSearcyQuery(e.target.value)} + value={searchQuery} + onChange={(e) => setSearcyQuery(e.target.value)} /> </div> <div className="mt-2 flex w-full px-8"> @@ -147,34 +153,32 @@ export function MemoriesBar() { ref={parent} className="grid w-full grid-flow-row grid-cols-3 gap-1 px-2 py-5" > - {query.trim().length > 0 ? ( - <> - {searchResults.map(({ type, space, memory }, i) => ( - <> - {type === "memory" && ( - <MemoryItem {...memory!} key={i} /> - )} - {type === "space" && ( - <SpaceItem {...space!} key={i} onDelete={() => {}} /> - )} - </> - ))} - </> - ): ( - <> - {spaces.map((space) => ( - <SpaceItem - onDelete={() => deleteSpace(space.id)} - key={space.id} - //onClick={() => setExpandedSpace(space.id)} - {...space} - /> - ))} - {freeMemories.map(m => ( - <MemoryItem {...m} key={m.id} /> - ))} - </> - )} + {query.trim().length > 0 ? ( + <> + {searchResults.map(({ type, space, memory }, i) => ( + <> + {type === "memory" && <MemoryItem {...memory!} key={i} />} + {type === "space" && ( + <SpaceItem {...space!} key={i} onDelete={() => {}} /> + )} + </> + ))} + </> + ) : ( + <> + {spaces.map((space) => ( + <SpaceItem + onDelete={() => deleteSpace(space.id)} + key={space.id} + //onClick={() => setExpandedSpace(space.id)} + {...space} + /> + ))} + {freeMemories.map((m) => ( + <MemoryItem {...m} key={m.id} /> + ))} + </> + )} </div> </div> ); @@ -190,44 +194,40 @@ const SpaceExitVariant: Variant = { }, }; -export function MemoryItem({ - id, - title, - image, - type -}: StoredContent) { +export function MemoryItem({ id, title, image, type }: StoredContent) { + const name = title + ? title.length > 10 + ? title.slice(0, 10) + "..." + : title + : "<no title>"; - const name = title ? title.length > 10 ? title.slice(0, 10) + "..." : title : '<no title>'; - - return ( - <div - - className="hover:bg-rgray-2 has-[[data-state='true']]:bg-rgray-2 has-[[data-space-text]:focus-visible]:bg-rgray-2 has-[[data-space-text]:focus-visible]:ring-rgray-7 [&:has-[[data-space-text]:focus-visible]>[data-more-button]]:opacity-100 relative flex select-none flex-col-reverse items-center justify-center rounded-md p-2 pb-4 text-center font-normal ring-transparent transition has-[[data-space-text]:focus-visible]:outline-none has-[[data-space-text]:focus-visible]:ring-2 md:has-[[data-state='true']]:bg-transparent [&:hover>[data-more-button]]:opacity-100" - > - <button data-space-text className="focus-visible:outline-none"> + return ( + <div className="hover:bg-rgray-2 has-[[data-state='true']]:bg-rgray-2 has-[[data-space-text]:focus-visible]:bg-rgray-2 has-[[data-space-text]:focus-visible]:ring-rgray-7 [&:has-[[data-space-text]:focus-visible]>[data-more-button]]:opacity-100 relative flex select-none flex-col-reverse items-center justify-center rounded-md p-2 pb-4 text-center font-normal ring-transparent transition has-[[data-space-text]:focus-visible]:outline-none has-[[data-space-text]:focus-visible]:ring-2 md:has-[[data-state='true']]:bg-transparent [&:hover>[data-more-button]]:opacity-100"> + <button data-space-text className="focus-visible:outline-none"> {name} </button> - - <div className="w-24 h-24 flex justify-center items-center"> - {type === "page" ? ( - <img - className="h-16 w-16" - id={id.toString()} - src={image!} - onError={(e) => { - (e.target as HTMLImageElement).src = "/icons/white_without_bg.png" - }} - /> - ): type === "note" ? ( - <div className="shadow-md rounded-md bg-rgray-4 p-2 flex justify-center items-center"> - <Text className="w-10 h-10" /> - </div> - ) : ( - <></> - )} - </div> - </div> - ) + + <div className="flex h-24 w-24 items-center justify-center"> + {type === "page" ? ( + <img + className="h-16 w-16" + id={id.toString()} + src={image!} + onError={(e) => { + (e.target as HTMLImageElement).src = + "/icons/white_without_bg.png"; + }} + /> + ) : type === "note" ? ( + <div className="bg-rgray-4 flex items-center justify-center rounded-md p-2 shadow-md"> + <Text className="h-10 w-10" /> + </div> + ) : ( + <></> + )} + </div> + </div> + ); } export function SpaceItem({ @@ -236,8 +236,7 @@ export function SpaceItem({ onDelete, onClick, }: StoredSpace & { onDelete: () => void; onClick?: () => void }) { - - const { cachedMemories } = useMemory(); + const { cachedMemories } = useMemory(); const [itemRef, animateItem] = useAnimate(); const { width } = useViewport(); @@ -250,11 +249,11 @@ export function SpaceItem({ }, }); - const spaceMemories = useMemo(() => { - return cachedMemories.filter(m => m.space === id) - }, [cachedMemories]) + const spaceMemories = useMemo(() => { + return cachedMemories.filter((m) => m.space === id); + }, [cachedMemories]); - const _name = name.length > 10 ? name.slice(0, 10) + "..." : name + const _name = name.length > 10 ? name.slice(0, 10) + "..." : name; return ( <motion.div ref={itemRef} @@ -269,110 +268,120 @@ export function SpaceItem({ isOpen={moreDropdownOpen} setIsOpen={setMoreDropdownOpen} onDelete={() => { - onDelete() - return; + onDelete(); + return; if (!itemRef.current || width < 768) { onDelete(); return; } - // const trash = document.querySelector("#trash")! as HTMLDivElement; - // const trashBin = document.querySelector("#trash-button")!; - // const trashRect = trashBin.getBoundingClientRect(); - // const scopeRect = itemRef.current.getBoundingClientRect(); - // const el = document.createElement("div"); - // el.style.position = "fixed"; - // el.style.top = "0"; - // el.style.left = "0"; - // el.style.width = "15px"; - // el.style.height = "15px"; - // el.style.backgroundColor = "var(--gray-7)"; - // el.style.zIndex = "60"; - // el.style.borderRadius = "50%"; - // el.style.transform = "scale(5)"; - // el.style.opacity = "0"; - // trash.dataset["open"] = "true"; - // const initial = { - // x: scopeRect.left + scopeRect.width / 2, - // y: scopeRect.top + scopeRect.height / 2, - // }; - // const delta = { - // x: - // trashRect.left + - // trashRect.width / 2 - - // scopeRect.left + - // scopeRect.width / 2, - // y: - // trashRect.top + - // trashRect.height / 4 - - // scopeRect.top + - // scopeRect.height / 2, - // }; - // const end = { - // x: trashRect.left + trashRect.width / 2, - // y: trashRect.top + trashRect.height / 4, - // }; - // el.style.offsetPath = `path('M ${initial.x} ${initial.y} Q ${delta.x * 0.01} ${delta.y * 0.01} ${end.x} ${end.y}`; - // animateItem(itemRef.current, SpaceExitVariant, { - // duration: 0.2, - // }).then(() => { - // itemRef.current.style.scale = "0"; - // onDelete(); - // }); - // document.body.appendChild(el); - // el.animate( - // { - // transform: ["scale(5)", "scale(1)"], - // opacity: [0, 0.3, 1], - // }, - // { - // duration: 200, - // easing: "cubic-bezier(0.64, 0.57, 0.67, 1.53)", - // fill: "forwards", - // }, - // ); - // el.animate( - // { - // offsetDistance: ["0%", "100%"], - // }, - // { - // duration: 2000, - // easing: "cubic-bezier(0.64, 0.57, 0.67, 1.53)", - // fill: "forwards", - // delay: 200, - // }, - // ).onfinish = () => { - // el.animate( - // { transform: "scale(0)", opacity: 0 }, - // { duration: 200, fill: "forwards" }, - // ).onfinish = () => { - // el.remove(); - // }; - // }; + // const trash = document.querySelector("#trash")! as HTMLDivElement; + // const trashBin = document.querySelector("#trash-button")!; + // const trashRect = trashBin.getBoundingClientRect(); + // const scopeRect = itemRef.current.getBoundingClientRect(); + // const el = document.createElement("div"); + // el.style.position = "fixed"; + // el.style.top = "0"; + // el.style.left = "0"; + // el.style.width = "15px"; + // el.style.height = "15px"; + // el.style.backgroundColor = "var(--gray-7)"; + // el.style.zIndex = "60"; + // el.style.borderRadius = "50%"; + // el.style.transform = "scale(5)"; + // el.style.opacity = "0"; + // trash.dataset["open"] = "true"; + // const initial = { + // x: scopeRect.left + scopeRect.width / 2, + // y: scopeRect.top + scopeRect.height / 2, + // }; + // const delta = { + // x: + // trashRect.left + + // trashRect.width / 2 - + // scopeRect.left + + // scopeRect.width / 2, + // y: + // trashRect.top + + // trashRect.height / 4 - + // scopeRect.top + + // scopeRect.height / 2, + // }; + // const end = { + // x: trashRect.left + trashRect.width / 2, + // y: trashRect.top + trashRect.height / 4, + // }; + // el.style.offsetPath = `path('M ${initial.x} ${initial.y} Q ${delta.x * 0.01} ${delta.y * 0.01} ${end.x} ${end.y}`; + // animateItem(itemRef.current, SpaceExitVariant, { + // duration: 0.2, + // }).then(() => { + // itemRef.current.style.scale = "0"; + // onDelete(); + // }); + // document.body.appendChild(el); + // el.animate( + // { + // transform: ["scale(5)", "scale(1)"], + // opacity: [0, 0.3, 1], + // }, + // { + // duration: 200, + // easing: "cubic-bezier(0.64, 0.57, 0.67, 1.53)", + // fill: "forwards", + // }, + // ); + // el.animate( + // { + // offsetDistance: ["0%", "100%"], + // }, + // { + // duration: 2000, + // easing: "cubic-bezier(0.64, 0.57, 0.67, 1.53)", + // fill: "forwards", + // delay: 200, + // }, + // ).onfinish = () => { + // el.animate( + // { transform: "scale(0)", opacity: 0 }, + // { duration: 200, fill: "forwards" }, + // ).onfinish = () => { + // el.remove(); + // }; + // }; }} /> {spaceMemories.length > 2 ? ( <MemoryWithImages3 className="h-24 w-24" id={id.toString()} - images={spaceMemories.map((c) => c.type === 'note' ? '/note.svg' : c.image).reverse() as string[]} + images={ + spaceMemories + .map((c) => (c.type === "note" ? "/note.svg" : c.image)) + .reverse() as string[] + } /> ) : spaceMemories.length > 1 ? ( - <MemoryWithImages2 + <MemoryWithImages2 className="h-24 w-24" id={id.toString()} - images={spaceMemories.map((c) => c.type === 'note' ? '/note.svg' : c.image).reverse() as string[]} + images={ + spaceMemories + .map((c) => (c.type === "note" ? "/note.svg" : c.image)) + .reverse() as string[] + } /> - ) : spaceMemories.length === 1 ? ( + ) : spaceMemories.length === 1 ? ( <MemoryWithImage className="h-24 w-24" id={id.toString()} - image={spaceMemories[0].type === 'note' ? '/note.svg' : spaceMemories[0].image!} + image={ + spaceMemories[0].type === "note" + ? "/note.svg" + : spaceMemories[0].image! + } /> ) : ( - <div className="bg-rgray-4 opacity-30 rounded-full w-24 h-24 scale-50 shadow-"> - - </div> - )} + <div className="bg-rgray-4 shadow- h-24 w-24 scale-50 rounded-full opacity-30"></div> + )} </motion.div> ); } @@ -409,34 +418,32 @@ export function SpaceMoreButton({ <Edit3 className="mr-2 h-4 w-4" strokeWidth={1.5} /> Edit </DropdownMenuItem> - <DialogTrigger asChild> - <DropdownMenuItem - className="focus:bg-red-100 focus:text-red-400 dark:focus:bg-red-100/10" - > - <Trash2 className="mr-2 h-4 w-4" strokeWidth={1.5} /> - Delete - </DropdownMenuItem> - </DialogTrigger> + <DialogTrigger asChild> + <DropdownMenuItem className="focus:bg-red-100 focus:text-red-400 dark:focus:bg-red-100/10"> + <Trash2 className="mr-2 h-4 w-4" strokeWidth={1.5} /> + Delete + </DropdownMenuItem> + </DialogTrigger> </DropdownMenuContent> </DropdownMenu> - <DialogContent> - <DialogTitle className='text-xl'>Are you sure?</DialogTitle> - <DialogDescription className='text-md'>You will not be able to recover this space</DialogDescription> - <DialogFooter> - <DialogClose - type={undefined} - onClick={onDelete} - className="bg-red-500/40 focus-visible:bg-red-500/60 focus-visible:ring-red-500 hover:bg-red-500/60 ml-auto flex items-center justify-center rounded-md px-3 py-2 transition focus-visible:outline-none focus-visible:ring-2" - > - Delete - </DialogClose> - <DialogClose - className="focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 hover:bg-rgray-4 ml-auto flex items-center justify-center rounded-md px-3 py-2 transition focus-visible:outline-none focus-visible:ring-2" - > - Cancel - </DialogClose> - </DialogFooter> - </DialogContent> + <DialogContent> + <DialogTitle className="text-xl">Are you sure?</DialogTitle> + <DialogDescription className="text-md"> + You will not be able to recover this space + </DialogDescription> + <DialogFooter> + <DialogClose + type={undefined} + onClick={onDelete} + className="ml-auto flex items-center justify-center rounded-md bg-red-500/40 px-3 py-2 transition hover:bg-red-500/60 focus-visible:bg-red-500/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500" + > + Delete + </DialogClose> + <DialogClose className="focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 hover:bg-rgray-4 ml-auto flex items-center justify-center rounded-md px-3 py-2 transition focus-visible:outline-none focus-visible:ring-2"> + Cancel + </DialogClose> + </DialogFooter> + </DialogContent> </Dialog> ); } diff --git a/apps/web/src/components/ui/command.tsx b/apps/web/src/components/ui/command.tsx index f3534b55..afc2cf46 100644 --- a/apps/web/src/components/ui/command.tsx +++ b/apps/web/src/components/ui/command.tsx @@ -7,7 +7,6 @@ import { Loader, Search } from "lucide-react"; import { cn } from "@/lib/utils"; import { Dialog, DialogContent } from "@/components/ui/dialog"; -import { isSea } from "node:sea"; const Command = React.forwardRef< React.ElementRef<typeof CommandPrimitive>, @@ -40,13 +39,19 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => { const CommandInput = React.forwardRef< React.ElementRef<typeof CommandPrimitive.Input>, - React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input> & { isSearching?: boolean } ->(({ className, isSearching = false ,...props }, ref) => ( + React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input> & { + isSearching?: boolean; + } +>(({ className, isSearching = false, ...props }, ref) => ( <div className="border-rgray-6 flex items-center border-b px-3" cmdk-input-wrapper="" > - {isSearching ? <Loader className="mr-2 h-4 w-4 shrink-9 opacity-50 animate-spin" /> : <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />} + {isSearching ? ( + <Loader className="shrink-9 mr-2 h-4 w-4 animate-spin opacity-50" /> + ) : ( + <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" /> + )} <CommandPrimitive.Input ref={ref} className={cn( diff --git a/apps/web/src/contexts/MemoryContext.tsx b/apps/web/src/contexts/MemoryContext.tsx index 67e6250e..e10984bb 100644 --- a/apps/web/src/contexts/MemoryContext.tsx +++ b/apps/web/src/contexts/MemoryContext.tsx @@ -1,14 +1,27 @@ "use client"; import React, { useCallback } from "react"; -import { ChachedSpaceContent, StoredContent, storedContent, StoredSpace } from "@/server/db/schema"; -import { addMemory, searchMemoriesAndSpaces, addSpace, fetchContentForSpace, deleteSpace, deleteMemory, fetchFreeMemories } from "@/actions/db"; +import { + ChachedSpaceContent, + StoredContent, + storedContent, + StoredSpace, +} from "@/server/db/schema"; +import { + addMemory, + searchMemoriesAndSpaces, + addSpace, + fetchContentForSpace, + deleteSpace, + deleteMemory, + fetchFreeMemories, +} from "@/actions/db"; import { User } from "next-auth"; export type SearchResult = { - type: "memory" | "space", - space: StoredSpace, - memory: StoredContent -} + type: "memory" | "space"; + space: StoredSpace; + memory: StoredContent; +}; // temperory (will change) export const MemoryContext = React.createContext<{ @@ -17,107 +30,118 @@ export const MemoryContext = React.createContext<{ addSpace: typeof addSpace; addMemory: typeof addMemory; cachedMemories: ChachedSpaceContent[]; - search: typeof searchMemoriesAndSpaces; - deleteSpace: typeof deleteSpace; - deleteMemory: typeof deleteMemory; + search: typeof searchMemoriesAndSpaces; + deleteSpace: typeof deleteSpace; + deleteMemory: typeof deleteMemory; }>({ spaces: [], freeMemories: [], - addMemory: (() => {}) as unknown as (typeof addMemory), - addSpace: (async () => {}) as unknown as (typeof addSpace), + addMemory: (() => {}) as unknown as typeof addMemory, + addSpace: (async () => {}) as unknown as typeof addSpace, cachedMemories: [], - search: async () => [], - deleteMemory: (() => {}) as unknown as (typeof deleteMemory), - deleteSpace: (() => {}) as unknown as (typeof deleteSpace) + search: async () => [], + deleteMemory: (() => {}) as unknown as typeof deleteMemory, + deleteSpace: (() => {}) as unknown as typeof deleteSpace, }); export const MemoryProvider: React.FC< { spaces: StoredSpace[]; freeMemories: StoredContent[]; - cachedMemories: ChachedSpaceContent[]; - user: User; + cachedMemories: ChachedSpaceContent[]; + user: User; } & React.PropsWithChildren -> = ({ children, user, spaces: initalSpaces, freeMemories: initialFreeMemories, cachedMemories: initialCachedMemories }) => { - +> = ({ + children, + user, + spaces: initalSpaces, + freeMemories: initialFreeMemories, + cachedMemories: initialCachedMemories, +}) => { const [spaces, setSpaces] = React.useState<StoredSpace[]>(initalSpaces); const [freeMemories, setFreeMemories] = React.useState<StoredContent[]>(initialFreeMemories); - const [cachedMemories, setCachedMemories] = React.useState<ChachedSpaceContent[]>( - initialCachedMemories - ); - - const _deleteSpace: typeof deleteSpace = async (...params) => { - const deleted = (await deleteSpace(...params))! + const [cachedMemories, setCachedMemories] = React.useState< + ChachedSpaceContent[] + >(initialCachedMemories); + + const _deleteSpace: typeof deleteSpace = async (...params) => { + const deleted = (await deleteSpace(...params))!; + + setSpaces((prev) => prev.filter((i) => i.id !== deleted.id)); + setCachedMemories((prev) => prev.filter((i) => i.space !== deleted.id)); - setSpaces(prev => prev.filter(i => i.id !== deleted.id)) - setCachedMemories(prev => prev.filter(i => i.space !== deleted.id)) + setFreeMemories(await fetchFreeMemories()); - setFreeMemories(await fetchFreeMemories()) + return deleted; + }; - return deleted - } + const _deleteMemory: typeof deleteMemory = async (...params) => { + const deleted = (await deleteMemory(...params))!; - const _deleteMemory: typeof deleteMemory = async (...params) => { - const deleted = (await deleteMemory(...params))! + setCachedMemories((prev) => prev.filter((i) => i.id !== deleted.id)); + setFreeMemories(await fetchFreeMemories()); - setCachedMemories(prev => prev.filter(i => i.id !== deleted.id)) - setFreeMemories(await fetchFreeMemories()) + return deleted; + }; - return deleted - } - // const fetchMemories = useCallback(async (query: string) => { // const response = await fetch(`/api/memories?${query}`); // }, []); - - const _addSpace: typeof addSpace = async (...params) => { - const { space: addedSpace, addedMemories } = (await addSpace(...params))!; - - setSpaces(prev => [...prev, addedSpace]) - const cachedMemories = (await fetchContentForSpace(addedSpace.id, { - offset: 0, - limit: 3 - })).map(m => ({ ...m, space: addedSpace.id })) - - setCachedMemories(prev => [...prev, ...cachedMemories]) - - setFreeMemories(await fetchFreeMemories()) - - return { - space: addedSpace, addedMemories - } - } - - const _addMemory: typeof addMemory = async (...params) => { - const { memory: addedMemory, addedToSpaces } = (await addMemory(...params))!; - - addedToSpaces.length > 0 ? setCachedMemories(prev => [ - ...prev, - ...addedToSpaces.map(s => ({ - ...addedMemory, - space: s.spaceId - })) - ]) : setFreeMemories(prev => [...prev, addedMemory]) - - return { - memory: addedMemory, - addedToSpaces - } - } + const _addSpace: typeof addSpace = async (...params) => { + const { space: addedSpace, addedMemories } = (await addSpace(...params))!; + + setSpaces((prev) => [...prev, addedSpace]); + const cachedMemories = ( + await fetchContentForSpace(addedSpace.id, { + offset: 0, + limit: 3, + }) + ).map((m) => ({ ...m, space: addedSpace.id })); + + setCachedMemories((prev) => [...prev, ...cachedMemories]); + + setFreeMemories(await fetchFreeMemories()); + + return { + space: addedSpace, + addedMemories, + }; + }; + + const _addMemory: typeof addMemory = async (...params) => { + const { memory: addedMemory, addedToSpaces } = (await addMemory( + ...params, + ))!; + + addedToSpaces.length > 0 + ? setCachedMemories((prev) => [ + ...prev, + ...addedToSpaces.map((s) => ({ + ...addedMemory, + space: s.spaceId, + })), + ]) + : setFreeMemories((prev) => [...prev, addedMemory]); + + return { + memory: addedMemory, + addedToSpaces, + }; + }; return ( <MemoryContext.Provider value={{ - search: searchMemoriesAndSpaces, + search: searchMemoriesAndSpaces, spaces, addSpace: _addSpace, deleteSpace: _deleteSpace, freeMemories, cachedMemories, - deleteMemory: _deleteMemory, + deleteMemory: _deleteMemory, addMemory: _addMemory, }} > diff --git a/apps/web/src/hooks/useDebounce.ts b/apps/web/src/hooks/useDebounce.ts index 4a47de72..d133b1ae 100644 --- a/apps/web/src/hooks/useDebounce.ts +++ b/apps/web/src/hooks/useDebounce.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useState } from "react"; /** * Use this hook when you need to debounce a value. diff --git a/apps/web/src/server/db/schema.ts b/apps/web/src/server/db/schema.ts index f3eafb94..cd2756f1 100644 --- a/apps/web/src/server/db/schema.ts +++ b/apps/web/src/server/db/schema.ts @@ -21,7 +21,7 @@ export const users = createTable("user", { image: text("image", { length: 255 }), }); -export type User = typeof users.$inferSelect +export type User = typeof users.$inferSelect; export const usersRelations = relations(users, ({ many }) => ({ accounts: many(accounts), @@ -34,7 +34,7 @@ export const accounts = createTable( id: integer("id").notNull().primaryKey({ autoIncrement: true }), userId: text("userId", { length: 255 }) .notNull() - .references(() => users.id, { onDelete: 'cascade' }), + .references(() => users.id, { onDelete: "cascade" }), type: text("type", { length: 255 }).notNull(), provider: text("provider", { length: 255 }).notNull(), providerAccountId: text("providerAccountId", { length: 255 }).notNull(), @@ -60,7 +60,7 @@ export const sessions = createTable( sessionToken: text("sessionToken", { length: 255 }).notNull(), userId: text("userId", { length: 255 }) .notNull() - .references(() => users.id, { onDelete: 'cascade' }), + .references(() => users.id, { onDelete: "cascade" }), expires: int("expires", { mode: "timestamp" }).notNull(), }, (session) => ({ @@ -94,7 +94,9 @@ export const storedContent = createTable( "page", ), image: text("image", { length: 255 }), - user: text("user", { length: 255 }).references(() => users.id, { onDelete: 'cascade' }), + user: text("user", { length: 255 }).references(() => users.id, { + onDelete: "cascade", + }), }, (sc) => ({ urlIdx: index("storedContent_url_idx").on(sc.url), @@ -109,10 +111,10 @@ export const contentToSpace = createTable( { contentId: integer("contentId") .notNull() - .references(() => storedContent.id, { onDelete: 'cascade' }), + .references(() => storedContent.id, { onDelete: "cascade" }), spaceId: integer("spaceId") .notNull() - .references(() => space.id, { onDelete: 'cascade' }), + .references(() => space.id, { onDelete: "cascade" }), }, (cts) => ({ compoundKey: primaryKey({ columns: [cts.contentId, cts.spaceId] }), @@ -124,7 +126,9 @@ export const space = createTable( { id: integer("id").notNull().primaryKey({ autoIncrement: true }), name: text("name").notNull().unique().default("none"), - user: text("user", { length: 255 }).references(() => users.id, { onDelete: 'cascade' }), + user: text("user", { length: 255 }).references(() => users.id, { + onDelete: "cascade", + }), }, (space) => ({ nameIdx: index("spaces_name_idx").on(space.name), @@ -135,5 +139,5 @@ export const space = createTable( export type StoredContent = Omit<typeof storedContent.$inferSelect, "user">; export type StoredSpace = typeof space.$inferSelect; export type ChachedSpaceContent = StoredContent & { - space: number; -} + space: number; +}; diff --git a/apps/web/src/server/db/test.ts b/apps/web/src/server/db/test.ts index 9cb8f2b5..37969e5e 100644 --- a/apps/web/src/server/db/test.ts +++ b/apps/web/src/server/db/test.ts @@ -1,10 +1,6 @@ -import { db } from "." -import { space, user } from "./schema" +import { db } from "."; +import { space, user } from "./schema"; -const user = await db.select(user).all() +const user = await db.select(user).all(); -await db.insert(space).values([ - { - - } -]) +await db.insert(space).values([{}]); diff --git a/apps/web/src/server/helpers.ts b/apps/web/src/server/helpers.ts index f1ac078c..9a9a9607 100644 --- a/apps/web/src/server/helpers.ts +++ b/apps/web/src/server/helpers.ts @@ -1,28 +1,32 @@ -'use server'; -import * as cheerio from "cheerio" +"use server"; +import * as cheerio from "cheerio"; export async function getMetaData(url: string) { const response = await fetch(url); const html = await response.text(); - - const $ = cheerio.load(html) + + const $ = cheerio.load(html); // Extract the base URL const baseUrl = new URL(url).origin; // Extract title - const title = $('title').text().trim() - - const description = $('meta[name=description]').attr('content') ?? '' - - const _favicon = $('link[rel=icon]').attr('href') ?? 'https://supermemory.dhr.wtf/web.svg'; - - let favicon = _favicon.trim().length > 0 ? _favicon.trim() : 'https://supermemory.dhr.wtf/web.svg' - if (favicon.startsWith("/")) { - favicon = baseUrl + favicon - } else if (favicon.startsWith("./")) { - favicon = baseUrl + favicon.slice(1) - } + const title = $("title").text().trim(); + + const description = $("meta[name=description]").attr("content") ?? ""; + + const _favicon = + $("link[rel=icon]").attr("href") ?? "https://supermemory.dhr.wtf/web.svg"; + + let favicon = + _favicon.trim().length > 0 + ? _favicon.trim() + : "https://supermemory.dhr.wtf/web.svg"; + if (favicon.startsWith("/")) { + favicon = baseUrl + favicon; + } else if (favicon.startsWith("./")) { + favicon = baseUrl + favicon.slice(1); + } // Prepare the metadata object const metadata = { diff --git a/apps/web/types/memory.tsx b/apps/web/types/memory.tsx index 287f763c..6bfda971 100644 --- a/apps/web/types/memory.tsx +++ b/apps/web/types/memory.tsx @@ -14,40 +14,55 @@ export async function fetchContentForSpace( limit: number; }, ) { - const query = db .select() .from(storedContent) .where( exists( - db.select().from(contentToSpace).where(and(eq(contentToSpace.spaceId, spaceId), eq(contentToSpace.contentId, storedContent.id))), + db + .select() + .from(contentToSpace) + .where( + and( + eq(contentToSpace.spaceId, spaceId), + eq(contentToSpace.contentId, storedContent.id), + ), + ), ), - ).orderBy(asc(storedContent.title)) + ) + .orderBy(asc(storedContent.title)); - return range ? await query.limit(range.limit).offset(range.offset) : await query.all() + return range + ? await query.limit(range.limit).offset(range.offset) + : await query.all(); } export async function fetchFreeMemories( - userId: string, - range?: { - offset: number; - limit: number; - } + userId: string, + range?: { + offset: number; + limit: number; + }, ) { - const query = db + const query = db .select() .from(storedContent) .where( - and( - notExists( - db.select().from(contentToSpace).where(eq(contentToSpace.contentId, storedContent.id)), - ), - eq(storedContent.user, userId), - ) - - ).orderBy(asc(storedContent.title)) + and( + notExists( + db + .select() + .from(contentToSpace) + .where(eq(contentToSpace.contentId, storedContent.id)), + ), + eq(storedContent.user, userId), + ), + ) + .orderBy(asc(storedContent.title)); - return range ? await query.limit(range.limit).offset(range.offset) : await query.all() + return range + ? await query.limit(range.limit).offset(range.offset) + : await query.all(); } export const transformContent = async ( diff --git a/apps/web/wrangler.toml b/apps/web/wrangler.toml index 049e482b..2db56e0d 100644 --- a/apps/web/wrangler.toml +++ b/apps/web/wrangler.toml @@ -17,4 +17,7 @@ type = "ratelimit" namespace_id = "1001" # 25 requests per 10 seconds -simple = { limit = 25, period = 10 }
\ No newline at end of file +simple = { limit = 25, period = 10 } + +[placement] +mode = "smart"
\ No newline at end of file |