diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml
index 81659d6cd..0dd2e1809 100644
--- a/.github/workflows/code-quality.yml
+++ b/.github/workflows/code-quality.yml
@@ -61,7 +61,7 @@ jobs:
echo "Running file quality hooks on changed files against $BASE_REF"
# Run each hook individually on changed files
- SKIP=detect-secrets,bandit,ruff,ruff-format,prettier,eslint,typescript-check-web,typescript-check-extension,commitizen \
+ SKIP=detect-secrets,bandit,ruff,ruff-format,biome-check-web,biome-check-extension,commitizen \
pre-commit run --from-ref $BASE_REF --to-ref HEAD || exit_code=$?
# Exit with the same code as pre-commit
@@ -118,7 +118,7 @@ jobs:
echo "Running security scans on changed files against $BASE_REF"
# Run only security hooks on changed files
- SKIP=check-yaml,check-json,check-toml,check-merge-conflict,check-added-large-files,debug-statements,check-case-conflict,ruff,ruff-format,prettier,eslint,typescript-check-web,typescript-check-extension,commitizen \
+ SKIP=check-yaml,check-json,check-toml,check-merge-conflict,check-added-large-files,debug-statements,check-case-conflict,ruff,ruff-format,biome-check-web,biome-check-extension,commitizen \
pre-commit run --from-ref $BASE_REF --to-ref HEAD || exit_code=$?
# Exit with the same code as pre-commit
@@ -199,7 +199,89 @@ jobs:
echo "Running Python backend checks on changed files against $BASE_REF"
# Run only ruff hooks on changed Python files
- SKIP=detect-secrets,bandit,check-yaml,check-json,check-toml,check-merge-conflict,check-added-large-files,debug-statements,check-case-conflict,prettier,eslint,typescript-check-web,typescript-check-extension,commitizen \
+ SKIP=detect-secrets,bandit,check-yaml,check-json,check-toml,check-merge-conflict,check-added-large-files,debug-statements,check-case-conflict,biome-check-web,biome-check-extension,commitizen \
+ pre-commit run --from-ref $BASE_REF --to-ref HEAD || exit_code=$?
+
+ # Exit with the same code as pre-commit
+ exit ${exit_code:-0}
+
+ typescript-frontend:
+ name: TypeScript/JavaScript Quality
+ runs-on: ubuntu-latest
+ if: github.event.pull_request.draft == false
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Fetch base branch
+ run: |
+ git fetch origin ${{ github.base_ref }}:${{ github.base_ref }} 2>/dev/null || git fetch origin ${{ github.base_ref }} 2>/dev/null || true
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '18'
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: latest
+
+ - name: Check if frontend files changed
+ id: frontend-changes
+ uses: dorny/paths-filter@v3
+ with:
+ filters: |
+ web:
+ - 'surfsense_web/**'
+ extension:
+ - 'surfsense_browser_extension/**'
+
+ - name: Install dependencies for web
+ if: steps.frontend-changes.outputs.web == 'true'
+ working-directory: surfsense_web
+ run: pnpm install --frozen-lockfile
+
+ - name: Install dependencies for extension
+ if: steps.frontend-changes.outputs.extension == 'true'
+ working-directory: surfsense_browser_extension
+ run: pnpm install --frozen-lockfile
+
+ - name: Install pre-commit
+ run: pip install pre-commit
+
+ - name: Cache pre-commit hooks
+ uses: actions/cache@v4
+ with:
+ path: ~/.cache/pre-commit
+ key: pre-commit-frontend-${{ hashFiles('.pre-commit-config.yaml') }}
+ restore-keys: |
+ pre-commit-frontend-
+
+ - name: Install hook environments (cache)
+ run: pre-commit install-hooks
+
+ - name: Run TypeScript/JavaScript quality checks
+ run: |
+ # Get base ref for comparison
+ if git show-ref --verify --quiet refs/heads/${{ github.base_ref }}; then
+ BASE_REF="${{ github.base_ref }}"
+ elif git show-ref --verify --quiet refs/remotes/origin/${{ github.base_ref }}; then
+ BASE_REF="origin/${{ github.base_ref }}"
+ else
+ echo "Base branch reference not found, running TypeScript/JavaScript checks on all files"
+ pre-commit run --all-files biome-check-web biome-check-extension
+ exit 0
+ fi
+
+ echo "Running TypeScript/JavaScript checks on changed files against $BASE_REF"
+
+ # Run only Biome hooks on changed TypeScript/JavaScript files
+ # Biome hooks use --diagnostic-level=error to only fail on errors, not warnings
+ SKIP=detect-secrets,bandit,check-yaml,check-json,check-toml,check-merge-conflict,check-added-large-files,debug-statements,check-case-conflict,ruff,ruff-format,commitizen \
pre-commit run --from-ref $BASE_REF --to-ref HEAD || exit_code=$?
# Exit with the same code as pre-commit
@@ -208,7 +290,7 @@ jobs:
quality-gate:
name: Quality Gate
runs-on: ubuntu-latest
- needs: [file-quality, security-scan, python-backend]
+ needs: [file-quality, security-scan, python-backend, typescript-frontend]
if: always()
steps:
@@ -216,7 +298,8 @@ jobs:
run: |
if [[ "${{ needs.file-quality.result }}" == "failure" ||
"${{ needs.security-scan.result }}" == "failure" ||
- "${{ needs.python-backend.result }}" == "failure" ]]; then
+ "${{ needs.python-backend.result }}" == "failure" ||
+ "${{ needs.typescript-frontend.result }}" == "failure" ]]; then
echo "❌ Code quality checks failed"
exit 1
else
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4486a9fad..6cccf2729 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -60,45 +60,28 @@ repos:
args: ['-f', 'json', '--severity-level', 'high', '--confidence-level', 'high']
exclude: ^surfsense_backend/(tests/|test_.*\.py|.*test.*\.py|alembic/)
- # Frontend/Extension Hooks (TypeScript/JavaScript)
- - repo: https://github.com/pre-commit/mirrors-prettier
- rev: v4.0.0-alpha.8
- hooks:
- - id: prettier
- files: ^(surfsense_web|surfsense_browser_extension)/
- types_or: [javascript, jsx, ts, tsx, json, yaml, markdown]
- exclude: '(package-lock\.json|\.next/|build/|dist/)'
-
- - repo: https://github.com/pre-commit/mirrors-eslint
- rev: v9.31.0
- hooks:
- - id: eslint
- files: ^surfsense_web/
- types: [file]
- types_or: [javascript, jsx, ts, tsx]
- additional_dependencies:
- - 'eslint@^9'
- - 'eslint-config-next@15.2.0'
- - '@eslint/eslintrc@^3'
- args: [--fix]
- exclude: '(\.next/|build/|dist/)'
-
- # TypeScript compilation check
+ # Biome hooks for TypeScript/JavaScript projects
- repo: local
hooks:
- - id: typescript-check-web
- name: TypeScript Check (Web)
- entry: bash -c 'cd surfsense_web && (command -v pnpm >/dev/null 2>&1 && pnpm build --dry-run || npx next build --dry-run)'
+ # Biome check for surfsense_web
+ - id: biome-check-web
+ name: biome-check-web
+ entry: bash -c 'cd surfsense_web && npx @biomejs/biome check --diagnostic-level=error .'
language: system
- files: ^surfsense_web/.*\.(ts|tsx)$
+ files: ^surfsense_web/
pass_filenames: false
+ always_run: true
+ stages: [pre-commit]
- - id: typescript-check-extension
- name: TypeScript Check (Browser Extension)
- entry: bash -c 'cd surfsense_browser_extension && npx tsc --noEmit'
+ # Biome check for surfsense_browser_extension
+ - id: biome-check-extension
+ name: biome-check-extension
+ entry: bash -c 'cd surfsense_browser_extension && npx @biomejs/biome check --diagnostic-level=error .'
language: system
- files: ^surfsense_browser_extension/.*\.(ts|tsx)$
+ files: ^surfsense_browser_extension/
pass_filenames: false
+ always_run: true
+ stages: [pre-commit]
# Commit message linting
- repo: https://github.com/commitizen-tools/commitizen
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 000000000..f134660b6
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "biome.configurationPath": "./surfsense_web/biome.json"
+}
\ No newline at end of file
diff --git a/biome.json b/biome.json
new file mode 100644
index 000000000..6e17e7f14
--- /dev/null
+++ b/biome.json
@@ -0,0 +1,115 @@
+{
+ "$schema": "https://biomejs.dev/schemas/2.1.2/schema.json",
+ "vcs": {
+ "enabled": true,
+ "clientKind": "git",
+ "useIgnoreFile": true
+ },
+ "files": {
+ "ignoreUnknown": true,
+ "experimentalScannerIgnores": ["node_modules", ".git", ".next", "dist", "build", "coverage"],
+ "maxSize": 1048576
+ },
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "tab",
+ "indentWidth": 2,
+ "lineWidth": 100,
+ "lineEnding": "lf",
+ "formatWithErrors": false
+ },
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": true,
+ "suspicious": {
+ "noExplicitAny": "warn",
+ "noArrayIndexKey": "warn"
+ },
+ "style": {
+ "useConst": "error",
+ "useTemplate": "warn"
+ },
+ "correctness": {
+ "useExhaustiveDependencies": "warn"
+ }
+ }
+ },
+ "javascript": {
+ "formatter": {
+ "quoteStyle": "double",
+ "jsxQuoteStyle": "double",
+ "quoteProperties": "asNeeded",
+ "trailingCommas": "es5",
+ "semicolons": "always",
+ "arrowParentheses": "always",
+ "bracketSameLine": false,
+ "bracketSpacing": true
+ },
+ "linter": {
+ "enabled": true
+ },
+ "assist": {
+ "enabled": true
+ }
+ },
+ "json": {
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "tab",
+ "indentWidth": 2,
+ "lineWidth": 100
+ },
+ "linter": {
+ "enabled": true
+ }
+ },
+ "css": {
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "tab",
+ "indentWidth": 2,
+ "lineWidth": 100,
+ "quoteStyle": "double"
+ },
+ "linter": {
+ "enabled": true
+ }
+ },
+ "assist": {
+ "enabled": true,
+ "actions": {
+ "source": {
+ "organizeImports": "on"
+ }
+ }
+ },
+ "overrides": [
+ {
+ "includes": ["*.json", "*.jsonc"],
+ "json": {
+ "parser": {
+ "allowComments": true,
+ "allowTrailingCommas": false
+ }
+ }
+ },
+ {
+ "includes": [".vscode/**/*.json"],
+ "json": {
+ "parser": {
+ "allowComments": true,
+ "allowTrailingCommas": true
+ }
+ }
+ },
+ {
+ "includes": ["**/*.config.*", "**/next.config.*"],
+ "javascript": {
+ "formatter": {
+ "semicolons": "always"
+ }
+ }
+ }
+ ]
+}
diff --git a/surfsense_backend/app/tasks/podcast_tasks.py b/surfsense_backend/app/tasks/podcast_tasks.py
index 6bc3510d9..312ae5bc3 100644
--- a/surfsense_backend/app/tasks/podcast_tasks.py
+++ b/surfsense_backend/app/tasks/podcast_tasks.py
@@ -76,18 +76,10 @@ async def generate_chat_podcast(
chat_history_str += f"{message['content']}"
processed_messages += 1
elif message["role"] == "assistant":
- # Last annotation type will always be "ANSWER" here
- answer_annotation = message["annotations"][-1]
- answer_text = ""
- if answer_annotation["type"] == "ANSWER":
- answer_text = answer_annotation["content"]
- # If content is a list, join it into a single string
- if isinstance(answer_text, list):
- answer_text = "\n".join(answer_text)
- chat_history_str += (
- f"{answer_text}"
- )
- processed_messages += 1
+ chat_history_str += (
+ f"{message['content']}"
+ )
+ processed_messages += 1
chat_history_str += ""
diff --git a/surfsense_browser_extension/.prettierrc.mjs b/surfsense_browser_extension/.prettierrc.mjs
deleted file mode 100644
index 77f84c218..000000000
--- a/surfsense_browser_extension/.prettierrc.mjs
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * @type {import('prettier').Options}
- */
-export default {
- printWidth: 80,
- tabWidth: 2,
- useTabs: false,
- semi: false,
- singleQuote: false,
- trailingComma: "none",
- bracketSpacing: true,
- bracketSameLine: true,
- plugins: ["@ianvs/prettier-plugin-sort-imports"],
- importOrder: [
- "", // Node.js built-in modules
- "", // Imports not matched by other special words or groups.
- "", // Empty line
- "^@plasmo/(.*)$",
- "",
- "^@plasmohq/(.*)$",
- "",
- "^~(.*)$",
- "",
- "^[./]"
- ]
-}
diff --git a/surfsense_browser_extension/background/index.ts b/surfsense_browser_extension/background/index.ts
index 8710fd453..8d66cf117 100644
--- a/surfsense_browser_extension/background/index.ts
+++ b/surfsense_browser_extension/background/index.ts
@@ -1,77 +1,70 @@
-import { initQueues, initWebHistory } from "~utils/commons"
-import type { WebHistory } from "~utils/interfaces"
-import { Storage } from "@plasmohq/storage"
-import {getRenderedHtml} from '~utils/commons'
+import { Storage } from "@plasmohq/storage";
+import { getRenderedHtml, initQueues, initWebHistory } from "~utils/commons";
+import type { WebHistory } from "~utils/interfaces";
chrome.tabs.onCreated.addListener(async (tab: any) => {
- try {
- await initWebHistory(tab.id)
- await initQueues(tab.id)
- } catch (error) {
- console.log(error)
- }
-})
+ try {
+ await initWebHistory(tab.id);
+ await initQueues(tab.id);
+ } catch (error) {
+ console.log(error);
+ }
+});
-chrome.tabs.onUpdated.addListener(
- async (tabId: number, changeInfo: any, tab: any) => {
- if (changeInfo.status === "complete" && tab.url) {
- const storage = new Storage({ area: "local" })
- await initWebHistory(tab.id)
- await initQueues(tab.id)
+chrome.tabs.onUpdated.addListener(async (tabId: number, changeInfo: any, tab: any) => {
+ if (changeInfo.status === "complete" && tab.url) {
+ const storage = new Storage({ area: "local" });
+ await initWebHistory(tab.id);
+ await initQueues(tab.id);
- const result = await chrome.scripting.executeScript({
- // @ts-ignore
- target: { tabId: tab.id },
- // @ts-ignore
- func: getRenderedHtml
- })
+ const result = await chrome.scripting.executeScript({
+ // @ts-ignore
+ target: { tabId: tab.id },
+ // @ts-ignore
+ func: getRenderedHtml,
+ });
- let toPushInTabHistory: any = result[0].result // const { renderedHtml, title, url, entryTime } = result[0].result;
+ const toPushInTabHistory: any = result[0].result; // const { renderedHtml, title, url, entryTime } = result[0].result;
- let urlQueueListObj: any = await storage.get("urlQueueList")
- let timeQueueListObj: any = await storage.get("timeQueueList")
+ const urlQueueListObj: any = await storage.get("urlQueueList");
+ const timeQueueListObj: any = await storage.get("timeQueueList");
- urlQueueListObj.urlQueueList
- .find((data: WebHistory) => data.tabsessionId === tabId)
- .urlQueue.push(toPushInTabHistory.url)
- timeQueueListObj.timeQueueList
- .find((data: WebHistory) => data.tabsessionId === tabId)
- .timeQueue.push(toPushInTabHistory.entryTime)
+ urlQueueListObj.urlQueueList
+ .find((data: WebHistory) => data.tabsessionId === tabId)
+ .urlQueue.push(toPushInTabHistory.url);
+ timeQueueListObj.timeQueueList
+ .find((data: WebHistory) => data.tabsessionId === tabId)
+ .timeQueue.push(toPushInTabHistory.entryTime);
- await storage.set("urlQueueList", {
- urlQueueList: urlQueueListObj.urlQueueList
- })
- await storage.set("timeQueueList", {
- timeQueueList: timeQueueListObj.timeQueueList
- })
- }
- }
-)
+ await storage.set("urlQueueList", {
+ urlQueueList: urlQueueListObj.urlQueueList,
+ });
+ await storage.set("timeQueueList", {
+ timeQueueList: timeQueueListObj.timeQueueList,
+ });
+ }
+});
chrome.tabs.onRemoved.addListener(async (tabId: number, removeInfo: object) => {
- const storage = new Storage({ area: "local" })
- let urlQueueListObj: any = await storage.get("urlQueueList")
- let timeQueueListObj: any = await storage.get("timeQueueList")
- if (urlQueueListObj.urlQueueList && timeQueueListObj.timeQueueList) {
- const urlQueueListToSave = urlQueueListObj.urlQueueList.map(
- (element: WebHistory) => {
- if (element.tabsessionId !== tabId) {
- return element
- }
- }
- )
- const timeQueueListSave = timeQueueListObj.timeQueueList.map(
- (element: WebHistory) => {
- if (element.tabsessionId !== tabId) {
- return element
- }
- }
- )
- await storage.set("urlQueueList", {
- urlQueueList: urlQueueListToSave.filter((item: any) => item)
- })
- await storage.set("timeQueueList", {
- timeQueueList: timeQueueListSave.filter((item: any) => item)
- })
- }
-})
+ const storage = new Storage({ area: "local" });
+ const urlQueueListObj: any = await storage.get("urlQueueList");
+ const timeQueueListObj: any = await storage.get("timeQueueList");
+ if (urlQueueListObj.urlQueueList && timeQueueListObj.timeQueueList) {
+ const urlQueueListToSave = urlQueueListObj.urlQueueList.map((element: WebHistory) => {
+ if (element.tabsessionId !== tabId) {
+ return element;
+ }
+ });
+ const timeQueueListSave = timeQueueListObj.timeQueueList.map((element: WebHistory) => {
+ if (element.tabsessionId !== tabId) {
+ return element;
+ }
+ });
+ await storage.set("urlQueueList", {
+ urlQueueList: urlQueueListToSave.filter((item: any) => item),
+ });
+ await storage.set("timeQueueList", {
+ timeQueueList: timeQueueListSave.filter((item: any) => item),
+ });
+ }
+});
diff --git a/surfsense_browser_extension/background/messages/savedata.ts b/surfsense_browser_extension/background/messages/savedata.ts
index e1e010a48..bd422af19 100644
--- a/surfsense_browser_extension/background/messages/savedata.ts
+++ b/surfsense_browser_extension/background/messages/savedata.ts
@@ -1,149 +1,150 @@
-import type { PlasmoMessaging } from "@plasmohq/messaging"
-import { Storage } from "@plasmohq/storage"
+import type { PlasmoMessaging } from "@plasmohq/messaging";
+import { Storage } from "@plasmohq/storage";
-import {
- emptyArr,
- webhistoryToLangChainDocument
-} from "~utils/commons"
+import { emptyArr, webhistoryToLangChainDocument } from "~utils/commons";
const clearMemory = async () => {
- try {
- const storage = new Storage({ area: "local" })
+ try {
+ const storage = new Storage({ area: "local" });
- let webHistory: any = await storage.get("webhistory")
- let urlQueue: any = await storage.get("urlQueueList")
- let timeQueue: any = await storage.get("timeQueueList")
+ const webHistory: any = await storage.get("webhistory");
+ const urlQueue: any = await storage.get("urlQueueList");
+ const timeQueue: any = await storage.get("timeQueueList");
- if (!webHistory.webhistory) {
- return
- }
+ if (!webHistory.webhistory) {
+ return;
+ }
- //Main Cleanup COde
- chrome.tabs.query({}, async (tabs) => {
- //Get Active Tabs Ids
- // console.log("Event Tabs",tabs)
- let actives = tabs.map((tab) => {
- if (tab.id) {
- return tab.id
- }
- })
+ //Main Cleanup COde
+ chrome.tabs.query({}, async (tabs) => {
+ //Get Active Tabs Ids
+ // console.log("Event Tabs",tabs)
+ let actives = tabs.map((tab) => {
+ if (tab.id) {
+ return tab.id;
+ }
+ });
- actives = actives.filter((item: any) => item)
+ actives = actives.filter((item: any) => item);
- //Only retain which is still active
- const newHistory = webHistory.webhistory.map((element: any) => {
- //@ts-ignore
- if (actives.includes(element.tabsessionId)) {
- return element
- }
- })
+ //Only retain which is still active
+ const newHistory = webHistory.webhistory.map((element: any) => {
+ //@ts-ignore
+ if (actives.includes(element.tabsessionId)) {
+ return element;
+ }
+ });
- const newUrlQueue = urlQueue.urlQueueList.map((element: any) => {
- //@ts-ignore
- if (actives.includes(element.tabsessionId)) {
- return element
- }
- })
+ const newUrlQueue = urlQueue.urlQueueList.map((element: any) => {
+ //@ts-ignore
+ if (actives.includes(element.tabsessionId)) {
+ return element;
+ }
+ });
- const newTimeQueue = timeQueue.timeQueueList.map((element: any) => {
- //@ts-ignore
- if (actives.includes(element.tabsessionId)) {
- return element
- }
- })
+ const newTimeQueue = timeQueue.timeQueueList.map((element: any) => {
+ //@ts-ignore
+ if (actives.includes(element.tabsessionId)) {
+ return element;
+ }
+ });
- await storage.set("webhistory", {
- webhistory: newHistory.filter((item: any) => item)
- })
- await storage.set("urlQueueList", {
- urlQueueList: newUrlQueue.filter((item: any) => item)
- })
- await storage.set("timeQueueList", {
- timeQueueList: newTimeQueue.filter((item: any) => item)
- })
- })
- } catch (error) {
- console.log(error)
- }
-}
+ await storage.set("webhistory", {
+ webhistory: newHistory.filter((item: any) => item),
+ });
+ await storage.set("urlQueueList", {
+ urlQueueList: newUrlQueue.filter((item: any) => item),
+ });
+ await storage.set("timeQueueList", {
+ timeQueueList: newTimeQueue.filter((item: any) => item),
+ });
+ });
+ } catch (error) {
+ console.log(error);
+ }
+};
const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
- try {
- const storage = new Storage({ area: "local" })
+ try {
+ const storage = new Storage({ area: "local" });
- const webhistoryObj: any = await storage.get("webhistory")
- const webhistory = webhistoryObj.webhistory
- if (webhistory) {
- let toSaveFinally: any[] = []
- let newHistoryAfterCleanup: any[] = []
+ const webhistoryObj: any = await storage.get("webhistory");
+ const webhistory = webhistoryObj.webhistory;
+ if (webhistory) {
+ const toSaveFinally: any[] = [];
+ const newHistoryAfterCleanup: any[] = [];
- for (let i = 0; i < webhistory.length; i++) {
- const markdownFormat = webhistoryToLangChainDocument(
- webhistory[i].tabsessionId,
- webhistory[i].tabHistory
- )
- toSaveFinally.push(...markdownFormat)
- newHistoryAfterCleanup.push({
- tabsessionId: webhistory[i].tabsessionId,
- tabHistory: emptyArr
- })
- }
+ for (let i = 0; i < webhistory.length; i++) {
+ const markdownFormat = webhistoryToLangChainDocument(
+ webhistory[i].tabsessionId,
+ webhistory[i].tabHistory
+ );
+ toSaveFinally.push(...markdownFormat);
+ newHistoryAfterCleanup.push({
+ tabsessionId: webhistory[i].tabsessionId,
+ tabHistory: emptyArr,
+ });
+ }
- await storage.set("webhistory",{ webhistory: newHistoryAfterCleanup });
+ await storage.set("webhistory", { webhistory: newHistoryAfterCleanup });
- // Log first item to debug metadata structure
- if (toSaveFinally.length > 0) {
- console.log("First item metadata:", toSaveFinally[0].metadata);
- }
+ // Log first item to debug metadata structure
+ if (toSaveFinally.length > 0) {
+ console.log("First item metadata:", toSaveFinally[0].metadata);
+ }
- // Create content array for documents in the format expected by the new API
- const content = toSaveFinally.map(item => ({
- metadata: {
- BrowsingSessionId: String(item.metadata.BrowsingSessionId || ""),
- VisitedWebPageURL: String(item.metadata.VisitedWebPageURL || ""),
- VisitedWebPageTitle: String(item.metadata.VisitedWebPageTitle || "No Title"),
- VisitedWebPageDateWithTimeInISOString: String(item.metadata.VisitedWebPageDateWithTimeInISOString || ""),
- VisitedWebPageReffererURL: String(item.metadata.VisitedWebPageReffererURL || ""),
- VisitedWebPageVisitDurationInMilliseconds: String(item.metadata.VisitedWebPageVisitDurationInMilliseconds || "0")
- },
- pageContent: String(item.pageContent || "")
- }));
+ // Create content array for documents in the format expected by the new API
+ const content = toSaveFinally.map((item) => ({
+ metadata: {
+ BrowsingSessionId: String(item.metadata.BrowsingSessionId || ""),
+ VisitedWebPageURL: String(item.metadata.VisitedWebPageURL || ""),
+ VisitedWebPageTitle: String(item.metadata.VisitedWebPageTitle || "No Title"),
+ VisitedWebPageDateWithTimeInISOString: String(
+ item.metadata.VisitedWebPageDateWithTimeInISOString || ""
+ ),
+ VisitedWebPageReffererURL: String(item.metadata.VisitedWebPageReffererURL || ""),
+ VisitedWebPageVisitDurationInMilliseconds: String(
+ item.metadata.VisitedWebPageVisitDurationInMilliseconds || "0"
+ ),
+ },
+ pageContent: String(item.pageContent || ""),
+ }));
- const token = await storage.get("token");
- const search_space_id = parseInt(await storage.get("search_space_id"), 10);
+ const token = await storage.get("token");
+ const search_space_id = parseInt(await storage.get("search_space_id"), 10);
- const toSend = {
- document_type: "EXTENSION",
- content: content,
- search_space_id: search_space_id
- }
+ const toSend = {
+ document_type: "EXTENSION",
+ content: content,
+ search_space_id: search_space_id,
+ };
- console.log("toSend", toSend)
+ console.log("toSend", toSend);
- const requestOptions = {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Authorization": `Bearer ${token}`
- },
- body: JSON.stringify(toSend)
- }
+ const requestOptions = {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Bearer ${token}`,
+ },
+ body: JSON.stringify(toSend),
+ };
- const response = await fetch(
- `${process.env.PLASMO_PUBLIC_BACKEND_URL}/api/v1/documents/`,
- requestOptions
- )
- const resp = await response.json()
- if (resp) {
- await clearMemory()
- res.send({
- message: "Save Job Started"
- })
- }
- }
- } catch (error) {
- console.log(error)
- }
-}
+ const response = await fetch(
+ `${process.env.PLASMO_PUBLIC_BACKEND_URL}/api/v1/documents/`,
+ requestOptions
+ );
+ const resp = await response.json();
+ if (resp) {
+ await clearMemory();
+ res.send({
+ message: "Save Job Started",
+ });
+ }
+ }
+ } catch (error) {
+ console.log(error);
+ }
+};
-export default handler
+export default handler;
diff --git a/surfsense_browser_extension/background/messages/savesnapshot.ts b/surfsense_browser_extension/background/messages/savesnapshot.ts
index 90aea7b65..0f3f0c0a9 100644
--- a/surfsense_browser_extension/background/messages/savesnapshot.ts
+++ b/surfsense_browser_extension/background/messages/savesnapshot.ts
@@ -1,145 +1,142 @@
-import { DOMParser } from "linkedom"
+import type { PlasmoMessaging } from "@plasmohq/messaging";
-import { Storage } from "@plasmohq/storage"
-import type { PlasmoMessaging } from "@plasmohq/messaging"
-
-import type { WebHistory } from "~utils/interfaces"
-import { webhistoryToLangChainDocument, getRenderedHtml } from "~utils/commons"
-import { convertHtmlToMarkdown } from "dom-to-semantic-markdown"
+import { Storage } from "@plasmohq/storage";
+import { convertHtmlToMarkdown } from "dom-to-semantic-markdown";
+import { DOMParser } from "linkedom";
+import { getRenderedHtml, webhistoryToLangChainDocument } from "~utils/commons";
+import type { WebHistory } from "~utils/interfaces";
// @ts-ignore
global.Node = {
- ELEMENT_NODE: 1,
- ATTRIBUTE_NODE: 2,
- TEXT_NODE: 3,
- CDATA_SECTION_NODE: 4,
- PROCESSING_INSTRUCTION_NODE: 7,
- COMMENT_NODE: 8,
- DOCUMENT_NODE: 9,
- DOCUMENT_TYPE_NODE: 10,
- DOCUMENT_FRAGMENT_NODE: 11,
+ ELEMENT_NODE: 1,
+ ATTRIBUTE_NODE: 2,
+ TEXT_NODE: 3,
+ CDATA_SECTION_NODE: 4,
+ PROCESSING_INSTRUCTION_NODE: 7,
+ COMMENT_NODE: 8,
+ DOCUMENT_NODE: 9,
+ DOCUMENT_TYPE_NODE: 10,
+ DOCUMENT_FRAGMENT_NODE: 11,
};
const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
- try {
- chrome.tabs.query(
- { active: true, currentWindow: true },
- async function (tabs) {
- const storage = new Storage({ area: "local" })
- const tab = tabs[0]
- if (tab.id) {
- const tabId: number = tab.id
- console.log("tabs", tabs)
- const result = await chrome.scripting.executeScript({
- // @ts-ignore
- target: { tabId: tab.id },
- // @ts-ignore
- func: getRenderedHtml,
- // world: "MAIN"
- })
+ try {
+ chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => {
+ const storage = new Storage({ area: "local" });
+ const tab = tabs[0];
+ if (tab.id) {
+ const tabId: number = tab.id;
+ console.log("tabs", tabs);
+ const result = await chrome.scripting.executeScript({
+ // @ts-ignore
+ target: { tabId: tab.id },
+ // @ts-ignore
+ func: getRenderedHtml,
+ // world: "MAIN"
+ });
- console.log("SnapRes", result)
+ console.log("SnapRes", result);
- let toPushInTabHistory: any = result[0].result // const { renderedHtml, title, url, entryTime } = result[0].result;
+ const toPushInTabHistory: any = result[0].result; // const { renderedHtml, title, url, entryTime } = result[0].result;
- toPushInTabHistory.pageContentMarkdown = convertHtmlToMarkdown(
- toPushInTabHistory.renderedHtml,
- {
- extractMainContent: true,
- enableTableColumnTracking: true,
- includeMetaData: false,
- overrideDOMParser: new DOMParser()
- }
- )
+ toPushInTabHistory.pageContentMarkdown = convertHtmlToMarkdown(
+ toPushInTabHistory.renderedHtml,
+ {
+ extractMainContent: true,
+ enableTableColumnTracking: true,
+ includeMetaData: false,
+ overrideDOMParser: new DOMParser(),
+ }
+ );
- delete toPushInTabHistory.renderedHtml
+ delete toPushInTabHistory.renderedHtml;
- console.log("toPushInTabHistory", toPushInTabHistory)
+ console.log("toPushInTabHistory", toPushInTabHistory);
- const urlQueueListObj: any = await storage.get("urlQueueList")
- const timeQueueListObj: any = await storage.get("timeQueueList")
+ const urlQueueListObj: any = await storage.get("urlQueueList");
+ const timeQueueListObj: any = await storage.get("timeQueueList");
- const isUrlQueueThere = urlQueueListObj.urlQueueList.find(
- (data: WebHistory) => data.tabsessionId === tabId
- )
- const isTimeQueueThere = timeQueueListObj.timeQueueList.find(
- (data: WebHistory) => data.tabsessionId === tabId
- )
+ const isUrlQueueThere = urlQueueListObj.urlQueueList.find(
+ (data: WebHistory) => data.tabsessionId === tabId
+ );
+ const isTimeQueueThere = timeQueueListObj.timeQueueList.find(
+ (data: WebHistory) => data.tabsessionId === tabId
+ );
- toPushInTabHistory.duration =
- toPushInTabHistory.entryTime -
- isTimeQueueThere.timeQueue[isTimeQueueThere.timeQueue.length - 1]
- if (isUrlQueueThere.urlQueue.length == 1) {
- toPushInTabHistory.reffererUrl = "START"
- }
- if (isUrlQueueThere.urlQueue.length > 1) {
- toPushInTabHistory.reffererUrl =
- isUrlQueueThere.urlQueue[isUrlQueueThere.urlQueue.length - 2]
- }
+ toPushInTabHistory.duration =
+ toPushInTabHistory.entryTime -
+ isTimeQueueThere.timeQueue[isTimeQueueThere.timeQueue.length - 1];
+ if (isUrlQueueThere.urlQueue.length === 1) {
+ toPushInTabHistory.reffererUrl = "START";
+ }
+ if (isUrlQueueThere.urlQueue.length > 1) {
+ toPushInTabHistory.reffererUrl =
+ isUrlQueueThere.urlQueue[isUrlQueueThere.urlQueue.length - 2];
+ }
- let toSaveFinally: any[] = []
+ const toSaveFinally: any[] = [];
- const markdownFormat = webhistoryToLangChainDocument(
- tab.id,
- [toPushInTabHistory]
- )
- toSaveFinally.push(...markdownFormat)
-
- console.log("toSaveFinally", toSaveFinally)
+ const markdownFormat = webhistoryToLangChainDocument(tab.id, [toPushInTabHistory]);
+ toSaveFinally.push(...markdownFormat);
- // Log first item to debug metadata structure
- if (toSaveFinally.length > 0) {
- console.log("First item metadata:", toSaveFinally[0].metadata);
- }
+ console.log("toSaveFinally", toSaveFinally);
- // Create content array for documents in the format expected by the new API
- // The metadata is already in the correct format in toSaveFinally
- const content = toSaveFinally.map(item => ({
- metadata: {
- BrowsingSessionId: String(item.metadata.BrowsingSessionId || ""),
- VisitedWebPageURL: String(item.metadata.VisitedWebPageURL || ""),
- VisitedWebPageTitle: String(item.metadata.VisitedWebPageTitle || "No Title"),
- VisitedWebPageDateWithTimeInISOString: String(item.metadata.VisitedWebPageDateWithTimeInISOString || ""),
- VisitedWebPageReffererURL: String(item.metadata.VisitedWebPageReffererURL || ""),
- VisitedWebPageVisitDurationInMilliseconds: String(item.metadata.VisitedWebPageVisitDurationInMilliseconds || "0")
- },
- pageContent: String(item.pageContent || "")
- }));
+ // Log first item to debug metadata structure
+ if (toSaveFinally.length > 0) {
+ console.log("First item metadata:", toSaveFinally[0].metadata);
+ }
- const token = await storage.get("token");
- const search_space_id = parseInt(await storage.get("search_space_id"), 10);
+ // Create content array for documents in the format expected by the new API
+ // The metadata is already in the correct format in toSaveFinally
+ const content = toSaveFinally.map((item) => ({
+ metadata: {
+ BrowsingSessionId: String(item.metadata.BrowsingSessionId || ""),
+ VisitedWebPageURL: String(item.metadata.VisitedWebPageURL || ""),
+ VisitedWebPageTitle: String(item.metadata.VisitedWebPageTitle || "No Title"),
+ VisitedWebPageDateWithTimeInISOString: String(
+ item.metadata.VisitedWebPageDateWithTimeInISOString || ""
+ ),
+ VisitedWebPageReffererURL: String(item.metadata.VisitedWebPageReffererURL || ""),
+ VisitedWebPageVisitDurationInMilliseconds: String(
+ item.metadata.VisitedWebPageVisitDurationInMilliseconds || "0"
+ ),
+ },
+ pageContent: String(item.pageContent || ""),
+ }));
- const toSend = {
- document_type: "EXTENSION",
- content: content,
- search_space_id: search_space_id
- }
+ const token = await storage.get("token");
+ const search_space_id = parseInt(await storage.get("search_space_id"), 10);
- const requestOptions = {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Authorization": `Bearer ${token}`
- },
- body: JSON.stringify(toSend)
- }
+ const toSend = {
+ document_type: "EXTENSION",
+ content: content,
+ search_space_id: search_space_id,
+ };
- const response = await fetch(
- `${process.env.PLASMO_PUBLIC_BACKEND_URL}/api/v1/documents/`,
- requestOptions
- )
- const resp = await response.json()
- if (resp) {
- res.send({
- message: "Snapshot Saved Successfully"
- })
- }
- }
- }
- )
- } catch (error) {
- console.log(error)
- }
-}
+ const requestOptions = {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Bearer ${token}`,
+ },
+ body: JSON.stringify(toSend),
+ };
-export default handler
+ const response = await fetch(
+ `${process.env.PLASMO_PUBLIC_BACKEND_URL}/api/v1/documents/`,
+ requestOptions
+ );
+ const resp = await response.json();
+ if (resp) {
+ res.send({
+ message: "Snapshot Saved Successfully",
+ });
+ }
+ }
+ });
+ } catch (error) {
+ console.log(error);
+ }
+};
+
+export default handler;
diff --git a/surfsense_browser_extension/biome.json b/surfsense_browser_extension/biome.json
new file mode 100644
index 000000000..6e17e7f14
--- /dev/null
+++ b/surfsense_browser_extension/biome.json
@@ -0,0 +1,115 @@
+{
+ "$schema": "https://biomejs.dev/schemas/2.1.2/schema.json",
+ "vcs": {
+ "enabled": true,
+ "clientKind": "git",
+ "useIgnoreFile": true
+ },
+ "files": {
+ "ignoreUnknown": true,
+ "experimentalScannerIgnores": ["node_modules", ".git", ".next", "dist", "build", "coverage"],
+ "maxSize": 1048576
+ },
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "tab",
+ "indentWidth": 2,
+ "lineWidth": 100,
+ "lineEnding": "lf",
+ "formatWithErrors": false
+ },
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": true,
+ "suspicious": {
+ "noExplicitAny": "warn",
+ "noArrayIndexKey": "warn"
+ },
+ "style": {
+ "useConst": "error",
+ "useTemplate": "warn"
+ },
+ "correctness": {
+ "useExhaustiveDependencies": "warn"
+ }
+ }
+ },
+ "javascript": {
+ "formatter": {
+ "quoteStyle": "double",
+ "jsxQuoteStyle": "double",
+ "quoteProperties": "asNeeded",
+ "trailingCommas": "es5",
+ "semicolons": "always",
+ "arrowParentheses": "always",
+ "bracketSameLine": false,
+ "bracketSpacing": true
+ },
+ "linter": {
+ "enabled": true
+ },
+ "assist": {
+ "enabled": true
+ }
+ },
+ "json": {
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "tab",
+ "indentWidth": 2,
+ "lineWidth": 100
+ },
+ "linter": {
+ "enabled": true
+ }
+ },
+ "css": {
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "tab",
+ "indentWidth": 2,
+ "lineWidth": 100,
+ "quoteStyle": "double"
+ },
+ "linter": {
+ "enabled": true
+ }
+ },
+ "assist": {
+ "enabled": true,
+ "actions": {
+ "source": {
+ "organizeImports": "on"
+ }
+ }
+ },
+ "overrides": [
+ {
+ "includes": ["*.json", "*.jsonc"],
+ "json": {
+ "parser": {
+ "allowComments": true,
+ "allowTrailingCommas": false
+ }
+ }
+ },
+ {
+ "includes": [".vscode/**/*.json"],
+ "json": {
+ "parser": {
+ "allowComments": true,
+ "allowTrailingCommas": true
+ }
+ }
+ },
+ {
+ "includes": ["**/*.config.*", "**/next.config.*"],
+ "javascript": {
+ "formatter": {
+ "semicolons": "always"
+ }
+ }
+ }
+ ]
+}
diff --git a/surfsense_browser_extension/content.ts b/surfsense_browser_extension/content.ts
index c13fbfe8e..b5e9cb5f6 100644
--- a/surfsense_browser_extension/content.ts
+++ b/surfsense_browser_extension/content.ts
@@ -1,8 +1,7 @@
-import type { PlasmoCSConfig } from "plasmo"
-
-export const config: PlasmoCSConfig = {
- matches: [""],
- all_frames: true,
- world: "MAIN"
-}
+import type { PlasmoCSConfig } from "plasmo";
+export const config: PlasmoCSConfig = {
+ matches: [""],
+ all_frames: true,
+ world: "MAIN",
+};
diff --git a/surfsense_browser_extension/font.css b/surfsense_browser_extension/font.css
index ac400cd99..7af252316 100644
--- a/surfsense_browser_extension/font.css
+++ b/surfsense_browser_extension/font.css
@@ -1,10 +1,11 @@
@font-face {
- font-family: "Fascinate";
- font-style: normal;
- font-weight: 400;
- font-display: swap;
- src: url(data-base64:~assets/Fascinate.woff2) format("woff2");
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
- U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
- U+FEFF, U+FFFD;
- }
\ No newline at end of file
+ font-family: "Fascinate";
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(data-base64:~assets/Fascinate.woff2) format("woff2");
+ unicode-range:
+ U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
+ U+FEFF, U+FFFD;
+}
diff --git a/surfsense_browser_extension/lib/utils.ts b/surfsense_browser_extension/lib/utils.ts
index bd0c391dd..ac680b303 100644
--- a/surfsense_browser_extension/lib/utils.ts
+++ b/surfsense_browser_extension/lib/utils.ts
@@ -1,6 +1,6 @@
-import { clsx, type ClassValue } from "clsx"
-import { twMerge } from "tailwind-merge"
+import { type ClassValue, clsx } from "clsx";
+import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
- return twMerge(clsx(inputs))
+ return twMerge(clsx(inputs));
}
diff --git a/surfsense_browser_extension/package.json b/surfsense_browser_extension/package.json
index 9274154ca..74551a244 100644
--- a/surfsense_browser_extension/package.json
+++ b/surfsense_browser_extension/package.json
@@ -1,62 +1,62 @@
{
- "name": "surfsense_browser_extension",
- "displayName": "Surfsense Browser Extension",
- "version": "0.0.7",
- "description": "Extension to collect Browsing History for SurfSense.",
- "author": "https://github.com/MODSetter",
- "scripts": {
- "dev": "plasmo dev",
- "build": "plasmo build",
- "package": "plasmo package"
- },
- "dependencies": {
- "@plasmohq/messaging": "^0.6.2",
- "@plasmohq/storage": "^1.11.0",
- "@radix-ui/react-dialog": "^1.1.2",
- "@radix-ui/react-icons": "^1.3.2",
- "@radix-ui/react-popover": "^1.1.2",
- "@radix-ui/react-slot": "^1.1.0",
- "@radix-ui/react-toast": "^1.2.2",
- "class-variance-authority": "^0.7.0",
- "clsx": "^2.1.1",
- "cmdk": "^1.0.3",
- "dom-to-semantic-markdown": "^1.2.11",
- "linkedom": "0.1.34",
- "lucide-react": "^0.454.0",
- "plasmo": "0.89.4",
- "postcss-loader": "^8.1.1",
- "radix-ui": "^1.0.1",
- "react": "18.2.0",
- "react-dom": "18.2.0",
- "react-hooks-global-state": "^2.1.0",
- "react-router-dom": "^6.26.1",
- "tailwind-merge": "^2.5.4",
- "tailwindcss-animate": "^1.0.7"
- },
- "devDependencies": {
- "@ianvs/prettier-plugin-sort-imports": "4.1.1",
- "@types/chrome": "0.0.258",
- "@types/node": "20.11.5",
- "@types/react": "18.2.48",
- "@types/react-dom": "18.2.18",
- "autoprefixer": "^10.4.20",
- "postcss": "^8.4.41",
- "prettier": "3.2.4",
- "tailwindcss": "^3.4.10",
- "typescript": "5.3.3"
- },
- "manifest": {
- "host_permissions": [
- ""
- ],
- "name": "SurfSense",
- "description": "Extension to collect Browsing History for SurfSense.",
- "version": "0.0.3"
- },
- "permissions": [
- "storage",
- "scripting",
- "unlimitedStorage",
- "activeTab"
- ]
+ "name": "surfsense_browser_extension",
+ "displayName": "Surfsense Browser Extension",
+ "version": "0.0.7",
+ "description": "Extension to collect Browsing History for SurfSense.",
+ "author": "https://github.com/MODSetter",
+ "scripts": {
+ "dev": "plasmo dev",
+ "build": "plasmo build",
+ "package": "plasmo package"
+ },
+ "dependencies": {
+ "@plasmohq/messaging": "^0.6.2",
+ "@plasmohq/storage": "^1.11.0",
+ "@radix-ui/react-dialog": "^1.1.2",
+ "@radix-ui/react-icons": "^1.3.2",
+ "@radix-ui/react-label": "^2.1.7",
+ "@radix-ui/react-popover": "^1.1.2",
+ "@radix-ui/react-slot": "^1.1.0",
+ "@radix-ui/react-toast": "^1.2.2",
+ "class-variance-authority": "^0.7.0",
+ "clsx": "^2.1.1",
+ "cmdk": "^1.0.3",
+ "dom-to-semantic-markdown": "^1.2.11",
+ "linkedom": "0.1.34",
+ "lucide-react": "^0.454.0",
+ "plasmo": "0.89.4",
+ "postcss-loader": "^8.1.1",
+ "radix-ui": "^1.0.1",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-hooks-global-state": "^2.1.0",
+ "react-router-dom": "^6.26.1",
+ "tailwind-merge": "^2.5.4",
+ "tailwindcss-animate": "^1.0.7"
+ },
+ "devDependencies": {
+ "@biomejs/biome": "2.1.2",
+ "@types/chrome": "0.0.258",
+ "@types/node": "20.11.5",
+ "@types/react": "18.2.48",
+ "@types/react-dom": "18.2.18",
+ "autoprefixer": "^10.4.20",
+ "postcss": "^8.4.41",
+ "tailwindcss": "^3.4.10",
+ "typescript": "5.3.3"
+ },
+ "manifest": {
+ "host_permissions": [
+ ""
+ ],
+ "name": "SurfSense",
+ "description": "Extension to collect Browsing History for SurfSense.",
+ "version": "0.0.3"
+ },
+ "permissions": [
+ "storage",
+ "scripting",
+ "unlimitedStorage",
+ "activeTab"
+ ]
}
diff --git a/surfsense_browser_extension/pnpm-lock.yaml b/surfsense_browser_extension/pnpm-lock.yaml
index 1d963608e..e1239fa9b 100644
--- a/surfsense_browser_extension/pnpm-lock.yaml
+++ b/surfsense_browser_extension/pnpm-lock.yaml
@@ -20,6 +20,9 @@ importers:
'@radix-ui/react-icons':
specifier: ^1.3.2
version: 1.3.2(react@18.2.0)
+ '@radix-ui/react-label':
+ specifier: ^2.1.7
+ version: 2.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
'@radix-ui/react-popover':
specifier: ^1.1.2
version: 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -75,9 +78,9 @@ importers:
specifier: ^1.0.7
version: 1.0.7(tailwindcss@3.4.10)
devDependencies:
- '@ianvs/prettier-plugin-sort-imports':
- specifier: 4.1.1
- version: 4.1.1(@vue/compiler-sfc@3.3.4)(prettier@3.2.4)
+ '@biomejs/biome':
+ specifier: 2.1.2
+ version: 2.1.2
'@types/chrome':
specifier: 0.0.258
version: 0.0.258
@@ -96,9 +99,6 @@ importers:
postcss:
specifier: ^8.4.41
version: 8.4.41
- prettier:
- specifier: 3.2.4
- version: 3.2.4
tailwindcss:
specifier: ^3.4.10
version: 3.4.10
@@ -191,6 +191,59 @@ packages:
resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==}
engines: {node: '>=6.9.0'}
+ '@biomejs/biome@2.1.2':
+ resolution: {integrity: sha512-yq8ZZuKuBVDgAS76LWCfFKHSYIAgqkxVB3mGVVpOe2vSkUTs7xG46zXZeNPRNVjiJuw0SZ3+J2rXiYx0RUpfGg==}
+ engines: {node: '>=14.21.3'}
+ hasBin: true
+
+ '@biomejs/cli-darwin-arm64@2.1.2':
+ resolution: {integrity: sha512-leFAks64PEIjc7MY/cLjE8u5OcfBKkcDB0szxsWUB4aDfemBep1WVKt0qrEyqZBOW8LPHzrFMyDl3FhuuA0E7g==}
+ engines: {node: '>=14.21.3'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@biomejs/cli-darwin-x64@2.1.2':
+ resolution: {integrity: sha512-Nmmv7wRX5Nj7lGmz0FjnWdflJg4zii8Ivruas6PBKzw5SJX/q+Zh2RfnO+bBnuKLXpj8kiI2x2X12otpH6a32A==}
+ engines: {node: '>=14.21.3'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@biomejs/cli-linux-arm64-musl@2.1.2':
+ resolution: {integrity: sha512-qgHvafhjH7Oca114FdOScmIKf1DlXT1LqbOrrbR30kQDLFPEOpBG0uzx6MhmsrmhGiCFCr2obDamu+czk+X0HQ==}
+ engines: {node: '>=14.21.3'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@biomejs/cli-linux-arm64@2.1.2':
+ resolution: {integrity: sha512-NWNy2Diocav61HZiv2enTQykbPP/KrA/baS7JsLSojC7Xxh2nl9IczuvE5UID7+ksRy2e7yH7klm/WkA72G1dw==}
+ engines: {node: '>=14.21.3'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@biomejs/cli-linux-x64-musl@2.1.2':
+ resolution: {integrity: sha512-xlB3mU14ZUa3wzLtXfmk2IMOGL+S0aHFhSix/nssWS/2XlD27q+S6f0dlQ8WOCbYoXcuz8BCM7rCn2lxdTrlQA==}
+ engines: {node: '>=14.21.3'}
+ cpu: [x64]
+ os: [linux]
+
+ '@biomejs/cli-linux-x64@2.1.2':
+ resolution: {integrity: sha512-Km/UYeVowygTjpX6sGBzlizjakLoMQkxWbruVZSNE6osuSI63i4uCeIL+6q2AJlD3dxoiBJX70dn1enjQnQqwA==}
+ engines: {node: '>=14.21.3'}
+ cpu: [x64]
+ os: [linux]
+
+ '@biomejs/cli-win32-arm64@2.1.2':
+ resolution: {integrity: sha512-G8KWZli5ASOXA3yUQgx+M4pZRv3ND16h77UsdunUL17uYpcL/UC7RkWTdkfvMQvogVsAuz5JUcBDjgZHXxlKoA==}
+ engines: {node: '>=14.21.3'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@biomejs/cli-win32-x64@2.1.2':
+ resolution: {integrity: sha512-9zajnk59PMpjBkty3bK2IrjUsUHvqe9HWwyAWQBjGLE7MIBjbX2vwv1XPEhmO2RRuGoTkVx3WCanHrjAytICLA==}
+ engines: {node: '>=14.21.3'}
+ cpu: [x64]
+ os: [win32]
+
'@esbuild/android-arm64@0.18.20':
resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
engines: {node: '>=12'}
@@ -342,15 +395,6 @@ packages:
'@floating-ui/utils@0.2.8':
resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==}
- '@ianvs/prettier-plugin-sort-imports@4.1.1':
- resolution: {integrity: sha512-kJhXq63ngpTQ2dxgf5GasbPJWsJA3LgoOdd7WGhpUSzLgLgI4IsIzYkbJf9kmpOHe7Vdm/o3PcRA3jmizXUuAQ==}
- peerDependencies:
- '@vue/compiler-sfc': '>=3.0.0'
- prettier: 2 || 3
- peerDependenciesMeta:
- '@vue/compiler-sfc':
- optional: true
-
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
@@ -1118,17 +1162,17 @@ packages:
resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==}
engines: {node: '>=12'}
- '@radix-ui/number@1.1.0':
- resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==}
+ '@radix-ui/number@1.1.1':
+ resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==}
'@radix-ui/primitive@1.1.0':
resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==}
- '@radix-ui/primitive@1.1.1':
- resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==}
+ '@radix-ui/primitive@1.1.2':
+ resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==}
- '@radix-ui/react-accessible-icon@1.1.2':
- resolution: {integrity: sha512-+rnMO0SEfzkcHr93RshkQVpOA26MtGOv4pcS9QUnLg4F8+GDmCJ8c2FEPhPz5e7arf31EzbTqJxFbzg3qen14g==}
+ '@radix-ui/react-accessible-icon@1.1.7':
+ resolution: {integrity: sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1140,8 +1184,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-accordion@1.2.3':
- resolution: {integrity: sha512-RIQ15mrcvqIkDARJeERSuXSry2N8uYnxkdDetpfmalT/+0ntOXLkFOsh9iwlAsCv+qcmhZjbdJogIm6WBa6c4A==}
+ '@radix-ui/react-accordion@1.2.11':
+ resolution: {integrity: sha512-l3W5D54emV2ues7jjeG1xcyN7S3jnK3zE2zHqgn0CmMsy9lNJwmgcrmaxS+7ipw15FAivzKNzH3d5EcGoFKw0A==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1153,8 +1197,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-alert-dialog@1.1.6':
- resolution: {integrity: sha512-p4XnPqgej8sZAAReCAKgz1REYZEBLR8hU9Pg27wFnCWIMc8g1ccCs0FjBcy05V15VTu8pAePw/VDYeOm/uZ6yQ==}
+ '@radix-ui/react-alert-dialog@1.1.14':
+ resolution: {integrity: sha512-IOZfZ3nPvN6lXpJTBCunFQPRSvK8MDgSc1FB85xnIpUKOw9en0dJj8JmCAxV7BiZdtYlUpmrQjoTFkVYtdoWzQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1179,8 +1223,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-arrow@1.1.2':
- resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==}
+ '@radix-ui/react-arrow@1.1.7':
+ resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1192,8 +1236,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-aspect-ratio@1.1.2':
- resolution: {integrity: sha512-TaJxYoCpxJ7vfEkv2PTNox/6zzmpKXT6ewvCuf2tTOIVN45/Jahhlld29Yw4pciOXS2Xq91/rSGEdmEnUWZCqA==}
+ '@radix-ui/react-aspect-ratio@1.1.7':
+ resolution: {integrity: sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1205,8 +1249,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-avatar@1.1.3':
- resolution: {integrity: sha512-Paen00T4P8L8gd9bNsRMw7Cbaz85oxiv+hzomsRZgFm2byltPFDtfcoqlWJ8GyZlIBWgLssJlzLCnKU0G0302g==}
+ '@radix-ui/react-avatar@1.1.10':
+ resolution: {integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1218,8 +1262,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-checkbox@1.1.4':
- resolution: {integrity: sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==}
+ '@radix-ui/react-checkbox@1.3.2':
+ resolution: {integrity: sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1231,8 +1275,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-collapsible@1.1.3':
- resolution: {integrity: sha512-jFSerheto1X03MUC0g6R7LedNW9EEGWdg9W1+MlpkMLwGkgkbUXLPBH/KIuWKXUoeYRVY11llqbTBDzuLg7qrw==}
+ '@radix-ui/react-collapsible@1.1.11':
+ resolution: {integrity: sha512-2qrRsVGSCYasSz1RFOorXwl0H7g7J1frQtgpQgYrt+MOidtPAINHn9CPovQXb83r8ahapdx3Tu0fa/pdFFSdPg==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1257,8 +1301,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-collection@1.1.2':
- resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==}
+ '@radix-ui/react-collection@1.1.7':
+ resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1279,8 +1323,8 @@ packages:
'@types/react':
optional: true
- '@radix-ui/react-compose-refs@1.1.1':
- resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==}
+ '@radix-ui/react-compose-refs@1.1.2':
+ resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
@@ -1288,8 +1332,8 @@ packages:
'@types/react':
optional: true
- '@radix-ui/react-context-menu@2.2.6':
- resolution: {integrity: sha512-aUP99QZ3VU84NPsHeaFt4cQUNgJqFsLLOt/RbbWXszZ6MP0DpDyjkFZORr4RpAEx3sUBk+Kc8h13yGtC5Qw8dg==}
+ '@radix-ui/react-context-menu@2.2.15':
+ resolution: {integrity: sha512-UsQUMjcYTsBjTSXw0P3GO0werEQvUY2plgRQuKoCTtkNr45q1DiL51j4m7gxhABzZ0BadoXNsIbg7F3KwiUBbw==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1319,6 +1363,28 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-context@1.1.2':
+ resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-dialog@1.1.14':
+ resolution: {integrity: sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-dialog@1.1.2':
resolution: {integrity: sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==}
peerDependencies:
@@ -1332,21 +1398,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-dialog@1.1.6':
- resolution: {integrity: sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
-
- '@radix-ui/react-direction@1.1.0':
- resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==}
+ '@radix-ui/react-direction@1.1.1':
+ resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
@@ -1367,8 +1420,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-dismissable-layer@1.1.5':
- resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==}
+ '@radix-ui/react-dismissable-layer@1.1.10':
+ resolution: {integrity: sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1380,8 +1433,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-dropdown-menu@2.1.6':
- resolution: {integrity: sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==}
+ '@radix-ui/react-dropdown-menu@2.1.15':
+ resolution: {integrity: sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1402,6 +1455,15 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-focus-guards@1.1.2':
+ resolution: {integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
'@radix-ui/react-focus-scope@1.1.0':
resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==}
peerDependencies:
@@ -1415,8 +1477,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-focus-scope@1.1.2':
- resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==}
+ '@radix-ui/react-focus-scope@1.1.7':
+ resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1428,8 +1490,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-hover-card@1.1.6':
- resolution: {integrity: sha512-E4ozl35jq0VRlrdc4dhHrNSV0JqBb4Jy73WAhBEK7JoYnQ83ED5r0Rb/XdVKw89ReAJN38N492BAPBZQ57VmqQ==}
+ '@radix-ui/react-hover-card@1.1.14':
+ resolution: {integrity: sha512-CPYZ24Mhirm+g6D8jArmLzjYu4Eyg3TTUHswR26QgzXBHBe64BO/RHOJKzmF/Dxb4y4f9PKyJdwm/O/AhNkb+Q==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1455,8 +1517,17 @@ packages:
'@types/react':
optional: true
- '@radix-ui/react-label@2.1.2':
- resolution: {integrity: sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==}
+ '@radix-ui/react-id@1.1.1':
+ resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-label@2.1.7':
+ resolution: {integrity: sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1468,8 +1539,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-menu@2.1.6':
- resolution: {integrity: sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==}
+ '@radix-ui/react-menu@2.1.15':
+ resolution: {integrity: sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1481,8 +1552,21 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-navigation-menu@1.2.5':
- resolution: {integrity: sha512-myMHHQUZ3ZLTi8W381/Vu43Ia0NqakkQZ2vzynMmTUtQQ9kNkjzhOwkZC9TAM5R07OZUVIQyHC06f/9JZJpvvA==}
+ '@radix-ui/react-navigation-menu@1.2.13':
+ resolution: {integrity: sha512-WG8wWfDiJlSF5hELjwfjSGOXcBR/ZMhBFCGYe8vERpC39CQYZeq1PQ2kaYHdye3V95d06H89KGMsVCIE4LWo3g==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-popover@1.1.14':
+ resolution: {integrity: sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1507,19 +1591,6 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-popover@1.1.6':
- resolution: {integrity: sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
-
'@radix-ui/react-popper@1.2.0':
resolution: {integrity: sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==}
peerDependencies:
@@ -1533,8 +1604,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-popper@1.2.2':
- resolution: {integrity: sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==}
+ '@radix-ui/react-popper@1.2.7':
+ resolution: {integrity: sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1559,8 +1630,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-portal@1.1.4':
- resolution: {integrity: sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==}
+ '@radix-ui/react-portal@1.1.9':
+ resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1585,8 +1656,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-presence@1.1.2':
- resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==}
+ '@radix-ui/react-presence@1.1.4':
+ resolution: {integrity: sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1611,8 +1682,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-primitive@2.0.2':
- resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==}
+ '@radix-ui/react-primitive@2.1.3':
+ resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1624,8 +1695,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-progress@1.1.2':
- resolution: {integrity: sha512-u1IgJFQ4zNAUTjGdDL5dcl/U8ntOR6jsnhxKb5RKp5Ozwl88xKR9EqRZOe/Mk8tnx0x5tNUe2F+MzsyjqMg0MA==}
+ '@radix-ui/react-progress@1.1.7':
+ resolution: {integrity: sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1637,8 +1708,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-radio-group@1.2.3':
- resolution: {integrity: sha512-xtCsqt8Rp09FK50ItqEqTJ7Sxanz8EM8dnkVIhJrc/wkMMomSmXHvYbhv3E7Zx4oXh98aaLt9W679SUYXg4IDA==}
+ '@radix-ui/react-radio-group@1.3.7':
+ resolution: {integrity: sha512-9w5XhD0KPOrm92OTTE0SysH3sYzHsSTHNvZgUBo/VZ80VdYyB5RneDbc0dKpURS24IxkoFRu/hI0i4XyfFwY6g==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1650,8 +1721,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-roving-focus@1.1.2':
- resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==}
+ '@radix-ui/react-roving-focus@1.1.10':
+ resolution: {integrity: sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1663,8 +1734,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-scroll-area@1.2.3':
- resolution: {integrity: sha512-l7+NNBfBYYJa9tNqVcP2AGvxdE3lmE6kFTBXdvHgUaZuy+4wGCL1Cl2AfaR7RKyimj7lZURGLwFO59k4eBnDJQ==}
+ '@radix-ui/react-scroll-area@1.2.9':
+ resolution: {integrity: sha512-YSjEfBXnhUELsO2VzjdtYYD4CfQjvao+lhhrX5XsHD7/cyUNzljF1FHEbgTPN7LH2MClfwRMIsYlqTYpKTTe2A==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1676,8 +1747,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-select@2.1.6':
- resolution: {integrity: sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==}
+ '@radix-ui/react-select@2.2.5':
+ resolution: {integrity: sha512-HnMTdXEVuuyzx63ME0ut4+sEMYW6oouHWNGUZc7ddvUWIcfCva/AMoqEW/3wnEllriMWBa0RHspCYnfCWJQYmA==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1689,8 +1760,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-separator@1.1.2':
- resolution: {integrity: sha512-oZfHcaAp2Y6KFBX6I5P1u7CQoy4lheCGiYj+pGFrHy8E/VNRb5E39TkTr3JrV520csPBTZjkuKFdEsjS5EUNKQ==}
+ '@radix-ui/react-separator@1.1.7':
+ resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1702,8 +1773,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-slider@1.2.3':
- resolution: {integrity: sha512-nNrLAWLjGESnhqBqcCNW4w2nn7LxudyMzeB6VgdyAnFLC6kfQgnAjSL2v6UkQTnDctJBlxrmxfplWS4iYjdUTw==}
+ '@radix-ui/react-slider@1.3.5':
+ resolution: {integrity: sha512-rkfe2pU2NBAYfGaxa3Mqosi7VZEWX5CxKaanRv0vZd4Zhl9fvQrg0VM93dv3xGLGfrHuoTRF3JXH8nb9g+B3fw==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1724,8 +1795,8 @@ packages:
'@types/react':
optional: true
- '@radix-ui/react-slot@1.1.2':
- resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==}
+ '@radix-ui/react-slot@1.2.3':
+ resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
@@ -1733,8 +1804,8 @@ packages:
'@types/react':
optional: true
- '@radix-ui/react-switch@1.1.3':
- resolution: {integrity: sha512-1nc+vjEOQkJVsJtWPSiISGT6OKm4SiOdjMo+/icLxo2G4vxz1GntC5MzfL4v8ey9OEfw787QCD1y3mUv0NiFEQ==}
+ '@radix-ui/react-switch@1.2.5':
+ resolution: {integrity: sha512-5ijLkak6ZMylXsaImpZ8u4Rlf5grRmoc0p0QeX9VJtlrM4f5m3nCTX8tWga/zOA8PZYIR/t0p2Mnvd7InrJ6yQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1746,8 +1817,21 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-tabs@1.1.3':
- resolution: {integrity: sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==}
+ '@radix-ui/react-tabs@1.1.12':
+ resolution: {integrity: sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-toast@1.2.14':
+ resolution: {integrity: sha512-nAP5FBxBJGQ/YfUB+r+O6USFVkWq3gAInkxyEnmvEV5jtSbfDhfa4hwX8CraCnbjMLsE7XSf/K75l9xXY7joWg==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1772,8 +1856,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-toast@1.2.6':
- resolution: {integrity: sha512-gN4dpuIVKEgpLn1z5FhzT9mYRUitbfZq9XqN/7kkBMUgFTzTG8x/KszWJugJXHcwxckY8xcKDZPz7kG3o6DsUA==}
+ '@radix-ui/react-toggle-group@1.1.10':
+ resolution: {integrity: sha512-kiU694Km3WFLTC75DdqgM/3Jauf3rD9wxeS9XtyWFKsBUeZA337lC+6uUazT7I1DhanZ5gyD5Stf8uf2dbQxOQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1785,8 +1869,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-toggle-group@1.1.2':
- resolution: {integrity: sha512-JBm6s6aVG/nwuY5eadhU2zDi/IwYS0sDM5ZWb4nymv/hn3hZdkw+gENn0LP4iY1yCd7+bgJaCwueMYJIU3vk4A==}
+ '@radix-ui/react-toggle@1.1.9':
+ resolution: {integrity: sha512-ZoFkBBz9zv9GWer7wIjvdRxmh2wyc2oKWw6C6CseWd6/yq1DK/l5lJ+wnsmFwJZbBYqr02mrf8A2q/CVCuM3ZA==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1798,8 +1882,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-toggle@1.1.2':
- resolution: {integrity: sha512-lntKchNWx3aCHuWKiDY+8WudiegQvBpDRAYL8dKLRvKEH8VOpl0XX6SSU/bUBqIRJbcTy4+MW06Wv8vgp10rzQ==}
+ '@radix-ui/react-toolbar@1.1.10':
+ resolution: {integrity: sha512-jiwQsduEL++M4YBIurjSa+voD86OIytCod0/dbIxFZDLD8NfO1//keXYMfsW8BPcfqwoNjt+y06XcJqAb4KR7A==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1811,21 +1895,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-toolbar@1.1.2':
- resolution: {integrity: sha512-wT20eQ7ScFk+kBMDmHp+lMk18cgxhu35b2Bn5deUcPxiVwfn5vuZgi7NGcHu8ocdkinahmp4FaSZysKDyRVPWQ==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
-
- '@radix-ui/react-tooltip@1.1.8':
- resolution: {integrity: sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA==}
+ '@radix-ui/react-tooltip@1.2.7':
+ resolution: {integrity: sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1846,6 +1917,15 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-use-callback-ref@1.1.1':
+ resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
'@radix-ui/react-use-controllable-state@1.1.0':
resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==}
peerDependencies:
@@ -1855,6 +1935,24 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-use-controllable-state@1.2.2':
+ resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-effect-event@0.0.2':
+ resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
'@radix-ui/react-use-escape-keydown@1.1.0':
resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==}
peerDependencies:
@@ -1864,6 +1962,24 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-use-escape-keydown@1.1.1':
+ resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-is-hydrated@0.1.0':
+ resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
'@radix-ui/react-use-layout-effect@1.1.0':
resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==}
peerDependencies:
@@ -1873,8 +1989,17 @@ packages:
'@types/react':
optional: true
- '@radix-ui/react-use-previous@1.1.0':
- resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==}
+ '@radix-ui/react-use-layout-effect@1.1.1':
+ resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-previous@1.1.1':
+ resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
@@ -1891,6 +2016,15 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-use-rect@1.1.1':
+ resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
'@radix-ui/react-use-size@1.1.0':
resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==}
peerDependencies:
@@ -1900,6 +2034,15 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-use-size@1.1.1':
+ resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
'@radix-ui/react-visually-hidden@1.1.0':
resolution: {integrity: sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==}
peerDependencies:
@@ -1913,8 +2056,8 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-visually-hidden@1.1.2':
- resolution: {integrity: sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==}
+ '@radix-ui/react-visually-hidden@1.2.3':
+ resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
@@ -1929,6 +2072,9 @@ packages:
'@radix-ui/rect@1.1.0':
resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==}
+ '@radix-ui/rect@1.1.1':
+ resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
+
'@remix-run/router@1.19.1':
resolution: {integrity: sha512-S45oynt/WH19bHbIXjtli6QmwNYvaz+vtnubvNpNDvUOoA/OWh6j1OikIP3G+v5GHdxyC6EXoChG3HgYGEUfcg==}
engines: {node: '>=14.0.0'}
@@ -3607,11 +3753,6 @@ packages:
engines: {node: '>=10'}
hasBin: true
- prettier@3.2.4:
- resolution: {integrity: sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==}
- engines: {node: '>=14'}
- hasBin: true
-
process@0.11.10:
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
engines: {node: '>= 0.6.0'}
@@ -4154,6 +4295,11 @@ packages:
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ use-sync-external-store@1.5.0:
+ resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@@ -4351,6 +4497,41 @@ snapshots:
'@babel/helper-validator-identifier': 7.24.7
to-fast-properties: 2.0.0
+ '@biomejs/biome@2.1.2':
+ optionalDependencies:
+ '@biomejs/cli-darwin-arm64': 2.1.2
+ '@biomejs/cli-darwin-x64': 2.1.2
+ '@biomejs/cli-linux-arm64': 2.1.2
+ '@biomejs/cli-linux-arm64-musl': 2.1.2
+ '@biomejs/cli-linux-x64': 2.1.2
+ '@biomejs/cli-linux-x64-musl': 2.1.2
+ '@biomejs/cli-win32-arm64': 2.1.2
+ '@biomejs/cli-win32-x64': 2.1.2
+
+ '@biomejs/cli-darwin-arm64@2.1.2':
+ optional: true
+
+ '@biomejs/cli-darwin-x64@2.1.2':
+ optional: true
+
+ '@biomejs/cli-linux-arm64-musl@2.1.2':
+ optional: true
+
+ '@biomejs/cli-linux-arm64@2.1.2':
+ optional: true
+
+ '@biomejs/cli-linux-x64-musl@2.1.2':
+ optional: true
+
+ '@biomejs/cli-linux-x64@2.1.2':
+ optional: true
+
+ '@biomejs/cli-win32-arm64@2.1.2':
+ optional: true
+
+ '@biomejs/cli-win32-x64@2.1.2':
+ optional: true
+
'@esbuild/android-arm64@0.18.20':
optional: true
@@ -4438,20 +4619,6 @@ snapshots:
'@floating-ui/utils@0.2.8': {}
- '@ianvs/prettier-plugin-sort-imports@4.1.1(@vue/compiler-sfc@3.3.4)(prettier@3.2.4)':
- dependencies:
- '@babel/core': 7.25.2
- '@babel/generator': 7.25.5
- '@babel/parser': 7.25.4
- '@babel/traverse': 7.25.4
- '@babel/types': 7.25.4
- prettier: 3.2.4
- semver: 7.6.3
- optionalDependencies:
- '@vue/compiler-sfc': 3.3.4
- transitivePeerDependencies:
- - supports-color
-
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
@@ -5605,46 +5772,46 @@ snapshots:
'@pnpm/network.ca-file': 1.0.2
config-chain: 1.1.13
- '@radix-ui/number@1.1.0': {}
+ '@radix-ui/number@1.1.1': {}
'@radix-ui/primitive@1.1.0': {}
- '@radix-ui/primitive@1.1.1': {}
+ '@radix-ui/primitive@1.1.2': {}
- '@radix-ui/react-accessible-icon@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-accordion@1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-accordion@1.2.11(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-collapsible': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-id': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-collapsible': 1.1.11(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-alert-dialog@1.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-alert-dialog@1.1.14(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-dialog': 1.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-slot': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-dialog': 1.1.14(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -5660,62 +5827,63 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-arrow@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-arrow@1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-aspect-ratio@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-avatar@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-avatar@1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-checkbox@1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-checkbox@1.3.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-previous': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-size': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-previous': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-size': 1.1.1(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-collapsible@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-collapsible@1.1.11(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-id': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -5734,12 +5902,12 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-collection@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-collection@1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-slot': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -5752,20 +5920,20 @@ snapshots:
optionalDependencies:
'@types/react': 18.2.48
- '@radix-ui/react-compose-refs@1.1.1(@types/react@18.2.48)(react@18.2.0)':
+ '@radix-ui/react-compose-refs@1.1.2(@types/react@18.2.48)(react@18.2.0)':
dependencies:
react: 18.2.0
optionalDependencies:
'@types/react': 18.2.48
- '@radix-ui/react-context-menu@2.2.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-context-menu@2.2.15(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-menu': 2.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-menu': 2.1.15(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -5784,6 +5952,34 @@ snapshots:
optionalDependencies:
'@types/react': 18.2.48
+ '@radix-ui/react-context@1.1.2(@types/react@18.2.48)(react@18.2.0)':
+ dependencies:
+ react: 18.2.0
+ optionalDependencies:
+ '@types/react': 18.2.48
+
+ '@radix-ui/react-dialog@1.1.14(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ aria-hidden: 1.2.4
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ react-remove-scroll: 2.6.3(@types/react@18.2.48)(react@18.2.0)
+ optionalDependencies:
+ '@types/react': 18.2.48
+ '@types/react-dom': 18.2.18
+
'@radix-ui/react-dialog@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
'@radix-ui/primitive': 1.1.0
@@ -5806,29 +6002,7 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-dialog@1.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
- dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-id': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-slot': 1.1.2(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- aria-hidden: 1.2.4
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- react-remove-scroll: 2.6.3(@types/react@18.2.48)(react@18.2.0)
- optionalDependencies:
- '@types/react': 18.2.48
- '@types/react-dom': 18.2.18
-
- '@radix-ui/react-direction@1.1.0(@types/react@18.2.48)(react@18.2.0)':
+ '@radix-ui/react-direction@1.1.1(@types/react@18.2.48)(react@18.2.0)':
dependencies:
react: 18.2.0
optionalDependencies:
@@ -5847,28 +6021,28 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-dismissable-layer@1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-dropdown-menu@2.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-dropdown-menu@2.1.15(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-id': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-menu': 2.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-menu': 2.1.15(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -5881,6 +6055,12 @@ snapshots:
optionalDependencies:
'@types/react': 18.2.48
+ '@radix-ui/react-focus-guards@1.1.2(@types/react@18.2.48)(react@18.2.0)':
+ dependencies:
+ react: 18.2.0
+ optionalDependencies:
+ '@types/react': 18.2.48
+
'@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.48)(react@18.2.0)
@@ -5892,28 +6072,28 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-hover-card@1.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-hover-card@1.1.14(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-popper': 1.2.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -5931,33 +6111,40 @@ snapshots:
optionalDependencies:
'@types/react': 18.2.48
- '@radix-ui/react-label@2.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-id@1.1.1(@types/react@18.2.48)(react@18.2.0)':
dependencies:
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ react: 18.2.0
+ optionalDependencies:
+ '@types/react': 18.2.48
+
+ '@radix-ui/react-label@2.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-menu@2.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-menu@2.1.15(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-id': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-slot': 1.1.2(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-popper': 1.2.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
aria-hidden: 1.2.4
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
@@ -5966,28 +6153,51 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-navigation-menu@1.2.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-navigation-menu@1.2.13(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-id': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-previous': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-previous': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
+ '@radix-ui/react-popover@1.1.14(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-popper': 1.2.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ aria-hidden: 1.2.4
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ react-remove-scroll: 2.6.3(@types/react@18.2.48)(react@18.2.0)
+ optionalDependencies:
+ '@types/react': 18.2.48
+ '@types/react-dom': 18.2.18
+
'@radix-ui/react-popover@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
'@radix-ui/primitive': 1.1.0
@@ -6011,29 +6221,6 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-popover@1.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
- dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-id': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-slot': 1.1.2(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- aria-hidden: 1.2.4
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- react-remove-scroll: 2.6.3(@types/react@18.2.48)(react@18.2.0)
- optionalDependencies:
- '@types/react': 18.2.48
- '@types/react-dom': 18.2.18
-
'@radix-ui/react-popper@1.2.0(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
'@floating-ui/react-dom': 2.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -6052,18 +6239,18 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-popper@1.2.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-popper@1.2.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
'@floating-ui/react-dom': 2.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-arrow': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-rect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-size': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/rect': 1.1.0
+ '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-rect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-size': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/rect': 1.1.1
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -6080,10 +6267,10 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-portal@1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-portal@1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -6100,10 +6287,10 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-presence@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-presence@1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -6119,98 +6306,98 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-primitive@2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-primitive@2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-slot': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-progress@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-progress@1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-radio-group@1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-radio-group@1.3.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-previous': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-size': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-previous': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-size': 1.1.1(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-roving-focus@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-roving-focus@1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-id': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-scroll-area@1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-scroll-area@1.2.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/number': 1.1.0
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/number': 1.1.1
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-select@2.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-select@2.2.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/number': 1.1.0
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-id': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-slot': 1.1.2(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-previous': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/number': 1.1.1
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-popper': 1.2.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-previous': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
aria-hidden: 1.2.4
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
@@ -6219,28 +6406,28 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-separator@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-separator@1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-slider@1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-slider@1.3.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/number': 1.1.0
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-previous': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-size': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/number': 1.1.1
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-previous': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-size': 1.1.1(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -6254,38 +6441,58 @@ snapshots:
optionalDependencies:
'@types/react': 18.2.48
- '@radix-ui/react-slot@1.1.2(@types/react@18.2.48)(react@18.2.0)':
+ '@radix-ui/react-slot@1.2.3(@types/react@18.2.48)(react@18.2.0)':
dependencies:
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
optionalDependencies:
'@types/react': 18.2.48
- '@radix-ui/react-switch@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-switch@1.2.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-previous': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-size': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-previous': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-size': 1.1.1(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-tabs@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-tabs@1.1.12(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-id': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ optionalDependencies:
+ '@types/react': 18.2.48
+ '@types/react-dom': 18.2.18
+
+ '@radix-ui/react-toast@1.2.14(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -6312,81 +6519,61 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-toast@1.2.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-toggle-group@1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-toggle': 1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-toggle-group@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-toggle@1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-toggle': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-toggle@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-toolbar@1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-separator': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-toggle-group': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-toolbar@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-tooltip@1.2.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-separator': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-toggle-group': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- optionalDependencies:
- '@types/react': 18.2.48
- '@types/react-dom': 18.2.18
-
- '@radix-ui/react-tooltip@1.1.8(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
- dependencies:
- '@radix-ui/primitive': 1.1.1
- '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-context': 1.1.1(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-id': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-slot': 1.1.2(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/primitive': 1.1.2
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-popper': 1.2.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -6399,6 +6586,12 @@ snapshots:
optionalDependencies:
'@types/react': 18.2.48
+ '@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.2.48)(react@18.2.0)':
+ dependencies:
+ react: 18.2.0
+ optionalDependencies:
+ '@types/react': 18.2.48
+
'@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.2.48)(react@18.2.0)':
dependencies:
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
@@ -6406,6 +6599,21 @@ snapshots:
optionalDependencies:
'@types/react': 18.2.48
+ '@radix-ui/react-use-controllable-state@1.2.2(@types/react@18.2.48)(react@18.2.0)':
+ dependencies:
+ '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ react: 18.2.0
+ optionalDependencies:
+ '@types/react': 18.2.48
+
+ '@radix-ui/react-use-effect-event@0.0.2(@types/react@18.2.48)(react@18.2.0)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ react: 18.2.0
+ optionalDependencies:
+ '@types/react': 18.2.48
+
'@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.2.48)(react@18.2.0)':
dependencies:
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.48)(react@18.2.0)
@@ -6413,13 +6621,33 @@ snapshots:
optionalDependencies:
'@types/react': 18.2.48
+ '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@18.2.48)(react@18.2.0)':
+ dependencies:
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ react: 18.2.0
+ optionalDependencies:
+ '@types/react': 18.2.48
+
+ '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@18.2.48)(react@18.2.0)':
+ dependencies:
+ react: 18.2.0
+ use-sync-external-store: 1.5.0(react@18.2.0)
+ optionalDependencies:
+ '@types/react': 18.2.48
+
'@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.2.48)(react@18.2.0)':
dependencies:
react: 18.2.0
optionalDependencies:
'@types/react': 18.2.48
- '@radix-ui/react-use-previous@1.1.0(@types/react@18.2.48)(react@18.2.0)':
+ '@radix-ui/react-use-layout-effect@1.1.1(@types/react@18.2.48)(react@18.2.0)':
+ dependencies:
+ react: 18.2.0
+ optionalDependencies:
+ '@types/react': 18.2.48
+
+ '@radix-ui/react-use-previous@1.1.1(@types/react@18.2.48)(react@18.2.0)':
dependencies:
react: 18.2.0
optionalDependencies:
@@ -6432,6 +6660,13 @@ snapshots:
optionalDependencies:
'@types/react': 18.2.48
+ '@radix-ui/react-use-rect@1.1.1(@types/react@18.2.48)(react@18.2.0)':
+ dependencies:
+ '@radix-ui/rect': 1.1.1
+ react: 18.2.0
+ optionalDependencies:
+ '@types/react': 18.2.48
+
'@radix-ui/react-use-size@1.1.0(@types/react@18.2.48)(react@18.2.0)':
dependencies:
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.48)(react@18.2.0)
@@ -6439,6 +6674,13 @@ snapshots:
optionalDependencies:
'@types/react': 18.2.48
+ '@radix-ui/react-use-size@1.1.1(@types/react@18.2.48)(react@18.2.0)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ react: 18.2.0
+ optionalDependencies:
+ '@types/react': 18.2.48
+
'@radix-ui/react-visually-hidden@1.1.0(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -6448,9 +6690,9 @@ snapshots:
'@types/react': 18.2.48
'@types/react-dom': 18.2.18
- '@radix-ui/react-visually-hidden@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
- '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
optionalDependencies:
@@ -6459,6 +6701,8 @@ snapshots:
'@radix-ui/rect@1.1.0': {}
+ '@radix-ui/rect@1.1.1': {}
+
'@remix-run/router@1.19.1': {}
'@sindresorhus/is@5.6.0': {}
@@ -8152,8 +8396,6 @@ snapshots:
tar-fs: 2.1.1
tunnel-agent: 0.6.0
- prettier@3.2.4: {}
-
process@0.11.10: {}
proto-list@1.2.4: {}
@@ -8176,37 +8418,37 @@ snapshots:
radix-ui@1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
dependencies:
- '@radix-ui/react-accessible-icon': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-accordion': 1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-alert-dialog': 1.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-aspect-ratio': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-avatar': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-checkbox': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-collapsible': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-context-menu': 2.2.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-dialog': 1.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-direction': 1.1.0(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-dropdown-menu': 2.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-hover-card': 1.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-label': 2.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-navigation-menu': 1.2.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-popover': 1.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-progress': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-radio-group': 1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-scroll-area': 1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-select': 2.1.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-separator': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-slider': 1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-slot': 1.1.2(@types/react@18.2.48)(react@18.2.0)
- '@radix-ui/react-switch': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-tabs': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-toast': 1.2.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-toggle': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-toggle-group': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-toolbar': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-tooltip': 1.1.8(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-accessible-icon': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-accordion': 1.2.11(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-alert-dialog': 1.1.14(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-aspect-ratio': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-avatar': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-checkbox': 1.3.2(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-collapsible': 1.1.11(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-context-menu': 2.2.15(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-dialog': 1.1.14(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-dropdown-menu': 2.1.15(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-hover-card': 1.1.14(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-label': 2.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-navigation-menu': 1.2.13(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-popover': 1.1.14(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-progress': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-radio-group': 1.3.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-scroll-area': 1.2.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-select': 2.2.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-separator': 1.1.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-slider': 1.3.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.2.48)(react@18.2.0)
+ '@radix-ui/react-switch': 1.2.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-tabs': 1.1.12(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-toast': 1.2.14(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-toggle': 1.1.9(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-toggle-group': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-toolbar': 1.1.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-tooltip': 1.2.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
transitivePeerDependencies:
@@ -8747,6 +8989,10 @@ snapshots:
dependencies:
react: 18.2.0
+ use-sync-external-store@1.5.0(react@18.2.0):
+ dependencies:
+ react: 18.2.0
+
util-deprecate@1.0.2: {}
utility-types@3.11.0: {}
diff --git a/surfsense_browser_extension/popup.tsx b/surfsense_browser_extension/popup.tsx
index bf3ab388c..c41926ced 100644
--- a/surfsense_browser_extension/popup.tsx
+++ b/surfsense_browser_extension/popup.tsx
@@ -1,15 +1,14 @@
-import { MemoryRouter } from "react-router-dom"
-
-import { Routing } from "~routes"
-import { Toaster } from "@/routes/ui/toaster"
+import { MemoryRouter } from "react-router-dom";
+import { Toaster } from "@/routes/ui/toaster";
+import { Routing } from "~routes";
function IndexPopup() {
- return (
-
-
-
-
- )
+ return (
+
+
+
+
+ );
}
-export default IndexPopup
\ No newline at end of file
+export default IndexPopup;
diff --git a/surfsense_browser_extension/postcss.config.js b/surfsense_browser_extension/postcss.config.js
index 12a703d90..e873f1a4f 100644
--- a/surfsense_browser_extension/postcss.config.js
+++ b/surfsense_browser_extension/postcss.config.js
@@ -1,6 +1,6 @@
module.exports = {
- plugins: {
- tailwindcss: {},
- autoprefixer: {},
- },
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
};
diff --git a/surfsense_browser_extension/routes/index.tsx b/surfsense_browser_extension/routes/index.tsx
index a24885b60..8df110be1 100644
--- a/surfsense_browser_extension/routes/index.tsx
+++ b/surfsense_browser_extension/routes/index.tsx
@@ -1,13 +1,12 @@
-import { Route, Routes } from "react-router-dom"
-
-import ApiKeyForm from "./pages/ApiKeyForm"
-import HomePage from "./pages/HomePage"
-import '../tailwind.css'
+import { Route, Routes } from "react-router-dom";
+import ApiKeyForm from "./pages/ApiKeyForm";
+import HomePage from "./pages/HomePage";
+import "../tailwind.css";
export const Routing = () => (
-
- } />
- } />
-
-)
\ No newline at end of file
+
+ } />
+ } />
+
+);
diff --git a/surfsense_browser_extension/routes/pages/ApiKeyForm.tsx b/surfsense_browser_extension/routes/pages/ApiKeyForm.tsx
index 717dc5835..2c8a7f286 100644
--- a/surfsense_browser_extension/routes/pages/ApiKeyForm.tsx
+++ b/surfsense_browser_extension/routes/pages/ApiKeyForm.tsx
@@ -1,123 +1,122 @@
-import React, { useState } from "react";
-import { useNavigate } from "react-router-dom"
-import icon from "data-base64:~assets/icon.png"
-import { Storage } from "@plasmohq/storage"
-import { Button } from "~/routes/ui/button"
-import { ReloadIcon } from "@radix-ui/react-icons"
+import icon from "data-base64:~assets/icon.png";
+import { Storage } from "@plasmohq/storage";
+import { ReloadIcon } from "@radix-ui/react-icons";
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { Button } from "~/routes/ui/button";
const ApiKeyForm = () => {
- const navigation = useNavigate()
- const [apiKey, setApiKey] = useState('');
- const [error, setError] = useState('');
- const [loading, setLoading] = useState(false);
- const storage = new Storage({ area: "local" })
+ const navigation = useNavigate();
+ const [apiKey, setApiKey] = useState("");
+ const [error, setError] = useState("");
+ const [loading, setLoading] = useState(false);
+ const storage = new Storage({ area: "local" });
- const validateForm = () => {
- if (!apiKey) {
- setError('API key is required');
- return false;
- }
- setError('');
- return true;
- };
+ const validateForm = () => {
+ if (!apiKey) {
+ setError("API key is required");
+ return false;
+ }
+ setError("");
+ return true;
+ };
- const handleSubmit = async (event: { preventDefault: () => void; }) => {
- event.preventDefault();
- if (!validateForm()) return;
- setLoading(true);
+ const handleSubmit = async (event: { preventDefault: () => void }) => {
+ event.preventDefault();
+ if (!validateForm()) return;
+ setLoading(true);
- try {
- // Verify token is valid by making a request to the API
- const response = await fetch(`${process.env.PLASMO_PUBLIC_BACKEND_URL}/verify-token`, {
- method: 'GET',
- headers: {
- 'Authorization': `Bearer ${apiKey}`,
- }
- });
+ try {
+ // Verify token is valid by making a request to the API
+ const response = await fetch(`${process.env.PLASMO_PUBLIC_BACKEND_URL}/verify-token`, {
+ method: "GET",
+ headers: {
+ Authorization: `Bearer ${apiKey}`,
+ },
+ });
- setLoading(false);
+ setLoading(false);
- if (response.ok) {
- // Store the API key as the token
- await storage.set('token', apiKey);
- navigation("/")
- } else {
- setError('Invalid API key. Please check and try again.');
- }
- } catch (error) {
- setLoading(false);
- setError('An error occurred. Please try again later.');
- }
- };
+ if (response.ok) {
+ // Store the API key as the token
+ await storage.set("token", apiKey);
+ navigation("/");
+ } else {
+ setError("Invalid API key. Please check and try again.");
+ }
+ } catch (error) {
+ setLoading(false);
+ setError("An error occurred. Please try again later.");
+ }
+ };
- return (
-
-
-
-
-

-
-
SurfSense
-
+ return (
+
+
+
+
+

+
+
SurfSense
+
-
-
-
Enter your API Key
-
- Your API key connects this extension to the SurfSense.
-
+
+
+
Enter your API Key
+
+ Your API key connects this extension to the SurfSense.
+
-
+
+
-
-
-
-
-
- );
-}
+
+
+
+
+
+ );
+};
-export default ApiKeyForm
+export default ApiKeyForm;
diff --git a/surfsense_browser_extension/routes/pages/HomePage.tsx b/surfsense_browser_extension/routes/pages/HomePage.tsx
index 0b45a3c4f..d1366a8df 100644
--- a/surfsense_browser_extension/routes/pages/HomePage.tsx
+++ b/surfsense_browser_extension/routes/pages/HomePage.tsx
@@ -1,476 +1,478 @@
-import React, { useEffect, useState } from "react";
-import { useNavigate } from "react-router-dom"
-import icon from "data-base64:~assets/icon.png"
+import brain from "data-base64:~assets/brain.png";
+import icon from "data-base64:~assets/icon.png";
+import { sendToBackground } from "@plasmohq/messaging";
+import { Storage } from "@plasmohq/storage";
+import {
+ CrossCircledIcon,
+ DiscIcon,
+ ExitIcon,
+ FileIcon,
+ ReloadIcon,
+ UploadIcon,
+} from "@radix-ui/react-icons";
import { convertHtmlToMarkdown } from "dom-to-semantic-markdown";
-import type { WebHistory } from "~utils/interfaces";
-import { getRenderedHtml } from "~utils/commons";
-import Loading from "./Loading";
-import brain from "data-base64:~assets/brain.png"
-import { Storage } from "@plasmohq/storage"
-import { sendToBackground } from "@plasmohq/messaging"
-import { Check, ChevronsUpDown } from "lucide-react"
-import { cn } from "~/lib/utils"
-import { Button } from "~/routes/ui/button"
+import { Check, ChevronsUpDown } from "lucide-react";
+import React, { useEffect, useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { cn } from "~/lib/utils";
+import { Button } from "~/routes/ui/button";
import {
- Command,
- CommandEmpty,
- CommandGroup,
- CommandInput,
- CommandItem,
- CommandList,
-} from "~/routes/ui/command"
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from "~/routes/ui/popover"
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+} from "~/routes/ui/command";
+import { Popover, PopoverContent, PopoverTrigger } from "~/routes/ui/popover";
+import { Label } from "~routes/ui/label";
import { useToast } from "~routes/ui/use-toast";
-import {
- CircleIcon,
- CrossCircledIcon,
- DiscIcon,
- ExitIcon,
- FileIcon,
- ReloadIcon,
- ResetIcon,
- UploadIcon
-} from "@radix-ui/react-icons"
+import { getRenderedHtml } from "~utils/commons";
+import type { WebHistory } from "~utils/interfaces";
+import Loading from "./Loading";
const HomePage = () => {
- const { toast } = useToast()
- const navigation = useNavigate()
- const [noOfWebPages, setNoOfWebPages] = useState(0);
- const [loading, setLoading] = useState(true);
- const [open, setOpen] = React.useState(false)
- const [value, setValue] = React.useState("")
- const [searchspaces, setSearchSpaces] = useState([])
- const [isSaving, setIsSaving] = useState(false);
+ const { toast } = useToast();
+ const navigation = useNavigate();
+ const [noOfWebPages, setNoOfWebPages] = useState(0);
+ const [loading, setLoading] = useState(true);
+ const [open, setOpen] = React.useState(false);
+ const [value, setValue] = React.useState("");
+ const [searchspaces, setSearchSpaces] = useState([]);
+ const [isSaving, setIsSaving] = useState(false);
- useEffect(() => {
- const checkSearchSpaces = async () => {
- const storage = new Storage({ area: "local" })
- const token = await storage.get('token');
- try {
- const response = await fetch(
- `${process.env.PLASMO_PUBLIC_BACKEND_URL}/api/v1/searchspaces/`,
- {
- headers: {
- 'Authorization': `Bearer ${token}`
- }
- }
- );
+ useEffect(() => {
+ const checkSearchSpaces = async () => {
+ const storage = new Storage({ area: "local" });
+ const token = await storage.get("token");
+ try {
+ const response = await fetch(
+ `${process.env.PLASMO_PUBLIC_BACKEND_URL}/api/v1/searchspaces/`,
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ }
+ );
- if (!response.ok) {
- throw new Error("Token verification failed");
- } else {
- const res = await response.json()
- console.log(res)
- setSearchSpaces(res)
- }
- } catch (error) {
- await storage.remove('token');
- await storage.remove('showShadowDom');
- navigation("/login")
- }
- };
+ if (!response.ok) {
+ throw new Error("Token verification failed");
+ } else {
+ const res = await response.json();
+ console.log(res);
+ setSearchSpaces(res);
+ }
+ } catch (error) {
+ await storage.remove("token");
+ await storage.remove("showShadowDom");
+ navigation("/login");
+ }
+ };
- checkSearchSpaces();
- setLoading(false);
- }, []);
+ checkSearchSpaces();
+ setLoading(false);
+ }, []);
+ useEffect(() => {
+ async function onLoad() {
+ try {
+ chrome.storage.onChanged.addListener((changes: any, areaName: string) => {
+ if (changes.webhistory) {
+ const webhistory = JSON.parse(changes.webhistory.newValue);
+ console.log("webhistory", webhistory);
- useEffect(() => {
- async function onLoad() {
- try {
- chrome.storage.onChanged.addListener(
- (changes: any, areaName: string) => {
- if (changes.webhistory) {
- const webhistory = JSON.parse(changes.webhistory.newValue);
- console.log("webhistory", webhistory)
+ let sum = 0;
+ webhistory.webhistory.forEach((element: any) => {
+ sum = sum + element.tabHistory.length;
+ });
- let sum = 0
- webhistory.webhistory.forEach((element: any) => {
- sum = sum + element.tabHistory.length
- });
+ setNoOfWebPages(sum);
+ }
+ });
- setNoOfWebPages(sum)
- }
- }
- );
+ const storage = new Storage({ area: "local" });
+ const searchspace = await storage.get("search_space");
- const storage = new Storage({ area: "local" })
- const searchspace = await storage.get("search_space");
+ if (searchspace) {
+ setValue(searchspace);
+ }
- if(searchspace){
- setValue(searchspace)
- }
+ await storage.set("showShadowDom", true);
- await storage.set("showShadowDom", true)
+ const webhistoryObj: any = await storage.get("webhistory");
+ if (webhistoryObj.webhistory.length) {
+ const webhistory = webhistoryObj.webhistory;
- const webhistoryObj: any = await storage.get("webhistory");
- if (webhistoryObj.webhistory.length) {
- const webhistory = webhistoryObj.webhistory;
+ if (webhistoryObj) {
+ let sum = 0;
+ webhistory.forEach((element: any) => {
+ sum = sum + element.tabHistory.length;
+ });
+ setNoOfWebPages(sum);
+ }
+ } else {
+ setNoOfWebPages(0);
+ }
+ } catch (error) {
+ console.log(error);
+ }
+ }
- if (webhistoryObj) {
- let sum = 0
- webhistory.forEach((element: any) => {
- sum = sum + element.tabHistory.length
- });
- setNoOfWebPages(sum)
- }
- } else {
- setNoOfWebPages(0)
- }
- } catch (error) {
- console.log(error);
- }
- }
+ onLoad();
+ }, []);
- onLoad()
- }, []);
+ async function clearMem(): Promise {
+ try {
+ const storage = new Storage({ area: "local" });
- async function clearMem(): Promise {
- try {
- const storage = new Storage({ area: "local" })
-
- let webHistory: any = await storage.get("webhistory");
- let urlQueue: any = await storage.get("urlQueueList");
- let timeQueue: any = await storage.get("timeQueueList");
-
- if (!webHistory.webhistory) {
- return
- }
-
- //Main Cleanup COde
- chrome.tabs.query({}, async (tabs) => {
- //Get Active Tabs Ids
- let actives = tabs.map((tab) => {
- if (tab.id) {
- return tab.id
- }
- })
-
- actives = actives.filter((item: any) => item)
-
- //Only retain which is still active
- const newHistory = webHistory.webhistory.map((element: any) => {
- //@ts-ignore
- if (actives.includes(element.tabsessionId)) {
- return element
- }
- })
-
- const newUrlQueue = urlQueue.urlQueueList.map((element: any) => {
- //@ts-ignore
- if (actives.includes(element.tabsessionId)) {
- return element
- }
- })
-
- const newTimeQueue = timeQueue.timeQueueList.map((element: any) => {
- //@ts-ignore
- if (actives.includes(element.tabsessionId)) {
- return element
- }
- })
-
- await storage.set("webhistory", { webhistory: newHistory.filter((item: any) => item) });
- await storage.set("urlQueueList", { urlQueueList: newUrlQueue.filter((item: any) => item) });
- await storage.set("timeQueueList", { timeQueueList: newTimeQueue.filter((item: any) => item) });
- toast({
- title: "History store cleared",
- description: "Inactive history sessions have been removed",
- variant: "destructive",
- })
- });
- } catch (error) {
- console.log(error);
- }
- }
+ const webHistory: any = await storage.get("webhistory");
+ const urlQueue: any = await storage.get("urlQueueList");
+ const timeQueue: any = await storage.get("timeQueueList");
- async function saveCurrSnapShot(): Promise {
- chrome.tabs.query({ active: true, currentWindow: true }, async function (tabs) {
- const storage = new Storage({ area: "local" })
- const tab = tabs[0];
- if (tab.id) {
- const tabId: number = tab.id
- const result = await chrome.scripting.executeScript({
- // @ts-ignore
- target: { tabId: tab.id },
- // @ts-ignore
- func: getRenderedHtml,
- });
+ if (!webHistory.webhistory) {
+ return;
+ }
- let toPushInTabHistory: any = result[0].result;
+ //Main Cleanup COde
+ chrome.tabs.query({}, async (tabs) => {
+ //Get Active Tabs Ids
+ let actives = tabs.map((tab) => {
+ if (tab.id) {
+ return tab.id;
+ }
+ });
- //Updates 'tabhistory'
- let webhistoryObj: any = await storage.get("webhistory");
+ actives = actives.filter((item: any) => item);
- const webHistoryOfTabId = webhistoryObj.webhistory.filter(
- (data: WebHistory) => {
- return data.tabsessionId === tab.id;
- }
- );
+ //Only retain which is still active
+ const newHistory = webHistory.webhistory.map((element: any) => {
+ //@ts-ignore
+ if (actives.includes(element.tabsessionId)) {
+ return element;
+ }
+ });
- toPushInTabHistory.pageContentMarkdown = convertHtmlToMarkdown(
- toPushInTabHistory.renderedHtml,
- {
- extractMainContent: true,
- includeMetaData: false,
- enableTableColumnTracking: true
- }
- )
+ const newUrlQueue = urlQueue.urlQueueList.map((element: any) => {
+ //@ts-ignore
+ if (actives.includes(element.tabsessionId)) {
+ return element;
+ }
+ });
- delete toPushInTabHistory.renderedHtml
+ const newTimeQueue = timeQueue.timeQueueList.map((element: any) => {
+ //@ts-ignore
+ if (actives.includes(element.tabsessionId)) {
+ return element;
+ }
+ });
- let tabhistory = webHistoryOfTabId[0].tabHistory;
+ await storage.set("webhistory", { webhistory: newHistory.filter((item: any) => item) });
+ await storage.set("urlQueueList", {
+ urlQueueList: newUrlQueue.filter((item: any) => item),
+ });
+ await storage.set("timeQueueList", {
+ timeQueueList: newTimeQueue.filter((item: any) => item),
+ });
+ toast({
+ title: "History store cleared",
+ description: "Inactive history sessions have been removed",
+ variant: "destructive",
+ });
+ });
+ } catch (error) {
+ console.log(error);
+ }
+ }
- const urlQueueListObj: any = await storage.get("urlQueueList");
- const timeQueueListObj: any = await storage.get("timeQueueList");
+ async function saveCurrSnapShot(): Promise {
+ chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => {
+ const storage = new Storage({ area: "local" });
+ const tab = tabs[0];
+ if (tab.id) {
+ const tabId: number = tab.id;
+ const result = await chrome.scripting.executeScript({
+ // @ts-ignore
+ target: { tabId: tab.id },
+ // @ts-ignore
+ func: getRenderedHtml,
+ });
- const isUrlQueueThere = urlQueueListObj.urlQueueList.find((data: WebHistory) => data.tabsessionId === tabId)
- const isTimeQueueThere = timeQueueListObj.timeQueueList.find((data: WebHistory) => data.tabsessionId === tabId)
+ const toPushInTabHistory: any = result[0].result;
- toPushInTabHistory.duration = toPushInTabHistory.entryTime - isTimeQueueThere.timeQueue[isTimeQueueThere.timeQueue.length - 1]
- if (isUrlQueueThere.urlQueue.length == 1) {
- toPushInTabHistory.reffererUrl = 'START'
- }
- if (isUrlQueueThere.urlQueue.length > 1) {
- toPushInTabHistory.reffererUrl = isUrlQueueThere.urlQueue[isUrlQueueThere.urlQueue.length - 2];
- }
+ //Updates 'tabhistory'
+ const webhistoryObj: any = await storage.get("webhistory");
- webHistoryOfTabId[0].tabHistory.push(toPushInTabHistory);
-
- await storage.set("webhistory", webhistoryObj);
-
- toast({
- title: "Snapshot saved",
- description: `Captured: ${toPushInTabHistory.title}`,
- })
- }
+ const webHistoryOfTabId = webhistoryObj.webhistory.filter((data: WebHistory) => {
+ return data.tabsessionId === tab.id;
+ });
- });
- }
+ toPushInTabHistory.pageContentMarkdown = convertHtmlToMarkdown(
+ toPushInTabHistory.renderedHtml,
+ {
+ extractMainContent: true,
+ includeMetaData: false,
+ enableTableColumnTracking: true,
+ }
+ );
- const saveDatamessage = async () => {
- if (value === "") {
- toast({
- title: "Select a SearchSpace !",
- })
- return
- }
-
- const storage = new Storage({ area: "local" })
- const search_space_id = await storage.get("search_space_id");
-
- if (!search_space_id) {
- toast({
- title: "Invalid SearchSpace selected!",
- variant: "destructive",
- })
- return
- }
+ delete toPushInTabHistory.renderedHtml;
- setIsSaving(true);
- toast({
- title: "Save job running",
- description: "Saving captured content to SurfSense",
- })
+ const tabhistory = webHistoryOfTabId[0].tabHistory;
- try {
- const resp = await sendToBackground({
- // @ts-ignore
- name: "savedata",
- })
+ const urlQueueListObj: any = await storage.get("urlQueueList");
+ const timeQueueListObj: any = await storage.get("timeQueueList");
- toast({
- title: resp.message,
- })
- } catch (error) {
- toast({
- title: "Error saving data",
- description: "Please try again",
- variant: "destructive",
- })
- } finally {
- setIsSaving(false);
- }
- }
+ const isUrlQueueThere = urlQueueListObj.urlQueueList.find(
+ (data: WebHistory) => data.tabsessionId === tabId
+ );
+ const isTimeQueueThere = timeQueueListObj.timeQueueList.find(
+ (data: WebHistory) => data.tabsessionId === tabId
+ );
- async function logOut(): Promise {
- const storage = new Storage({ area: "local" })
- await storage.remove('token');
- await storage.remove('showShadowDom');
- navigation("/login")
- }
+ toPushInTabHistory.duration =
+ toPushInTabHistory.entryTime -
+ isTimeQueueThere.timeQueue[isTimeQueueThere.timeQueue.length - 1];
+ if (isUrlQueueThere.urlQueue.length === 1) {
+ toPushInTabHistory.reffererUrl = "START";
+ }
+ if (isUrlQueueThere.urlQueue.length > 1) {
+ toPushInTabHistory.reffererUrl =
+ isUrlQueueThere.urlQueue[isUrlQueueThere.urlQueue.length - 2];
+ }
- if (loading) {
- return ;
- } else {
- return searchspaces.length === 0 ? (
-
-
-
-
-
-

-
-
SurfSense
-
-
Please create a Search Space to continue
-
-
-
-
-
-
-
-
-
- ) : (
-
-
-
-
-
-

-
-
SurfSense
-
-
-
+ webHistoryOfTabId[0].tabHistory.push(toPushInTabHistory);
-
-
-
-
-

-
{noOfWebPages}
-
-
-
Captured web pages
-
+ await storage.set("webhistory", webhistoryObj);
-
-
-
-
-
-
-
-
-
-
- No search spaces found.
-
- {searchspaces.map((space) => (
- {
- const storage = new Storage({ area: "local" })
- if (currentValue === value) {
- await storage.set("search_space", "");
- await storage.set("search_space_id", 0);
- } else {
- const selectedSpace = searchspaces.find((space) => space.name === currentValue);
- await storage.set("search_space", currentValue);
- await storage.set("search_space_id", selectedSpace.id);
- }
- setValue(currentValue === value ? "" : currentValue)
- setOpen(false)
- }}
- className="aria-selected:bg-gray-700"
- >
-
-
-
- {space.name}
-
-
- ))}
-
-
-
-
-
-
+ toast({
+ title: "Snapshot saved",
+ description: `Captured: ${toPushInTabHistory.title}`,
+ });
+ }
+ });
+ }
-
-
-
-
-
-
-
-
-
-
- );
- }
+ const saveDatamessage = async () => {
+ if (value === "") {
+ toast({
+ title: "Select a SearchSpace !",
+ });
+ return;
+ }
+
+ const storage = new Storage({ area: "local" });
+ const search_space_id = await storage.get("search_space_id");
+
+ if (!search_space_id) {
+ toast({
+ title: "Invalid SearchSpace selected!",
+ variant: "destructive",
+ });
+ return;
+ }
+
+ setIsSaving(true);
+ toast({
+ title: "Save job running",
+ description: "Saving captured content to SurfSense",
+ });
+
+ try {
+ const resp = await sendToBackground({
+ // @ts-ignore
+ name: "savedata",
+ });
+
+ toast({
+ title: resp.message,
+ });
+ } catch (error) {
+ toast({
+ title: "Error saving data",
+ description: "Please try again",
+ variant: "destructive",
+ });
+ } finally {
+ setIsSaving(false);
+ }
+ };
+
+ async function logOut(): Promise {
+ const storage = new Storage({ area: "local" });
+ await storage.remove("token");
+ await storage.remove("showShadowDom");
+ navigation("/login");
+ }
+
+ if (loading) {
+ return ;
+ } else {
+ return searchspaces.length === 0 ? (
+
+
+
+
+
+

+
+
SurfSense
+
+
Please create a Search Space to continue
+
+
+
+
+
+
+
+
+
+ ) : (
+
+
+
+
+
+

+
+
SurfSense
+
+
+
+
+
+
+
+
+

+
{noOfWebPages}
+
+
+
Captured web pages
+
+
+
+
+
+
+
+
+
+
+
+
+ No search spaces found.
+
+ {searchspaces.map((space) => (
+ {
+ const storage = new Storage({ area: "local" });
+ if (currentValue === value) {
+ await storage.set("search_space", "");
+ await storage.set("search_space_id", 0);
+ } else {
+ const selectedSpace = searchspaces.find(
+ (space) => space.name === currentValue
+ );
+ await storage.set("search_space", currentValue);
+ await storage.set("search_space_id", selectedSpace.id);
+ }
+ setValue(currentValue === value ? "" : currentValue);
+ setOpen(false);
+ }}
+ className="aria-selected:bg-gray-700"
+ >
+
+
+
+ {space.name}
+
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
};
-export default HomePage
\ No newline at end of file
+export default HomePage;
diff --git a/surfsense_browser_extension/routes/pages/Loading.tsx b/surfsense_browser_extension/routes/pages/Loading.tsx
index e1bba1b9c..4b04705d8 100644
--- a/surfsense_browser_extension/routes/pages/Loading.tsx
+++ b/surfsense_browser_extension/routes/pages/Loading.tsx
@@ -1,38 +1,37 @@
-import React from 'react'
-import icon from "data-base64:~assets/icon.png"
-import { ReloadIcon } from "@radix-ui/react-icons"
+import icon from "data-base64:~assets/icon.png";
+import { ReloadIcon } from "@radix-ui/react-icons";
const Loading = () => {
- return (
-
-
-
-
-

-
-
SurfSense
-
-
-
-
-
- {Array.from("LOADING").map((letter, i) => (
-
- {letter}
-
- ))}
-
-
-
-
- )
-}
+ return (
+
+
+
+
+

+
+
SurfSense
+
-export default Loading
\ No newline at end of file
+
+
+
+ {Array.from("LOADING").map((letter, i) => (
+
+ {letter}
+
+ ))}
+
+
+
+
+ );
+};
+
+export default Loading;
diff --git a/surfsense_browser_extension/routes/ui/button.tsx b/surfsense_browser_extension/routes/ui/button.tsx
index 65729daa1..7eec6438e 100644
--- a/surfsense_browser_extension/routes/ui/button.tsx
+++ b/surfsense_browser_extension/routes/ui/button.tsx
@@ -1,56 +1,49 @@
-import * as React from "react"
-import { Slot } from "@radix-ui/react-slot"
-import { cva, type VariantProps } from "class-variance-authority"
+import { Slot } from "@radix-ui/react-slot";
+import { cva, type VariantProps } from "class-variance-authority";
+import * as React from "react";
-import { cn } from "~/lib/utils"
+import { cn } from "~/lib/utils";
const buttonVariants = cva(
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
- {
- variants: {
- variant: {
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
- destructive:
- "bg-destructive text-destructive-foreground hover:bg-destructive/90",
- outline:
- "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
- secondary:
- "bg-secondary text-secondary-foreground hover:bg-secondary/80",
- ghost: "hover:bg-accent hover:text-accent-foreground",
- link: "text-primary underline-offset-4 hover:underline",
- },
- size: {
- default: "h-10 px-4 py-2",
- sm: "h-9 rounded-md px-3",
- lg: "h-11 rounded-md px-8",
- icon: "h-10 w-10",
- },
- },
- defaultVariants: {
- variant: "default",
- size: "default",
- },
- }
-)
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
+ {
+ variants: {
+ variant: {
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
+ outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
+ ghost: "hover:bg-accent hover:text-accent-foreground",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-10 px-4 py-2",
+ sm: "h-9 rounded-md px-3",
+ lg: "h-11 rounded-md px-8",
+ icon: "h-10 w-10",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+);
export interface ButtonProps
- extends React.ButtonHTMLAttributes,
- VariantProps {
- asChild?: boolean
+ extends React.ButtonHTMLAttributes,
+ VariantProps {
+ asChild?: boolean;
}
const Button = React.forwardRef(
- ({ className, variant, size, asChild = false, ...props }, ref) => {
- const Comp = asChild ? Slot : "button"
- return (
-
- )
- }
-)
-Button.displayName = "Button"
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
+ const Comp = asChild ? Slot : "button";
+ return (
+
+ );
+ }
+);
+Button.displayName = "Button";
-export { Button, buttonVariants }
+export { Button, buttonVariants };
diff --git a/surfsense_browser_extension/routes/ui/command.tsx b/surfsense_browser_extension/routes/ui/command.tsx
index 15f897110..8d4c59ead 100644
--- a/surfsense_browser_extension/routes/ui/command.tsx
+++ b/surfsense_browser_extension/routes/ui/command.tsx
@@ -1,155 +1,145 @@
-"use client"
+"use client";
-import * as React from "react"
-import { type DialogProps } from "@radix-ui/react-dialog"
-import { Command as CommandPrimitive } from "cmdk"
-import { Search } from "lucide-react"
+import type { DialogProps } from "@radix-ui/react-dialog";
+import { Command as CommandPrimitive } from "cmdk";
+import { Search } from "lucide-react";
+import * as React from "react";
-import { cn } from "~/lib/utils"
-import { Dialog, DialogContent } from "~/routes/ui/dialog"
+import { cn } from "~/lib/utils";
+import { Dialog, DialogContent } from "~/routes/ui/dialog";
const Command = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
-Command.displayName = CommandPrimitive.displayName
+
+));
+Command.displayName = CommandPrimitive.displayName;
interface CommandDialogProps extends DialogProps {}
const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
- return (
-
- )
-}
+ return (
+
+ );
+};
const CommandInput = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-
-
-
-))
+
+
+
+
+));
-CommandInput.displayName = CommandPrimitive.Input.displayName
+CommandInput.displayName = CommandPrimitive.Input.displayName;
const CommandList = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
+
+));
-CommandList.displayName = CommandPrimitive.List.displayName
+CommandList.displayName = CommandPrimitive.List.displayName;
const CommandEmpty = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>((props, ref) => (
-
-))
+
+));
-CommandEmpty.displayName = CommandPrimitive.Empty.displayName
+CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
const CommandGroup = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
+
+));
-CommandGroup.displayName = CommandPrimitive.Group.displayName
+CommandGroup.displayName = CommandPrimitive.Group.displayName;
const CommandSeparator = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
-CommandSeparator.displayName = CommandPrimitive.Separator.displayName
+
+));
+CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
const CommandItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
+
+));
-CommandItem.displayName = CommandPrimitive.Item.displayName
+CommandItem.displayName = CommandPrimitive.Item.displayName;
-const CommandShortcut = ({
- className,
- ...props
-}: React.HTMLAttributes) => {
- return (
-
- )
-}
-CommandShortcut.displayName = "CommandShortcut"
+const CommandShortcut = ({ className, ...props }: React.HTMLAttributes) => {
+ return (
+
+ );
+};
+CommandShortcut.displayName = "CommandShortcut";
export {
- Command,
- CommandDialog,
- CommandInput,
- CommandList,
- CommandEmpty,
- CommandGroup,
- CommandItem,
- CommandShortcut,
- CommandSeparator,
-}
+ Command,
+ CommandDialog,
+ CommandInput,
+ CommandList,
+ CommandEmpty,
+ CommandGroup,
+ CommandItem,
+ CommandShortcut,
+ CommandSeparator,
+};
diff --git a/surfsense_browser_extension/routes/ui/dialog.tsx b/surfsense_browser_extension/routes/ui/dialog.tsx
index 9850daa41..f041eabdf 100644
--- a/surfsense_browser_extension/routes/ui/dialog.tsx
+++ b/surfsense_browser_extension/routes/ui/dialog.tsx
@@ -1,122 +1,104 @@
-"use client"
+"use client";
-import * as React from "react"
-import * as DialogPrimitive from "@radix-ui/react-dialog"
-import { X } from "lucide-react"
+import * as DialogPrimitive from "@radix-ui/react-dialog";
+import { X } from "lucide-react";
+import * as React from "react";
-import { cn } from "~/lib/utils"
+import { cn } from "~/lib/utils";
-const Dialog = DialogPrimitive.Root
+const Dialog = DialogPrimitive.Root;
-const DialogTrigger = DialogPrimitive.Trigger
+const DialogTrigger = DialogPrimitive.Trigger;
-const DialogPortal = DialogPrimitive.Portal
+const DialogPortal = DialogPrimitive.Portal;
-const DialogClose = DialogPrimitive.Close
+const DialogClose = DialogPrimitive.Close;
const DialogOverlay = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
-DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
+
+));
+DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
const DialogContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, children, ...props }, ref) => (
-
-
-
- {children}
-
-
- Close
-
-
-
-))
-DialogContent.displayName = DialogPrimitive.Content.displayName
+
+
+
+ {children}
+
+
+ Close
+
+
+
+));
+DialogContent.displayName = DialogPrimitive.Content.displayName;
-const DialogHeader = ({
- className,
- ...props
-}: React.HTMLAttributes) => (
-
-)
-DialogHeader.displayName = "DialogHeader"
+const DialogHeader = ({ className, ...props }: React.HTMLAttributes) => (
+
+);
+DialogHeader.displayName = "DialogHeader";
-const DialogFooter = ({
- className,
- ...props
-}: React.HTMLAttributes) => (
-
-)
-DialogFooter.displayName = "DialogFooter"
+const DialogFooter = ({ className, ...props }: React.HTMLAttributes) => (
+
+);
+DialogFooter.displayName = "DialogFooter";
const DialogTitle = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
-DialogTitle.displayName = DialogPrimitive.Title.displayName
+
+));
+DialogTitle.displayName = DialogPrimitive.Title.displayName;
const DialogDescription = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
-DialogDescription.displayName = DialogPrimitive.Description.displayName
+
+));
+DialogDescription.displayName = DialogPrimitive.Description.displayName;
export {
- Dialog,
- DialogPortal,
- DialogOverlay,
- DialogClose,
- DialogTrigger,
- DialogContent,
- DialogHeader,
- DialogFooter,
- DialogTitle,
- DialogDescription,
-}
+ Dialog,
+ DialogPortal,
+ DialogOverlay,
+ DialogClose,
+ DialogTrigger,
+ DialogContent,
+ DialogHeader,
+ DialogFooter,
+ DialogTitle,
+ DialogDescription,
+};
diff --git a/surfsense_browser_extension/routes/ui/label.tsx b/surfsense_browser_extension/routes/ui/label.tsx
new file mode 100644
index 000000000..eca3fdbda
--- /dev/null
+++ b/surfsense_browser_extension/routes/ui/label.tsx
@@ -0,0 +1,21 @@
+"use client";
+
+import * as LabelPrimitive from "@radix-ui/react-label";
+import type * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+function Label({ className, ...props }: React.ComponentProps) {
+ return (
+
+ );
+}
+
+export { Label };
diff --git a/surfsense_browser_extension/routes/ui/popover.tsx b/surfsense_browser_extension/routes/ui/popover.tsx
index d45a633e7..fc4cb8b4e 100644
--- a/surfsense_browser_extension/routes/ui/popover.tsx
+++ b/surfsense_browser_extension/routes/ui/popover.tsx
@@ -1,31 +1,31 @@
-"use client"
+"use client";
-import * as React from "react"
-import * as PopoverPrimitive from "@radix-ui/react-popover"
+import * as PopoverPrimitive from "@radix-ui/react-popover";
+import * as React from "react";
-import { cn } from "~/lib/utils"
+import { cn } from "~/lib/utils";
-const Popover = PopoverPrimitive.Root
+const Popover = PopoverPrimitive.Root;
-const PopoverTrigger = PopoverPrimitive.Trigger
+const PopoverTrigger = PopoverPrimitive.Trigger;
const PopoverContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
-
-
-
-))
-PopoverContent.displayName = PopoverPrimitive.Content.displayName
+
+
+
+));
+PopoverContent.displayName = PopoverPrimitive.Content.displayName;
-export { Popover, PopoverTrigger, PopoverContent }
+export { Popover, PopoverTrigger, PopoverContent };
diff --git a/surfsense_browser_extension/routes/ui/toast.tsx b/surfsense_browser_extension/routes/ui/toast.tsx
index 521b94b07..dd03a72d4 100644
--- a/surfsense_browser_extension/routes/ui/toast.tsx
+++ b/surfsense_browser_extension/routes/ui/toast.tsx
@@ -1,129 +1,124 @@
-"use client"
+"use client";
-import * as React from "react"
-import * as ToastPrimitives from "@radix-ui/react-toast"
-import { cva, type VariantProps } from "class-variance-authority"
-import { X } from "lucide-react"
+import * as ToastPrimitives from "@radix-ui/react-toast";
+import { cva, type VariantProps } from "class-variance-authority";
+import { X } from "lucide-react";
+import * as React from "react";
-import { cn } from "@/lib/utils"
+import { cn } from "@/lib/utils";
-const ToastProvider = ToastPrimitives.Provider
+const ToastProvider = ToastPrimitives.Provider;
const ToastViewport = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
-ToastViewport.displayName = ToastPrimitives.Viewport.displayName
+
+));
+ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
const toastVariants = cva(
- "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
- {
- variants: {
- variant: {
- default: "border bg-background text-foreground",
- destructive:
- "destructive group border-destructive bg-destructive text-destructive-foreground",
- },
- },
- defaultVariants: {
- variant: "default",
- },
- }
-)
+ "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
+ {
+ variants: {
+ variant: {
+ default: "border bg-background text-foreground",
+ destructive:
+ "destructive group border-destructive bg-destructive text-destructive-foreground",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ }
+);
const Toast = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef &
- VariantProps
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & VariantProps
>(({ className, variant, ...props }, ref) => {
- return (
-
- )
-})
-Toast.displayName = ToastPrimitives.Root.displayName
+ return (
+
+ );
+});
+Toast.displayName = ToastPrimitives.Root.displayName;
const ToastAction = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
-ToastAction.displayName = ToastPrimitives.Action.displayName
+
+));
+ToastAction.displayName = ToastPrimitives.Action.displayName;
const ToastClose = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-
-
-))
-ToastClose.displayName = ToastPrimitives.Close.displayName
+
+
+
+));
+ToastClose.displayName = ToastPrimitives.Close.displayName;
const ToastTitle = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
-ToastTitle.displayName = ToastPrimitives.Title.displayName
+
+));
+ToastTitle.displayName = ToastPrimitives.Title.displayName;
const ToastDescription = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-))
-ToastDescription.displayName = ToastPrimitives.Description.displayName
+
+));
+ToastDescription.displayName = ToastPrimitives.Description.displayName;
-type ToastProps = React.ComponentPropsWithoutRef
+type ToastProps = React.ComponentPropsWithoutRef;
-type ToastActionElement = React.ReactElement
+type ToastActionElement = React.ReactElement;
export {
- type ToastProps,
- type ToastActionElement,
- ToastProvider,
- ToastViewport,
- Toast,
- ToastTitle,
- ToastDescription,
- ToastClose,
- ToastAction,
-}
+ type ToastProps,
+ type ToastActionElement,
+ ToastProvider,
+ ToastViewport,
+ Toast,
+ ToastTitle,
+ ToastDescription,
+ ToastClose,
+ ToastAction,
+};
diff --git a/surfsense_browser_extension/routes/ui/toaster.tsx b/surfsense_browser_extension/routes/ui/toaster.tsx
index 89077be38..7369163dd 100644
--- a/surfsense_browser_extension/routes/ui/toaster.tsx
+++ b/surfsense_browser_extension/routes/ui/toaster.tsx
@@ -1,35 +1,31 @@
-"use client"
+"use client";
-import { useToast } from "@/routes/ui/use-toast"
import {
- Toast,
- ToastClose,
- ToastDescription,
- ToastProvider,
- ToastTitle,
- ToastViewport,
-} from "@/routes/ui/toast"
+ Toast,
+ ToastClose,
+ ToastDescription,
+ ToastProvider,
+ ToastTitle,
+ ToastViewport,
+} from "@/routes/ui/toast";
+import { useToast } from "@/routes/ui/use-toast";
export function Toaster() {
- const { toasts } = useToast()
+ const { toasts } = useToast();
- return (
-
- {toasts.map(function ({ id, title, description, action, ...props }) {
- return (
-
-
- {title && {title}}
- {description && (
- {description}
- )}
-
- {action}
-
-
- )
- })}
-
-
- )
+ return (
+
+ {toasts.map(({ id, title, description, action, ...props }) => (
+
+
+ {title && {title}}
+ {description && {description}}
+
+ {action}
+
+
+ ))}
+
+
+ );
}
diff --git a/surfsense_browser_extension/routes/ui/use-toast.tsx b/surfsense_browser_extension/routes/ui/use-toast.tsx
index fd284dca9..2d821ad94 100644
--- a/surfsense_browser_extension/routes/ui/use-toast.tsx
+++ b/surfsense_browser_extension/routes/ui/use-toast.tsx
@@ -1,194 +1,189 @@
-"use client"
+"use client";
// Inspired by react-hot-toast library
-import * as React from "react"
+import * as React from "react";
-import type {
- ToastActionElement,
- ToastProps,
-} from "@/routes/ui/toast"
+import type { ToastActionElement, ToastProps } from "@/routes/ui/toast";
-const TOAST_LIMIT = 1
-const TOAST_REMOVE_DELAY = 1000000
+const TOAST_LIMIT = 1;
+const TOAST_REMOVE_DELAY = 1000000;
type ToasterToast = ToastProps & {
- id: string
- title?: React.ReactNode
- description?: React.ReactNode
- action?: ToastActionElement
-}
+ id: string;
+ title?: React.ReactNode;
+ description?: React.ReactNode;
+ action?: ToastActionElement;
+};
const actionTypes = {
- ADD_TOAST: "ADD_TOAST",
- UPDATE_TOAST: "UPDATE_TOAST",
- DISMISS_TOAST: "DISMISS_TOAST",
- REMOVE_TOAST: "REMOVE_TOAST",
-} as const
+ ADD_TOAST: "ADD_TOAST",
+ UPDATE_TOAST: "UPDATE_TOAST",
+ DISMISS_TOAST: "DISMISS_TOAST",
+ REMOVE_TOAST: "REMOVE_TOAST",
+} as const;
-let count = 0
+let count = 0;
function genId() {
- count = (count + 1) % Number.MAX_SAFE_INTEGER
- return count.toString()
+ count = (count + 1) % Number.MAX_SAFE_INTEGER;
+ return count.toString();
}
-type ActionType = typeof actionTypes
+type ActionType = typeof actionTypes;
type Action =
- | {
- type: ActionType["ADD_TOAST"]
- toast: ToasterToast
- }
- | {
- type: ActionType["UPDATE_TOAST"]
- toast: Partial
- }
- | {
- type: ActionType["DISMISS_TOAST"]
- toastId?: ToasterToast["id"]
- }
- | {
- type: ActionType["REMOVE_TOAST"]
- toastId?: ToasterToast["id"]
- }
+ | {
+ type: ActionType["ADD_TOAST"];
+ toast: ToasterToast;
+ }
+ | {
+ type: ActionType["UPDATE_TOAST"];
+ toast: Partial;
+ }
+ | {
+ type: ActionType["DISMISS_TOAST"];
+ toastId?: ToasterToast["id"];
+ }
+ | {
+ type: ActionType["REMOVE_TOAST"];
+ toastId?: ToasterToast["id"];
+ };
interface State {
- toasts: ToasterToast[]
+ toasts: ToasterToast[];
}
-const toastTimeouts = new Map>()
+const toastTimeouts = new Map>();
const addToRemoveQueue = (toastId: string) => {
- if (toastTimeouts.has(toastId)) {
- return
- }
+ if (toastTimeouts.has(toastId)) {
+ return;
+ }
- const timeout = setTimeout(() => {
- toastTimeouts.delete(toastId)
- dispatch({
- type: "REMOVE_TOAST",
- toastId: toastId,
- })
- }, TOAST_REMOVE_DELAY)
+ const timeout = setTimeout(() => {
+ toastTimeouts.delete(toastId);
+ dispatch({
+ type: "REMOVE_TOAST",
+ toastId: toastId,
+ });
+ }, TOAST_REMOVE_DELAY);
- toastTimeouts.set(toastId, timeout)
-}
+ toastTimeouts.set(toastId, timeout);
+};
export const reducer = (state: State, action: Action): State => {
- switch (action.type) {
- case "ADD_TOAST":
- return {
- ...state,
- toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
- }
+ switch (action.type) {
+ case "ADD_TOAST":
+ return {
+ ...state,
+ toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
+ };
- case "UPDATE_TOAST":
- return {
- ...state,
- toasts: state.toasts.map((t) =>
- t.id === action.toast.id ? { ...t, ...action.toast } : t
- ),
- }
+ case "UPDATE_TOAST":
+ return {
+ ...state,
+ toasts: state.toasts.map((t) => (t.id === action.toast.id ? { ...t, ...action.toast } : t)),
+ };
- case "DISMISS_TOAST": {
- const { toastId } = action
+ case "DISMISS_TOAST": {
+ const { toastId } = action;
- // ! Side effects ! - This could be extracted into a dismissToast() action,
- // but I'll keep it here for simplicity
- if (toastId) {
- addToRemoveQueue(toastId)
- } else {
- state.toasts.forEach((toast) => {
- addToRemoveQueue(toast.id)
- })
- }
+ // ! Side effects ! - This could be extracted into a dismissToast() action,
+ // but I'll keep it here for simplicity
+ if (toastId) {
+ addToRemoveQueue(toastId);
+ } else {
+ state.toasts.forEach((toast) => {
+ addToRemoveQueue(toast.id);
+ });
+ }
- return {
- ...state,
- toasts: state.toasts.map((t) =>
- t.id === toastId || toastId === undefined
- ? {
- ...t,
- open: false,
- }
- : t
- ),
- }
- }
- case "REMOVE_TOAST":
- if (action.toastId === undefined) {
- return {
- ...state,
- toasts: [],
- }
- }
- return {
- ...state,
- toasts: state.toasts.filter((t) => t.id !== action.toastId),
- }
- }
-}
+ return {
+ ...state,
+ toasts: state.toasts.map((t) =>
+ t.id === toastId || toastId === undefined
+ ? {
+ ...t,
+ open: false,
+ }
+ : t
+ ),
+ };
+ }
+ case "REMOVE_TOAST":
+ if (action.toastId === undefined) {
+ return {
+ ...state,
+ toasts: [],
+ };
+ }
+ return {
+ ...state,
+ toasts: state.toasts.filter((t) => t.id !== action.toastId),
+ };
+ }
+};
-const listeners: Array<(state: State) => void> = []
+const listeners: Array<(state: State) => void> = [];
-let memoryState: State = { toasts: [] }
+let memoryState: State = { toasts: [] };
function dispatch(action: Action) {
- memoryState = reducer(memoryState, action)
- listeners.forEach((listener) => {
- listener(memoryState)
- })
+ memoryState = reducer(memoryState, action);
+ listeners.forEach((listener) => {
+ listener(memoryState);
+ });
}
-type Toast = Omit
+type Toast = Omit;
function toast({ ...props }: Toast) {
- const id = genId()
+ const id = genId();
- const update = (props: ToasterToast) =>
- dispatch({
- type: "UPDATE_TOAST",
- toast: { ...props, id },
- })
- const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
+ const update = (props: ToasterToast) =>
+ dispatch({
+ type: "UPDATE_TOAST",
+ toast: { ...props, id },
+ });
+ const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id });
- dispatch({
- type: "ADD_TOAST",
- toast: {
- ...props,
- id,
- open: true,
- onOpenChange: (open) => {
- if (!open) dismiss()
- },
- },
- })
+ dispatch({
+ type: "ADD_TOAST",
+ toast: {
+ ...props,
+ id,
+ open: true,
+ onOpenChange: (open) => {
+ if (!open) dismiss();
+ },
+ },
+ });
- return {
- id: id,
- dismiss,
- update,
- }
+ return {
+ id: id,
+ dismiss,
+ update,
+ };
}
function useToast() {
- const [state, setState] = React.useState(memoryState)
+ const [state, setState] = React.useState(memoryState);
- React.useEffect(() => {
- listeners.push(setState)
- return () => {
- const index = listeners.indexOf(setState)
- if (index > -1) {
- listeners.splice(index, 1)
- }
- }
- }, [state])
+ React.useEffect(() => {
+ listeners.push(setState);
+ return () => {
+ const index = listeners.indexOf(setState);
+ if (index > -1) {
+ listeners.splice(index, 1);
+ }
+ };
+ }, [state]);
- return {
- ...state,
- toast,
- dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
- }
+ return {
+ ...state,
+ toast,
+ dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
+ };
}
-export { useToast, toast }
+export { useToast, toast };
diff --git a/surfsense_browser_extension/tailwind.config.js b/surfsense_browser_extension/tailwind.config.js
index e362d8239..94ec92383 100644
--- a/surfsense_browser_extension/tailwind.config.js
+++ b/surfsense_browser_extension/tailwind.config.js
@@ -1,76 +1,76 @@
-const { fontFamily } = require("tailwindcss/defaultTheme")
+const { fontFamily } = require("tailwindcss/defaultTheme");
/** @type {import('tailwindcss').Config} */
module.exports = {
- darkMode: ["class"],
- content: ["./*.{js,jsx,ts,tsx}","./routes/*.tsx","./routes/**/*.tsx"],
- theme: {
- container: {
- center: true,
- padding: "2rem",
- screens: {
- "2xl": "1400px",
- },
- },
- extend: {
- colors: {
- border: "hsl(var(--border))",
- input: "hsl(var(--input))",
- ring: "hsl(var(--ring))",
- background: "hsl(var(--background))",
- foreground: "hsl(var(--foreground))",
- primary: {
- DEFAULT: "hsl(var(--primary))",
- foreground: "hsl(var(--primary-foreground))",
- },
- secondary: {
- DEFAULT: "hsl(var(--secondary))",
- foreground: "hsl(var(--secondary-foreground))",
- },
- destructive: {
- DEFAULT: "hsl(var(--destructive))",
- foreground: "hsl(var(--destructive-foreground))",
- },
- muted: {
- DEFAULT: "hsl(var(--muted))",
- foreground: "hsl(var(--muted-foreground))",
- },
- accent: {
- DEFAULT: "hsl(var(--accent))",
- foreground: "hsl(var(--accent-foreground))",
- },
- popover: {
- DEFAULT: "hsl(var(--popover))",
- foreground: "hsl(var(--popover-foreground))",
- },
- card: {
- DEFAULT: "hsl(var(--card))",
- foreground: "hsl(var(--card-foreground))",
- },
- },
- borderRadius: {
- lg: `var(--radius)`,
- md: `calc(var(--radius) - 2px)`,
- sm: "calc(var(--radius) - 4px)",
- },
- fontFamily: {
- sans: ["var(--font-sans)", ...fontFamily.sans],
- },
- keyframes: {
- "accordion-down": {
- from: { height: "0" },
- to: { height: "var(--radix-accordion-content-height)" },
- },
- "accordion-up": {
- from: { height: "var(--radix-accordion-content-height)" },
- to: { height: "0" },
- },
- },
- animation: {
- "accordion-down": "accordion-down 0.2s ease-out",
- "accordion-up": "accordion-up 0.2s ease-out",
- },
- },
- },
- plugins: [require("tailwindcss-animate")],
-}
+ darkMode: ["class"],
+ content: ["./*.{js,jsx,ts,tsx}", "./routes/*.tsx", "./routes/**/*.tsx"],
+ theme: {
+ container: {
+ center: true,
+ padding: "2rem",
+ screens: {
+ "2xl": "1400px",
+ },
+ },
+ extend: {
+ colors: {
+ border: "hsl(var(--border))",
+ input: "hsl(var(--input))",
+ ring: "hsl(var(--ring))",
+ background: "hsl(var(--background))",
+ foreground: "hsl(var(--foreground))",
+ primary: {
+ DEFAULT: "hsl(var(--primary))",
+ foreground: "hsl(var(--primary-foreground))",
+ },
+ secondary: {
+ DEFAULT: "hsl(var(--secondary))",
+ foreground: "hsl(var(--secondary-foreground))",
+ },
+ destructive: {
+ DEFAULT: "hsl(var(--destructive))",
+ foreground: "hsl(var(--destructive-foreground))",
+ },
+ muted: {
+ DEFAULT: "hsl(var(--muted))",
+ foreground: "hsl(var(--muted-foreground))",
+ },
+ accent: {
+ DEFAULT: "hsl(var(--accent))",
+ foreground: "hsl(var(--accent-foreground))",
+ },
+ popover: {
+ DEFAULT: "hsl(var(--popover))",
+ foreground: "hsl(var(--popover-foreground))",
+ },
+ card: {
+ DEFAULT: "hsl(var(--card))",
+ foreground: "hsl(var(--card-foreground))",
+ },
+ },
+ borderRadius: {
+ lg: `var(--radius)`,
+ md: `calc(var(--radius) - 2px)`,
+ sm: "calc(var(--radius) - 4px)",
+ },
+ fontFamily: {
+ sans: ["var(--font-sans)", ...fontFamily.sans],
+ },
+ keyframes: {
+ "accordion-down": {
+ from: { height: "0" },
+ to: { height: "var(--radix-accordion-content-height)" },
+ },
+ "accordion-up": {
+ from: { height: "var(--radix-accordion-content-height)" },
+ to: { height: "0" },
+ },
+ },
+ animation: {
+ "accordion-down": "accordion-down 0.2s ease-out",
+ "accordion-up": "accordion-up 0.2s ease-out",
+ },
+ },
+ },
+ plugins: [require("tailwindcss-animate")],
+};
diff --git a/surfsense_browser_extension/tailwind.css b/surfsense_browser_extension/tailwind.css
index a95fb751c..0c41c6ae1 100644
--- a/surfsense_browser_extension/tailwind.css
+++ b/surfsense_browser_extension/tailwind.css
@@ -3,96 +3,97 @@
@tailwind utilities;
@layer base {
- :root {
- --background: 240 10% 3.9%;
- --foreground: 0 0% 98%;
-
- --card: 240 10% 3.9%;
- --card-foreground: 0 0% 98%;
-
- --popover: 240 10% 3.9%;
- --popover-foreground: 0 0% 98%;
-
- --primary: 180 100% 37%;
- --primary-foreground: 0 0% 98%;
-
- --secondary: 240 5.9% 10%;
- --secondary-foreground: 0 0% 98%;
-
- --muted: 240 5.9% 10%;
- --muted-foreground: 240 5% 64.9%;
-
- --accent: 169 97% 37%;
- --accent-foreground: 0 0% 98%;
-
- --destructive: 0 84.2% 60.2%;
- --destructive-foreground: 0 0% 98%;
+ :root {
+ --background: 240 10% 3.9%;
+ --foreground: 0 0% 98%;
- --border: 240 5.9% 24%;
- --input: 240 5.9% 10%;
- --ring: 180 100% 37%;
-
- --radius: 0.5rem;
- }
+ --card: 240 10% 3.9%;
+ --card-foreground: 0 0% 98%;
- .dark {
- --background: 224 71% 4%;
- --foreground: 213 31% 91%;
+ --popover: 240 10% 3.9%;
+ --popover-foreground: 0 0% 98%;
- --muted: 223 47% 11%;
- --muted-foreground: 215.4 16.3% 56.9%;
+ --primary: 180 100% 37%;
+ --primary-foreground: 0 0% 98%;
- --accent: 216 34% 17%;
- --accent-foreground: 210 40% 98%;
+ --secondary: 240 5.9% 10%;
+ --secondary-foreground: 0 0% 98%;
- --popover: 224 71% 4%;
- --popover-foreground: 215 20.2% 65.1%;
+ --muted: 240 5.9% 10%;
+ --muted-foreground: 240 5% 64.9%;
- --border: 216 34% 17%;
- --input: 216 34% 17%;
+ --accent: 169 97% 37%;
+ --accent-foreground: 0 0% 98%;
- --card: 224 71% 4%;
- --card-foreground: 213 31% 91%;
+ --destructive: 0 84.2% 60.2%;
+ --destructive-foreground: 0 0% 98%;
- --primary: 210 40% 98%;
- --primary-foreground: 222.2 47.4% 1.2%;
+ --border: 240 5.9% 24%;
+ --input: 240 5.9% 10%;
+ --ring: 180 100% 37%;
- --secondary: 222.2 47.4% 11.2%;
- --secondary-foreground: 210 40% 98%;
+ --radius: 0.5rem;
+ }
- --destructive: 0 63% 31%;
- --destructive-foreground: 210 40% 98%;
+ .dark {
+ --background: 224 71% 4%;
+ --foreground: 213 31% 91%;
- --ring: 216 34% 17%;
+ --muted: 223 47% 11%;
+ --muted-foreground: 215.4 16.3% 56.9%;
- --radius: 0.5rem;
- }
+ --accent: 216 34% 17%;
+ --accent-foreground: 210 40% 98%;
+
+ --popover: 224 71% 4%;
+ --popover-foreground: 215 20.2% 65.1%;
+
+ --border: 216 34% 17%;
+ --input: 216 34% 17%;
+
+ --card: 224 71% 4%;
+ --card-foreground: 213 31% 91%;
+
+ --primary: 210 40% 98%;
+ --primary-foreground: 222.2 47.4% 1.2%;
+
+ --secondary: 222.2 47.4% 11.2%;
+ --secondary-foreground: 210 40% 98%;
+
+ --destructive: 0 63% 31%;
+ --destructive-foreground: 210 40% 98%;
+
+ --ring: 216 34% 17%;
+
+ --radius: 0.5rem;
+ }
}
body {
- min-width: 380px;
- min-height: 580px;
+ min-width: 380px;
+ min-height: 580px;
}
@layer base {
- * {
- @apply border-border;
- }
- body {
- @apply bg-background text-foreground;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
- Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
- }
+ * {
+ @apply border-border;
+ }
+ body {
+ @apply bg-background text-foreground;
+ font-family:
+ -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
+ "Helvetica Neue", sans-serif;
+ }
- /* Styling for shadcn/ui components */
- .command-dialog {
- @apply dark;
- }
+ /* Styling for shadcn/ui components */
+ .command-dialog {
+ @apply dark;
+ }
}
/* Popup page dimensions */
@media (prefers-color-scheme: dark) {
- body {
- @apply bg-slate-950 text-white;
- }
+ body {
+ @apply bg-slate-950 text-white;
+ }
}
diff --git a/surfsense_browser_extension/tsconfig.json b/surfsense_browser_extension/tsconfig.json
index 88daa5059..3f9c649ae 100644
--- a/surfsense_browser_extension/tsconfig.json
+++ b/surfsense_browser_extension/tsconfig.json
@@ -1,20 +1,12 @@
{
- "extends": "plasmo/templates/tsconfig.base",
- "exclude": [
- "node_modules"
- ],
- "include": [
- ".plasmo/index.d.ts",
- "./**/*.ts",
- "./**/*.tsx"
- ],
- "compilerOptions": {
- "paths": {
- "~*": [
- "./*"
- ],
- "@/*": ["./*"]
- },
- "baseUrl": "."
- }
+ "extends": "plasmo/templates/tsconfig.base.json",
+ "exclude": ["node_modules"],
+ "include": [".plasmo/index.d.ts", "./**/*.ts", "./**/*.tsx"],
+ "compilerOptions": {
+ "paths": {
+ "~*": ["./*"],
+ "@/*": ["./*"]
+ },
+ "baseUrl": "."
+ }
}
diff --git a/surfsense_browser_extension/utils/commons.ts b/surfsense_browser_extension/utils/commons.ts
index 5056594ee..a750d8c44 100644
--- a/surfsense_browser_extension/utils/commons.ts
+++ b/surfsense_browser_extension/utils/commons.ts
@@ -1,144 +1,137 @@
-import { Storage } from "@plasmohq/storage"
-import type { WebHistory } from "./interfaces"
+import { Storage } from "@plasmohq/storage";
+import type { WebHistory } from "./interfaces";
-export const emptyArr: any[] = []
+export const emptyArr: any[] = [];
export const initQueues = async (tabId: number) => {
- const storage = new Storage({ area: "local" })
+ const storage = new Storage({ area: "local" });
- let urlQueueListObj: any = await storage.get("urlQueueList")
- let timeQueueListObj: any = await storage.get("timeQueueList")
+ const urlQueueListObj: any = await storage.get("urlQueueList");
+ const timeQueueListObj: any = await storage.get("timeQueueList");
- if (!urlQueueListObj && !timeQueueListObj) {
- await storage.set("urlQueueList", {
- urlQueueList: [{ tabsessionId: tabId, urlQueue: [] }]
- })
- await storage.set("timeQueueList", {
- timeQueueList: [{ tabsessionId: tabId, timeQueue: [] }]
- })
+ if (!urlQueueListObj && !timeQueueListObj) {
+ await storage.set("urlQueueList", {
+ urlQueueList: [{ tabsessionId: tabId, urlQueue: [] }],
+ });
+ await storage.set("timeQueueList", {
+ timeQueueList: [{ tabsessionId: tabId, timeQueue: [] }],
+ });
- return
- }
+ return;
+ }
- if (urlQueueListObj.urlQueueList && timeQueueListObj.timeQueueList) {
- const isUrlQueueThere = urlQueueListObj.urlQueueList.find(
- (data: WebHistory) => data.tabsessionId === tabId
- )
- const isTimeQueueThere = timeQueueListObj.timeQueueList.find(
- (data: WebHistory) => data.tabsessionId === tabId
- )
+ if (urlQueueListObj.urlQueueList && timeQueueListObj.timeQueueList) {
+ const isUrlQueueThere = urlQueueListObj.urlQueueList.find(
+ (data: WebHistory) => data.tabsessionId === tabId
+ );
+ const isTimeQueueThere = timeQueueListObj.timeQueueList.find(
+ (data: WebHistory) => data.tabsessionId === tabId
+ );
- if (!isUrlQueueThere) {
- urlQueueListObj.urlQueueList.push({ tabsessionId: tabId, urlQueue: [] })
+ if (!isUrlQueueThere) {
+ urlQueueListObj.urlQueueList.push({ tabsessionId: tabId, urlQueue: [] });
- await storage.set("urlQueueList", {
- urlQueueList: urlQueueListObj.urlQueueList
- })
- }
+ await storage.set("urlQueueList", {
+ urlQueueList: urlQueueListObj.urlQueueList,
+ });
+ }
- if (!isTimeQueueThere) {
- timeQueueListObj.timeQueueList.push({
- tabsessionId: tabId,
- timeQueue: []
- })
+ if (!isTimeQueueThere) {
+ timeQueueListObj.timeQueueList.push({
+ tabsessionId: tabId,
+ timeQueue: [],
+ });
- await storage.set("timeQueueList", {
- timeQueueList: timeQueueListObj.timeQueueList
- })
- }
+ await storage.set("timeQueueList", {
+ timeQueueList: timeQueueListObj.timeQueueList,
+ });
+ }
- return
- }
-}
+ return;
+ }
+};
export function getRenderedHtml() {
- return {
- url: window.location.href,
- entryTime: Date.now(),
- title: document.title,
- renderedHtml: document.documentElement.outerHTML
- }
+ return {
+ url: window.location.href,
+ entryTime: Date.now(),
+ title: document.title,
+ renderedHtml: document.documentElement.outerHTML,
+ };
}
export const initWebHistory = async (tabId: number) => {
-const storage = new Storage({ area: "local" })
- const result: any = await storage.get("webhistory")
+ const storage = new Storage({ area: "local" });
+ const result: any = await storage.get("webhistory");
- if (result === undefined) {
- await storage.set("webhistory", { webhistory: emptyArr })
- return
- }
+ if (result === undefined) {
+ await storage.set("webhistory", { webhistory: emptyArr });
+ return;
+ }
- const ifIdExists = result.webhistory.find(
- (data: WebHistory) => data.tabsessionId === tabId
- )
+ const ifIdExists = result.webhistory.find((data: WebHistory) => data.tabsessionId === tabId);
- if (ifIdExists === undefined) {
- let webHistory = result.webhistory
- const initData = {
- tabsessionId: tabId,
- tabHistory: emptyArr
- }
+ if (ifIdExists === undefined) {
+ const webHistory = result.webhistory;
+ const initData = {
+ tabsessionId: tabId,
+ tabHistory: emptyArr,
+ };
- webHistory.push(initData)
+ webHistory.push(initData);
- try {
- await storage.set("webhistory", { webhistory: webHistory })
- return
- } catch (error) {
- console.log(error)
- }
- } else {
- return
- }
-}
+ try {
+ await storage.set("webhistory", { webhistory: webHistory });
+ return;
+ } catch (error) {
+ console.log(error);
+ }
+ } else {
+ return;
+ }
+};
export function toIsoString(date: Date) {
- var tzo = -date.getTimezoneOffset(),
- dif = tzo >= 0 ? "+" : "-",
- pad = function (num: number) {
- return (num < 10 ? "0" : "") + num
- }
+ var tzo = -date.getTimezoneOffset(),
+ dif = tzo >= 0 ? "+" : "-",
+ pad = (num: number) => (num < 10 ? "0" : "") + num;
- return (
- date.getFullYear() +
- "-" +
- pad(date.getMonth() + 1) +
- "-" +
- pad(date.getDate()) +
- "T" +
- pad(date.getHours()) +
- ":" +
- pad(date.getMinutes()) +
- ":" +
- pad(date.getSeconds()) +
- dif +
- pad(Math.floor(Math.abs(tzo) / 60)) +
- ":" +
- pad(Math.abs(tzo) % 60)
- )
+ return (
+ date.getFullYear() +
+ "-" +
+ pad(date.getMonth() + 1) +
+ "-" +
+ pad(date.getDate()) +
+ "T" +
+ pad(date.getHours()) +
+ ":" +
+ pad(date.getMinutes()) +
+ ":" +
+ pad(date.getSeconds()) +
+ dif +
+ pad(Math.floor(Math.abs(tzo) / 60)) +
+ ":" +
+ pad(Math.abs(tzo) % 60)
+ );
}
-export const webhistoryToLangChainDocument = (
- tabId: number,
- tabHistory: any[]
-) => {
- let toSaveFinally = []
- for (let j = 0; j < tabHistory.length; j++) {
- const mtadata = {
- BrowsingSessionId: `${tabId}`,
- VisitedWebPageURL: `${tabHistory[j].url}`,
- VisitedWebPageTitle: `${tabHistory[j].title}`,
- VisitedWebPageDateWithTimeInISOString: `${toIsoString(new Date(tabHistory[j].entryTime))}`,
- VisitedWebPageReffererURL: `${tabHistory[j].reffererUrl}`,
- VisitedWebPageVisitDurationInMilliseconds: tabHistory[j].duration
- }
+export const webhistoryToLangChainDocument = (tabId: number, tabHistory: any[]) => {
+ const toSaveFinally = [];
+ for (let j = 0; j < tabHistory.length; j++) {
+ const mtadata = {
+ BrowsingSessionId: `${tabId}`,
+ VisitedWebPageURL: `${tabHistory[j].url}`,
+ VisitedWebPageTitle: `${tabHistory[j].title}`,
+ VisitedWebPageDateWithTimeInISOString: `${toIsoString(new Date(tabHistory[j].entryTime))}`,
+ VisitedWebPageReffererURL: `${tabHistory[j].reffererUrl}`,
+ VisitedWebPageVisitDurationInMilliseconds: tabHistory[j].duration,
+ };
- toSaveFinally.push({
- metadata: mtadata,
- pageContent: tabHistory[j].pageContentMarkdown
- })
- }
+ toSaveFinally.push({
+ metadata: mtadata,
+ pageContent: tabHistory[j].pageContentMarkdown,
+ });
+ }
- return toSaveFinally
-}
+ return toSaveFinally;
+};
diff --git a/surfsense_browser_extension/utils/interfaces.ts b/surfsense_browser_extension/utils/interfaces.ts
index ba75e8d4c..641cdbb03 100644
--- a/surfsense_browser_extension/utils/interfaces.ts
+++ b/surfsense_browser_extension/utils/interfaces.ts
@@ -1,4 +1,4 @@
export interface WebHistory {
- tabsessionId: number;
- tabHistory: any[];
-}
\ No newline at end of file
+ tabsessionId: number;
+ tabHistory: any[];
+}
diff --git a/surfsense_web/.vscode/launch.json b/surfsense_web/.vscode/launch.json
index 0f7a24de3..13a8a9b00 100644
--- a/surfsense_web/.vscode/launch.json
+++ b/surfsense_web/.vscode/launch.json
@@ -1,31 +1,31 @@
{
- "version": "0.2.0",
- "configurations": [
- {
- "name": "Next.js: debug client-side",
- "type": "chrome",
- "request": "launch",
- "url": "http://localhost:3000",
- "webRoot": "${workspaceFolder}"
- },
- {
- "name": "Next.js: debug server-side",
- "type": "node-terminal",
- "request": "launch",
- "command": "pnpm run debug:server",
- "skipFiles": ["/**"]
- },
- {
- "name": "Next.js: debug full stack",
- "type": "node-terminal",
- "request": "launch",
- "command": "pnpm run debug",
- "serverReadyAction": {
- "pattern": "- Local:.+(https?://.+)",
- "uriFormat": "%s",
- "action": "debugWithChrome"
- },
- "skipFiles": ["/**"]
- }
- ]
-}
\ No newline at end of file
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Next.js: debug client-side",
+ "type": "chrome",
+ "request": "launch",
+ "url": "http://localhost:3000",
+ "webRoot": "${workspaceFolder}"
+ },
+ {
+ "name": "Next.js: debug server-side",
+ "type": "node-terminal",
+ "request": "launch",
+ "command": "pnpm run debug:server",
+ "skipFiles": ["/**"]
+ },
+ {
+ "name": "Next.js: debug full stack",
+ "type": "node-terminal",
+ "request": "launch",
+ "command": "pnpm run debug",
+ "serverReadyAction": {
+ "pattern": "- Local:.+(https?://.+)",
+ "uriFormat": "%s",
+ "action": "debugWithChrome"
+ },
+ "skipFiles": ["/**"]
+ }
+ ]
+}
diff --git a/surfsense_web/app/api/search/route.ts b/surfsense_web/app/api/search/route.ts
index 01401b7f5..e8aa2e34b 100644
--- a/surfsense_web/app/api/search/route.ts
+++ b/surfsense_web/app/api/search/route.ts
@@ -1,4 +1,4 @@
-import { source } from '@/lib/source';
-import { createFromSource } from 'fumadocs-core/search/server';
-
-export const { GET } = createFromSource(source);
\ No newline at end of file
+import { createFromSource } from "fumadocs-core/search/server";
+import { source } from "@/lib/source";
+
+export const { GET } = createFromSource(source);
diff --git a/surfsense_web/app/auth/callback/page.tsx b/surfsense_web/app/auth/callback/page.tsx
index d4ec41442..da868c316 100644
--- a/surfsense_web/app/auth/callback/page.tsx
+++ b/surfsense_web/app/auth/callback/page.tsx
@@ -1,19 +1,23 @@
-import { Suspense } from 'react';
-import TokenHandler from '@/components/TokenHandler';
+import { Suspense } from "react";
+import TokenHandler from "@/components/TokenHandler";
export default function AuthCallbackPage() {
- return (
-
-
Authentication Callback
-
-
- }>
-
-
-
- );
-}
\ No newline at end of file
+ return (
+
+
Authentication Callback
+
+
+
+ }
+ >
+
+
+
+ );
+}
diff --git a/surfsense_web/app/dashboard/[search_space_id]/chats/chats-client.tsx b/surfsense_web/app/dashboard/[search_space_id]/chats/chats-client.tsx
index 45f6d4610..dbad14eba 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/chats/chats-client.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/chats/chats-client.tsx
@@ -1,874 +1,911 @@
-'use client';
+"use client";
-import { useState, useEffect } from 'react';
-import { motion, AnimatePresence } from 'framer-motion';
-import { useSearchParams } from 'next/navigation';
-import { MessageCircleMore, Search, Calendar, Tag, Trash2, ExternalLink, MoreHorizontal, Radio, CheckCircle, Circle, Podcast } from 'lucide-react';
-import { format } from 'date-fns';
-
-// UI Components
-import { Input } from '@/components/ui/input';
-import { Button } from '@/components/ui/button';
-import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
-import { Badge } from '@/components/ui/badge';
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuTrigger,
- DropdownMenuSeparator
-} from '@/components/ui/dropdown-menu';
+import { format } from "date-fns";
+import { AnimatePresence, motion, type Variants } from "framer-motion";
import {
- Pagination,
- PaginationContent,
- PaginationItem,
- PaginationLink,
- PaginationNext,
- PaginationPrevious,
-} from '@/components/ui/pagination';
+ Calendar,
+ CheckCircle,
+ Circle,
+ ExternalLink,
+ MessageCircleMore,
+ MoreHorizontal,
+ Podcast,
+ Search,
+ Tag,
+ Trash2,
+} from "lucide-react";
+import { useRouter, useSearchParams } from "next/navigation";
+import { useEffect, useState } from "react";
+import { toast } from "sonner";
+import { Badge } from "@/components/ui/badge";
+import { Button } from "@/components/ui/button";
import {
- Dialog,
- DialogContent,
- DialogDescription,
- DialogFooter,
- DialogHeader,
- DialogTitle,
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card";
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
} from "@/components/ui/dialog";
import {
- Select,
- SelectContent,
- SelectGroup,
- SelectItem,
- SelectTrigger,
- SelectValue,
-} from "@/components/ui/select";
-import { Checkbox } from "@/components/ui/checkbox";
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu";
+// UI Components
+import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
-import { toast } from "sonner";
+import {
+ Pagination,
+ PaginationContent,
+ PaginationItem,
+ PaginationLink,
+ PaginationNext,
+ PaginationPrevious,
+} from "@/components/ui/pagination";
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select";
interface Chat {
- created_at: string;
- id: number;
- type: string;
- title: string;
- messages: ChatMessage[];
- search_space_id: number;
+ created_at: string;
+ id: number;
+ type: string;
+ title: string;
+ messages: ChatMessage[];
+ search_space_id: number;
}
interface ChatMessage {
- id: string;
- createdAt: string;
- role: string;
- content: string;
- parts?: any;
+ id: string;
+ createdAt: string;
+ role: string;
+ content: string;
+ parts?: any;
}
interface ChatsPageClientProps {
- searchSpaceId: string;
+ searchSpaceId: string;
}
-const pageVariants = {
- initial: { opacity: 0 },
- enter: { opacity: 1, transition: { duration: 0.3, ease: 'easeInOut' } },
- exit: { opacity: 0, transition: { duration: 0.3, ease: 'easeInOut' } }
+const pageVariants: Variants = {
+ initial: { opacity: 0 },
+ enter: { opacity: 1, transition: { duration: 0.3, ease: "easeInOut" } },
+ exit: { opacity: 0, transition: { duration: 0.3, ease: "easeInOut" } },
};
-const chatCardVariants = {
- initial: { y: 20, opacity: 0 },
- animate: { y: 0, opacity: 1 },
- exit: { y: -20, opacity: 0 }
+const chatCardVariants: Variants = {
+ initial: { y: 20, opacity: 0 },
+ animate: { y: 0, opacity: 1 },
+ exit: { y: -20, opacity: 0 },
};
const MotionCard = motion(Card);
export default function ChatsPageClient({ searchSpaceId }: ChatsPageClientProps) {
- const [chats, setChats] = useState([]);
- const [filteredChats, setFilteredChats] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
- const [error, setError] = useState(null);
- const [searchQuery, setSearchQuery] = useState('');
- const [currentPage, setCurrentPage] = useState(1);
- const [totalPages, setTotalPages] = useState(1);
- const [selectedType, setSelectedType] = useState('all');
- const [sortOrder, setSortOrder] = useState('newest');
- const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
- const [chatToDelete, setChatToDelete] = useState<{ id: number, title: string } | null>(null);
- const [isDeleting, setIsDeleting] = useState(false);
-
- // New state for podcast generation
- const [selectedChats, setSelectedChats] = useState([]);
- const [selectionMode, setSelectionMode] = useState(false);
- const [podcastDialogOpen, setPodcastDialogOpen] = useState(false);
- const [podcastTitle, setPodcastTitle] = useState("");
- const [isGeneratingPodcast, setIsGeneratingPodcast] = useState(false);
-
- // New state for individual podcast generation
- const [currentChatIndex, setCurrentChatIndex] = useState(0);
- const [podcastTitles, setPodcastTitles] = useState<{[key: number]: string}>({});
- const [processingChat, setProcessingChat] = useState(null);
-
- const chatsPerPage = 9;
- const searchParams = useSearchParams();
-
- // Get initial page from URL params if it exists
- useEffect(() => {
- const pageParam = searchParams.get('page');
- if (pageParam) {
- const pageNumber = parseInt(pageParam, 10);
- if (!isNaN(pageNumber) && pageNumber > 0) {
- setCurrentPage(pageNumber);
- }
- }
- }, [searchParams]);
+ const router = useRouter();
+ const [chats, setChats] = useState([]);
+ const [filteredChats, setFilteredChats] = useState([]);
+ const [isLoading, setIsLoading] = useState(true);
+ const [error, setError] = useState(null);
+ const [searchQuery, setSearchQuery] = useState("");
+ const [currentPage, setCurrentPage] = useState(1);
+ const [totalPages, setTotalPages] = useState(1);
+ const [selectedType, setSelectedType] = useState("all");
+ const [sortOrder, setSortOrder] = useState("newest");
+ const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
+ const [chatToDelete, setChatToDelete] = useState<{ id: number; title: string } | null>(null);
+ const [isDeleting, setIsDeleting] = useState(false);
- // Fetch chats from API
- useEffect(() => {
- const fetchChats = async () => {
- try {
- setIsLoading(true);
-
- // Get token from localStorage
- const token = localStorage.getItem('surfsense_bearer_token');
-
- if (!token) {
- setError('Authentication token not found. Please log in again.');
- setIsLoading(false);
- return;
- }
+ // New state for podcast generation
+ const [selectedChats, setSelectedChats] = useState([]);
+ const [selectionMode, setSelectionMode] = useState(false);
+ const [podcastDialogOpen, setPodcastDialogOpen] = useState(false);
+ const [podcastTitle, setPodcastTitle] = useState("");
+ const [isGeneratingPodcast, setIsGeneratingPodcast] = useState(false);
- // Fetch all chats for this search space
- const response = await fetch(
- `${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats/?search_space_id=${searchSpaceId}`,
- {
- headers: {
- 'Authorization': `Bearer ${token}`,
- 'Content-Type': 'application/json',
- },
- cache: 'no-store',
- }
- );
+ // New state for individual podcast generation
+ const [currentChatIndex, setCurrentChatIndex] = useState(0);
+ const [podcastTitles, setPodcastTitles] = useState<{ [key: number]: string }>({});
+ const [processingChat, setProcessingChat] = useState(null);
- if (!response.ok) {
- const errorData = await response.json().catch(() => null);
- throw new Error(`Failed to fetch chats: ${response.status} ${errorData?.error || ''}`);
- }
+ const chatsPerPage = 9;
+ const searchParams = useSearchParams();
- const data: Chat[] = await response.json();
- setChats(data);
- setFilteredChats(data);
- setError(null);
- } catch (error) {
- console.error('Error fetching chats:', error);
- setError(error instanceof Error ? error.message : 'Unknown error occurred');
- setChats([]);
- setFilteredChats([]);
- } finally {
- setIsLoading(false);
- }
- };
+ // Get initial page from URL params if it exists
+ useEffect(() => {
+ const pageParam = searchParams.get("page");
+ if (pageParam) {
+ const pageNumber = parseInt(pageParam, 10);
+ if (!Number.isNaN(pageNumber) && pageNumber > 0) {
+ setCurrentPage(pageNumber);
+ }
+ }
+ }, [searchParams]);
- fetchChats();
- }, [searchSpaceId]);
+ // Fetch chats from API
+ useEffect(() => {
+ const fetchChats = async () => {
+ try {
+ setIsLoading(true);
- // Filter and sort chats based on search query, type, and sort order
- useEffect(() => {
- let result = [...chats];
-
- // Filter by search term
- if (searchQuery) {
- const query = searchQuery.toLowerCase();
- result = result.filter(chat =>
- chat.title.toLowerCase().includes(query)
- );
- }
-
- // Filter by type
- if (selectedType !== 'all') {
- result = result.filter(chat => chat.type === selectedType);
- }
-
- // Sort chats
- result.sort((a, b) => {
- const dateA = new Date(a.created_at).getTime();
- const dateB = new Date(b.created_at).getTime();
-
- return sortOrder === 'newest' ? dateB - dateA : dateA - dateB;
- });
-
- setFilteredChats(result);
- setTotalPages(Math.max(1, Math.ceil(result.length / chatsPerPage)));
-
- // Reset to first page when filters change
- if (currentPage !== 1 && (searchQuery || selectedType !== 'all' || sortOrder !== 'newest')) {
- setCurrentPage(1);
- }
- }, [chats, searchQuery, selectedType, sortOrder, currentPage]);
+ // Get token from localStorage
+ const token = localStorage.getItem("surfsense_bearer_token");
- // Function to handle chat deletion
- const handleDeleteChat = async () => {
- if (!chatToDelete) return;
-
- setIsDeleting(true);
- try {
- const token = localStorage.getItem('surfsense_bearer_token');
- if (!token) {
- setIsDeleting(false);
- return;
- }
-
- const response = await fetch(`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats/${chatToDelete.id}`, {
- method: 'DELETE',
- headers: {
- 'Authorization': `Bearer ${token}`,
- 'Content-Type': 'application/json',
- }
- });
-
- if (!response.ok) {
- throw new Error(`Failed to delete chat: ${response.statusText}`);
- }
-
- // Close dialog and refresh chats
- setDeleteDialogOpen(false);
- setChatToDelete(null);
-
- // Update local state by removing the deleted chat
- setChats(prevChats => prevChats.filter(chat => chat.id !== chatToDelete.id));
- } catch (error) {
- console.error('Error deleting chat:', error);
- } finally {
- setIsDeleting(false);
- }
- };
+ if (!token) {
+ setError("Authentication token not found. Please log in again.");
+ setIsLoading(false);
+ return;
+ }
- // Calculate pagination
- const indexOfLastChat = currentPage * chatsPerPage;
- const indexOfFirstChat = indexOfLastChat - chatsPerPage;
- const currentChats = filteredChats.slice(indexOfFirstChat, indexOfLastChat);
-
- // Get unique chat types for filter dropdown
- const chatTypes = ['all', ...Array.from(new Set(chats.map(chat => chat.type)))];
+ // Fetch all chats for this search space
+ const response = await fetch(
+ `${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats/?search_space_id=${searchSpaceId}`,
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ "Content-Type": "application/json",
+ },
+ cache: "no-store",
+ }
+ );
- // Generate individual podcasts from selected chats
- const handleGeneratePodcast = async () => {
- if (selectedChats.length === 0) {
- toast.error("Please select at least one chat");
- return;
- }
-
- const currentChatId = selectedChats[currentChatIndex];
- const currentTitle = podcastTitles[currentChatId] || podcastTitle;
-
- if (!currentTitle.trim()) {
- toast.error("Please enter a podcast title");
- return;
- }
-
- setIsGeneratingPodcast(true);
- try {
- const token = localStorage.getItem('surfsense_bearer_token');
- if (!token) {
- toast.error("Authentication error. Please log in again.");
- setIsGeneratingPodcast(false);
- return;
- }
-
- // Create payload for single chat
- const payload = {
- type: "CHAT",
- ids: [currentChatId], // Single chat ID
- search_space_id: parseInt(searchSpaceId),
- podcast_title: currentTitle
- };
-
- const response = await fetch(`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/podcasts/generate/`, {
- method: 'POST',
- headers: {
- 'Authorization': `Bearer ${token}`,
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(payload)
- });
-
- if (!response.ok) {
- const errorData = await response.json().catch(() => ({}));
- throw new Error(errorData.detail || "Failed to generate podcast");
- }
-
- const data = await response.json();
- toast.success(`Podcast "${currentTitle}" generation started!`);
-
- // Move to the next chat or finish
- if (currentChatIndex < selectedChats.length - 1) {
- // Set up for next chat
- setCurrentChatIndex(currentChatIndex + 1);
-
- // Find the next chat from the chats array
- const nextChatId = selectedChats[currentChatIndex + 1];
- const nextChat = chats.find(chat => chat.id === nextChatId) || null;
- setProcessingChat(nextChat);
-
- // Default title for the next chat
- if (!podcastTitles[nextChatId]) {
- setPodcastTitle(nextChat?.title || `Podcast from Chat ${nextChatId}`);
- } else {
- setPodcastTitle(podcastTitles[nextChatId]);
- }
-
- setIsGeneratingPodcast(false);
- } else {
- // All done
- finishPodcastGeneration();
- }
- } catch (error) {
- console.error('Error generating podcast:', error);
- toast.error(error instanceof Error ? error.message : 'Failed to generate podcast');
- setIsGeneratingPodcast(false);
- }
- };
-
- // Helper to finish the podcast generation process
- const finishPodcastGeneration = () => {
- toast.success("All podcasts are being generated! Check the logs tab to see their status.");
- setPodcastDialogOpen(false);
- setSelectedChats([]);
- setSelectionMode(false);
- setCurrentChatIndex(0);
- setPodcastTitles({});
- setProcessingChat(null);
- setPodcastTitle("");
- setIsGeneratingPodcast(false);
- };
+ if (!response.ok) {
+ const errorData = await response.json().catch(() => null);
+ throw new Error(`Failed to fetch chats: ${response.status} ${errorData?.error || ""}`);
+ }
- // Start podcast generation flow
- const startPodcastGeneration = () => {
- if (selectedChats.length === 0) {
- toast.error("Please select at least one chat");
- return;
- }
-
- // Reset the state for podcast generation
- setCurrentChatIndex(0);
- setPodcastTitles({});
-
- // Set up for the first chat
- const firstChatId = selectedChats[0];
- const firstChat = chats.find(chat => chat.id === firstChatId) || null;
- setProcessingChat(firstChat);
-
- // Set default title for the first chat
- setPodcastTitle(firstChat?.title || `Podcast from Chat ${firstChatId}`);
- setPodcastDialogOpen(true);
- };
-
- // Update the title for the current chat
- const updateCurrentChatTitle = (title: string) => {
- const currentChatId = selectedChats[currentChatIndex];
- setPodcastTitle(title);
- setPodcastTitles(prev => ({
- ...prev,
- [currentChatId]: title
- }));
- };
-
- // Skip generating a podcast for the current chat
- const skipCurrentChat = () => {
- if (currentChatIndex < selectedChats.length - 1) {
- // Move to the next chat
- setCurrentChatIndex(currentChatIndex + 1);
-
- // Find the next chat
- const nextChatId = selectedChats[currentChatIndex + 1];
- const nextChat = chats.find(chat => chat.id === nextChatId) || null;
- setProcessingChat(nextChat);
-
- // Set default title for the next chat
- if (!podcastTitles[nextChatId]) {
- setPodcastTitle(nextChat?.title || `Podcast from Chat ${nextChatId}`);
- } else {
- setPodcastTitle(podcastTitles[nextChatId]);
- }
- } else {
- // All done (all skipped)
- finishPodcastGeneration();
- }
- };
+ const data: Chat[] = await response.json();
+ setChats(data);
+ setFilteredChats(data);
+ setError(null);
+ } catch (error) {
+ console.error("Error fetching chats:", error);
+ setError(error instanceof Error ? error.message : "Unknown error occurred");
+ setChats([]);
+ setFilteredChats([]);
+ } finally {
+ setIsLoading(false);
+ }
+ };
- // Toggle chat selection
- const toggleChatSelection = (chatId: number) => {
- setSelectedChats(prev =>
- prev.includes(chatId)
- ? prev.filter(id => id !== chatId)
- : [...prev, chatId]
- );
- };
+ fetchChats();
+ }, [searchSpaceId]);
- // Select all visible chats
- const selectAllVisibleChats = () => {
- const visibleChatIds = currentChats.map(chat => chat.id);
- setSelectedChats(prev => {
- const allSelected = visibleChatIds.every(id => prev.includes(id));
- return allSelected
- ? prev.filter(id => !visibleChatIds.includes(id)) // Deselect all visible if all are selected
- : [...new Set([...prev, ...visibleChatIds])]; // Add all visible, ensuring no duplicates
- });
- };
+ // Filter and sort chats based on search query, type, and sort order
+ useEffect(() => {
+ let result = [...chats];
- // Cancel selection mode
- const cancelSelectionMode = () => {
- setSelectionMode(false);
- setSelectedChats([]);
- };
+ // Filter by search term
+ if (searchQuery) {
+ const query = searchQuery.toLowerCase();
+ result = result.filter((chat) => chat.title.toLowerCase().includes(query));
+ }
- return (
-
-
-
-
All Chats
-
View, search, and manage all your chats.
-
-
- {/* Filter and Search Bar */}
-
-
-
-
- setSearchQuery(e.target.value)}
- />
-
-
-
-
-
-
- {selectionMode ? (
- <>
-
-
-
- >
- ) : (
- <>
-
-
- >
- )}
-
-
-
- {/* Status Messages */}
- {isLoading && (
-
- )}
-
- {error && !isLoading && (
-
-
Error loading chats
-
{error}
-
- )}
-
- {!isLoading && !error && filteredChats.length === 0 && (
-
-
-
No chats found
-
- {searchQuery || selectedType !== 'all'
- ? 'Try adjusting your search filters'
- : 'Start a new chat to get started'}
-
-
- )}
-
- {/* Chat Grid */}
- {!isLoading && !error && filteredChats.length > 0 && (
-
-
- {currentChats.map((chat, index) => (
-
{
- if (!selectionMode) return;
- // Ignore clicks coming from interactive elements
- if ((e.target as HTMLElement).closest('button, a, [data-stop-selection]')) return;
- toggleChatSelection(chat.id);
- }}
- >
-
-
-
- {selectionMode && (
-
- {selectedChats.includes(chat.id)
- ?
- : }
-
- )}
-
- {chat.title || `Chat ${chat.id}`}
-
-
-
- {format(new Date(chat.created_at), 'MMM d, yyyy')}
-
-
-
-
- {!selectionMode && (
-
-
-
-
-
- window.location.href = `/dashboard/${chat.search_space_id}/researcher/${chat.id}`}>
-
- View Chat
-
- {
- setSelectedChats([chat.id]);
- setPodcastTitle(chat.title || `Chat ${chat.id}`);
- setPodcastDialogOpen(true);
- }}
- >
-
- Generate Podcast
-
-
- {
- e.stopPropagation();
- setChatToDelete({ id: chat.id, title: chat.title || `Chat ${chat.id}` });
- setDeleteDialogOpen(true);
- }}
- >
-
- Delete Chat
-
-
-
- )}
-
-
-
-
- {chat.messages && chat.messages.length > 0
- ? typeof chat.messages[0] === 'string'
- ? chat.messages[0]
- : chat.messages[0]?.content || 'No message content'
- : 'No messages in this chat.'}
-
-
-
-
-
- {chat.messages?.length || 0} messages
-
-
-
- {chat.type || 'Unknown'}
-
-
-
- ))}
-
-
- )}
-
- {/* Pagination */}
- {!isLoading && !error && totalPages > 1 && (
-
-
-
- {
- e.preventDefault();
- if (currentPage > 1) setCurrentPage(currentPage - 1);
- }}
- className={currentPage <= 1 ? 'pointer-events-none opacity-50' : ''}
- />
-
-
- {Array.from({ length: totalPages }).map((_, index) => {
- const pageNumber = index + 1;
- const isVisible =
- pageNumber === 1 ||
- pageNumber === totalPages ||
- (pageNumber >= currentPage - 1 && pageNumber <= currentPage + 1);
-
- if (!isVisible) {
- // Show ellipsis at appropriate positions
- if (pageNumber === 2 || pageNumber === totalPages - 1) {
- return (
-
- ...
-
- );
- }
- return null;
- }
-
- return (
-
- {
- e.preventDefault();
- setCurrentPage(pageNumber);
- }}
- isActive={pageNumber === currentPage}
- >
- {pageNumber}
-
-
- );
- })}
-
-
- {
- e.preventDefault();
- if (currentPage < totalPages) setCurrentPage(currentPage + 1);
- }}
- className={currentPage >= totalPages ? 'pointer-events-none opacity-50' : ''}
- />
-
-
-
- )}
-
-
- {/* Delete Confirmation Dialog */}
-
-
- {/* Podcast Generation Dialog */}
-
-
- );
-}
\ No newline at end of file
+ // Filter by type
+ if (selectedType !== "all") {
+ result = result.filter((chat) => chat.type === selectedType);
+ }
+
+ // Sort chats
+ result.sort((a, b) => {
+ const dateA = new Date(a.created_at).getTime();
+ const dateB = new Date(b.created_at).getTime();
+
+ return sortOrder === "newest" ? dateB - dateA : dateA - dateB;
+ });
+
+ setFilteredChats(result);
+ setTotalPages(Math.max(1, Math.ceil(result.length / chatsPerPage)));
+
+ // Reset to first page when filters change
+ if (currentPage !== 1 && (searchQuery || selectedType !== "all" || sortOrder !== "newest")) {
+ setCurrentPage(1);
+ }
+ }, [chats, searchQuery, selectedType, sortOrder, currentPage]);
+
+ // Function to handle chat deletion
+ const handleDeleteChat = async () => {
+ if (!chatToDelete) return;
+
+ setIsDeleting(true);
+ try {
+ const token = localStorage.getItem("surfsense_bearer_token");
+ if (!token) {
+ setIsDeleting(false);
+ return;
+ }
+
+ const response = await fetch(
+ `${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats/${chatToDelete.id}`,
+ {
+ method: "DELETE",
+ headers: {
+ Authorization: `Bearer ${token}`,
+ "Content-Type": "application/json",
+ },
+ }
+ );
+
+ if (!response.ok) {
+ throw new Error(`Failed to delete chat: ${response.statusText}`);
+ }
+
+ // Close dialog and refresh chats
+ setDeleteDialogOpen(false);
+ setChatToDelete(null);
+
+ // Update local state by removing the deleted chat
+ setChats((prevChats) => prevChats.filter((chat) => chat.id !== chatToDelete.id));
+ } catch (error) {
+ console.error("Error deleting chat:", error);
+ } finally {
+ setIsDeleting(false);
+ }
+ };
+
+ // Calculate pagination
+ const indexOfLastChat = currentPage * chatsPerPage;
+ const indexOfFirstChat = indexOfLastChat - chatsPerPage;
+ const currentChats = filteredChats.slice(indexOfFirstChat, indexOfLastChat);
+
+ // Get unique chat types for filter dropdown
+ const chatTypes = ["all", ...Array.from(new Set(chats.map((chat) => chat.type)))];
+
+ // Generate individual podcasts from selected chats
+ const handleGeneratePodcast = async () => {
+ if (selectedChats.length === 0) {
+ toast.error("Please select at least one chat");
+ return;
+ }
+
+ const currentChatId = selectedChats[currentChatIndex];
+ const currentTitle = podcastTitles[currentChatId] || podcastTitle;
+
+ if (!currentTitle.trim()) {
+ toast.error("Please enter a podcast title");
+ return;
+ }
+
+ setIsGeneratingPodcast(true);
+ try {
+ const token = localStorage.getItem("surfsense_bearer_token");
+ if (!token) {
+ toast.error("Authentication error. Please log in again.");
+ setIsGeneratingPodcast(false);
+ return;
+ }
+
+ // Create payload for single chat
+ const payload = {
+ type: "CHAT",
+ ids: [currentChatId], // Single chat ID
+ search_space_id: parseInt(searchSpaceId),
+ podcast_title: currentTitle,
+ };
+
+ const response = await fetch(
+ `${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/podcasts/generate/`,
+ {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${token}`,
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(payload),
+ }
+ );
+
+ if (!response.ok) {
+ const errorData = await response.json().catch(() => ({}));
+ throw new Error(errorData.detail || "Failed to generate podcast");
+ }
+
+ const _data = await response.json();
+ toast.success(`Podcast "${currentTitle}" generation started!`);
+
+ // Move to the next chat or finish
+ if (currentChatIndex < selectedChats.length - 1) {
+ // Set up for next chat
+ setCurrentChatIndex(currentChatIndex + 1);
+
+ // Find the next chat from the chats array
+ const nextChatId = selectedChats[currentChatIndex + 1];
+ const nextChat = chats.find((chat) => chat.id === nextChatId) || null;
+ setProcessingChat(nextChat);
+
+ // Default title for the next chat
+ if (!podcastTitles[nextChatId]) {
+ setPodcastTitle(nextChat?.title || `Podcast from Chat ${nextChatId}`);
+ } else {
+ setPodcastTitle(podcastTitles[nextChatId]);
+ }
+
+ setIsGeneratingPodcast(false);
+ } else {
+ // All done
+ finishPodcastGeneration();
+ }
+ } catch (error) {
+ console.error("Error generating podcast:", error);
+ toast.error(error instanceof Error ? error.message : "Failed to generate podcast");
+ setIsGeneratingPodcast(false);
+ }
+ };
+
+ // Helper to finish the podcast generation process
+ const finishPodcastGeneration = () => {
+ toast.success("All podcasts are being generated! Check the logs tab to see their status.");
+ setPodcastDialogOpen(false);
+ setSelectedChats([]);
+ setSelectionMode(false);
+ setCurrentChatIndex(0);
+ setPodcastTitles({});
+ setProcessingChat(null);
+ setPodcastTitle("");
+ setIsGeneratingPodcast(false);
+ };
+
+ // Start podcast generation flow
+ const startPodcastGeneration = () => {
+ if (selectedChats.length === 0) {
+ toast.error("Please select at least one chat");
+ return;
+ }
+
+ // Reset the state for podcast generation
+ setCurrentChatIndex(0);
+ setPodcastTitles({});
+
+ // Set up for the first chat
+ const firstChatId = selectedChats[0];
+ const firstChat = chats.find((chat) => chat.id === firstChatId) || null;
+ setProcessingChat(firstChat);
+
+ // Set default title for the first chat
+ setPodcastTitle(firstChat?.title || `Podcast from Chat ${firstChatId}`);
+ setPodcastDialogOpen(true);
+ };
+
+ // Update the title for the current chat
+ const updateCurrentChatTitle = (title: string) => {
+ const currentChatId = selectedChats[currentChatIndex];
+ setPodcastTitle(title);
+ setPodcastTitles((prev) => ({
+ ...prev,
+ [currentChatId]: title,
+ }));
+ };
+
+ // Skip generating a podcast for the current chat
+ const skipCurrentChat = () => {
+ if (currentChatIndex < selectedChats.length - 1) {
+ // Move to the next chat
+ setCurrentChatIndex(currentChatIndex + 1);
+
+ // Find the next chat
+ const nextChatId = selectedChats[currentChatIndex + 1];
+ const nextChat = chats.find((chat) => chat.id === nextChatId) || null;
+ setProcessingChat(nextChat);
+
+ // Set default title for the next chat
+ if (!podcastTitles[nextChatId]) {
+ setPodcastTitle(nextChat?.title || `Podcast from Chat ${nextChatId}`);
+ } else {
+ setPodcastTitle(podcastTitles[nextChatId]);
+ }
+ } else {
+ // All done (all skipped)
+ finishPodcastGeneration();
+ }
+ };
+
+ // Toggle chat selection
+ const toggleChatSelection = (chatId: number) => {
+ setSelectedChats((prev) =>
+ prev.includes(chatId) ? prev.filter((id) => id !== chatId) : [...prev, chatId]
+ );
+ };
+
+ // Select all visible chats
+ const selectAllVisibleChats = () => {
+ const visibleChatIds = currentChats.map((chat) => chat.id);
+ setSelectedChats((prev) => {
+ const allSelected = visibleChatIds.every((id) => prev.includes(id));
+ return allSelected
+ ? prev.filter((id) => !visibleChatIds.includes(id)) // Deselect all visible if all are selected
+ : [...new Set([...prev, ...visibleChatIds])]; // Add all visible, ensuring no duplicates
+ });
+ };
+
+ // Cancel selection mode
+ const cancelSelectionMode = () => {
+ setSelectionMode(false);
+ setSelectedChats([]);
+ };
+
+ return (
+
+
+
+
All Chats
+
View, search, and manage all your chats.
+
+
+ {/* Filter and Search Bar */}
+
+
+
+
+ setSearchQuery(e.target.value)}
+ />
+
+
+
+
+
+
+ {selectionMode ? (
+ <>
+
+
+
+ >
+ ) : (
+ <>
+
+
+ >
+ )}
+
+
+
+ {/* Status Messages */}
+ {isLoading && (
+
+ )}
+
+ {error && !isLoading && (
+
+
Error loading chats
+
{error}
+
+ )}
+
+ {!isLoading && !error && filteredChats.length === 0 && (
+
+
+
No chats found
+
+ {searchQuery || selectedType !== "all"
+ ? "Try adjusting your search filters"
+ : "Start a new chat to get started"}
+
+
+ )}
+
+ {/* Chat Grid */}
+ {!isLoading && !error && filteredChats.length > 0 && (
+
+
+ {currentChats.map((chat, index) => (
+
{
+ if (!selectionMode) return;
+ // Ignore clicks coming from interactive elements
+ if ((e.target as HTMLElement).closest("button, a, [data-stop-selection]"))
+ return;
+ toggleChatSelection(chat.id);
+ }}
+ >
+
+
+
+ {selectionMode && (
+
+ {selectedChats.includes(chat.id) ? (
+
+ ) : (
+
+ )}
+
+ )}
+
+
+ {chat.title || `Chat ${chat.id}`}
+
+
+
+
+ {format(new Date(chat.created_at), "MMM d, yyyy")}
+
+
+
+
+ {!selectionMode && (
+
+
+
+
+
+
+ router.push(
+ `/dashboard/${chat.search_space_id}/researcher/${chat.id}`
+ )
+ }
+ >
+
+ View Chat
+
+ {
+ setSelectedChats([chat.id]);
+ setPodcastTitle(chat.title || `Chat ${chat.id}`);
+ setPodcastDialogOpen(true);
+ }}
+ >
+
+ Generate Podcast
+
+
+ {
+ e.stopPropagation();
+ setChatToDelete({
+ id: chat.id,
+ title: chat.title || `Chat ${chat.id}`,
+ });
+ setDeleteDialogOpen(true);
+ }}
+ >
+
+ Delete Chat
+
+
+
+ )}
+
+
+
+
+ {chat.messages && chat.messages.length > 0
+ ? typeof chat.messages[0] === "string"
+ ? chat.messages[0]
+ : chat.messages[0]?.content || "No message content"
+ : "No messages in this chat."}
+
+
+
+
+
+ {chat.messages?.length || 0} messages
+
+
+
+ {chat.type || "Unknown"}
+
+
+
+ ))}
+
+
+ )}
+
+ {/* Pagination */}
+ {!isLoading && !error && totalPages > 1 && (
+
+
+
+ {
+ e.preventDefault();
+ if (currentPage > 1) setCurrentPage(currentPage - 1);
+ }}
+ className={currentPage <= 1 ? "pointer-events-none opacity-50" : ""}
+ />
+
+
+ {Array.from({ length: totalPages }).map((_, index) => {
+ const pageNumber = index + 1;
+ const isVisible =
+ pageNumber === 1 ||
+ pageNumber === totalPages ||
+ (pageNumber >= currentPage - 1 && pageNumber <= currentPage + 1);
+
+ if (!isVisible) {
+ // Show ellipsis at appropriate positions
+ if (pageNumber === 2 || pageNumber === totalPages - 1) {
+ return (
+
+ ...
+
+ );
+ }
+ return null;
+ }
+
+ return (
+
+ {
+ e.preventDefault();
+ setCurrentPage(pageNumber);
+ }}
+ isActive={pageNumber === currentPage}
+ >
+ {pageNumber}
+
+
+ );
+ })}
+
+
+ {
+ e.preventDefault();
+ if (currentPage < totalPages) setCurrentPage(currentPage + 1);
+ }}
+ className={currentPage >= totalPages ? "pointer-events-none opacity-50" : ""}
+ />
+
+
+
+ )}
+
+
+ {/* Delete Confirmation Dialog */}
+
+
+ {/* Podcast Generation Dialog */}
+
+
+ );
+}
diff --git a/surfsense_web/app/dashboard/[search_space_id]/chats/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/chats/page.tsx
index f382d633c..9a2bb0f48 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/chats/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/chats/page.tsx
@@ -1,21 +1,25 @@
-import { Suspense } from 'react';
-import ChatsPageClient from './chats-client';
+import { Suspense } from "react";
+import ChatsPageClient from "./chats-client";
interface PageProps {
- params: {
- search_space_id: string;
- };
+ params: {
+ search_space_id: string;
+ };
}
export default async function ChatsPage({ params }: PageProps) {
- // Get search space ID from the route parameter
- const { search_space_id: searchSpaceId } = await Promise.resolve(params);
-
- return (
-
-
- }>
-
-
- );
-}
\ No newline at end of file
+ // Get search space ID from the route parameter
+ const { search_space_id: searchSpaceId } = await Promise.resolve(params);
+
+ return (
+
+
+
+ }
+ >
+
+
+ );
+}
diff --git a/surfsense_web/app/dashboard/[search_space_id]/client-layout.tsx b/surfsense_web/app/dashboard/[search_space_id]/client-layout.tsx
index c9a768461..97c7894c0 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/client-layout.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/client-layout.tsx
@@ -1,44 +1,40 @@
-'use client';
+"use client";
-import {
- SidebarInset,
- SidebarProvider,
- SidebarTrigger,
-} from "@/components/ui/sidebar"
-import { ThemeTogglerComponent } from "@/components/theme/theme-toggle"
-import React from 'react'
-import { Separator } from "@/components/ui/separator"
-import { AppSidebarProvider } from "@/components/sidebar/AppSidebarProvider"
+import type React from "react";
+import { AppSidebarProvider } from "@/components/sidebar/AppSidebarProvider";
+import { ThemeTogglerComponent } from "@/components/theme/theme-toggle";
+import { Separator } from "@/components/ui/separator";
+import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
export function DashboardClientLayout({
- children,
- searchSpaceId,
- navSecondary,
- navMain
+ children,
+ searchSpaceId,
+ navSecondary,
+ navMain,
}: {
- children: React.ReactNode;
- searchSpaceId: string;
- navSecondary: any[];
- navMain: any[];
+ children: React.ReactNode;
+ searchSpaceId: string;
+ navSecondary: any[];
+ navMain: any[];
}) {
- return (
-
- {/* Use AppSidebarProvider which fetches user, search space, and recent chats */}
-
-
-
- {children}
-
-
- )
-}
\ No newline at end of file
+ return (
+
+ {/* Use AppSidebarProvider which fetches user, search space, and recent chats */}
+
+
+
+ {children}
+
+
+ );
+}
diff --git a/surfsense_web/app/dashboard/[search_space_id]/connectors/(manage)/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/connectors/(manage)/page.tsx
index d01d54ad5..8afe07b3f 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/connectors/(manage)/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/connectors/(manage)/page.tsx
@@ -1,34 +1,12 @@
"use client";
-import { useState, useEffect } from "react";
-import { useRouter, useParams } from "next/navigation";
+import { format } from "date-fns";
import { motion } from "framer-motion";
+import { Calendar as CalendarIcon, Edit, Plus, RefreshCw, Trash2 } from "lucide-react";
+import { useParams, useRouter } from "next/navigation";
+import { useEffect, useState } from "react";
import { toast } from "sonner";
-import {
- Edit,
- Plus,
- Trash2,
- RefreshCw,
- Calendar as CalendarIcon,
-} from "lucide-react";
-
-import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
-import { Button } from "@/components/ui/button";
-import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
-import {
- Table,
- TableBody,
- TableCell,
- TableHead,
- TableHeader,
- TableRow,
-} from "@/components/ui/table";
+import { getConnectorIcon } from "@/components/chat";
import {
AlertDialog,
AlertDialogAction,
@@ -40,12 +18,9 @@ import {
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
-import {
- Tooltip,
- TooltipContent,
- TooltipProvider,
- TooltipTrigger,
-} from "@/components/ui/tooltip";
+import { Button } from "@/components/ui/button";
+import { Calendar } from "@/components/ui/calendar";
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import {
Dialog,
DialogContent,
@@ -53,14 +28,20 @@ import {
DialogFooter,
DialogHeader,
DialogTitle,
- DialogTrigger,
} from "@/components/ui/dialog";
-import { Calendar } from "@/components/ui/calendar";
-import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Label } from "@/components/ui/label";
-import { getConnectorIcon } from "@/components/chat";
+import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table";
+import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
+import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
import { cn } from "@/lib/utils";
-import { format } from "date-fns";
// Helper function to format date with time
const formatDateTime = (dateString: string | null): string => {
@@ -83,14 +64,12 @@ export default function ConnectorsPage() {
const { connectors, isLoading, error, deleteConnector, indexConnector } =
useSearchSourceConnectors();
- const [connectorToDelete, setConnectorToDelete] = useState(
- null,
- );
- const [indexingConnectorId, setIndexingConnectorId] = useState(
- null,
- );
+ const [connectorToDelete, setConnectorToDelete] = useState(null);
+ const [indexingConnectorId, setIndexingConnectorId] = useState(null);
const [datePickerOpen, setDatePickerOpen] = useState(false);
- const [selectedConnectorForIndexing, setSelectedConnectorForIndexing] = useState(null);
+ const [selectedConnectorForIndexing, setSelectedConnectorForIndexing] = useState(
+ null
+ );
const [startDate, setStartDate] = useState(undefined);
const [endDate, setEndDate] = useState(undefined);
@@ -127,21 +106,17 @@ export default function ConnectorsPage() {
if (selectedConnectorForIndexing === null) return;
setDatePickerOpen(false);
-
+
try {
setIndexingConnectorId(selectedConnectorForIndexing);
const startDateStr = startDate ? format(startDate, "yyyy-MM-dd") : undefined;
const endDateStr = endDate ? format(endDate, "yyyy-MM-dd") : undefined;
-
+
await indexConnector(selectedConnectorForIndexing, searchSpaceId, startDateStr, endDateStr);
toast.success("Connector content indexing started");
} catch (error) {
console.error("Error indexing connector content:", error);
- toast.error(
- error instanceof Error
- ? error.message
- : "Failed to index connector content",
- );
+ toast.error(error instanceof Error ? error.message : "Failed to index connector content");
} finally {
setIndexingConnectorId(null);
setSelectedConnectorForIndexing(null);
@@ -158,11 +133,7 @@ export default function ConnectorsPage() {
toast.success("Connector content indexing started");
} catch (error) {
console.error("Error indexing connector content:", error);
- toast.error(
- error instanceof Error
- ? error.message
- : "Failed to index connector content",
- );
+ toast.error(error instanceof Error ? error.message : "Failed to index connector content");
} finally {
setIndexingConnectorId(null);
}
@@ -182,11 +153,7 @@ export default function ConnectorsPage() {
Manage your connected services and data sources.
-