diff --git a/.cursor/rules/app.mdc b/.cursor/rules/app.mdc deleted file mode 100644 index 34d12dda1..000000000 --- a/.cursor/rules/app.mdc +++ /dev/null @@ -1,27 +0,0 @@ ---- -description: -globs: -alwaysApply: true ---- -You are writing a UI modernized, AI-driven, user-friendly RSS reader. - -This project is a monorepo for web front-end electron and React Native. - -Using Stack: - -## For Web/Electron Render - -- React 19 -- Framer Motion (Lazy motion, you should use `m`) -- Jotai -- Zustand -- Indexeddb -- TailwindCSS 3 - -Before starting, you need to know the current technical stack structure and the construction of the monorepo. Read tailwindcss to understand the design style. - -## For React Native - -- React 19 -- Expo -- Expo Module Core (Some Native modules included) \ No newline at end of file diff --git a/.cursor/rules/base.mdc b/.cursor/rules/base.mdc deleted file mode 100644 index b52c94c51..000000000 --- a/.cursor/rules/base.mdc +++ /dev/null @@ -1,112 +0,0 @@ ---- -description: -globs: -alwaysApply: true ---- -# Role - -Act as a highly experienced software developer and coding assistant. You are proficient in all major programming languages and frameworks. Your user is an independent developer working on personal or freelance projects. Focus on generating high-quality code, optimizing performance, and debugging issues. - ---- - -# Objective - -Efficiently assist the user in writing and improving code, proactively solving technical issues without needing repeated prompting. Focus on the following core tasks: - -- Writing code -- Optimizing code -- Debugging and issue resolution - -Ensure all solutions are clearly explained and easy to understand. - ---- - -## Phase 1: Initial Assessment - -1. When the user requests a task, check for existing documentation (e.g., `README.md`) to understand the project. -2. If no documentation is found, generate a `README.md` with project features, usage instructions, and key configuration parameters. -3. Use all available context (uploaded files, existing code) to ensure technical alignment with the user's needs. - ---- - -## Phase 2: Implementation - -### 1. Clarify Requirements -- Confirm user requirements clearly. Ask questions when uncertain. -- Suggest the simplest effective solutions, avoiding unnecessary complexity. - -### 2. Writing Code -- Review existing code and outline implementation steps. -- Choose the appropriate language and framework. Follow best practices (e.g., SOLID principles). -- Write clean, readable, and commented code. -- Optimize for clarity, maintainability, and performance. -- Include unit tests when applicable. -- Follow standard language-specific style guides (e.g., PEP 8 for Python, Airbnb for JavaScript). - -### 3. Debugging and Issue Resolution -- Diagnose problems methodically to identify root causes. -- Clearly explain the issue and proposed fix. -- Keep the user informed of progress and adapt quickly to changes. - ---- - -## Phase 3: Completion and Summary - -1. Summarize key changes and improvements. -2. Highlight potential risks, edge cases, or performance concerns. -3. Update documentation (e.g., `README.md`) accordingly. - ---- - -# Best Practices - -### Sequential Thinking (Step-Based Problem Solving Framework) - -Use the [Sequential Thinking](https://github.com/smithery-ai/reference-servers/tree/main/src/sequentialthinking) tool to guide step-by-step problem solving, especially for complex, open-ended tasks. - -- Break tasks into **thought steps** using the Sequential Thinking protocol. -- For each step, follow this structure: - 1.**Define the current goal or assumption** (e.g., "Evaluate authentication options", "Refactor state handling"). - 2.**Use a suitable MCP tool** based on context (e.g., `search_docs`, `code_generator`, `error_explainer`). - 3.**Record the result/output** clearly. - 4.**Determine the next thought step** and continue. - -- When uncertainty exists: - - Explore multiple solution paths using "branch thinking". - - Compare trade-offs or competing strategies. - - Allow rollback or edits to previous thought steps. - -- Use metadata such as: - -`thought`: current thought text - -`thoughtNumber`: current step index - -`totalThoughts`: number of expected steps - -- Encourage interactive feedback and continuous iteration throughout the sequence. - -### Context7 (Up-to-Date Documentation Integration) - -Utilize [Context7](https://github.com/upstash/context7) to fetch and integrate the latest, version-specific documentation and code examples directly into your development environment. - --**Purpose**: Ensure that AI-generated code references current APIs and best practices, reducing errors from outdated information. - --**Usage**: - 1.**Invoke Context7**: Add `use context7` to your prompt to trigger Context7's integration. - 2.**Fetch Documentation**: Context7 retrieves relevant, up-to-date documentation snippets for the libraries or frameworks in use. - 3.**Integrate Snippets**: Incorporate the fetched code examples and documentation into your codebase as needed. - --**Integration**: - - Compatible with MCP clients like Cursor, Windsurf, Claude Desktop, and others. - - Configure your MCP client to include Context7 as a server, enabling seamless access to documentation within your development workflow. - --**Benefits**: - - Reduces reliance on outdated training data. - - Minimizes code hallucinations and deprecated API usage. - - Enhances code accuracy and relevance. - ---- - -# Communication - -- Ask questions when clarification is needed. -- Remain concise, technical, and helpful. -- Include inline code comments where necessary. \ No newline at end of file diff --git a/.cursor/rules/color.mdc b/.cursor/rules/color.mdc deleted file mode 100644 index 09ab34a51..000000000 --- a/.cursor/rules/color.mdc +++ /dev/null @@ -1,191 +0,0 @@ ---- -description: -globs: apps/desktop/**/*,packages/internal/components/**/* -alwaysApply: false ---- -# UIKit Colors for Tailwind CSS - -You should use @https://github.com/Innei/apple-uikit-colors/blob/main/packages/uikit-colors/macos.ts TailwindCSS atom classname. - -## System Colors -red -orange -yellow -green -mint -teal -cyan -blue -indigo -purple -pink -brown -gray - -## Fill Colors -fill -fill-secondary -fill-tertiary -fill-quaternary -fill-quinary -fill-vibrant -fill-vibrant-secondary -fill-vibrant-tertiary -fill-vibrant-quaternary -fill-vibrant-quinary - -## Text Colors -text -text-secondary -text-tertiary -text-quaternary -text-quinary -text-vibrant -text-vibrant-secondary -text-vibrant-tertiary -text-vibrant-quaternary -text-vibrant-quinary - -## Material Colors -material-ultra-thick -material-thick -material-medium -material-thin -material-ultra-thin -material-opaque - -## Control Colors -control-enabled -control-disabled - -## Interface Colors -menu -popover -titlebar -sidebar -selection-focused -selection-focused-fill -selection-unfocused -selection-unfocused-fill -header-view -tooltip -under-window-background - - -## Applied Colors -All above tailwind atom will match this colors. - -``` -@media (prefers-color-scheme: light) { - html { - --color-red: 255 69 58; - --color-orange: 255 149 0; - --color-yellow: 255 204 0; - --color-green: 40 205 65; - --color-mint: 0 199 190; - --color-teal: 89 173 196; - --color-cyan: 85 190 240; - --color-blue: 0 122 255; - --color-indigo: 88 86 214; - --color-purple: 175 82 222; - --color-pink: 255 45 85; - --color-brown: 162 132 94; - --color-gray: 142 142 147; - --color-fill: 0 0 0 / 0.1; - --color-fillSecondary: 0 0 0 / 0.08; - --color-fillTertiary: 0 0 0 / 0.05; - --color-fillQuaternary: 0 0 0 / 0.03; - --color-fillQuinary: 0 0 0 / 0.02; - --color-fillVibrant: 217 217 217; - --color-fillVibrantSecondary: 230 230 230; - --color-fillVibrantTertiary: 242 242 242; - --color-fillVibrantQuaternary: 247 247 247; - --color-fillVibrantQuinary: 251 251 251; - --color-text: 0 0 0 / 0.85; - --color-textSecondary: 0 0 0 / 0.5; - --color-textTertiary: 0 0 0 / 0.25; - --color-textQuaternary: 0 0 0 / 0.1; - --color-textQuinary: 0 0 0 / 0.05; - --color-textVibrant: 76 76 76; - --color-textVibrantSecondary: 128 128 128; - --color-textVibrantTertiary: 191 191 191; - --color-textVibrantQuaternary: 230 230 230; - --color-textVibrantQuinary: 242 242 242; - --color-materialUltraThick: 246 246 246 / 0.84; - --color-materialThick: 246 246 246 / 0.72; - --color-materialMedium: 246 246 246 / 0.6; - --color-materialThin: 246 246 246 / 0.48; - --color-materialUltraThin: 246 246 246 / 0.36; - --color-materialOpaque: 246 246 246; - --color-controlEnabled: 251 251 251; - --color-controlDisabled: 243 243 243; - --color-menu: 40 40 40 / 0.58; - --color-popover: 0 0 0 / 0.28; - --color-titlebar: 234 234 234 / 0.8; - --color-sidebar: 234 234 234 / 0.84; - --color-selectionFocused: 10 130 255 / 0.75; - --color-selectionFocusedFill: 10 130 255; - --color-selectionUnfocused: 0 0 0 / 0.1; - --color-selectionUnfocusedFill: 246 246 246 / 0.84; - --color-headerView: 255 255 255 / 0.8; - --color-tooltip: 246 246 246 / 0.6; - --color-underWindowBackground: 246 246 246 / 0.84; - } -} -@media (prefers-color-scheme: dark) { - html { - --color-red: 255 69 58; - --color-orange: 255 159 10; - --color-yellow: 255 214 10; - --color-green: 50 215 75; - --color-mint: 106 196 220; - --color-teal: 106 196 220; - --color-cyan: 90 200 245; - --color-blue: 10 132 255; - --color-indigo: 94 92 230; - --color-purple: 191 90 242; - --color-pink: 255 55 95; - --color-brown: 172 142 104; - --color-gray: 152 152 157; - --color-fill: 255 255 255 / 0.1; - --color-fillSecondary: 255 255 255 / 0.08; - --color-fillTertiary: 255 255 255 / 0.05; - --color-fillQuaternary: 255 255 255 / 0.03; - --color-fillQuinary: 255 255 255 / 0.02; - --color-fillVibrant: 36 36 36; - --color-fillVibrantSecondary: 20 20 20; - --color-fillVibrantTertiary: 13 13 13; - --color-fillVibrantQuaternary: 9 9 9; - --color-fillVibrantQuinary: 7 7 7; - --color-text: 255 255 255 / 0.85; - --color-textSecondary: 255 255 255 / 0.5; - --color-textTertiary: 255 255 255 / 0.25; - --color-textQuaternary: 255 255 255 / 0.1; - --color-textQuinary: 255 255 255 / 0.05; - --color-textVibrant: 229 229 229; - --color-textVibrantSecondary: 124 124 124; - --color-textVibrantTertiary: 65 65 65; - --color-textVibrantQuaternary: 35 35 35; - --color-textVibrantQuinary: 17 17 17; - --color-materialUltraThick: 40 40 40 / 0.84; - --color-materialThick: 40 40 40 / 0.72; - --color-materialMedium: 40 40 40 / 0.6; - --color-materialThin: 40 40 40 / 0.48; - --color-materialUltraThin: 40 40 40 / 0.36; - --color-materialOpaque: 40 40 40; - --color-controlEnabled: 255 255 255 / 0.2; - --color-controlDisabled: 255 255 255 / 0.1; - --color-menu: 246 246 246 / 0.72; - --color-popover: 246 246 246 / 0.6; - --color-titlebar: 60 60 60 / 0.8; - --color-sidebar: 0 0 0 / 0.45; - --color-selectionFocused: 10 130 255 / 0.75; - --color-selectionFocusedFill: 10 130 255; - --color-selectionUnfocused: 255 255 255 / 0.1; - --color-selectionUnfocusedFill: 40 40 40 / 0.65; - --color-headerView: 30 30 30 / 0.8; - --color-tooltip: 0 0 0 / 0.35; - --color-underWindowBackground: 0 0 0 / 0.45; - } -} -``` \ No newline at end of file diff --git a/.cursor/rules/header-button-design.mdc b/.cursor/rules/header-button-design.mdc deleted file mode 100644 index c0ae5dce1..000000000 --- a/.cursor/rules/header-button-design.mdc +++ /dev/null @@ -1,135 +0,0 @@ ---- -description: -globs: -alwaysApply: false ---- -# Header Button Design System - -When creating header buttons for media previews, overlays, or modal interfaces, follow this modern glass morphism design pattern: - -## Design Principles - -### 1. Glass Morphism Style -- Use semi-transparent backgrounds: `bg-black/20` or `bg-white/10` -- Apply backdrop blur: `backdrop-blur-md` -- Add subtle borders: `border border-white/10` for depth -- Include shadow layers: `shadow-lg shadow-black/25` - -### 2. Perfect 1:1 Circular Design -- Always use `size-10` (40px × 40px) for consistent sizing -- Apply `rounded-full` for perfect circular shape -- Ensure proper centering with `flex items-center justify-center` - -### 3. Layered Depth Effects -```tsx -{/* Glass effect overlay */} -
- -{/* Icon container */} -
{children}
- -{/* Subtle inner shadow for depth */} -
-``` - -### 4. Interactive Animation -- Use Framer Motion `m.button` for smooth animations -- Scale on hover: `whileHover={{ scale: 1.1 }}` -- Scale on tap: `whileTap={{ scale: 0.95 }}` -- Spring transitions: `stiffness: 400, damping: 30` - -### 5. Opacity and Visibility -- Start hidden: `opacity-0` -- Show on group hover: `group-hover/left:opacity-100` -- Use `transition-all duration-300 ease-out` for smooth reveals - -## Implementation Pattern - -```tsx -const HeaderButton: FC<{ - description?: string - onClick: () => void - className?: string - children: React.ReactNode -}> = ({ description, onClick, className, children }) => { - return ( - - - { - e.stopPropagation() - onClick() - }} - className={cn( - // Base styles with modern glass morphism - perfect 1:1 circle - "pointer-events-auto relative flex size-10 items-center justify-center rounded-full", - "bg-black/20 text-white backdrop-blur-md", - // Border and shadow for depth - "border border-white/10 shadow-lg shadow-black/25", - // Opacity and transition - "opacity-0 transition-all duration-300 ease-out group-hover/left:opacity-100", - // Text size - "text-lg", - className, - )} - initial={{ scale: 1 }} - whileHover={{ - scale: 1.1, - backgroundColor: "rgba(255, 255, 255, 0.15)", - borderColor: "rgba(255, 255, 255, 0.2)", - }} - whileTap={{ scale: 0.95 }} - transition={{ - type: "spring", - stiffness: 400, - damping: 30, - }} - > - {/* Glass effect overlay */} -
- - {/* Icon container */} -
{children}
- - {/* Subtle inner shadow for depth */} -
- - - {description && ( - - {description} - - )} - - ) -} -``` - -## Special Variants - -### Close Button (Danger State) -```tsx -className="!bg-red-600/30 !border-red-500/20 !opacity-100 hover:!bg-red-600/50" -``` - -### Navigation Buttons (Carousel Controls) -- Use smaller sizes: `size-8` for mobile, `lg:size-10` for desktop -- Position absolutely with proper spacing: `left-2 lg:left-4` -- Maintain same glass morphism principles - -## Usage Guidelines - -1. **Always use with tooltips** for accessibility -2. **Include stopPropagation** on click handlers to prevent modal dismissal -3. **Make description optional** for navigation buttons that don't need tooltips -4. **Use consistent icon sizing**: `text-lg` for standard, `lg:text-xl` for larger variants -5. **Apply proper z-index**: `z-[100]` for overlay buttons -6. **Group hover patterns**: Use `group-hover/left:opacity-100` for contextual visibility - -## Icons -- Always use icons from `@/icons` directory (project standard) -- Common patterns: `i-mgc-close-cute-re`, `i-mgc-external-link-cute-re`, `i-mgc-download-2-cute-re` -- Navigation: `i-mingcute-left-line`, `i-mingcute-right-line` - -This design system ensures consistent, modern, and accessible header buttons across all media preview and overlay interfaces. diff --git a/.cursor/rules/i18n.mdc b/.cursor/rules/i18n.mdc deleted file mode 100644 index 74fec07a1..000000000 --- a/.cursor/rules/i18n.mdc +++ /dev/null @@ -1,17 +0,0 @@ ---- -description: -globs: locales/**/*.json -alwaysApply: false ---- - -i18n Coding Standards. - -1. Read and follow https://www.i18next.com/translation-function/formatting - -2. Use flat keys. Use `.` to separate. Do not use object form nesting. - -3. For languages sensitive to singular and plural, distinguish between them using the `_one` and `_other` forms. - -4. In the build stage, flattened dot-separated keys (such as 'exif.custom.rendered.custom') will be automatically converted to nested object objects, which may cause conflicts. For example, 'exif.custom.rendered.custom' may conflict with 'exif.custom.rendered'. Please avoid using such dot-separated flat keys. - -5. @locales is located at the root directory and needs to handle all existing languages at the same time. diff --git a/.cursor/rules/rn.mdc b/.cursor/rules/rn.mdc deleted file mode 100644 index 6f54ca323..000000000 --- a/.cursor/rules/rn.mdc +++ /dev/null @@ -1,12 +0,0 @@ ---- -description: -globs: apps/mobile/**/* -alwaysApply: false ---- -1. This is an app written in React native. - -2. You need to use @/apps/mobile/icons for icons, do not use other icon libraries. - -3. You need to use NativewindCSS to write styles, not external StyleSheet.create. - -4. You need to use https://github.com/Innei/apple-uikit-colors/tree/main/packages/react-native-uikit-colors for color design. \ No newline at end of file diff --git a/.cursor/rules/web-component.mdc b/.cursor/rules/web-component.mdc deleted file mode 100644 index 4e5e53d40..000000000 --- a/.cursor/rules/web-component.mdc +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: -globs: apps/desktop/layer/renderer/src/**/* -alwaysApply: false ---- -You need to find the available UI components in the project. - -For web applications (apps/dekstop) - -Components are located at `packages/internal/components` and `apps/desktop/layer/renderer/src/components/ui` - -For rn applications (apps/mobile) - -Components are located at `apps/mobile/src/components` \ No newline at end of file diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml index 7940d142c..2bd681eed 100644 --- a/.github/workflows/build-android.yml +++ b/.github/workflows/build-android.yml @@ -68,7 +68,7 @@ jobs: - name: 📤 Upload apk Artifact if: github.event.inputs.profile != 'production' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: app-android path: ${{ github.workspace }}/build.apk @@ -76,7 +76,7 @@ jobs: - name: 📤 Upload aab Artifact if: github.event.inputs.profile == 'production' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: aab-android path: ${{ github.workspace }}/build.aab diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 8d3886900..2ec5c5139 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -183,7 +183,7 @@ jobs: run: pnpm build:render - name: Upload file (macos-arm64-dmg) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: runner.os == 'macOS' with: name: macos-arm64-dmg @@ -193,7 +193,7 @@ jobs: retention-days: 90 - name: Upload file (macos-x64-dmg) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: runner.os == 'macOS' with: name: macos-x64-dmg @@ -203,7 +203,7 @@ jobs: retention-days: 90 - name: Upload file (macos-mas-pkg) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: runner.os == 'macOS' with: name: macos-mas-pkg @@ -212,7 +212,7 @@ jobs: retention-days: 90 - name: Upload file (windows-x64-exe unsigned) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 id: upload-unsigned-windows-x64-exe if: runner.os == 'windows' with: @@ -222,7 +222,7 @@ jobs: apps/desktop/out/make/**/latest.yml retention-days: 90 - - uses: signpath/github-action-submit-signing-request@v1.3 + - uses: signpath/github-action-submit-signing-request@v2.0 continue-on-error: true if: runner.os == 'windows' && env.RELEASE == 'true' with: @@ -239,7 +239,7 @@ jobs: run: npx tsx apps/desktop/scripts/update-windows-yml.ts - name: Upload file (windows-x64-exe signed) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: runner.os == 'windows' && env.RELEASE == 'true' with: name: windows-x64-exe @@ -250,7 +250,7 @@ jobs: overwrite: true - name: Upload file (windows-x64-appx) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: runner.os == 'windows' with: name: windows-x64-appx @@ -259,7 +259,7 @@ jobs: retention-days: 90 - name: Upload file (linux-x64-appimage) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: runner.os == 'linux' with: name: linux-x64-appimage @@ -271,7 +271,7 @@ jobs: - name: Generate artifact attestation if: env.RELEASE == 'true' continue-on-error: true - uses: actions/attest-build-provenance@v2 + uses: actions/attest-build-provenance@v3 with: subject-path: | apps/desktop/out/make/**/Folo-*.dmg diff --git a/.github/workflows/build-ios-development.yml b/.github/workflows/build-ios-development.yml index 565762f26..65990d6a8 100644 --- a/.github/workflows/build-ios-development.yml +++ b/.github/workflows/build-ios-development.yml @@ -60,7 +60,7 @@ jobs: # Optional: Upload artifact - name: 📤 Upload IPA - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: app-ios-development-device path: apps/mobile/build.ipa @@ -109,7 +109,7 @@ jobs: SENTRY_AUTH_TOKEN: ${{ secrets.RN_SENTRY_AUTH_TOKEN }} # Optional: Upload artifact - name: 📤 Upload IPA - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: app-ios-development-device path: apps/mobile/build.ipa @@ -153,7 +153,7 @@ jobs: SENTRY_AUTH_TOKEN: ${{ secrets.RN_SENTRY_AUTH_TOKEN }} # Optional: Upload artifact - name: 📤 Upload IPA - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: app-ios-development-simulator path: apps/mobile/build-simulator.ipa diff --git a/.github/workflows/build-ios.yml b/.github/workflows/build-ios.yml index 7f4d70367..764f78906 100644 --- a/.github/workflows/build-ios.yml +++ b/.github/workflows/build-ios.yml @@ -67,7 +67,7 @@ jobs: # Optional: Upload artifact - name: 📤 Upload IPA - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: app-ios path: apps/mobile/build.ipa @@ -121,7 +121,7 @@ jobs: SENTRY_AUTH_TOKEN: ${{ secrets.RN_SENTRY_AUTH_TOKEN }} # Optional: Upload artifact - name: 📤 Upload IPA - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: app-ios path: apps/mobile/build.ipa diff --git a/apps/desktop/changelog/1.0.0.md b/apps/desktop/changelog/1.0.0.md new file mode 100644 index 000000000..70b91bfe0 --- /dev/null +++ b/apps/desktop/changelog/1.0.0.md @@ -0,0 +1,19 @@ +# What's new in v1.0.0 + +## Shiny new things + +- 🌟 **Folo is now the AI Reader** — a smarter way to follow everything. + +## Improvements + +- Added support for multilingual `params` in YouTube video previews (#4610) +- Redirects now go to your configured first view instead of always defaulting to All (a82b0e9) + +## No longer broken + +- Fixed the hover indicator style on the audio player progress bar (#4600) +- Fixed video autoplay in media previews (#4531) + +## Thanks + +Special thanks to volunteer contributors @yeeway0609 @kovsu @unixzii for their valuable contributions diff --git a/apps/desktop/layer/renderer/package.json b/apps/desktop/layer/renderer/package.json index 41b709f94..a9ebb5338 100644 --- a/apps/desktop/layer/renderer/package.json +++ b/apps/desktop/layer/renderer/package.json @@ -13,6 +13,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@byjohann/toon": "0.4.0", "@dnd-kit/core": "6.3.1", "@dnd-kit/sortable": "10.0.0", "@electron-toolkit/preload": "3.0.2", @@ -29,6 +30,7 @@ "@lexical/markdown": "0.33.1", "@lexical/react": "0.33.1", "@lottiefiles/dotlottie-react": "0.17.5", + "@number-flow/react": "0.5.10", "@openpanel/web": "1.0.1", "@radix-ui/react-avatar": "1.1.10", "@radix-ui/react-context-menu": "2.2.16", @@ -84,7 +86,6 @@ "nanoid": "5.1.6", "ofetch": "1.4.1", "plain-shiki": "0.3.1", - "progressive-blur": "1.0.0", "re-resizable": "6.11.2", "react": "19.0.0", "react-blurhash": "0.3.0", @@ -125,7 +126,7 @@ "@follow/models": "workspace:*", "@follow/types": "workspace:*", "@follow/utils": "workspace:*", - "@folo-services/ai-tools": "0.2.47", + "@folo-services/ai-tools": "0.2.49", "@types/node": "24.8.1", "@vite-pwa/assets-generator": "1.0.2", "fake-indexeddb": "6.2.4", diff --git a/apps/desktop/layer/renderer/src/atoms/server-configs.ts b/apps/desktop/layer/renderer/src/atoms/server-configs.ts index 8e1632785..96b342b52 100644 --- a/apps/desktop/layer/renderer/src/atoms/server-configs.ts +++ b/apps/desktop/layer/renderer/src/atoms/server-configs.ts @@ -16,6 +16,10 @@ export const [, , useServerConfigs, , getServerConfigs, setServerConfigs] = crea ), ) +export type ServerConfigs = ExtractResponseData +export type PaymentPlan = ServerConfigs["PAYMENT_PLAN_LIST"][number] +export type PaymentFeature = PaymentPlan["limit"] + export const useIsInMASReview = () => { const serverConfigs = useServerConfigs() return ( @@ -24,3 +28,24 @@ export const useIsInMASReview = () => { serverConfigs?.MAS_IN_REVIEW_VERSION === PKG.version ) } + +export const getIsInMASReview = () => { + const serverConfigs = getServerConfigs() + return ( + typeof process !== "undefined" && + process.mas && + serverConfigs?.MAS_IN_REVIEW_VERSION === PKG.version + ) +} + +export const useIsPaymentEnabled = () => { + const serverConfigs = useServerConfigs() + const isInMASReview = useIsInMASReview() + return !isInMASReview && serverConfigs?.PAYMENT_ENABLED +} + +export const getIsPaymentEnabled = () => { + const serverConfigs = getServerConfigs() + const isInMASReview = getIsInMASReview() + return !isInMASReview && serverConfigs?.PAYMENT_ENABLED +} diff --git a/apps/desktop/layer/renderer/src/components/ui/ai-summary-card/AISummaryCardBase.tsx b/apps/desktop/layer/renderer/src/components/ui/ai-summary-card/AISummaryCardBase.tsx index d3885ca3d..77739afbc 100644 --- a/apps/desktop/layer/renderer/src/components/ui/ai-summary-card/AISummaryCardBase.tsx +++ b/apps/desktop/layer/renderer/src/components/ui/ai-summary-card/AISummaryCardBase.tsx @@ -1,12 +1,15 @@ import { AutoResizeHeight } from "@follow/components/ui/auto-resize-height/index.js" import { MotionButtonBase } from "@follow/components/ui/button/index.js" import { cn } from "@follow/utils/utils" +import { isNeedUpgradeError } from "@follow-app/client-sdk" import type { ReactNode } from "react" import { useTranslation } from "react-i18next" +import { useIsPaymentEnabled } from "~/atoms/server-configs" import { CopyButton } from "~/components/ui/button/CopyButton" import { Markdown } from "~/components/ui/markdown/Markdown" import { useFeature } from "~/hooks/biz/useFeature" +import { useSettingModal } from "~/modules/settings/modal/useSettingModal" interface AISummaryCardBaseProps { /** Summary content to display */ @@ -21,8 +24,6 @@ interface AISummaryCardBaseProps { footerContent?: ReactNode /** Custom loading state component */ loadingComponent?: ReactNode - /** Custom empty state component */ - emptyComponent?: ReactNode /** Title text for the AI Summary header */ title?: string /** Whether to show the copy button */ @@ -31,6 +32,8 @@ interface AISummaryCardBaseProps { showAskAIButton?: boolean /** Callback when Ask AI button is clicked */ onAskAI?: () => void + /** Error code returned when requesting the summary */ + errorCode?: number } const DefaultLoadingState = () => ( @@ -41,12 +44,24 @@ const DefaultLoadingState = () => (
) -const DefaultEmptyState = ({ message }: { message: string }) => ( -
- -

{message}

-
-) +const DefaultEmptyState = ({ + message, + shouldSuggestUpgrade, +}: { + message: string + shouldSuggestUpgrade?: boolean +}) => { + const settingModalPresent = useSettingModal() + + return ( +
settingModalPresent("plan") : undefined} + > +

{message}

+
+ ) +} export const AISummaryCardBase: React.FC = ({ content, @@ -55,16 +70,20 @@ export const AISummaryCardBase: React.FC = ({ headerContent, footerContent, loadingComponent, - emptyComponent, title = "AI Summary", showCopyButton = true, showAskAIButton = false, onAskAI, + errorCode, }) => { const { t } = useTranslation("app") const aiEnabled = useFeature("ai") + const isPaymentEnabled = useIsPaymentEnabled() const hasContent = !isLoading && content + const normalizedErrorCode = typeof errorCode === "number" ? errorCode : undefined + const shouldSuggestUpgrade = + normalizedErrorCode !== undefined && isPaymentEnabled && isNeedUpgradeError(normalizedErrorCode) return (
= ({ loadingComponent || ) : hasContent ? ( {String(content)} + ) : shouldSuggestUpgrade ? ( + ) : ( - emptyComponent || + )} - {/* Footer */} {footerContent}
) diff --git a/apps/desktop/layer/renderer/src/components/ui/hover-preview/FeedPreviewCard.tsx b/apps/desktop/layer/renderer/src/components/ui/hover-preview/FeedPreviewCard.tsx index 72cd69ede..a35ecd6be 100644 --- a/apps/desktop/layer/renderer/src/components/ui/hover-preview/FeedPreviewCard.tsx +++ b/apps/desktop/layer/renderer/src/components/ui/hover-preview/FeedPreviewCard.tsx @@ -43,7 +43,7 @@ export const FeedPreviewCard: React.FC = ({ > {/* Header */} { e.preventDefault() @@ -52,8 +52,8 @@ export const FeedPreviewCard: React.FC = ({ target="_blank" rel="noopener noreferrer" > -
- +
+

{feed.title}

diff --git a/apps/desktop/layer/renderer/src/components/ui/media/PreviewMediaContent.tsx b/apps/desktop/layer/renderer/src/components/ui/media/PreviewMediaContent.tsx index e54fb128c..b9237ac30 100644 --- a/apps/desktop/layer/renderer/src/components/ui/media/PreviewMediaContent.tsx +++ b/apps/desktop/layer/renderer/src/components/ui/media/PreviewMediaContent.tsx @@ -21,6 +21,7 @@ import { ipcServices } from "~/lib/client" import { replaceImgUrlIfNeed } from "~/lib/img-proxy" import { useCurrentModal } from "../modal/stacked/hooks" +import type { VideoPlayerRef } from "./VideoPlayer" import { VideoPlayer } from "./VideoPlayer" // Calculate the dynamic scale value and offset @@ -264,6 +265,7 @@ export const PreviewMediaContent: FC<{ children?: React.ReactNode onZoomChange?: (isZoomed: boolean) => void }> = ({ media, initialIndex = 0, children, onZoomChange }) => { + const videoRefs = useRef<(VideoPlayerRef | null)[]>([]) const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true, startIndex: initialIndex }, [ WheelGesturesPlugin(), ]) @@ -297,6 +299,22 @@ export const PreviewMediaContent: FC<{ return () => $container.removeEventListener("keydown", handleKeyDown) }, [emblaApi, ref]) + const setVideoRef = useCallback((el: VideoPlayerRef | null, index: number) => { + videoRefs.current[index] = el + }, []) + + // Pause all videos when slide change + // And play the current video if it's a video + useEffect(() => { + videoRefs.current.forEach((video) => { + video?.controls.pause() + }) + const currentVideo = videoRefs.current[currentSlideIndex] + if (currentVideo) { + currentVideo.controls.play() + } + }, [currentSlideIndex]) + if (media.length === 0) return null if (media.length === 1) { const src = media[0]!.url! @@ -338,12 +356,12 @@ export const PreviewMediaContent: FC<{ {(handleZoomChange) => [
- {media.map((med) => ( + {media.map((med, i) => (
{med.type === "video" ? ( setVideoRef(el, i)} src={med.url} - autoPlay muted controls className="size-full object-contain" diff --git a/apps/desktop/layer/renderer/src/hooks/biz/useEntryActions.tsx b/apps/desktop/layer/renderer/src/hooks/biz/useEntryActions.tsx index e8ee82f16..246b2d82b 100644 --- a/apps/desktop/layer/renderer/src/hooks/biz/useEntryActions.tsx +++ b/apps/desktop/layer/renderer/src/hooks/biz/useEntryActions.tsx @@ -357,7 +357,6 @@ export const useEntryActions = ({ entryId, view }: { entryId: string; view: Feed view, ), active: isShowAISummaryOnce, - disabled: userRole === UserRole.Free || userRole === UserRole.Trial, entryId, }), new EntryActionMenuItem({ diff --git a/apps/desktop/layer/renderer/src/hooks/biz/useFollow.tsx b/apps/desktop/layer/renderer/src/hooks/biz/useFollow.tsx index 26e821224..220099203 100644 --- a/apps/desktop/layer/renderer/src/hooks/biz/useFollow.tsx +++ b/apps/desktop/layer/renderer/src/hooks/biz/useFollow.tsx @@ -1,63 +1,17 @@ -import { UserRole } from "@follow/constants" import { getFeedByIdOrUrl } from "@follow/store/feed/getter" import { getSubscriptionByFeedId } from "@follow/store/subscription/getter" -import { - useFeedSubscriptionCount, - useListSubscriptionCount, -} from "@follow/store/subscription/hooks" -import { useUserRole } from "@follow/store/user/hooks" import { t } from "i18next" import { useCallback } from "react" import { useNavigate } from "react-router" import { withoutTrailingSlash, withTrailingSlash } from "ufo" -import { useEventCallback } from "usehooks-ts" import { previewBackPath } from "~/atoms/preview" -import { useServerConfigs } from "~/atoms/server-configs" import { useModalStack } from "~/components/ui/modal/stacked/hooks" -import { CustomSafeError } from "~/errors/CustomSafeError" -import { useActivationModal } from "~/modules/activation" import type { FeedFormDataValuesType } from "~/modules/discover/FeedForm" import { FeedForm } from "~/modules/discover/FeedForm" import type { ListFormDataValuesType } from "~/modules/discover/ListForm" import { ListForm } from "~/modules/discover/ListForm" -const useCanFollowMoreInboxAndNotify = () => { - const role = useUserRole() - const listCurrentCount = useListSubscriptionCount() - const feedCurrentCount = useFeedSubscriptionCount() - const presentActivationModal = useActivationModal() - const serverConfigs = useServerConfigs() - - return useEventCallback((type: "list" | "feed") => { - if (role === UserRole.Free || role === UserRole.Trial) { - const LIMIT = - (type !== "list" - ? serverConfigs?.MAX_TRIAL_USER_FEED_SUBSCRIPTION - : serverConfigs?.MAX_TRIAL_USER_LIST_SUBSCRIPTION) || 50 - const CURRENT = type === "list" ? listCurrentCount : feedCurrentCount - const can = CURRENT < LIMIT - if (!can) { - presentActivationModal() - - throw new CustomSafeError( - `Trial user cannot create more ${type}, limit: ${LIMIT}, current: ${CURRENT}`, - true, - ) - } - return can - } else { - // const can = currentInboxCount < MAX_INBOX_COUNT - // if (!can) { - // // TODO - // } - // return can - - return true - } - }) -} - export interface FollowOptions { isList: boolean id?: string @@ -68,17 +22,10 @@ export interface FollowOptions { } export const useFollow = () => { const { present } = useModalStack() - const canFollowMoreInboxAndNotify = useCanFollowMoreInboxAndNotify() const navigate = useNavigate() return useCallback( (options?: FollowOptions) => { - if (options?.isList) { - canFollowMoreInboxAndNotify("list") - } else { - canFollowMoreInboxAndNotify("feed") - } - // Some feeds redirect xxx.com/feed to xxx.com/feed/ // Try to get a valid feed, then we can check isFollowed correctly const feed = @@ -117,6 +64,6 @@ export const useFollow = () => { }, }) }, - [canFollowMoreInboxAndNotify, present], + [present], ) } diff --git a/apps/desktop/layer/renderer/src/hooks/biz/useTimelineList.ts b/apps/desktop/layer/renderer/src/hooks/biz/useTimelineList.ts index ba8ae7ee0..8f7d640b8 100644 --- a/apps/desktop/layer/renderer/src/hooks/biz/useTimelineList.ts +++ b/apps/desktop/layer/renderer/src/hooks/biz/useTimelineList.ts @@ -1,10 +1,56 @@ import { FeedViewType, getViewList } from "@follow/constants" +import type { UISettings } from "@follow/shared/settings/interface" import { useSubscriptionStore } from "@follow/store/subscription/store" import { useMemo } from "react" import { useUISettingKey } from "~/atoms/settings/ui" import { ROUTE_TIMELINE_OF_VIEW, ROUTE_VIEW_ALL } from "~/constants/app" +const ALL_TIMELINE_IDS = getViewList({ includeAll: true }).map((view) => + view.view === FeedViewType.All ? ROUTE_VIEW_ALL : `${ROUTE_TIMELINE_OF_VIEW}${view.view}`, +) + +export const computeTimelineTabLists = ({ + timelineTabs, + hasAudiosSubscription, + hasNotificationsSubscription, +}: { + timelineTabs?: UISettings["timelineTabs"] + hasAudiosSubscription: boolean + hasNotificationsSubscription: boolean +}) => { + const savedVisible = (timelineTabs?.visible ?? []).filter((id) => ALL_TIMELINE_IDS.includes(id)) + const savedHidden = (timelineTabs?.hidden ?? []).filter((id) => ALL_TIMELINE_IDS.includes(id)) + const extras = ALL_TIMELINE_IDS.filter( + (id) => !savedVisible.includes(id) && !savedHidden.includes(id), + ) + + const isDefaultHidden = (id: string) => { + if (id === `${ROUTE_TIMELINE_OF_VIEW}${FeedViewType.Audios}`) return !hasAudiosSubscription + if (id === `${ROUTE_TIMELINE_OF_VIEW}${FeedViewType.Notifications}`) + return !hasNotificationsSubscription + return false + } + + const extraVisible = extras.filter((id) => !isDefaultHidden(id)) + const extraHidden = extras.filter((id) => isDefaultHidden(id)) + + const allConfigured = + savedVisible.includes(ROUTE_VIEW_ALL) || savedHidden.includes(ROUTE_VIEW_ALL) + + let nextVisible = [...savedVisible] + + if (!allConfigured && extraVisible.includes(ROUTE_VIEW_ALL)) { + nextVisible = [ROUTE_VIEW_ALL, ...nextVisible] + } + + nextVisible = [...nextVisible, ...extraVisible.filter((id) => id !== ROUTE_VIEW_ALL)] + + const nextHidden = [...savedHidden, ...extraHidden].filter((id) => !nextVisible.includes(id)) + + return { visible: nextVisible, hidden: nextHidden } +} + export const useTimelineList = (options?: { visible?: boolean hidden?: boolean @@ -22,50 +68,15 @@ export const useTimelineList = (options?: { state.listIdByView[FeedViewType.Notifications].size > 0, ) - const allTimelineIds = useMemo(() => { - return getViewList({ includeAll: true }).map((view) => - view.view === FeedViewType.All ? ROUTE_VIEW_ALL : `${ROUTE_TIMELINE_OF_VIEW}${view.view}`, - ) - }, []) - - const { visible, hidden } = useMemo(() => { - const ids = allTimelineIds - const savedVisible = (timelineTabs?.visible ?? []).filter((id) => ids.includes(id)) - const savedHidden = (timelineTabs?.hidden ?? []).filter((id) => ids.includes(id)) - const extras = ids.filter((id) => !savedVisible.includes(id) && !savedHidden.includes(id)) - - let nextVisible = [...savedVisible] - let nextHidden = [...savedHidden] - - const isDefaultHidden = (id: string) => { - if (id === `${ROUTE_TIMELINE_OF_VIEW}${FeedViewType.Audios}`) return !hasAudiosSubscription - if (id === `${ROUTE_TIMELINE_OF_VIEW}${FeedViewType.Notifications}`) - return !hasNotificationsSubscription - return false - } - - const extraVisible = extras.filter((id) => !isDefaultHidden(id)) - const extraHidden = extras.filter((id) => isDefaultHidden(id)) - - const allConfigured = - savedVisible.includes(ROUTE_VIEW_ALL) || savedHidden.includes(ROUTE_VIEW_ALL) - - if (!allConfigured && extraVisible.includes(ROUTE_VIEW_ALL)) { - nextVisible = [ROUTE_VIEW_ALL, ...nextVisible] - } - - nextVisible = [...nextVisible, ...extraVisible.filter((id) => id !== ROUTE_VIEW_ALL)] - - nextHidden = [...nextHidden, ...extraHidden].filter((id) => !nextVisible.includes(id)) - - return { visible: nextVisible, hidden: nextHidden } - }, [ - allTimelineIds, - hasAudiosSubscription, - hasNotificationsSubscription, - timelineTabs?.hidden, - timelineTabs?.visible, - ]) + const { visible, hidden } = useMemo( + () => + computeTimelineTabLists({ + timelineTabs, + hasAudiosSubscription, + hasNotificationsSubscription, + }), + [hasAudiosSubscription, hasNotificationsSubscription, timelineTabs], + ) return useMemo(() => { let result: string[] diff --git a/apps/desktop/layer/renderer/src/initialize/index.ts b/apps/desktop/layer/renderer/src/initialize/index.ts index 9d4a5aab7..1e7fd4c95 100644 --- a/apps/desktop/layer/renderer/src/initialize/index.ts +++ b/apps/desktop/layer/renderer/src/initialize/index.ts @@ -7,6 +7,7 @@ import { repository } from "@pkg" import { enableMapSet } from "immer" import { initI18n } from "~/i18n" +import { hydrateSessionsFromLocalDb } from "~/modules/ai-chat-session" import { settingSyncQueue } from "~/modules/settings/helper/sync-queue" import { ElectronCloseEvent, ElectronShowEvent } from "~/providers/invalidate-query-provider" @@ -55,6 +56,7 @@ export const initializeApp = async () => { initializeDayjs() registerHistoryStack() + hydrateSessionsFromLocalDb() // Set Environment document.documentElement.dataset.buildType = ELECTRON_BUILD ? "electron" : "web" diff --git a/apps/desktop/layer/renderer/src/lib/api-client.ts b/apps/desktop/layer/renderer/src/lib/api-client.ts index 7f500e3bf..c5e00da9a 100644 --- a/apps/desktop/layer/renderer/src/lib/api-client.ts +++ b/apps/desktop/layer/renderer/src/lib/api-client.ts @@ -3,12 +3,9 @@ import { userActions } from "@follow/store/user/store" import { createDesktopAPIHeaders } from "@follow/utils/headers" import { FollowClient } from "@follow-app/client-sdk" import PKG from "@pkg" -import { createElement } from "react" -import { toast } from "sonner" import { NetworkStatus, setApiStatus } from "~/atoms/network" import { setLoginModalShow } from "~/atoms/user" -import { NeedActivationToast } from "~/modules/activation/NeedActivationToast" import { getClientId, getSessionId } from "./client-session" @@ -78,25 +75,6 @@ followClient.addResponseInterceptor(async ({ response }) => { if (response.status === 400 && json.code === 1003) { router.navigate("/invitation") } - if (json.code.toString().startsWith("11")) { - setTimeout(() => { - const toastId = toast.error( - createElement(NeedActivationToast, { - dimiss: () => { - toast.dismiss(toastId) - }, - }), - { - closeButton: true, - duration: 10e4, - - classNames: { - content: tw`w-full`, - }, - }, - ) - }, 500) - } } catch { // ignore } diff --git a/apps/desktop/layer/renderer/src/lib/api-fetch.ts b/apps/desktop/layer/renderer/src/lib/api-fetch.ts index e2c8918b2..ef89ed855 100644 --- a/apps/desktop/layer/renderer/src/lib/api-fetch.ts +++ b/apps/desktop/layer/renderer/src/lib/api-fetch.ts @@ -1,16 +1,11 @@ -import { DEV } from "@follow/shared/constants" import { env } from "@follow/shared/env.desktop" import { userActions } from "@follow/store/user/store" import { createDesktopAPIHeaders } from "@follow/utils/headers" import PKG from "@pkg" import { ofetch } from "ofetch" -import { createElement } from "react" -import { toast } from "sonner" import { NetworkStatus, setApiStatus } from "~/atoms/network" import { setLoginModalShow } from "~/atoms/user" -import { NeedActivationToast } from "~/modules/activation/NeedActivationToast" -import { DebugRegistry } from "~/modules/debug/registry" import { getClientId, getSessionId } from "./client-session" @@ -57,48 +52,8 @@ export const apiFetch = ofetch.create({ if (context.response.status === 400 && json.code === 1003) { router.navigate("/invitation") } - if (json.code.toString().startsWith("11")) { - setTimeout(() => { - const toastId = toast.error( - createElement(NeedActivationToast, { - dimiss: () => { - toast.dismiss(toastId) - }, - }), - { - closeButton: true, - duration: 10e4, - - classNames: { - content: tw`w-full`, - }, - }, - ) - }, 500) - } } catch { // ignore } }, }) - -if (DEV) { - DebugRegistry.add("Activation Toast", () => { - setTimeout(() => { - const toastId = toast.error( - createElement(NeedActivationToast, { - dimiss: () => { - toast.dismiss(toastId) - }, - }), - { - closeButton: true, - duration: 10e4, - classNames: { - content: tw`w-full`, - }, - }, - ) - }, 500) - }) -} diff --git a/apps/desktop/layer/renderer/src/lib/error-parser.ts b/apps/desktop/layer/renderer/src/lib/error-parser.ts index 5aad15db8..bc1912140 100644 --- a/apps/desktop/layer/renderer/src/lib/error-parser.ts +++ b/apps/desktop/layer/renderer/src/lib/error-parser.ts @@ -1,11 +1,13 @@ import { DEV } from "@follow/shared/constants" import { cn } from "@follow/utils/utils" +import { FollowAPIError, isNeedUpgradeError } from "@follow-app/client-sdk" import { t } from "i18next" import { FetchError } from "ofetch" import { createElement } from "react" import type { ExternalToast } from "sonner" import { toast } from "sonner" +import { getIsPaymentEnabled } from "~/atoms/server-configs" import { CopyButton } from "~/components/ui/button/CopyButton" import { Markdown } from "~/components/ui/markdown/Markdown" import { DebugRegistry } from "~/modules/debug/registry" @@ -32,6 +34,20 @@ export const getFetchErrorInfo = ( } } + if (error instanceof FollowAPIError && error.code) { + const code = Number(error.code) + try { + const i18nKey = `errors:${code}` as any + const i18nMessage = t(i18nKey) === i18nKey ? error.message : t(i18nKey) + return { + message: i18nMessage, + code, + } + } catch { + return { message: error.message } + } + } + return { message: error.message } } @@ -78,6 +94,17 @@ export const toastFetchError = ( } } + if ("code" in error && error.code) { + code = Number(error.code) + try { + const tValue = t(`errors:${code}` as any) + const i18nMessage = tValue === code?.toString() ? error.message : tValue + message = i18nMessage + } catch { + message = error.message + } + } + // 2fa errors are handled by the form if (code === 4007 || code === 4008) { return @@ -94,9 +121,24 @@ export const toastFetchError = ( } if (!_reason) { - const title = _title || message - toastOptions.description = _title ? message : undefined - return toast.error(title, toastOptions) + const title = _title || message || "Unknown error occurred" + toastOptions.description = _title ? message : "" + const isPaymentEnabled = getIsPaymentEnabled() + const needUpgradeError = code && isPaymentEnabled ? isNeedUpgradeError(code) : false + if (needUpgradeError) { + toastOptions.description = "Please upgrade your plan." + } + return toast.error(title, { + ...toastOptions, + action: needUpgradeError + ? { + label: "Upgrade", + onClick: () => { + window.router.showSettings({ tab: "plan" }) + }, + } + : undefined, + }) } else { return toast.error(message || _title, { duration: 5000, diff --git a/apps/desktop/layer/renderer/src/modules/action/action-setting.tsx b/apps/desktop/layer/renderer/src/modules/action/action-setting.tsx index b87494f81..c3ea06729 100644 --- a/apps/desktop/layer/renderer/src/modules/action/action-setting.tsx +++ b/apps/desktop/layer/renderer/src/modules/action/action-setting.tsx @@ -32,6 +32,7 @@ import { useDialog } from "~/components/ui/modal/stacked/hooks" import { useContextMenu } from "~/hooks/common/useContextMenu" import { getI18n } from "~/i18n" import { copyToClipboard, readFromClipboard } from "~/lib/clipboard" +import { toastFetchError } from "~/lib/error-parser" import { downloadJsonFile, selectJsonFile } from "~/lib/export" import { RuleCard } from "~/modules/action/rule-card" import { @@ -421,7 +422,7 @@ const ActionButtonGroup = ({ onCreateRule }: { onCreateRule: () => void }) => { toast(t("actions.saveSuccess")) }, onError: (error) => { - toast.error(error) + toastFetchError(error) }, }) diff --git a/apps/desktop/layer/renderer/src/modules/activation/NeedActivationToast.tsx b/apps/desktop/layer/renderer/src/modules/activation/NeedActivationToast.tsx deleted file mode 100644 index c9370c41b..000000000 --- a/apps/desktop/layer/renderer/src/modules/activation/NeedActivationToast.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { toastStyles } from "@follow/components/ui/toast/styles.js" -import { stopPropagation } from "@follow/utils/dom" -import { useCallback } from "react" -import { useTranslation } from "react-i18next" - -import { useSettingModal } from "../settings/modal/use-setting-modal-hack" - -export const NeedActivationToast = (props: { dimiss: () => void }) => { - const settingModalPresent = useSettingModal() - - const { t } = useTranslation() - return ( -
-
{t("activation.plan.description")}
- - -
- ) -} diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat-session/index.ts b/apps/desktop/layer/renderer/src/modules/ai-chat-session/index.ts index 639903a38..87023a121 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat-session/index.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat-session/index.ts @@ -1,2 +1,3 @@ export * from "./query" export * from "./service" +export * from "./store" diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat-session/service.ts b/apps/desktop/layer/renderer/src/modules/ai-chat-session/service.ts index 6e8ab923f..3ac09a875 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat-session/service.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat-session/service.ts @@ -1,10 +1,17 @@ import type { AIChatMessage, AIChatSession, ListSessionsQuery } from "@follow-app/client-sdk" +import type { UIMessagePart } from "ai" import { followApi } from "../../lib/api-client" import { queryClient } from "../../lib/query-client" import { AIPersistService } from "../ai-chat/services" -import type { BizUIMessage, BizUIMetadata } from "../ai-chat/store/types" +import type { + BizUIDataTypes, + BizUIMessage, + BizUIMetadata, + BizUITools, +} from "../ai-chat/store/types" import { aiChatSessionKeys } from "./query" +import { aiChatSessionStoreActions } from "./store" // Hard cap on pagination to prevent excessive API calls while keeping initial sync fast. const MAX_PAGES = 10 @@ -19,52 +26,51 @@ class AIChatSessionServiceStatic { * List sessions from backend and ensure local DB has sessions and unseen messages. * This does NOT mark sessions as seen on the server (non-destructive sync). * - * Returns a small summary for observability. + * Returns the list of sessions. */ - async syncSessionsAndMessagesFromServer(filters?: ListSessionsQuery): Promise<{ - sessions: number - messages: number - failures: number - }> { + async syncSessionsAndMessagesFromServer(filters?: ListSessionsQuery): Promise { if (this.sync) { - return { sessions: 0, messages: 0, failures: 0 } + return [] } + this.sync = true - const res = await followApi.aiChatSessions.list(filters) - const sessions = res.data - let totalMessages = 0 - let failures = 0 + aiChatSessionStoreActions.setSyncing(true) + aiChatSessionStoreActions.clearError() - for (const session of sessions) { - const dbSession = await AIPersistService.getChatSession(session.chatId) - const lastUpdatedAt = dbSession ? dbSession.updatedAt : new Date(0) - if (lastUpdatedAt >= new Date(session.updatedAt)) { - // If local session is already up-to-date, skip fetching messages - continue - } - try { - // Ensure session exists locally first + try { + const { data: sessions } = await followApi.aiChatSessions.list(filters) + + const summary = { sessions: sessions.length, messages: 0, failures: 0 } + + sessions.forEach(async (session) => { await AIPersistService.ensureSession(session.chatId, { title: session.title, createdAt: new Date(session.createdAt), - updatedAt: new Date(session.updatedAt), + // Use createdAt for updatedAt as we are syncing session instead of messages + updatedAt: new Date(session.createdAt), }) - - // Fetch unseen messages (newer than lastSeenAt) without changing read state remotely - const unseenMessages = await this.fetchUnseenRemoteMessages(session.chatId, lastUpdatedAt) - if (unseenMessages.length === 0) continue - - const normalized = unseenMessages.map(this.normalizeRemoteMessage) - await AIPersistService.upsertMessages(session.chatId, normalized) - totalMessages += normalized.length - } catch (err) { - // Keep going even if a single session fails - console.error("syncSessionsAndMessagesFromServer: failed for session", session.chatId, err) - failures += 1 - } + }) + await this.loadSessionsFromDb() + aiChatSessionStoreActions.setStats(summary) + aiChatSessionStoreActions.setLastSyncedAt(new Date()) + return sessions + } catch (error) { + aiChatSessionStoreActions.setError( + error instanceof Error ? error.message : "Failed to sync chat sessions", + ) + throw error + } finally { + aiChatSessionStoreActions.setSyncing(false) + this.sync = false } - return { sessions: sessions.length, messages: totalMessages, failures } + } + + async loadSessionsFromDb() { + const rows = await AIPersistService.getChatSessions() + + aiChatSessionStoreActions.setSessions(rows) + return rows } /** * Fetch messages for a chat session from the remote API and persist (upsert) them locally. @@ -72,10 +78,17 @@ class AIChatSessionServiceStatic { * * Defensive in extracting the message array because the SDK response shape may evolve. */ - async fetchAndPersistMessages(session: AIChatSession): Promise { + async fetchAndPersistMessages( + session: AIChatSession, + options?: { + force?: boolean + }, + ): Promise { const dbSession = await AIPersistService.getChatSession(session.chatId) const lastUpdatedAt = dbSession ? dbSession.updatedAt : new Date(0) - if (lastUpdatedAt >= new Date(session.updatedAt)) { + const hasUpToDateSession = lastUpdatedAt >= new Date(session.updatedAt) + + if (!options?.force && hasUpToDateSession) { // If local session is already up-to-date, skip fetching messages return } @@ -88,14 +101,14 @@ class AIChatSessionServiceStatic { await AIPersistService.ensureSession(session.chatId, { title: session.title, createdAt: new Date(session.createdAt), - updatedAt: new Date(session.updatedAt), + // Use createdAt for updatedAt + // Because we are fetching session data instead of messages + updatedAt: new Date(session.createdAt), }) await AIPersistService.upsertMessages(session.chatId, normalized) - await followApi.aiChatSessions.markSeen({ - chatId: session.chatId, - lastSeenAt: new Date().toISOString(), - }) + await this.loadSessionsFromDb() + aiChatSessionStoreActions.setLastSyncedAt(new Date()) // Invalidate related queries so UI updates outside of hook-based mutation flows Promise.all([ @@ -105,6 +118,23 @@ class AIChatSessionServiceStatic { ]) } + async syncSessionMessages(chatId: string) { + try { + const sessionResponse = await followApi.aiChatSessions.get({ chatId }) + const session = sessionResponse.data + + if (!session) { + return AIPersistService.loadUIMessages(chatId) + } + + await this.fetchAndPersistMessages(session) + return AIPersistService.loadUIMessages(chatId) + } catch (error) { + console.error("syncSessionMessages: failed", error) + throw error + } + } + /** * Fetch remote messages for a chat session that are newer than the provided lastSeenAt timestamp. * Implements keyset pagination using `before` / `nextBefore` and stops when: @@ -147,9 +177,7 @@ class AIChatSessionServiceStatic { return { id: msg.id, role: msg.role satisfies BizUIMessage["role"], - // Remove this comment once @follow-app/client-sdk updated - // @ts-expect-error TODO fix message part types - parts: msg.messageParts, + parts: msg.messageParts as UIMessagePart[], metadata, createdAt: new Date(msg.createdAt), } diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat-session/store.ts b/apps/desktop/layer/renderer/src/modules/ai-chat-session/store.ts new file mode 100644 index 000000000..1f4589350 --- /dev/null +++ b/apps/desktop/layer/renderer/src/modules/ai-chat-session/store.ts @@ -0,0 +1,110 @@ +import { createWithEqualityFn } from "zustand/traditional" + +import { getI18n } from "~/i18n" + +import type { ChatSession } from "../ai-chat/types/ChatSession" +import { AIChatSessionService } from "./service" + +export interface AIChatSessionSyncStats { + sessions: number + messages: number + failures: number +} + +export interface AIChatSessionViewModelState { + sessions: ChatSession[] + isLoading: boolean + isSyncing: boolean + stats: AIChatSessionSyncStats + lastSyncedAt?: Date + error?: string +} + +const createInitialStats = (): AIChatSessionSyncStats => ({ + sessions: 0, + messages: 0, + failures: 0, +}) + +export const useAIChatSessionStore = createWithEqualityFn(() => ({ + sessions: [], + isLoading: false, + isSyncing: false, + stats: createInitialStats(), + lastSyncedAt: undefined, + error: undefined, +})) + +const { setState, getState, subscribe } = useAIChatSessionStore + +export const aiChatSessionStoreActions = { + setSessions: (sessions: ChatSession[]) => + setState({ + sessions, + }), + setLoading: (isLoading: boolean) => + setState({ + isLoading, + }), + setSyncing: (isSyncing: boolean) => + setState({ + isSyncing, + }), + setStats: (stats: AIChatSessionSyncStats) => + setState({ + stats: { ...stats }, + }), + resetStats: () => + setState({ + stats: createInitialStats(), + }), + setLastSyncedAt: (lastSyncedAt?: Date) => + setState({ + lastSyncedAt, + }), + setError: (error?: string) => + setState({ + error, + }), + clearError: () => + setState({ + error: undefined, + }), + + // syncing + fetchRemoteSessions: async () => { + try { + const { t } = getI18n() + const sessions = await AIChatSessionService.syncSessionsAndMessagesFromServer() + aiChatSessionStoreActions.setSessions( + sessions.map((session) => ({ + chatId: session.chatId, + title: session.title || t("ai:common.new_chat"), + createdAt: new Date(session.createdAt), + updatedAt: new Date(session.updatedAt), + })), + ) + } catch (error) { + console.error("fetchRemoteSessionsAndMessages: failed", error) + aiChatSessionStoreActions.setError(error instanceof Error ? error.message : "fetch_failed") + } + }, +} + +export const useAIChatSessionViewModel = useAIChatSessionStore + +export const createEmptyAIChatSessionSyncStats = createInitialStats + +export const getAIChatSessionState = getState +export const subscribeAIChatSessionStore = subscribe + +export const hydrateSessionsFromLocalDb = async () => { + try { + await AIChatSessionService.loadSessionsFromDb() + } catch (error) { + console.error("hydrateSessionsFromLocalDb: failed", error) + aiChatSessionStoreActions.setError(error instanceof Error ? error.message : "hydrate_failed") + } +} + +void hydrateSessionsFromLocalDb() diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/3d-models/AISplineLoader.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/3d-models/AISplineLoader.tsx index 6c2e4849a..0bb9a8a00 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/3d-models/AISplineLoader.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/3d-models/AISplineLoader.tsx @@ -2,8 +2,7 @@ import { clamp, cn } from "@follow/utils" import Spline from "@splinetool/react-spline" import { useCallback, useRef } from "react" -// TODO: use folo cdn -const resolvedAIIconUrl = "https://prod.spline.design/n2hjp93nWReC-512/scene.splinecode" +const resolvedAIIconUrl = "https://cdn.follow.is/ai2.splinecode" export const AISplineLoader = ({ className }: { className?: string }) => { const containerRef = useRef(null) diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/displays/AIChainOfThought.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/displays/AIChainOfThought.tsx index 44de3cf3b..317e963a1 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/displays/AIChainOfThought.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/displays/AIChainOfThought.tsx @@ -110,7 +110,7 @@ export const AIChainOfThought: React.FC = React.memo( contentClassName="pb-2 pt-1" >
-
+
{groups.map((part, index) => { const innerCollapseId = `${collapseId}-${index}` if (isToolUIPart(part)) { @@ -125,13 +125,7 @@ export const AIChainOfThought: React.FC = React.memo( return (
-
+
diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/AIModelIndicator.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/AIModelIndicator.tsx index 405de6841..0b3212429 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/AIModelIndicator.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/AIModelIndicator.tsx @@ -1,10 +1,12 @@ import { cn } from "@follow/utils" -import { memo, useMemo } from "react" +import { Fragment, memo, useMemo } from "react" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu/dropdown-menu" @@ -25,17 +27,6 @@ const providerIcons: Record = { deepseek: "i-mgc-deepseek-original", } -const AIModelNameMapping = { - auto: "Auto", - "gpt-5": "GPT-5", - "gpt-5-mini": "GPT-5 mini", - "gpt-5-nano": "GPT-5 nano", - "gpt-4.1": "GPT-4.1", - "claude-sonnet-4.5": "Claude Sonnet 4.5", - "gemini-2.5-pro": "Gemini 2.5 Pro", - "deepseek-v3.2-exp-thinking": "DeepSeek V3.2 Exp Thinking", -} - const parseModelString = (modelString: string) => { if (!modelString || !modelString.includes("/") || modelString === "auto") { return { provider: "auto" as ProviderType, modelName: modelString || "Unknown" } @@ -52,7 +43,7 @@ const parseModelString = (modelString: string) => { export const AIModelIndicator = memo(({ className, onModelChange }: AIModelIndicatorProps) => { const { data, changeModel } = useAIModel() - const { defaultModel, availableModels = [], currentModel } = data || {} + const { defaultModel, availableModels = [], currentModel, availableModelsMenu = [] } = data || {} const { provider, modelName } = useMemo(() => { return parseModelString(currentModel || defaultModel || "") @@ -79,7 +70,7 @@ export const AIModelIndicator = memo(({ className, onModelChange }: AIModelIndic > - {AIModelNameMapping[modelName] || modelName} + {availableModelsMenu.find((item) => item.value === currentModel)?.label || modelName} {hasMultipleModels && }
@@ -93,27 +84,36 @@ export const AIModelIndicator = memo(({ className, onModelChange }: AIModelIndic {modelContent} - {availableModels.map((model) => { - const { provider: itemProvider, modelName: itemModelName } = parseModelString(model) - const itemIconClass = providerIcons[itemProvider] || providerIcons.auto - const isSelected = model === (currentModel || defaultModel) + {availableModelsMenu.map(({ label, value }, index) => { + if (value) { + const { provider: itemProvider, modelName: itemModelName } = parseModelString(value) + const itemIconClass = providerIcons[itemProvider] || providerIcons.auto + const isSelected = value === (currentModel || defaultModel) - const handleModelSelect = () => { - changeModel(model) - onModelChange?.(model) + const handleModelSelect = () => { + changeModel(value) + onModelChange?.(value) + } + + return ( + + + {label || itemModelName} + + ) + } else { + return ( + + {index > 0 && } + {label} + + ) } - - return ( - - - {AIModelNameMapping[itemModelName] || itemModelName} - - ) })} diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHeader.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHeader.tsx index 423d0dca2..f045b1830 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHeader.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHeader.tsx @@ -61,6 +61,7 @@ const ChatHeaderLayout = ({ const { isScrolledBeyondThreshold } = useAIRootState() const isScrolledBeyondThresholdValue = useAtomValue(isScrolledBeyondThreshold) + return (
- {hasMessages && ( + {(hasMessages || currentTitle) && (
settingModalPresent("ai")}>
diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHistoryDropdown.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHistoryDropdown.tsx index 46b9414e3..597ff4e99 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHistoryDropdown.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHistoryDropdown.tsx @@ -38,7 +38,7 @@ export const ChatHistoryDropdown = ({ (open: boolean) => { if (open) { loadHistory() - AIPersistService.cleanupEmptySessions() + // AIPersistService.cleanupEmptySessions() } }, [loadHistory], @@ -95,7 +95,7 @@ export const ChatHistoryDropdown = ({ {triggerElement || defaultTrigger} - {loading ? ( + {loading && sessions.length === 0 ? (
@@ -107,17 +107,18 @@ export const ChatHistoryDropdown = ({ {sessions.map((session) => ( startTransition(() => chatActions.switchToChat(session.chatId))} - className="group flex h-12 cursor-pointer items-center justify-between rounded-md px-2 py-3" + onClick={() => + startTransition(() => { + chatActions.setTimelineSummaryManualOverride(true) + chatActions.switchToChat(session.chatId) + }) + } + className="group flex h-8 cursor-pointer items-center justify-between rounded-md px-2 py-3" >

{session.title || t("common.new_chat")}

-

- {session.messageCount} - {session.messageCount === 1 ? "message" : "messages"} -

diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatInput.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatInput.tsx index 49b4316ca..93befe1d9 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatInput.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatInput.tsx @@ -152,7 +152,7 @@ export const ChatInput = memo( ) return ( -
+
{/* Input Area */}
diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatInterface.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatInterface.tsx index 209b4af4d..9d528ff74 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatInterface.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatInterface.tsx @@ -59,7 +59,7 @@ import { WelcomeScreen } from "./WelcomeScreen" const SCROLL_BOTTOM_THRESHOLD = 100 const draftMessages = new Map() -const ChatInterfaceContent = ({ centerInputOnEmpty, visualOffsetY }: ChatInterfaceProps) => { +const ChatInterfaceContent = ({ centerInputOnEmpty }: ChatInterfaceProps) => { const hasMessages = useHasMessages() const status = useChatStatus() const chatActions = useChatActions() @@ -117,7 +117,7 @@ const ChatInterfaceContent = ({ centerInputOnEmpty, visualOffsetY }: ChatInterfa previousMinHeightRef.current = 0 }, [currentChatId]) - const { isLoading: isLoadingHistory } = useLoadMessages(currentChatId || "", { + const { isLoading: isLoadingHistory, isSyncingRemote } = useLoadMessages(currentChatId || "", { onLoad: () => { nextFrame(() => { const $scrollArea = scrollAreaRef @@ -333,6 +333,8 @@ const ChatInterfaceContent = ({ centerInputOnEmpty, visualOffsetY }: ChatInterfa }, [status, resetScrollState, messageContainerMinHeight, scrollAreaRef]) const shouldShowScrollToBottom = hasMessages && !isAtBottom && !isLoadingHistory + const shouldShowLoadingOverlay = + Boolean(currentChatId) && !hasMessages && (isLoadingHistory || isSyncingRemote) const { handleScroll } = useAttachScrollBeyond() @@ -343,23 +345,26 @@ const ChatInterfaceContent = ({ centerInputOnEmpty, visualOffsetY }: ChatInterfa const rateLimitExtraHeight = hasRateLimitError ? 40 : 0 return ( -
+
- {!hasMessages && !isLoadingHistory ? ( + {!hasMessages && !shouldShowLoadingOverlay ? ( ) : ( <> + {shouldShowLoadingOverlay ? ( +
+
+ + {isSyncingRemote && ( +

+ Syncing messages from server... +

+ )} +
+
+ ) : null} - {isLoadingHistory ? ( -
- -
- ) : ( -
- } /> +
+ } /> - {(status === "submitted" || status === "streaming") && ( - - )} -
- )} + {(status === "submitted" || status === "streaming") && ( + + )} +
)} @@ -424,6 +423,7 @@ const ChatInterfaceContent = ({ centerInputOnEmpty, visualOffsetY }: ChatInterfa
( diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatMoreDropdown.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatMoreDropdown.tsx index 380f29530..26bb9024b 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatMoreDropdown.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatMoreDropdown.tsx @@ -94,11 +94,10 @@ export const ChatMoreDropdown = ({ : "Switch to Fixed Panel"} + )} - - settingModalPresent("ai")}> AI Settings diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/RateLimitNotice.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/RateLimitNotice.tsx index 09056ddec..1c81c4cd2 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/RateLimitNotice.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/RateLimitNotice.tsx @@ -2,6 +2,8 @@ import { cn } from "@follow/utils" import { m } from "motion/react" import * as React from "react" +import { useSettingModal } from "~/modules/settings/modal/useSettingModal" + import { parseAIError } from "../../utils/error" interface RateLimitNoticeProps { @@ -16,6 +18,7 @@ interface RateLimitNoticeProps { export const RateLimitNotice: React.FC = ({ error, className }) => { const parsedError = React.useMemo(() => parseAIError(error), [error]) const { isRateLimitError, errorData } = parsedError + const settingModalPresent = useSettingModal() // Only render for rate limit errors if (!isRateLimitError || !errorData) { @@ -57,7 +60,7 @@ export const RateLimitNotice: React.FC = ({ error, classNa parts.push(`${remainingTokens.toLocaleString()} tokens left`) } } else { - parts.push("AI usage limit reached") + parts.push("Upgrade plan to get more AI credits.") } // Reset time @@ -79,9 +82,10 @@ export const RateLimitNotice: React.FC = ({ error, classNa exit={{ opacity: 0, y: -10 }} transition={{ duration: 0.2 }} className={cn("mb-3", className)} + onClick={() => settingModalPresent("plan")} > -
- +
+ {buildMessage()} diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/TaskReportDropdown.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/TaskReportDropdown.tsx index bfbfbaf14..e9665d411 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/TaskReportDropdown.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/TaskReportDropdown.tsx @@ -21,6 +21,7 @@ import { AIChatSessionService } from "~/modules/ai-chat-session" import { useAIChatSessionListQuery, useDeleteAIChatSessionMutation, + useMarkChatSessionSeenMutation, } from "~/modules/ai-chat-session/query" import { AITaskModal, useCanCreateNewAITask } from "~/modules/ai-task" import { useSettingModal } from "~/modules/settings/modal/use-setting-modal-hack" @@ -40,20 +41,32 @@ interface SessionItemProps { isLoading?: boolean } -// Helper to determine if a session has unread messages -const isSessionUnread = (session: AIChatSession): boolean => { +const isTaskSession = (session: AIChatSession): boolean => { if (!session.lastSeenAt || !session.updatedAt) return false - return new Date(session.updatedAt) > new Date(session.lastSeenAt) + if (!session.chatId.startsWith("ai-task")) return false + return true } +// Helper to determine if a session has unread messages +const isUnreadSession = (session: AIChatSession): boolean => { + return new Date(session.updatedAt) > new Date(session.lastSeenAt) +} const SessionItem = ({ session, onClick, onDelete, isLoading }: SessionItemProps) => { + const hasUnreadMessages = isUnreadSession(session) return ( -
+
+ {hasUnreadMessages && ( + + )}

{session.title || "Untitled Chat"}

@@ -99,15 +112,15 @@ export const TaskReportDropdown = ({ triggerElement, asChild = true }: TaskRepor const { t } = useTranslation("ai") const [loadingChatId, setLoadingChatId] = useState(null) const showSettings = useSettingModal() - - // Only keep unread sessions for display - const unreadSessions = useMemo( - () => (sessions || []).filter((s) => isSessionUnread(s)), - [sessions], + const markChatSessionSeenMutation = useMarkChatSessionSeenMutation() + // Only keep task sessions for display + const taskSessions = useMemo(() => (sessions || []).filter((s) => isTaskSession(s)), [sessions]) + const hasTaskSessions = taskSessions.length > 0 + const hasUnreadSessions = useMemo( + () => taskSessions.some((s) => isUnreadSession(s)), + [taskSessions], ) - const hasUnreadSessions = unreadSessions.length > 0 - const { present } = useModalStack() const canCreateNewTask = useCanCreateNewAITask() const handleScheduleActionClick = () => { @@ -127,7 +140,10 @@ export const TaskReportDropdown = ({ triggerElement, asChild = true }: TaskRepor const handleSessionSelect = useCallback( async (session: AIChatSession) => { - if (session.chatId === currentChatId) return + if (session.chatId === currentChatId) { + console.warn("Session already active, no action taken") + return + } try { await AIChatSessionService.fetchAndPersistMessages(session) } catch (e) { @@ -138,8 +154,14 @@ export const TaskReportDropdown = ({ triggerElement, asChild = true }: TaskRepor chatActions.setTimelineSummaryManualOverride(true) } chatActions.switchToChat(session.chatId) + if (isUnreadSession(session)) { + markChatSessionSeenMutation.mutate({ + chatId: session.chatId, + lastSeenAt: new Date().toISOString(), + }) + } }, - [chatActions, currentChatId], + [chatActions, currentChatId, markChatSessionSeenMutation, shouldDisableTimelineSummary], ) const handleDeleteSession = useCallback( @@ -211,7 +233,7 @@ export const TaskReportDropdown = ({ triggerElement, asChild = true }: TaskRepor ) : ( {triggerElement || defaultTrigger} - {hasUnreadSessions && triggerElement && ( + {hasTaskSessions && triggerElement && ( - {unreadSessions.length > 0 ? ( - unreadSessions.map((session) => ( + {taskSessions.length > 0 ? ( + taskSessions.map((session) => ( ( animate={{ opacity: 1, y: 0 }} className="space-y-6 text-center" > -
- -
-
-

- AI -

+
+
+ +
+
+

+ AI +

-

{description}

+

{description}

+
) diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/AIMessageParts.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/AIMessageParts.tsx index bd3f0c5ce..277a56902 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/AIMessageParts.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/AIMessageParts.tsx @@ -44,7 +44,7 @@ export const AIMessageParts: React.FC = React.memo( const parts = [] as (ChainReasoningPart[] | TextUIPart | ToolUIPart)[] const shouldBypass = (name: string) => - name.startsWith("tool-") || name.startsWith("tool-save_user_memory") + name.startsWith("tool-save_user_memory") || name.startsWith("tool-display") let chainReasoningParts: ChainReasoningPart[] | null = null for (const part of message.parts) { diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/TokenUsagePill.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/TokenUsagePill.tsx index 061249a62..6e7bd5dfd 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/TokenUsagePill.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/TokenUsagePill.tsx @@ -41,7 +41,7 @@ export const TokenUsagePill: React.FC = ({ metadata, childr
-
Token Usage
+
AI Credits Usage
{metadata.totalTokens != null && (
diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/ToolInvocationComponent.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/ToolInvocationComponent.tsx index ea3525bd4..40ea3bc94 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/ToolInvocationComponent.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/message/ToolInvocationComponent.tsx @@ -4,6 +4,7 @@ import type { ToolUIPart } from "ai" import { getToolName } from "ai" import clsx from "clsx" import * as React from "react" +import { titleCase } from "title-case" interface ToolInvocationComponentProps { part: ToolUIPart @@ -13,7 +14,8 @@ interface ToolInvocationComponentProps { export const ToolInvocationComponent: React.FC = React.memo( ({ part, variant }) => { - const toolName = getToolName(part) + const toolName = titleCase(getToolName(part).replaceAll("_", " ")) + const hasError = "errorText" in part && part.errorText const hasResult = "output" in part && part.output const hasArgs = "input" in part && part.input @@ -23,11 +25,22 @@ export const ToolInvocationComponent: React.FC = R // Generate a unique value for this accordion item const accordionValue = `tool-${"toolCallId" in part ? part.toolCallId : Math.random()}` + const result = React.useMemo(() => { + if (hasResult) { + const string = JSON.stringify(part.output, null, 2) + if (string.length > 1000) { + return `${string.slice(0, 1000)}\n...` + } else { + return string + } + } + }, [hasResult, part]) + return (
@@ -72,7 +85,7 @@ export const ToolInvocationComponent: React.FC = R
Result:
) : null} diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/welcome/EntrySummaryCard.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/welcome/EntrySummaryCard.tsx index 934eb9057..8b6015281 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/welcome/EntrySummaryCard.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/welcome/EntrySummaryCard.tsx @@ -6,6 +6,7 @@ import { useTranslation } from "react-i18next" import { useEntryIsInReadabilitySuccess } from "~/atoms/readability" import { useActionLanguage } from "~/atoms/settings/general" import { AISummaryCardBase } from "~/components/ui/ai-summary-card" +import { getFetchErrorInfo } from "~/lib/error-parser" interface EntrySummaryCardProps { entryId: string @@ -22,6 +23,8 @@ export const EntrySummaryCard: React.FC = ({ entryId, cla actionLanguage, enabled: true, }) + const summaryErrorCode = + summary.error instanceof Error ? getFetchErrorInfo(summary.error).code : undefined return ( = ({ entryId, cla isLoading={summary.isLoading} className={className} title={t("ai_summary")} + errorCode={summaryErrorCode} /> ) diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useAIModel.ts b/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useAIModel.ts index f3cd1ac22..6cc8b1537 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useAIModel.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useAIModel.ts @@ -52,6 +52,7 @@ export const useAIModel = () => { data: { defaultModel: configuration?.defaultModel, availableModels: configuration?.availableModels, + availableModelsMenu: configuration?.availableModelsMenu, currentModel, }, isLoading, diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useAutoTimelineSummaryShortcut.ts b/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useAutoTimelineSummaryShortcut.ts index c9ff96025..4d0173795 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useAutoTimelineSummaryShortcut.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useAutoTimelineSummaryShortcut.ts @@ -21,7 +21,7 @@ import { BlockSliceAction } from "../store/slices/block.slice" import type { AIChatContextBlock, SendingUIMessage } from "../store/types" import { isTimelineSummaryAutoContext } from "./useTimelineSummaryAutoContext" -const ONE_HOUR = 60 * 60 * 1000 +const INTERVAL = 5 * 60 * 60 * 1000 const buildSummaryMessage = ( editor: LexicalEditor, @@ -100,7 +100,7 @@ export const useAutoTimelineSummaryShortcut = () => { }) const previousContextKeyRef = useRef(null) - const isAllTimeline = isTimelineSummaryAutoContext({ view, entryId }) + const isAllTimeline = isTimelineSummaryAutoContext({ view, feedId, entryId }) const defaultShortcut = useMemo(() => { const shortcuts = aiSettings.shortcuts ?? [] @@ -227,7 +227,7 @@ export const useAutoTimelineSummaryShortcut = () => { if (existingSession) { const lastUpdatedAt = existingSession.updatedAt?.getTime?.() ?? existingSession.updatedAt - if (typeof lastUpdatedAt === "number" && now - lastUpdatedAt < ONE_HOUR) { + if (typeof lastUpdatedAt === "number" && now - lastUpdatedAt < INTERVAL) { if (currentChatId !== existingSession.chatId) { await chatActions.switchToChat(existingSession.chatId) } diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useChatHistory.ts b/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useChatHistory.ts index 08944686d..824255ae0 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useChatHistory.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useChatHistory.ts @@ -1,41 +1,40 @@ -import { useCallback, useState } from "react" +import { useMemo } from "react" +import { useEventCallback } from "usehooks-ts" -import { getI18n } from "~/i18n" -import { AIPersistService } from "~/modules/ai-chat/services/index" -import { AIChatSessionService } from "~/modules/ai-chat-session/service" - -import type { ChatSession } from "../types/ChatSession" +import { aiChatSessionStoreActions, useAIChatSessionStore } from "~/modules/ai-chat-session/store" export const useChatHistory = () => { - const [sessions, setSessions] = useState([]) - const [loading, setLoading] = useState(false) + const state = useAIChatSessionStore() - const loadHistory = useCallback(async () => { - setLoading(true) + const { sessions } = state + const loading = state.isLoading || state.isSyncing + + const loadHistory = useEventCallback(async () => { + if (loading) return + + aiChatSessionStoreActions.setLoading(true) + aiChatSessionStoreActions.clearError() - const { t } = getI18n() try { - await AIChatSessionService.syncSessionsAndMessagesFromServer() - const result = await AIPersistService.getChatSessions() - const sessions: ChatSession[] = result.map((row) => ({ - chatId: row.chatId, - title: row.title || t("ai:common.new_chat"), - createdAt: new Date(row.createdAt), - updatedAt: new Date(row.updatedAt), - messageCount: row.messageCount, - })) - - setSessions(sessions) + await aiChatSessionStoreActions.fetchRemoteSessions() } catch (error) { console.error("Failed to load chat history:", error) + aiChatSessionStoreActions.setError(error instanceof Error ? error.message : "Unknown error") } finally { - setLoading(false) + aiChatSessionStoreActions.setSyncing(false) + aiChatSessionStoreActions.setLoading(false) } - }, []) + }) - return { - sessions, - loading, - loadHistory, - } + return useMemo( + () => ({ + sessions, + loading, + loadHistory, + stats: state.stats, + lastSyncedAt: state.lastSyncedAt, + error: state.error, + }), + [sessions, loading, loadHistory, state.stats, state.lastSyncedAt, state.error], + ) } diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useLoadMessages.ts b/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useLoadMessages.ts index 856cc5c53..9d6af2bca 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useLoadMessages.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useLoadMessages.ts @@ -1,9 +1,10 @@ import { useEffect, useState } from "react" import { useEventCallback } from "usehooks-ts" -import { AIPersistService } from "../services" +import { AIChatSessionService } from "~/modules/ai-chat-session/service" + import { useChatActions } from "../store/hooks" -import type { BizUIMessage, BizUIMetadata } from "../store/types" +import type { BizUIMessage } from "../store/types" export const useLoadMessages = ( chatId: string, @@ -12,6 +13,7 @@ export const useLoadMessages = ( const chatActions = useChatActions() const [isLoading, setIsLoading] = useState(true) + const [isSyncingRemote, setIsSyncingRemote] = useState(false) const onLoadEventCallback = useEventCallback((messages: BizUIMessage[]) => { options?.onLoad?.(messages) @@ -20,25 +22,15 @@ export const useLoadMessages = ( useEffect(() => { let mounted = true setIsLoading(true) - AIPersistService.loadMessages(chatId) - .then((messages) => { - if (mounted) { - const messagesToSet: BizUIMessage[] = messages.map((message) => ({ - id: message.id, - parts: message.messageParts as any[], - role: message.role, - metadata: message.metadata as BizUIMetadata, - createdAt: message.createdAt, - })) - const existingMessages = chatActions.getMessages() - - if (messagesToSet.length === 0 && existingMessages.length > 0) { - onLoadEventCallback(existingMessages) - } else { - chatActions.setMessages(messagesToSet) - onLoadEventCallback(messagesToSet) - } + setIsSyncingRemote(false) + AIChatSessionService.syncSessionMessages(chatId) + .then(async (messages) => { + if (!mounted) { + return [] } + chatActions.setMessages(messages) + onLoadEventCallback(messages) + return messages }) .catch((error) => { console.error(error) @@ -46,11 +38,12 @@ export const useLoadMessages = ( .finally(() => { if (mounted) { setIsLoading(false) + setIsSyncingRemote(false) } }) return () => { mounted = false } }, [chatId, onLoadEventCallback, chatActions]) - return { isLoading } + return { isLoading, isSyncingRemote } } diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useTimelineSummaryAutoContext.ts b/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useTimelineSummaryAutoContext.ts index 6353f649b..2fdd65b16 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useTimelineSummaryAutoContext.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useTimelineSummaryAutoContext.ts @@ -1,14 +1,24 @@ import { FeedViewType } from "@follow/constants" -import { ROUTE_ENTRY_PENDING } from "~/constants" +import { ROUTE_ENTRY_PENDING, ROUTE_FEED_PENDING } from "~/constants" import type { BizRouteParams } from "~/hooks/biz/useRouteParams" import { useRouteParamsSelector } from "~/hooks/biz/useRouteParams" -export type TimelineSummaryContextParams = Pick +export type TimelineSummaryContextParams = Pick -export const isTimelineSummaryAutoContext = ({ view, entryId }: TimelineSummaryContextParams) => { - return view === FeedViewType.All && (!entryId || entryId === ROUTE_ENTRY_PENDING) +export const isTimelineSummaryAutoContext = ({ + view, + feedId, + entryId, +}: TimelineSummaryContextParams) => { + return ( + view === FeedViewType.All && + (!entryId || entryId === ROUTE_ENTRY_PENDING) && + (!feedId || feedId === ROUTE_FEED_PENDING) + ) } export const useTimelineSummaryAutoContext = () => - useRouteParamsSelector(({ view, entryId }) => isTimelineSummaryAutoContext({ view, entryId })) + useRouteParamsSelector(({ view, feedId, entryId }) => + isTimelineSummaryAutoContext({ view, feedId, entryId }), + ) diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/services/index.ts b/apps/desktop/layer/renderer/src/modules/ai-chat/services/index.ts index 4c77d92ef..12d2c385b 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/services/index.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/services/index.ts @@ -1,8 +1,7 @@ -import type { AsyncDb } from "@follow/database/db" import { db } from "@follow/database/db" import type { AiChatMessagesModel } from "@follow/database/schemas/index" import { aiChatMessagesTable, aiChatTable } from "@follow/database/schemas/index" -import { asc, count, eq, inArray, sql } from "drizzle-orm" +import { asc, eq, inArray, sql } from "drizzle-orm" import { getI18n } from "~/i18n" import { followClient } from "~/lib/api-client" @@ -130,6 +129,10 @@ class AIPersistServiceStatic { const cleanParts = [] as typeof message.parts for (const part of message.parts) { + // Skip streaming messages + if ("state" in part && part.state === "streaming") { + return acc + } if (isDataBlockPart(part)) { const nextPart = structuredClone(part) for (const block of nextPart.data) { @@ -169,8 +172,24 @@ class AIPersistServiceStatic { metadata: sql`excluded.metadata`, finishedAt: sql`excluded.finished_at`, status: sql`excluded.status`, + createdAt: sql`excluded.created_at`, }, }) + + const date = results.reduce((latest, msg) => { + const date = msg.createdAt ? new Date(msg.createdAt) : null + if (date === null) { + return latest + } + if (!latest || date > latest) { + return date + } + return latest + }, null) + if (date) { + // Update session time after successfully saving messages + await AIPersistService.updateSessionTime(chatId, date) + } } /** @@ -371,18 +390,6 @@ class AIPersistServiceStatic { return [] } - const chatIds = chats.map((chat) => chat.chatId) - const messageCounts = await (db as AsyncDb) - .select({ - chatId: aiChatMessagesTable.chatId, - messageCount: count(aiChatMessagesTable.id), - }) - .from(aiChatMessagesTable) - .where(inArray(aiChatMessagesTable.chatId, chatIds)) - .groupBy(aiChatMessagesTable.chatId) - - const messageCountMap = new Map(messageCounts.map((item) => [item.chatId, item.messageCount])) - const normalizedChats = await Promise.all( chats.map(async (chat) => { const resolvedTitle = this.resolveSessionTitle(chat.chatId, chat.title, { @@ -401,15 +408,12 @@ class AIPersistServiceStatic { }), ) - return normalizedChats - .map((chat) => ({ - chatId: chat.chatId, - title: chat.title, - createdAt: chat.createdAt, - updatedAt: chat.updatedAt, - messageCount: messageCountMap.get(chat.chatId) || 0, - })) - .filter((chat) => chat.messageCount > 0) + return normalizedChats.map((chat) => ({ + chatId: chat.chatId, + title: chat.title, + createdAt: chat.createdAt, + updatedAt: chat.updatedAt, + })) } async deleteSession(chatId: string) { @@ -432,11 +436,11 @@ class AIPersistServiceStatic { .where(eq(aiChatTable.chatId, chatId)) } - async updateSessionTime(chatId: string) { + async updateSessionTime(chatId: string, date: Date = new Date()) { await db .update(aiChatTable) .set({ - updatedAt: new Date(Date.now()), + updatedAt: date, }) .where(eq(aiChatTable.chatId, chatId)) } @@ -459,6 +463,11 @@ class AIPersistServiceStatic { // Clear deleted sessions from cache chatIdsToDelete.forEach((chatId) => this.clearSessionCache(chatId)) + for (const chatId of chatIdsToDelete) { + await followClient.api.aiChatSessions.delete({ chatId }).catch((error) => { + console.error("Failed to delete remote chat sessions:", error) + }) + } } } } diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/store/chat-core/chat-actions.ts b/apps/desktop/layer/renderer/src/modules/ai-chat/store/chat-core/chat-actions.ts index 1e6e32e0b..6573a4152 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/store/chat-core/chat-actions.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/store/chat-core/chat-actions.ts @@ -36,6 +36,7 @@ export class ChatSliceActions { private params: Parameters>, private chatInstance: ZustandChat, ) { + this.chatInstance.resumeStream() return autoBindThis(this) } @@ -280,6 +281,7 @@ export class ChatSliceActions { chatInstance: newChatInstance, })) + newChatInstance.resumeStream() // Update the reference this.chatInstance = newChatInstance } catch (error) { diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/store/chat-core/chat-state.ts b/apps/desktop/layer/renderer/src/modules/ai-chat/store/chat-core/chat-state.ts index 205340a90..6c05ff329 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/store/chat-core/chat-state.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/store/chat-core/chat-state.ts @@ -147,14 +147,12 @@ export class ZustandChatState implements ChatState { await AIPersistService.ensureSession(this.chatId) // Save messages using incremental updates await AIPersistService.replaceAllMessages(this.chatId, this.#messages) - // Update session time after successfully saving messages - await AIPersistService.updateSessionTime(this.chatId) } catch (error) { console.error("Failed to persist messages:", error) } }, 100, - { leading: true, trailing: true }, + { leading: false, trailing: true }, ) #fillMessageCreatedAt(message: SendingUIMessage | BizUIMessage): BizUIMessage { diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/types/ChatSession.ts b/apps/desktop/layer/renderer/src/modules/ai-chat/types/ChatSession.ts index 60f422e8c..305398345 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/types/ChatSession.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/types/ChatSession.ts @@ -5,7 +5,6 @@ export interface ChatSession { title?: string createdAt: Date updatedAt: Date - messageCount: number } export type RichTextPart = { diff --git a/apps/desktop/layer/renderer/src/modules/ai-memory/query.ts b/apps/desktop/layer/renderer/src/modules/ai-memory/query.ts index c39f867ad..2319f5bfc 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-memory/query.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-memory/query.ts @@ -42,6 +42,7 @@ export const useAIMemoryListQuery = (params: MemoryListQuery = {}) => { const response = await followApi.ai.memory.list({ ...params, limit, + // @ts-expect-error TODO: fix type before: pageParam ?? undefined, }) diff --git a/apps/desktop/layer/renderer/src/modules/ai-task/components/task-item.tsx b/apps/desktop/layer/renderer/src/modules/ai-task/components/task-item.tsx index 60084b208..246b11fde 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-task/components/task-item.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-task/components/task-item.tsx @@ -8,6 +8,7 @@ import { toast } from "sonner" import { setAIPanelVisibility } from "~/atoms/settings/ai" import { useDialog, useModalStack } from "~/components/ui/modal/stacked/hooks" +import { followApi } from "~/lib/api-client" import { ChatSliceActions } from "~/modules/ai-chat/store/chat-core/chat-actions" import { AIChatSessionService } from "~/modules/ai-chat-session" import { useAIChatSessionListQuery } from "~/modules/ai-chat-session/query" @@ -122,7 +123,7 @@ export const TaskItem = memo(({ task }: { task: AITask }) => { const statusColorClass = getStatusColor(status) const taskSession = useMemo( - () => sessions?.find((s) => s.chatId === task.id), + () => sessions?.find((s) => s.chatId.startsWith(`ai-task-${task.id}`)), [sessions, task.id], ) @@ -175,10 +176,23 @@ export const TaskItem = memo(({ task }: { task: AITask }) => { onClick: async () => { const loadingId = toast.loading(t("tasks.toast.test_start")) try { - await testRunMutation.mutateAsync({ id: task.id }) + const testRunResult = await testRunMutation.mutateAsync({ id: task.id }) + if (testRunResult.data.error) { + throw new Error(testRunResult.data.error) + } toast.success(t("tasks.toast.test_success"), { id: loadingId, }) + // @ts-ignore -- Remove once SDK types are updated + const { sessionId } = testRunResult.data + if (sessionId) { + const session = ( + await followApi.aiChatSessions.get({ + chatId: sessionId, + }) + ).data + await AIChatSessionService.fetchAndPersistMessages(session) + } } catch (error) { console.error("Failed to run test:", error) toast.error(t("tasks.toast.test_failed"), { diff --git a/apps/desktop/layer/renderer/src/modules/app-layout/ai-enhanced-timeline/AIEnhancedTimelineLayout.tsx b/apps/desktop/layer/renderer/src/modules/app-layout/ai-enhanced-timeline/AIEnhancedTimelineLayout.tsx index f2def5f70..a7fa27491 100644 --- a/apps/desktop/layer/renderer/src/modules/app-layout/ai-enhanced-timeline/AIEnhancedTimelineLayout.tsx +++ b/apps/desktop/layer/renderer/src/modules/app-layout/ai-enhanced-timeline/AIEnhancedTimelineLayout.tsx @@ -69,6 +69,7 @@ const AIEnhancedTimelineLayoutImpl = () => { const layoutContainerRef = useRef(null) const hasMountedRef = useRef(false) + // Delay the details column until the timeline width animation finishes const [shouldRenderDetailsColumn, setShouldRenderDetailsColumn] = useState(showEntryDetailsColumn) const feedColumnWidth = useUISettingKey("feedColWidth") @@ -158,7 +159,7 @@ const AIEnhancedTimelineLayoutImpl = () => { setAiPanelWidth(width) // Trigger layout update window.dispatchEvent(new Event("resize")) - }, [resolvePreferredWidth]) + }, [resolvePreferredWidth, setAiPanelWidth]) const handleTimelineTransitionEnd = useCallback( (event: TransitionEvent) => { @@ -174,15 +175,18 @@ const AIEnhancedTimelineLayoutImpl = () => { [showEntryDetailsColumn], ) + useEffect(() => { + if (!showEntryDetailsColumn) { + setShouldRenderDetailsColumn(false) + } + }, [showEntryDetailsColumn]) + useEffect(() => { if (!hasMountedRef.current) { hasMountedRef.current = true setShouldRenderDetailsColumn(showEntryDetailsColumn) return } - - // Defer rendering until the width transition signals completion - setShouldRenderDetailsColumn(false) }, [showEntryDetailsColumn]) return ( diff --git a/apps/desktop/layer/renderer/src/modules/app-layout/subview/SubviewLayout.tsx b/apps/desktop/layer/renderer/src/modules/app-layout/subview/SubviewLayout.tsx index fccf121e4..ca5e4ac39 100644 --- a/apps/desktop/layer/renderer/src/modules/app-layout/subview/SubviewLayout.tsx +++ b/apps/desktop/layer/renderer/src/modules/app-layout/subview/SubviewLayout.tsx @@ -1,13 +1,13 @@ import { getReadonlyRoute } from "@follow/components/atoms/route.js" import { useGlobalFocusableHasScope } from "@follow/components/common/Focusable/hooks.js" import { RootPortal } from "@follow/components/ui/portal/index.js" +import { LinearBlur } from "@follow/components/ui/progressive-blur/index.js" import { ScrollArea } from "@follow/components/ui/scroll-area/index.js" import { Routes } from "@follow/constants" import { ELECTRON_BUILD } from "@follow/shared/constants" import { springScrollTo } from "@follow/utils/scroller" import { clsx, cn, getOS } from "@follow/utils/utils" import { m } from "framer-motion" -import { LinearBlur } from "progressive-blur" import { isValidElement, useCallback, useEffect, useRef, useState } from "react" import { useHotkeys } from "react-hotkeys-hook" import { useTranslation } from "react-i18next" @@ -161,7 +161,7 @@ function SubviewLayoutInner() { {/* Enhanced Header with smooth transitions */}
diff --git a/apps/desktop/layer/renderer/src/modules/command/commands/entry.tsx b/apps/desktop/layer/renderer/src/modules/command/commands/entry.tsx index 51dce0851..3a02ef6a6 100644 --- a/apps/desktop/layer/renderer/src/modules/command/commands/entry.tsx +++ b/apps/desktop/layer/renderer/src/modules/command/commands/entry.tsx @@ -399,10 +399,6 @@ export const useRegisterEntryCommands = () => { icon: , category, run: () => { - if (role === UserRole.Free || role === UserRole.Trial) { - presentActivationModal() - return - } toggleShowAISummaryOnce() }, }, diff --git a/apps/desktop/layer/renderer/src/modules/discover/DiscoverInboxList.tsx b/apps/desktop/layer/renderer/src/modules/discover/DiscoverInboxList.tsx index a44089763..86df9214f 100644 --- a/apps/desktop/layer/renderer/src/modules/discover/DiscoverInboxList.tsx +++ b/apps/desktop/layer/renderer/src/modules/discover/DiscoverInboxList.tsx @@ -1,48 +1,17 @@ import { Button } from "@follow/components/ui/button/index.js" -import { UserRole } from "@follow/constants" -import { useUserRole } from "@follow/store/user/hooks" import { repository } from "@pkg" import { useTranslation } from "react-i18next" -import { useEventCallback } from "usehooks-ts" import { useModalStack } from "~/components/ui/modal/stacked/hooks" -import { CustomSafeError } from "~/errors/CustomSafeError" -import { useActivationModal } from "../activation" import { InboxTable } from "./Inbox" import { InboxForm } from "./InboxForm" -const useCanCreateMoreInboxAndNotify = () => { - const role = useUserRole() - const presentActivationModal = useActivationModal() - - return useEventCallback(() => { - if (role === UserRole.Free || role === UserRole.Trial) { - const can = false - if (!can) { - presentActivationModal() - - throw new CustomSafeError(`Trial user cannot create more inboxes`, true) - } - return can - } else { - // const can = currentInboxCount < MAX_INBOX_COUNT - // if (!can) { - // // TODO - // } - // return can - - return true - } - }) -} export function DiscoverInboxList() { const { t } = useTranslation() const { present } = useModalStack() - const preCheck = useCanCreateMoreInboxAndNotify() - return (
@@ -63,7 +32,6 @@ export function DiscoverInboxList() { + ) } diff --git a/apps/desktop/layer/renderer/src/modules/profile/update-password-form.tsx b/apps/desktop/layer/renderer/src/modules/profile/update-password-form.tsx index 76e2065ea..501688ed1 100644 --- a/apps/desktop/layer/renderer/src/modules/profile/update-password-form.tsx +++ b/apps/desktop/layer/renderer/src/modules/profile/update-password-form.tsx @@ -36,6 +36,8 @@ const updatePasswordFormSchema = z const UpdateExistingPasswordForm = () => { const { t } = useTranslation("settings") + const { t: tApp } = useTranslation("app") + const form = useForm>({ resolver: zodResolver(updatePasswordFormSchema), defaultValues: { @@ -119,7 +121,14 @@ const UpdateExistingPasswordForm = () => { )} /> -
+
+ + {tApp("login.forget_password.note")} + diff --git a/apps/desktop/layer/renderer/src/modules/settings/control.tsx b/apps/desktop/layer/renderer/src/modules/settings/control.tsx index 8f0ec2715..b3b2f4226 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/control.tsx +++ b/apps/desktop/layer/renderer/src/modules/settings/control.tsx @@ -4,11 +4,57 @@ import { Input, TextArea } from "@follow/components/ui/input/index.js" import { Label } from "@follow/components/ui/label/index.jsx" import { SegmentGroup, SegmentItem } from "@follow/components/ui/segment/index.jsx" import { Switch } from "@follow/components/ui/switch/index.jsx" +import { + Tooltip, + TooltipContent, + TooltipPortal, + TooltipTrigger, +} from "@follow/components/ui/tooltip/index.js" import { cn } from "@follow/utils/utils" import type { ChangeEventHandler, ReactNode } from "react" -import { useId, useState } from "react" +import { useCallback, useId, useState } from "react" +import { useTranslation } from "react-i18next" import { titleCase } from "title-case" +import { useIsPaymentEnabled } from "~/atoms/server-configs" + +import { SettingPaidLevels } from "./helper/setting-builder" +import { useSetSettingTab } from "./modal/context" + +export const PaidBadge: Component<{ + paidLevel: SettingPaidLevels +}> = ({ paidLevel }) => { + const { t } = useTranslation("settings") + const setTab = useSetSettingTab() + const isPaymentEnabled = useIsPaymentEnabled() + + const handleClick = useCallback( + (e) => { + e.preventDefault() + setTab("plan") + }, + [setTab], + ) + + if (!isPaymentEnabled) { + return null + } + + return ( + + + + + + + {paidLevel === SettingPaidLevels.FreeLimited && t("control.paid_badge.free_limited")} + {paidLevel === SettingPaidLevels.Plus && t("control.paid_badge.plus_or_higher")} + + + + ) +} + export const SettingCheckbox: Component<{ label: string checked: boolean @@ -32,15 +78,20 @@ export const SettingSwitch: Component<{ label: string checked: boolean onCheckedChange: (checked: boolean) => void -}> = ({ checked, label, onCheckedChange, className }) => { + disabled?: boolean + paidLevel?: SettingPaidLevels +}> = ({ checked, label, onCheckedChange, className, disabled, paidLevel }) => { const id = useId() const handleCheckedChange = (checked: boolean) => { onCheckedChange(checked) } return (
- - + +
) } diff --git a/apps/desktop/layer/renderer/src/modules/settings/helper/builder.ts b/apps/desktop/layer/renderer/src/modules/settings/helper/builder.ts index 67a8505e2..6fe933686 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/helper/builder.ts +++ b/apps/desktop/layer/renderer/src/modules/settings/helper/builder.ts @@ -1,10 +1,16 @@ +import type { SettingNamespace } from "@follow/shared/settings/constants" +import { getSettingPaidLevel } from "@follow/shared/settings/constants" import type { JSX } from "react/jsx-runtime" import type { SettingItem } from "./setting-builder" import { createSettingBuilder } from "./setting-builder" export const createDefineSettingItem = - (_getSetting: () => T, setSetting: (key: any, value: Partial) => void) => + ( + settingNamespace: SettingNamespace, + _getSetting: () => T, + setSetting: (key: any, value: Partial) => void, + ) => ( key: K, options: { @@ -13,9 +19,10 @@ export const createDefineSettingItem = onChange?: (value: T[K]) => void onAfterChange?: (value: T[K]) => void hide?: boolean - } & Omit, "onChange" | "description" | "label" | "hide" | "key">, + } & Omit, "onChange" | "description" | "label" | "hide" | "key" | "paidLevel">, ): any => { const { label, description, onChange, hide, onAfterChange, ...rest } = options + const paidLevel = getSettingPaidLevel(settingNamespace, String(key)) if (hide) return null return { @@ -31,16 +38,18 @@ export const createDefineSettingItem = } }, disabled: hide, + paidLevel, ...rest, } as SettingItem } export const createSetting = ( + settingNamespace: SettingNamespace, useSetting: () => T, setSetting: (key: any, value: Partial) => void, ) => { const SettingBuilder = createSettingBuilder(useSetting) - const defineSettingItem = createDefineSettingItem(useSetting, setSetting) + const defineSettingItem = createDefineSettingItem(settingNamespace, useSetting, setSetting) return { SettingBuilder, defineSettingItem, diff --git a/apps/desktop/layer/renderer/src/modules/settings/helper/setting-builder.tsx b/apps/desktop/layer/renderer/src/modules/settings/helper/setting-builder.tsx index 73fcf9214..14d79ae89 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/helper/setting-builder.tsx +++ b/apps/desktop/layer/renderer/src/modules/settings/helper/setting-builder.tsx @@ -1,4 +1,7 @@ /* eslint-disable @eslint-react/no-array-index-key */ +import { UserRole } from "@follow/constants" +import { SettingPaidLevels } from "@follow/shared/settings/constants" +import { useUserRole } from "@follow/store/user/hooks" import type { FC, ReactNode } from "react" import * as React from "react" import { isValidElement } from "react" @@ -6,6 +9,8 @@ import { isValidElement } from "react" import { SettingActionItem, SettingDescription, SettingInput, SettingSwitch } from "../control" import { SettingItemGroup, SettingSectionTitle } from "../section" +export { SettingPaidLevels } from "@follow/shared/settings/constants" + type SharedSettingItem = { disabled?: boolean } @@ -25,6 +30,7 @@ export type SettingItem = { className?: string [key: string]: any } + paidLevel?: SettingPaidLevels } & SharedSettingItem type SectionSettingItem = { @@ -54,6 +60,7 @@ export const createSettingBuilder = }) => { const { settings } = props const settingObject = useSetting() + const role = useUserRole() const filteredSettings = settings.filter((i) => !!i) return filteredSettings.map((setting, index) => { @@ -64,7 +71,7 @@ export const createSettingBuilder = const assertSetting = setting as SettingItem | SectionSettingItem | ActionSettingItem if (!assertSetting) return null - if (assertSetting.disabled) return null + // if (assertSetting.disabled) return null const nextItem = filteredSettings[index + 1] // If has no next item or next item is also a title, then it is an empty section @@ -90,6 +97,12 @@ export const createSettingBuilder = if ("type" in assertSetting && assertSetting.type === "title") { return null } + const disabledForRole = + role === UserRole.Free && + "paidLevel" in assertSetting && + assertSetting.paidLevel !== undefined && + assertSetting.paidLevel !== SettingPaidLevels.Free && + assertSetting.paidLevel !== SettingPaidLevels.FreeLimited let ControlElement: React.ReactNode @@ -110,6 +123,8 @@ export const createSettingBuilder = assertSetting.onChange(checked as T[keyof T]) }} label={assertSetting.label} + disabled={assertSetting.disabled || disabledForRole} + paidLevel={assertSetting.paidLevel} /> ) break diff --git a/apps/desktop/layer/renderer/src/modules/settings/modal/SettingModalContent.tsx b/apps/desktop/layer/renderer/src/modules/settings/modal/SettingModalContent.tsx index bd186f782..dfbc995af 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/modal/SettingModalContent.tsx +++ b/apps/desktop/layer/renderer/src/modules/settings/modal/SettingModalContent.tsx @@ -1,5 +1,5 @@ import { ScrollArea } from "@follow/components/ui/scroll-area/index.js" -import { cn } from "@follow/utils" +import { clsx, cn } from "@follow/utils" import { repository } from "@pkg" import type { FC } from "react" import { @@ -8,7 +8,6 @@ import { useDeferredValue, useEffect, useLayoutEffect, - useMemo, useRef, useState, } from "react" @@ -18,10 +17,11 @@ import { useLoaderData } from "react-router" import { ModalClose } from "~/components/ui/modal/stacked/components" import { SettingsTitle } from "~/modules/settings/title" -import { SettingSectionHighlightContext } from "../section" +import { useAvailableSettings } from "../hooks/use-setting-ctx" +import { SettingSectionHighlightIdContext } from "../section" import { getSettingPages } from "../settings-glob" import type { SettingPageConfig } from "../utils" -import { useSettingTab } from "./context" +import { SettingTabProvider, useSettingTab } from "./context" import { SettingModalLayout } from "./layout" export const SettingModalContent: FC<{ @@ -29,102 +29,95 @@ export const SettingModalContent: FC<{ initialSection?: string }> = ({ initialTab, initialSection }) => { const pages = getSettingPages() - const resolvedInitialTab = initialTab && initialTab in pages ? initialTab : undefined + + const availableSettings = useAvailableSettings() + + const resolvedInitialTab = + initialTab && initialTab in pages ? initialTab : availableSettings[0]!.path return ( - - - + + + + + ) } const Content: FC<{ - initialTab?: string - initialSection?: string -}> = ({ initialTab, initialSection }) => { + initialSection?: string | null +}> = ({ initialSection }) => { const key = useDeferredValue(useSettingTab() || "general") const pages = getSettingPages() const { Component, loader } = pages[key] + const [scrollerAtTop, setScrollerAtTop] = useState(true) const [scroller, setScroller] = useState(null) - const sectionRefs = useRef(new Map()) + const pendingSectionRef = useRef(initialSection ?? null) const hasAppliedInitialSectionRef = useRef(false) - const [highlightedSectionId, setHighlightedSectionId] = useState() useEffect(() => { pendingSectionRef.current = initialSection ?? null hasAppliedInitialSectionRef.current = false - setHighlightedSectionId(undefined) }, [initialSection]) useLayoutEffect(() => { if (scroller) { scroller.scrollTop = 0 } - }, [key]) + }, [key, scroller]) - const scrollToSection = useCallback((sectionId: string) => { - if (!sectionId) return false - const element = sectionRefs.current.get(sectionId) - if (!element) return false + useEffect(() => { + if (!scroller) return + const handler = () => { + setScrollerAtTop(scroller.scrollTop < 20) + } + scroller.addEventListener("scroll", handler) + return () => { + scroller.removeEventListener("scroll", handler) + } + }, [scroller]) - element.scrollIntoView({ - behavior: "smooth", - block: "start", - }) + const scrollToSection = useCallback( + (sectionId: string) => { + if (!sectionId) return false + if (!scroller) return false + const element = scroller.querySelector(`[data-setting-section="${sectionId}"]`) as HTMLElement + if (!element) return false - setHighlightedSectionId(sectionId) + const elementTop = element.offsetTop + const scrollerTop = scroller.scrollTop + const delta = elementTop - scrollerTop - return true - }, []) + scroller.scrollTo({ + top: delta, + behavior: "smooth", + }) - const registerSection = useCallback( - (sectionId: string, element: HTMLElement | null) => { - if (!sectionId) return - if (element) { - sectionRefs.current.set(sectionId, element) - if (pendingSectionRef.current === sectionId) { - const handled = scrollToSection(sectionId) - if (handled) { - pendingSectionRef.current = null - hasAppliedInitialSectionRef.current = true - } - } - } else { - sectionRefs.current.delete(sectionId) - } + return true }, - [scrollToSection], + [scroller], ) useEffect(() => { - if (!initialSection || hasAppliedInitialSectionRef.current) return - if (initialTab && key !== initialTab) return - - const handled = scrollToSection(initialSection) - if (handled) { - hasAppliedInitialSectionRef.current = true - pendingSectionRef.current = null - } else { - pendingSectionRef.current = initialSection + if (initialSection) { + scrollToSection(initialSection) } - }, [initialSection, initialTab, key, scrollToSection]) - - const highlightContextValue = useMemo( - () => ({ - highlightedSectionId: highlightedSectionId ?? undefined, - registerSection, - }), - [highlightedSectionId, registerSection], - ) + }, [initialSection, scrollToSection]) const config = (useLoaderData() || loader || {}) as SettingPageConfig if (!Component) return null return ( - + - + - +

diff --git a/apps/desktop/layer/renderer/src/modules/settings/modal/context.tsx b/apps/desktop/layer/renderer/src/modules/settings/modal/context.tsx index be75864a1..34720df0d 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/modal/context.tsx +++ b/apps/desktop/layer/renderer/src/modules/settings/modal/context.tsx @@ -1,12 +1,37 @@ import type { PrimitiveAtom } from "jotai" import { atom } from "jotai" -import { createContext } from "react" +import { createContext, use, useMemo } from "react" import { createAtomHooks } from "~/lib/jotai" -export const [, , useSettingTab, useSetSettingTab, getSettingTab, setSettingTab] = createAtomHooks( - atom(""), -) +const SettingTabContext = createContext>>(null!) +export const SettingTabProvider = ({ + children, + initialTab, +}: { + children: React.ReactNode + initialTab?: string +}) => { + const ctxValue = useMemo(() => { + return createAtomHooks(atom(initialTab ?? "")) + }, []) + return {children} +} + +const useSettingTabContext = () => { + const ctx = use(SettingTabContext) + if (!ctx) { + throw new Error("SettingTabContext not found") + } + return ctx +} +export const useSettingTab = () => { + return useSettingTabContext()[2]() +} + +export const useSetSettingTab = () => { + return useSettingTabContext()[3]() +} export const SettingModalContentPortalableContext = createContext>( atom(null as any), diff --git a/apps/desktop/layer/renderer/src/modules/settings/modal/layout.tsx b/apps/desktop/layer/renderer/src/modules/settings/modal/layout.tsx index f4e6e785e..6cc8691b6 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/modal/layout.tsx +++ b/apps/desktop/layer/renderer/src/modules/settings/modal/layout.tsx @@ -9,7 +9,7 @@ import { atom, useAtomValue, useSetAtom } from "jotai" import type { BoundingBox } from "motion/react" import { Resizable } from "re-resizable" import type { PropsWithChildren } from "react" -import { memo, Suspense, use, useCallback, useEffect, useMemo, useRef } from "react" +import { memo, Suspense, use, useCallback, useMemo, useRef } from "react" import { createPortal } from "react-dom" import { useUISettingSelector } from "~/atoms/settings/ui" @@ -29,14 +29,9 @@ import { DisableWhy } from "../utils" import { SettingModalContentPortalableContext, useSetSettingTab, useSettingTab } from "./context" import { defaultCtx, SettingContext } from "./hooks" -export function SettingModalLayout( - props: PropsWithChildren<{ - initialTab?: string - }>, -) { - const { children, initialTab } = props - const setTab = useSetSettingTab() - const tab = useSettingTab() +export function SettingModalLayout(props: PropsWithChildren) { + const { children } = props + const elementRef = useRef(null) const edgeElementRef = useRef(null) const { @@ -53,17 +48,6 @@ export function SettingModalLayout( draggable: true, }) - const availableSettings = useAvailableSettings() - useEffect(() => { - if (!tab) { - if (initialTab) { - setTab(initialTab) - } else { - setTab(availableSettings[0]!.path) - } - } - }, [availableSettings]) - const { draggable, overlay } = useUISettingSelector((state) => ({ draggable: state.modalDraggable, overlay: state.modalOverlay, diff --git a/apps/desktop/layer/renderer/src/modules/settings/section.tsx b/apps/desktop/layer/renderer/src/modules/settings/section.tsx index e48714312..6d6eb6303 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/section.tsx +++ b/apps/desktop/layer/renderer/src/modules/settings/section.tsx @@ -9,13 +9,7 @@ import { titleCase } from "title-case" import { SettingActionItem, SettingDescription, SettingSwitch } from "./control" -type SettingSectionHighlightContextValue = { - highlightedSectionId?: string - registerSection: (sectionId: string, element: HTMLElement | null) => void -} - -export const SettingSectionHighlightContext = - createContext(null) +export const SettingSectionHighlightIdContext = createContext(null) export const SettingSectionTitle: FC<{ title: string | ReactNode @@ -23,32 +17,59 @@ export const SettingSectionTitle: FC<{ margin?: "compact" | "normal" sectionId?: string }> = ({ title, margin, className, sectionId }) => { - const highlightCtx = use(SettingSectionHighlightContext) + const highlightedSectionId = use(SettingSectionHighlightIdContext) const elementRef = useRef(null) + const isHighlighted = !!sectionId && highlightedSectionId === sectionId && !!elementRef.current + useEffect(() => { - if (!sectionId || !highlightCtx) return - highlightCtx.registerSection(sectionId, elementRef.current) - return () => { - highlightCtx.registerSection(sectionId, null) + if (!isHighlighted) { + return } - }, [highlightCtx, sectionId]) - const isHighlighted = - !!sectionId && highlightCtx?.highlightedSectionId === sectionId && !!elementRef.current + let rollingAnimation: Animation | null = null + const timer = setTimeout(() => { + const highlightedElement = elementRef.current?.querySelector( + "[data-highlighted-element]", + ) as HTMLElement + if (!highlightedElement) { + clearTimeout(timer) + return + } + const keyframeEffect = new KeyframeEffect( + highlightedElement, + [ + { + backgroundColor: "color-mix(in srgb, hsl(var(--fo-a)) 33%, hsl(var(--background)) 67%)", + }, + { backgroundColor: "transparent" }, + ], + { + duration: 1000, + easing: "ease-in-out", + }, + ) + rollingAnimation = new Animation(keyframeEffect, document.timeline) + rollingAnimation.play() + }, 500) + return () => { + rollingAnimation?.cancel() + clearTimeout(timer) + } + }, [isHighlighted]) return (

+ {isHighlighted &&
} {typeof title === "string" ? titleCase(title) : title}
) diff --git a/apps/desktop/layer/renderer/src/modules/settings/tabs/ai.tsx b/apps/desktop/layer/renderer/src/modules/settings/tabs/ai.tsx index d7010c514..8fb7a22ed 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/tabs/ai.tsx +++ b/apps/desktop/layer/renderer/src/modules/settings/tabs/ai.tsx @@ -14,7 +14,7 @@ import { TaskSchedulingSection } from "./ai/tasks" import { UsageAnalysisSection } from "./ai/usage" const SettingBuilder = createSettingBuilder(useAISettingValue) -const defineSettingItem = createDefineSettingItem(useAISettingValue, setAISetting) +const defineSettingItem = createDefineSettingItem("ai", useAISettingValue, setAISetting) export const AI_SETTING_SECTION_IDS = { shortcuts: "settings-ai-shortcuts", diff --git a/apps/desktop/layer/renderer/src/modules/settings/tabs/ai/tasks/TaskSchedulingSection.tsx b/apps/desktop/layer/renderer/src/modules/settings/tabs/ai/tasks/TaskSchedulingSection.tsx index 444487e1d..ef5d654dd 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/tabs/ai/tasks/TaskSchedulingSection.tsx +++ b/apps/desktop/layer/renderer/src/modules/settings/tabs/ai/tasks/TaskSchedulingSection.tsx @@ -34,6 +34,7 @@ export const TaskSchedulingSection = () => { size={"sm"} variant={"outline"} onClick={handleCreateTask} + buttonClassName="!-translate-y-7" > {t("tasks.actions.new_task")} diff --git a/apps/desktop/layer/renderer/src/modules/settings/tabs/ai/usage/UsageAnalysisSection.tsx b/apps/desktop/layer/renderer/src/modules/settings/tabs/ai/usage/UsageAnalysisSection.tsx index 4dad28c3f..73e406ce3 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/tabs/ai/usage/UsageAnalysisSection.tsx +++ b/apps/desktop/layer/renderer/src/modules/settings/tabs/ai/usage/UsageAnalysisSection.tsx @@ -5,7 +5,7 @@ import { useModalStack } from "~/components/ui/modal/stacked/hooks" import { useAIConfiguration } from "~/modules/ai-chat/hooks/useAIConfiguration" import { DetailedUsageModal, UsageProgressRing, UsageWarningBanner } from "./components" -import { formatTimeRemaining, formatTokenCountString } from "./utils" +import { formatTokenCountString } from "./utils" export const UsageAnalysisSection = () => { const { t } = useTranslation("ai") @@ -48,11 +48,6 @@ export const UsageAnalysisSection = () => {
{formatTokenCountString(usage.used)} / {formatTokenCountString(usage.total)} used
- -
- {t("usage_analysis.resets_in")}{" "} - {formatTimeRemaining(rateLimit.windowResetTime - Date.now())} -
- -
+ setBillingPeriod(value as "monthly" | "yearly")} + > + + + Yearly + {averageSavings > 0 && ( + Save {averageSavings}% + )} + + } + /> +
{/* Plans Grid */}
- {PLAN_CONFIGS.map((plan) => ( + {plans.map((plan) => ( ))}
+ + {/* Comparison Table */} + ) } // Reusable PlanCard Component interface PlanCardProps { - plan: Plan + plan: PaymentPlan billingPeriod: "monthly" | "yearly" - currentUserRole: UserRole | null isCurrentPlan: boolean - daysLeft: number | null + currentTier: number } -const PlanCard = ({ - plan, - billingPeriod, - currentUserRole, - isCurrentPlan, - daysLeft, -}: PlanCardProps) => { - const getPlanActionType = (): "current" | "upgrade" | "coming-soon" | "in-trial" | null => { +const PlanCard = ({ plan, billingPeriod, isCurrentPlan, currentTier }: PlanCardProps) => { + const { t } = useTranslation("settings") + const getPlanActionType = (): + | "current" + | "upgrade" + | "coming-soon" + | "in-trial" + | "switch" + | null => { if (plan.isComingSoon) return "coming-soon" - - if (!currentUserRole) { - return plan.tier > PLAN_TIER_MAP[UserRole.Free] ? "upgrade" : "current" - } - - const currentTier = PLAN_TIER_MAP[currentUserRole] - const targetTier = plan.tier - - if (currentTier === targetTier) { - // if (currentUserRole === UserRole.PreProTrial) { - // return "in-trial" - // } else { - // return "current" + switch (true) { + case isCurrentPlan: { + return "current" + } + case plan.tier > currentTier && !!plan.planID: { + return "upgrade" + } + // case plan.tier < currentTier && !!plan.planID: { + // return "switch" // } - return "current" + default: { + return null + } } - if (targetTier > currentTier) return "upgrade" - return null } const actionType = getPlanActionType() const upgradePlanMutation = useUpgradePlan({ - plan: "folo pro", + plan: plan.planID, annual: billingPeriod === "yearly", }) const cancelPlanMutation = useCancelPlan() // Calculate price and period based on billing period - const price = billingPeriod === "yearly" ? plan.yearlyPrice : plan.monthlyPrice - const formattedPrice = price === 0 ? "$0" : `$${price}` - const period = plan.role === UserRole.Free ? "" : billingPeriod === "yearly" ? "year" : "month" + const regularPrice = + billingPeriod === "yearly" ? plan.priceInDollarsAnnual / 12 : plan.priceInDollars + const discountPrice = + billingPeriod === "yearly" + ? (plan.priceInDollarsInDiscountAnnual || 0) / 12 + : plan.priceInDollarsInDiscount + const period = plan.role === UserRole.Free ? "" : "month" - // Calculate savings for yearly plan - const yearlyTotalPrice = plan.yearlyPrice - const monthlyTotalPrice = plan.monthlyPrice * 12 - const savingsPercentage = - plan.monthlyPrice > 0 && plan.yearlyPrice > 0 - ? Math.round(((monthlyTotalPrice - yearlyTotalPrice) / monthlyTotalPrice) * 100) - : 0 + // Calculate discount percentage from prices + const hasDiscount = + discountPrice && + discountPrice > 0 && + discountPrice < regularPrice && + discountPrice !== regularPrice + + // Use discount price if available, otherwise use regular price + const finalPrice = hasDiscount ? discountPrice : regularPrice + const regularPriceForStrike = hasDiscount && regularPrice > 0 ? regularPrice : undefined + + // Calculate discount percentage + const discountPercentage = hasDiscount + ? Math.round(((regularPrice - discountPrice) / regularPrice) * 100) + : 0 + + // Create discount description + const discountDescription = + hasDiscount && discountPercentage > 0 + ? `Early bird discount, ${discountPercentage}% off` + : undefined + + // Get plan description from i18n + const planDescriptionKey = `plan.descriptions.${plan.role}` as const + const planDescription = t(planDescriptionKey, { defaultValue: "" }) return (
-
-
- - -
-
+
+ { cancelPlanMutation.mutate() } @@ -299,8 +293,10 @@ const PlanCard = ({ />
- {/* Subtle gradient line at bottom */} -
+ {/* Subtle bottom accent line */} + {actionType === "upgrade" && ( +
+ )}
) } @@ -310,7 +306,7 @@ const PlanBadges = ({ isPopular }: { isPopular: boolean }) => ( <> {isPopular && (
-
+
Most Popular
@@ -321,108 +317,107 @@ const PlanBadges = ({ isPopular }: { isPopular: boolean }) => ( const PlanHeader = ({ title, price, + regularPrice, period, - billingPeriod, - monthlyPrice, - yearlyPrice, - savingsPercentage, + description, + discountDescription, }: { title: string - price: string + price: number + regularPrice?: number period: string - billingPeriod: "monthly" | "yearly" - monthlyPrice: number - yearlyPrice: number - savingsPercentage: number + description?: string + discountDescription?: string }) => ( -
-

{title}

-
- {price} - {period && /{period}} -
-
- {billingPeriod === "yearly" && - monthlyPrice > 0 && - yearlyPrice > 0 && - savingsPercentage > 0 && ( -
- - ${(monthlyPrice * 12).toFixed(0)}/year - - Save {savingsPercentage}% -
+
+

{title}

+
+
+ + {period && /{period}} + + {typeof regularPrice === "number" && regularPrice > 0 && ( + + + )} - {billingPeriod === "yearly" && monthlyPrice > 0 && yearlyPrice > 0 && ( -
- ${(yearlyPrice / 12).toFixed(1)}/month billed annually +
+ {typeof regularPrice === "number" && regularPrice > 0 && ( +
+ {discountDescription && ( + + {discountDescription} + + )}
)}
-
-) - -const PlanFeatures = ({ features }: { features: string[] }) => ( -
- {features.map((feature) => ( -
-
- -
- {feature} -
- ))} + {description &&

{description}

}
) const PlanAction = ({ - isPopular, actionType, onSelect, onCancel, isLoading, - daysLeft, }: { - isPopular: boolean - actionType: "current" | "upgrade" | "coming-soon" | "in-trial" | null + actionType: "current" | "upgrade" | "coming-soon" | "in-trial" | "switch" | null onSelect?: () => void onCancel?: () => void isLoading?: boolean - daysLeft: number | null }) => { const getButtonConfig = () => { switch (actionType) { case "coming-soon": { return { text: "Coming Soon", + icon: "i-mgc-time-cute-re", variant: "outline" as const, - className: "w-full h-9 @md:h-10 text-xs @md:text-sm", disabled: true, } } case "current": { return { - text: typeof daysLeft === "number" ? `${daysLeft} days left` : "Current Plan", + text: `Current Plan${onCancel ? " | Cancel" : ""}`, + icon: undefined, variant: "outline" as const, - className: "w-full h-9 @md:h-10 text-xs @md:text-sm text-text-secondary", - disabled: true, + className: onCancel ? "" : "text-text-secondary", + disabled: onCancel ? false : true, } } case "in-trial": { return { - text: `In Trial (${daysLeft} days left)`, + text: "In Trial", + icon: "i-mgc-stopwatch-cute-re", variant: "outline" as const, - className: "w-full h-9 @md:h-10 text-xs @md:text-sm", disabled: false, } } case "upgrade": { return { text: "Upgrade", - variant: isPopular ? undefined : ("outline" as const), - className: isPopular - ? "w-full h-9 @md:h-10 text-xs @md:text-sm bg-gradient-to-r from-accent to-accent/80 hover:from-accent/90 hover:to-accent/70" - : "w-full h-9 @md:h-10 text-xs @md:text-sm", + icon: "i-mgc-arrow-up-cute-re", + className: + "bg-gradient-to-r from-accent to-accent/90 text-white hover:from-accent/95 hover:to-accent/85", + disabled: false, + } + } + case "switch": { + return { + text: "Switch Plan", + icon: "i-mgc-transfer-cute-re", + className: + "bg-gradient-to-r from-accent to-accent/90 text-white font-semibold hover:from-accent/95 hover:to-accent/85", disabled: false, } } @@ -439,27 +434,98 @@ const PlanAction = ({ } return ( -
- - - {actionType === "current" && typeof daysLeft === "number" && onCancel && ( - + + ) +} + +const PlanComparisonTable = ({ plans }: { plans: PaymentPlan[] }) => { + const { t } = useTranslation("settings") + + // Get all unique feature keys + const allFeatureKeys = Array.from( + new Set(plans.flatMap((plan) => Object.keys(plan.limit))), + ) as (keyof PaymentFeature)[] + + // Filter out features that are all false/0/null + const visibleFeatureKeys = allFeatureKeys.filter((key) => + plans.some((plan) => { + const value = plan.limit[key] + if (value == null) return false + if (typeof value === "boolean" && !value) return false + if (typeof value === "number" && value === 0) return false + return true + }), + ) + + return ( +
+
+ + + + + {plans.map((plan) => ( + + ))} + + + + {visibleFeatureKeys.map((featureKey, index) => ( + + + {plans.map((plan) => { + const value = plan.limit[featureKey] + const formattedValue = formatFeatureValue(featureKey, value) + + return ( + + ) + })} + + ))} + +
+ Features + + {plan.name} +
+ {t(`plan.features.${featureKey}` as any)} + + + {formattedValue} + +
+
) } diff --git a/apps/desktop/layer/renderer/src/modules/shared/ViewSelectorRadioGroup.tsx b/apps/desktop/layer/renderer/src/modules/shared/ViewSelectorRadioGroup.tsx index 4baf5310f..f8e560f4e 100644 --- a/apps/desktop/layer/renderer/src/modules/shared/ViewSelectorRadioGroup.tsx +++ b/apps/desktop/layer/renderer/src/modules/shared/ViewSelectorRadioGroup.tsx @@ -42,7 +42,7 @@ export const ViewSelectorRadioGroup = ({ return ( - + {configuredViews.map((view) => (
= memo((props) => { const navigate = useNavigate() const role = useUserRole() - const presentActivationModal = useActivationModal() const isInMASReview = useIsInMASReview() if (status === "unauthenticated") { @@ -83,7 +80,7 @@ export const ProfileButton: FC = memo((props) => { {user?.name} - {serverConfig?.REFERRAL_ENABLED ? ( + {!isInMASReview && serverConfig?.PAYMENT_ENABLED ? ( = memo((props) => { { - if (role !== UserRole.Trial && role !== UserRole.Free) { - presentAchievement() - } else { - presentActivationModal() - } + presentAchievement() }} icon={} > {t("user_button.achievement")} - {!isInMASReview && ( + {!isInMASReview && serverConfig?.PAYMENT_ENABLED && ( { - navigate("/power") + settingModalPresent("plan") }} icon={} > - {t("user_button.power")} + {t("activation.plan.title")} )} diff --git a/apps/desktop/layer/renderer/src/modules/user/UserAvatar.tsx b/apps/desktop/layer/renderer/src/modules/user/UserAvatar.tsx index 0a237a67a..f1da1458c 100644 --- a/apps/desktop/layer/renderer/src/modules/user/UserAvatar.tsx +++ b/apps/desktop/layer/renderer/src/modules/user/UserAvatar.tsx @@ -82,7 +82,7 @@ export const UserAvatar = ({ {renderUserData?.name?.[0]} - {serverConfig?.REFERRAL_ENABLED && + {serverConfig?.PAYMENT_ENABLED && !userId && role !== UserRole.Free && role !== UserRole.Trial && ( diff --git a/apps/desktop/layer/renderer/src/modules/user/UserProBadge.tsx b/apps/desktop/layer/renderer/src/modules/user/UserProBadge.tsx index 09f07617e..4a3a8684e 100644 --- a/apps/desktop/layer/renderer/src/modules/user/UserProBadge.tsx +++ b/apps/desktop/layer/renderer/src/modules/user/UserProBadge.tsx @@ -27,7 +27,7 @@ export const UserProBadge = ({ )} onClick={onClick} > - + {withText && {UserRoleName[role]}}
) diff --git a/apps/desktop/layer/renderer/src/pages/(main)/(layer)/(ai)/ai/index.tsx b/apps/desktop/layer/renderer/src/pages/(main)/(layer)/(ai)/ai/index.tsx index 731c21b1e..1b85bbcc7 100644 --- a/apps/desktop/layer/renderer/src/pages/(main)/(layer)/(ai)/ai/index.tsx +++ b/apps/desktop/layer/renderer/src/pages/(main)/(layer)/(ai)/ai/index.tsx @@ -1,3 +1,5 @@ +import { cn } from "@follow/utils" + import { AIChatRoot } from "~/modules/ai-chat/components/layouts/AIChatRoot" import { ChatPageHeader } from "~/modules/ai-chat/components/layouts/ChatHeader" import { ChatInterface } from "~/modules/ai-chat/components/layouts/ChatInterface" @@ -5,12 +7,15 @@ import { ChatInterface } from "~/modules/ai-chat/components/layouts/ChatInterfac export const Component = () => { return (
- +
) diff --git a/apps/desktop/layer/renderer/src/pages/(main)/(layer)/(subview)/discover/index.tsx b/apps/desktop/layer/renderer/src/pages/(main)/(layer)/(subview)/discover/index.tsx index 436a092ad..61b5df46c 100644 --- a/apps/desktop/layer/renderer/src/pages/(main)/(layer)/(subview)/discover/index.tsx +++ b/apps/desktop/layer/renderer/src/pages/(main)/(layer)/(subview)/discover/index.tsx @@ -2,16 +2,12 @@ import { Divider } from "@follow/components/ui/divider/Divider.js" import { useScrollElementUpdate } from "@follow/components/ui/scroll-area/hooks.js" import { ScrollArea } from "@follow/components/ui/scroll-area/index.js" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@follow/components/ui/tabs/index.jsx" -import { UserRole } from "@follow/constants" -import { useUserRole } from "@follow/store/user/hooks" -import { cn } from "@follow/utils/utils" import { createElement } from "react" import { useTranslation } from "react-i18next" import { useSearchParams } from "react-router" import { AppErrorBoundary } from "~/components/common/AppErrorBoundary" import { ErrorComponentType } from "~/components/errors/enum" -import { useActivationModal } from "~/modules/activation" import { useSubViewTitle } from "~/modules/app-layout/subview/hooks" import { DiscoverForm } from "~/modules/discover/DiscoverForm" import { DiscoverImport } from "~/modules/discover/DiscoverImport" @@ -24,7 +20,6 @@ import { Trending } from "~/modules/trending" const tabs: { name: I18nKeys value: string - disableForTrial?: boolean }[] = [ { name: "words.search", @@ -41,7 +36,6 @@ const tabs: { { name: "words.inbox", value: "inbox", - disableForTrial: true, }, { name: "words.user", @@ -62,18 +56,8 @@ export function Component() { const { t } = useTranslation() useSubViewTitle("words.discover") - const presentActivationModal = useActivationModal() - const role = useUserRole() const { onUpdateMaxScroll } = useScrollElementUpdate() - const currentTabs = tabs.map((tab) => { - const disabled = tab.disableForTrial && (role === UserRole.Free || role === UserRole.Trial) - return { - ...tab, - disabled, - } - }) - return (
{/* Simple Header */} @@ -100,17 +84,12 @@ export function Component() {
- {currentTabs.map((tab) => ( + {tabs.map((tab) => ( { - if (tab.disabled) { - presentActivationModal() - } else { - onUpdateMaxScroll?.() - } + onUpdateMaxScroll?.() }} > {t(tab.name)} @@ -122,7 +101,7 @@ export function Component() { {/* Tab Content */}
- {currentTabs.map((tab) => ( + {tabs.map((tab) => (
{createElement(TabComponent[tab.value]! || TabComponent.default, { diff --git a/apps/desktop/layer/renderer/src/pages/(main)/index.sync.tsx b/apps/desktop/layer/renderer/src/pages/(main)/index.sync.tsx index 649e197b4..235aa1da5 100644 --- a/apps/desktop/layer/renderer/src/pages/(main)/index.sync.tsx +++ b/apps/desktop/layer/renderer/src/pages/(main)/index.sync.tsx @@ -1,11 +1,34 @@ +import { FeedViewType } from "@follow/constants" +import { useSubscriptionStore } from "@follow/store/subscription/store" import { redirect } from "react-router" +import { getUISettings } from "~/atoms/settings/ui" import { ROUTE_ENTRY_PENDING, ROUTE_FEED_PENDING, ROUTE_VIEW_ALL } from "~/constants" +import { computeTimelineTabLists } from "~/hooks/biz/useTimelineList" export function Component() { return null } export const loader = () => { - return redirect(`/timeline/${ROUTE_VIEW_ALL}/${ROUTE_FEED_PENDING}/${ROUTE_ENTRY_PENDING}`) + const uiSettings = getUISettings() + const subscriptionState = useSubscriptionStore.getState() + + const hasAudiosSubscription = + subscriptionState.feedIdByView[FeedViewType.Audios].size > 0 || + subscriptionState.listIdByView[FeedViewType.Audios].size > 0 + + const hasNotificationsSubscription = + subscriptionState.feedIdByView[FeedViewType.Notifications].size > 0 || + subscriptionState.listIdByView[FeedViewType.Notifications].size > 0 + + const { visible } = computeTimelineTabLists({ + timelineTabs: uiSettings.timelineTabs, + hasAudiosSubscription, + hasNotificationsSubscription, + }) + + const firstTimeline = visible[0] ?? ROUTE_VIEW_ALL + + return redirect(`/timeline/${firstTimeline}/${ROUTE_FEED_PENDING}/${ROUTE_ENTRY_PENDING}`) } diff --git a/apps/desktop/layer/renderer/src/pages/settings/(settings)/list.tsx b/apps/desktop/layer/renderer/src/pages/settings/(settings)/list.tsx index 54c9fee64..87dcda6a7 100644 --- a/apps/desktop/layer/renderer/src/pages/settings/(settings)/list.tsx +++ b/apps/desktop/layer/renderer/src/pages/settings/(settings)/list.tsx @@ -1,8 +1,6 @@ -import { UserRole } from "@follow/constants" - import { SettingLists } from "~/modules/settings/tabs/lists" import { SettingsTitle } from "~/modules/settings/title" -import { defineSettingPageData, DisableWhy } from "~/modules/settings/utils" +import { defineSettingPageData } from "~/modules/settings/utils" const iconName = "i-mgc-rada-cute-re" const priority = (1000 << 2) + 10 @@ -11,10 +9,6 @@ export const loader = defineSettingPageData({ icon: iconName, name: "titles.lists", priority, - disableIf: (ctx) => [ - ctx.role === UserRole.Free || ctx.role === UserRole.Trial, - DisableWhy.NotActivation, - ], hideIf: (ctx) => ctx.isInMASReview, }) diff --git a/apps/desktop/layer/renderer/src/pages/settings/(settings)/notifications.tsx b/apps/desktop/layer/renderer/src/pages/settings/(settings)/notifications.tsx index 2cc901417..3d202519e 100644 --- a/apps/desktop/layer/renderer/src/pages/settings/(settings)/notifications.tsx +++ b/apps/desktop/layer/renderer/src/pages/settings/(settings)/notifications.tsx @@ -1,8 +1,6 @@ -import { UserRole } from "@follow/constants" - import { SettingNotifications } from "~/modules/settings/tabs/notifications" import { SettingsTitle } from "~/modules/settings/title" -import { defineSettingPageData, DisableWhy } from "~/modules/settings/utils" +import { defineSettingPageData } from "~/modules/settings/utils" const iconName = "i-mgc-notification-cute-re" const priority = (1000 << 1) + 50 @@ -11,10 +9,6 @@ export const loader = defineSettingPageData({ icon: iconName, name: "titles.notifications", priority, - disableIf: (ctx) => [ - ctx.role === UserRole.Free || ctx.role === UserRole.Trial, - DisableWhy.NotActivation, - ], }) export function Component() { diff --git a/apps/desktop/layer/renderer/src/pages/settings/(settings)/plan.tsx b/apps/desktop/layer/renderer/src/pages/settings/(settings)/plan.tsx index 4493c4b13..405ff286e 100644 --- a/apps/desktop/layer/renderer/src/pages/settings/(settings)/plan.tsx +++ b/apps/desktop/layer/renderer/src/pages/settings/(settings)/plan.tsx @@ -3,14 +3,14 @@ import { SettingsTitle } from "~/modules/settings/title" import { defineSettingPageData } from "~/modules/settings/utils" const iconName = "i-mgc-power-outline" -const priority = (1000 << 2) + 30 +const priority = (1000 << 1) + 17 export const loader = defineSettingPageData({ icon: iconName, name: "titles.plan.short", title: "titles.plan.long", priority, - hideIf: (ctx, serverConfigs) => ctx.isInMASReview || !serverConfigs?.REFERRAL_ENABLED, + hideIf: (ctx, serverConfigs) => ctx.isInMASReview || !serverConfigs?.PAYMENT_ENABLED, }) export function Component() { diff --git a/apps/desktop/layer/renderer/src/providers/user-provider.tsx b/apps/desktop/layer/renderer/src/providers/user-provider.tsx index d2cba04f9..0cbb7079d 100644 --- a/apps/desktop/layer/renderer/src/providers/user-provider.tsx +++ b/apps/desktop/layer/renderer/src/providers/user-provider.tsx @@ -1,67 +1,16 @@ -import { UserRole, UserRoleName } from "@follow/constants" -import { getStorageNS } from "@follow/utils/ns" -import { useEffect, useMemo } from "react" -import { toast } from "sonner" +import { useEffect } from "react" import { setIntegrationIdentify } from "~/initialize/helper" -import { useSettingModal } from "~/modules/settings/modal/useSettingModal" import { useSession } from "~/queries/auth" export const UserProvider = () => { const { session } = useSession() - const settingModalPresent = useSettingModal() - useEffect(() => { if (!session?.user) return setIntegrationIdentify(session.user) }, [session?.user]) - const roleEndDate = useMemo( - () => - session?.roleEndAt - ? typeof session.roleEndAt === "string" - ? new Date(session.roleEndAt) - : session.roleEndAt - : undefined, - [session?.roleEndAt], - ) - useEffect(() => { - if (!session?.role) return - - const itemKey = getStorageNS("pro-preview-toast-dismissed") - - const isToastDismissed = localStorage.getItem(itemKey) - - const sessionRole = session.role as string - - if (sessionRole && sessionRole !== UserRole.Pro && !isToastDismissed) { - const message = - sessionRole === UserRole.Free || sessionRole === UserRole.Trial - ? `You are currently on the ${UserRoleName[UserRole.Free]} plan. Some features may be limited.` - : sessionRole === UserRole.PreProTrial - ? `You are currently on the ${UserRoleName[UserRole.PreProTrial]} plan.${roleEndDate ? ` It will end on ${roleEndDate.toLocaleDateString()}.` : ""}` - : "" - if (!message) { - localStorage.setItem(itemKey, "true") - return - } - toast.warning(message, { - duration: Number.POSITIVE_INFINITY, - action: { - label: "More", - onClick: () => { - settingModalPresent("plan") - localStorage.setItem(itemKey, "true") - }, - }, - onDismiss: () => { - localStorage.setItem(itemKey, "true") - }, - }) - } - }, [roleEndDate, session?.role, settingModalPresent]) - return null } diff --git a/apps/desktop/package.json b/apps/desktop/package.json index e4a453eb5..8ab2969eb 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "Folo", "type": "module", - "version": "0.9.0", + "version": "1.0.0", "private": true, "description": "Follow everything in one place", "author": "Folo Team", @@ -87,5 +87,5 @@ "vite-tsconfig-paths": "5.1.4" }, "productName": "Folo", - "mainHash": "823542ad4a3ce980cca614cb0cb5c928d00a3f44e955ffa162e9ddf071a0dfb0" + "mainHash": "f1dfc9d28134209d9561f5da2f735250b7c20d9e9759d0f7bc982b0790ad89f5" } diff --git a/apps/desktop/tailwind.config.ts b/apps/desktop/tailwind.config.ts index 02758b5ae..68c2b45c3 100644 --- a/apps/desktop/tailwind.config.ts +++ b/apps/desktop/tailwind.config.ts @@ -50,6 +50,7 @@ export default extendConfig({ // 2 + 0.625 * 2 = 3.25 "top-header": "3.25rem", "top-header-with-border-b": "calc(3.25rem + 1px)", + "top-header-in-preview-with-border-b": "calc(3.25rem + 41px)", }, colors: { sidebar: "hsl(var(--fo-sidebar) / )", diff --git a/apps/desktop/vite.config.ts b/apps/desktop/vite.config.ts index ba9476390..4439905f3 100644 --- a/apps/desktop/vite.config.ts +++ b/apps/desktop/vite.config.ts @@ -36,7 +36,7 @@ const devPrint = (): PluginOption => ({ ) console.info( ` ${green("➜")} ${dim("Development debug")}: ${cyan( - "https://dev.follow.is/__debug_proxy", + "https://dev.folo.is/__debug_proxy", )}`, ) } diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 0822fd8fa..1133aa751 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -21,6 +21,7 @@ "@better-auth/expo": "1.3.28", "@expo/metro-runtime": "5.0.4", "@expo/react-native-action-sheet": "4.1.1", + "@follow-app/client-sdk": "catalog:", "@follow/components": "workspace:*", "@follow/constants": "workspace:*", "@follow/database": "workspace:*", diff --git a/apps/mobile/src/lib/error-parser.ts b/apps/mobile/src/lib/error-parser.ts index aa06abfc8..d4f09a9cf 100644 --- a/apps/mobile/src/lib/error-parser.ts +++ b/apps/mobile/src/lib/error-parser.ts @@ -1,3 +1,4 @@ +import { FollowAPIError } from "@follow-app/client-sdk" import { t } from "i18next" import { FetchError } from "ofetch" @@ -25,6 +26,20 @@ export const getFetchErrorInfo = ( } } + if (error instanceof FollowAPIError && error.code) { + const code = Number(error.code) + try { + const i18nKey = `errors:${code}` as any + const i18nMessage = t(i18nKey) === i18nKey ? error.message : t(i18nKey) + return { + message: i18nMessage, + code, + } + } catch { + return { message: error.message } + } + } + return { message: error.message } } @@ -67,6 +82,17 @@ export const toastFetchError = (error: Error, { title: _title }: { title?: strin } } + if (error instanceof FollowAPIError && error.code) { + code = Number(error.code) + try { + const tValue = t(`errors:${code}` as any) + const i18nMessage = tValue === code?.toString() ? error.message : tValue + message = i18nMessage + } catch { + message = error.message + } + } + // 2fa errors are handled by the form if (code === 4007 || code === 4008) { return diff --git a/apps/mobile/src/modules/settings/routes/Actions.tsx b/apps/mobile/src/modules/settings/routes/Actions.tsx index 6dce7435f..95089908c 100644 --- a/apps/mobile/src/modules/settings/routes/Actions.tsx +++ b/apps/mobile/src/modules/settings/routes/Actions.tsx @@ -31,6 +31,7 @@ import { Switch } from "@/src/components/ui/switch/Switch" import { Text } from "@/src/components/ui/typography/Text" import { Book6CuteReIcon } from "@/src/icons/book_6_cute_re" import { Magic2CuteFiIcon } from "@/src/icons/magic_2_cute_fi" +import { toastFetchError } from "@/src/lib/error-parser" import { useNavigation } from "@/src/lib/navigation/hooks" import { toast } from "@/src/lib/toast" import { accentColor } from "@/src/theme/colors" @@ -129,8 +130,8 @@ const SaveRuleButton = ({ disabled }: { disabled?: boolean }) => { navigation.back() toast.success("Actions saved") }, - onError(errorMessage) { - toast.error(errorMessage) + onError(error) { + toastFetchError(error) }, }) return ( diff --git a/apps/mobile/src/modules/settings/routes/Plan.tsx b/apps/mobile/src/modules/settings/routes/Plan.tsx index 2fe8c1c26..9233becca 100644 --- a/apps/mobile/src/modules/settings/routes/Plan.tsx +++ b/apps/mobile/src/modules/settings/routes/Plan.tsx @@ -7,22 +7,17 @@ import type { ProductPurchase } from "expo-iap" import { useIAP } from "expo-iap" import { openURL } from "expo-linking" import { useEffect } from "react" -import { Trans, useTranslation } from "react-i18next" -import { Linking, Pressable, View } from "react-native" +import { useTranslation } from "react-i18next" +import { Pressable, View } from "react-native" import { useServerConfigs } from "@/src/atoms/server-configs" import { NavigationBlurEffectHeaderView, SafeNavigationScrollView, } from "@/src/components/layouts/views/SafeNavigationScrollView" -import { - GroupedInformationCell, - GroupedInsetListCard, -} from "@/src/components/ui/grouped/GroupedList" // Plan configuration types import { Text } from "@/src/components/ui/typography/Text" import { CheckLineIcon } from "@/src/icons/check_line" -import { PowerOutlineIcon } from "@/src/icons/power_outline" import { TimeCuteReIcon } from "@/src/icons/time_cute_re" import { followClient } from "@/src/lib/api-client" import { authClient } from "@/src/lib/auth" @@ -30,7 +25,6 @@ import { useNavigation } from "@/src/lib/navigation/hooks" import type { NavigationControllerView } from "@/src/lib/navigation/types" import { isIOS } from "@/src/lib/platform" import { proxyEnv } from "@/src/lib/proxy-env" -import { accentColor } from "@/src/theme/colors" import { ReferralScreen } from "./Referral" @@ -55,6 +49,7 @@ const PLAN_TIER_MAP: Record = { // Same as Free (deprecated) [UserRole.PreProTrial]: 2, [UserRole.Pro]: 3, + [UserRole.Plus]: 4, } // Plan configurations @@ -129,7 +124,6 @@ export const PlanScreen: NavigationControllerView = () => { const navigation = useNavigation() const { t } = useTranslation("settings") const serverConfigs = useServerConfigs() - const ruleLink = serverConfigs?.REFERRAL_RULE_LINK const requiredInvitationsAmount = serverConfigs?.REFERRAL_REQUIRED_INVITATIONS || 3 const { data: referralInfo } = useReferralInfoQuery() const validInvitationsAmount = referralInfo?.invitations.filter((i) => i.usedAt).length || 0 @@ -165,40 +159,6 @@ export const PlanScreen: NavigationControllerView = () => { className="bg-system-grouped-background" Header={} > - - - } - iconBackgroundColor={accentColor} - > - ( - - {children} - - )} - components={{ - Link: ( - { - if (ruleLink) { - Linking.openURL(ruleLink) - } - }} - > - Learn more - - ), - }} - /> - - - - {PLAN_CONFIGS.map((plan) => { const isProPreview = plan.id === "pro-preview" diff --git a/apps/ssr/client/components/layout/header/index.tsx b/apps/ssr/client/components/layout/header/index.tsx index 0479ccf07..f4e03572c 100644 --- a/apps/ssr/client/components/layout/header/index.tsx +++ b/apps/ssr/client/components/layout/header/index.tsx @@ -99,8 +99,8 @@ export const Header = () => { whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} className={cn( - "inline-flex items-center gap-2 rounded-full border px-6 font-medium", - "bg-fill/60 text-sm text-text hover:bg-fill/80", + "inline-flex items-center gap-2 rounded-full border border-fill-tertiary px-6 font-medium", + "bg-fill-quinary text-sm text-text backdrop-blur-background hover:bg-fill-tertiary", isCompact ? "h-8" : "h-10", )} > @@ -115,8 +115,7 @@ export const Header = () => { whileTap={{ scale: 0.98 }} className={cn( "inline-flex items-center justify-center rounded-full px-6 font-medium", - "bg-white text-sm text-black shadow-sm hover:shadow", - "dark:bg-zinc-50 dark:text-zinc-900", + "border border-accent/20 bg-accent/90 text-sm text-white shadow-sm hover:shadow", isCompact ? "h-8" : "h-10", )} > diff --git a/apps/ssr/client/components/ui/user-avatar.tsx b/apps/ssr/client/components/ui/user-avatar.tsx index 2b927a56a..b9ce3da7f 100644 --- a/apps/ssr/client/components/ui/user-avatar.tsx +++ b/apps/ssr/client/components/ui/user-avatar.tsx @@ -42,6 +42,8 @@ export const UserAvatar = ({ className }: { className?: string }) => { updatedAt: new Date().toISOString(), twoFactorEnabled: false, deleted: false, + inactive: false, + lastLoginMethod: "github", } } else { return null diff --git a/apps/ssr/client/pages/(login)/forget-password.tsx b/apps/ssr/client/pages/(login)/forget-password.tsx index bd835274f..76799dc2b 100644 --- a/apps/ssr/client/pages/(login)/forget-password.tsx +++ b/apps/ssr/client/pages/(login)/forget-password.tsx @@ -1,5 +1,5 @@ import { forgetPassword } from "@client/lib/auth" -import { Button, MotionButtonBase } from "@follow/components/ui/button/index.jsx" +import { Button } from "@follow/components/ui/button/index.jsx" import { Card, CardContent, @@ -24,7 +24,6 @@ import { useRef } from "react" import * as React from "react" import { useForm } from "react-hook-form" import { useTranslation } from "react-i18next" -import { useNavigate } from "react-router" import { toast } from "sonner" import { z } from "zod" @@ -38,7 +37,7 @@ const createEmailSchema = (t: any) => export function Component() { const { t } = useTranslation() - const navigate = useNavigate() + const captchaRef = useRef(null) const EmailSchema = createEmailSchema(t) @@ -85,17 +84,9 @@ export function Component() { return (
- + - { - history.length > 1 ? history.back() : navigate("/login") - }} - className="-ml-1 inline-flex cursor-pointer items-center" - > - - {t("login.forget_password.label")} diff --git a/apps/ssr/client/pages/(login)/reset-password.tsx b/apps/ssr/client/pages/(login)/reset-password.tsx index e3be97868..8739bcee8 100644 --- a/apps/ssr/client/pages/(login)/reset-password.tsx +++ b/apps/ssr/client/pages/(login)/reset-password.tsx @@ -1,5 +1,5 @@ import { resetPassword } from "@client/lib/auth" -import { Button, MotionButtonBase } from "@follow/components/ui/button/index.jsx" +import { Button } from "@follow/components/ui/button/index.jsx" import { Card, CardContent, @@ -77,17 +77,9 @@ export function Component() { return (
- + - { - history.length > 1 ? history.back() : navigate("/login") - }} - className="-ml-1 inline-flex cursor-pointer items-center" - > - - {t("login.forget_password.label")} diff --git a/locales/ai/en.json b/locales/ai/en.json index 4f511fb21..6e30853cd 100644 --- a/locales/ai/en.json +++ b/locales/ai/en.json @@ -4,10 +4,11 @@ "analytics.efficiency_analysis": "Efficiency Analysis", "analytics.efficiency_placeholder": "Model efficiency comparison and optimization suggestions", "analytics.history_operation": "{{operation}} operation", - "analytics.history_usage": "Token usage", + "analytics.history_usage": "AI Credits usage", "analytics.no_data": "No usage data available for the selected period", "analytics.no_history": "No usage history available", "analytics.operation_types.chat": "Chat", + "analytics.operation_types.onboarding": "Onboarding", "analytics.operation_types.task": "Task", "analytics.operation_types.title_generation": "Title Generation", "analytics.patterns_placeholder": "Pattern analysis will show peak usage times and habits", @@ -17,7 +18,7 @@ "analytics.tabs.patterns": "Patterns", "analytics.trend.operations": "Operations", "analytics.trend.title": "Usage Trends (Last 30 Days)", - "analytics.trend.tokens": "Tokens Used", + "analytics.trend.tokens": "Credits Used", "analytics.usage_history": "Usage History", "analytics.usage_patterns": "Usage Patterns", "analytics.usage_trends": "Usage Trends (Last 30 Days)", @@ -284,11 +285,11 @@ "timeline_summary.generating": "Summarizing your timeline...", "timeline_summary.heading": "What's New in Timeline", "timeline_summary.options.include": "Chat with timeline summary", - "token_usage.description": "Monitor your AI token consumption and limits.", + "token_usage.description": "Monitor your AI credits consumption and limits.", "token_usage.resets_at": "Resets at", - "token_usage.title": "Token Usage", - "token_usage.tokens_remaining": "tokens remaining", - "token_usage.tokens_used": "{{used}} / {{total}} tokens used", + "token_usage.title": "AI Credits Usage", + "token_usage.tokens_remaining": "credits remaining", + "token_usage.tokens_used": "{{used}} / {{total}} credits used", "usage_analysis.active_session": "Active Session", "usage_analysis.current_usage": "Current Usage", "usage_analysis.detailed_description": "Comprehensive overview of your AI usage patterns and insights", @@ -296,9 +297,9 @@ "usage_analysis.no_data": "No usage data available", "usage_analysis.resets_in": "Resets in", "usage_analysis.session_duration": "Duration: {{duration}}", - "usage_analysis.title": "Token Usage", - "usage_analysis.tokens_remaining": "tokens remaining", - "usage_analysis.tokens_used": "Tokens Used", + "usage_analysis.title": "AI Credits Usage", + "usage_analysis.tokens_remaining": "credits remaining", + "usage_analysis.tokens_used": "Credits Used", "usage_analysis.total_limit": "Total Limit", "usage_analysis.view_details": "View Details", "usage_analysis.warning.general": "Consider reducing usage to avoid hitting limits", diff --git a/locales/ai/ja.json b/locales/ai/ja.json index 531e0112e..32b4e6489 100644 --- a/locales/ai/ja.json +++ b/locales/ai/ja.json @@ -8,6 +8,7 @@ "analytics.no_data": "選択した期間に利用可能な使用データがありません", "analytics.no_history": "利用可能な使用履歴がありません", "analytics.operation_types.chat": "チャット", + "analytics.operation_types.onboarding": "オンボーディング", "analytics.operation_types.task": "タスク", "analytics.operation_types.title_generation": "タイトル生成", "analytics.patterns_placeholder": "パターン分析はピーク使用時間と習慣を表示します", diff --git a/locales/ai/zh-CN.json b/locales/ai/zh-CN.json index efebcc5a2..777d103e5 100644 --- a/locales/ai/zh-CN.json +++ b/locales/ai/zh-CN.json @@ -8,6 +8,7 @@ "analytics.no_data": "所选期间没有可用的使用数据", "analytics.no_history": "没有可用的使用历史", "analytics.operation_types.chat": "聊天", + "analytics.operation_types.onboarding": "入门", "analytics.operation_types.task": "任务", "analytics.operation_types.title_generation": "标题生成", "analytics.patterns_placeholder": "模式分析将显示高峰使用时间和习惯", diff --git a/locales/ai/zh-TW.json b/locales/ai/zh-TW.json new file mode 100644 index 000000000..83b2618bc --- /dev/null +++ b/locales/ai/zh-TW.json @@ -0,0 +1,295 @@ +{ + "ai_summary": "AI 摘要", + "analytics.chart_placeholder": "圖表可視化將透過 Recharts 實現", + "analytics.efficiency_analysis": "效率分析", + "analytics.efficiency_placeholder": "模型效率比較和優化建議", + "analytics.history_operation": "{{operation}} 操作", + "analytics.history_usage": "令牌使用", + "analytics.no_data": "所選期間沒有可用的使用資料", + "analytics.no_history": "沒有可用的使用歷史", + "analytics.operation_types.chat": "聊天", + "analytics.operation_types.title_generation": "標題生成", + "analytics.patterns_placeholder": "模式分析將顯示高峰使用時間和習慣", + "analytics.tabs.efficiency": "效率", + "analytics.tabs.history": "歷史", + "analytics.tabs.overview": "概覽", + "analytics.tabs.patterns": "模式", + "analytics.trend.operations": "操作次數", + "analytics.trend.title": "最近30天使用趨勢", + "analytics.trend.tokens": "使用令牌", + "analytics.usage_history": "使用歷史", + "analytics.usage_patterns": "使用模式", + "analytics.usage_trends": "使用趨勢(最近30天)", + "chat.history.auto_title": "{{- datetime}} 聊天", + "clear_chat": "清空對話", + "clear_chat_message": "確定要清空所有歷史記錄嗎?此操作將永久刪除所有內容,包括所有聊天記錄和數據,且無法撤銷。", + "common.generate_title": "生成標題", + "common.generating_title": "正在生成標題...", + "common.new_chat": "新對話", + "customize_shortcuts": "自訂快速鍵", + "delete_chat": "刪除對話", + "delete_chat_error": "刪除對話失敗", + "delete_chat_message": "確定要刪除\"{{title}}\"嗎?此操作無法撤銷。", + "delete_chat_success": "對話刪除成功", + "features.title": "功能", + "integration.mcp.description": "透過安全的 OAuth 整合連接到相容 MCP 的服務,擴充 AI 功能。", + "integration.mcp.enabled": "啟用 MCP 服務", + "integration.mcp.security.description": "OAuth 驗證令牌使用 AES-GCM-256 加密技術安全儲存,以保護您的憑據並確保資料隱私。", + "integration.mcp.security.title": "安全聲明", + "integration.mcp.service.active": "活躍", + "integration.mcp.service.added": "MCP 服務新增成功", + "integration.mcp.service.auth_message": "此服務需要 OAuth 授權。點擊\"開啟授權\"以在新視窗中進行身份驗證。", + "integration.mcp.service.auth_required": "需要授權", + "integration.mcp.service.auth_window_opened": "授權視窗已打開。請完成身份驗證。", + "integration.mcp.service.baseUrl": "服務基礎 URL", + "integration.mcp.service.baseUrl_placeholder": "例如:https://api.example.com", + "integration.mcp.service.connect": "連接", + "integration.mcp.service.connected": "已連接", + "integration.mcp.service.connected_success": "成功連接到 MCP 服務", + "integration.mcp.service.connecting": "連線中...", + "integration.mcp.service.connection_failed": "連接 MCP 服務失敗", + "integration.mcp.service.degraded": "降級", + "integration.mcp.service.delete_message": "您確定要刪除此 MCP 服務嗎?此操作無法撤銷。", + "integration.mcp.service.delete_title": "刪除 MCP 服務", + "integration.mcp.service.deleted": "MCP 服務刪除成功", + "integration.mcp.service.disabled": "已停用", + "integration.mcp.service.disconnect": "斷開連接", + "integration.mcp.service.disconnected": "已斷開連接", + "integration.mcp.service.discover": "探索服務", + "integration.mcp.service.discovery_failed": "探索服務端點失敗", + "integration.mcp.service.enabled": "已啟用", + "integration.mcp.service.endpoints": "OAuth 端點", + "integration.mcp.service.error": "連接錯誤", + "integration.mcp.service.healthy": "健康", + "integration.mcp.service.inactive": "非活躍", + "integration.mcp.service.name": "服務名稱", + "integration.mcp.service.name_placeholder": "例如:GitHub 工具、Slack 集成", + "integration.mcp.service.open_auth": "開啟授權", + "integration.mcp.service.open_manually": "啟動授權", + "integration.mcp.service.popup_blocked": "授權彈出視窗被瀏覽器阻擋", + "integration.mcp.service.reconnect": "重新連接", + "integration.mcp.service.scopes": "所需權限範圍", + "integration.mcp.service.unhealthy": "不健康", + "integration.mcp.service.updated": "MCP 服務更新成功", + "integration.mcp.service.validation.baseUrl_required": "基礎 URL 為必填項目", + "integration.mcp.service.validation.invalid_url": "請輸入有效的 URL", + "integration.mcp.service.validation.name_required": "服務名稱為必填項目", + "integration.mcp.services.add": "新增服務", + "integration.mcp.services.empty.description": "連接 MCP 服務以透過外部工具、API 和資料源來擴展 AI 功能。", + "integration.mcp.services.empty.title": "未連接 MCP 服務", + "integration.mcp.services.title": "MCP 服務", + "integration.title": "整合", + "mentions.date.relative.last_15_days.label": "最近 15 天", + "mentions.date.relative.last_15_days.search": "最近 15 天|近半個月", + "mentions.date.relative.last_30_days.label": "最近 30 天", + "mentions.date.relative.last_30_days.search": "最近 30 天|近一個月", + "mentions.date.relative.last_3_days.label": "最近 3 天", + "mentions.date.relative.last_3_days.search": "最近 3 天|近三天", + "mentions.date.relative.last_7_days.label": "最近 7 天", + "mentions.date.relative.last_7_days.search": "最近 7 天|近一週", + "mentions.date.relative.last_month.label": "上個月", + "mentions.date.relative.last_month.search": "上個月|上月|上一個月", + "mentions.date.relative.last_week.label": "上週", + "mentions.date.relative.last_week.search": "上週|上一週|上星期|上個星期|上禮拜|上個禮拜", + "mentions.date.relative.this_month.label": "這個月", + "mentions.date.relative.this_month.search": "這個月|本月|這月", + "mentions.date.relative.this_week.label": "這周", + "mentions.date.relative.this_week.search": "這周|本週|這星期|本星期|這禮拜|本禮拜", + "mentions.date.relative.today.label": "今天", + "mentions.date.relative.today.search": "今天|今日", + "mentions.date.relative.yesterday.label": "昨天", + "mentions.date.relative.yesterday.search": "昨天|昨日", + "mentions.date.weekday.auto.label": "{{weekday}}", + "mentions.date.weekday.day.friday.label": "週五", + "mentions.date.weekday.day.friday.search": "週五|星期五|禮拜五", + "mentions.date.weekday.day.monday.label": "週一", + "mentions.date.weekday.day.monday.search": "週一|星期一|禮拜一", + "mentions.date.weekday.day.saturday.label": "週六", + "mentions.date.weekday.day.saturday.search": "週六|星期六|禮拜六", + "mentions.date.weekday.day.sunday.label": "週日", + "mentions.date.weekday.day.sunday.search": "週日|星期日|禮拜日|周天|星期天|禮拜天", + "mentions.date.weekday.day.thursday.label": "週四", + "mentions.date.weekday.day.thursday.search": "週四|星期四|禮拜四", + "mentions.date.weekday.day.tuesday.label": "週二", + "mentions.date.weekday.day.tuesday.search": "週二|星期二|禮拜二", + "mentions.date.weekday.day.wednesday.label": "週三", + "mentions.date.weekday.day.wednesday.search": "週三|星期三|禮拜三", + "mentions.date.weekday.last.label": "上週{{weekday}}", + "mentions.date.weekday.prefix.auto.search": "", + "mentions.date.weekday.prefix.last.search": "上週|上一週|上星期|上個星期|上禮拜|上個禮拜", + "mentions.date.weekday.prefix.this.search": "這周|本週|這星期|本星期|這禮拜|本禮拜", + "mentions.date.weekday.this.label": "本週{{weekday}}", + "mentions.section.category": "分類", + "mentions.section.date": "日期", + "mentions.section.entry": "條目", + "mentions.section.feed": "RSS 摘要", + "mentions.section.view": "視圖", + "new_shortcuts": "新增快速鍵", + "personalize.description": "介紹一下您自己,以獲得個性化的 AI 回應。", + "personalize.prompt.help": "這有助於 AI 根據您的偏好提供個性化的回應。", + "personalize.prompt.placeholder": "介紹一下您自己以及您希望如何閱讀內容...", + "personalize.saved": "個人化設定儲存成功", + "personalize.title": "個性化", + "quick_actions.discuss": "討論見解", + "quick_actions.questions": "提出問題", + "quick_actions.simplify": "簡化內容", + "quick_actions.takeaways": "關鍵重點", + "schedule.configuration_label": "設定", + "schedule.date_time_label": "日期和時間", + "schedule.date_time_placeholder": "選擇日期和時間", + "schedule.day_label": "日期", + "schedule.day_placeholder": "選擇日期", + "schedule.days.friday": "星期五", + "schedule.days.monday": "星期一", + "schedule.days.saturday": "星期六", + "schedule.days.sunday": "星期日", + "schedule.days.thursday": "星期四", + "schedule.days.tuesday": "星期二", + "schedule.days.wednesday": "星期三", + "schedule.frequency.daily": "每日", + "schedule.frequency.monthly": "每月", + "schedule.frequency.once": "單次", + "schedule.frequency.weekly": "每週", + "schedule.next_execution": "下次執行:{{time}} ({{relative}})", + "schedule.no_upcoming": "沒有即將執行的任務", + "schedule.presets.daily_6pm": "每天下午 6 點", + "schedule.presets.first_9am": "1 號上午 9 點", + "schedule.presets.monday_9am": "週一上午 9 點", + "schedule.presets.tomorrow_9am": "明天上午 9 點", + "schedule.presets_title": "快速預設", + "schedule.time_label": "時間", + "schedule.time_placeholder": "選擇時間", + "schedule.title": "排程", + "settings.autoScrollWhenStreaming.description": "在串流時自動捲動到聊天底部。", + "settings.autoScrollWhenStreaming.label": "串流時自動捲動", + "settings.description": "設定您的 AI 體驗並建立自訂快速鍵", + "settings.panel_style.description": "AI 聊天面板的樣式", + "settings.panel_style.fixed": "固定", + "settings.panel_style.floating": "浮動", + "settings.panel_style.label": "面板樣式", + "settings.showSplineButton.description": "顯示或隱藏右下角的 AI 助手指示器。", + "settings.showSplineButton.label": "AI 助手指示器", + "settings.title": "AI 設定", + "shortcuts.add": "新增快速鍵", + "shortcuts.added": "快捷方式新增成功", + "shortcuts.context_menu.empty.entry": "尚無可用於條目詳情的快速鍵", + "shortcuts.context_menu.empty.list": "列表視圖尚無可用的快速鍵", + "shortcuts.create_first": "建立您的第一個快速鍵", + "shortcuts.custom_prompt.help": "留空則使用伺服器端提供的預設提示。", + "shortcuts.custom_prompt.title": "自訂提示", + "shortcuts.custom_prompt_placeholder": "覆蓋預設提示內容...", + "shortcuts.default_prompt.label": "預設提示", + "shortcuts.deleted": "快速鍵刪除成功", + "shortcuts.empty.description": "建立自訂 AI 快速鍵,快速執行常見任務並獲得即時 AI 協助。", + "shortcuts.empty.title": "尚無快速鍵", + "shortcuts.enabled": "已啟用", + "shortcuts.icon": "圖示", + "shortcuts.manage": "管理快速鍵", + "shortcuts.name": "名稱", + "shortcuts.name_placeholder": "例如:摘要文章", + "shortcuts.prompt": "提示", + "shortcuts.prompt_placeholder": "為 AI 撰寫清晰的指令...", + "shortcuts.server_delete_disabled": "該快速鍵由伺服器端提供,無法刪除", + "shortcuts.targets.entry": "條目詳情", + "shortcuts.targets.help": "選擇適用場景以控制此快捷方式的展示位置。", + "shortcuts.targets.label": "展示位置", + "shortcuts.targets.list": "時間軸", + "shortcuts.title": "AI 快捷方式", + "shortcuts.updated": "快捷方式更新成功", + "shortcuts.validation.name_required": "名稱為必填項目", + "shortcuts.validation.prompt_required": "提示為必填項目", + "shortcuts.validation.required": "名稱和提示為必填項目", + "shortcuts.validation.targets_required": "至少選擇一個展示位置", + "summary_not_available": "摘要不可用", + "tasks.actions.delete_task": "刪除任務", + "tasks.actions.edit_task": "編輯任務", + "tasks.actions.new_task": "新增任務", + "tasks.actions.schedule": "安排任務", + "tasks.actions.scheduling": "正在安排...", + "tasks.actions.test_run": "測試執行", + "tasks.actions.update": "更新任務", + "tasks.actions.updating": "正在更新...", + "tasks.actions.view_reports": "查看報告", + "tasks.empty.desc": "創建您的第一個 AI 任務以自動化您的工作流程。", + "tasks.empty.title": "暫無計劃任務", + "tasks.fields.created": "建立時間:", + "tasks.fields.prompt": "指令:", + "tasks.fields.schedule": "排程:", + "tasks.manage.desc": "建立並管理按排程自動執行的 AI 任務。", + "tasks.manage.limit_reached": "(已達到最大任務數量限制)", + "tasks.manage.title": "排程 AI 任務", + "tasks.modal.delete_confirm": "確定要刪除任務 \"{{name}}\" 嗎?", + "tasks.modal.delete_title": "刪除任務", + "tasks.modal.edit_title": "編輯 AI 任務", + "tasks.modal.new_title": "新增 AI 任務", + "tasks.name": "任務名稱", + "tasks.name_placeholder": "輸入一個描述性的任務名稱...", + "tasks.notify.coming_soon": "即將推出", + "tasks.notify.email": "郵件", + "tasks.notify.email_helper": "任務完成後將結果發送到您的帳戶信箱。", + "tasks.prompt": "指令", + "tasks.prompt_helper": "請提供清晰、具體的指令供 AI 執行", + "tasks.prompt_placeholder": "描述當此任務執行時您希望 AI 做什麼...", + "tasks.schedule.daily": "每天 {{time}}", + "tasks.schedule.monthly": "每月第 {{day}} 天 {{time}}", + "tasks.schedule.once": "{{date}} {{time}} 單次", + "tasks.schedule.unknown": "未知排程", + "tasks.schedule.weekly": "每週{{day}} {{time}}", + "tasks.section.info": "任務資訊", + "tasks.section.instructions": "AI 指令", + "tasks.section.notifications": "通知", + "tasks.section.schedule": "排程設定", + "tasks.section.title": "AI 任務", + "tasks.status.completed": "已完成", + "tasks.status.paused": "已暫停", + "tasks.status.scheduled": "已排程", + "tasks.status.unknown": "未知", + "tasks.toast.create_error": "安排 AI 任務失敗,請重試。", + "tasks.toast.created": "AI 任務安排成功", + "tasks.toast.delete_failed": "刪除任務失敗,請重試。", + "tasks.toast.delete_success": "任務刪除成功", + "tasks.toast.load_failed": "載入聊天訊息失敗", + "tasks.toast.no_report": "此任務尚無報告。", + "tasks.toast.switch_to_chat": "切換到聊天面板檢視報告。", + "tasks.toast.test_failed": "測試執行失敗,請重試。", + "tasks.toast.test_start": "開始測試執行...大約需要 1 分鐘。您可以在聊天面板檢視結果。", + "tasks.toast.test_success": "測試執行完成。您可以在聊天面板檢視報告。", + "tasks.toast.update_error": "更新 AI 任務失敗,請重試。", + "tasks.toast.update_failed": "更新任務失敗,請重試。", + "tasks.toast.updated": "AI 任務更新成功", + "tasks.validation.date_future": "排程時間必須是未來的時間", + "tasks.validation.prompt_max": "指令必須少於 2000 個字元", + "tasks.validation.prompt_required": "指令為必填項目", + "tasks.validation.title_max": "標題必須少於 50 個字元", + "tasks.validation.title_required": "標題為必填項目", + "tasks.view_in_settings": "在設定中檢視已排程任務", + "timeline.summary.title_template": "{{- datetime}} 時間軸摘要", + "timeline_summary.empty": "時間軸摘要即將呈現。", + "timeline_summary.error": "暫時無法產生時間軸摘要。", + "timeline_summary.generating": "正在產生時間軸摘要...", + "timeline_summary.heading": "時間軸有什麼新內容", + "timeline_summary.options.include": "與時間軸摘要聊天", + "token_usage.description": "監控您的 AI 令牌消耗和限制", + "token_usage.resets_at": "重設時間", + "token_usage.title": "令牌使用狀況", + "token_usage.tokens_remaining": "剩餘令牌", + "token_usage.tokens_used": "已使用 {{used}} / {{total}} 令牌", + "usage_analysis.active_session": "活躍工作階段", + "usage_analysis.current_usage": "目前使用狀況", + "usage_analysis.detailed_description": "全面瞭解您的 AI 使用模式和洞察", + "usage_analysis.detailed_title": "AI 使用分析", + "usage_analysis.no_data": "沒有可用的使用資料", + "usage_analysis.resets_in": "重設時間", + "usage_analysis.session_duration": "持續時間:{{duration}}", + "usage_analysis.title": "令牌使用狀況", + "usage_analysis.tokens_remaining": "剩餘令牌", + "usage_analysis.tokens_used": "已使用令牌", + "usage_analysis.total_limit": "總限制", + "usage_analysis.view_details": "檢視詳情", + "usage_analysis.warning.general": "請考慮降低使用以避免達到限制", + "usage_analysis.warning.projected": "預計在 {{eta}} 達到限制", + "usage_analysis.warning.rate": "速率:{{rate}} 令牌/分鐘", + "usage_analysis.warning.title": "檢測到較高的 AI 使用量", + "welcome_description": "我在這裡幫助您處理閱讀需求。今天我能為您做些什麼?", + "welcome_description_contextual": "讓我們一起討論這個條目" +} diff --git a/locales/app/en.json b/locales/app/en.json index b884c6a01..603f67432 100644 --- a/locales/app/en.json +++ b/locales/app/en.json @@ -25,6 +25,7 @@ "activation.plan.upgrade": "Upgrade", "activation.title": "Invitation Code", "ai.summary_not_available": "Summary not available", + "ai.summary_upgrade_required_title": "Upgrade plan to continue using AI summary", "app.copy_logo_svg": "Copy Logo SVG", "app.copy_logo_text_svg": "Copy Logo Text SVG", "app.toggle_sidebar": "Toggle Sidebar", diff --git a/locales/app/zh-TW.json b/locales/app/zh-TW.json index ecc5d8bb1..d03dd8d93 100644 --- a/locales/app/zh-TW.json +++ b/locales/app/zh-TW.json @@ -5,22 +5,26 @@ "achievement.description": "成為硬派玩家,鑄造 NFT。", "achievement.first_claim_feed": "RSS 摘要作者", "achievement.first_claim_feed_description": "在 Folo 上認證 RSS 摘要", - "achievement.first_create_list": "列表創建者", - "achievement.first_create_list_description": "在 Folo 上創建一個列表", + "achievement.first_create_list": "列表建立者", + "achievement.first_create_list_description": "在 Folo 上建立一個列表", "achievement.follow_special_feed": "特別 RSS 摘要跟隨者", "achievement.follow_special_feed_description": "在 Folo 上跟隨了一個特別的 RSS 摘要", "achievement.list_subscribe_100": "100 名列表訂閱者", - "achievement.list_subscribe_100_description": "創建的列表有 100 名訂閱者", + "achievement.list_subscribe_100_description": "建立的列表有 100 名訂閱者", "achievement.list_subscribe_50": "50 名列表訂閱者", "achievement.list_subscribe_500": "500 名列表訂閱者", - "achievement.list_subscribe_500_description": "創建的列表有 500 名訂閱者", - "achievement.list_subscribe_50_description": "創建的列表有 50 名訂閱者", + "achievement.list_subscribe_500_description": "建立的列表有 500 名訂閱者", + "achievement.list_subscribe_50_description": "建立的列表有 50 名訂閱者", "achievement.nft_coming_soon": "目前您無法鑄造 NFT。一旦我們準備好,NFT 將自動轉移到您的帳戶。", "achievement.product_hunt_vote": "Product Hunt 投票", "achievement.product_hunt_vote_description": "您在 Product Hunt 上投票給了 Folo", "activation.activate": "啟用", "activation.description": "在公開測試階段,您需要邀請碼才能使用此功能。", + "activation.plan.description": "您目前使用的是免費方案。升級方案以解鎖更多功能。", + "activation.plan.title": "升級方案", + "activation.plan.upgrade": "升級", "activation.title": "邀請碼", + "ai.summary_not_available": "暫無摘要", "app.copy_logo_svg": "複製 Logo SVG", "app.copy_logo_text_svg": "複製圖標 SVG 文字", "app.toggle_sidebar": "切換側邊欄", @@ -46,13 +50,16 @@ "discover.import.opml_step1_other": "從其他閱讀器匯出 OPML 檔案", "discover.import.opml_step1_other_step1": "OPML 是一種廣泛支援的開放格式,基本上是分享 RSS摘要列表的標準。幾乎所有 RSS 閱讀器都允許匯入與匯出 OPML。如果你不確定如何操作,請參考你的 RSS 閱讀器說明文件或加入我們的社群尋求協助。", "discover.import.opml_step2": "匯入 OPML 到 Folo", + "discover.import.parse_opml": "解析 OPML", "discover.import.parsedErrorItems": "解析錯誤項目", + "discover.import.preview_opml_content": "預覽 OPML 內容", "discover.import.quota_exceeded": "超出額度", "discover.import.quota_exceeded_warning": "您選擇的 RSS 摘要數量超過了剩餘額度。請取消選擇一些 RSS 摘要以繼續。", "discover.import.quota_limit_reached": "已達額度限制", "discover.import.quota_status": "匯入額度:", "discover.import.quota_warning": "您的額度還剩 {{remaining}} 個 RSS 摘要。", "discover.import.remaining_quota": "你還可以匯入 {{remaining}} 個 RSS 摘要", + "discover.import.result": " 個 RSS 摘要匯入成功。
已訂閱。
匯入失敗。", "discover.import.search_feeds_placeholder": "搜尋 RSS 摘要...", "discover.import.select_all_feeds": "全選 RSS 摘要", "discover.import.select_all_filtered": "全選篩選結果", @@ -63,6 +70,7 @@ "discover.inbox.description": "你可以透過電子信箱和 Webhooks 在收件匣接收資訊。", "discover.inbox.email": "電子信箱", "discover.inbox.handle": "名稱", + "discover.inbox.no_inbox": "你目前沒有收件匣,請點擊下方按鈕建立第一個收件匣。", "discover.inbox.secret": "密鑰", "discover.inbox.title": "標題", "discover.inbox.webhooks_docs": "Webhooks 文件", @@ -91,6 +99,9 @@ "discover.target.feeds": "RSS 摘要", "discover.target.label": "搜尋", "discover.target.lists": "列表", + "entry.click_to_return": "向上捲動或點擊此處返回", + "entry.exit_detail": "返回時間軸", + "entry.scroll_up_to_exit": "向上捲動返回時間軸", "entry_actions.copied_notify": "{{which}}已複製到剪貼簿", "entry_actions.copy_link": "複製連結", "entry_actions.copy_title": "複製標題", @@ -98,20 +109,23 @@ "entry_actions.deleted": "已刪除。", "entry_actions.export_as_pdf": "匯出為 PDF", "entry_actions.failed_to_delete": "刪除失敗。", + "entry_actions.failed_to_login_to_qbittorrent": "無法登入 qBittorrent", "entry_actions.failed_to_save_to_cubox": "無法儲存到 Cubox。", "entry_actions.failed_to_save_to_eagle": "無法儲存到 Eagle。", "entry_actions.failed_to_save_to_instapaper": "無法儲存到 Instapaper。", "entry_actions.failed_to_save_to_obsidian": "無法儲存到 Obsidian。", "entry_actions.failed_to_save_to_outline": "無法儲存到 Outline。", + "entry_actions.failed_to_save_to_qbittorrent": "無法使用 qBittorrent 下載", "entry_actions.failed_to_save_to_readeck": "無法儲存到 Readeck。", "entry_actions.failed_to_save_to_readwise": "無法儲存到 Readwise。", "entry_actions.failed_to_save_to_zotero": "無法儲存到 Zotero。", "entry_actions.image_gallery": "影像圖庫", "entry_actions.image_gallery_description": "當文章中存在多張大圖時,可以在 Gallery Modal 中瀏覽文章中的全部圖片", "entry_actions.mark_above_as_read": "將以上標記為已讀", - "entry_actions.mark_as_read": "標記為已讀", + "entry_actions.mark_as_read": "標記為已讀 / 未讀", "entry_actions.mark_as_unread": "標記為未讀", "entry_actions.mark_below_as_read": "將以下標記為已讀", + "entry_actions.no_bittorrent_urls_found": "此條目中未找到 BitTorrent 連結。", "entry_actions.open_in_browser": "在{{which}}中打開", "entry_actions.recent_reader": "最近閲讀者:", "entry_actions.save_media_to_eagle": "儲存媒體至 Eagle", @@ -119,6 +133,7 @@ "entry_actions.save_to_instapaper": "儲存到 Instapaper", "entry_actions.save_to_obsidian": "儲存到 Obsidian", "entry_actions.save_to_outline": "儲存到 Outline", + "entry_actions.save_to_qbittorrent": "使用 qBittorrent 下載", "entry_actions.save_to_readeck": "儲存到 Readeck", "entry_actions.save_to_readwise": "儲存到 Readwise", "entry_actions.save_to_zotero": "儲存到 Zotero", @@ -127,6 +142,7 @@ "entry_actions.saved_to_instapaper": "已儲存到 Instapaper。", "entry_actions.saved_to_obsidian": "已儲存到 Obsidian。", "entry_actions.saved_to_outline": "已儲存到 Outline。", + "entry_actions.saved_to_qbittorrent": "種子已加入 qBittorrent。", "entry_actions.saved_to_readeck": "已儲存到 Readeck。", "entry_actions.saved_to_readwise": "已儲存到 Readwise。", "entry_actions.saved_to_zotero": "已儲存到 Zotero。", @@ -139,6 +155,7 @@ "entry_actions.unstarred": "已取消收藏", "entry_actions.view_source_content": "查看原始內容", "entry_actions.view_source_content_description": "嘗試以源網站的風格閱讀此文章的內容", + "entry_actions.warn_info_ai_chat_pinned_tip": "此功能目前為灰度測試,僅少數用戶可用。", "entry_actions.warn_info_for_desktop": "此功能只在桌面端可用", "entry_column.filtered_content_tip": "您已隱藏部分過濾的內容。", "entry_column.filtered_content_tip_2": "除了上方顯示的條目外,還有一些被過濾的內容。", @@ -191,8 +208,8 @@ "feed_claim_modal.verify_ownership": "要證明你是此 RSS 摘要的作者,您需要完成驗證。", "feed_form.add_feed": "新增 RSS 摘要", "feed_form.add_follow": "新增跟隨", - "feed_form.category": "類別", - "feed_form.category_description": "預設情況下,您的跟隨將按網站域名分組。", + "feed_form.category": "分類", + "feed_form.category_description": "預設情形下,您的跟隨將依網站網域分組。", "feed_form.error_fetching_feed": "獲取 RSS 摘要出錯。", "feed_form.fee": "跟隨費用", "feed_form.fee_description": "若需跟隨此列表,需支付費用", @@ -202,11 +219,13 @@ "feed_form.follow": "跟隨", "feed_form.follow_with_fee": "使用 {{fee}} Power 跟隨", "feed_form.followed": "🎉 跟隨成功。", + "feed_form.hide_from_timeline": "從時間軸隱藏", + "feed_form.hide_from_timeline_description": "開啟後,此訂閱將不再顯示在主時間軸中", "feed_form.private_follow": "私人跟隨", "feed_form.private_follow_description": "啟用後,此跟隨將不再顯示於個人資料頁面上。", "feed_form.retry": "重試", "feed_form.title": "標題", - "feed_form.title_description": "此 RSS 摘要的自定義標題。留空以使用預設標題。", + "feed_form.title_description": "此 RSS 摘要的自訂標題。留空則使用預設標題。", "feed_form.unfollow": "取消跟隨", "feed_form.update": "更新", "feed_form.update_follow": "更新跟隨", @@ -218,14 +237,16 @@ "feed_item.claimed_feed": "已認領 RSS 摘要", "feed_item.claimed_list": "已認領列表", "feed_item.error_since": "RSS 摘要失效:", - "feed_item.not_publicly_visible": "在您的個人頁面上隱藏", + "feed_item.not_publicly_visible": "未公開顯示於您的個人頁面", "login.agree_to": "繼續即表示你同意我們的", "login.back": "返回", "login.confirm_password.label": "確認密碼", "login.continueWith": "透過 {{provider}} 繼續", "login.email": "電子信箱", + "login.enter_token": "請輸入授權令牌以繼續", "login.forget_password.note": "忘記密碼了嗎?", "login.have_account": "已有帳號?登入", + "login.lastUsed": "最近使用", "login.no_account": "沒有帳號?註冊", "login.or": "或", "login.password": "密碼", @@ -290,6 +311,10 @@ "register.email": "電子信箱", "register.login": "登入", "register.password": "密碼", + "register.referral.days": "使用此推薦碼註冊可獲得 {{days}} 天的專業版預覽", + "register.referral.description": "使用推薦碼註冊可獲得額外幾日的專業版預覽。", + "register.referral.invalid": "無效的推薦碼", + "register.referral.label": "推薦碼", "register.submit": "創建帳號", "resize.tooltip.double_click_to_collapse": "雙擊重置為預設大小", "resize.tooltip.drag_to_resize": "拖動以調整大小", @@ -303,8 +328,19 @@ "search.placeholder": "搜尋...", "search.result_count_local_mode": "(本地模式)", "search.tooltip.local_search": "此搜尋涵蓋本地可用資料。嘗試重新獲取以獲得更多結果。", + "share.actions": "操作", + "share.copy_failed": "複製連結失敗", + "share.copy_link": "複製連結", + "share.default_description": "查看這個精彩內容", + "share.default_title": "內容分享", + "share.discover_more": "在 Folo 上探索更多精彩內容", + "share.link_copied": "連結已複製到剪貼簿", + "share.social_media": "社群媒體", + "share.system_share": "系統分享", + "share.title": "分享內容", "shortcuts.guide.title": "快捷鍵指南", "sidebar.add_more_feeds": "新增 RSS 摘要", + "sidebar.already_on_discover_page": "你已位於探索頁面!請將想要訂閱的內容加入右側面板。", "sidebar.category_remove_dialog.cancel": "取消", "sidebar.category_remove_dialog.continue": "繼續", "sidebar.category_remove_dialog.description": "正在刪除類別,但仍保留 RSS 摘要並按網站分組。", @@ -319,7 +355,7 @@ "sidebar.feed_actions.copy_feed_url": "複製 RSS 摘要 URL", "sidebar.feed_actions.copy_list_id": "複製列表 ID", "sidebar.feed_actions.copy_list_url": "複製列表連結", - "sidebar.feed_actions.create_list": "建立列表", + "sidebar.feed_actions.create_list": "新增列表", "sidebar.feed_actions.edit": "編輯", "sidebar.feed_actions.edit_feed": "編輯 RSS 摘要", "sidebar.feed_actions.edit_inbox": "編輯收件匣", @@ -345,16 +381,16 @@ "sidebar.feed_column.context_menu.add_feeds_to_category": "移動到類別", "sidebar.feed_column.context_menu.add_feeds_to_list": "新增 RSS 摘要到列表", "sidebar.feed_column.context_menu.change_to_other_view": "切換到其他視圖", - "sidebar.feed_column.context_menu.create_category": "新增類別", - "sidebar.feed_column.context_menu.delete_category": "刪除類別", - "sidebar.feed_column.context_menu.delete_category_confirmation": "刪除類別 {{folderName}}?", + "sidebar.feed_column.context_menu.create_category": "新增分類", + "sidebar.feed_column.context_menu.delete_category": "刪除分類", + "sidebar.feed_column.context_menu.delete_category_confirmation": "刪除分類 {{folderName}}?", "sidebar.feed_column.context_menu.mark_as_read": "標記為已讀", - "sidebar.feed_column.context_menu.new_category_modal.category_name": "類別名稱", + "sidebar.feed_column.context_menu.new_category_modal.category_name": "分類名稱", "sidebar.feed_column.context_menu.new_category_modal.create": "創建", - "sidebar.feed_column.context_menu.rename_category": "重新命名類別", - "sidebar.feed_column.context_menu.rename_category_error": "重命名類別失敗", - "sidebar.feed_column.context_menu.rename_category_success": "類別重新命名成功", - "sidebar.feed_column.context_menu.title": "移動到新類別", + "sidebar.feed_column.context_menu.rename_category": "重新命名分類", + "sidebar.feed_column.context_menu.rename_category_error": "重命名分類失敗", + "sidebar.feed_column.context_menu.rename_category_success": "分類重新命名成功", + "sidebar.feed_column.context_menu.title": "移動到新分類", "sidebar.select_sort_method": "選擇排序方式", "signin.continue_with": "透過 {{provider}} 登入", "signin.sign_in_to": "登入", @@ -367,25 +403,32 @@ "trending.feed": "熱門 RSS 摘要", "trending.list": "熱門列表", "trending.user": "熱門使用者", + "tutorial.scroll_to_exit.description": "在頂部向上捲動可快速返回時間軸。", + "tutorial.scroll_to_exit.dismiss_hint": "點擊關閉", + "tutorial.scroll_to_exit.title": "向上捲動返回", "user_button.account": "帳號", "user_button.achievement": "成就", "user_button.actions": "自動化操作", + "user_button.ai": "AI", "user_button.download_desktop_app": "下載桌面應用程式", "user_button.log_out": "登出", "user_button.power": "Power", "user_button.preferences": "偏好設定", "user_button.profile": "個人檔案", + "user_profile.about": "關於", "user_profile.close": "關閉", + "user_profile.created_lists": "已創建列表", "user_profile.edit": "編輯", "user_profile.loading": "載入中", "user_profile.share": "分享", + "user_profile.subscriptions": "訂閱", "user_profile.toggle_item_style": "切換項目樣式", "words.achievement": "成就", "words.actions": "自動化操作", "words.add": "新增", "words.all": "全部", "words.browser": "瀏覽器", - "words.categories": "類別", + "words.categories": "分類", "words.confirm": "確認", "words.discover": "發現", "words.email": "電子信箱", diff --git a/locales/errors/zh-TW.json b/locales/errors/zh-TW.json index b1be5ed31..29bd00374 100644 --- a/locales/errors/zh-TW.json +++ b/locales/errors/zh-TW.json @@ -1,6 +1,9 @@ { "1": "上一操作未完成", "3": "無法處理的內容", + "4": "輸入無效", + "5": "缺少設定", + "6": "找不到資源", "1000": "未經授權", "1001": "建立會話失敗", "1002": "參數無效", @@ -67,5 +70,16 @@ "13007": "此 RSSHub 實例目前不可用", "14000": "檔案無效", "14001": "檔案過大", - "14002": "上傳失敗" + "14002": "上傳失敗", + "15000": "AI Token 已超過限制,請稍後再試。", + "15001": "你無權存取 AI 聊天", + "15002": "AI 附件檔案數量超過限制,請稍後再試。", + "16000": "MCP OAuth 錯誤", + "16001": "MCP 探索錯誤", + "16002": "找不到 MCP 服務", + "16003": "OAuth 狀態無效或已過期", + "16004": "Token 交換失敗", + "16005": "找不到使用者 MCP 服務", + "16006": "MCP 設定錯誤", + "16007": "MCP 工具執行失敗" } diff --git a/locales/external/zh-TW.json b/locales/external/zh-TW.json index 1d66e7abc..d0f6f5f98 100644 --- a/locales/external/zh-TW.json +++ b/locales/external/zh-TW.json @@ -41,6 +41,7 @@ "login.confirm_password.label": "確認密碼", "login.continueWith": "透過 {{provider}} 登入", "login.email": "電子信箱", + "login.enter_token": "如果你已安裝客戶端但未自動跳轉,請複製下方 token 並貼到客戶端(v0.5.0+)的「請輸入授權令牌以繼續」欄位。", "login.errors.unknown": "未知錯誤", "login.forget_password.description": "輸入與您的帳號關聯的電子信箱,我們將向您發送有關如何重設密碼的電子郵件。", "login.forget_password.email_invalid": "無效的電子信箱地址", @@ -49,10 +50,12 @@ "login.forget_password.note": "忘記密碼了嗎?", "login.forget_password.success": "信件已成功發送", "login.have_account": "已有帳號?登入", + "login.lastUsed": "最近使用", "login.logInTo": "登入至 ", "login.logInWithEmail": "使用電子信箱登入", "login.new_password.label": "新密碼", "login.no_account": "沒有帳號?註冊", + "login.no_client": "未偵測到客戶端,你可以繼續使用網頁版。", "login.openApp": "開啟應用程式", "login.or": "或", "login.password": "密碼", @@ -77,6 +80,10 @@ "register.label": "創建 {{app_name}} 帳號", "register.login": "登入", "register.password": "密碼", + "register.referral.days": "使用此推薦碼註冊可獲得 {{days}} 天專業版預覽", + "register.referral.description": "使用推薦碼註冊可獲得幾日專業版預覽。", + "register.referral.invalid": "無效的推薦碼", + "register.referral.label": "推薦碼", "register.submit": "創建帳號", "words.email": "電子信箱" } diff --git a/locales/mobile/default/zh-TW.json b/locales/mobile/default/zh-TW.json index 1796f3f93..1752d89a0 100644 --- a/locales/mobile/default/zh-TW.json +++ b/locales/mobile/default/zh-TW.json @@ -2,7 +2,7 @@ "entry.pull_up_to_next_entry": "繼續上拉查看下一條內容", "entry.release_to_next_entry": "鬆開查看下一條內容", "login.back": "返回", - "login.continueWith": "使用 {{provider}} 继续", + "login.continueWith": "透過 {{provider}} 繼續", "login.have_account": "已有帳號?登入", "login.no_account": "沒有帳號?註冊", "onboarding.edit_profile": "編輯個人資料", @@ -34,7 +34,10 @@ "operation.copy_which": "複製{{which}}", "operation.copy_which_success": "{{which}}已複製到剪貼簿", "operation.delete_category": "刪除類別", + "operation.delete_category_confirm": "此操作將刪除你的類別,但其中的 RSS 摘要會被保留並按網站分組。", + "operation.delete_category_which": "刪除類別 {{category}}", "operation.edit": "編輯", + "operation.enter_new_name_for_category": "請輸入 {{category}} 的新名稱", "operation.error_since": "RSS 摘要失效:", "operation.mark_all_as_read": "全部標記為已讀", "operation.mark_all_as_read_confirm": "確認將全部標記為已讀?", @@ -60,6 +63,8 @@ "signin.sign_up_to": "註冊", "subscription_form.category": "類別", "subscription_form.category_description": "預設情況下,您的跟隨將按網站域名分組。", + "subscription_form.hide_from_timeline": "從時間軸隱藏", + "subscription_form.hide_from_timeline_description": "開啟後,此訂閱將不再顯示在主時間軸中", "subscription_form.private_follow": "私人跟隨", "subscription_form.private_follow_description": "啟用後,此跟隨將不再顯示於個人資料頁面上。", "subscription_form.title": "標題", diff --git a/locales/settings/en.json b/locales/settings/en.json index b7165df29..8bdc81330 100644 --- a/locales/settings/en.json +++ b/locales/settings/en.json @@ -212,6 +212,8 @@ "appearance.use_pointer_cursor.label": "Use Hand Cursor", "appearance.words.customize": "Customize", "common.give_star": "Love our product? Give us a star on GitHub!", + "control.paid_badge.free_limited": "This feature is limited for free plan", + "control.paid_badge.plus_or_higher": "This feature requires a Plus plan or higher to use", "customizeToolbar.more_actions.description": "Will be shown in the dropdown menu.", "customizeToolbar.more_actions.title": "More Actions", "customizeToolbar.quick_actions.description": "Customize and reorder your frequently used actions.", @@ -553,7 +555,23 @@ "notifications.test": "Test Notification", "notifications.test_success": "Test notification sent successfully.", "notifications.token": "Client Token", - "plan.description": "Enjoy every Pro feature from day one—new users get a full‑access trial, and you can keep those perks simply by inviting friends or making a small support contribution. Learn more.", + "plan.descriptions.free": "Great for beginners.", + "plan.descriptions.plus": "Unlock AI features and more feeds.", + "plan.descriptions.pro": "Full access to the best of Folo.", + "plan.features.AI_CREDIT": "AI Credits", + "plan.features.AI_ENTRY_TRANSLATION": "AI Entry Translation", + "plan.features.BOOSTS": "Feed Boosts", + "plan.features.INTEGRATION_SUPPORTED": "Third-Party Integrations", + "plan.features.MAX_ACTIONS": "Actions", + "plan.features.MAX_AI_ENTRY_SUMMARY_PER_DAY": "AI Summaries Per Day", + "plan.features.MAX_AI_REQUESTS_PER_DAY": "AI Requests Per Day", + "plan.features.MAX_AI_TASKS": "AI Tasks", + "plan.features.MAX_INBOXES": "Inbox", + "plan.features.MAX_LISTS": "List", + "plan.features.MAX_RSSHUB_SUBSCRIPTIONS": "RSSHub Subscriptions", + "plan.features.MAX_SUBSCRIPTIONS": "Feed Subscriptions", + "plan.features.PRIORITY_SUPPORT": "Priority Support", + "plan.features.PRIVATE_SUBSCRIPTION": "Private Subscriptions", "privacy.privacy": "Privacy", "privacy.terms": "Terms", "profile.avatar.cropInstructions": "Drag the crop area to adjust your avatar", @@ -684,7 +702,7 @@ "titles.referral.short": "Invite & Earn", "titles.shortcuts": "Shortcuts", "titles.sign_out": "Sign Out", - "titles.token_usage": "Token Usage", + "titles.token_usage": "AI Credits Usage", "wallet.balance.activePoints": "Active Points", "wallet.balance.dailyReward": "Your Daily Reward", "wallet.balance.title": "Your Balance", diff --git a/locales/settings/ja.json b/locales/settings/ja.json index 7321ac9ae..d58ac133f 100644 --- a/locales/settings/ja.json +++ b/locales/settings/ja.json @@ -208,6 +208,8 @@ "appearance.use_pointer_cursor.description": "マウスがインタラクティブな要素の上にあるとき、カーソルは手の形になります。", "appearance.use_pointer_cursor.label": "手の形のカーソルを使用する", "common.give_star": "私たちの製品が好きですか?GitHub で Star を付けましょう!", + "control.paid_badge.free_limited": "この機能は無料プランでは制限されています", + "control.paid_badge.plus_or_higher": "この機能を利用するには Plus プラン以上が必要です", "customizeToolbar.more_actions.description": "ドロップダウンメニューに表示されます", "customizeToolbar.more_actions.title": "その他のアクション", "customizeToolbar.quick_actions.description": "よく使用するアクションをカスタマイズして並べ替える。", @@ -549,7 +551,20 @@ "notifications.test": "テスト通知", "notifications.test_success": "テスト通知が正常に送信されました。", "notifications.token": "クライアントトークン", - "plan.description": "すべての Pro 機能を初日から利用できます。新しいユーザーはフルアクセスのトライアルを受け取ります。友達を招待するか、少額のサポート寄付をすることで、その特典を維持できます。詳細はこちら。", + "plan.features.AI_CREDIT": "AI クレジット", + "plan.features.AI_ENTRY_TRANSLATION": "AI エントリ翻訳", + "plan.features.BOOSTS": "購読フィードの加速", + "plan.features.INTEGRATION_SUPPORTED": "サードパーティ統合", + "plan.features.MAX_ACTIONS": "自動化アクション", + "plan.features.MAX_AI_ENTRY_SUMMARY_PER_DAY": "1日あたりのAI要約数", + "plan.features.MAX_AI_REQUESTS_PER_DAY": "1日あたりのAIリクエスト数", + "plan.features.MAX_AI_TASKS": "AI タスク", + "plan.features.MAX_INBOXES": "受信トレイフィード", + "plan.features.MAX_LISTS": "カスタムリスト", + "plan.features.MAX_RSSHUB_SUBSCRIPTIONS": "RSSHub サブスクリプション", + "plan.features.MAX_SUBSCRIPTIONS": "フィードサブスクリプション", + "plan.features.PRIORITY_SUPPORT": "優先サポート", + "plan.features.PRIVATE_SUBSCRIPTION": "プライベートサブスクリプション", "privacy.privacy": "プライバシー", "privacy.terms": "利用規約", "profile.avatar.cropInstructions": "ドラッグしてトリミングエリアを調整します", diff --git a/locales/settings/zh-CN.json b/locales/settings/zh-CN.json index e576fdf7b..52026381c 100644 --- a/locales/settings/zh-CN.json +++ b/locales/settings/zh-CN.json @@ -208,6 +208,8 @@ "appearance.use_pointer_cursor.description": "当鼠标悬停在任何可交互元素上时,光标会显示为手型光标。", "appearance.use_pointer_cursor.label": "使用手型光标", "common.give_star": "喜欢我们的产品吗? 在 GitHub 上给我们「Star」吧!", + "control.paid_badge.free_limited": "此功能在免费计划中有限制", + "control.paid_badge.plus_or_higher": "此功能需要 Plus 计划或更高级别才能使用", "customizeToolbar.more_actions.description": "将显示在下拉菜单中", "customizeToolbar.more_actions.title": "更多操作", "customizeToolbar.quick_actions.description": "自定义并重新排列您常用的操作", @@ -549,7 +551,20 @@ "notifications.test": "测试通知", "notifications.test_success": "测试通知发送成功。", "notifications.token": "客户端令牌", - "plan.description": "从第一天起享受所有专业版功能——新用户可获得完整试用,只需邀请朋友或小额支持贡献即可保留这些权益。了解更多。", + "plan.features.AI_CREDIT": "AI 积分", + "plan.features.AI_ENTRY_TRANSLATION": "AI 条目翻译", + "plan.features.BOOSTS": "订阅源加速", + "plan.features.INTEGRATION_SUPPORTED": "第三方集成", + "plan.features.MAX_ACTIONS": "自动化操作", + "plan.features.MAX_AI_ENTRY_SUMMARY_PER_DAY": "每日 AI 摘要次数", + "plan.features.MAX_AI_REQUESTS_PER_DAY": "每日 AI 请求次数", + "plan.features.MAX_AI_TASKS": "AI 任务", + "plan.features.MAX_INBOXES": "收件箱订阅源", + "plan.features.MAX_LISTS": "自定义列表", + "plan.features.MAX_RSSHUB_SUBSCRIPTIONS": "RSSHub 订阅", + "plan.features.MAX_SUBSCRIPTIONS": "订阅源数量", + "plan.features.PRIORITY_SUPPORT": "优先支持", + "plan.features.PRIVATE_SUBSCRIPTION": "私有订阅", "privacy.privacy": "隐私政策", "privacy.terms": "服务条款", "profile.avatar.cropInstructions": "拖动裁剪区域以调整头像", diff --git a/locales/settings/zh-TW.json b/locales/settings/zh-TW.json index 1b6ef9c30..8379295ae 100644 --- a/locales/settings/zh-TW.json +++ b/locales/settings/zh-TW.json @@ -6,7 +6,7 @@ "about.checkingForUpdates": "正在檢查更新...", "about.copyEnvironment": "複製環境", "about.environmentCopied": "環境資訊已複製", - "about.feedbackInfo": "{{appName}} ({{commitSha}}) 正處於開發早期階段。如果您有任何回饋或建議,請隨時在我們的 GitHub 上 提交問題 。", + "about.feedbackInfo": "{{appName}} ({{commitSha}}) 是開源且持續開發中的專案。如果您有任何回饋或建議,請隨時在我們的 GitHub 提出 issue。", "about.iconLibrary": "所使用的圖標庫版權由 所有,不得重新分發。", "about.legal": "法律資訊", "about.licenseInfo": "版權所有 © {{currentYear}} {{appName}}。保留所有權利。", @@ -28,6 +28,9 @@ "actions.action_card.block": "封鎖", "actions.action_card.block_rules": "封鎖規則", "actions.action_card.custom_filters": "自訂過濾條件", + "actions.action_card.empty.description": "建立首個自動化規則以自動處理您的訂閱內容。", + "actions.action_card.empty.start": "從此處開始!", + "actions.action_card.empty.title": "尚無自動化規則", "actions.action_card.enable_readability": "啟用可讀模式", "actions.action_card.feed_options.entry_attachments_duration": "條目視頻時長", "actions.action_card.feed_options.entry_author": "條目作者", @@ -57,9 +60,9 @@ "actions.action_card.operator": "運算子", "actions.action_card.or": "或", "actions.action_card.rewrite_rules": "重寫規則", - "actions.action_card.settings": "设置", + "actions.action_card.settings": "設置", "actions.action_card.silence": "靜音", - "actions.action_card.source_content": "瀏覽原始内容", + "actions.action_card.source_content": "瀏覽原始內容", "actions.action_card.star": "收藏", "actions.action_card.summary.action_count": "已啟用 {{count}} 個動作", "actions.action_card.summary.active": "啟用中", @@ -90,13 +93,19 @@ "actions.edit_rewrite_rule": "編輯覆寫規則", "actions.edit_rule": "編輯規則", "actions.edit_webhook": "編輯 Webhook", - "actions.info": "自動化操作是您可以自動化以在伺服器或客戶端執行任務的規則集合。", + "actions.info": "自動化操作是您可以自動化以在伺服器或客户端執行任務的規則集合。", "actions.navigate.prompt": "您有未儲存的自動化操作變更。您確定要離開嗎?", "actions.newRule": "新增規則", "actions.save": "儲存", "actions.saveSuccess": "🎉 規則已儲存", "actions.sidebar_title": "自動化操作", "actions.title": "自動化操作", + "ai.personalize.prompt.description": "告訴 Folo 你的閲讀偏好與個人資訊。", + "ai.personalize.prompt.label": "個人化提示", + "ai.personalize.title": "個人化", + "ai.shortcuts.title": "快捷鍵", + "appearance.accent_color.description": "選擇應用程式介面的強調色。", + "appearance.accent_color.label": "強調色", "appearance.code_highlight_theme.description": "調整語法突顯主題", "appearance.code_highlight_theme.label": "語法突顯主題", "appearance.code_highlighting.title": "語法突顯", @@ -104,6 +113,7 @@ "appearance.content": "內容", "appearance.content_display.title": "內容顯示", "appearance.content_font.default": "預設(介面字體)", + "appearance.content_font.description": "調整閲讀內容所用字體。", "appearance.content_font.label": "內容字體", "appearance.content_font_size": "內容字體大小", "appearance.content_line_height.description": "調整文章中文字行間距", @@ -118,7 +128,11 @@ "appearance.custom_css.label": "自訂 CSS", "appearance.custom_font": "自訂字體", "appearance.customization.title": "自訂", + "appearance.customize_sub_tabs.description": "自訂你的訂閱分頁。", + "appearance.customize_sub_tabs.label": "自訂訂閱分頁", + "appearance.customize_toolbar.description": "自訂條目內容工具列。", "appearance.customize_toolbar.label": "自訂工具欄", + "appearance.date_format.description": "調整日期顯示格式。", "appearance.date_format.label": "日期格式", "appearance.font.custom": "自訂", "appearance.font.system": "系統字體", @@ -143,22 +157,24 @@ "appearance.font_scaling.title": "字體縮放", "appearance.fonts": "字體", "appearance.general": "一般", + "appearance.global_font.default": "跟隨系統", "appearance.global_font_size.description": "調整整體文字大小", "appearance.global_font_size.label": "全域字體大小", "appearance.guess_code_language.description": "使用模型來推斷未標記程式碼區塊的主要程式語言", "appearance.guess_code_language.label": "推測程式碼語言", "appearance.hide_extra_badge.description": "將側邊欄中 RSS 摘要的特殊徽章隱藏,例如:已加成、已認領。", "appearance.hide_extra_badge.label": "隱藏徽章", - "appearance.hide_recent_reader.description": "隱藏條目標題顯示的最近閱讀者", - "appearance.hide_recent_reader.label": "隱藏最近閱讀者", + "appearance.hide_recent_reader.description": "隱藏條目標題顯示的最近閲讀者", + "appearance.hide_recent_reader.label": "隱藏最近閲讀者", "appearance.interface_window.title": "介面與視窗", "appearance.misc": "其他", "appearance.modal_overlay.description": "顯示遮罩效果", "appearance.modal_overlay.label": "遮罩顯示", + "appearance.opaque_sidebars.description": "讓側邊欄背景透明。", "appearance.opaque_sidebars.label": "不透明側邊欄", "appearance.reader_render_inline_style.description": "允許渲染原始 HTML 的行內樣式。", "appearance.reader_render_inline_style.label": "渲染行內樣式", - "appearance.reading_view.title": "閱讀視圖", + "appearance.reading_view.title": "閲讀視圖", "appearance.reduce_motion.description": "減少元素的動畫效果以提升效能並降低功耗。", "appearance.reduce_motion.label": "減少動畫", "appearance.save": "儲存", @@ -183,13 +199,21 @@ "appearance.thumbnail_ratio.title": "縮略比例", "appearance.title": "外觀", "appearance.typography.title": "排版", + "appearance.ui_font.description": "調整 UI 元素所用字體。", "appearance.ui_font.label": "介面字體", + "appearance.unread_count.badge.description": "在 Dock 圖示上顯示未讀數量徽章。", "appearance.unread_count.badge.label": "在 Dock 圖示上顯示", "appearance.unread_count.label": "未讀數量", + "appearance.unread_count.sidebar.description": "在 RSS 摘要與羣組旁顯示未讀數量。", + "appearance.unread_count.sidebar.title": "顯示未讀數量", + "appearance.unread_count.view_and_subscription.description": "在視圖與訂閱列表中顯示未讀數量。", "appearance.unread_count.view_and_subscription.label": "在側邊欄中顯示", - "appearance.use_pointer_cursor.description": "當滑鼠懸停在任何互動元素上時,游標會顯示為手型游標。", - "appearance.use_pointer_cursor.label": "使用手型游標", + "appearance.use_pointer_cursor.description": "當滑鼠懸停在任何互動元素上時,遊標會顯示為手型遊標。", + "appearance.use_pointer_cursor.label": "使用手指遊標", + "appearance.words.customize": "自訂", "common.give_star": "喜歡我們的產品嗎? 在 GitHub 上給我們 Star 吧!", + "control.paid_badge.free_limited": "此功能在免費方案中受限", + "control.paid_badge.plus_or_higher": "此功能需要 Plus 方案或更高級別才能使用", "customizeToolbar.more_actions.description": "將顯示在下拉選單中", "customizeToolbar.more_actions.title": "更多操作", "customizeToolbar.quick_actions.description": "自訂並重新排列您常用的操作", @@ -203,6 +227,7 @@ "data_control.clean_cache.clear": "清理", "data_control.clean_cache.description": "清理程式快取以釋放空間。", "data_control.clean_cache.description_web": "清理網頁應用服務快取以釋放空間。", + "data_control.clean_cache.success": "快取清理成功。", "data_control.data_sources": "資料來源", "data_control.export_local_database.label": "匯出本地資料庫", "data_control.import_opml.label": "從 OPML 匯入訂閱", @@ -214,9 +239,19 @@ "feeds.claimTips": "要認領您的 RSS 摘要並接收贊助,請在您的訂閱列表中右鍵點擊該 RSS 摘要,然後選擇「認領」。", "feeds.noFeeds": "沒有已認領的 RSS 摘要", "feeds.subscription": "已訂閱的 RSS 摘要", + "feeds.tableHeaders.date": "訂閱日期", + "feeds.tableHeaders.followers": "追隨者", "feeds.tableHeaders.name": "名稱", "feeds.tableHeaders.subscriptionCount": "訂閱數", "feeds.tableHeaders.tipAmount": "收到的贊助", + "feeds.tableHeaders.updatesPerWeek": "更新頻率", + "feeds.tableHeaders.view": "視圖", + "feeds.tableSelected.clear": "清除", + "feeds.tableSelected.item": "{{count}} 項選取", + "feeds.tableSelected.moveToView.action": "移動到視圖", + "feeds.tableSelected.moveToView.confirm": "您確定要將這些訂閱源移動到 {{view}} 嗎?", + "feeds.tableSelected.moveToView.confirmTitle": "確認", + "feeds.tableSelected.unsubscribe": "取消訂閱", "general.action.summary.description": "使用 AI 生成條目摘要。", "general.action.summary.label": "AI 總結", "general.action.title": "自動化操作", @@ -224,7 +259,7 @@ "general.action.translation.label": "AI 翻譯", "general.action_language.default": "預設(介面語言)", "general.action_language.description": "選擇 AI 操作的語言,例如 AI 總結、AI 翻譯。", - "general.action_language.label": "AI 输出语言", + "general.action_language.label": "AI 輸出語言", "general.advanced": "進階", "general.app": "App", "general.auto_expand_long_social_media.description": "自動擴展包含長文字的社群媒體條目。", @@ -235,8 +270,14 @@ "general.content": "內容", "general.data": "資料", "general.data_file.label": "資料檔案", + "general.dim_read.description": "淡化時間軸上已讀條目的顏色。", + "general.dim_read.label": "淡化已讀條目", "general.enhanced.description": "啟用增強設定可提供更多自訂選項,但也可能引入不可預見的問題。", "general.enhanced.disabled.tip": "增強設定已停用,您可以在「一般設定 - 進階」中啟用。", + "general.enhanced.enable.modal.cancel": "取消", + "general.enhanced.enable.modal.confirm": "啟用", + "general.enhanced.enable.modal.description": "啟用增強設定可提供更多自訂選項,但也可能引入不可預見的問題。請勿在不確定的情況下啟用此選項。", + "general.enhanced.enable.modal.title": "啟用增強設定", "general.enhanced.enabled.tip": "增強設定已啟用,您可以在「一般設定 - 進階」中停用。", "general.enhanced.label": "增強設定", "general.export.button": "匯出", @@ -265,7 +306,7 @@ "general.log_file.description": "在系統中顯示記錄檔案。", "general.log_file.label": "記錄檔案", "general.maintenance.title": "維護", - "general.mark_as_read.hover.description": "游標懸停時自動將條目標記為已讀。", + "general.mark_as_read.hover.description": "遊標懸停時自動將條目標記為已讀。", "general.mark_as_read.hover.label": "滑鼠懸停在文章上時", "general.mark_as_read.render.description": "將社群媒體貼文或圖片等單項內容立即標記為已讀。", "general.mark_as_read.render.label": "單項內容進入視圖時", @@ -290,6 +331,8 @@ "general.send_anonymous_data.label": "傳送匿名資料", "general.show_quick_timeline.description": "在 RSS 摘要列表頂部顯示快速時間軸。", "general.show_quick_timeline.label": "顯示 RSS 摘要列表時間軸", + "general.show_unread_on_launch.description": "啟動應用程式時自動篩選未讀內容。", + "general.show_unread_on_launch.label": "啟動時僅顯示未讀", "general.sidebar_title": "一般", "general.subscription": "訂閱", "general.subscriptions": "訂閱", @@ -299,6 +342,12 @@ "general.translation_mode.label": "翻譯偏好", "general.translation_mode.translation-only": "僅譯文", "general.voices": "聲音", + "integration.builtin.title": "內建整合", + "integration.categories.custom_integrations": "自訂整合", + "integration.categories.download_tools": "下載工具", + "integration.categories.knowledge_management": "知識管理", + "integration.categories.media_tools": "媒體工具", + "integration.categories.reading_services": "閲讀服務", "integration.cubox.autoMemo.description": "當選取文字儲存到 Cubox 時,自動使用備忘模式。", "integration.cubox.autoMemo.label": "自動備忘模式", "integration.cubox.enable.description": "顯示「儲存到 Cubox」按鈕(如果可用)。", @@ -306,11 +355,87 @@ "integration.cubox.title": "Cubox", "integration.cubox.token.description": "請輸入完整的 Cubox API URL,格式為:https://cubox.pro/c/api/save/xxxxxxxxx。您可以在此處獲取:", "integration.cubox.token.label": "Cubox API 網址", + "integration.custom_integrations.actions.delete": "刪除", + "integration.custom_integrations.actions.disable": "停用", + "integration.custom_integrations.actions.edit": "編輯", + "integration.custom_integrations.actions.enable": "啟用", + "integration.custom_integrations.add.button": "新增", + "integration.custom_integrations.create.error": "建立失敗", + "integration.custom_integrations.create.success": "建立成功", + "integration.custom_integrations.create.title": "建立自訂整合", + "integration.custom_integrations.delete.success": "刪除成功", + "integration.custom_integrations.edit.error": "編輯失敗", + "integration.custom_integrations.edit.success": "編輯成功", + "integration.custom_integrations.edit.title": "編輯自訂整合", + "integration.custom_integrations.enable.description": "允許使用 Fetch 模板建立自訂分享整合,支援各種 HTTP 方法與設定。", + "integration.custom_integrations.enable.label": "啟用自訂整合", + "integration.custom_integrations.form.body.description": "POST/PUT/PATCH 方法的請求主體。支援佔位符與 JSON 格式。", + "integration.custom_integrations.form.body.label": "請求主體", + "integration.custom_integrations.form.body.placeholder": "{\"title\": \"[title]\", \"url\": \"[url]\", \"content\": \"[content_markdown]\"}", + "integration.custom_integrations.form.fetch_template.label": "獲取模板", + "integration.custom_integrations.form.headers.add": "以鍵值對方式新增自訂標頭,值可使用佔位符。", + "integration.custom_integrations.form.headers.description": "自定義標頭", + "integration.custom_integrations.form.headers.key_placeholder": "標頭名稱", + "integration.custom_integrations.form.headers.label": "標頭", + "integration.custom_integrations.form.headers.value_placeholder": "標頭值", + "integration.custom_integrations.form.icon.description": "選擇整合圖示", + "integration.custom_integrations.form.icon.label": "圖示", + "integration.custom_integrations.form.method.description": "選擇請求的 HTTP 方法。", + "integration.custom_integrations.form.method.label": "HTTP 方法", + "integration.custom_integrations.form.name.label": "整合名稱", + "integration.custom_integrations.form.name.placeholder": "輸入整合名稱", + "integration.custom_integrations.form.scheme.description": "輸入外部應用程式的 URL Scheme。可使用佔位符(如 [title]、[url]、[content_markdown] 等)。", + "integration.custom_integrations.form.scheme.examples.title": "範例", + "integration.custom_integrations.form.scheme.label": "URL Scheme", + "integration.custom_integrations.form.scheme.placeholder": "例:obsidian://new?vault=MyVault&name=[title]&content=[content_markdown]", + "integration.custom_integrations.form.type.description": "選擇使用 HTTP API 請求或 URL Scheme 重定向至外部應用程式。", + "integration.custom_integrations.form.type.http": "HTTP 請求", + "integration.custom_integrations.form.type.label": "整合類型", + "integration.custom_integrations.form.type.url_scheme": "URL Scheme", + "integration.custom_integrations.form.url.description": "可使用佔位符:[title]、[url]、[content_html]、[summary]、[content_markdown]。", + "integration.custom_integrations.form.url.label": "URL", + "integration.custom_integrations.form.url.placeholder": "https://example.com/api/share", + "integration.custom_integrations.icons.bookmark": "書籤", + "integration.custom_integrations.icons.document": "文檔", + "integration.custom_integrations.icons.download": "下載", + "integration.custom_integrations.icons.external_link": "外部連結", + "integration.custom_integrations.icons.link": "連結", + "integration.custom_integrations.icons.picture": "圖片", + "integration.custom_integrations.icons.save": "保存", + "integration.custom_integrations.icons.send": "發送", + "integration.custom_integrations.icons.share": "分享", + "integration.custom_integrations.icons.star": "收藏", + "integration.custom_integrations.list.empty.button": "建立首個整合", + "integration.custom_integrations.list.empty.description": "建立自訂整合以擴充功能。", + "integration.custom_integrations.list.empty.title": "尚無自訂整合", + "integration.custom_integrations.list.title": "自定義整合列表", + "integration.custom_integrations.modal.description": "設定自訂整合參數。", + "integration.custom_integrations.placeholders.click_to_copy": "點擊複製", + "integration.custom_integrations.placeholders.description": "點擊任一佔位符以複製到剪貼簿。", + "integration.custom_integrations.placeholders.help": "可用的佔位符", + "integration.custom_integrations.preview.body": "請求主體", + "integration.custom_integrations.preview.failed": "預覽失敗", + "integration.custom_integrations.preview.generating": "正在生成預覽...", + "integration.custom_integrations.preview.headers": "請求標頭", + "integration.custom_integrations.preview.placeholders": "可用佔位符", + "integration.custom_integrations.preview.request": "請求", + "integration.custom_integrations.preview.title": "請求預覽", + "integration.custom_integrations.status.disabled": "已停用", + "integration.custom_integrations.title": "自定義整合", + "integration.custom_integrations.validation.invalid": "模板錯誤", + "integration.custom_integrations.validation.valid": "模板正確", "integration.eagle.enable.description": "顯示「將媒體儲存到 Eagle」按鈕(如果可用)。", "integration.eagle.enable.label": "啟用", "integration.eagle.title": "Eagle", + "integration.export.button": "匯出設定", + "integration.export.error": "匯出整合設定失敗", + "integration.export.success": "整合設定匯出成功", "integration.general": "通用", - "integration.instapaper.enable.description": "顯示「儲存到 Instapaper」按钮(如果可用)。", + "integration.import.button": "匯入設定", + "integration.import.error": "匯入整合設定失敗", + "integration.import.invalid": "無效的整合設定檔", + "integration.import.success": "整合設定匯入成功", + "integration.instapaper.enable.description": "顯示「儲存到 Instapaper」按鈕(如果可用)。", "integration.instapaper.enable.label": "啟用", "integration.instapaper.password.label": "Instapaper 密碼", "integration.instapaper.title": "Instapaper", @@ -329,6 +454,13 @@ "integration.outline.title": "Outline", "integration.outline.token.description": "在你的 Outline 帳戶設置中獲取。", "integration.outline.token.label": "Outline API 密鑰", + "integration.qbittorrent.enable.description": "在可用時顯示「使用 qBittorrent 下載」按鈕。", + "integration.qbittorrent.enable.label": "啟用", + "integration.qbittorrent.host.description": "你的 qBittorrent WebUI 的 URL,例如 http://localhost:8080。", + "integration.qbittorrent.host.label": "qBittorrent 主機", + "integration.qbittorrent.password.label": "qBittorrent 密碼", + "integration.qbittorrent.title": "qBittorrent", + "integration.qbittorrent.username.label": "qBittorrent 使用者名稱", "integration.readeck.enable.description": "顯示「儲存到 Readeck」按鈕(如果可用)。", "integration.readeck.enable.label": "啟用", "integration.readeck.endpoint.description": "此網址為 'https://<你的 READECK 域名>'。", @@ -336,16 +468,21 @@ "integration.readeck.title": "Readeck", "integration.readeck.token.description": "在你的 Readeck 帳戶設置中獲取。", "integration.readeck.token.label": "Readeck API 密鑰", - "integration.readwise.enable.description": "顯示「儲存到 Readwise」按钮(如果可用)。", + "integration.readwise.enable.description": "顯示「儲存到 Readwise」按鈕(如果可用)。", "integration.readwise.enable.label": "啟用", "integration.readwise.title": "Readwise", "integration.readwise.token.description": "您可以在這裡獲取:", "integration.readwise.token.label": "Readwise 存取密鑰", "integration.save_ai_summary_as_description.label": "將 AI 總結儲存為描述", - "integration.sidebar_title": "整合功能", + "integration.search.placeholder": "搜尋整合功能....", + "integration.sidebar_title": "第三方整合", + "integration.status.configured": "已配置", + "integration.status.enabled": "已啟用", "integration.tip": "提示:您的敏感資料儲存於本機,不會上傳到伺服器。", - "integration.title": "整合功能", - "integration.zotero.enable.description": "顯示「儲存到 Zotero」按钮(如果可用)。", + "integration.title": "第三方整合", + "integration.use_browser_fetch.description": "使用瀏覽器的 fetch API 進行自訂整合,而不是 Electron 的原生 fetch。啟用以獲得更好的網頁兼容性,禁用以增強安全性。", + "integration.use_browser_fetch.label": "使用瀏覽器 Fetch", + "integration.zotero.enable.description": "顯示「儲存到 Zotero」按鈕(如果可用)。", "integration.zotero.enable.label": "啟用", "integration.zotero.title": "Zotero", "integration.zotero.token.description": "你可以在此獲取 API 密鑰:", @@ -420,7 +557,18 @@ "notifications.token": "客户端令牌", "privacy.privacy": "隱私政策", "privacy.terms": "服務條款", + "profile.avatar.cropInstructions": "拖曳裁切區域以調整你的頭像", + "profile.avatar.dropZoneSubtext": "或點擊從你的電腦中選擇", + "profile.avatar.dropZoneText": "將圖片拖放到此處", + "profile.avatar.fileTooLarge": "檔案大小必須小於 {{size}}", + "profile.avatar.invalidFileType": "請選擇有效的圖片檔案", "profile.avatar.label": "頭像", + "profile.avatar.processingError": "處理圖片時發生錯誤", + "profile.avatar.selectAnother": "選擇其他圖片", + "profile.avatar.selectFile": "選擇檔案", + "profile.avatar.uploadError": "上傳頭像失敗", + "profile.avatar.uploadSuccess": "頭像上傳成功", + "profile.avatar.uploadTitle": "上傳頭像", "profile.change_password.label": "修改密碼", "profile.confirm_password.label": "確認密碼", "profile.current_password.label": "目前密碼", @@ -449,6 +597,18 @@ "profile.new_password.label": "新密碼", "profile.no_password": "重設密碼以設定新密碼。", "profile.password.label": "密碼", + "profile.profile.bio": "個人簡介", + "profile.profile.bio_placeholder": "介紹一下你自己…", + "profile.profile.changed": "個人資料已更新", + "profile.profile.save": "儲存", + "profile.profile.social_links": "社群連結", + "profile.profile.social_links_discord": "Discord ID", + "profile.profile.social_links_facebook": "Facebook ID", + "profile.profile.social_links_github": "Github ID", + "profile.profile.social_links_instagram": "Instagram ID", + "profile.profile.social_links_twitter": "Twitter ID", + "profile.profile.social_links_youtube": "Youtube ID", + "profile.profile.website": "網站", "profile.reset_password_mail_sent": "重設密碼信件已發送。", "profile.security": "安全性", "profile.set_avatar": "設定頭像", @@ -468,6 +628,13 @@ "profile.two_factor.no_password": "啟用雙因素驗證之前需要設定密碼。", "profile.updateSuccess": "個人資料已更新。", "profile.update_password_success": "密碼已更新。", + "referral.description": "將 Folo 分享給朋友!延長你的專業版預覽及未來福利,朋友也可獲得 45 天試用期。了解更多。", + "referral.invited_friend_status.pending": "等待驗證", + "referral.invited_friend_status.valid": "有效", + "referral.link": "你的邀請連結:", + "referral.pro_status.preview": "你的專業版預覽狀態:將於 {{dateString}} 到期(剩餘 {{daysLeft}} 天)", + "referral.pro_status.trial": "你目前的方案:免費", + "referral.pro_status.user": "你的專業版預覽狀態:啟用中", "rsshub.addModal.access_key_label": "存取金鑰(選填)", "rsshub.addModal.add": "新增", "rsshub.addModal.base_url_label": "基礎 URL", @@ -501,6 +668,7 @@ "titles.about": "關於", "titles.account": "帳戶", "titles.actions": "自動化操作", + "titles.ai": "AI", "titles.appearance": "外觀", "titles.data_control": "資料管理", "titles.feeds": "RSS 摘要", @@ -509,10 +677,15 @@ "titles.invitations": "邀請", "titles.lists": "列表", "titles.notifications": "通知", + "titles.plan.long": "Upgrade your plan", + "titles.plan.short": "Plan", "titles.power": "Power", "titles.privacy": "隱私", + "titles.referral.long": "邀請朋友並延長專業版", + "titles.referral.short": "邀請並賺取", "titles.shortcuts": "快捷鍵", "titles.sign_out": "登出", + "titles.token_usage": "令牌使用情況", "wallet.balance.activePoints": "活躍度", "wallet.balance.dailyReward": "每日獎勵", "wallet.balance.title": "餘額", @@ -547,15 +720,15 @@ "wallet.transactions.more": "通過區塊鏈瀏覽器查看更多交易…", "wallet.transactions.noTransactions": "無交易紀錄", "wallet.transactions.title": "交易紀錄", - "wallet.transactions.to": "接收者", - "wallet.transactions.tx": "交易", - "wallet.transactions.type": "類型", - "wallet.transactions.types.airdrop": "空投", - "wallet.transactions.types.all": "全部", - "wallet.transactions.types.burn": "銷毀", - "wallet.transactions.types.mint": "鑄造", - "wallet.transactions.types.purchase": "購買", - "wallet.transactions.types.tip": "贊助", + "wallet.transactions.to": "To", + "wallet.transactions.tx": "Tx", + "wallet.transactions.type": "Type", + "wallet.transactions.types.airdrop": "Airdrop", + "wallet.transactions.types.all": "All", + "wallet.transactions.types.burn": "Burn", + "wallet.transactions.types.mint": "Mint", + "wallet.transactions.types.purchase": "Purchase", + "wallet.transactions.types.tip": "Tip", "wallet.transactions.types.withdraw": "提領", "wallet.transactions.you": "你", "wallet.withdraw.addressLabel": "以太坊地址", diff --git a/locales/shortcuts/zh-TW.json b/locales/shortcuts/zh-TW.json index bc0c79dc8..d2d285e60 100644 --- a/locales/shortcuts/zh-TW.json +++ b/locales/shortcuts/zh-TW.json @@ -18,8 +18,12 @@ "command.entry.scroll_up.title": "向上捲動", "command.global.quick_add.description": "開啟快速新增面板以訂閱新的 RSS 摘要或其他內容。", "command.global.quick_add.title": "快速新增", + "command.global.quick_search.description": "開啟快速搜尋面板。", + "command.global.quick_search.title": "快速搜尋", "command.global.show_shortcuts.description": "顯示快捷鍵指南。", "command.global.show_shortcuts.title": "顯示快捷鍵", + "command.global.toggle_ai_chat.description": "切換 AI 聊天面板。", + "command.global.toggle_ai_chat.title": "AI 聊天", "command.global.toggle_corner_play.description": "播放或暫停播放狀態(若目前有音訊在背景播放)。", "command.global.toggle_corner_play.title": "切換角落播放", "command.layout.focus_to_entry_render.title": "聚焦到條目內容", @@ -67,9 +71,9 @@ "command.timeline.toggle_unread_only.title": "切換僅顯示未讀", "settings.shortcuts.conflict": "快捷鍵衝突", "settings.shortcuts.conflict_command": "此快捷鍵與以下指令衝突:", - "settings.shortcuts.custom": "自定義", - "settings.shortcuts.custom_content": "此快捷鍵由您自定義", - "settings.shortcuts.description": "自定義應用程式的快捷鍵。以下是一些可以自定義的指令清單。", + "settings.shortcuts.custom": "自訂", + "settings.shortcuts.custom_content": "此快捷鍵由您自訂", + "settings.shortcuts.description": "自訂應用程式的快捷鍵。以下是一些可以自訂的指令清單。", "settings.shortcuts.press_to_record": "按下以記錄", "settings.shortcuts.reset": "重設", "settings.shortcuts.undo": "復原" diff --git a/packages/internal/atoms/package.json b/packages/internal/atoms/package.json index 185a0a057..8c982271a 100644 --- a/packages/internal/atoms/package.json +++ b/packages/internal/atoms/package.json @@ -17,7 +17,10 @@ }, "dependencies": { "@follow/configs": "workspace:*", + "@follow/constants": "workspace:*", "@follow/hooks": "workspace:*", + "@follow/shared": "workspace:*", + "@follow/store": "workspace:*", "@follow/types": "workspace:*", "@follow/utils": "workspace:*", "jotai": "2.15.0" diff --git a/packages/internal/atoms/src/helper/setting.ts b/packages/internal/atoms/src/helper/setting.ts index 3c7a8f899..2f314f995 100644 --- a/packages/internal/atoms/src/helper/setting.ts +++ b/packages/internal/atoms/src/helper/setting.ts @@ -1,4 +1,7 @@ +import { UserRole } from "@follow/constants" import { useRefValue } from "@follow/hooks" +import { getSettingPaidLevel, SettingPaidLevels } from "@follow/shared/settings/constants" +import { useUserStore } from "@follow/store/user/store" import { EventBus } from "@follow/utils/event-bus" import { createAtomHooks } from "@follow/utils/jotai" import { getStorageNS } from "@follow/utils/ns" @@ -25,21 +28,66 @@ export const createSettingAtom = ( getOnInit: true, }) - const [, , useSettingValue, , getSettings, setSettings] = createAtomHooks(atom) + const [, , useSettingValueRaw, , getSettingsRaw, setSettings] = createAtomHooks(atom) const initializeDefaultSettings = () => { - const currentSettings = getSettings() + const currentSettings = getSettingsRaw() const defaultSettings = createDefaultSettings() if (typeof currentSettings !== "object") setSettings(defaultSettings) const newSettings = { ...defaultSettings, ...currentSettings } setSettings(newSettings) } - const selectAtomCacheMap = {} as Record, any> + const selectAtomCacheMap = {} as Record, any> const noopAtom = jotaiAtom(null) - const useMaybeSettingKey = >(key: Nullable) => { + const canUpdatePaidSetting = (requiredLevel?: SettingPaidLevels) => { + if (requiredLevel === undefined) return true + if ( + requiredLevel === SettingPaidLevels.Free || + requiredLevel === SettingPaidLevels.FreeLimited + ) { + return true + } + const role = useUserStore.getState().role ?? UserRole.Free + return role !== UserRole.Free && role !== UserRole.Trial + } + + const resolveAccessibleValue = ( + key: string, + value: unknown, + defaults: Record, + ) => { + const requiredLevel = getSettingPaidLevel(settingKey, key) + if (requiredLevel === undefined || canUpdatePaidSetting(requiredLevel)) { + return value + } + if (Object.prototype.hasOwnProperty.call(defaults, key)) { + return defaults[key] + } + return value + } + + const sanitizeSettingsSnapshot = (settings: ReturnType) => { + const defaults = createDefaultSettings() as Record + const raw = settings as Record + let sanitized: Record | null = null + + for (const key of Object.keys(defaults)) { + const safeValue = resolveAccessibleValue(key, raw[key], defaults) + if (safeValue !== raw[key]) { + if (!sanitized) sanitized = { ...raw } + sanitized[key] = safeValue + } + } + + return (sanitized ?? raw) as ReturnType + } + + const useMaybeSettingKey = >( + key: Nullable, + ) => { // @ts-expect-error let selectedAtom: Record[T] | null = null if (key) { @@ -52,15 +100,20 @@ export const createSettingAtom = ( selectedAtom = noopAtom } - return useAtomValue(selectedAtom) as ReturnType[T] + const value = useAtomValue(selectedAtom) as ReturnType[T] + if (!key) return value + const defaults = createDefaultSettings() as Record + return resolveAccessibleValue(String(key), value, defaults) as ReturnType< + typeof getSettingsRaw + >[T] } - const useSettingKey = >(key: T) => { - return useMaybeSettingKey(key) as ReturnType[T] + const useSettingKey = >(key: T) => { + return useMaybeSettingKey(key) as ReturnType[T] } function useSettingKeys< - T extends keyof ReturnType, + T extends keyof ReturnType, K1 extends T, K2 extends T, K3 extends T, @@ -84,22 +137,22 @@ export const createSettingAtom = ( useMaybeSettingKey(keys[8]), useMaybeSettingKey(keys[9]), ] as [ - ReturnType[K1], - ReturnType[K2], - ReturnType[K3], - ReturnType[K4], - ReturnType[K5], - ReturnType[K6], - ReturnType[K7], - ReturnType[K8], - ReturnType[K9], - ReturnType[K10], + ReturnType[K1], + ReturnType[K2], + ReturnType[K3], + ReturnType[K4], + ReturnType[K5], + ReturnType[K6], + ReturnType[K7], + ReturnType[K8], + ReturnType[K9], + ReturnType[K10], ] } const useSettingSelector = < - T extends keyof ReturnType, - S extends ReturnType, + T extends keyof ReturnType, + S extends ReturnType, R = S[T], >( selector: (s: S) => R, @@ -107,18 +160,29 @@ export const createSettingAtom = ( const stableSelector = useRefValue(selector) return useAtomValue( - // @ts-expect-error - useMemo(() => selectAtom(atom, stableSelector.current, shallow), [stableSelector]), + useMemo( + () => + selectAtom( + atom, + (state) => stableSelector.current(sanitizeSettingsSnapshot(state) as S), + shallow, + ), + [stableSelector], + ), ) } - const setSetting = >( + const setSetting = >( key: K, - value: ReturnType[K], + value: ReturnType[K], ) => { + const requiredLevel = getSettingPaidLevel(settingKey, String(key)) + if (!canUpdatePaidSetting(requiredLevel)) { + return + } const updated = Date.now() setSettings({ - ...getSettings(), + ...getSettingsRaw(), [key]: value, updated, @@ -135,6 +199,15 @@ export const createSettingAtom = ( setSettings(createDefaultSettings()) } + const useSettingValue = () => { + const value = useSettingValueRaw() + return useMemo(() => sanitizeSettingsSnapshot(value), [value]) + } + + const getSettings = () => { + return sanitizeSettingsSnapshot(getSettingsRaw()) + } + Object.defineProperty(useSettingValue, "select", { value: useSettingSelector, }) diff --git a/packages/internal/components/src/ui/progressive-blur/index.tsx b/packages/internal/components/src/ui/progressive-blur/index.tsx new file mode 100644 index 000000000..351a59470 --- /dev/null +++ b/packages/internal/components/src/ui/progressive-blur/index.tsx @@ -0,0 +1,80 @@ +import * as React from "react" + +interface LinearBlurProps extends React.HTMLAttributes { + strength?: number + steps?: number + falloffPercentage?: number + tint?: string + side?: "left" | "right" | "top" | "bottom" +} + +const oppositeSide = { + left: "right", + right: "left", + top: "bottom", + bottom: "top", +} + +export function LinearBlur({ + strength = 64, + steps = 8, + falloffPercentage = 100, + tint = "transparent", + side = "top", + ...props +}: LinearBlurProps) { + const actualSteps = Math.max(1, steps) + const step = falloffPercentage / actualSteps + + const factor = 0.5 + + const base = Math.pow(strength / factor, 1 / (actualSteps - 1)) + + const mainPercentage = 100 - falloffPercentage + + const getBackdropFilter = (i: number) => `blur(${factor * base ** (actualSteps - i - 1)}px)` + + return ( +
+
+ {/* Full blur at 100-falloffPercentage% */} + {actualSteps > 1 && ( +
+ )} + {actualSteps > 2 && + Array.from({ length: actualSteps - 2 }).map((_, i) => ( +
+ ))} +
+
+
+ ) +} diff --git a/packages/internal/components/src/ui/toast/styles.ts b/packages/internal/components/src/ui/toast/styles.ts index 84db0d1c7..b152d22ae 100644 --- a/packages/internal/components/src/ui/toast/styles.ts +++ b/packages/internal/components/src/ui/toast/styles.ts @@ -1,7 +1,7 @@ export const toastStyles = { toast: tw` group relative flex w-full items-center justify-between gap-3 rounded-2xl p-4 - backdrop-blur-2xl duration-300 ease-out overflow-hidden + backdrop-blur-2xl duration-300 ease-out max-w-md min-w-[320px] font-theme [&]:border [&]:border-solid @@ -67,7 +67,13 @@ export const toastStyles = { bg-material-ultra-thick transition-all duration-200 opacity-0 group-hover:opacity-100 - focus:outline-none focus:ring-2 focus:ring-accent/50 + focus:outline-none focus:ring-2 + group-data-[type=default]:focus:ring-[rgba(255,92,0,0.5)] + group-data-[type=success]:focus:ring-[rgba(40,205,65,0.5)] + group-data-[type=error]:focus:ring-[rgba(255,69,58,0.5)] + group-data-[type=warning]:focus:ring-[rgba(255,149,0,0.5)] + group-data-[type=info]:focus:ring-[rgba(0,122,255,0.5)] + group-data-[type=loading]:focus:ring-[rgba(142,142,147,0.5)] focus:opacity-100 `, } diff --git a/packages/internal/constants/src/enums.ts b/packages/internal/constants/src/enums.ts index 2cd116221..e1b51392e 100644 --- a/packages/internal/constants/src/enums.ts +++ b/packages/internal/constants/src/enums.ts @@ -15,6 +15,7 @@ export enum UserRole { // TODO: remove this Trial = "trial", Pro = "pro", + Plus = "plus", } export const UserRoleName: Record = { @@ -27,4 +28,5 @@ export const UserRoleName: Record = { */ [UserRole.Trial]: "Free", [UserRole.Pro]: "Pro", + [UserRole.Plus]: "Plus", } as const diff --git a/packages/internal/shared/package.json b/packages/internal/shared/package.json index 6db30f249..44d1566e9 100644 --- a/packages/internal/shared/package.json +++ b/packages/internal/shared/package.json @@ -35,7 +35,7 @@ "@electron-toolkit/preload": "3.0.2", "@electron-toolkit/tsconfig": "2.0.0", "@follow-app/client-sdk": "catalog:", - "@folo-services/drizzle": "0.1.29", + "@folo-services/drizzle": "0.1.34", "@t3-oss/env-core": "0.13.8", "ai": "5.0.76", "better-auth": "1.3.28", diff --git a/packages/internal/shared/src/settings/constants.ts b/packages/internal/shared/src/settings/constants.ts index 88e7800ba..34e2b6c66 100644 --- a/packages/internal/shared/src/settings/constants.ts +++ b/packages/internal/shared/src/settings/constants.ts @@ -1,4 +1,57 @@ -import type { AccentColor } from "./interface" +import type { + AccentColor, + AISettings, + GeneralSettings, + IntegrationSettings, + UISettings, +} from "./interface" + +export enum SettingPaidLevels { + Free, + FreeLimited, + Plus, +} + +type PartialRecord = Partial> + +export const PAID_SETTINGS = { + general: { + summary: SettingPaidLevels.FreeLimited, + translation: SettingPaidLevels.Plus, + translationMode: SettingPaidLevels.Plus, + hidePrivateSubscriptionsInTimeline: SettingPaidLevels.Plus, + }, + ui: { + hideExtraBadge: SettingPaidLevels.Plus, + hideRecentReader: SettingPaidLevels.Plus, + }, + integration: { + enableCubox: SettingPaidLevels.Plus, + enableObsidian: SettingPaidLevels.Plus, + enableOutline: SettingPaidLevels.Plus, + enableReadwise: SettingPaidLevels.Plus, + enableZotero: SettingPaidLevels.Plus, + enableInstapaper: SettingPaidLevels.Plus, + enableReadeck: SettingPaidLevels.Plus, + enableEagle: SettingPaidLevels.Plus, + enableQBittorrent: SettingPaidLevels.Plus, + enableCustomIntegration: SettingPaidLevels.Plus, + }, + ai: {}, +} as const satisfies { + general: PartialRecord + ui: PartialRecord + integration: PartialRecord + ai: PartialRecord +} + +export type SettingNamespace = keyof typeof PAID_SETTINGS + +export const getSettingPaidLevel = (namespace: string, key: string) => { + const group = PAID_SETTINGS[namespace as keyof typeof PAID_SETTINGS] + if (!group) return + return group[key as keyof typeof group] +} const ACCENT_COLOR_MAP = { orange: { @@ -40,5 +93,6 @@ export const getAccentColorValue = (color: AccentColor) => { if (color.startsWith("#")) { return { light: color, dark: color } } - return ACCENT_COLOR_MAP[color] || ACCENT_COLOR_MAP.orange + const preset = ACCENT_COLOR_MAP[color as keyof typeof ACCENT_COLOR_MAP] + return preset || ACCENT_COLOR_MAP.orange } diff --git a/packages/internal/store/package.json b/packages/internal/store/package.json index 892ab8a84..35eae29c0 100644 --- a/packages/internal/store/package.json +++ b/packages/internal/store/package.json @@ -101,7 +101,7 @@ "typecheck": "tsc --noEmit" }, "peerDependencies": { - "react": "19.2.0" + "react": "19.0.0" }, "dependencies": { "@follow-app/client-sdk": "catalog:", diff --git a/packages/internal/store/src/modules/action/hooks.ts b/packages/internal/store/src/modules/action/hooks.ts index 448e7703a..c9a25b586 100644 --- a/packages/internal/store/src/modules/action/hooks.ts +++ b/packages/internal/store/src/modules/action/hooks.ts @@ -1,6 +1,5 @@ import type { ActionConditionIndex } from "@follow-app/client-sdk" import { useMutation, useQuery } from "@tanstack/react-query" -import { FetchError } from "ofetch" import { useCallback } from "react" import type { GeneralMutationOptions } from "../../types" @@ -16,19 +15,8 @@ export const usePrefetchActions = () => { export const useUpdateActionsMutation = (options?: GeneralMutationOptions) => { return useMutation({ + ...options, mutationFn: () => actionSyncService.saveRules(), - onSuccess() { - options?.onSuccess?.() - }, - onError(err) { - if (err instanceof FetchError && err.response?._data) { - const { message } = err.response._data - options?.onError?.(message) - return - } - - options?.onError?.("Error saving actions") - }, }) } diff --git a/packages/internal/store/src/modules/subscription/store.ts b/packages/internal/store/src/modules/subscription/store.ts index c71cf24f6..bb0ab8974 100644 --- a/packages/internal/store/src/modules/subscription/store.ts +++ b/packages/internal/store/src/modules/subscription/store.ts @@ -74,6 +74,23 @@ const defaultState: SubscriptionState = { subscriptionIdSet: new Set(), categoryOpenStateByView: { ...emptyCategoryOpenStateByView }, } + +const invalidateViews = (...views: (FeedViewType | undefined)[]) => { + const viewSet = new Set() + + for (const view of views) { + if (view === undefined) continue + viewSet.add(view) + } + + if (viewSet.size === 0) return + + viewSet.add(FeedViewType.All) + + invalidateEntriesQuery({ + views: Array.from(viewSet), + }) +} export const useSubscriptionStore = createZustandStore("subscription")( () => defaultState, ) @@ -259,7 +276,7 @@ class SubscriptionSyncService { await tx.run() - invalidateEntriesQuery({ views: [subscription.view] }) + invalidateViews(subscription.view) } async subscribe(subscription: SubscriptionForm) { @@ -303,7 +320,7 @@ class SubscriptionSyncService { }, ]) - invalidateEntriesQuery({ views: [subscription.view] }) + invalidateViews(subscription.view) } async unsubscribe(id: string | undefined | null | (string | undefined | null)[]) { @@ -380,9 +397,10 @@ class SubscriptionSyncService { }) await tx.run() - invalidateEntriesQuery({ - views: Array.from(new Set([...feedSubscriptions, ...listSubscriptions].map((i) => i.view))), - }) + const affectedViews = Array.from( + new Set([...feedSubscriptions, ...listSubscriptions].map((i) => i.view)), + ) + invalidateViews(...affectedViews) feedSubscriptions.forEach((i) => { unreadActions.updateById(i.feedId, 0) @@ -585,9 +603,7 @@ class SubscriptionSyncService { view: newView, }) - invalidateEntriesQuery({ - views: [currentView, newView], - }) + invalidateViews(currentView, newView) } async renameCategory({ diff --git a/packages/internal/store/src/morph/api.ts b/packages/internal/store/src/morph/api.ts index 4b6e6346d..d3f570213 100644 --- a/packages/internal/store/src/morph/api.ts +++ b/packages/internal/store/src/morph/api.ts @@ -278,6 +278,8 @@ class APIMorph { roleEndAt: data.roleEndAt, deleted: data.deleted, stripeCustomerId: data.stripeCustomerId, + inactive: data.inactive, + lastLoginMethod: data.lastLoginMethod, } } } diff --git a/packages/internal/store/src/types.ts b/packages/internal/store/src/types.ts index 6c8c36fff..913f363f8 100644 --- a/packages/internal/store/src/types.ts +++ b/packages/internal/store/src/types.ts @@ -2,7 +2,7 @@ import type { ModuleAPIs } from "@follow-app/client-sdk" export type GeneralMutationOptions = { onSuccess?: () => void - onError?: (errorMessage: string) => void + onError?: (errorMessage: Error) => void } export type GeneralQueryOptions = { diff --git a/packages/internal/utils/src/url-for-video.ts b/packages/internal/utils/src/url-for-video.ts index ae83a39d8..7620e3d5d 100644 --- a/packages/internal/utils/src/url-for-video.ts +++ b/packages/internal/utils/src/url-for-video.ts @@ -3,6 +3,7 @@ export const transformVideoUrl = ({ mini = false, isIframe = false, attachments, + lang, }: { url: string mini?: boolean @@ -13,6 +14,7 @@ export const transformVideoUrl = ({ mime_type?: string }[] | null + lang?: string }): string | null => { if (url?.match(/\/\/www.bilibili.com\/video\/BV\w+/)) { const player = isIframe @@ -34,6 +36,8 @@ export const transformVideoUrl = ({ controls: mini ? "0" : "1", autoplay: "1", mute: mini ? "1" : "0", + hl: lang ?? "en-US", + cc_lang_pref: lang ?? "en-US", }, ).toString()}` } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3790f927a..35c65d038 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,8 +7,8 @@ settings: catalogs: default: '@follow-app/client-sdk': - specifier: 0.3.73 - version: 0.3.73 + specifier: 0.3.78 + version: 0.3.78 tailwindcss-uikit-colors: specifier: 1.0.0 version: 1.0.0 @@ -339,7 +339,7 @@ importers: version: 4.3.0 '@follow-app/client-sdk': specifier: 'catalog:' - version: 0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@follow-app/readability': specifier: workspace:* version: link:../../../../packages/readability @@ -443,6 +443,9 @@ importers: apps/desktop/layer/renderer: dependencies: + '@byjohann/toon': + specifier: 0.4.0 + version: 0.4.0 '@dnd-kit/core': specifier: 6.3.1 version: 6.3.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -454,7 +457,7 @@ importers: version: 3.0.2(electron@38.3.0) '@follow-app/client-sdk': specifier: 'catalog:' - version: 0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@follow/database': specifier: workspace:* version: link:../../../../packages/internal/database @@ -491,6 +494,9 @@ importers: '@lottiefiles/dotlottie-react': specifier: 0.17.5 version: 0.17.5(react@19.0.0) + '@number-flow/react': + specifier: 0.5.10 + version: 0.5.10(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@openpanel/web': specifier: 1.0.1 version: 1.0.1 @@ -656,9 +662,6 @@ importers: plain-shiki: specifier: 0.3.1 version: 0.3.1(shiki@3.13.0) - progressive-blur: - specifier: 1.0.0 - version: 1.0.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) re-resizable: specifier: 6.11.2 version: 6.11.2(patch_hash=adb774d32dfdf0ef779d30a8e9e35ba7f3d07706cfe61907db2a53775ea09f23)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -775,8 +778,8 @@ importers: specifier: workspace:* version: link:../../../../packages/internal/utils '@folo-services/ai-tools': - specifier: 0.2.47 - version: 0.2.47(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3) + specifier: 0.2.49 + version: 0.2.49(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3) '@types/node': specifier: 24.8.1 version: 24.8.1 @@ -807,6 +810,9 @@ importers: '@expo/react-native-action-sheet': specifier: 4.1.1 version: 4.1.1(react@19.0.0) + '@follow-app/client-sdk': + specifier: 'catalog:' + version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@follow/components': specifier: workspace:* version: link:../../packages/internal/components @@ -1187,7 +1193,7 @@ importers: version: 6.2.1 '@follow-app/client-sdk': specifier: 'catalog:' - version: 0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@follow/tracker': specifier: workspace:* version: link:../../packages/internal/tracker @@ -1226,7 +1232,7 @@ importers: version: 25.6.0(typescript@5.9.3) jotai: specifier: 2.15.0 - version: 2.15.0(@babel/core@7.28.4)(@babel/template@7.27.2)(@types/react@19.2.2)(react@19.0.0) + version: 2.15.0(@babel/core@7.28.5)(@babel/template@7.27.2)(@types/react@19.2.2)(react@19.0.0) kose-font: specifier: 1.0.0 version: 1.0.0 @@ -1259,7 +1265,7 @@ importers: version: 5.2.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react-i18next: specifier: 16.1.0 - version: 16.1.0(i18next@25.6.0(typescript@5.9.3))(react-dom@19.0.0(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)(typescript@5.9.3) + version: 16.1.0(i18next@25.6.0(typescript@5.9.3))(react-dom@19.0.0(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)(typescript@5.9.3) react-photo-view: specifier: 1.2.7 version: 1.2.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -1427,9 +1433,18 @@ importers: '@follow/configs': specifier: workspace:* version: link:../../configs + '@follow/constants': + specifier: workspace:* + version: link:../constants '@follow/hooks': specifier: workspace:* version: link:../hooks + '@follow/shared': + specifier: workspace:* + version: link:../shared + '@follow/store': + specifier: workspace:* + version: link:../store '@follow/types': specifier: workspace:* version: link:../types @@ -1438,7 +1453,7 @@ importers: version: link:../utils jotai: specifier: 2.15.0 - version: 2.15.0(@babel/core@7.28.4)(@babel/template@7.27.2)(@types/react@19.2.2)(react@19.0.0) + version: 2.15.0(@babel/core@7.28.5)(@babel/template@7.27.2)(@types/react@19.2.2)(react@19.0.0) packages/internal/components: dependencies: @@ -1585,7 +1600,7 @@ importers: version: 1.4.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) jotai: specifier: 2.15.0 - version: 2.15.0(@babel/core@7.28.4)(@babel/template@7.27.2)(@types/react@19.2.2)(react@19.0.0) + version: 2.15.0(@babel/core@7.28.5)(@babel/template@7.27.2)(@types/react@19.2.2)(react@19.0.0) katex: specifier: 0.16.25 version: 0.16.25 @@ -1609,7 +1624,7 @@ importers: version: 7.65.0(react@19.0.0) react-i18next: specifier: 16.1.0 - version: 16.1.0(i18next@25.6.0(typescript@5.9.3))(react-dom@19.0.0(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)(typescript@5.9.3) + version: 16.1.0(i18next@25.6.0(typescript@5.9.3))(react-dom@19.0.0(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)(typescript@5.9.3) rehype-infer-description-meta: specifier: 2.0.0 version: 2.0.0 @@ -1673,7 +1688,7 @@ importers: dependencies: '@follow-app/client-sdk': specifier: 'catalog:' - version: 0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@follow/configs': specifier: workspace:* version: link:../../configs @@ -1685,7 +1700,7 @@ importers: dependencies: '@follow-app/client-sdk': specifier: 'catalog:' - version: 0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@follow/constants': specifier: workspace:* version: link:../constants @@ -1700,13 +1715,13 @@ importers: version: 5.0.76(zod@4.1.12) drizzle-orm: specifier: 0.44.6 - version: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + version: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) expo-sqlite: specifier: 15.2.12 - version: 15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + version: 15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) sqlocal: specifier: npm:@hyoban/sqlocal@0.14.1-fork.4 - version: '@hyoban/sqlocal@0.14.1-fork.4(bufferutil@4.0.9)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(kysely@0.28.8)' + version: '@hyoban/sqlocal@0.14.1-fork.4(bufferutil@4.0.9)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(kysely@0.28.8)' wa-sqlite: specifier: git+https://github.com/rhashimoto/wa-sqlite.git#v1.0.8 version: https://codeload.github.com/rhashimoto/wa-sqlite/tar.gz/03c00ed67cd934bd664ae310234bba317928f851 @@ -1734,7 +1749,7 @@ importers: version: 0.2.49(react@19.0.0) jotai: specifier: 2.15.0 - version: 2.15.0(@babel/core@7.28.4)(@babel/template@7.27.2)(@types/react@19.2.2)(react@19.0.0) + version: 2.15.0(@babel/core@7.28.5)(@babel/template@7.27.2)(@types/react@19.2.2)(react@19.0.0) usehooks-ts: specifier: 3.1.1 version: 3.1.1(react@19.0.0) @@ -1757,7 +1772,7 @@ importers: dependencies: '@follow-app/client-sdk': specifier: 'catalog:' - version: 0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@follow/constants': specifier: workspace:* version: link:../constants @@ -1779,7 +1794,7 @@ importers: dependencies: '@better-auth/stripe': specifier: 1.3.28 - version: 1.3.28(@better-auth/core@1.3.28(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(better-sqlite3@12.4.1)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1))(better-auth@1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(stripe@19.1.0(@types/node@24.8.1)) + version: 1.3.28(@better-auth/core@1.3.33(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1))(better-auth@1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(stripe@19.1.0(@types/node@24.8.1)) '@electron-toolkit/preload': specifier: 3.0.2 version: 3.0.2(electron@38.3.0) @@ -1788,10 +1803,10 @@ importers: version: 2.0.0(@types/node@24.8.1) '@follow-app/client-sdk': specifier: 'catalog:' - version: 0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@folo-services/drizzle': - specifier: 0.1.29 - version: 0.1.29(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) + specifier: 0.1.34 + version: 0.1.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) '@t3-oss/env-core': specifier: 0.13.8 version: 0.13.8(arktype@2.1.20)(typescript@5.9.3)(zod@3.25.75) @@ -1803,7 +1818,7 @@ importers: version: 1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) drizzle-orm: specifier: 0.44.6 - version: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + version: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) sonner: specifier: 2.0.7 version: 2.0.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -1818,7 +1833,7 @@ importers: dependencies: '@follow-app/client-sdk': specifier: 'catalog:' - version: 0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@follow/configs': specifier: workspace:* version: link:../../configs @@ -1863,17 +1878,17 @@ importers: version: 1.255.0 posthog-react-native: specifier: ^4.6.1 - version: 4.6.1(44d673e4df26769ba228ec7d0915f53d) + version: 4.6.1(461865fcfd961a251771c2c321e278de) devDependencies: '@follow-app/client-sdk': specifier: 'catalog:' - version: 0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@follow/configs': specifier: workspace:* version: link:../../configs '@react-native-firebase/analytics': specifier: 22.2.1 - version: 22.2.1(@react-native-firebase/app@22.2.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)) + version: 22.2.1(@react-native-firebase/app@22.2.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)) packages/internal/types: {} @@ -1921,7 +1936,7 @@ importers: version: link:../../configs react-native: specifier: 0.79.6 - version: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + version: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) vite-tsconfig-paths: specifier: 5.1.4 version: 5.1.4(typescript@5.9.3)(vite@7.1.11(@types/node@24.8.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) @@ -1978,8 +1993,8 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/openai@2.0.53': - resolution: {integrity: sha512-GIkR3+Fyif516ftXv+YPSPstnAHhcZxNoR2s8uSHhQ1yBT7I7aQYTVwpjAuYoT3GR+TeP50q7onj2/nDRbT2FQ==} + '@ai-sdk/openai@2.0.56': + resolution: {integrity: sha512-D+IlvQJYvlhSMTL9t6RxwineAznyKv9j1wytjvD+mf8oivDCEyHjURXbcFKK7yyVJQTUc91YbnhjUw7YgxPbYQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -1990,6 +2005,12 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider-utils@3.0.13': + resolution: {integrity: sha512-aXFLBLRPTUYA853MJliItefSXeJPl+mg0KSjbToP41kJ+banBmHO8ZPGLJhNqGlCU82o11TYN7G05EREKX8CkA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider@2.0.0': resolution: {integrity: sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==} engines: {node: '>=18'} @@ -2046,6 +2067,10 @@ packages: resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + engines: {node: '>=6.9.0'} + '@babel/core@7.28.0': resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} engines: {node: '>=6.9.0'} @@ -2054,6 +2079,10 @@ packages: resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} engines: {node: '>=6.9.0'} + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.28.0': resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} engines: {node: '>=6.9.0'} @@ -2062,6 +2091,10 @@ packages: resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} engines: {node: '>=6.9.0'} + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} @@ -2137,6 +2170,10 @@ packages: resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.27.1': resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} @@ -2158,12 +2195,23 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1': resolution: {integrity: sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': + resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} engines: {node: '>=6.9.0'} @@ -2369,6 +2417,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-block-scoping@7.28.5': + resolution: {integrity: sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-class-properties@7.27.1': resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==} engines: {node: '>=6.9.0'} @@ -2399,6 +2453,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-destructuring@7.28.5': + resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-dotall-regex@7.27.1': resolution: {integrity: sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==} engines: {node: '>=6.9.0'} @@ -2435,6 +2495,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-exponentiation-operator@7.28.5': + resolution: {integrity: sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-export-namespace-from@7.27.1': resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} engines: {node: '>=6.9.0'} @@ -2477,6 +2543,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-logical-assignment-operators@7.28.5': + resolution: {integrity: sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-member-expression-literals@7.27.1': resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} engines: {node: '>=6.9.0'} @@ -2501,6 +2573,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-systemjs@7.28.5': + resolution: {integrity: sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-umd@7.27.1': resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} engines: {node: '>=6.9.0'} @@ -2555,6 +2633,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-optional-chaining@7.28.5': + resolution: {integrity: sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-parameters@7.27.7': resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} engines: {node: '>=6.9.0'} @@ -2705,6 +2789,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/preset-env@7.28.5': + resolution: {integrity: sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/preset-modules@0.1.6-no-external-plugins': resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} peerDependencies: @@ -2734,6 +2824,10 @@ packages: resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + '@babel/types@7.28.1': resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==} engines: {node: '>=6.9.0'} @@ -2742,6 +2836,10 @@ packages: resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + '@better-auth/core@1.3.28': resolution: {integrity: sha512-iZOGKlXaNEIEj0Q3z7+REE94I89YUJ0sel/1pvm1qqdHkm59G+ToTysHtyTcLYby3+UtAeJRKyFAY0nwJH0H7A==} peerDependencies: @@ -2753,6 +2851,16 @@ packages: kysely: ^0.28.5 nanostores: ^1.0.1 + '@better-auth/core@1.3.33': + resolution: {integrity: sha512-QDJZwGbozYVwPIR+2Odrp+vhdSF+C4Eneh1vcoILbnQT6OdVT8egpMsa/ubisHgk7VY+P5idAE45sgdAvoG6Nw==} + peerDependencies: + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.18 + better-call: 1.0.19 + jose: ^6.1.0 + kysely: ^0.28.5 + nanostores: ^1.0.1 + '@better-auth/expo@1.3.28': resolution: {integrity: sha512-P15v2x4OC5Er57/yjondWZODNrDLgCkcvFUSxMum+wgHmoUfAZ9Cg416F/JPFDfgPtSb144ea/J03z2xOcIfDw==} peerDependencies: @@ -2779,6 +2887,9 @@ packages: '@better-fetch/fetch@1.1.18': resolution: {integrity: sha512-rEFOE1MYIsBmoMJtQbl32PGHHXuG2hDxvEd7rUHE0vCBoFQVSDqaVs9hkZEtHCxRoY+CljXKFCOuJ8uxqw1LcA==} + '@byjohann/toon@0.4.0': + resolution: {integrity: sha512-3RcynuFRrGCINeKpDA3uGlKcwubSgKRmvRd4ZMgYLfnA/U/6nhf27wFqTBGGT4k6w4JVhyiGWY7iAlGl2lG6VQ==} + '@canvas/image-data@1.1.0': resolution: {integrity: sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==} @@ -4247,29 +4358,32 @@ packages: '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} - '@follow-app/client-sdk@0.3.73': - resolution: {integrity: sha512-7wxerhZbSY941QUJywQpIOEGNZ+t7UA7LQPQZ5glGyYXWVhzASqOuFKV61Ll1tUtoXm8DOFxSnYfdnuEXaHjmg==} + '@follow-app/client-sdk@0.3.78': + resolution: {integrity: sha512-I8SPfimOqNcQZrN03wolVxj7IrOje3IuIxA9CA7ulS9i2K0GNhw8k64bhSjTGutkATstdzxTkCJYfS7wn9F0dQ==} - '@folo-services/ai-tools@0.2.47': - resolution: {integrity: sha512-Od0hgzDK6pP+9pbpYpKTPU0LGFmUWUavVHeu5gyKkOTAJndnquDANtodpgRuqlZwSEa7ttYvfmh9a/8vGfKCbA==} + '@folo-services/ai-tools@0.2.49': + resolution: {integrity: sha512-QsKTW8N18812Thkdcc7wDTff3QkQxxTYHxHi1RM321jk4DbCq+mHlAr10Krwj0mRtKuULtqFHPm13udmfIv1Bw==} - '@folo-services/constants@0.1.38': - resolution: {integrity: sha512-Xv7EtoEyYYaG/bYGBWAg26Hlir7boEhdm0Q28Yp5MBl4gro2LTgfjZpSZkOQrcH1DdQk7I6Ov12ppTgvF5Qclw==} + '@folo-services/constants@0.1.41': + resolution: {integrity: sha512-fXJ5DVWMgc4czW8i9JmVx3WckKhUksiwXkzzOClH0GePEOeS+DQ08o21UfZl1pBvhvhZm0pS+klHLljeBaRb1g==} - '@folo-services/drizzle@0.1.29': - resolution: {integrity: sha512-gds7kFpkDzIiVtV4MofeffaayCo6qJdiXMDEacYdQqOVcyn+BC4S3KRpYqcGNQKZCrgw0C0o16elEqZhj7X6dg==} + '@folo-services/constants@0.1.42': + resolution: {integrity: sha512-GoHKg4Wdr+rGYGQauOhVFz+VyHZSiW1/9AGpIUa173a+HM5btvFN6e+Tu8ZNKl6Mu8J5M5GKIL0ditROp9Xv+A==} - '@folo-services/drizzle@0.1.32': - resolution: {integrity: sha512-dXgunYPWGof8Jfgd/jxy4bgT8VogP86b56aFBu8uYVFJ2n5muuGzlkv1SCsOVXU5xjo6TYceeSa5wxqlG2vekA==} + '@folo-services/drizzle@0.1.34': + resolution: {integrity: sha512-p6dsveNwXwNxmy+8+FHHKiFjVFXwc7yx7c4902k13hd1vcBihxiWUD4MdCwAcQTAPSJ3dYx1UZojHSdyiXwqnw==} - '@folo-services/exceptions@0.1.16': - resolution: {integrity: sha512-ThmLLe1Dv2CFsDIgcuY6kJhYJnjiQ7UEsewaqc25MkuImDabhzWnnad+3zRnJGLpveaMeEZ69uqUsTbKC+fR7g==} + '@folo-services/drizzle@0.1.35': + resolution: {integrity: sha512-b+5OPwjKW3gnf0lkLj7PuhjLCldD9TItXNWRwIvJrPYmIGlrQmUiKgQIuLR8dsksF9L7w8IcIi4Vt40Qppx7nQ==} - '@folo-services/exceptions@0.1.17': - resolution: {integrity: sha512-6CYgbdeS290RBp3hqUiDphQZmYFQCXqNI0i6CLNiz6a//UA05KuM3AFwGUVMQOxjODP7U9LC7Qdyajgg2AN04w==} + '@folo-services/exceptions@0.1.19': + resolution: {integrity: sha512-rXgLssE3r3w2WzC3knCX9nYe0cszHXpYwAllrYOsPpzjQSHWRwJ6LuJyt0xlvdeX/9i8KQ/UYgf4to6Abt2whg==} - '@folo-services/shared@0.0.31': - resolution: {integrity: sha512-KKn2cA3iFRL7RrYq8iT0KJhUY/xQHI3RIBjndLgJHZsP1ex/JqqLntlJePvNnJkMyUYo6O4/fbiH8pS+yEOvaA==} + '@folo-services/exceptions@0.1.20': + resolution: {integrity: sha512-iuV6F22XI6kvSSVQRTCoS/wfJnPGvI3XQbA3YQGgXa8fT28SE+8LBGCyAj0rqbfnXlXdpxZE/IooXdpJyxkp0Q==} + + '@folo-services/shared@0.0.34': + resolution: {integrity: sha512-T0gZRBlDVP9WLG0Dg8tLgWdk+TVjbdKfSvRHEyBY+YioQ1LO4vulN8ddCv1oBvMQxl0iESY9mnmB4ua9iGGkyQ==} '@fontsource/sn-pro@5.2.5': resolution: {integrity: sha512-rBdBv/0ygj6bkO7xDMMFpwobLdSrcQ2Jncb6DIwdeYGoAgeWkQRwVYhGDKasfLjEYCNYxrqr6wsXsM9+aU39RA==} @@ -4320,13 +4434,6 @@ packages: '@hexagon/base64@1.1.28': resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} - '@hono/zod-openapi@1.1.2': - resolution: {integrity: sha512-XqfK6cdEMo7Nz7N4rYgfndvQDPGf1T4TzZnG2dEqx5aIiSN4MNIC/73xy1KhUo7pGSKlf9fKL9VOtOkRUNHu6w==} - engines: {node: '>=16.0.0'} - peerDependencies: - hono: '>=4.3.6' - zod: ^4.0.0 - '@hono/zod-openapi@1.1.4': resolution: {integrity: sha512-4BbOtd6oKg20yo6HLluVbEycBLLIfdKX5o/gUSoKZ2uBmeP4Og/VDfIX3k9pbNEX5W3fRkuPeVjGA+zaQDVY1A==} engines: {node: '>=16.0.0'} @@ -4875,6 +4982,12 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} deprecated: This functionality has been moved to @npmcli/fs + '@number-flow/react@0.5.10': + resolution: {integrity: sha512-a8Wh5eNITn7Km4xbddAH7QH8eNmnduR6k34ER1hkHSGO4H2yU1DDnuAWLQM99vciGInFODemSc0tdxrXkJEpbA==} + peerDependencies: + react: 19.0.0 + react-dom: 19.0.0 + '@oclif/core@1.26.2': resolution: {integrity: sha512-6jYuZgXvHfOIc9GIaS4T3CIKGTjPmfAxuMcbCbMRKJJl4aq/4xeRlEz0E8/hz8HxvxZBGvN2GwAUHlrGWQVrVw==} engines: {node: '>=14.0.0'} @@ -6118,89 +6231,89 @@ packages: resolution: {integrity: sha512-xBaJish5OeGmniDj9cW5PRa/PtmuVU3ziqrbr5xJj901ZDN4TosrVaNZpEiLZAxdfnhAe7uQ7QFWfjPe9d9K2Q==} engines: {node: '>= 10'} - '@rolldown/binding-android-arm64@1.0.0-beta.44': - resolution: {integrity: sha512-g9ejDOehJFhxC1DIXQuZQ9bKv4lRDioOTL42cJjFjqKPl1L7DVb9QQQE1FxokGEIMr6FezLipxwnzOXWe7DNPg==} + '@rolldown/binding-android-arm64@1.0.0-beta.45': + resolution: {integrity: sha512-bfgKYhFiXJALeA/riil908+2vlyWGdwa7Ju5S+JgWZYdR4jtiPOGdM6WLfso1dojCh+4ZWeiTwPeV9IKQEX+4g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-beta.44': - resolution: {integrity: sha512-PxAW1PXLPmCzfhfKIS53kwpjLGTUdIfX4Ht+l9mj05C3lYCGaGowcNsYi2rdxWH24vSTmeK+ajDNRmmmrK0M7g==} + '@rolldown/binding-darwin-arm64@1.0.0-beta.45': + resolution: {integrity: sha512-xjCv4CRVsSnnIxTuyH1RDJl5OEQ1c9JYOwfDAHddjJDxCw46ZX9q80+xq7Eok7KC4bRSZudMJllkvOKv0T9SeA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-beta.44': - resolution: {integrity: sha512-/CtQqs1oO9uSb5Ju60rZvsdjE7Pzn8EK2ISAdl2jedjMzeD/4neNyCbwyJOAPzU+GIQTZVyrFZJX+t7HXR1R/g==} + '@rolldown/binding-darwin-x64@1.0.0-beta.45': + resolution: {integrity: sha512-ddcO9TD3D/CLUa/l8GO8LHzBOaZqWg5ClMy3jICoxwCuoz47h9dtqPsIeTiB6yR501LQTeDsjA4lIFd7u3Ljfw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-beta.44': - resolution: {integrity: sha512-V5Q5W9c4+2GJ4QabmjmVV6alY97zhC/MZBaLkDtHwGy3qwzbM4DYgXUbun/0a8AH5hGhuU27tUIlYz6ZBlvgOA==} + '@rolldown/binding-freebsd-x64@1.0.0-beta.45': + resolution: {integrity: sha512-MBTWdrzW9w+UMYDUvnEuh0pQvLENkl2Sis15fHTfHVW7ClbGuez+RWopZudIDEGkpZXdeI4CkRXk+vdIIebrmg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.44': - resolution: {integrity: sha512-X6adjkHeFqKsTU0FXdNN9HY4LDozPqIfHcnXovE5RkYLWIjMWuc489mIZ6iyhrMbCqMUla9IOsh5dvXSGT9o9A==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.45': + resolution: {integrity: sha512-4YgoCFiki1HR6oSg+GxxfzfnVCesQxLF1LEnw9uXS/MpBmuog0EOO2rYfy69rWP4tFZL9IWp6KEfGZLrZ7aUog==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.44': - resolution: {integrity: sha512-kRRKGZI4DXWa6ANFr3dLA85aSVkwPdgXaRjfanwY84tfc3LncDiIjyWCb042e3ckPzYhHSZ3LmisO+cdOIYL6Q==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.45': + resolution: {integrity: sha512-LE1gjAwQRrbCOorJJ7LFr10s5vqYf5a00V5Ea9wXcT2+56n5YosJkcp8eQ12FxRBv2YX8dsdQJb+ZTtYJwb6XQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.44': - resolution: {integrity: sha512-hMtiN9xX1NhxXBa2U3Up4XkVcsVp2h73yYtMDY59z9CDLEZLrik9RVLhBL5QtoX4zZKJ8HZKJtWuGYvtmkCbIQ==} + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.45': + resolution: {integrity: sha512-tdy8ThO/fPp40B81v0YK3QC+KODOmzJzSUOO37DinQxzlTJ026gqUSOM8tzlVixRbQJltgVDCTYF8HNPRErQTA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.44': - resolution: {integrity: sha512-rd1LzbpXQuR8MTG43JB9VyXDjG7ogSJbIkBpZEHJ8oMKzL6j47kQT5BpIXrg3b5UVygW9QCI2fpFdMocT5Kudg==} + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.45': + resolution: {integrity: sha512-lS082ROBWdmOyVY/0YB3JmsiClaWoxvC+dA8/rbhyB9VLkvVEaihLEOr4CYmrMse151C4+S6hCw6oa1iewox7g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.0-beta.44': - resolution: {integrity: sha512-qI2IiPqmPRW25exXkuQr3TlweCDc05YvvbSDRPCuPsWkwb70dTiSoXn8iFxT4PWqTi71wWHg1Wyta9PlVhX5VA==} + '@rolldown/binding-linux-x64-musl@1.0.0-beta.45': + resolution: {integrity: sha512-Hi73aYY0cBkr1/SvNQqH8Cd+rSV6S9RB5izCv0ySBcRnd/Wfn5plguUoGYwBnhHgFbh6cPw9m2dUVBR6BG1gxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.0-beta.44': - resolution: {integrity: sha512-+vHvEc1pL5iJRFlldLC8mjm6P4Qciyfh2bh5ZI6yxDQKbYhCHRKNURaKz1mFcwxhVL5YMYsLyaqM3qizVif9MQ==} + '@rolldown/binding-openharmony-arm64@1.0.0-beta.45': + resolution: {integrity: sha512-fljEqbO7RHHogNDxYtTzr+GNjlfOx21RUyGmF+NrkebZ8emYYiIqzPxsaMZuRx0rgZmVmliOzEp86/CQFDKhJQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-beta.44': - resolution: {integrity: sha512-XSgLxRrtFj6RpTeMYmmQDAwHjKseYGKUn5LPiIdW4Cq+f5SBSStL2ToBDxkbdxKPEbCZptnLPQ/nfKcAxrC8Xg==} + '@rolldown/binding-wasm32-wasi@1.0.0-beta.45': + resolution: {integrity: sha512-ZJDB7lkuZE9XUnWQSYrBObZxczut+8FZ5pdanm8nNS1DAo8zsrPuvGwn+U3fwU98WaiFsNrA4XHngesCGr8tEQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.44': - resolution: {integrity: sha512-cF1LJdDIX02cJrFrX3wwQ6IzFM7I74BYeKFkzdcIA4QZ0+2WA7/NsKIgjvrunupepWb1Y6PFWdRlHSaz5AW1Wg==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.45': + resolution: {integrity: sha512-zyzAjItHPUmxg6Z8SyRhLdXlJn3/D9KL5b9mObUrBHhWS/GwRH4665xCiFqeuktAhhWutqfc+rOV2LjK4VYQGQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.44': - resolution: {integrity: sha512-5uaJonDafhHiMn+iEh7qUp3QQ4Gihv3lEOxKfN8Vwadpy0e+5o28DWI42DpJ9YBYMrVy4JOWJ/3etB/sptpUwA==} + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.45': + resolution: {integrity: sha512-wODcGzlfxqS6D7BR0srkJk3drPwXYLu7jPHN27ce2c4PUnVVmJnp9mJzUQGT4LpmHmmVdMZ+P6hKvyTGBzc1CA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.44': - resolution: {integrity: sha512-vsqhWAFJkkmgfBN/lkLCWTXF1PuPhMjfnAyru48KvF7mVh2+K7WkKYHezF3Fjz4X/mPScOcIv+g6cf6wnI6eWg==} + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.45': + resolution: {integrity: sha512-wiU40G1nQo9rtfvF9jLbl79lUgjfaD/LTyUEw2Wg/gdF5OhjzpKMVugZQngO+RNdwYaNj+Fs+kWBWfp4VXPMHA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -6208,8 +6321,8 @@ packages: '@rolldown/pluginutils@1.0.0-beta.38': resolution: {integrity: sha512-N/ICGKleNhA5nc9XXQG/kkKHJ7S55u0x0XUJbbkmdCnFuoRkM1Il12q9q0eX19+M7KKUEPw/daUPIRnxhcxAIw==} - '@rolldown/pluginutils@1.0.0-beta.44': - resolution: {integrity: sha512-g6eW7Zwnr2c5RADIoqziHoVs6b3W5QTQ4+qbpfjbkMJ9x+8Og211VW/oot2dj9dVwaK/UyC6Yo+02gV+wWQVNg==} + '@rolldown/pluginutils@1.0.0-beta.45': + resolution: {integrity: sha512-Le9ulGCrD8ggInzWw/k2J8QcbPz7eGIOWqfJ2L+1R0Opm7n6J37s2hiDWlh6LJN0Lk9L5sUzMvRHKW7UxBZsQA==} '@rollup/plugin-babel@5.3.1': resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} @@ -8730,6 +8843,9 @@ packages: core-js-compat@3.45.1: resolution: {integrity: sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==} + core-js-compat@3.46.0: + resolution: {integrity: sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==} + core-js@3.43.0: resolution: {integrity: sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==} @@ -9293,6 +9409,98 @@ packages: sqlite3: optional: true + drizzle-orm@0.44.7: + resolution: {integrity: sha512-quIpnYznjU9lHshEOAYLoZ9s3jweleHlZIAWR/jX9gAWNg/JhQ1wj0KGRf7/Zm+obRrYd9GjPVJg790QY9N5AQ==} + peerDependencies: + '@aws-sdk/client-rds-data': '>=3' + '@cloudflare/workers-types': '>=4' + '@electric-sql/pglite': '>=0.2.0' + '@libsql/client': '>=0.10.0' + '@libsql/client-wasm': '>=0.10.0' + '@neondatabase/serverless': '>=0.10.0' + '@op-engineering/op-sqlite': '>=2' + '@opentelemetry/api': ^1.4.1 + '@planetscale/database': '>=1.13' + '@prisma/client': '*' + '@tidbcloud/serverless': '*' + '@types/better-sqlite3': '*' + '@types/pg': '*' + '@types/sql.js': '*' + '@upstash/redis': '>=1.34.7' + '@vercel/postgres': '>=0.8.0' + '@xata.io/client': '*' + better-sqlite3: '>=7' + bun-types: '*' + expo-sqlite: '>=14.0.0' + gel: '>=2' + knex: '*' + kysely: '*' + mysql2: '>=2' + pg: '>=8' + postgres: '>=3' + prisma: '*' + sql.js: '>=1' + sqlite3: '>=5' + peerDependenciesMeta: + '@aws-sdk/client-rds-data': + optional: true + '@cloudflare/workers-types': + optional: true + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + '@libsql/client-wasm': + optional: true + '@neondatabase/serverless': + optional: true + '@op-engineering/op-sqlite': + optional: true + '@opentelemetry/api': + optional: true + '@planetscale/database': + optional: true + '@prisma/client': + optional: true + '@tidbcloud/serverless': + optional: true + '@types/better-sqlite3': + optional: true + '@types/pg': + optional: true + '@types/sql.js': + optional: true + '@upstash/redis': + optional: true + '@vercel/postgres': + optional: true + '@xata.io/client': + optional: true + better-sqlite3: + optional: true + bun-types: + optional: true + expo-sqlite: + optional: true + gel: + optional: true + knex: + optional: true + kysely: + optional: true + mysql2: + optional: true + pg: + optional: true + postgres: + optional: true + prisma: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + drizzle-zod@0.8.3: resolution: {integrity: sha512-66yVOuvGhKJnTdiqj1/Xaaz9/qzOdRJADpDa68enqS6g3t0kpNkwNYjUuaeXgZfO/UWuIM9HIhSlJ6C5ZraMww==} peerDependencies: @@ -9988,6 +10196,9 @@ packages: jiti: optional: true + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + espree@10.4.0: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -12870,6 +13081,9 @@ packages: nullthrows@1.1.1: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + number-flow@0.5.8: + resolution: {integrity: sha512-FPr1DumWyGi5Nucoug14bC6xEz70A1TnhgSHhKyfqjgji2SOTz+iLJxKtv37N5JyJbteGYCm6NQ9p1O4KZ7iiA==} + nypm@0.6.2: resolution: {integrity: sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==} engines: {node: ^14.16.0 || >=16.10.0} @@ -13750,12 +13964,6 @@ packages: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} - progressive-blur@1.0.0: - resolution: {integrity: sha512-BZkJJHksqsxt9eJ+bv5ptXyUDa+ZbpOzdGJNJVxFo2qF0u+Y38E1oKWidt6JIaHCM1xk9o8LSjf9TbtHpbx9WQ==} - peerDependencies: - react: 19.0.0 - react-dom: 19.0.0 - promise-inflight@1.0.1: resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} peerDependencies: @@ -14632,8 +14840,8 @@ packages: vue-tsc: optional: true - rolldown@1.0.0-beta.44: - resolution: {integrity: sha512-gcqgyCi3g93Fhr49PKvymE8PoaGS0sf6ajQrsYaQ8o5de6aUEbD6rJZiJbhOfpcqOnycgsAsUNPYri1h25NgsQ==} + rolldown@1.0.0-beta.45: + resolution: {integrity: sha512-iMmuD72XXLf26Tqrv1cryNYLX6NNPLhZ3AmNkSf8+xda0H+yijjGJ+wVT9UdBUHOpKzq9RjKtQKRCWoEKQQBZQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -16590,9 +16798,6 @@ packages: zod@3.25.75: resolution: {integrity: sha512-OhpzAmVzabPOL6C3A3gpAifqr9MqihV/Msx3gor2b2kviCgcb+HM9SEOpMWwwNp9MRunWnhtAKUoo0AHhjyPPg==} - zod@4.1.11: - resolution: {integrity: sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==} - zod@4.1.12: resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} @@ -16663,10 +16868,10 @@ snapshots: '@vercel/oidc': 3.0.3 zod: 4.1.12 - '@ai-sdk/openai@2.0.53(zod@4.1.12)': + '@ai-sdk/openai@2.0.56(zod@4.1.12)': dependencies: '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.12(zod@4.1.12) + '@ai-sdk/provider-utils': 3.0.13(zod@4.1.12) zod: 4.1.12 '@ai-sdk/provider-utils@3.0.12(zod@3.25.75)': @@ -16683,6 +16888,13 @@ snapshots: eventsource-parser: 3.0.6 zod: 4.1.12 + '@ai-sdk/provider-utils@3.0.13(zod@4.1.12)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@standard-schema/spec': 1.0.0 + eventsource-parser: 3.0.6 + zod: 4.1.12 + '@ai-sdk/provider@2.0.0': dependencies: json-schema: 0.4.0 @@ -16720,11 +16932,6 @@ snapshots: '@ark/util@0.46.0': optional: true - '@asteasolutions/zod-to-openapi@8.1.0(zod@4.1.11)': - dependencies: - openapi3-ts: 4.5.0 - zod: 4.1.11 - '@asteasolutions/zod-to-openapi@8.1.0(zod@4.1.12)': dependencies: openapi3-ts: 4.5.0 @@ -16747,6 +16954,8 @@ snapshots: '@babel/compat-data@7.28.4': {} + '@babel/compat-data@7.28.5': {} + '@babel/core@7.28.0': dependencies: '@ampproject/remapping': 2.3.0 @@ -16787,6 +16996,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/generator@7.28.0': dependencies: '@babel/parser': 7.28.4 @@ -16803,6 +17032,14 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.27.3': dependencies: '@babel/types': 7.28.4 @@ -16842,6 +17079,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.4 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -16857,6 +17107,13 @@ snapshots: regexpu-core: 6.2.0 semver: 6.3.1 + '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.2.0 + semver: 6.3.1 + '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -16880,12 +17137,23 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + debug: 4.4.3(supports-color@8.1.1) + lodash.debounce: 4.0.8 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + '@babel/helper-globals@7.28.0': {} '@babel/helper-member-expression-to-functions@7.27.1': dependencies: '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 + '@babel/types': 7.28.5 transitivePeerDependencies: - supports-color @@ -16914,9 +17182,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.28.5 '@babel/helper-plugin-utils@7.27.1': {} @@ -16939,6 +17216,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.3 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -16958,6 +17244,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: '@babel/traverse': 7.28.4 @@ -16969,13 +17264,15 @@ snapshots: '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-option@7.27.1': {} '@babel/helper-wrap-function@7.28.3': dependencies: '@babel/template': 7.27.2 '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 + '@babel/types': 7.28.5 transitivePeerDependencies: - supports-color @@ -16995,6 +17292,10 @@ snapshots: dependencies: '@babel/types': 7.28.4 + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17003,6 +17304,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17049,6 +17358,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-proposal-decorators@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + '@babel/plugin-proposal-export-default-from@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17060,6 +17378,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-proposal-export-default-from@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17083,6 +17406,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17094,6 +17422,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17105,6 +17438,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17116,6 +17454,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17127,6 +17470,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17138,6 +17486,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-export-default-from@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17149,6 +17502,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-export-default-from@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17160,6 +17518,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17176,6 +17539,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17187,6 +17555,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17198,6 +17571,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17209,6 +17587,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17220,6 +17603,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17231,6 +17619,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17242,6 +17635,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17253,6 +17651,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17264,6 +17667,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17275,6 +17683,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17286,6 +17699,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17297,6 +17715,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17308,6 +17731,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17325,6 +17753,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17344,6 +17777,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17363,6 +17805,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17379,6 +17830,16 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-block-scoping@7.28.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-block-scoping@7.28.5(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17396,6 +17857,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17429,6 +17898,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17442,6 +17923,12 @@ snapshots: '@babel/helper-plugin-utils': 7.27.1 '@babel/template': 7.27.2 + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/template': 7.27.2 + '@babel/plugin-transform-destructuring@7.28.0(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17459,6 +17946,22 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-destructuring@7.28.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17494,6 +17997,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-exponentiation-operator@7.28.5(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17505,6 +18013,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17518,6 +18031,12 @@ snapshots: '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-flow': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-flow': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17535,6 +18054,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17554,6 +18081,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17570,6 +18106,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17581,6 +18122,16 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-logical-assignment-operators@7.28.5(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17611,6 +18162,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17621,6 +18180,16 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17642,6 +18211,12 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17658,6 +18233,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17669,6 +18249,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17692,6 +18277,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.5) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17711,6 +18307,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17728,6 +18329,22 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-chaining@7.28.5(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17739,6 +18356,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17756,6 +18378,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17775,6 +18405,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17791,6 +18430,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-display-name@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17806,6 +18450,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17817,6 +18468,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17828,6 +18484,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17851,6 +18512,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/types': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17864,6 +18536,12 @@ snapshots: '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17875,6 +18553,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17911,6 +18594,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-runtime@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5) + babel-plugin-polyfill-corejs3: 0.11.1(@babel/core@7.28.5) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17922,6 +18617,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17939,6 +18639,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -17950,6 +18658,11 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -17983,6 +18696,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-typescript@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -18007,6 +18731,12 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -18089,6 +18819,82 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/preset-env@7.28.5(@babel/core@7.28.4)': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/core': 7.28.4 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.28.4) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.4) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.4) + '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.4) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-block-scoping': 7.28.5(@babel/core@7.28.4) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.4) + '@babel/plugin-transform-classes': 7.28.4(@babel/core@7.28.4) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.4) + '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-exponentiation-operator': 7.28.5(@babel/core@7.28.4) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-logical-assignment-operators': 7.28.5(@babel/core@7.28.4) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.28.4) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.4) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.4) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.4) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.28.4) + '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.4) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.4) + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.4) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.4) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.4) + core-js-compat: 3.46.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -18121,6 +18927,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/preset-react@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-transform-react-display-name': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + '@babel/preset-typescript@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -18144,6 +18962,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/preset-typescript@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + '@babel/runtime@7.28.4': {} '@babel/template@7.27.2': @@ -18164,6 +18993,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@babel/types@7.28.1': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -18174,6 +19015,11 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@better-auth/core@1.3.28(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(better-sqlite3@12.4.1)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1)': dependencies: '@better-auth/utils': 0.3.0 @@ -18185,6 +19031,16 @@ snapshots: nanostores: 1.0.1 zod: 4.1.12 + '@better-auth/core@1.3.33(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1)': + dependencies: + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.18 + better-call: 1.0.19 + jose: 6.1.0 + kysely: 0.28.8 + nanostores: 1.0.1 + zod: 4.1.12 + '@better-auth/expo@1.3.28(da0c12289c6dd131f140e923ebf78c44)': dependencies: '@better-fetch/fetch': 1.1.18 @@ -18196,9 +19052,9 @@ snapshots: expo-web-browser: 14.2.0(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)) zod: 4.1.12 - '@better-auth/stripe@1.3.28(@better-auth/core@1.3.28(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(better-sqlite3@12.4.1)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1))(better-auth@1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(stripe@19.1.0(@types/node@24.8.1))': + '@better-auth/stripe@1.3.28(@better-auth/core@1.3.33(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1))(better-auth@1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(stripe@19.1.0(@types/node@24.8.1))': dependencies: - '@better-auth/core': 1.3.28(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(better-sqlite3@12.4.1)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1) + '@better-auth/core': 1.3.33(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1) better-auth: 1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) defu: 6.1.4 stripe: 19.1.0(@types/node@24.8.1) @@ -18220,6 +19076,8 @@ snapshots: '@better-fetch/fetch@1.1.18': {} + '@byjohann/toon@0.4.0': {} + '@canvas/image-data@1.1.0': {} '@cfcs/core@0.0.6': @@ -19609,15 +20467,20 @@ snapshots: react-native: 0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) optional: true - '@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))': - dependencies: - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) - optional: true - '@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))': dependencies: react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + '@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))': + dependencies: + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) + optional: true + + '@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))': + dependencies: + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + optional: true + '@expo/multipart-body-parser@2.0.0': dependencies: multipasta: 0.2.7 @@ -19781,13 +20644,6 @@ snapshots: react-native: 0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) optional: true - '@expo/vector-icons@14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)': - dependencies: - expo-font: 13.3.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) - react: 19.0.0 - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) - optional: true - '@expo/vector-icons@14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)': dependencies: expo-font: 13.3.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0) @@ -19799,6 +20655,20 @@ snapshots: expo-font: 13.3.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0) react: 19.0.0 react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + optional: true + + '@expo/vector-icons@14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)': + dependencies: + expo-font: 13.3.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) + optional: true + + '@expo/vector-icons@14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)': + dependencies: + expo-font: 13.3.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0) + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) '@expo/ws-tunnel@1.0.6': {} @@ -20478,12 +21348,12 @@ snapshots: '@floating-ui/utils@0.2.10': {} - '@follow-app/client-sdk@0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@follow-app/client-sdk@0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@folo-services/constants': 0.1.38 - '@folo-services/drizzle': 0.1.32(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) - '@folo-services/exceptions': 0.1.17 - '@folo-services/shared': 0.0.31(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3) + '@folo-services/constants': 0.1.42 + '@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) + '@folo-services/exceptions': 0.1.20 + '@folo-services/shared': 0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3) better-auth: 1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) zod: 4.1.12 transitivePeerDependencies: @@ -20527,12 +21397,12 @@ snapshots: - svelte - vue - '@follow-app/client-sdk@0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@follow-app/client-sdk@0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@folo-services/constants': 0.1.38 - '@folo-services/drizzle': 0.1.32(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) - '@folo-services/exceptions': 0.1.17 - '@folo-services/shared': 0.0.31(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3) + '@folo-services/constants': 0.1.42 + '@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) + '@folo-services/exceptions': 0.1.20 + '@folo-services/shared': 0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3) better-auth: 1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) zod: 4.1.12 transitivePeerDependencies: @@ -20576,12 +21446,12 @@ snapshots: - svelte - vue - '@follow-app/client-sdk@0.3.73(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@follow-app/client-sdk@0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@folo-services/constants': 0.1.38 - '@folo-services/drizzle': 0.1.32(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) - '@folo-services/exceptions': 0.1.17 - '@folo-services/shared': 0.0.31(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3) + '@folo-services/constants': 0.1.42 + '@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) + '@folo-services/exceptions': 0.1.20 + '@folo-services/shared': 0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3) better-auth: 1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) zod: 4.1.12 transitivePeerDependencies: @@ -20625,12 +21495,61 @@ snapshots: - svelte - vue - '@folo-services/ai-tools@0.2.47(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)': + '@follow-app/client-sdk@0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@ai-sdk/openai': 2.0.53(zod@4.1.12) - '@folo-services/drizzle': 0.1.32(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) + '@folo-services/constants': 0.1.42 + '@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) + '@folo-services/exceptions': 0.1.20 + '@folo-services/shared': 0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3) + better-auth: 1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + zod: 4.1.12 + transitivePeerDependencies: + - '@aws-sdk/client-rds-data' + - '@cloudflare/workers-types' + - '@electric-sql/pglite' + - '@libsql/client' + - '@libsql/client-wasm' + - '@lynx-js/react' + - '@neondatabase/serverless' + - '@op-engineering/op-sqlite' + - '@opentelemetry/api' + - '@planetscale/database' + - '@prisma/client' + - '@sveltejs/kit' + - '@tidbcloud/serverless' + - '@types/better-sqlite3' + - '@types/pg' + - '@types/sql.js' + - '@upstash/redis' + - '@vercel/postgres' + - '@xata.io/client' + - better-sqlite3 + - bun-types + - expo-sqlite + - gel + - hono + - knex + - kysely + - mysql2 + - next + - pg + - pg-native + - postgres + - prisma + - react + - react-dom + - solid-js + - sql.js + - sqlite3 + - svelte + - vue + + '@folo-services/ai-tools@0.2.49(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)': + dependencies: + '@ai-sdk/openai': 2.0.56(zod@4.1.12) + '@folo-services/drizzle': 0.1.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) ai: 5.0.76(zod@4.1.12) - drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-orm: 0.44.7(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) zod: 4.1.12 transitivePeerDependencies: - '@aws-sdk/client-rds-data' @@ -20665,54 +21584,17 @@ snapshots: - sql.js - sqlite3 - '@folo-services/constants@0.1.38': + '@folo-services/constants@0.1.41': dependencies: zod: 4.1.12 - '@folo-services/drizzle@0.1.29(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)': + '@folo-services/constants@0.1.42': dependencies: - '@folo-services/exceptions': 0.1.16 - '@hono/zod-openapi': 1.1.2(hono@4.9.8)(zod@4.1.11) - drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) - drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.11) - nanoid: 5.1.6 - pg: 8.16.3 - zod: 4.1.11 - transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@cloudflare/workers-types' - - '@electric-sql/pglite' - - '@libsql/client' - - '@libsql/client-wasm' - - '@neondatabase/serverless' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@planetscale/database' - - '@prisma/client' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/postgres' - - '@xata.io/client' - - better-sqlite3 - - bun-types - - expo-sqlite - - gel - - hono - - knex - - kysely - - mysql2 - - pg-native - - postgres - - prisma - - sql.js - - sqlite3 + zod: 4.1.12 - '@folo-services/drizzle@0.1.32(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)': + '@folo-services/drizzle@0.1.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)': dependencies: - '@folo-services/exceptions': 0.1.17 + '@folo-services/exceptions': 0.1.19 '@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12) drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) @@ -20751,12 +21633,12 @@ snapshots: - sql.js - sqlite3 - '@folo-services/drizzle@0.1.32(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)': + '@folo-services/drizzle@0.1.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)': dependencies: - '@folo-services/exceptions': 0.1.17 + '@folo-services/exceptions': 0.1.19 '@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12) - drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) - drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) nanoid: 5.1.6 pg: 8.16.3 zod: 4.1.12 @@ -20792,12 +21674,12 @@ snapshots: - sql.js - sqlite3 - '@folo-services/drizzle@0.1.32(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)': + '@folo-services/drizzle@0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)': dependencies: - '@folo-services/exceptions': 0.1.17 + '@folo-services/exceptions': 0.1.20 '@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12) - drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) - drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) nanoid: 5.1.6 pg: 8.16.3 zod: 4.1.12 @@ -20833,13 +21715,137 @@ snapshots: - sql.js - sqlite3 - '@folo-services/exceptions@0.1.16': {} - - '@folo-services/exceptions@0.1.17': {} - - '@folo-services/shared@0.0.31(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)': + '@folo-services/drizzle@0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)': dependencies: - '@folo-services/drizzle': 0.1.32(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) + '@folo-services/exceptions': 0.1.20 + '@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12) + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) + nanoid: 5.1.6 + pg: 8.16.3 + zod: 4.1.12 + transitivePeerDependencies: + - '@aws-sdk/client-rds-data' + - '@cloudflare/workers-types' + - '@electric-sql/pglite' + - '@libsql/client' + - '@libsql/client-wasm' + - '@neondatabase/serverless' + - '@op-engineering/op-sqlite' + - '@opentelemetry/api' + - '@planetscale/database' + - '@prisma/client' + - '@tidbcloud/serverless' + - '@types/better-sqlite3' + - '@types/pg' + - '@types/sql.js' + - '@upstash/redis' + - '@vercel/postgres' + - '@xata.io/client' + - better-sqlite3 + - bun-types + - expo-sqlite + - gel + - hono + - knex + - kysely + - mysql2 + - pg-native + - postgres + - prisma + - sql.js + - sqlite3 + + '@folo-services/drizzle@0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)': + dependencies: + '@folo-services/exceptions': 0.1.20 + '@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12) + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) + nanoid: 5.1.6 + pg: 8.16.3 + zod: 4.1.12 + transitivePeerDependencies: + - '@aws-sdk/client-rds-data' + - '@cloudflare/workers-types' + - '@electric-sql/pglite' + - '@libsql/client' + - '@libsql/client-wasm' + - '@neondatabase/serverless' + - '@op-engineering/op-sqlite' + - '@opentelemetry/api' + - '@planetscale/database' + - '@prisma/client' + - '@tidbcloud/serverless' + - '@types/better-sqlite3' + - '@types/pg' + - '@types/sql.js' + - '@upstash/redis' + - '@vercel/postgres' + - '@xata.io/client' + - better-sqlite3 + - bun-types + - expo-sqlite + - gel + - hono + - knex + - kysely + - mysql2 + - pg-native + - postgres + - prisma + - sql.js + - sqlite3 + + '@folo-services/drizzle@0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)': + dependencies: + '@folo-services/exceptions': 0.1.20 + '@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12) + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) + nanoid: 5.1.6 + pg: 8.16.3 + zod: 4.1.12 + transitivePeerDependencies: + - '@aws-sdk/client-rds-data' + - '@cloudflare/workers-types' + - '@electric-sql/pglite' + - '@libsql/client' + - '@libsql/client-wasm' + - '@neondatabase/serverless' + - '@op-engineering/op-sqlite' + - '@opentelemetry/api' + - '@planetscale/database' + - '@prisma/client' + - '@tidbcloud/serverless' + - '@types/better-sqlite3' + - '@types/pg' + - '@types/sql.js' + - '@upstash/redis' + - '@vercel/postgres' + - '@xata.io/client' + - better-sqlite3 + - bun-types + - expo-sqlite + - gel + - hono + - knex + - kysely + - mysql2 + - pg-native + - postgres + - prisma + - sql.js + - sqlite3 + + '@folo-services/exceptions@0.1.19': {} + + '@folo-services/exceptions@0.1.20': {} + + '@folo-services/shared@0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)': + dependencies: + '@folo-services/constants': 0.1.41 + '@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) '@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12) drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) @@ -20877,12 +21883,13 @@ snapshots: - sql.js - sqlite3 - '@folo-services/shared@0.0.31(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)': + '@folo-services/shared@0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)': dependencies: - '@folo-services/drizzle': 0.1.32(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) + '@folo-services/constants': 0.1.41 + '@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) '@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12) - drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) - drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) zod: 4.1.12 transitivePeerDependencies: - '@aws-sdk/client-rds-data' @@ -20917,12 +21924,54 @@ snapshots: - sql.js - sqlite3 - '@folo-services/shared@0.0.31(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)': + '@folo-services/shared@0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)': dependencies: - '@folo-services/drizzle': 0.1.32(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) + '@folo-services/constants': 0.1.41 + '@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) '@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12) - drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) - drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) + zod: 4.1.12 + transitivePeerDependencies: + - '@aws-sdk/client-rds-data' + - '@cloudflare/workers-types' + - '@electric-sql/pglite' + - '@libsql/client' + - '@libsql/client-wasm' + - '@neondatabase/serverless' + - '@op-engineering/op-sqlite' + - '@opentelemetry/api' + - '@planetscale/database' + - '@prisma/client' + - '@tidbcloud/serverless' + - '@types/better-sqlite3' + - '@types/pg' + - '@types/sql.js' + - '@upstash/redis' + - '@vercel/postgres' + - '@xata.io/client' + - better-sqlite3 + - bun-types + - expo-sqlite + - gel + - hono + - knex + - kysely + - mysql2 + - pg + - pg-native + - postgres + - prisma + - sql.js + - sqlite3 + + '@folo-services/shared@0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)': + dependencies: + '@folo-services/constants': 0.1.41 + '@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8) + '@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12) + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12) zod: 4.1.12 transitivePeerDependencies: - '@aws-sdk/client-rds-data' @@ -21008,14 +22057,6 @@ snapshots: '@hexagon/base64@1.1.28': {} - '@hono/zod-openapi@1.1.2(hono@4.9.8)(zod@4.1.11)': - dependencies: - '@asteasolutions/zod-to-openapi': 8.1.0(zod@4.1.11) - '@hono/zod-validator': 0.7.4(hono@4.9.8)(zod@4.1.11) - hono: 4.9.8 - openapi3-ts: 4.5.0 - zod: 4.1.11 - '@hono/zod-openapi@1.1.4(hono@4.9.8)(zod@4.1.12)': dependencies: '@asteasolutions/zod-to-openapi': 8.1.0(zod@4.1.12) @@ -21024,11 +22065,6 @@ snapshots: openapi3-ts: 4.5.0 zod: 4.1.12 - '@hono/zod-validator@0.7.4(hono@4.9.8)(zod@4.1.11)': - dependencies: - hono: 4.9.8 - zod: 4.1.11 - '@hono/zod-validator@0.7.4(hono@4.9.8)(zod@4.1.12)': dependencies: hono: 4.9.8 @@ -21052,12 +22088,12 @@ snapshots: '@hutson/parse-repository-url@5.0.0': {} - '@hyoban/sqlocal@0.14.1-fork.4(bufferutil@4.0.9)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(kysely@0.28.8)': + '@hyoban/sqlocal@0.14.1-fork.4(bufferutil@4.0.9)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(kysely@0.28.8)': dependencies: '@sqlite.org/sqlite-wasm': 3.50.0-build1 coincident: 1.2.3(bufferutil@4.0.9) optionalDependencies: - drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) kysely: 0.28.8 transitivePeerDependencies: - bufferutil @@ -21752,6 +22788,13 @@ snapshots: mkdirp: 1.0.4 rimraf: 3.0.2 + '@number-flow/react@0.5.10(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + esm-env: 1.2.2 + number-flow: 0.5.8 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + '@oclif/core@1.26.2': dependencies: '@oclif/linewrap': 1.0.0 @@ -23014,9 +24057,9 @@ snapshots: '@react-native-firebase/app': 22.2.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) superstruct: 2.0.2 - '@react-native-firebase/analytics@22.2.1(@react-native-firebase/app@22.2.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))': + '@react-native-firebase/analytics@22.2.1(@react-native-firebase/app@22.2.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))': dependencies: - '@react-native-firebase/app': 22.2.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + '@react-native-firebase/app': 22.2.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) superstruct: 2.0.2 '@react-native-firebase/app-check@22.2.1(a1bfa83ffadfedc9bd85862d3b44f7a6)': @@ -23035,13 +24078,13 @@ snapshots: transitivePeerDependencies: - '@react-native-async-storage/async-storage' - '@react-native-firebase/app@22.2.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)': + '@react-native-firebase/app@22.2.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)': dependencies: firebase: 11.3.1 react: 19.0.0 - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) optionalDependencies: - expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -23085,6 +24128,14 @@ snapshots: - '@babel/core' - supports-color + '@react-native/babel-plugin-codegen@0.79.4(@babel/core@7.28.5)': + dependencies: + '@babel/traverse': 7.28.4 + '@react-native/codegen': 0.79.4(@babel/core@7.28.5) + transitivePeerDependencies: + - '@babel/core' + - supports-color + '@react-native/babel-preset@0.79.4(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -23186,6 +24237,56 @@ snapshots: transitivePeerDependencies: - supports-color + '@react-native/babel-preset@0.79.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-export-default-from': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.5) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-block-scoping': 7.28.4(@babel/core@7.28.5) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-classes': 7.28.4(@babel/core@7.28.5) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.5) + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.5) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-display-name': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.28.5) + '@babel/plugin-transform-runtime': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.5) + '@babel/template': 7.27.2 + '@react-native/babel-plugin-codegen': 0.79.4(@babel/core@7.28.5) + babel-plugin-syntax-hermes-parser: 0.25.1 + babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.28.5) + react-refresh: 0.14.2 + transitivePeerDependencies: + - supports-color + '@react-native/codegen@0.79.4(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -23205,6 +24306,15 @@ snapshots: nullthrows: 1.1.1 yargs: 17.7.2 + '@react-native/codegen@0.79.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + glob: 7.2.3 + hermes-parser: 0.25.1 + invariant: 2.2.4 + nullthrows: 1.1.1 + yargs: 17.7.2 + '@react-native/codegen@0.79.6(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -23226,6 +24336,16 @@ snapshots: nullthrows: 1.1.1 yargs: 17.7.2 + '@react-native/codegen@0.79.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/parser': 7.28.4 + glob: 7.2.3 + hermes-parser: 0.25.1 + invariant: 2.2.4 + nullthrows: 1.1.1 + yargs: 17.7.2 + '@react-native/community-cli-plugin@0.79.6(bufferutil@4.0.9)': dependencies: '@react-native/dev-middleware': 0.79.6(bufferutil@4.0.9)(utf-8-validate@6.0.5) @@ -23248,7 +24368,7 @@ snapshots: debug: 2.6.9 invariant: 2.2.4 metro: 0.82.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) - metro-config: 0.82.4(bufferutil@4.0.9) + metro-config: 0.82.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) metro-core: 0.82.4 semver: 7.7.3 transitivePeerDependencies: @@ -23319,16 +24439,6 @@ snapshots: '@types/react': 19.2.2 optional: true - '@react-native/virtualized-lists@0.79.6(@types/react@19.2.2)(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)': - dependencies: - invariant: 2.2.4 - nullthrows: 1.1.1 - react: 19.0.0 - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) - optionalDependencies: - '@types/react': 19.2.2 - optional: true - '@react-native/virtualized-lists@0.79.6(@types/react@19.2.2)(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)': dependencies: invariant: 2.2.4 @@ -23338,6 +24448,25 @@ snapshots: optionalDependencies: '@types/react': 19.2.2 + '@react-native/virtualized-lists@0.79.6(@types/react@19.2.2)(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)': + dependencies: + invariant: 2.2.4 + nullthrows: 1.1.1 + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) + optionalDependencies: + '@types/react': 19.2.2 + optional: true + + '@react-native/virtualized-lists@0.79.6(@types/react@19.2.2)(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)': + dependencies: + invariant: 2.2.4 + nullthrows: 1.1.1 + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + optionalDependencies: + '@types/react': 19.2.2 + '@react-stately/flags@3.1.2': dependencies: '@swc/helpers': 0.5.17 @@ -23406,53 +24535,53 @@ snapshots: '@resvg/resvg-js-win32-ia32-msvc': 2.6.2 '@resvg/resvg-js-win32-x64-msvc': 2.6.2 - '@rolldown/binding-android-arm64@1.0.0-beta.44': + '@rolldown/binding-android-arm64@1.0.0-beta.45': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-beta.44': + '@rolldown/binding-darwin-arm64@1.0.0-beta.45': optional: true - '@rolldown/binding-darwin-x64@1.0.0-beta.44': + '@rolldown/binding-darwin-x64@1.0.0-beta.45': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-beta.44': + '@rolldown/binding-freebsd-x64@1.0.0-beta.45': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.44': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.45': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.44': + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.45': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.44': + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.45': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.44': + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.45': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-beta.44': + '@rolldown/binding-linux-x64-musl@1.0.0-beta.45': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-beta.44': + '@rolldown/binding-openharmony-arm64@1.0.0-beta.45': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-beta.44': + '@rolldown/binding-wasm32-wasi@1.0.0-beta.45': dependencies: '@napi-rs/wasm-runtime': 1.0.7 optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.44': + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.45': optional: true - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.44': + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.45': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.44': + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.45': optional: true '@rolldown/pluginutils@1.0.0-beta.38': {} - '@rolldown/pluginutils@1.0.0-beta.44': {} + '@rolldown/pluginutils@1.0.0-beta.45': {} '@rollup/plugin-babel@5.3.1(@babel/core@7.28.4)(@types/babel__core@7.20.5)(rollup@2.79.2)': dependencies: @@ -25457,6 +26586,19 @@ snapshots: transitivePeerDependencies: - supports-color + babel-jest@29.7.0(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.28.5) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + babel-plugin-inline-import@3.0.0: dependencies: require-resolve: 0.0.2 @@ -25497,6 +26639,15 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.5): + dependencies: + '@babel/compat-data': 7.28.4 + '@babel/core': 7.28.5 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + babel-plugin-polyfill-corejs3@0.11.1(@babel/core@7.28.0): dependencies: '@babel/core': 7.28.0 @@ -25514,6 +26665,14 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-polyfill-corejs3@0.11.1(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + core-js-compat: 3.45.1 + transitivePeerDependencies: + - supports-color + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.4): dependencies: '@babel/core': 7.28.4 @@ -25537,6 +26696,13 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + babel-plugin-react-native-web@0.19.13: {} babel-plugin-syntax-hermes-parser@0.25.1: @@ -25556,6 +26722,12 @@ snapshots: transitivePeerDependencies: - '@babel/core' + babel-plugin-transform-flow-enums@0.0.2(@babel/core@7.28.5): + dependencies: + '@babel/plugin-syntax-flow': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - '@babel/core' + babel-preset-current-node-syntax@1.1.0(@babel/core@7.28.0): dependencies: '@babel/core': 7.28.0 @@ -25595,6 +26767,25 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.4) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.4) + babel-preset-current-node-syntax@1.1.0(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.5) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.5) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.5) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.5) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.5) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.5) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.5) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.5) + babel-preset-expo@13.2.1(@babel/core@7.28.0): dependencies: '@babel/helper-module-imports': 7.27.1 @@ -25650,6 +26841,33 @@ snapshots: - '@babel/core' - supports-color + babel-preset-expo@13.2.1(@babel/core@7.28.5): + dependencies: + '@babel/helper-module-imports': 7.27.1 + '@babel/plugin-proposal-decorators': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-export-default-from': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.5) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-runtime': 7.27.1(@babel/core@7.28.5) + '@babel/preset-react': 7.27.1(@babel/core@7.28.5) + '@babel/preset-typescript': 7.27.1(@babel/core@7.28.5) + '@react-native/babel-preset': 0.79.4(@babel/core@7.28.5) + babel-plugin-react-native-web: 0.19.13 + babel-plugin-syntax-hermes-parser: 0.25.1 + babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.28.5) + debug: 4.4.3(supports-color@8.1.1) + react-refresh: 0.14.2 + resolve-from: 5.0.0 + transitivePeerDependencies: + - '@babel/core' + - supports-color + babel-preset-jest@29.6.3(@babel/core@7.28.0): dependencies: '@babel/core': 7.28.0 @@ -25663,6 +26881,12 @@ snapshots: babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.28.4) + babel-preset-jest@29.6.3(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.28.5) + badgin@1.2.3: {} bail@2.0.2: {} @@ -26501,6 +27725,10 @@ snapshots: dependencies: browserslist: 4.26.2 + core-js-compat@3.46.0: + dependencies: + browserslist: 4.26.3 + core-js@3.43.0: {} core-js@3.45.1: {} @@ -26990,12 +28218,12 @@ snapshots: kysely: 0.28.8 pg: 8.16.3 - drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3): + drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3): optionalDependencies: '@opentelemetry/api': 1.9.0 '@types/pg': 8.15.5 better-sqlite3: 12.4.1 - expo-sqlite: 15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) + expo-sqlite: 15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) kysely: 0.28.8 pg: 8.16.3 @@ -27008,24 +28236,51 @@ snapshots: kysely: 0.28.8 pg: 8.16.3 + drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3): + optionalDependencies: + '@opentelemetry/api': 1.9.0 + '@types/pg': 8.15.5 + better-sqlite3: 12.4.1 + expo-sqlite: 15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) + kysely: 0.28.8 + pg: 8.16.3 + + drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3): + optionalDependencies: + '@opentelemetry/api': 1.9.0 + '@types/pg': 8.15.5 + better-sqlite3: 12.4.1 + expo-sqlite: 15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + kysely: 0.28.8 + pg: 8.16.3 + + drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3): + optionalDependencies: + '@opentelemetry/api': 1.9.0 + '@types/pg': 8.15.5 + better-sqlite3: 12.4.1 + expo-sqlite: 15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + kysely: 0.28.8 + pg: 8.16.3 + drizzle-zod@0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12): dependencies: drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) zod: 4.1.12 - drizzle-zod@0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12): + drizzle-zod@0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12): dependencies: - drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) zod: 4.1.12 - drizzle-zod@0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.11): + drizzle-zod@0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12): dependencies: - drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) - zod: 4.1.11 + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + zod: 4.1.12 - drizzle-zod@0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12): + drizzle-zod@0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12): dependencies: - drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) + drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3) zod: 4.1.12 ds-store@0.1.6: @@ -28099,6 +29354,8 @@ snapshots: transitivePeerDependencies: - supports-color + esm-env@1.2.2: {} + espree@10.4.0: dependencies: acorn: 8.15.0 @@ -28180,9 +29437,9 @@ snapshots: dependencies: expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) - expo-application@6.1.4(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)): + expo-application@6.1.4(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)): dependencies: - expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) optional: true expo-asset@11.1.5(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): @@ -28196,17 +29453,6 @@ snapshots: - supports-color optional: true - expo-asset@11.1.5(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): - dependencies: - '@expo/image-utils': 0.7.4 - expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) - expo-constants: 17.1.6(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)) - react: 19.0.0 - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) - transitivePeerDependencies: - - supports-color - optional: true - expo-asset@11.1.5(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: '@expo/image-utils': 0.7.4 @@ -28226,6 +29472,28 @@ snapshots: react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) transitivePeerDependencies: - supports-color + optional: true + + expo-asset@11.1.5(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): + dependencies: + '@expo/image-utils': 0.7.4 + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) + expo-constants: 17.1.6(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)) + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - supports-color + optional: true + + expo-asset@11.1.5(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): + dependencies: + '@expo/image-utils': 0.7.4 + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + expo-constants: 17.1.6(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)) + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + transitivePeerDependencies: + - supports-color expo-background-task@0.2.7(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)): dependencies: @@ -28262,16 +29530,6 @@ snapshots: - supports-color optional: true - expo-constants@17.1.6(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)): - dependencies: - '@expo/config': 11.0.10 - '@expo/env': 1.0.7 - expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) - transitivePeerDependencies: - - supports-color - optional: true - expo-constants@17.1.6(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)): dependencies: '@expo/config': 11.0.10 @@ -28289,6 +29547,26 @@ snapshots: react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) transitivePeerDependencies: - supports-color + optional: true + + expo-constants@17.1.6(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)): + dependencies: + '@expo/config': 11.0.10 + '@expo/env': 1.0.7 + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - supports-color + optional: true + + expo-constants@17.1.6(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)): + dependencies: + '@expo/config': 11.0.10 + '@expo/env': 1.0.7 + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + transitivePeerDependencies: + - supports-color expo-crypto@15.0.7(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)): dependencies: @@ -28330,9 +29608,9 @@ snapshots: expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) ua-parser-js: 0.7.40 - expo-device@7.1.4(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)): + expo-device@7.1.4(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)): dependencies: - expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) ua-parser-js: 0.7.40 optional: true @@ -28353,12 +29631,6 @@ snapshots: react-native: 0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) optional: true - expo-file-system@18.1.10(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)): - dependencies: - expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) - optional: true - expo-file-system@18.1.10(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)): dependencies: expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) @@ -28368,6 +29640,18 @@ snapshots: dependencies: expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + optional: true + + expo-file-system@18.1.10(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)): + dependencies: + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) + optional: true + + expo-file-system@18.1.10(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)): + dependencies: + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0): dependencies: @@ -28376,13 +29660,6 @@ snapshots: react: 19.0.0 optional: true - expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): - dependencies: - expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) - fontfaceobserver: 2.3.0 - react: 19.0.0 - optional: true - expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0): dependencies: expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) @@ -28394,6 +29671,20 @@ snapshots: expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) fontfaceobserver: 2.3.0 react: 19.0.0 + optional: true + + expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): + dependencies: + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) + fontfaceobserver: 2.3.0 + react: 19.0.0 + optional: true + + expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0): + dependencies: + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + fontfaceobserver: 2.3.0 + react: 19.0.0 expo-glass-effect@0.1.4(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: @@ -28441,12 +29732,6 @@ snapshots: react: 19.0.0 optional: true - expo-keep-awake@14.1.4(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): - dependencies: - expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) - react: 19.0.0 - optional: true - expo-keep-awake@14.1.4(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0): dependencies: expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) @@ -28456,6 +29741,18 @@ snapshots: dependencies: expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) react: 19.0.0 + optional: true + + expo-keep-awake@14.1.4(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): + dependencies: + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) + react: 19.0.0 + optional: true + + expo-keep-awake@14.1.4(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0): + dependencies: + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + react: 19.0.0 expo-linear-gradient@14.1.5(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: @@ -28479,9 +29776,9 @@ snapshots: react: 19.0.0 rtl-detect: 1.1.2 - expo-localization@16.1.5(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0): + expo-localization@16.1.5(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0): dependencies: - expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) react: 19.0.0 rtl-detect: 1.1.2 optional: true @@ -28551,14 +29848,6 @@ snapshots: react-native: 0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) optional: true - expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): - dependencies: - await-lock: 2.2.2 - expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) - react: 19.0.0 - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) - optional: true - expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: await-lock: 2.2.2 @@ -28572,6 +29861,22 @@ snapshots: expo: 53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) react: 19.0.0 react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + optional: true + + expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): + dependencies: + await-lock: 2.2.2 + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5) + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) + optional: true + + expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): + dependencies: + await-lock: 2.2.2 + expo: 53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) expo-status-bar@2.2.3(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: @@ -28673,39 +29978,6 @@ snapshots: - utf-8-validate optional: true - expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5): - dependencies: - '@babel/runtime': 7.28.4 - '@expo/cli': 0.24.15(bufferutil@4.0.9)(graphql@16.8.1)(utf-8-validate@6.0.5) - '@expo/config': 11.0.10 - '@expo/config-plugins': 10.0.3 - '@expo/fingerprint': 0.13.1 - '@expo/metro-config': 0.20.15 - '@expo/vector-icons': 14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) - babel-preset-expo: 13.2.1(@babel/core@7.28.4) - expo-asset: 11.1.5(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) - expo-constants: 17.1.6(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)) - expo-file-system: 18.1.10(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)) - expo-font: 13.3.1(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) - expo-keep-awake: 14.1.4(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) - expo-modules-autolinking: 2.1.12 - expo-modules-core: 2.4.0 - react: 19.0.0 - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) - react-native-edge-to-edge: 1.6.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) - whatwg-url-without-unicode: 8.0.0-3 - optionalDependencies: - '@expo/metro-runtime': 5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)) - react-native-webview: 13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-react-compiler - - bufferutil - - graphql - - supports-color - - utf-8-validate - optional: true - expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: '@babel/runtime': 7.28.4 @@ -28769,6 +30041,72 @@ snapshots: - graphql - supports-color - utf-8-validate + optional: true + + expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5): + dependencies: + '@babel/runtime': 7.28.4 + '@expo/cli': 0.24.15(bufferutil@4.0.9)(graphql@16.8.1)(utf-8-validate@6.0.5) + '@expo/config': 11.0.10 + '@expo/config-plugins': 10.0.3 + '@expo/fingerprint': 0.13.1 + '@expo/metro-config': 0.20.15 + '@expo/vector-icons': 14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) + babel-preset-expo: 13.2.1(@babel/core@7.28.5) + expo-asset: 11.1.5(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) + expo-constants: 17.1.6(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)) + expo-file-system: 18.1.10(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)) + expo-font: 13.3.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) + expo-keep-awake: 14.1.4(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) + expo-modules-autolinking: 2.1.12 + expo-modules-core: 2.4.0 + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) + react-native-edge-to-edge: 1.6.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) + whatwg-url-without-unicode: 8.0.0-3 + optionalDependencies: + '@expo/metro-runtime': 5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)) + react-native-webview: 13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-react-compiler + - bufferutil + - graphql + - supports-color + - utf-8-validate + optional: true + + expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): + dependencies: + '@babel/runtime': 7.28.4 + '@expo/cli': 0.24.15(bufferutil@4.0.9)(graphql@16.8.1)(utf-8-validate@6.0.5) + '@expo/config': 11.0.10 + '@expo/config-plugins': 10.0.3 + '@expo/fingerprint': 0.13.1 + '@expo/metro-config': 0.20.15 + '@expo/vector-icons': 14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + babel-preset-expo: 13.2.1(@babel/core@7.28.5) + expo-asset: 11.1.5(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + expo-constants: 17.1.6(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)) + expo-file-system: 18.1.10(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)) + expo-font: 13.3.1(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0) + expo-keep-awake: 14.1.4(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0) + expo-modules-autolinking: 2.1.12 + expo-modules-core: 2.4.0 + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + react-native-edge-to-edge: 1.6.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + whatwg-url-without-unicode: 8.0.0-3 + optionalDependencies: + '@expo/metro-runtime': 5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)) + react-native-webview: 13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-react-compiler + - bufferutil + - graphql + - supports-color + - utf-8-validate exponential-backoff@3.1.2: {} @@ -30370,6 +31708,13 @@ snapshots: '@types/react': 19.2.2 react: 19.0.0 + jotai@2.15.0(@babel/core@7.28.5)(@babel/template@7.27.2)(@types/react@19.2.2)(react@19.0.0): + optionalDependencies: + '@babel/core': 7.28.5 + '@babel/template': 7.27.2 + '@types/react': 19.2.2 + react: 19.0.0 + jpeg-js@0.4.4: {} js-tokens@4.0.0: {} @@ -31158,6 +32503,22 @@ snapshots: - supports-color - utf-8-validate + metro-config@0.82.4(bufferutil@4.0.9)(utf-8-validate@6.0.5): + dependencies: + connect: 3.7.0 + cosmiconfig: 5.2.1 + flow-enums-runtime: 0.0.6 + jest-validate: 29.7.0 + metro: 0.82.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) + metro-cache: 0.82.4 + metro-core: 0.82.4 + metro-runtime: 0.82.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + optional: true + metro-core@0.82.4: dependencies: flow-enums-runtime: 0.0.6 @@ -31343,7 +32704,7 @@ snapshots: metro-babel-transformer: 0.82.4 metro-cache: 0.82.4 metro-cache-key: 0.82.4 - metro-config: 0.82.4(bufferutil@4.0.9) + metro-config: 0.82.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) metro-core: 0.82.4 metro-file-map: 0.82.4 metro-resolver: 0.82.4 @@ -31926,6 +33287,10 @@ snapshots: nullthrows@1.1.1: {} + number-flow@0.5.8: + dependencies: + esm-env: 1.2.2 + nypm@0.6.2: dependencies: citty: 0.1.6 @@ -32618,17 +33983,17 @@ snapshots: preact: 10.26.9 web-vitals: 4.2.4 - posthog-react-native@4.6.1(44d673e4df26769ba228ec7d0915f53d): + posthog-react-native@4.6.1(461865fcfd961a251771c2c321e278de): dependencies: '@posthog/core': 1.1.0 - react-native-svg: 15.13.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + react-native-svg: 15.13.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) optionalDependencies: - expo-application: 6.1.4(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)) - expo-device: 7.1.4(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)) - expo-file-system: 18.1.10(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)) - expo-localization: 16.1.5(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0) - react-native-device-info: 14.1.1(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)) - react-native-safe-area-context: 5.6.1(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + expo-application: 6.1.4(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)) + expo-device: 7.1.4(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)) + expo-file-system: 18.1.10(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)) + expo-localization: 16.1.5(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react@19.0.0) + react-native-device-info: 14.1.1(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)) + react-native-safe-area-context: 5.6.1(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) posthog-react-native@4.6.1(4874fc532e43aacd471f0c07439ae4e2): dependencies: @@ -32701,11 +34066,6 @@ snapshots: progress@2.0.3: {} - progressive-blur@1.0.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - promise-inflight@1.0.1: {} promise-limit@2.7.0: {} @@ -32920,6 +34280,17 @@ snapshots: react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) typescript: 5.9.3 + react-i18next@16.1.0(i18next@25.6.0(typescript@5.9.3))(react-dom@19.0.0(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0)(typescript@5.9.3): + dependencies: + '@babel/runtime': 7.28.4 + html-parse-stringify: 3.0.1 + i18next: 25.6.0(typescript@5.9.3) + react: 19.0.0 + optionalDependencies: + react-dom: 19.0.0(react@19.0.0) + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + typescript: 5.9.3 + react-intersection-observer@9.16.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: react: 19.0.0 @@ -32996,23 +34367,33 @@ snapshots: dependencies: react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + react-native-device-info@14.1.1(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)): + dependencies: + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + optional: true + react-native-edge-to-edge@1.6.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: react: 19.0.0 react-native: 0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) optional: true - react-native-edge-to-edge@1.6.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): - dependencies: - react: 19.0.0 - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) - optional: true - react-native-edge-to-edge@1.6.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: react: 19.0.0 react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + react-native-edge-to-edge@1.6.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): + dependencies: + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) + optional: true + + react-native-edge-to-edge@1.6.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): + dependencies: + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + react-native-gesture-handler@2.28.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: '@egjs/hammerjs': 2.0.17 @@ -33085,6 +34466,12 @@ snapshots: react: 19.0.0 react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + react-native-safe-area-context@5.6.1(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): + dependencies: + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + optional: true + react-native-screens@4.11.1(patch_hash=4904c53aa4ed573c7e31df357d1b73feeefa4f92b6d41d4157a611401b34345d)(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: react: 19.0.0 @@ -33108,12 +34495,12 @@ snapshots: react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) warn-once: 0.1.1 - react-native-svg@15.13.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): + react-native-svg@15.13.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: css-select: 5.2.2 css-tree: 1.1.3 react: 19.0.0 - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) warn-once: 0.1.1 react-native-track-player@4.1.1(patch_hash=d011fdd16d124609523059323ac7614e3999174a9c7b21074c1124d7075650fb)(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): @@ -33165,14 +34552,6 @@ snapshots: react-native: 0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) optional: true - react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): - dependencies: - escape-string-regexp: 4.0.0 - invariant: 2.2.4 - react: 19.0.0 - react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) - optional: true - react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: escape-string-regexp: 4.0.0 @@ -33181,6 +34560,22 @@ snapshots: react-native: 0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) optional: true + react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0): + dependencies: + escape-string-regexp: 4.0.0 + invariant: 2.2.4 + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5) + optional: true + + react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): + dependencies: + escape-string-regexp: 4.0.0 + invariant: 2.2.4 + react: 19.0.0 + react-native: 0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0) + optional: true + react-native-worklets@0.5.1(@babel/core@7.28.4)(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0): dependencies: '@babel/core': 7.28.4 @@ -33297,20 +34692,68 @@ snapshots: - supports-color - utf-8-validate - react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5): + react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0): dependencies: '@jest/create-cache-key-function': 29.7.0 '@react-native/assets-registry': 0.79.6 - '@react-native/codegen': 0.79.6(@babel/core@7.28.4) + '@react-native/codegen': 0.79.6(@babel/core@7.28.5) + '@react-native/community-cli-plugin': 0.79.6(bufferutil@4.0.9) + '@react-native/gradle-plugin': 0.79.6 + '@react-native/js-polyfills': 0.79.6 + '@react-native/normalize-colors': 0.79.6 + '@react-native/virtualized-lists': 0.79.6(@types/react@19.2.2)(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0) + abort-controller: 3.0.0 + anser: 1.4.10 + ansi-regex: 5.0.1 + babel-jest: 29.7.0(@babel/core@7.28.5) + babel-plugin-syntax-hermes-parser: 0.25.1 + base64-js: 1.5.1 + chalk: 4.1.2 + commander: 12.1.0 + event-target-shim: 5.0.1 + flow-enums-runtime: 0.0.6 + glob: 7.2.3 + invariant: 2.2.4 + jest-environment-node: 29.7.0 + memoize-one: 5.2.1 + metro-runtime: 0.82.4 + metro-source-map: 0.82.4 + nullthrows: 1.1.1 + pretty-format: 29.7.0 + promise: 8.3.0 + react: 19.0.0 + react-devtools-core: 6.1.2(bufferutil@4.0.9)(utf-8-validate@6.0.5) + react-refresh: 0.14.2 + regenerator-runtime: 0.13.11 + scheduler: 0.25.0 + semver: 7.7.3 + stacktrace-parser: 0.1.11 + whatwg-fetch: 3.6.20 + ws: 6.2.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) + yargs: 17.7.2 + optionalDependencies: + '@types/react': 19.2.2 + transitivePeerDependencies: + - '@babel/core' + - '@react-native-community/cli' + - bufferutil + - supports-color + - utf-8-validate + + react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5): + dependencies: + '@jest/create-cache-key-function': 29.7.0 + '@react-native/assets-registry': 0.79.6 + '@react-native/codegen': 0.79.6(@babel/core@7.28.5) '@react-native/community-cli-plugin': 0.79.6(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@react-native/gradle-plugin': 0.79.6 '@react-native/js-polyfills': 0.79.6 '@react-native/normalize-colors': 0.79.6 - '@react-native/virtualized-lists': 0.79.6(@types/react@19.2.2)(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) + '@react-native/virtualized-lists': 0.79.6(@types/react@19.2.2)(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0) abort-controller: 3.0.0 anser: 1.4.10 ansi-regex: 5.0.1 - babel-jest: 29.7.0(@babel/core@7.28.4) + babel-jest: 29.7.0(@babel/core@7.28.5) babel-plugin-syntax-hermes-parser: 0.25.1 base64-js: 1.5.1 chalk: 4.1.2 @@ -33831,7 +35274,7 @@ snapshots: sprintf-js: 1.1.3 optional: true - rolldown-plugin-dts@0.16.12(rolldown@1.0.0-beta.44)(typescript@5.9.3): + rolldown-plugin-dts@0.16.12(rolldown@1.0.0-beta.45)(typescript@5.9.3): dependencies: '@babel/generator': 7.28.3 '@babel/parser': 7.28.4 @@ -33842,32 +35285,32 @@ snapshots: dts-resolver: 2.1.2 get-tsconfig: 4.12.0 magic-string: 0.30.19 - rolldown: 1.0.0-beta.44 + rolldown: 1.0.0-beta.45 optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - oxc-resolver - supports-color - rolldown@1.0.0-beta.44: + rolldown@1.0.0-beta.45: dependencies: '@oxc-project/types': 0.95.0 - '@rolldown/pluginutils': 1.0.0-beta.44 + '@rolldown/pluginutils': 1.0.0-beta.45 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-beta.44 - '@rolldown/binding-darwin-arm64': 1.0.0-beta.44 - '@rolldown/binding-darwin-x64': 1.0.0-beta.44 - '@rolldown/binding-freebsd-x64': 1.0.0-beta.44 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.44 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.44 - '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.44 - '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.44 - '@rolldown/binding-linux-x64-musl': 1.0.0-beta.44 - '@rolldown/binding-openharmony-arm64': 1.0.0-beta.44 - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.44 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.44 - '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.44 - '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.44 + '@rolldown/binding-android-arm64': 1.0.0-beta.45 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.45 + '@rolldown/binding-darwin-x64': 1.0.0-beta.45 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.45 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.45 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.45 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.45 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.45 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.45 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.45 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.45 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.45 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.45 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.45 rollup@2.79.2: optionalDependencies: @@ -34998,8 +36441,8 @@ snapshots: diff: 8.0.2 empathic: 2.0.0 hookable: 5.5.3 - rolldown: 1.0.0-beta.44 - rolldown-plugin-dts: 0.16.12(rolldown@1.0.0-beta.44)(typescript@5.9.3) + rolldown: 1.0.0-beta.45 + rolldown-plugin-dts: 0.16.12(rolldown@1.0.0-beta.45)(typescript@5.9.3) semver: 7.7.3 tinyexec: 1.0.1 tinyglobby: 0.2.15 @@ -35803,7 +37246,7 @@ snapshots: dependencies: '@apideck/better-ajv-errors': 0.3.6(ajv@8.17.1) '@babel/core': 7.28.4 - '@babel/preset-env': 7.28.3(@babel/core@7.28.4) + '@babel/preset-env': 7.28.5(@babel/core@7.28.4) '@babel/runtime': 7.28.4 '@rollup/plugin-babel': 5.3.1(@babel/core@7.28.4)(@types/babel__core@7.20.5)(rollup@2.79.2) '@rollup/plugin-node-resolve': 15.3.1(rollup@2.79.2) @@ -36094,8 +37537,6 @@ snapshots: zod@3.25.75: {} - zod@4.1.11: {} - zod@4.1.12: {} zustand@4.5.7(@types/react@19.2.2)(immer@10.1.3)(react@19.0.0): diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 0daa39bd5..895053cbe 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -8,7 +8,7 @@ packages: - "!**/example/**" catalog: - "@follow-app/client-sdk": 0.3.73 + "@follow-app/client-sdk": 0.3.78 tailwindcss-uikit-colors: 1.0.0 typescript: 5.9.3 @@ -19,6 +19,7 @@ minimumReleaseAge: 1440 minimumReleaseAgeExclude: - "@follow-app/*" - "@folo-services/*" + - "@byjohann/toon" onlyBuiltDependencies: - "@firebase/util" diff --git a/vercel.json b/vercel.json index 44f63fdd5..ae4ccfe5e 100644 --- a/vercel.json +++ b/vercel.json @@ -175,7 +175,7 @@ "has": [ { "type": "host", - "value": "dev.follow.is" + "value": "dev.folo.is" } ] }, @@ -185,7 +185,7 @@ "has": [ { "type": "host", - "value": "dev.follow.is" + "value": "dev.folo.is" } ] }, @@ -195,7 +195,7 @@ "has": [ { "type": "host", - "value": "dev.follow.is" + "value": "dev.folo.is" } ] }, @@ -205,7 +205,7 @@ "has": [ { "type": "host", - "value": "dev.follow.is" + "value": "dev.folo.is" } ] }, @@ -215,7 +215,7 @@ "has": [ { "type": "host", - "value": "dev.follow.is" + "value": "dev.folo.is" } ] }, @@ -225,7 +225,7 @@ "has": [ { "type": "host", - "value": "dev.follow.is" + "value": "dev.folo.is" } ] }, @@ -235,7 +235,7 @@ "has": [ { "type": "host", - "value": "dev.follow.is" + "value": "dev.folo.is" } ] }, @@ -245,7 +245,7 @@ "has": [ { "type": "host", - "value": "dev.follow.is" + "value": "dev.folo.is" } ] },