diff --git a/apps/mobile/package.json b/apps/mobile/package.json
index 6cebead6e..2fbeaa26e 100644
--- a/apps/mobile/package.json
+++ b/apps/mobile/package.json
@@ -35,7 +35,7 @@
"fs-extra": "^11.3.4",
"i18next": "^24.2.0",
"lucide-react-native": "^0.475.0",
- "react": "^19.1.0",
+ "react": "19.1.0",
"react-hook-form": "^7.54.0",
"react-i18next": "^15.4.0",
"react-native": "0.81.5",
diff --git a/apps/web/__tests__/stores/chat-store.test.ts b/apps/web/__tests__/stores/chat-store.test.ts
index 7aad69a46..2c6d799e6 100644
--- a/apps/web/__tests__/stores/chat-store.test.ts
+++ b/apps/web/__tests__/stores/chat-store.test.ts
@@ -7,7 +7,6 @@ describe('chat store', () => {
useChatStore.setState({
messages: [],
isTyping: false,
- isStreaming: false,
})
})
@@ -31,10 +30,9 @@ describe('chat store', () => {
expect(state.messages).toEqual([])
})
- it('starts with typing and streaming false', () => {
+ it('starts with typing false', () => {
const state = useChatStore.getState()
expect(state.isTyping).toBe(false)
- expect(state.isStreaming).toBe(false)
})
})
@@ -122,25 +120,6 @@ describe('chat store', () => {
})
})
- // -------------------------------------------------------------------------
- // setIsStreaming
- // -------------------------------------------------------------------------
-
- describe('setIsStreaming', () => {
- it('sets streaming to true', () => {
- const { setIsStreaming } = useChatStore.getState()
- setIsStreaming(true)
- expect(useChatStore.getState().isStreaming).toBe(true)
- })
-
- it('sets streaming to false', () => {
- useChatStore.setState({ isStreaming: true })
- const { setIsStreaming } = useChatStore.getState()
- setIsStreaming(false)
- expect(useChatStore.getState().isStreaming).toBe(false)
- })
- })
-
// -------------------------------------------------------------------------
// clearMessages
// -------------------------------------------------------------------------
@@ -162,12 +141,5 @@ describe('chat store', () => {
clearMessages()
expect(useChatStore.getState().isTyping).toBe(false)
})
-
- it('resets streaming state', () => {
- useChatStore.setState({ isStreaming: true })
- const { clearMessages } = useChatStore.getState()
- clearMessages()
- expect(useChatStore.getState().isStreaming).toBe(false)
- })
})
})
diff --git a/apps/web/app/(app)/calendar-sync/page.tsx b/apps/web/app/(app)/calendar-sync/page.tsx
index 6104b693e..cf420adae 100644
--- a/apps/web/app/(app)/calendar-sync/page.tsx
+++ b/apps/web/app/(app)/calendar-sync/page.tsx
@@ -8,6 +8,7 @@ import { useTranslations } from 'next-intl'
import { plural } from '@/lib/plural'
import { useProfile, useHasProAccess } from '@/hooks/use-profile'
import { useBulkCreateHabits } from '@/hooks/use-habits'
+import { getSupabaseClient } from '@/lib/supabase'
import { API } from '@orbit/shared/api'
import { getErrorMessage } from '@orbit/shared/utils'
import type { FrequencyUnit } from '@orbit/shared/types/habit'
@@ -215,8 +216,20 @@ export default function CalendarSyncPage() {
}
async function connectGoogle() {
- // Redirect to auth flow with Google Calendar scope
- window.location.href = '/api/auth/google?scope=calendar'
+ const supabase = getSupabaseClient()
+ const redirectTo = `${window.location.origin}/auth-callback`
+ sessionStorage.setItem('auth_return_url', '/calendar-sync')
+
+ await supabase.auth.signInWithOAuth({
+ provider: 'google',
+ options: {
+ redirectTo,
+ scopes: 'https://www.googleapis.com/auth/calendar.readonly',
+ queryParams: {
+ access_type: 'offline',
+ },
+ },
+ })
}
return (
diff --git a/apps/web/app/(app)/calendar/page.tsx b/apps/web/app/(app)/calendar/page.tsx
index 0e2923523..c885b17ec 100644
--- a/apps/web/app/(app)/calendar/page.tsx
+++ b/apps/web/app/(app)/calendar/page.tsx
@@ -1,6 +1,6 @@
'use client'
-import { useState, useMemo, useCallback } from 'react'
+import { useState, useMemo, useCallback, useRef } from 'react'
import { addMonths, subMonths, startOfMonth, format } from 'date-fns'
import { enUS, ptBR } from 'date-fns/locale'
import { ChevronLeft, ChevronRight, Search } from 'lucide-react'
@@ -9,6 +9,8 @@ import { useCalendarData } from '@/hooks/use-calendar-data'
import { CalendarGrid } from '@/components/calendar/calendar-grid'
import { CalendarDayDetail } from '@/components/calendar/calendar-day-detail'
+const SWIPE_THRESHOLD = 50
+
export default function CalendarPage() {
const t = useTranslations()
const locale = useLocale()
@@ -43,8 +45,33 @@ export default function CalendarPage() {
return dayMap.get(selectedDay) ?? []
}, [selectedDay, dayMap])
+ // Swipe navigation
+ const touchStartX = useRef(null)
+
+ const handleTouchStart = useCallback((e: React.TouchEvent) => {
+ const touch = e.touches[0]
+ if (touch) touchStartX.current = touch.clientX
+ }, [])
+
+ const handleTouchEnd = useCallback((e: React.TouchEvent) => {
+ if (touchStartX.current === null) return
+ const touch = e.changedTouches[0]
+ if (!touch) return
+ const deltaX = touch.clientX - touchStartX.current
+ touchStartX.current = null
+ if (Math.abs(deltaX) < SWIPE_THRESHOLD) return
+ if (deltaX < 0) {
+ setCurrentMonth((m) => addMonths(m, 1))
+ } else {
+ setCurrentMonth((m) => subMonths(m, 1))
+ }
+ }, [])
+
return (
-
+
{/* Header */}
@@ -100,9 +127,11 @@ export default function CalendarPage() {
)}
{/* Refetch loading bar */}
- {isFetching && !isLoading && (
-
- )}
+
{/* Calendar grid */}
{(!isLoading || isFetching) && (
diff --git a/apps/web/app/(app)/error.tsx b/apps/web/app/(app)/error.tsx
new file mode 100644
index 000000000..4f05e5a00
--- /dev/null
+++ b/apps/web/app/(app)/error.tsx
@@ -0,0 +1,34 @@
+'use client'
+
+import { useEffect } from 'react'
+import { AlertTriangle } from 'lucide-react'
+import { useTranslations } from 'next-intl'
+
+export default function AppError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string }
+ reset: () => void
+}) {
+ const t = useTranslations()
+
+ useEffect(() => {
+ // Log error for debugging (server-side only via digest)
+ }, [error])
+
+ return (
+
+
+
+ {error.message || t('auth.genericError')}
+
+
+ {t('common.retry')}
+
+
+ )
+}
diff --git a/apps/web/app/(app)/layout.tsx b/apps/web/app/(app)/layout.tsx
index 08fe763c2..fc4764353 100644
--- a/apps/web/app/(app)/layout.tsx
+++ b/apps/web/app/(app)/layout.tsx
@@ -1,41 +1,238 @@
'use client'
+import { useState, useEffect, useCallback, useRef } from 'react'
+import { useRouter } from 'next/navigation'
import { useTranslations } from 'next-intl'
+import { CalendarDays } from 'lucide-react'
import { Providers } from '@/lib/providers'
import { BottomNav } from '@/components/navigation/bottom-nav'
import { TrialBanner } from '@/components/ui/trial-banner'
+import { TrialExpiredModal } from '@/components/ui/trial-expired-modal'
+import { PushPrompt } from '@/components/ui/push-prompt'
+import { AppOverlay } from '@/components/ui/app-overlay'
+import { OnboardingFlow } from '@/components/onboarding/onboarding-flow'
+import { StreakCelebration } from '@/components/gamification/streak-celebration'
+import { AllDoneCelebration } from '@/components/gamification/all-done-celebration'
+import { GoalCompletedCelebration } from '@/components/gamification/goal-completed-celebration'
+import { WelcomeBackToast } from '@/components/gamification/welcome-back-toast'
+import { AchievementToast } from '@/components/gamification/achievement-toast'
+import { LevelUpOverlay } from '@/components/gamification/level-up-overlay'
+import { StreakFreezeCelebration } from '@/components/gamification/streak-freeze-celebration'
+import { useProfile, useHasProAccess } from '@/hooks/use-profile'
+import { useTotalHabitCount } from '@/hooks/use-habits'
+import { useGamificationProfile } from '@/hooks/use-gamification'
import { useUIStore } from '@/stores/ui-store'
+import { getSupabaseClient } from '@/lib/supabase'
+import { dismissCalendarImport } from '@/app/actions/profile'
export default function AppLayout({
children,
}: {
children: React.ReactNode
}) {
+ return (
+
+ {children}
+
+ )
+}
+
+function AppLayoutContent({ children }: { children: React.ReactNode }) {
const t = useTranslations()
+ const router = useRouter()
+ const { profile } = useProfile()
+ const hasProAccess = useHasProAccess()
+ const totalHabitCount = useTotalHabitCount()
+ const gamification = useGamificationProfile()
+
+ const activeView = useUIStore((s) => s.activeView)
const setShowCreateModal = useUIStore((s) => s.setShowCreateModal)
+ const setShowCreateGoalModal = useUIStore((s) => s.setShowCreateGoalModal)
+
+ // Streak freeze ref
+ const streakFreezeRef = useRef<{ show: () => void }>(null)
+
+ // Google Calendar import prompt state
+ const [showCalendarPrompt, setShowCalendarPrompt] = useState(false)
+
+ useEffect(() => {
+ if (
+ profile &&
+ profile.hasCompletedOnboarding &&
+ !profile.hasImportedCalendar
+ ) {
+ setShowCalendarPrompt(true)
+ }
+ }, [profile])
+
+ // ---------------------------------------------------------------------------
+ // handleCreate -- mirrors Nuxt default.vue logic
+ // ---------------------------------------------------------------------------
+ const handleCreate = useCallback(() => {
+ if (activeView === 'goals') {
+ setShowCreateGoalModal(true)
+ return
+ }
+ if (!hasProAccess && totalHabitCount >= 10) {
+ router.push('/upgrade')
+ return
+ }
+ setShowCreateModal(true)
+ }, [activeView, hasProAccess, totalHabitCount, router, setShowCreateModal, setShowCreateGoalModal])
+
+ // ---------------------------------------------------------------------------
+ // Calendar import prompt handlers
+ // ---------------------------------------------------------------------------
+ const handleDismissCalendarPrompt = useCallback(() => {
+ setShowCalendarPrompt(false)
+ dismissCalendarImport().catch(() => {})
+ }, [])
+
+ const handleCalendarImport = useCallback(async () => {
+ setShowCalendarPrompt(false)
+ dismissCalendarImport().catch(() => {})
+
+ if (profile?.hasGoogleConnection) {
+ router.push('/calendar-sync')
+ return
+ }
+
+ // No Google tokens yet -- trigger OAuth, redirect to calendar-sync after
+ const supabase = getSupabaseClient()
+ const redirectTo = `${globalThis.location.origin}/auth-callback`
+ sessionStorage.setItem('auth_return_url', '/calendar-sync')
+
+ await supabase.auth.signInWithOAuth({
+ provider: 'google',
+ options: {
+ redirectTo,
+ scopes: 'https://www.googleapis.com/auth/calendar.readonly',
+ queryParams: { access_type: 'offline' },
+ },
+ })
+ }, [profile?.hasGoogleConnection, router])
+
+ // Track when calendar prompt is closed via overlay X button
+ const handleCalendarPromptOpenChange = useCallback(
+ (open: boolean) => {
+ if (!open && showCalendarPrompt) {
+ handleDismissCalendarPrompt()
+ }
+ },
+ [showCalendarPrompt, handleDismissCalendarPrompt],
+ )
+
+ // ---------------------------------------------------------------------------
+ // Gamification clear handlers
+ // ---------------------------------------------------------------------------
+ const clearLevelUp = useCallback(() => {
+ // Level-up is tracked via ref diff in the hook -- no explicit clear needed
+ }, [])
return (
-
-
-
- {t('nav.skipToContent')}
-
-
- {/* Main content - full width mobile, max-w on desktop */}
-
-
- {children}
-
-
- {/* Bottom navigation */}
-
setShowCreateModal(true)} />
-
-
+
+
+ {t('nav.skipToContent')}
+
+
+ {/* Main content - full width mobile, max-w on desktop */}
+
+
+ {children}
+
+
+ {/* Bottom navigation */}
+
+
+
+
+ )
+}
+
+// Extracted to its own component so conditional children don't trigger React key warnings
+// in the parent AppLayoutContent
+function GlobalOverlays({
+ profile,
+ hasProAccess,
+ gamification,
+ streakFreezeRef,
+ showCalendarPrompt,
+ onCalendarPromptOpenChange,
+ onCalendarImport,
+ onDismissCalendarPrompt,
+}: {
+ profile: ReturnType
['profile']
+ hasProAccess: boolean
+ gamification: ReturnType
+ streakFreezeRef: React.RefObject<{ show: () => void } | null>
+ showCalendarPrompt: boolean
+ onCalendarPromptOpenChange: (open: boolean) => void
+ onCalendarImport: () => void
+ onDismissCalendarPrompt: () => void
+}) {
+ const t = useTranslations()
+
+ return (
+
+
+ {profile?.hasCompletedOnboarding &&
}
+ {profile && !profile.hasCompletedOnboarding &&
}
+
+
+
+
+ {hasProAccess &&
}
+ {hasProAccess && (
+
{}}
+ />
+ )}
+
+
+
+
+
+
+
+ {t('onboarding.wizard.calendarDescription')}
+
+
+
+ {t('onboarding.wizard.calendarButton')}
+
+
+ {t('common.later')}
+
+
+
+
+
)
}
diff --git a/apps/web/app/(app)/page.tsx b/apps/web/app/(app)/page.tsx
index 1fcb7cb15..dcb5cbbaa 100644
--- a/apps/web/app/(app)/page.tsx
+++ b/apps/web/app/(app)/page.tsx
@@ -2,6 +2,7 @@
import { useState, useMemo, useCallback, useRef, useEffect } from 'react'
import { createPortal } from 'react-dom'
+import { useSearchParams } from 'next/navigation'
import {
addDays,
subDays,
@@ -29,8 +30,10 @@ import {
Trash2,
} from 'lucide-react'
import { useTranslations, useLocale } from 'next-intl'
+import { useQueryClient } from '@tanstack/react-query'
+import { habitKeys } from '@orbit/shared/query'
import { plural } from '@/lib/plural'
-import { HabitList } from '@/components/habits/habit-list'
+import { HabitList, type HabitListHandle } from '@/components/habits/habit-list'
import { HabitSummaryCard } from '@/components/habits/habit-summary-card'
import { CreateHabitModal } from '@/components/habits/create-habit-modal'
import { GoalsView } from '@/components/goals/goals-view'
@@ -41,7 +44,7 @@ import { NotificationBell } from '@/components/navigation/notification-bell'
import { useUIStore } from '@/stores/ui-store'
import { useProfile } from '@/hooks/use-profile'
import { useStreakInfo } from '@/hooks/use-gamification'
-import { useBulkDeleteHabits, useBulkLogHabits, useBulkSkipHabits } from '@/hooks/use-habits'
+import { useHabits, useBulkDeleteHabits, useBulkLogHabits, useBulkSkipHabits } from '@/hooks/use-habits'
import { useTags } from '@/hooks/use-tags'
import { formatAPIDate } from '@orbit/shared/utils'
import type { HabitsFilter } from '@orbit/shared/types/habit'
@@ -59,6 +62,8 @@ export default function TodayPage() {
const t = useTranslations()
const locale = useLocale()
const dateFnsLocale = locale === 'pt-BR' ? ptBR : enUS
+ const searchParams = useSearchParams()
+ const queryClient = useQueryClient()
const { profile } = useProfile()
const { data: streakInfo } = useStreakInfo()
const { tags } = useTags()
@@ -84,7 +89,8 @@ export default function TodayPage() {
const isSelectMode = useUIStore((s) => s.isSelectMode)
const selectedHabitIds = useUIStore((s) => s.selectedHabitIds)
const toggleSelectMode = useUIStore((s) => s.toggleSelectMode)
- const toggleHabitSelection = useUIStore((s) => s.toggleHabitSelection)
+ const toggleSelectionCascade = useUIStore((s) => s.toggleSelectionCascade)
+ const selectAllHabits = useUIStore((s) => s.selectAllHabits)
const clearSelection = useUIStore((s) => s.clearSelection)
// Create modal (shared with layout's BottomNav via store)
@@ -101,22 +107,32 @@ export default function TodayPage() {
const [showBulkDeleteConfirm, setShowBulkDeleteConfirm] = useState(false)
const [showBulkLogConfirm, setShowBulkLogConfirm] = useState(false)
const [showBulkSkipConfirm, setShowBulkSkipConfirm] = useState(false)
- const [allCollapsed, setAllCollapsed] = useState(false)
const [slideDirection, setSlideDirection] = useState<'left' | 'right'>('right')
const searchDebounceTimer = useRef | null>(null)
const controlsMenuRef = useRef(null)
const controlsMenuPanelRef = useRef(null)
- const habitListRef = useRef<{
- collapseAll: () => void
- expandAll: () => void
- allCollapsed: boolean
- markRecentlyCompleted: (habitId: string) => void
- checkAndPromptParentLog: (childHabitId: string) => void
- } | null>(null)
+ const habitListRef = useRef(null)
const CONTROLS_MENU_WIDTH_PX = 200
const CONTROLS_MENU_MARGIN_PX = 8
+ // ?date= query parameter handling
+ const dateParam = searchParams.get('date')
+ const initialDateStr = useMemo(() => {
+ if (dateParam && /^\d{4}-\d{2}-\d{2}$/.test(dateParam)) return dateParam
+ return null
+ }, [dateParam])
+
+ // Initialize selectedDate from URL ?date= param on mount
+ useEffect(() => {
+ if (initialDateStr) {
+ setSelectedDate(initialDateStr)
+ setActiveView('today')
+ }
+ // Only run on mount / when dateParam changes
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [initialDateStr])
+
const selectedDate = useMemo(
() => new Date(selectedDateStr + 'T00:00:00'),
[selectedDateStr],
@@ -253,6 +269,46 @@ export default function TodayPage() {
return f
}, [activeView, selectedDate, searchQueryStore, selectedFrequency, selectedTagIds, showGeneralOnToday])
+ // Query habits for selection cascade helpers and count
+ const habitsQuery = useHabits(filters)
+ const habitsById = habitsQuery.data?.habitsById ?? new Map()
+ const childrenByParent = habitsQuery.data?.childrenByParent ?? new Map()
+ const habitsCount = habitsById.size
+ const hasFetched = habitsQuery.dataUpdatedAt > 0
+ const isRefetching = habitsQuery.isFetching && hasFetched
+
+ // Selection cascade helpers (matches Nuxt getDescendantIds / isAncestorSelected)
+ const getDescendantIds = useCallback(
+ (parentId: string): string[] => {
+ const childIds = childrenByParent.get(parentId) ?? []
+ const loaded = habitListRef.current?.allLoadedIds
+ const ids: string[] = []
+ for (const cid of childIds) {
+ if (loaded && !loaded.has(cid)) continue
+ ids.push(cid, ...getDescendantIds(cid))
+ }
+ return ids
+ },
+ [childrenByParent],
+ )
+
+ const isAncestorSelected = useCallback(
+ (habitId: string): boolean => {
+ const habit = habitsById.get(habitId)
+ if (!habit?.parentId) return false
+ if (selectedHabitIds.has(habit.parentId)) return true
+ return isAncestorSelected(habit.parentId)
+ },
+ [habitsById, selectedHabitIds],
+ )
+
+ const handleToggleSelection = useCallback(
+ (habitId: string) => {
+ toggleSelectionCascade(habitId, getDescendantIds, isAncestorSelected)
+ },
+ [toggleSelectionCascade, getDescendantIds, isAncestorSelected],
+ )
+
// Tab keyboard navigation
const handleTabKeydown = useCallback(
(e: React.KeyboardEvent) => {
@@ -287,10 +343,12 @@ export default function TodayPage() {
}, [])
// Select all / deselect all
- const allSelected = selectedHabitIds.size > 0
+ const allSelected = habitsCount > 0 && selectedHabitIds.size === habitsCount
const selectAll = useCallback(() => {
- // Toggle all currently visible -- store manages
- }, [])
+ const loaded = habitListRef.current?.allLoadedIds
+ const allIds = loaded ? Array.from(loaded) : Array.from(habitsById.keys())
+ selectAllHabits(allIds)
+ }, [habitsById, selectAllHabits])
const deselectAll = useCallback(() => {
clearSelection()
}, [clearSelection])
@@ -313,7 +371,16 @@ export default function TodayPage() {
const ids = Array.from(selectedHabitIds)
if (ids.length === 0) return
try {
- await bulkLog.mutateAsync(ids.map((id) => ({ habitId: id })))
+ const result = await bulkLog.mutateAsync(ids.map((id) => ({ habitId: id })))
+ const successIds = result.results
+ .filter((r) => r.status === 'Success')
+ .map((r) => r.habitId)
+ for (const id of successIds) {
+ habitListRef.current?.markRecentlyCompleted(id)
+ }
+ for (const id of successIds) {
+ habitListRef.current?.checkAndPromptParentLog(id)
+ }
} catch {
// Error handled in hook
} finally {
@@ -326,7 +393,16 @@ export default function TodayPage() {
const ids = Array.from(selectedHabitIds)
if (ids.length === 0) return
try {
- await bulkSkip.mutateAsync(ids.map((id) => ({ habitId: id })))
+ const result = await bulkSkip.mutateAsync(ids.map((id) => ({ habitId: id })))
+ const successIds = result.results
+ .filter((r) => r.status === 'Success')
+ .map((r) => r.habitId)
+ for (const id of successIds) {
+ habitListRef.current?.markRecentlyCompleted(id)
+ }
+ for (const id of successIds) {
+ habitListRef.current?.checkAndPromptParentLog(id)
+ }
} catch {
// Error handled in hook
} finally {
@@ -595,31 +671,32 @@ export default function TodayPage() {
{
- if (allCollapsed) {
- habitListRef.current?.expandAll()
+ if (habitListRef.current?.allCollapsed) {
+ habitListRef.current.expandAll()
} else {
habitListRef.current?.collapseAll()
}
- setAllCollapsed(!allCollapsed)
closeControlsMenu()
}}
>
- {allCollapsed ? (
+ {habitListRef.current?.allCollapsed ? (
) : (
)}
- {allCollapsed
+ {habitListRef.current?.allCollapsed
? t('habits.expandAll')
: t('habits.collapseAll')}
{
+ queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
closeControlsMenu()
}}
>
-
+
{t('habits.refresh')}
+ {Array.from({ length: 5 }).map((_, i) => (
+
+ ))}
+
+ )}
+
+ {/* Refetch loading bar */}
+ {isRefetching && (
+
+ )}
+
{/* Habit list */}
+ {hasFetched && (
{
if (!isSelectMode) toggleSelectMode()
- toggleHabitSelection(habitId)
+ handleToggleSelection(habitId)
}}
onCreate={() => setShowCreateModal(true)}
onSeeUpcoming={goToNextDay}
/>
+ )}
)}
diff --git a/apps/web/app/(app)/preferences/page.tsx b/apps/web/app/(app)/preferences/page.tsx
index 97ff3043f..6d7dff067 100644
--- a/apps/web/app/(app)/preferences/page.tsx
+++ b/apps/web/app/(app)/preferences/page.tsx
@@ -49,6 +49,8 @@ export default function PreferencesPage() {
// Error handled silently like Vue
}
}
+ // Re-render page in the new locale (Nuxt equivalent: navigateTo(switchLocalePath(newLocale)))
+ router.refresh()
}
// --- Week Start Day ---
@@ -98,14 +100,28 @@ export default function PreferencesPage() {
colorSchemeMutation.mutate(scheme)
}
- // --- Time Format (local-only preference) ---
+ // --- Time Format (local-only preference, cookie for SSR safety) ---
const [timeFormat, setTimeFormat] = useState<'12h' | '24h'>(() => {
- if (typeof window === 'undefined') return '12h'
- return (localStorage.getItem('orbit_time_format') as '12h' | '24h') ?? '12h'
+ if (typeof document === 'undefined') return '12h'
+ // Check cookie first
+ const match = document.cookie.match(/(?:^|; )orbit_time_format=([^;]*)/)
+ if (match?.[1]) return match[1] as '12h' | '24h'
+ // Migrate from localStorage if present
+ const stored = localStorage.getItem('orbit_time_format') as '12h' | '24h' | null
+ if (stored) return stored
+ // Auto-detect from browser locale
+ try {
+ const resolved = new Intl.DateTimeFormat(navigator.language, { hour: 'numeric' }).resolvedOptions()
+ return resolved.hour12 ? '12h' : '24h'
+ } catch {
+ return '12h'
+ }
})
function handleTimeFormatChange(format: '12h' | '24h') {
setTimeFormat(format)
+ // Store in both cookie (SSR-safe) and localStorage (backward compat)
+ document.cookie = `orbit_time_format=${format};max-age=${365 * 24 * 60 * 60};path=/;samesite=strict`
localStorage.setItem('orbit_time_format', format)
}
@@ -133,32 +149,81 @@ export default function PreferencesPage() {
const [pushLoading, setPushLoading] = useState(false)
useEffect(() => {
- if (typeof window !== 'undefined' && 'Notification' in window && 'serviceWorker' in navigator) {
- setPushSupported(true)
- setPushPermission(Notification.permission as PermissionState)
- // Check if already subscribed
- navigator.serviceWorker.ready.then((reg) => {
- reg.pushManager.getSubscription().then((sub) => {
- setPushSubscribed(!!sub)
- })
- }).catch(() => {})
+ if (typeof window === 'undefined' || !('serviceWorker' in navigator) || !('PushManager' in window)) {
+ setPushSupported(false)
+ return
}
+
+ setPushSupported(true)
+ setPushPermission(Notification.permission as PermissionState)
+
+ // Check if already subscribed
+ navigator.serviceWorker.ready.then((reg) => {
+ reg.pushManager.getSubscription().then((sub) => {
+ setPushSubscribed(!!sub && Notification.permission === 'granted')
+ })
+ }).catch(() => {})
}, [])
async function handleTogglePush() {
setPushLoading(true)
try {
if (pushSubscribed) {
- const reg = await navigator.serviceWorker.ready
- const sub = await reg.pushManager.getSubscription()
- if (sub) await sub.unsubscribe()
+ // --- Unsubscribe ---
+ const registration = await navigator.serviceWorker.ready
+ const subscription = await registration.pushManager.getSubscription()
+ if (subscription) {
+ const keys = subscription.toJSON()
+ // Notify backend to remove subscription
+ await fetch('/api/notifications/unsubscribe', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ endpoint: subscription.endpoint,
+ p256dh: keys.keys?.p256dh,
+ auth: keys.keys?.auth,
+ }),
+ })
+ await subscription.unsubscribe()
+ }
setPushSubscribed(false)
} else {
- const permission = await Notification.requestPermission()
+ // --- Subscribe ---
+ // Skip permission prompt if already granted
+ const permission = Notification.permission === 'granted'
+ ? 'granted'
+ : await Notification.requestPermission()
setPushPermission(permission as PermissionState)
- if (permission === 'granted') {
- setPushSubscribed(true)
- }
+ if (permission !== 'granted') return
+
+ const registration = await navigator.serviceWorker.ready
+
+ // Unsubscribe any stale subscription first
+ const existing = await registration.pushManager.getSubscription()
+ if (existing) await existing.unsubscribe()
+
+ const vapidKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY
+ if (!vapidKey) return
+
+ const subscription = await registration.pushManager.subscribe({
+ userVisibleOnly: true,
+ applicationServerKey: urlBase64ToUint8Array(vapidKey) as BufferSource,
+ })
+
+ const keys = subscription.toJSON()
+
+ // Send subscription to backend
+ await fetch('/api/notifications/subscribe', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ endpoint: subscription.endpoint,
+ p256dh: keys.keys?.p256dh,
+ auth: keys.keys?.auth,
+ }),
+ })
+
+ setPushSubscribed(true)
}
} catch {
// Error handled silently
@@ -373,3 +438,15 @@ export default function PreferencesPage() {
)
}
+
+/** Convert a VAPID public key from URL-safe base64 to a Uint8Array for pushManager.subscribe */
+function urlBase64ToUint8Array(base64String: string): Uint8Array {
+ const padding = '='.repeat((4 - base64String.length % 4) % 4)
+ const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/')
+ const rawData = atob(base64)
+ const outputArray = new Uint8Array(rawData.length)
+ for (let i = 0; i < rawData.length; ++i) {
+ outputArray[i] = rawData.codePointAt(i) ?? 0
+ }
+ return outputArray
+}
diff --git a/apps/web/app/(app)/profile/page.tsx b/apps/web/app/(app)/profile/page.tsx
index b32dcf095..54a0af044 100644
--- a/apps/web/app/(app)/profile/page.tsx
+++ b/apps/web/app/(app)/profile/page.tsx
@@ -1,7 +1,11 @@
'use client'
-import { useState, useMemo } from 'react'
+import { useState, useMemo, useEffect } from 'react'
import Link from 'next/link'
+import { useSearchParams } from 'next/navigation'
+import { useQueryClient } from '@tanstack/react-query'
+import { profileKeys } from '@orbit/shared/query'
+import { getErrorMessage } from '@orbit/shared/utils'
import {
Settings,
Sparkles,
@@ -34,12 +38,21 @@ export default function ProfilePage() {
const t = useTranslations()
const locale = useLocale()
const dateFnsLocale = locale === 'pt-BR' ? ptBR : enUS
+ const searchParams = useSearchParams()
+ const queryClient = useQueryClient()
const { profile, isLoading, error, invalidate } = useProfile()
const trialDaysLeft = useTrialDaysLeft()
const trialExpired = useTrialExpired()
const logout = useAuthStore((s) => s.logout)
const { profile: gamificationProfile } = useGamificationProfile()
+ // Handle subscription success redirect -- refresh profile to pick up new plan
+ useEffect(() => {
+ if (searchParams.get('subscription') === 'success') {
+ queryClient.invalidateQueries({ queryKey: profileKeys.all })
+ }
+ }, [searchParams, queryClient])
+
// --- Fresh Start ---
const [showResetModal, setShowResetModal] = useState(false)
const [resetStep, setResetStep] = useState<'info' | 'confirm'>('info')
@@ -70,8 +83,7 @@ export default function ProfilePage() {
setShowResetModal(false)
setShowFreshStartAnimation(true)
} catch (err: unknown) {
- const msg = err instanceof Error ? err.message : t('profile.freshStart.errorGeneric')
- setResetError(msg)
+ setResetError(getErrorMessage(err, t('profile.freshStart.errorGeneric')))
} finally {
setResetLoading(false)
}
@@ -106,8 +118,7 @@ export default function ProfilePage() {
await requestDeletion()
setDeleteStep('code')
} catch (err: unknown) {
- const msg = err instanceof Error ? err.message : t('profile.deleteAccount.errorGeneric')
- setDeleteError(msg)
+ setDeleteError(getErrorMessage(err, t('profile.deleteAccount.errorGeneric')))
} finally {
setDeleteLoading(false)
}
@@ -119,12 +130,11 @@ export default function ProfilePage() {
setDeleteLoading(true)
setDeleteError('')
try {
- await confirmDeletion(code)
- setScheduledDeletionDate(new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString())
+ const response = await confirmDeletion(code)
+ setScheduledDeletionDate(response.scheduledDeletionAt ?? null)
setDeleteStep('deactivated')
} catch (err: unknown) {
- const msg = err instanceof Error ? err.message : t('profile.deleteAccount.errorGeneric')
- setDeleteError(msg)
+ setDeleteError(getErrorMessage(err, t('profile.deleteAccount.errorGeneric')))
} finally {
setDeleteLoading(false)
}
diff --git a/apps/web/app/(app)/retrospective/page.tsx b/apps/web/app/(app)/retrospective/page.tsx
index ce7915f5c..905f4be8a 100644
--- a/apps/web/app/(app)/retrospective/page.tsx
+++ b/apps/web/app/(app)/retrospective/page.tsx
@@ -4,11 +4,29 @@ import { useState, useCallback } from 'react'
import Link from 'next/link'
import { ArrowLeft, Loader2, Lock, BarChart3 } from 'lucide-react'
import { useTranslations } from 'next-intl'
+import DOMPurify from 'dompurify'
import { useProfile, useHasProAccess, useIsYearlyPro } from '@/hooks/use-profile'
import { useRetrospective, type RetrospectivePeriod } from '@/hooks/use-retrospective'
import { API } from '@orbit/shared/api'
import { getErrorMessage } from '@orbit/shared/utils'
+function escapeHtml(text: string): string {
+ return text
+ .replaceAll('&', '&')
+ .replaceAll('<', '<')
+ .replaceAll('>', '>')
+ .replaceAll('"', '"')
+ .replaceAll("'", ''')
+}
+
+function renderMarkdown(text: string): string {
+ const result = escapeHtml(text)
+ .replaceAll(/\*\*(.+?)\*\*/g, '$1 ')
+ .replaceAll('\n', ' ')
+
+ return DOMPurify.sanitize(result, { ALLOWED_TAGS: ['strong', 'br'], ALLOWED_ATTR: ['class'] })
+}
+
export default function RetrospectivePage() {
const t = useTranslations()
const { profile } = useProfile()
@@ -180,7 +198,7 @@ export default function RetrospectivePage() {
{fromCache && (
{t('retrospective.cached')}
diff --git a/apps/web/app/(app)/streak/page.tsx b/apps/web/app/(app)/streak/page.tsx
index c559f046f..5da918165 100644
--- a/apps/web/app/(app)/streak/page.tsx
+++ b/apps/web/app/(app)/streak/page.tsx
@@ -19,7 +19,7 @@ export default function StreakPage() {
const dateFnsLocale = locale === 'pt-BR' ? ptBR : enUS
const { profile } = useProfile()
const streak = profile?.currentStreak ?? 0
- const { streakQuery, streakInfo, freezesAvailable, isFrozenToday, hasCompletedToday, canFreeze } = useStreakFreeze()
+ const { streakQuery, streakInfo, freezesAvailable, isFrozenToday, hasCompletedToday, canFreeze } = useStreakFreeze(profile)
const activateFreezeMutation = useActivateStreakFreeze()
const [showConfirm, setShowConfirm] = useState(false)
diff --git a/apps/web/app/(app)/upgrade/page.tsx b/apps/web/app/(app)/upgrade/page.tsx
index 855d39765..5f1bf828f 100644
--- a/apps/web/app/(app)/upgrade/page.tsx
+++ b/apps/web/app/(app)/upgrade/page.tsx
@@ -1,6 +1,6 @@
'use client'
-import { useState, useMemo, useCallback } from 'react'
+import { useState, useMemo, useCallback, useRef, useEffect } from 'react'
import Link from 'next/link'
import { format, parseISO } from 'date-fns'
import { enUS, ptBR } from 'date-fns/locale'
@@ -89,6 +89,39 @@ function formatCardBrand(brand: string): string {
return brand.charAt(0).toUpperCase() + brand.slice(1)
}
+function FeatureTooltip({ text }: { text: string }) {
+ const [open, setOpen] = useState(false)
+ const ref = useRef
(null)
+
+ useEffect(() => {
+ if (!open) return
+ function handleClickOutside(e: MouseEvent) {
+ if (ref.current && !ref.current.contains(e.target as Node)) {
+ setOpen(false)
+ }
+ }
+ document.addEventListener('mousedown', handleClickOutside)
+ return () => document.removeEventListener('mousedown', handleClickOutside)
+ }, [open])
+
+ return (
+
+
setOpen((v) => !v)}
+ type="button"
+ >
+
+
+ {open && (
+
+ )}
+
+ )
+}
+
export default function UpgradePage() {
const t = useTranslations()
const locale = useLocale()
@@ -702,12 +735,7 @@ export default function UpgradePage() {
{t(`upgrade.features.${feat.key}.label`)}
-
-
-
+
{/* Free value */}
diff --git a/apps/web/app/(auth)/auth-callback/page.tsx b/apps/web/app/(auth)/auth-callback/page.tsx
index 546085b3e..6c1069333 100644
--- a/apps/web/app/(auth)/auth-callback/page.tsx
+++ b/apps/web/app/(auth)/auth-callback/page.tsx
@@ -2,8 +2,10 @@
import { useEffect, useState, useRef } from 'react'
import { useRouter, useSearchParams } from 'next/navigation'
-import { useTranslations } from 'next-intl'
+import Link from 'next/link'
+import { useTranslations, useLocale } from 'next-intl'
import { useAuthStore } from '@/stores/auth-store'
+import { getSupabaseClient } from '@/lib/supabase'
import type { LoginResponse } from '@orbit/shared/types/auth'
function getCookieValue(name: string): string | undefined {
@@ -15,112 +17,65 @@ function getCookieValue(name: string): string | undefined {
export default function AuthCallbackPage() {
const t = useTranslations()
+ const locale = useLocale()
const router = useRouter()
const searchParams = useSearchParams()
- const { setAuth, isAuthenticated } = useAuthStore()
+ const { setAuth } = useAuthStore()
const [errorMessage, setErrorMessage] = useState(null)
const processedRef = useRef(false)
+ const isAuthenticatedRef = useRef(false)
+ const errorMessageRef = useRef(null)
useEffect(() => {
if (processedRef.current) return
processedRef.current = true
- async function handleCallback() {
- // Extract provider tokens from URL hash (Supabase implicit flow)
- // and from query params (fallback)
- let providerToken: string | undefined
- let providerRefreshToken: string | undefined
- let accessToken: string | undefined
-
- if (window.location.hash) {
- const hashParams = new URLSearchParams(window.location.hash.substring(1))
- providerToken = hashParams.get('provider_token') ?? undefined
- providerRefreshToken = hashParams.get('provider_refresh_token') ?? undefined
- accessToken = hashParams.get('access_token') ?? undefined
- }
+ // Extract provider tokens before Supabase client consumes them.
+ // Web: tokens are in the URL hash (implicit flow).
+ let extractedProviderToken: string | undefined
+ let extractedProviderRefreshToken: string | undefined
- // Also check query params as fallback
- providerToken ??= searchParams.get('provider_token') ?? undefined
- providerRefreshToken ??= searchParams.get('provider_refresh_token') ?? undefined
- accessToken ??= searchParams.get('access_token') ?? undefined
+ if (window.location.hash) {
+ const hashParams = new URLSearchParams(window.location.hash.substring(1))
+ extractedProviderToken = hashParams.get('provider_token') ?? undefined
+ extractedProviderRefreshToken = hashParams.get('provider_refresh_token') ?? undefined
+ }
+ const query = new URLSearchParams(window.location.search)
+ extractedProviderToken ??= query.get('provider_token') ?? undefined
+ extractedProviderRefreshToken ??= query.get('provider_refresh_token') ?? undefined
- // Supabase PKCE flow: code is in query params, exchange via Supabase client
- const code = searchParams.get('code')
+ const supabase = getSupabaseClient()
- if (!accessToken && !code) {
- // No tokens at all -- something went wrong
- setErrorMessage(t('auth.callbackError'))
- return
- }
+ const { data: { subscription } } = supabase.auth.onAuthStateChange(async (event, session) => {
+ if (event !== 'SIGNED_IN' && event !== 'INITIAL_SESSION') return
+ if (!session) return
- // If we have a code but no access_token, we need to exchange it.
- // For PKCE flow, exchange code for session via Supabase.
- if (code && !accessToken) {
- try {
- // Exchange code for access token via Supabase REST API
- const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
- const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
-
- if (!supabaseUrl || !supabaseKey) {
- setErrorMessage(t('auth.callbackError'))
- return
- }
-
- const tokenResponse = await fetch(`${supabaseUrl}/auth/v1/token?grant_type=pkce`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'apikey': supabaseKey,
- },
- body: JSON.stringify({
- auth_code: code,
- code_verifier: sessionStorage.getItem('supabase-code-verifier') ?? '',
- }),
- })
-
- if (tokenResponse.ok) {
- const tokenData = await tokenResponse.json()
- accessToken = tokenData.access_token
- providerToken ??= tokenData.provider_token
- providerRefreshToken ??= tokenData.provider_refresh_token
- } else {
- setErrorMessage(t('auth.callbackError'))
- return
- }
- } catch {
- setErrorMessage(t('auth.callbackError'))
- return
- }
- }
-
- if (!accessToken) {
- setErrorMessage(t('auth.callbackError'))
- return
- }
-
- // Exchange Supabase token for our app token via BFF
- const referralCode = getCookieValue('referral_code')
+ subscription.unsubscribe()
try {
+ const referralCode = getCookieValue('referral_code')
+
const response = await fetch('/api/auth/google', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
- accessToken,
- language: 'en',
- googleAccessToken: providerToken,
- googleRefreshToken: providerRefreshToken,
+ accessToken: session.access_token,
+ language: locale,
+ googleAccessToken: extractedProviderToken ?? session.provider_token ?? undefined,
+ googleRefreshToken: extractedProviderRefreshToken ?? session.provider_refresh_token ?? undefined,
...(referralCode ? { referralCode } : {}),
}),
})
if (!response.ok) {
setErrorMessage(t('auth.callbackError'))
+ errorMessageRef.current = t('auth.callbackError')
return
}
const loginResponse = (await response.json()) as LoginResponse
setAuth(loginResponse)
+ isAuthenticatedRef.current = true
// Handle referral
if (referralCode) {
@@ -139,14 +94,14 @@ export default function AuthCallbackPage() {
router.push(safeUrl)
} catch {
setErrorMessage(t('auth.callbackError'))
+ errorMessageRef.current = t('auth.callbackError')
}
- }
-
- handleCallback()
+ })
- // 15s timeout for OAuth callback
+ // 15s timeout -- uses refs to avoid stale closure
const timeoutId = setTimeout(() => {
- if (!isAuthenticated && !errorMessage) {
+ subscription.unsubscribe()
+ if (!isAuthenticatedRef.current && !errorMessageRef.current) {
setErrorMessage(t('auth.callbackError'))
}
}, 15000)
@@ -163,12 +118,12 @@ export default function AuthCallbackPage() {
{errorMessage}
-
{t('auth.backToLogin')}
-
+
>
) : (
<>
diff --git a/apps/web/app/(auth)/error.tsx b/apps/web/app/(auth)/error.tsx
new file mode 100644
index 000000000..965993c5f
--- /dev/null
+++ b/apps/web/app/(auth)/error.tsx
@@ -0,0 +1,44 @@
+'use client'
+
+import { useTranslations } from 'next-intl'
+
+/**
+ * Error boundary for auth pages (login, auth-callback).
+ * Matches the Nuxt NuxtErrorBoundary in auth.vue layout.
+ */
+export default function AuthError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string }
+ reset: () => void
+}) {
+ const t = useTranslations()
+
+ return (
+
+
+
+
+
+
+
+ {error.message || t('auth.genericError')}
+
+
+ {t('common.retry')}
+
+
+ )
+}
diff --git a/apps/web/app/(auth)/login/page.tsx b/apps/web/app/(auth)/login/page.tsx
index 302b7fbfd..ff6c35503 100644
--- a/apps/web/app/(auth)/login/page.tsx
+++ b/apps/web/app/(auth)/login/page.tsx
@@ -2,9 +2,11 @@
import { useState, useRef, useCallback, useEffect } from 'react'
import { useRouter, useSearchParams } from 'next/navigation'
+import Link from 'next/link'
import { useTranslations, useLocale } from 'next-intl'
import { isValidEmail } from '@orbit/shared/utils/email'
import { useAuthStore } from '@/stores/auth-store'
+import { getSupabaseClient } from '@/lib/supabase'
import type { LoginResponse } from '@orbit/shared/types/auth'
const BACKEND_ERROR_MAP: Record = {
@@ -22,6 +24,56 @@ function getCookieValue(name: string): string | undefined {
return value !== undefined ? decodeURIComponent(value) : undefined
}
+/**
+ * Extract a backend error message from a fetch response body.
+ *
+ * BFF routes return JSON bodies shaped like:
+ * { error: "..." } -- simple error
+ * { data: { error: "..." } } -- nested
+ * { errors: { Field: ["msg"] } } -- FluentValidation
+ * { data: { errors: { ... } } } -- nested FluentValidation
+ */
+function extractFetchError(err: unknown): string | undefined {
+ if (!err || typeof err !== 'object') return undefined
+
+ const obj = err as Record
+
+ // Direct error string
+ if (typeof obj.error === 'string') return obj.error
+
+ // Nested data.error
+ if (obj.data && typeof obj.data === 'object') {
+ const data = obj.data as Record
+ if (typeof data.error === 'string') return data.error
+
+ // Deeper: data.data.error
+ if (data.data && typeof data.data === 'object') {
+ const inner = data.data as Record
+ if (typeof inner.error === 'string') return inner.error
+
+ // FluentValidation at data.data.errors
+ if (inner.errors && typeof inner.errors === 'object') {
+ const firstField = Object.values(inner.errors as Record)[0]
+ if (Array.isArray(firstField) && firstField.length > 0) return firstField[0] as string
+ }
+ }
+
+ // FluentValidation at data.errors
+ if (data.errors && typeof data.errors === 'object') {
+ const firstField = Object.values(data.errors as Record)[0]
+ if (Array.isArray(firstField) && firstField.length > 0) return firstField[0] as string
+ }
+ }
+
+ // Top-level FluentValidation
+ if (obj.errors && typeof obj.errors === 'object') {
+ const firstField = Object.values(obj.errors as Record)[0]
+ if (Array.isArray(firstField) && firstField.length > 0) return firstField[0] as string
+ }
+
+ return undefined
+}
+
export default function LoginPage() {
const router = useRouter()
const searchParams = useSearchParams()
@@ -35,11 +87,8 @@ export default function LoginPage() {
}
function extractError(err: unknown): string {
- if (err && typeof err === 'object' && 'error' in err) {
- const msg = (err as { error?: string }).error
- if (msg) return translateBackendError(msg)
- }
- return t('auth.genericError')
+ const backendError = extractFetchError(err)
+ return backendError ? translateBackendError(backendError) : t('auth.genericError')
}
const [step, setStep] = useState<'email' | 'code'>('email')
@@ -260,29 +309,29 @@ export default function LoginPage() {
}
}
- function signInWithGoogle() {
+ async function signInWithGoogle() {
setIsGoogleLoading(true)
setErrorMessage(null)
try {
- const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
- const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
-
- if (!supabaseUrl || !supabaseKey) {
- setErrorMessage(t('auth.googleError'))
- setIsGoogleLoading(false)
- return
- }
-
+ const supabase = getSupabaseClient()
const redirectTo = `${window.location.origin}/auth-callback`
- const params = new URLSearchParams({
+
+ const { error } = await supabase.auth.signInWithOAuth({
provider: 'google',
- redirect_to: redirectTo,
- scopes: 'https://www.googleapis.com/auth/calendar.readonly',
- access_type: 'offline',
+ options: {
+ redirectTo,
+ scopes: 'https://www.googleapis.com/auth/calendar.readonly',
+ queryParams: {
+ access_type: 'offline',
+ },
+ },
})
- window.location.href = `${supabaseUrl}/auth/v1/authorize?${params.toString()}`
+ if (error) {
+ setErrorMessage(t('auth.googleError'))
+ setIsGoogleLoading(false)
+ }
} catch {
setErrorMessage(t('auth.googleError'))
setIsGoogleLoading(false)
@@ -425,7 +474,7 @@ export default function LoginPage() {
ref={(el) => { codeInputRefs.current[index] = el }}
value={digit}
data-code-index={index}
- aria-label={`${t('auth.codeDigit')} ${index + 1}`}
+ aria-label={t('auth.codeDigit', { n: index + 1 })}
type="text"
inputMode="numeric"
maxLength={20}
@@ -476,9 +525,9 @@ export default function LoginPage() {
{/* Privacy & Terms */}
-
+
{t('privacy.title')}
-
+
diff --git a/apps/web/app/(chat)/chat/page.tsx b/apps/web/app/(chat)/chat/page.tsx
index f15108cee..1f05c6933 100644
--- a/apps/web/app/(chat)/chat/page.tsx
+++ b/apps/web/app/(chat)/chat/page.tsx
@@ -11,6 +11,7 @@ import {
type KeyboardEvent,
} from 'react'
import Link from 'next/link'
+import { useRouter } from 'next/navigation'
import {
ArrowLeft,
Sparkles,
@@ -22,8 +23,9 @@ import {
} from 'lucide-react'
import { useQueryClient } from '@tanstack/react-query'
import { useTranslations } from 'next-intl'
-import { habitKeys } from '@orbit/shared/query'
-import type { ChatResponse } from '@orbit/shared/types/chat'
+import { habitKeys, profileKeys } from '@orbit/shared/query'
+import type { Profile } from '@orbit/shared/types/profile'
+import { getErrorMessage } from '@orbit/shared/utils'
import { useChatStore } from '@/stores/chat-store'
import { useProfile } from '@/hooks/use-profile'
import { sendChatMessage } from '@/app/actions/chat'
@@ -51,6 +53,7 @@ const STARTER_CHIP_KEYS = [
export default function ChatPage() {
const t = useTranslations()
+ const router = useRouter()
const queryClient = useQueryClient()
const { profile } = useProfile()
@@ -93,7 +96,7 @@ export default function ChatPage() {
const scrollToBottom = useCallback(() => {
requestAnimationFrame(() => {
const el = chatContainerRef.current
- if (el) el.scrollTop = el.scrollHeight
+ if (el) el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' })
})
}, [])
@@ -108,6 +111,18 @@ export default function ChatPage() {
textarea.style.height = `${Math.min(textarea.scrollHeight, 120)}px`
}, [input])
+ // -------------------------------------------------------------------------
+ // Escape key -> navigate back
+ // -------------------------------------------------------------------------
+
+ useEffect(() => {
+ function handleKeydown(e: globalThis.KeyboardEvent) {
+ if (e.key === 'Escape') router.push('/')
+ }
+ document.addEventListener('keydown', handleKeydown)
+ return () => document.removeEventListener('keydown', handleKeydown)
+ }, [router])
+
// -------------------------------------------------------------------------
// Image handling
// -------------------------------------------------------------------------
@@ -197,9 +212,6 @@ export default function ChatPage() {
setIsTyping(true)
scrollToBottom()
- const controller = new AbortController()
- const timeoutId = setTimeout(() => controller.abort(), 60000)
-
try {
const formData = new FormData()
if (messageContent) formData.append('message', messageContent)
@@ -211,41 +223,54 @@ export default function ChatPage() {
.map((m) => ({ role: m.role, content: m.content }))
formData.append('history', JSON.stringify(recentHistory))
- const response: ChatResponse = await sendChatMessage(formData)
+ const result = await sendChatMessage(formData)
+
+ if (!result.ok) {
+ setIsTyping(false)
+
+ if (result.status === 408) {
+ setSendError(t('chat.timeoutError'))
+ } else if (result.status === 403) {
+ setSendError(t('chat.limitReachedError'))
+ } else {
+ setSendError(getErrorMessage(result.error, t('chat.sendError')))
+ }
+
+ addMessage({
+ id: crypto.randomUUID(),
+ role: 'ai',
+ content: t('chat.aiError'),
+ timestamp: new Date(),
+ })
+ scrollToBottom()
+ return
+ }
setIsTyping(false)
addMessage({
id: crypto.randomUUID(),
role: 'ai',
- content: response.aiMessage || '',
- actions: response.actions,
+ content: result.data.aiMessage || '',
+ actions: result.data.actions,
timestamp: new Date(),
})
scrollToBottom()
- if (response.actions?.some((a) => a.status === 'Success')) {
+ // Increment AI messages used counter (optimistic cache update)
+ if (!hasProAccess) {
+ queryClient.setQueryData(profileKeys.detail(), (old) =>
+ old ? { ...old, aiMessagesUsed: (old.aiMessagesUsed ?? 0) + 1 } : old,
+ )
+ }
+
+ if (result.data.actions?.some((a) => a.status === 'Success')) {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
}
} catch (err: unknown) {
setIsTyping(false)
-
- const isAbort =
- err instanceof DOMException && err.name === 'AbortError'
- const is403 =
- (err as { status?: number })?.status === 403 ||
- (err as { response?: { status?: number } })?.response?.status === 403
-
- if (isAbort) {
- setSendError(t('chat.timeoutError'))
- } else if (is403) {
- setSendError(t('chat.limitReachedError'))
- } else {
- setSendError(
- err instanceof Error ? err.message : t('chat.sendError'),
- )
- }
+ setSendError(getErrorMessage(err, t('chat.sendError')))
addMessage({
id: crypto.randomUUID(),
@@ -254,8 +279,6 @@ export default function ChatPage() {
timestamp: new Date(),
})
scrollToBottom()
- } finally {
- clearTimeout(timeoutId)
}
},
[
@@ -263,6 +286,7 @@ export default function ChatPage() {
selectedImage,
imagePreview,
isTyping,
+ hasProAccess,
addMessage,
setIsTyping,
scrollToBottom,
diff --git a/apps/web/app/actions/auth.ts b/apps/web/app/actions/auth.ts
index 0233889c6..e21c680c3 100644
--- a/apps/web/app/actions/auth.ts
+++ b/apps/web/app/actions/auth.ts
@@ -29,10 +29,12 @@ export async function requestDeletion(): Promise {
/**
* Confirm account deletion with the code received via email.
+ * Returns the scheduled deletion date from the backend response.
*/
-export async function confirmDeletion(code: string): Promise {
- await authFetch('/api/auth/confirm-deletion', {
+export async function confirmDeletion(code: string): Promise<{ scheduledDeletionAt?: string }> {
+ const response = await authFetch('/api/auth/confirm-deletion', {
method: 'POST',
body: JSON.stringify({ code }),
})
+ return response ?? {}
}
diff --git a/apps/web/app/actions/chat.ts b/apps/web/app/actions/chat.ts
index 80147ae79..dd159b00d 100644
--- a/apps/web/app/actions/chat.ts
+++ b/apps/web/app/actions/chat.ts
@@ -5,25 +5,50 @@ import type { ChatResponse } from '@orbit/shared'
const API_BASE = process.env.API_BASE ?? 'http://localhost:5000'
+const CHAT_TIMEOUT_MS = 60_000
+
+export type ChatResult =
+ | { ok: true; data: ChatResponse }
+ | { ok: false; error: string; status: number }
+
/**
* Send a chat message to the AI assistant.
* Accepts FormData with fields: message, image (File), history (JSON string).
* Forwarded as multipart/form-data to the backend.
+ *
+ * Returns a discriminated union so the caller can inspect the HTTP status
+ * (Server Actions cannot propagate custom Error subclasses to the client).
*/
-export async function sendChatMessage(formData: FormData): Promise {
+export async function sendChatMessage(formData: FormData): Promise {
const headers = await getAuthHeaders()
- // Do NOT set Content-Type -- fetch will set the multipart boundary automatically
- const res = await fetch(`${API_BASE}/api/chat`, {
- method: 'POST',
- headers,
- body: formData,
- })
+ const controller = new AbortController()
+ const timeoutId = setTimeout(() => controller.abort(), CHAT_TIMEOUT_MS)
- if (!res.ok) {
- const error = await res.json().catch(() => null)
- throw new Error(error?.error ?? error?.message ?? `Failed with status ${res.status}`)
- }
+ try {
+ // Do NOT set Content-Type -- fetch will set the multipart boundary automatically
+ const res = await fetch(`${API_BASE}/api/chat`, {
+ method: 'POST',
+ headers,
+ body: formData,
+ signal: controller.signal,
+ })
- return res.json()
+ if (!res.ok) {
+ const body = await res.json().catch(() => null)
+ const message = body?.error ?? body?.message ?? `Failed with status ${res.status}`
+ return { ok: false, error: message, status: res.status }
+ }
+
+ const data: ChatResponse = await res.json()
+ return { ok: true, data }
+ } catch (err: unknown) {
+ if (err instanceof DOMException && err.name === 'AbortError') {
+ return { ok: false, error: 'Request timed out', status: 408 }
+ }
+ const message = err instanceof Error ? err.message : 'Unknown error'
+ return { ok: false, error: message, status: 500 }
+ } finally {
+ clearTimeout(timeoutId)
+ }
}
diff --git a/apps/web/app/actions/profile.ts b/apps/web/app/actions/profile.ts
index 9df3755f8..1f69cd2d1 100644
--- a/apps/web/app/actions/profile.ts
+++ b/apps/web/app/actions/profile.ts
@@ -87,3 +87,9 @@ export async function resetAccount(): Promise {
method: 'POST',
})
}
+
+export async function dismissCalendarImport(): Promise {
+ await authFetch('/api/calendar/dismiss', {
+ method: 'PUT',
+ })
+}
diff --git a/apps/web/app/api/auth/send-code/route.ts b/apps/web/app/api/auth/send-code/route.ts
index f8f00a7ae..4d1e421ee 100644
--- a/apps/web/app/api/auth/send-code/route.ts
+++ b/apps/web/app/api/auth/send-code/route.ts
@@ -11,7 +11,6 @@ export async function POST(request: NextRequest) {
const body = await request.json()
const url = `${apiBase}/api/auth/send-code`
- console.log('[send-code] POST', url)
const response = await fetch(url, {
method: 'POST',
@@ -19,20 +18,16 @@ export async function POST(request: NextRequest) {
body: JSON.stringify(body),
})
- console.log('[send-code] response status:', response.status)
-
const data = await response.json().catch(() => null)
if (!response.ok) {
- console.log('[send-code] error data:', JSON.stringify(data))
return NextResponse.json(data ?? { error: 'Authentication failed' }, {
status: response.status,
})
}
return NextResponse.json(data)
- } catch (err: unknown) {
- console.error('[send-code] fetch failed:', err)
+ } catch {
return NextResponse.json({ error: 'Authentication failed' }, { status: 500 })
}
}
diff --git a/apps/web/app/api/subscription/webhook/route.ts b/apps/web/app/api/subscription/webhook/route.ts
deleted file mode 100644
index 3f9e9344c..000000000
--- a/apps/web/app/api/subscription/webhook/route.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { NextResponse, type NextRequest } from 'next/server'
-
-/**
- * BFF: POST /api/subscription/webhook
- * Forwards Stripe webhook to .NET backend with raw body and signature header.
- * Does NOT use auth -- webhooks are unauthenticated.
- */
-export async function POST(request: NextRequest) {
- const apiBase = process.env.API_BASE ?? 'http://localhost:5000'
-
- try {
- const rawBody = await request.text()
- const stripeSignature = request.headers.get('stripe-signature') ?? ''
-
- const response = await fetch(`${apiBase}/api/subscriptions/webhook`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Stripe-Signature': stripeSignature,
- },
- body: rawBody,
- })
-
- const data = await response.text()
-
- return new NextResponse(data, {
- status: response.status,
- headers: {
- 'Content-Type': response.headers.get('Content-Type') ?? 'application/json',
- },
- })
- } catch {
- return NextResponse.json({ error: 'Webhook processing failed' }, { status: 500 })
- }
-}
diff --git a/apps/web/app/api/subscriptions/checkout/route.ts b/apps/web/app/api/subscriptions/checkout/route.ts
new file mode 100644
index 000000000..3584c4fbd
--- /dev/null
+++ b/apps/web/app/api/subscriptions/checkout/route.ts
@@ -0,0 +1,74 @@
+import { NextResponse, type NextRequest } from 'next/server'
+import { getAuthToken, tryRefreshSession } from '@/lib/auth-api'
+
+/**
+ * BFF: POST /api/subscriptions/checkout
+ * Dedicated route that proxies checkout session creation to the .NET backend.
+ * Forwards the client's real IP via X-Forwarded-For for geolocation-based pricing.
+ *
+ * This takes precedence over the catch-all proxy because Next.js resolves
+ * specific routes before [...path]. The catch-all does NOT forward X-Forwarded-For,
+ * which breaks geolocation-based pricing on the backend.
+ */
+
+const IP_PATTERN = /^[\d.:a-fA-F]+$/
+
+function getClientIp(request: NextRequest): string {
+ const forwardedRaw = request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ?? ''
+ const realIpRaw = request.headers.get('x-real-ip') ?? ''
+ return [forwardedRaw, realIpRaw].find((ip) => ip && IP_PATTERN.test(ip)) ?? ''
+}
+
+function buildHeaders(token: string | null, clientIp: string): Record {
+ const headers: Record = {
+ 'Content-Type': 'application/json',
+ 'X-Forwarded-For': clientIp,
+ }
+ if (token) {
+ headers['Authorization'] = `Bearer ${token}`
+ }
+ return headers
+}
+
+async function proxyCheckout(
+ body: string,
+ token: string | null,
+ clientIp: string,
+): Promise {
+ const apiBase = process.env.API_BASE ?? 'http://localhost:5000'
+ return fetch(`${apiBase}/api/subscriptions/checkout`, {
+ method: 'POST',
+ headers: buildHeaders(token, clientIp),
+ body,
+ })
+}
+
+export async function POST(request: NextRequest) {
+ const token = await getAuthToken()
+ const clientIp = getClientIp(request)
+ const body = await request.text()
+
+ const response = await proxyCheckout(body, token, clientIp)
+
+ if (response.status === 401) {
+ const newToken = await tryRefreshSession()
+ if (newToken) {
+ const retryResponse = await proxyCheckout(body, newToken, clientIp)
+ const retryData = await retryResponse.text()
+ return new NextResponse(retryData, {
+ status: retryResponse.status,
+ headers: {
+ 'Content-Type': retryResponse.headers.get('Content-Type') ?? 'application/json',
+ },
+ })
+ }
+ }
+
+ const data = await response.text()
+ return new NextResponse(data, {
+ status: response.status,
+ headers: {
+ 'Content-Type': response.headers.get('Content-Type') ?? 'application/json',
+ },
+ })
+}
diff --git a/apps/web/app/api/subscriptions/plans/route.ts b/apps/web/app/api/subscriptions/plans/route.ts
new file mode 100644
index 000000000..df6890296
--- /dev/null
+++ b/apps/web/app/api/subscriptions/plans/route.ts
@@ -0,0 +1,70 @@
+import { NextResponse, type NextRequest } from 'next/server'
+import { getAuthToken, tryRefreshSession } from '@/lib/auth-api'
+
+/**
+ * BFF: GET /api/subscriptions/plans
+ * Dedicated route that proxies plan pricing to the .NET backend.
+ * Forwards the client's real IP via X-Forwarded-For for geolocation-based pricing.
+ *
+ * This takes precedence over the catch-all proxy because Next.js resolves
+ * specific routes before [...path]. The catch-all does NOT forward X-Forwarded-For,
+ * which breaks geolocation-based pricing on the backend.
+ */
+
+const IP_PATTERN = /^[\d.:a-fA-F]+$/
+
+function getClientIp(request: NextRequest): string {
+ const forwardedRaw = request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ?? ''
+ const realIpRaw = request.headers.get('x-real-ip') ?? ''
+ return [forwardedRaw, realIpRaw].find((ip) => ip && IP_PATTERN.test(ip)) ?? ''
+}
+
+function buildHeaders(token: string | null, clientIp: string): Record {
+ const headers: Record = {
+ 'X-Forwarded-For': clientIp,
+ }
+ if (token) {
+ headers['Authorization'] = `Bearer ${token}`
+ }
+ return headers
+}
+
+async function proxyPlans(
+ token: string | null,
+ clientIp: string,
+): Promise {
+ const apiBase = process.env.API_BASE ?? 'http://localhost:5000'
+ return fetch(`${apiBase}/api/subscriptions/plans`, {
+ method: 'GET',
+ headers: buildHeaders(token, clientIp),
+ })
+}
+
+export async function GET(request: NextRequest) {
+ const token = await getAuthToken()
+ const clientIp = getClientIp(request)
+
+ const response = await proxyPlans(token, clientIp)
+
+ if (response.status === 401) {
+ const newToken = await tryRefreshSession()
+ if (newToken) {
+ const retryResponse = await proxyPlans(newToken, clientIp)
+ const retryData = await retryResponse.text()
+ return new NextResponse(retryData, {
+ status: retryResponse.status,
+ headers: {
+ 'Content-Type': retryResponse.headers.get('Content-Type') ?? 'application/json',
+ },
+ })
+ }
+ }
+
+ const data = await response.text()
+ return new NextResponse(data, {
+ status: response.status,
+ headers: {
+ 'Content-Type': response.headers.get('Content-Type') ?? 'application/json',
+ },
+ })
+}
diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css
index f2dcba893..3639a3d79 100644
--- a/apps/web/app/globals.css
+++ b/apps/web/app/globals.css
@@ -442,6 +442,120 @@ input[type="date"]::-webkit-calendar-picker-indicator {
animation: ring-complete-pulse 800ms var(--ease-out);
}
+/* ═══════════════════════════════════════════════════════
+ FRESH START ANIMATION
+ ═══════════════════════════════════════════════════════ */
+
+.fresh-start-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 99999;
+ opacity: 0;
+ transition: opacity 0.4s ease;
+}
+
+.fresh-start-overlay.is-visible {
+ opacity: 1;
+}
+
+.fresh-start-overlay.is-fading-out {
+ opacity: 0;
+ transition: opacity 0.5s ease;
+}
+
+/* Center orb */
+.fresh-start-orb {
+ width: 5rem;
+ height: 5rem;
+ border-radius: 9999px;
+ border: 2px solid var(--color-primary);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ transform: scale(0.3);
+ box-shadow: 0 0 0 0 rgba(var(--primary-shadow), 0);
+}
+
+.is-visible .fresh-start-orb {
+ animation: fresh-start-orb 0.8s var(--ease-spring) forwards;
+}
+
+/* Radiating rings */
+.fresh-start-ring {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 5rem;
+ height: 5rem;
+ margin-top: -2.5rem;
+ margin-left: -2.5rem;
+ border-radius: 9999px;
+ border: 2px solid rgba(var(--primary-shadow), 0.4);
+ opacity: 0;
+ transform: scale(0.5);
+ pointer-events: none;
+}
+
+.is-visible .fresh-start-ring-1 {
+ animation: fresh-start-ring 1.2s ease-out 0.2s forwards;
+}
+
+.is-visible .fresh-start-ring-2 {
+ animation: fresh-start-ring 1.2s ease-out 0.4s forwards;
+}
+
+/* Text reveal */
+.fresh-start-text {
+ opacity: 0;
+ transform: translateY(10px);
+}
+
+.is-visible .fresh-start-text {
+ animation: fresh-start-text 0.6s var(--ease-out) 0.8s forwards;
+}
+
+/* Fresh start keyframes */
+@keyframes fresh-start-orb {
+ 0% {
+ opacity: 0;
+ transform: scale(0.3);
+ box-shadow: 0 0 0 0 rgba(var(--primary-shadow), 0);
+ }
+ 50% {
+ opacity: 1;
+ transform: scale(1.1);
+ box-shadow: 0 0 30px rgba(var(--primary-shadow), 0.3), 0 0 60px rgba(var(--primary-shadow), 0.15);
+ }
+ 100% {
+ opacity: 1;
+ transform: scale(1);
+ box-shadow: 0 0 20px rgba(var(--primary-shadow), 0.2), 0 0 40px rgba(var(--primary-shadow), 0.1);
+ }
+}
+
+@keyframes fresh-start-ring {
+ 0% {
+ opacity: 0.6;
+ transform: scale(0.5);
+ }
+ 100% {
+ opacity: 0;
+ transform: scale(3);
+ }
+}
+
+@keyframes fresh-start-text {
+ 0% {
+ opacity: 0;
+ transform: translateY(10px);
+ }
+ 100% {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
/* ═══════════════════════════════════════════════════════
ACCESSIBILITY
═══════════════════════════════════════════════════════ */
@@ -454,6 +568,28 @@ input[type="date"]::-webkit-calendar-picker-indicator {
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
+
+ /* Fresh start: simple fade only */
+ .fresh-start-orb,
+ .fresh-start-ring,
+ .fresh-start-text {
+ animation: none !important;
+ }
+
+ .is-visible .fresh-start-orb {
+ opacity: 1;
+ transform: scale(1);
+ box-shadow: 0 0 20px rgba(var(--primary-shadow), 0.2);
+ }
+
+ .is-visible .fresh-start-ring {
+ display: none;
+ }
+
+ .is-visible .fresh-start-text {
+ opacity: 1;
+ transform: translateY(0);
+ }
}
/* Global focus-visible indicator */
diff --git a/apps/web/app/icon.png b/apps/web/app/icon.png
new file mode 100644
index 000000000..3b1588a4c
Binary files /dev/null and b/apps/web/app/icon.png differ
diff --git a/apps/web/components/calendar/calendar-day-detail.tsx b/apps/web/components/calendar/calendar-day-detail.tsx
index f18442d16..70307cc53 100644
--- a/apps/web/components/calendar/calendar-day-detail.tsx
+++ b/apps/web/components/calendar/calendar-day-detail.tsx
@@ -65,8 +65,8 @@ export function CalendarDayDetail({
const formattedDate = useMemo(() => {
if (!dateStr) return ''
const date = parseAPIDate(dateStr)
- return format(date, locale === 'pt-BR' ? "EEEE, dd 'de' MMMM 'de' yyyy" : 'EEEE, MMMM d, yyyy', { locale: dateFnsLocale })
- }, [dateStr, locale, dateFnsLocale])
+ return format(date, 'EEEE, MMM d', { locale: dateFnsLocale })
+ }, [dateStr, dateFnsLocale])
const filteredEntries = useMemo(() => {
if (showRecurring) return entries
diff --git a/apps/web/components/gamification/achievement-card.tsx b/apps/web/components/gamification/achievement-card.tsx
index 94e46e347..6254bfa6d 100644
--- a/apps/web/components/gamification/achievement-card.tsx
+++ b/apps/web/components/gamification/achievement-card.tsx
@@ -59,7 +59,7 @@ export function AchievementCard({ achievement, earned, earnedDate }: Achievement
{earned && earnedDate && (
- {t('gamification.page.earnedOn', { date: format(new Date(earnedDate), locale === 'pt-BR' ? 'dd MMM yyyy' : 'MMM d, yyyy', { locale: dateFnsLocale }) })}
+ {t('gamification.page.earnedOn', { date: format(new Date(earnedDate), 'PPP', { locale: dateFnsLocale }) })}
)}
diff --git a/apps/web/components/gamification/achievement-toast.tsx b/apps/web/components/gamification/achievement-toast.tsx
index 98752aa09..c34c29dba 100644
--- a/apps/web/components/gamification/achievement-toast.tsx
+++ b/apps/web/components/gamification/achievement-toast.tsx
@@ -3,54 +3,73 @@
import { useState, useEffect, useRef, useCallback } from 'react'
import { createPortal } from 'react-dom'
import { useTranslations } from 'next-intl'
+import { useGamificationProfile } from '@/hooks/use-gamification'
+import { usePortalContainer } from '@/hooks/use-portal-container'
import type { Achievement } from '@orbit/shared/types/gamification'
-interface AchievementToastProps {
- newAchievements: Achievement[]
- onClear: () => void
-}
-
-export function AchievementToast({ newAchievements, onClear }: AchievementToastProps) {
+export function AchievementToast() {
const t = useTranslations()
+ const portalContainer = usePortalContainer('achievement-toast')
+ const { newAchievements, invalidate } = useGamificationProfile()
const [visible, setVisible] = useState(false)
const [currentAchievement, setCurrentAchievement] = useState(null)
const queueRef = useRef([])
const [mounted, setMounted] = useState(false)
+ const [shouldRender, setShouldRender] = useState(false)
+ const [isVisible, setIsVisible] = useState(false)
+ const visibleRef = useRef(false)
useEffect(() => {
setMounted(true)
}, [])
+ // Keep visibleRef in sync
+ useEffect(() => {
+ visibleRef.current = visible
+ }, [visible])
+
const processQueue = useCallback(() => {
- if (queueRef.current.length === 0) return
+ if (visibleRef.current || queueRef.current.length === 0) return
const next = queueRef.current.shift() ?? null
setCurrentAchievement(next)
setVisible(true)
+ setShouldRender(true)
+ requestAnimationFrame(() => setIsVisible(true))
setTimeout(() => {
setVisible(false)
- setTimeout(() => processQueue(), 400)
+ setIsVisible(false)
+ setTimeout(() => {
+ setShouldRender(false)
+ processQueue()
+ }, 400)
}, 4000)
}, [])
useEffect(() => {
if (newAchievements.length > 0) {
queueRef.current.push(...newAchievements)
- onClear()
- if (!visible) {
+ invalidate()
+ if (!visibleRef.current) {
processQueue()
}
}
- }, [newAchievements, onClear, processQueue, visible])
+ }, [newAchievements, invalidate, processQueue])
- if (!mounted || !visible || !currentAchievement) return null
+ if (!mounted || !shouldRender || !currentAchievement) return null
- return createPortal(
+ return portalContainer ? createPortal(
{'\u2B50'}
@@ -70,6 +89,6 @@ export function AchievementToast({ newAchievements, onClear }: AchievementToastP
,
- document.body
- )
+ portalContainer
+ ) : null
}
diff --git a/apps/web/components/gamification/all-done-celebration.tsx b/apps/web/components/gamification/all-done-celebration.tsx
index 2bd67ab37..4a620454e 100644
--- a/apps/web/components/gamification/all-done-celebration.tsx
+++ b/apps/web/components/gamification/all-done-celebration.tsx
@@ -4,14 +4,18 @@ import { useState, useEffect, useRef } from 'react'
import { createPortal } from 'react-dom'
import { useTranslations } from 'next-intl'
import { useUIStore } from '@/stores/ui-store'
+import { usePortalContainer } from '@/hooks/use-portal-container'
import './all-done-celebration.css'
export function AllDoneCelebration() {
const t = useTranslations()
+ const portalContainer = usePortalContainer('all-done-celebration')
const allDoneCelebration = useUIStore((s) => s.allDoneCelebration)
const setAllDoneCelebration = useUIStore((s) => s.setAllDoneCelebration)
const [visible, setVisible] = useState(false)
const [mounted, setMounted] = useState(false)
+ const [shouldRender, setShouldRender] = useState(false)
+ const [isVisible, setIsVisible] = useState(false)
const dismissTimerRef = useRef>(undefined)
useEffect(() => {
@@ -24,25 +28,35 @@ export function AllDoneCelebration() {
useEffect(() => {
if (allDoneCelebration) {
setVisible(true)
+ setShouldRender(true)
+ requestAnimationFrame(() => setIsVisible(true))
if (dismissTimerRef.current) clearTimeout(dismissTimerRef.current)
dismissTimerRef.current = setTimeout(() => {
setVisible(false)
+ setIsVisible(false)
setAllDoneCelebration(false)
+ setTimeout(() => setShouldRender(false), 300)
}, 3500)
}
}, [allDoneCelebration, setAllDoneCelebration])
function dismiss() {
setVisible(false)
+ setIsVisible(false)
setAllDoneCelebration(false)
+ setTimeout(() => setShouldRender(false), 300)
}
- if (!mounted || !visible) return null
+ if (!mounted || !shouldRender) return null
- return createPortal(
+ return portalContainer ? createPortal(
{/* Backdrop */}
@@ -95,6 +109,6 @@ export function AllDoneCelebration() {
,
- document.body
- )
+ portalContainer
+ ) : null
}
diff --git a/apps/web/components/gamification/goal-completed-celebration.tsx b/apps/web/components/gamification/goal-completed-celebration.tsx
index 6b9b51cad..553d5155f 100644
--- a/apps/web/components/gamification/goal-completed-celebration.tsx
+++ b/apps/web/components/gamification/goal-completed-celebration.tsx
@@ -4,15 +4,19 @@ import { useState, useEffect, useRef } from 'react'
import { createPortal } from 'react-dom'
import { useTranslations } from 'next-intl'
import { useUIStore } from '@/stores/ui-store'
+import { usePortalContainer } from '@/hooks/use-portal-container'
import './goal-completed-celebration.css'
export function GoalCompletedCelebration() {
const t = useTranslations()
+ const portalContainer = usePortalContainer('goal-completed-celebration')
const goalCompletedCelebration = useUIStore((s) => s.goalCompletedCelebration)
const setGoalCompletedCelebration = useUIStore((s) => s.setGoalCompletedCelebration)
const [visible, setVisible] = useState(false)
const [goalName, setGoalName] = useState('')
const [mounted, setMounted] = useState(false)
+ const [shouldRender, setShouldRender] = useState(false)
+ const [isVisible, setIsVisible] = useState(false)
const dismissTimerRef = useRef>(undefined)
useEffect(() => {
@@ -26,24 +30,34 @@ export function GoalCompletedCelebration() {
if (goalCompletedCelebration) {
setGoalName(goalCompletedCelebration.name)
setVisible(true)
+ setShouldRender(true)
+ requestAnimationFrame(() => setIsVisible(true))
if (dismissTimerRef.current) clearTimeout(dismissTimerRef.current)
dismissTimerRef.current = setTimeout(() => {
setVisible(false)
+ setIsVisible(false)
setGoalCompletedCelebration(null)
+ setTimeout(() => setShouldRender(false), 300)
}, 3500)
}
}, [goalCompletedCelebration, setGoalCompletedCelebration])
function dismiss() {
setVisible(false)
+ setIsVisible(false)
setGoalCompletedCelebration(null)
+ setTimeout(() => setShouldRender(false), 300)
}
- if (!mounted || !visible) return null
+ if (!mounted || !shouldRender) return null
- return createPortal(
+ return portalContainer ? createPortal(
{/* Backdrop */}
@@ -88,6 +102,6 @@ export function GoalCompletedCelebration() {
,
- document.body
- )
+ portalContainer
+ ) : null
}
diff --git a/apps/web/components/gamification/level-up-overlay.tsx b/apps/web/components/gamification/level-up-overlay.tsx
index 72e131444..609585402 100644
--- a/apps/web/components/gamification/level-up-overlay.tsx
+++ b/apps/web/components/gamification/level-up-overlay.tsx
@@ -3,6 +3,7 @@
import { useState, useEffect, useRef } from 'react'
import { createPortal } from 'react-dom'
import { useTranslations } from 'next-intl'
+import { usePortalContainer } from '@/hooks/use-portal-container'
import './level-up-overlay.css'
interface LevelUpOverlayProps {
@@ -13,13 +14,20 @@ interface LevelUpOverlayProps {
export function LevelUpOverlay({ leveledUp, newLevel, onClear }: LevelUpOverlayProps) {
const t = useTranslations()
+ const portalContainer = usePortalContainer('level-up-overlay')
const [visible, setVisible] = useState(false)
const [level, setLevel] = useState(0)
const [title, setTitle] = useState('')
const [mounted, setMounted] = useState(false)
+ const [shouldRender, setShouldRender] = useState(false)
+ const [isVisible, setIsVisible] = useState(false)
+ const timerRef = useRef>(undefined)
useEffect(() => {
setMounted(true)
+ return () => {
+ if (timerRef.current) clearTimeout(timerRef.current)
+ }
}, [])
useEffect(() => {
@@ -27,21 +35,27 @@ export function LevelUpOverlay({ leveledUp, newLevel, onClear }: LevelUpOverlayP
setLevel(newLevel)
setTitle(t(`gamification.levels.${newLevel}`))
setVisible(true)
- const timer = setTimeout(() => {
+ setShouldRender(true)
+ requestAnimationFrame(() => setIsVisible(true))
+ timerRef.current = setTimeout(() => {
setVisible(false)
+ setIsVisible(false)
onClear()
+ setTimeout(() => setShouldRender(false), 400)
}, 3000)
- return () => clearTimeout(timer)
}
}, [leveledUp, newLevel, onClear, t])
- if (!mounted || !visible) return null
+ if (!mounted || !shouldRender) return null
- return createPortal(
+ return portalContainer ? createPortal(
{/* Orbital ring animation */}
@@ -70,6 +84,6 @@ export function LevelUpOverlay({ leveledUp, newLevel, onClear }: LevelUpOverlayP
,
- document.body
- )
+ portalContainer
+ ) : null
}
diff --git a/apps/web/components/gamification/streak-celebration.tsx b/apps/web/components/gamification/streak-celebration.tsx
index c65c4c383..8a46cac77 100644
--- a/apps/web/components/gamification/streak-celebration.tsx
+++ b/apps/web/components/gamification/streak-celebration.tsx
@@ -5,17 +5,21 @@ import { createPortal } from 'react-dom'
import { useTranslations } from 'next-intl'
import { plural } from '@/lib/plural'
import { useUIStore } from '@/stores/ui-store'
+import { usePortalContainer } from '@/hooks/use-portal-container'
import './streak-celebration.css'
const MILESTONE_VALUES = [7, 14, 30, 100, 365] as const
export function StreakCelebration() {
const t = useTranslations()
+ const portalContainer = usePortalContainer('streak-celebration')
const streakCelebration = useUIStore((s) => s.streakCelebration)
const setStreakCelebration = useUIStore((s) => s.setStreakCelebration)
const [visible, setVisible] = useState(false)
const [streakCount, setStreakCount] = useState(0)
const [mounted, setMounted] = useState(false)
+ const [shouldRender, setShouldRender] = useState(false)
+ const [isVisible, setIsVisible] = useState(false)
const dismissTimerRef = useRef>(undefined)
useEffect(() => {
@@ -29,10 +33,14 @@ export function StreakCelebration() {
if (streakCelebration) {
setStreakCount(streakCelebration.streak)
setVisible(true)
+ setShouldRender(true)
+ requestAnimationFrame(() => setIsVisible(true))
if (dismissTimerRef.current) clearTimeout(dismissTimerRef.current)
dismissTimerRef.current = setTimeout(() => {
setVisible(false)
+ setIsVisible(false)
setStreakCelebration(null)
+ setTimeout(() => setShouldRender(false), 300)
}, 2500)
}
}, [streakCelebration, setStreakCelebration])
@@ -51,15 +59,21 @@ export function StreakCelebration() {
function dismiss() {
setVisible(false)
+ setIsVisible(false)
setStreakCelebration(null)
+ setTimeout(() => setShouldRender(false), 300)
}
- if (!mounted || !visible) return null
+ if (!mounted || !shouldRender) return null
- return createPortal(
+ return portalContainer ? createPortal(
{/* Backdrop */}
@@ -118,6 +132,6 @@ export function StreakCelebration() {
,
- document.body
- )
+ portalContainer
+ ) : null
}
diff --git a/apps/web/components/gamification/streak-freeze-celebration.tsx b/apps/web/components/gamification/streak-freeze-celebration.tsx
index 60ecf785b..5a46ee3d7 100644
--- a/apps/web/components/gamification/streak-freeze-celebration.tsx
+++ b/apps/web/components/gamification/streak-freeze-celebration.tsx
@@ -3,6 +3,7 @@
import { useState, useEffect, useImperativeHandle, forwardRef, useRef } from 'react'
import { createPortal } from 'react-dom'
import { useTranslations } from 'next-intl'
+import { usePortalContainer } from '@/hooks/use-portal-container'
import './streak-freeze-celebration.css'
export interface StreakFreezeCelebrationHandle {
@@ -12,8 +13,11 @@ export interface StreakFreezeCelebrationHandle {
export const StreakFreezeCelebration = forwardRef(
function StreakFreezeCelebration(_props, ref) {
const t = useTranslations()
+ const portalContainer = usePortalContainer('streak-freeze-celebration')
const [visible, setVisible] = useState(false)
const [mounted, setMounted] = useState(false)
+ const [shouldRender, setShouldRender] = useState(false)
+ const [isVisible, setIsVisible] = useState(false)
const dismissTimerRef = useRef>(undefined)
useEffect(() => {
@@ -25,24 +29,34 @@ export const StreakFreezeCelebration = forwardRef
function show() {
setVisible(true)
+ setShouldRender(true)
+ requestAnimationFrame(() => setIsVisible(true))
if (dismissTimerRef.current) clearTimeout(dismissTimerRef.current)
dismissTimerRef.current = setTimeout(() => {
setVisible(false)
+ setIsVisible(false)
+ setTimeout(() => setShouldRender(false), 300)
}, 3000)
}
function dismiss() {
setVisible(false)
+ setIsVisible(false)
if (dismissTimerRef.current) clearTimeout(dismissTimerRef.current)
+ setTimeout(() => setShouldRender(false), 300)
}
useImperativeHandle(ref, () => ({ show }))
- if (!mounted || !visible) return null
+ if (!mounted || !shouldRender) return null
- return createPortal(
+ return portalContainer ? createPortal(
{/* Backdrop */}
@@ -84,7 +98,7 @@ export const StreakFreezeCelebration = forwardRef
,
- document.body
- )
+ portalContainer
+ ) : null
}
)
diff --git a/apps/web/components/gamification/welcome-back-toast.tsx b/apps/web/components/gamification/welcome-back-toast.tsx
index 9acd70a2b..fba6f57f1 100644
--- a/apps/web/components/gamification/welcome-back-toast.tsx
+++ b/apps/web/components/gamification/welcome-back-toast.tsx
@@ -4,14 +4,18 @@ import { useState, useEffect, useRef } from 'react'
import { createPortal } from 'react-dom'
import { useTranslations } from 'next-intl'
import { useProfile } from '@/hooks/use-profile'
+import { usePortalContainer } from '@/hooks/use-portal-container'
export function WelcomeBackToast() {
const t = useTranslations()
+ const portalContainer = usePortalContainer('welcome-back-toast')
const { profile } = useProfile()
const [visible, setVisible] = useState(false)
const [toastMessage, setToastMessage] = useState('')
const [toastEmoji, setToastEmoji] = useState('\uD83D\uDC4B')
const [mounted, setMounted] = useState(false)
+ const [shouldRender, setShouldRender] = useState(false)
+ const [isVisible, setIsVisible] = useState(false)
const dismissTimerRef = useRef>(undefined)
const checkedRef = useRef(false)
@@ -26,12 +30,22 @@ export function WelcomeBackToast() {
setToastMessage(message)
setToastEmoji(emoji)
setVisible(true)
+ setShouldRender(true)
+ requestAnimationFrame(() => setIsVisible(true))
if (dismissTimerRef.current) clearTimeout(dismissTimerRef.current)
dismissTimerRef.current = setTimeout(() => {
setVisible(false)
+ setIsVisible(false)
+ setTimeout(() => setShouldRender(false), 300)
}, 4000)
}
+ function dismiss() {
+ setVisible(false)
+ setIsVisible(false)
+ setTimeout(() => setShouldRender(false), 300)
+ }
+
useEffect(() => {
if (!profile || checkedRef.current) return
checkedRef.current = true
@@ -59,13 +73,19 @@ export function WelcomeBackToast() {
}
}, [profile, t])
- if (!mounted || !visible) return null
+ if (!mounted || !shouldRender) return null
- return createPortal(
+ return portalContainer ? createPortal(
setVisible(false)}
+ className="fixed top-4 left-1/2 z-[10000] max-w-sm w-[calc(100%-2rem)] bg-surface-overlay border border-border-muted rounded-2xl shadow-[var(--shadow-lg)] backdrop-blur-xl px-5 py-4 cursor-pointer"
+ style={{
+ transition: 'opacity 0.4s var(--ease-spring), transform 0.4s var(--ease-spring)',
+ opacity: isVisible ? 1 : 0,
+ transform: isVisible
+ ? 'translate(-50%, 0) scale(1)'
+ : 'translate(-50%, -20px) scale(0.95)',
+ }}
+ onClick={dismiss}
>
{toastEmoji}
@@ -74,6 +94,6 @@ export function WelcomeBackToast() {
,
- document.body
- )
+ portalContainer
+ ) : null
}
diff --git a/apps/web/components/goals/goal-list.tsx b/apps/web/components/goals/goal-list.tsx
index aaa944978..04bb556ba 100644
--- a/apps/web/components/goals/goal-list.tsx
+++ b/apps/web/components/goals/goal-list.tsx
@@ -1,6 +1,6 @@
'use client'
-import { useRef, useCallback } from 'react'
+import { useRef, useCallback, useState } from 'react'
import { GoalCard } from './goal-card'
import { useReorderGoals } from '@/hooks/use-goals'
import type { Goal, GoalPositionItem } from '@orbit/shared/types/goal'
@@ -13,6 +13,16 @@ interface GoalListProps {
goals: Goal[]
}
+// ---------------------------------------------------------------------------
+// Constants (matching Nuxt SortableJS config)
+// ---------------------------------------------------------------------------
+
+/** Delay before touch drag starts (ms) -- matches SortableJS delay: 300 */
+const TOUCH_HOLD_DELAY = 300
+
+/** Minimum movement (px) before cancelling hold -- matches touchStartThreshold: 5 */
+const TOUCH_MOVE_THRESHOLD = 5
+
// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------
@@ -21,19 +31,25 @@ export function GoalList({ goals }: GoalListProps) {
const listRef = useRef(null)
const reorderGoals = useReorderGoals()
- // Drag state
+ // Drag state (shared between mouse and touch)
const dragItemRef = useRef(null)
const dragOverItemRef = useRef(null)
- const handleDragStart = useCallback((index: number) => {
- dragItemRef.current = index
- }, [])
+ // Visual state
+ const [dragIndex, setDragIndex] = useState(null)
+ const [dragOverIndex, setDragOverIndex] = useState(null)
- const handleDragEnter = useCallback((index: number) => {
- dragOverItemRef.current = index
- }, [])
+ // Touch state
+ const touchTimerRef = useRef | null>(null)
+ const touchStartPos = useRef<{ x: number; y: number } | null>(null)
+ const touchDragging = useRef(false)
+ const touchItemRef = useRef(null)
- const handleDragEnd = useCallback(() => {
+ // -------------------------------------------------------------------------
+ // Reorder logic (shared)
+ // -------------------------------------------------------------------------
+
+ const commitReorder = useCallback(() => {
if (
dragItemRef.current === null ||
dragOverItemRef.current === null ||
@@ -41,10 +57,11 @@ export function GoalList({ goals }: GoalListProps) {
) {
dragItemRef.current = null
dragOverItemRef.current = null
+ setDragIndex(null)
+ setDragOverIndex(null)
return
}
- // Build reordered list
const reordered = [...goals]
const [draggedItem] = reordered.splice(dragItemRef.current, 1)
if (draggedItem) {
@@ -60,18 +77,141 @@ export function GoalList({ goals }: GoalListProps) {
dragItemRef.current = null
dragOverItemRef.current = null
+ setDragIndex(null)
+ setDragOverIndex(null)
}, [goals, reorderGoals])
+ // -------------------------------------------------------------------------
+ // HTML5 drag handlers (mouse/pointer)
+ // -------------------------------------------------------------------------
+
+ const handleDragStart = useCallback((index: number) => {
+ dragItemRef.current = index
+ setDragIndex(index)
+ }, [])
+
+ const handleDragEnter = useCallback((index: number) => {
+ dragOverItemRef.current = index
+ setDragOverIndex(index)
+ }, [])
+
+ const handleDragEnd = useCallback(() => {
+ commitReorder()
+ }, [commitReorder])
+
+ // -------------------------------------------------------------------------
+ // Touch handlers (mobile support with 300ms hold delay)
+ // -------------------------------------------------------------------------
+
+ const clearTouchTimer = useCallback(() => {
+ if (touchTimerRef.current) {
+ clearTimeout(touchTimerRef.current)
+ touchTimerRef.current = null
+ }
+ }, [])
+
+ const getItemIndexFromPoint = useCallback((x: number, y: number): number | null => {
+ const list = listRef.current
+ if (!list) return null
+ const children = Array.from(list.children) as HTMLElement[]
+ for (let i = 0; i < children.length; i++) {
+ const child = children[i]
+ if (!child) continue
+ const rect = child.getBoundingClientRect()
+ if (y >= rect.top && y <= rect.bottom) {
+ return i
+ }
+ }
+ return null
+ }, [])
+
+ const handleTouchStart = useCallback(
+ (index: number, e: React.TouchEvent) => {
+ const touch = e.touches[0]
+ if (!touch) return
+ touchStartPos.current = { x: touch.clientX, y: touch.clientY }
+ touchItemRef.current = e.currentTarget
+
+ touchTimerRef.current = setTimeout(() => {
+ touchDragging.current = true
+ dragItemRef.current = index
+ setDragIndex(index)
+ }, TOUCH_HOLD_DELAY)
+ },
+ [],
+ )
+
+ const handleTouchMove = useCallback(
+ (e: React.TouchEvent) => {
+ const touch = e.touches[0]
+ if (!touch) return
+
+ // Cancel hold if moved too far before delay elapsed
+ if (!touchDragging.current && touchStartPos.current) {
+ const dx = Math.abs(touch.clientX - touchStartPos.current.x)
+ const dy = Math.abs(touch.clientY - touchStartPos.current.y)
+ if (dx > TOUCH_MOVE_THRESHOLD || dy > TOUCH_MOVE_THRESHOLD) {
+ clearTouchTimer()
+ return
+ }
+ }
+
+ if (!touchDragging.current) return
+
+ // Prevent scrolling while dragging
+ e.preventDefault()
+
+ const overIndex = getItemIndexFromPoint(touch.clientX, touch.clientY)
+ if (overIndex !== null) {
+ dragOverItemRef.current = overIndex
+ setDragOverIndex(overIndex)
+ }
+ },
+ [clearTouchTimer, getItemIndexFromPoint],
+ )
+
+ const handleTouchEnd = useCallback(() => {
+ clearTouchTimer()
+ if (touchDragging.current) {
+ touchDragging.current = false
+ commitReorder()
+ }
+ touchStartPos.current = null
+ touchItemRef.current = null
+ }, [clearTouchTimer, commitReorder])
+
+ // -------------------------------------------------------------------------
+ // CSS class helper
+ // -------------------------------------------------------------------------
+
+ const getDragClasses = useCallback(
+ (index: number): string => {
+ if (dragIndex === null) return ''
+ if (index === dragIndex) return 'drag-chosen'
+ if (index === dragOverIndex) return 'drag-ghost'
+ return ''
+ },
+ [dragIndex, dragOverIndex],
+ )
+
+ // -------------------------------------------------------------------------
+ // Render
+ // -------------------------------------------------------------------------
+
return (
{goals.map((goal, index) => (
handleDragStart(index)}
onDragEnter={() => handleDragEnter(index)}
onDragEnd={handleDragEnd}
onDragOver={(e) => e.preventDefault()}
+ onTouchStart={(e) => handleTouchStart(index, e)}
+ onTouchMove={handleTouchMove}
+ onTouchEnd={handleTouchEnd}
>
diff --git a/apps/web/components/habits/create-habit-modal.tsx b/apps/web/components/habits/create-habit-modal.tsx
index 7bfa48d35..14e82a73e 100644
--- a/apps/web/components/habits/create-habit-modal.tsx
+++ b/apps/web/components/habits/create-habit-modal.tsx
@@ -9,7 +9,8 @@ import { useHabitForm } from '@/hooks/use-habit-form'
import { useTagSelection } from '@/hooks/use-tag-selection'
import { useCreateHabit, useCreateSubHabit } from '@/hooks/use-habits'
import { formatAPIDate } from '@orbit/shared/utils'
-import type { NormalizedHabit, CreateHabitRequest, CreateSubHabitRequest } from '@orbit/shared/types/habit'
+import { useUIStore } from '@/stores/ui-store'
+import type { NormalizedHabit, CreateHabitRequest, CreateSubHabitRequest, ScheduledReminderTime } from '@orbit/shared/types/habit'
// ---------------------------------------------------------------------------
// Props
@@ -36,6 +37,7 @@ export function CreateHabitModal({
const createHabit = useCreateHabit()
const createSubHabit = useCreateSubHabit()
const isSubHabitMode = !!parentHabit
+ const activeView = useUIStore((s) => s.activeView)
const formHelpers = useHabitForm({
initialData: {
@@ -47,8 +49,9 @@ export function CreateHabitModal({
const [selectedGoalIds, setSelectedGoalIds] = useState
([])
const [subHabits, setSubHabits] = useState([])
const [validationError, setValidationError] = useState('')
+ const [reminderTimes, setReminderTimes] = useState([0, 15])
- const atGoalLimit = selectedGoalIds.length >= 5
+ const atGoalLimit = selectedGoalIds.length >= 10
const toggleGoal = useCallback((goalId: string) => {
setSelectedGoalIds((prev) => {
@@ -83,25 +86,49 @@ export function CreateHabitModal({
setSelectedGoalIds([])
setSubHabits([])
setValidationError('')
+ setReminderTimes([0, 15])
// Prefill from parent if sub-habit mode
if (parentHabit) {
+ formHelpers.form.setValue('frequencyUnit', parentHabit.frequencyUnit)
+ formHelpers.form.setValue('frequencyQuantity', parentHabit.frequencyQuantity)
+ if (parentHabit.days?.length) {
+ formHelpers.form.setValue('days', [...parentHabit.days])
+ }
formHelpers.form.setValue('isBadHabit', parentHabit.isBadHabit)
+ formHelpers.form.setValue('isGeneral', parentHabit.isGeneral ?? false)
+ formHelpers.form.setValue('isFlexible', parentHabit.isFlexible ?? false)
+ formHelpers.form.setValue('slipAlertEnabled', parentHabit.slipAlertEnabled ?? false)
+ formHelpers.form.setValue('dueDate', parentHabit.dueDate ?? initialDate ?? formatAPIDate(new Date()))
+ formHelpers.form.setValue('dueTime', parentHabit.dueTime?.slice(0, 5) ?? '')
+ formHelpers.form.setValue('dueEndTime', parentHabit.dueEndTime?.slice(0, 5) ?? '')
+ formHelpers.form.setValue('endDate', parentHabit.endDate ?? '')
+ formHelpers.form.setValue('reminderEnabled', parentHabit.reminderEnabled ?? false)
+ setReminderTimes(parentHabit.reminderTimes?.length ? [...parentHabit.reminderTimes] : [0, 15])
+ formHelpers.form.setValue('scheduledReminders',
+ parentHabit.scheduledReminders?.length
+ ? parentHabit.scheduledReminders.map((sr: ScheduledReminderTime) => ({ ...sr }))
+ : []
+ )
+
if (parentHabit.isGeneral) {
formHelpers.setGeneral()
} else if (parentHabit.isFlexible) {
formHelpers.setFlexible()
} else if (parentHabit.frequencyUnit) {
formHelpers.setRecurring()
- formHelpers.form.setValue('frequencyUnit', parentHabit.frequencyUnit)
- formHelpers.form.setValue('frequencyQuantity', parentHabit.frequencyQuantity)
- if (parentHabit.days?.length) {
- formHelpers.form.setValue('days', [...parentHabit.days])
- }
+ } else {
+ formHelpers.setOneTime()
}
+
tags.resetTags(parentHabit.tags?.map((t) => t.id) ?? [])
setSelectedGoalIds(parentHabit.linkedGoals?.map((g) => g.id) ?? [])
}
+
+ // Auto-set general mode when on the general view
+ if (activeView === 'general') {
+ formHelpers.setGeneral()
+ }
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [open])
@@ -125,6 +152,7 @@ export function CreateHabitModal({
}
if (data.description) subRequest.description = data.description
if (!data.isGeneral) {
+ // Schedule fields
if (data.dueDate) subRequest.dueDate = data.dueDate
if (data.isFlexible) {
subRequest.isFlexible = true
@@ -136,7 +164,16 @@ export function CreateHabitModal({
if (data.days?.length) subRequest.days = data.days
if (data.endDate) subRequest.endDate = data.endDate
}
- if (data.dueTime) subRequest.dueTime = data.dueTime
+ // Reminder fields
+ if (data.dueTime) {
+ subRequest.dueTime = data.dueTime
+ if (data.dueEndTime) subRequest.dueEndTime = data.dueEndTime
+ subRequest.reminderEnabled = data.reminderEnabled
+ subRequest.reminderTimes = reminderTimes
+ } else if (data.reminderEnabled && (data.scheduledReminders?.length ?? 0) > 0) {
+ subRequest.reminderEnabled = true
+ subRequest.scheduledReminders = data.scheduledReminders ?? undefined
+ }
}
if (data.isBadHabit) {
subRequest.isBadHabit = true
@@ -163,21 +200,27 @@ export function CreateHabitModal({
if (data.isGeneral) {
request.isGeneral = true
} else {
- if (data.dueDate) request.dueDate = data.dueDate
+ // Schedule fields
+ request.dueDate = data.dueDate
if (data.isFlexible) {
request.isFlexible = true
- if (data.frequencyUnit) request.frequencyUnit = data.frequencyUnit
- if (data.frequencyQuantity) request.frequencyQuantity = data.frequencyQuantity
+ request.frequencyUnit = data.frequencyUnit ?? undefined
+ request.frequencyQuantity = data.frequencyQuantity ?? undefined
} else if (data.frequencyUnit) {
request.frequencyUnit = data.frequencyUnit
request.frequencyQuantity = data.frequencyQuantity ?? undefined
if (data.days?.length) request.days = data.days
if (data.endDate) request.endDate = data.endDate
}
+ // Reminder fields (match Nuxt applyReminderFields)
if (data.dueTime) {
request.dueTime = data.dueTime
if (data.dueEndTime) request.dueEndTime = data.dueEndTime
request.reminderEnabled = data.reminderEnabled
+ request.reminderTimes = reminderTimes
+ } else if (data.reminderEnabled && (data.scheduledReminders?.length ?? 0) > 0) {
+ request.reminderEnabled = true
+ request.scheduledReminders = data.scheduledReminders ?? undefined
}
}
if (data.isBadHabit) request.slipAlertEnabled = data.slipAlertEnabled
@@ -196,7 +239,7 @@ export function CreateHabitModal({
}
}
},
- [formHelpers, isSubHabitMode, parentHabit, tags, selectedGoalIds, subHabits, createHabit, createSubHabit, onOpenChange],
+ [formHelpers, isSubHabitMode, parentHabit, tags, selectedGoalIds, subHabits, reminderTimes, createHabit, createSubHabit, onOpenChange],
)
const isPending = createHabit.isPending || createSubHabit.isPending
@@ -219,6 +262,8 @@ export function CreateHabitModal({
selectedGoalIds={selectedGoalIds}
atGoalLimit={atGoalLimit}
onToggleGoal={toggleGoal}
+ reminderTimes={reminderTimes}
+ onReminderTimesChange={setReminderTimes}
>
{/* Sub-habits (create-only, not in sub-habit mode) */}
{!isSubHabitMode && (
diff --git a/apps/web/components/habits/description-viewer.tsx b/apps/web/components/habits/description-viewer.tsx
index 4428b065b..0b245bc78 100644
--- a/apps/web/components/habits/description-viewer.tsx
+++ b/apps/web/components/habits/description-viewer.tsx
@@ -1,9 +1,12 @@
'use client'
-import { useState, useEffect, useMemo } from 'react'
+import { useState, useEffect } from 'react'
import { createPortal } from 'react-dom'
+import { marked } from 'marked'
+import DOMPurify from 'dompurify'
import { ArrowLeft } from 'lucide-react'
import { useTranslations } from 'next-intl'
+import { usePortalContainer } from '@/hooks/use-portal-container'
interface DescriptionViewerProps {
open: boolean
@@ -12,23 +15,6 @@ interface DescriptionViewerProps {
description: string
}
-/**
- * Minimal Markdown-like rendering: bold, italic, headers, line breaks.
- * For full Markdown, install `marked` and `dompurify` packages.
- */
-function renderSimpleMarkdown(text: string): string {
- return text
- .replace(/&/g, '&')
- .replace(//g, '>')
- .replace(/^### (.+)$/gm, '$1 ')
- .replace(/^## (.+)$/gm, '$1 ')
- .replace(/^# (.+)$/gm, '$1 ')
- .replace(/\*\*(.+?)\*\*/g, '$1 ')
- .replace(/\*(.+?)\*/g, '$1 ')
- .replace(/\n/g, ' ')
-}
-
export function DescriptionViewer({
open,
onOpenChange,
@@ -36,20 +22,26 @@ export function DescriptionViewer({
description,
}: DescriptionViewerProps) {
const t = useTranslations()
+ const portalContainer = usePortalContainer('description-viewer')
const [mounted, setMounted] = useState(false)
+ const [renderedHtml, setRenderedHtml] = useState('')
useEffect(() => {
setMounted(true)
}, [])
- const renderedHtml = useMemo(() => {
- if (!description) return ''
- return renderSimpleMarkdown(description)
- }, [description])
+ useEffect(() => {
+ if (!open || !description) {
+ setRenderedHtml('')
+ return
+ }
+ const raw = marked.parse(description, { async: false }) as string
+ setRenderedHtml(DOMPurify.sanitize(raw))
+ }, [open, description])
if (!mounted || !open) return null
- return createPortal(
+ return portalContainer ? createPortal(
{/* Header */}
@@ -71,6 +63,6 @@ export function DescriptionViewer({
/>
,
- document.body,
- )
+ portalContainer,
+ ) : null
}
diff --git a/apps/web/components/habits/edit-habit-modal.tsx b/apps/web/components/habits/edit-habit-modal.tsx
index 1ffd1a8d4..7a7e74958 100644
--- a/apps/web/components/habits/edit-habit-modal.tsx
+++ b/apps/web/components/habits/edit-habit-modal.tsx
@@ -8,6 +8,8 @@ import { HabitFormFields } from './habit-form-fields'
import { useHabitForm } from '@/hooks/use-habit-form'
import { useTagSelection } from '@/hooks/use-tag-selection'
import { useUpdateHabit, useHabitDetail } from '@/hooks/use-habits'
+import { assignTags } from '@/app/actions/tags'
+import { getErrorMessage } from '@orbit/shared/utils'
import type { NormalizedHabit, UpdateHabitRequest } from '@orbit/shared/types/habit'
// ---------------------------------------------------------------------------
@@ -36,12 +38,14 @@ export function EditHabitModal({
const tags = useTagSelection()
const [selectedGoalIds, setSelectedGoalIds] = useState([])
const [validationError, setValidationError] = useState('')
+ const [detailFetchError, setDetailFetchError] = useState('')
const [originalEndDate, setOriginalEndDate] = useState('')
+ const [reminderTimes, setReminderTimes] = useState([0, 15])
- const atGoalLimit = selectedGoalIds.length >= 5
+ const atGoalLimit = selectedGoalIds.length >= 10
// Fetch detail to get dueDate, dueTime, endDate etc.
- const { data: habitDetail } = useHabitDetail(open && habit ? habit.id : null)
+ const { data: habitDetail, error: detailError } = useHabitDetail(open && habit ? habit.id : null)
const toggleGoal = useCallback((goalId: string) => {
setSelectedGoalIds((prev) => {
@@ -51,10 +55,20 @@ export function EditHabitModal({
})
}, [])
+ // Show detail fetch error
+ useEffect(() => {
+ if (detailError) {
+ setDetailFetchError(getErrorMessage(detailError, t('errors.fetchHabits')))
+ }
+ }, [detailError, t])
+
// Populate form when modal opens or detail loads
useEffect(() => {
if (!open || !habit) return
+ setValidationError('')
+ setDetailFetchError('')
+
formHelpers.form.reset({
title: habit.title,
description: habit.description || '',
@@ -75,9 +89,9 @@ export function EditHabitModal({
})
setOriginalEndDate(habitDetail?.endDate ?? '')
+ setReminderTimes(habit.reminderTimes?.length ? [...habit.reminderTimes] : [0, 15])
tags.resetTags(habit.tags?.map((t) => t.id) ?? [])
setSelectedGoalIds(habit.linkedGoals?.map((g) => g.id) ?? [])
- setValidationError('')
// Set mode based on habit data
if (habit.isGeneral) {
@@ -116,10 +130,11 @@ export function EditHabitModal({
if (data.description) request.description = data.description
if (!data.isGeneral) {
+ // Schedule fields
if (data.dueDate) request.dueDate = data.dueDate
- if (data.frequencyUnit) {
- request.frequencyUnit = data.frequencyUnit
+ if (!formHelpers.isOneTime) {
+ request.frequencyUnit = data.frequencyUnit ?? undefined
request.frequencyQuantity = data.frequencyQuantity ?? undefined
if (data.days?.length) request.days = data.days
if (data.endDate) {
@@ -129,10 +144,15 @@ export function EditHabitModal({
}
}
+ // Reminder fields (match Nuxt applyRemindersToUpdate)
if (data.dueTime) {
request.dueTime = data.dueTime
request.dueEndTime = data.dueEndTime || undefined
request.reminderEnabled = data.reminderEnabled
+ request.reminderTimes = reminderTimes
+ } else if (data.reminderEnabled && (data.scheduledReminders?.length ?? 0) > 0) {
+ request.reminderEnabled = true
+ request.scheduledReminders = data.scheduledReminders ?? undefined
} else {
request.reminderEnabled = false
}
@@ -144,12 +164,13 @@ export function EditHabitModal({
try {
await updateHabit.mutateAsync({ habitId: habit.id, data: request })
+ await assignTags(habit.id, tags.selectedTagIds)
onOpenChange(false)
} catch {
// Error handled by mutation
}
},
- [habit, formHelpers, originalEndDate, selectedGoalIds, updateHabit, onOpenChange],
+ [habit, formHelpers, originalEndDate, selectedGoalIds, reminderTimes, tags, updateHabit, onOpenChange],
)
return (
@@ -166,8 +187,15 @@ export function EditHabitModal({
selectedGoalIds={selectedGoalIds}
atGoalLimit={atGoalLimit}
onToggleGoal={toggleGoal}
+ reminderTimes={reminderTimes}
+ onReminderTimesChange={setReminderTimes}
/>
+ {/* Detail fetch error */}
+ {detailFetchError && (
+ {detailFetchError}
+ )}
+
{/* Validation error */}
{validationError && (
{validationError}
diff --git a/apps/web/components/habits/habit-calendar.tsx b/apps/web/components/habits/habit-calendar.tsx
index 66bcb5c58..7ba8a19c1 100644
--- a/apps/web/components/habits/habit-calendar.tsx
+++ b/apps/web/components/habits/habit-calendar.tsx
@@ -19,6 +19,7 @@ import { enUS, ptBR } from 'date-fns/locale'
import { ChevronLeft, ChevronRight, X } from 'lucide-react'
import { useTranslations, useLocale } from 'next-intl'
import { useHabitLogs } from '@/hooks/use-habits'
+import { useProfile } from '@/hooks/use-profile'
import type { HabitLog } from '@orbit/shared/types/calendar'
// ---------------------------------------------------------------------------
@@ -63,8 +64,8 @@ export function HabitCalendar({ habitId, logs: externalLogs }: HabitCalendarProp
[currentMonth, locale, dateFnsLocale],
)
- // TODO: weekStartsOn from profile when available
- const weekStartsOn = 1 as 0 | 1
+ const { profile } = useProfile()
+ const weekStartsOn = (profile?.weekStartDay ?? 1) as 0 | 1
const weekdays = useMemo(() => {
const sundayFirst = [
diff --git a/apps/web/components/habits/habit-card.tsx b/apps/web/components/habits/habit-card.tsx
index a4257406c..e0a96b456 100644
--- a/apps/web/components/habits/habit-card.tsx
+++ b/apps/web/components/habits/habit-card.tsx
@@ -2,6 +2,7 @@
import { useState, useEffect, useRef, useMemo, useCallback } from 'react'
import { createPortal } from 'react-dom'
+import { usePortalContainer } from '@/hooks/use-portal-container'
import {
ChevronRight,
Check,
@@ -41,6 +42,7 @@ interface HabitCardProps {
childrenDone?: number
childrenTotal?: number
searchQuery?: string
+ maxHabitDepth?: number
onLog?: () => void
onUnlog?: () => void
onSkip?: () => void
@@ -84,6 +86,7 @@ export function HabitCard({
childrenDone = 0,
childrenTotal = 0,
searchQuery = '',
+ maxHabitDepth = 5,
onLog,
onUnlog,
onSkip,
@@ -99,6 +102,7 @@ export function HabitCard({
onEnterSelectMode,
}: HabitCardProps) {
const t = useTranslations()
+ const portalContainer = usePortalContainer('habit-card')
const { displayTime } = useTimeFormat()
const isChild = depth > 0
@@ -729,7 +733,7 @@ export function HabitCard({
{/* Actions menu portal */}
{showActionsMenu &&
- typeof document !== 'undefined' &&
+ portalContainer &&
createPortal(
e.stopPropagation()}
>
- {showAddSubHabit && (
+ {showAddSubHabit && depth < maxHabitDepth - 1 && (
{
@@ -835,7 +839,7 @@ export function HabitCard({
)}
,
- document.body,
+ portalContainer,
)}
>
)
diff --git a/apps/web/components/habits/habit-checklist.tsx b/apps/web/components/habits/habit-checklist.tsx
index f64a8dfc6..c91d9ecf0 100644
--- a/apps/web/components/habits/habit-checklist.tsx
+++ b/apps/web/components/habits/habit-checklist.tsx
@@ -144,6 +144,9 @@ export function HabitChecklist({
)}
{/* Items list (editable) */}
+ {/* NOTE: Nuxt source uses VueDraggable for drag-to-reorder in editable mode.
+ The GripHorizontal icon below is currently decorative only.
+ TODO: Add drag-to-reorder via @dnd-kit/core or react-beautiful-dnd. */}
{editable ? (
{items.map((item, index) => (
diff --git a/apps/web/components/habits/habit-form-fields.tsx b/apps/web/components/habits/habit-form-fields.tsx
index e170c2687..55e00107e 100644
--- a/apps/web/components/habits/habit-form-fields.tsx
+++ b/apps/web/components/habits/habit-form-fields.tsx
@@ -1,6 +1,6 @@
'use client'
-import { useState, useCallback, useMemo, useId, type ReactNode } from 'react'
+import { useState, useMemo, useId, type ReactNode } from 'react'
import { X, Plus, Bell, Check, ShieldAlert, PenSquare } from 'lucide-react'
import { useTranslations } from 'next-intl'
import { useQuery } from '@tanstack/react-query'
@@ -14,6 +14,7 @@ import { AppDatePicker } from '@/components/ui/app-date-picker'
import { AppSelect } from '@/components/ui/app-select'
import type { TagSelectionState } from '@/hooks/use-tag-selection'
import type { HabitFormHelpers } from '@/hooks/use-habit-form'
+import { useHasProAccess } from '@/hooks/use-profile'
// ---------------------------------------------------------------------------
// Props
@@ -25,6 +26,9 @@ interface HabitFormFieldsProps {
selectedGoalIds: string[]
atGoalLimit: boolean
onToggleGoal: (goalId: string) => void
+ /** Controlled reminderTimes state from parent modal */
+ reminderTimes: number[]
+ onReminderTimesChange: (times: number[]) => void
children?: ReactNode
}
@@ -55,6 +59,8 @@ export function HabitFormFields({
selectedGoalIds,
atGoalLimit,
onToggleGoal,
+ reminderTimes,
+ onReminderTimesChange,
children,
}: HabitFormFieldsProps) {
const t = useTranslations()
@@ -62,6 +68,7 @@ export function HabitFormFields({
const scheduledReminderLabelId = useId()
const slipAlertLabelId = useId()
const slipAlertDescriptionId = useId()
+ const hasProAccess = useHasProAccess()
const {
form,
@@ -130,9 +137,6 @@ export function HabitFormFields({
{ value: 'days', label: t('habits.form.reminderUnitDays') },
], [t])
- // reminderTimes is not in the form schema, manage as local state
- const [reminderTimes, setReminderTimes] = useState
([0, 15])
-
const availablePresets = useMemo(
() => REMINDER_PRESETS.filter((p) => !reminderTimes.includes(p.value)),
[reminderTimes],
@@ -152,7 +156,7 @@ export function HabitFormFields({
function addPreset(value: number) {
if (!reminderTimes.includes(value)) {
- setReminderTimes((prev) => [...prev, value].sort((a, b) => b - a))
+ onReminderTimesChange([...reminderTimes, value].sort((a, b) => b - a))
}
setShowAddReminder(false)
}
@@ -164,7 +168,7 @@ export function HabitFormFields({
else if (customUnit === 'hours') multiplier = 60
const minutes = customValue * multiplier
if (!reminderTimes.includes(minutes)) {
- setReminderTimes((prev) => [...prev, minutes].sort((a, b) => b - a))
+ onReminderTimesChange([...reminderTimes, minutes].sort((a, b) => b - a))
}
setCustomValue(null)
setShowCustomInput(false)
@@ -172,7 +176,7 @@ export function HabitFormFields({
}
function removeReminder(value: number) {
- setReminderTimes((prev) => prev.filter((v) => v !== value))
+ onReminderTimesChange(reminderTimes.filter((v) => v !== value))
}
// Scheduled reminders
@@ -937,26 +941,44 @@ export function HabitFormFields({
{/* Slip alert toggle (only when bad habit) */}
{watchedIsBadHabit && (
-
-
-
-
-
{t('habits.form.slipAlert')}
+ {!hasProAccess ? (
+ /* Pro locked state */
+
+
+
+
+ {t('habits.form.slipAlert')}
+ {t('common.proBadge')}
+
+
{t('habits.form.slipAlertDescription')}
+
+
+
-
{t('habits.form.slipAlertDescription')}
-
setValue('slipAlertEnabled', !watchedSlipAlertEnabled, { shouldDirty: true })}
- >
-
-
-
+ ) : (
+ /* Pro unlocked state */
+
+
+
+
+ {t('habits.form.slipAlert')}
+
+
{t('habits.form.slipAlertDescription')}
+
+
setValue('slipAlertEnabled', !watchedSlipAlertEnabled, { shouldDirty: true })}
+ >
+
+
+
+ )}
)}
diff --git a/apps/web/components/habits/habit-list.tsx b/apps/web/components/habits/habit-list.tsx
index ab907ffac..836172b2f 100644
--- a/apps/web/components/habits/habit-list.tsx
+++ b/apps/web/components/habits/habit-list.tsx
@@ -1,6 +1,6 @@
'use client'
-import { useState, useMemo, useCallback, useRef, useEffect } from 'react'
+import { useState, useMemo, useCallback, forwardRef, useImperativeHandle } from 'react'
import {
isToday as isDateToday,
isTomorrow,
@@ -24,6 +24,7 @@ import { CreateHabitModal } from './create-habit-modal'
import { EditHabitModal } from './edit-habit-modal'
import { LogHabitModal } from './log-habit-modal'
import { ConfirmDialog } from '@/components/ui/confirm-dialog'
+import { AppOverlay } from '@/components/ui/app-overlay'
import {
useHabits,
useLogHabit,
@@ -31,16 +32,17 @@ import {
useDeleteHabit,
useDuplicateHabit,
useReorderHabits,
- type NormalizedHabitsData,
+ useMoveHabitParent,
} from '@/hooks/use-habits'
import { useHabitVisibility } from '@/hooks/use-habit-visibility'
import { useDrillNavigation } from '@/hooks/use-drill-navigation'
+import { useConfig } from '@/hooks/use-config'
import { useUIStore } from '@/stores/ui-store'
import { formatAPIDate } from '@orbit/shared/utils'
import type { NormalizedHabit, HabitsFilter } from '@orbit/shared/types/habit'
// ---------------------------------------------------------------------------
-// Props
+// Props & Handle
// ---------------------------------------------------------------------------
interface HabitListProps {
@@ -57,11 +59,32 @@ interface HabitListProps {
onSeeUpcoming?: () => void
}
+export interface HabitListHandle {
+ collapseAll: () => void
+ expandAll: () => void
+ allCollapsed: boolean
+ allLoadedIds: Set
+ markRecentlyCompleted: (habitId: string) => void
+ checkAndPromptParentLog: (childHabitId: string) => void
+}
+
+// ---------------------------------------------------------------------------
+// Move parent picker types
+// ---------------------------------------------------------------------------
+
+interface MoveParentOption {
+ id: string | null
+ label: string
+ depth: number
+ disabled: boolean
+ reason: string | null
+}
+
// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------
-export function HabitList({
+export const HabitList = forwardRef(function HabitList({
view = 'today',
selectedDate,
showCompleted = false,
@@ -73,7 +96,7 @@ export function HabitList({
onEnterSelectMode,
onCreate,
onSeeUpcoming,
-}: HabitListProps) {
+}, ref) {
const t = useTranslations()
const locale = useLocale()
const dateFnsLocale = locale === 'pt-BR' ? ptBR : enUS
@@ -84,7 +107,13 @@ export function HabitList({
const skipHabit = useSkipHabit()
const deleteHabitMut = useDeleteHabit()
const duplicateHabitMut = useDuplicateHabit()
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
const reorderHabitsMut = useReorderHabits()
+ const moveHabitParentMut = useMoveHabitParent()
+
+ // Config
+ const { config: appConfig } = useConfig()
+ const maxHabitDepth = appConfig.limits.maxHabitDepth
const data = habitsQuery.data
const habitsById = data?.habitsById ?? new Map()
@@ -124,6 +153,11 @@ export function HabitList({
recentlyCompletedIds,
})
+ // Wrapper for getVisibleChildren that passes the current view
+ function getVisibleChildren(parentId: string): NormalizedHabit[] {
+ return visibility.getVisibleChildren(parentId, view)
+ }
+
// Drill navigation
const drill = useDrillNavigation(habitsById, habitsQuery.dataUpdatedAt)
@@ -142,6 +176,26 @@ export function HabitList({
})
}, [])
+ // Collapse / expand all
+ const expandableIds = useMemo(() => {
+ const ids: string[] = []
+ for (const h of habitsById.values()) {
+ const childIds = childrenByParent.get(h.id)
+ if (childIds && childIds.length > 0) ids.push(h.id)
+ }
+ return ids
+ }, [habitsById, childrenByParent])
+
+ const allCollapsed = expandableIds.length > 0 && expandableIds.every((id) => collapsedIds.has(id))
+
+ const collapseAll = useCallback(() => {
+ setCollapsedIds(new Set(expandableIds))
+ }, [expandableIds])
+
+ const expandAll = useCallback(() => {
+ setCollapsedIds(new Set())
+ }, [])
+
// Filter habits
const habits = useMemo(() => {
if (view === 'general' || view === 'all') {
@@ -155,25 +209,91 @@ export function HabitList({
return topLevelHabits.filter((h) => visibility.hasVisibleContent(h))
}, [topLevelHabits, view, showCompleted, recentlyCompletedIds, visibility])
- // Children progress
- const getChildrenProgress = useCallback(
- (habitId: string) => {
- const children = getChildren(habitId)
+ // All loaded/selectable IDs including descendants
+ const allLoadedIds = useMemo(() => {
+ const ids = new Set()
+ function collect(habitId: string) {
+ ids.add(habitId)
+ const childIds = childrenByParent.get(habitId)
+ if (childIds) {
+ for (const cid of childIds) collect(cid)
+ }
+ }
+ for (const h of habits) {
+ collect(h.id)
+ }
+ return ids
+ }, [habits, childrenByParent])
+
+ // Children progress -- matches Nuxt computeChildProgress logic
+ const isListView = view === 'all' || view === 'general'
+
+ const childrenProgressMap = useMemo(() => {
+ const map = new Map()
+
+ function computeChildProgress(
+ child: NormalizedHabit,
+ computeFn: (id: string) => { done: number; total: number },
+ ): { done: number; total: number } {
let done = 0
let total = 0
- for (const child of children) {
+
+ if (isListView || child.isGeneral) {
+ total++
+ if (child.isCompleted) done++
+ } else if (!visibility.isRelevantToday(child) && !child.isLoggedInRange) {
+ // Not relevant today and not logged -- only count nested
+ const nested = computeFn(child.id)
+ return nested
+ } else if (visibility.isDueOnSelectedDate(child) || child.isLoggedInRange) {
total++
if (child.isCompleted || child.isLoggedInRange) done++
- // Recurse
- const nested = getChildren(child.id)
- for (const nc of nested) {
- total++
- if (nc.isCompleted || nc.isLoggedInRange) done++
- }
}
+
+ const nested = computeFn(child.id)
+ done += nested.done
+ total += nested.total
return { done, total }
+ }
+
+ function compute(habitId: string): { done: number; total: number } {
+ const cached = map.get(habitId)
+ if (cached) return cached
+
+ const children = getChildren(habitId)
+ if (children.length === 0) {
+ const result = { done: 0, total: 0 }
+ map.set(habitId, result)
+ return result
+ }
+
+ let done = 0
+ let total = 0
+ for (const child of children) {
+ const progress = computeChildProgress(child, compute)
+ done += progress.done
+ total += progress.total
+ }
+
+ const result = { done, total }
+ map.set(habitId, result)
+ return result
+ }
+
+ for (const habit of habitsById.values()) {
+ if (!map.has(habit.id)) {
+ compute(habit.id)
+ }
+ }
+
+ return map
+ }, [habitsById, getChildren, isListView, visibility])
+
+ const getChildrenProgress = useCallback(
+ (habitId: string) => {
+ return childrenProgressMap.get(habitId) ?? { done: 0, total: 0 }
},
- [getChildren],
+ [childrenProgressMap],
)
// Date groups for "all" view
@@ -267,16 +387,16 @@ export function HabitList({
const items: DragItem[] = []
function addHabitTree(habit: NormalizedHabit, depth: number) {
- const visibleChildren = visibility.getVisibleChildren(habit.id, view)
+ const visChildren = visibility.getVisibleChildren(habit.id, view)
items.push({
id: habit.id,
habit,
depth,
- hasChildren: visibleChildren.length > 0,
+ hasChildren: visChildren.length > 0,
hasSubHabits: habit.hasSubHabits,
})
if (!collapsedIds.has(habit.id)) {
- for (const child of visibleChildren) {
+ for (const child of visChildren) {
addHabitTree(child, depth + 1)
}
}
@@ -308,7 +428,192 @@ export function HabitList({
const [showForceLogConfirm, setShowForceLogConfirm] = useState(false)
const [forceLogHabitId, setForceLogHabitId] = useState(null)
+ // Auto-log parent state
+ const [showAutoLogParent, setShowAutoLogParent] = useState(false)
+ const [autoLogParentId, setAutoLogParentId] = useState(null)
+ const autoLogParentHabit = autoLogParentId ? habitsById.get(autoLogParentId) ?? null : null
+
+ // Move parent picker state
+ const [showMoveParentOverlay, setShowMoveParentOverlay] = useState(false)
+ const [movingHabitId, setMovingHabitId] = useState(null)
+ const [selectedMoveParentId, setSelectedMoveParentId] = useState(null)
+ const [isMovingParent, setIsMovingParent] = useState(false)
+ const movingHabit = movingHabitId ? habitsById.get(movingHabitId) ?? null : null
+
+ // -------------------------------------------------------------------------
+ // Auto-log parent when all sub-habits complete
+ // -------------------------------------------------------------------------
+
+ function checkAndPromptParentLog(childHabitId: string) {
+ const child = habitsById.get(childHabitId)
+ if (!child?.parentId) return
+ const parent = habitsById.get(child.parentId)
+ if (!parent || parent.isCompleted) return
+ const { done, total } = getChildrenProgress(parent.id)
+ if (total > 0 && done >= total) {
+ setAutoLogParentId(parent.id)
+ setShowAutoLogParent(true)
+ }
+ }
+
+ async function confirmAutoLogParent() {
+ const parentId = autoLogParentId
+ if (!parentId) return
+ setShowAutoLogParent(false)
+ setAutoLogParentId(null)
+ markRecentlyCompleted(parentId)
+ try {
+ await logHabit.mutateAsync({ habitId: parentId })
+ // After logging parent, check if grandparent also needs logging
+ checkAndPromptParentLog(parentId)
+ } catch {
+ // Error handled by mutation
+ }
+ }
+
+ // -------------------------------------------------------------------------
+ // Move parent picker helpers
+ // -------------------------------------------------------------------------
+
+ function getHabitDepth(habitId: string): number {
+ let depth = 0
+ let current = habitsById.get(habitId)
+ while (current?.parentId) {
+ depth++
+ current = habitsById.get(current.parentId)
+ }
+ return depth
+ }
+
+ function getSubtreeMaxDepth(habitId: string, baseDepth: number): number {
+ let max = baseDepth
+ const children = getChildren(habitId)
+ for (const child of children) {
+ const childMax = getSubtreeMaxDepth(child.id, baseDepth + 1)
+ if (childMax > max) max = childMax
+ }
+ return max
+ }
+
+ function isDescendant(candidateId: string, ancestorId: string): boolean {
+ let current = habitsById.get(candidateId)
+ while (current?.parentId) {
+ if (current.parentId === ancestorId) return true
+ current = habitsById.get(current.parentId)
+ }
+ return false
+ }
+
+ function validateMoveTarget(
+ targetParentId: string | null,
+ draggedId: string,
+ ): { valid: boolean; reason: string | null } {
+ if (targetParentId === draggedId) {
+ return { valid: false, reason: t('habits.moveParent.invalidSelf') }
+ }
+
+ if (targetParentId && isDescendant(targetParentId, draggedId)) {
+ return { valid: false, reason: t('habits.moveParent.invalidDescendant') }
+ }
+
+ const newParentDepth = targetParentId ? getHabitDepth(targetParentId) : -1
+ const subtreeMax = getSubtreeMaxDepth(draggedId, newParentDepth + 1)
+ if (subtreeMax >= maxHabitDepth) {
+ return {
+ valid: false,
+ reason: t('habits.moveParent.invalidDepth', { max: maxHabitDepth }),
+ }
+ }
+
+ return { valid: true, reason: null }
+ }
+
+ const moveParentOptions = useMemo(() => {
+ if (!movingHabitId) return []
+
+ const options: MoveParentOption[] = []
+ const rootValidation = validateMoveTarget(null, movingHabitId)
+ options.push({
+ id: null,
+ label: t('habits.moveParent.toRoot'),
+ depth: 0,
+ disabled: !rootValidation.valid,
+ reason: rootValidation.reason,
+ })
+
+ function addOption(habit: NormalizedHabit, depth: number) {
+ const validation = validateMoveTarget(habit.id, movingHabitId!)
+ options.push({
+ id: habit.id,
+ label: habit.title,
+ depth,
+ disabled: !validation.valid,
+ reason: validation.reason,
+ })
+
+ const ch = getChildren(habit.id)
+ for (const child of ch) {
+ addOption(child, depth + 1)
+ }
+ }
+
+ for (const topLevel of topLevelHabits) {
+ addOption(topLevel, 0)
+ }
+
+ return options
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [movingHabitId, topLevelHabits, habitsById, t, maxHabitDepth])
+
+ const selectedMoveOption = moveParentOptions.find(
+ (option) => option.id === selectedMoveParentId,
+ ) ?? null
+
+ const canSubmitMoveParent =
+ movingHabit !== null &&
+ !isMovingParent &&
+ selectedMoveParentId !== movingHabit.parentId &&
+ selectedMoveOption !== null &&
+ !selectedMoveOption.disabled
+
+ function openMoveParentPicker(habitId: string) {
+ const habit = habitsById.get(habitId)
+ if (!habit) return
+ setMovingHabitId(habitId)
+ setSelectedMoveParentId(habit.parentId)
+ setShowMoveParentOverlay(true)
+ }
+
+ function closeMoveParentPicker() {
+ if (isMovingParent) return
+ setShowMoveParentOverlay(false)
+ setMovingHabitId(null)
+ setSelectedMoveParentId(null)
+ }
+
+ async function confirmMoveParent() {
+ if (!movingHabitId || !canSubmitMoveParent) return
+
+ setIsMovingParent(true)
+ try {
+ await moveHabitParentMut.mutateAsync({
+ habitId: movingHabitId,
+ data: { parentId: selectedMoveParentId },
+ })
+ setShowMoveParentOverlay(false)
+ setMovingHabitId(null)
+ setSelectedMoveParentId(null)
+ } catch {
+ // Error handled by mutation
+ } finally {
+ setIsMovingParent(false)
+ }
+ }
+
+ // -------------------------------------------------------------------------
// Actions
+ // -------------------------------------------------------------------------
+
function openDetail(habit: NormalizedHabit) {
setSelectedHabit(habit)
setShowDetailDrawer(true)
@@ -351,9 +656,11 @@ export function HabitList({
async function confirmSkip() {
if (!habitToSkip) return
+ const skippedId = habitToSkip
try {
- await skipHabit.mutateAsync({ habitId: habitToSkip })
- markRecentlyCompleted(habitToSkip)
+ await skipHabit.mutateAsync({ habitId: skippedId })
+ markRecentlyCompleted(skippedId)
+ checkAndPromptParentLog(skippedId)
} catch {
// Error handled by mutation
} finally {
@@ -364,6 +671,7 @@ export function HabitList({
function handleLogged(habitId: string) {
markRecentlyCompleted(habitId)
+ checkAndPromptParentLog(habitId)
}
async function confirmForceLog() {
@@ -400,6 +708,31 @@ export function HabitList({
return habit ? !habit.frequencyUnit : false
}, [habitToSkip, habitsById])
+ // Skip confirm message -- 3 branches: postpone, flexible, regular
+ const skipConfirmMessage = useMemo(() => {
+ if (isPostponeAction) return t('habits.postponeConfirmMessage')
+ if (habitToSkip) {
+ const habit = habitsById.get(habitToSkip)
+ if (habit?.flexibleTarget != null) {
+ return t('habits.skipConfirmMessageFlexible')
+ }
+ }
+ return t('habits.skipConfirmMessage')
+ }, [isPostponeAction, habitToSkip, habitsById, t])
+
+ // -------------------------------------------------------------------------
+ // Expose imperative handle
+ // -------------------------------------------------------------------------
+
+ useImperativeHandle(ref, () => ({
+ collapseAll,
+ expandAll,
+ get allCollapsed() { return allCollapsed },
+ get allLoadedIds() { return allLoadedIds },
+ markRecentlyCompleted,
+ checkAndPromptParentLog,
+ }))
+
// Render a single HabitCard with all handlers
function renderHabitCard(
habit: NormalizedHabit,
@@ -424,6 +757,7 @@ export function HabitList({
childrenTotal={progress.total}
isSelectMode={isSelectMode}
isSelected={selectedHabitIds?.has(habit.id) ?? false}
+ maxHabitDepth={maxHabitDepth}
onLog={() => promptLog(habit)}
onUnlog={() => logHabit.mutate({ habitId: habit.id })}
onForceLogParent={() => {
@@ -432,9 +766,7 @@ export function HabitList({
}}
onSkip={() => promptSkip(habit.id)}
onDuplicate={() => duplicateHabitMut.mutate(habit.id)}
- onMoveParent={() => {
- // TODO: Move parent picker
- }}
+ onMoveParent={() => openMoveParentPicker(habit.id)}
onDelete={() => promptDelete(habit.id)}
onDetail={() => openDetail(habit)}
onDrillInto={() => drill.drillInto(habit.id)}
@@ -591,7 +923,7 @@ export function HabitList({
)}
) : view === 'all' ? (
- /* ALL VIEW: date-grouped list */
+ /* ALL VIEW: date-grouped list with nested children (up to depth 2) */
<>
{dateGroups.map((group) => (
@@ -610,14 +942,38 @@ export function HabitList({
/>
- {group.habits.map((habit) =>
- renderHabitCard(
- habit,
- 0,
- getChildren(habit.id).length > 0,
- habit.hasSubHabits,
- ),
- )}
+ {group.habits.map((habit) => (
+
+ {renderHabitCard(
+ habit,
+ 0,
+ getChildren(habit.id).length > 0,
+ habit.hasSubHabits,
+ )}
+ {/* Children (depth 1) when expanded */}
+ {!collapsedIds.has(habit.id) && getVisibleChildren(habit.id).map((child) => (
+
+ {renderHabitCard(
+ child,
+ 1,
+ getVisibleChildren(child.id).length > 0,
+ habitsById.get(child.id)?.hasSubHabits ?? false,
+ )}
+ {/* Grandchildren (depth 2) when child expanded */}
+ {!collapsedIds.has(child.id) && getVisibleChildren(child.id).map((grandchild) => (
+
+ {renderHabitCard(
+ grandchild,
+ 2,
+ getVisibleChildren(grandchild.id).length > 0,
+ habitsById.get(grandchild.id)?.hasSubHabits ?? false,
+ )}
+
+ ))}
+
+ ))}
+
+ ))}
))}
@@ -690,11 +1046,7 @@ export function HabitList({
? 'habits.postponeConfirmTitle'
: 'habits.skipConfirmTitle',
)}
- description={t(
- isPostponeAction
- ? 'habits.postponeConfirmMessage'
- : 'habits.skipConfirmMessage',
- )}
+ description={skipConfirmMessage}
confirmLabel={t(
isPostponeAction
? 'habits.postponeConfirmButton'
@@ -714,7 +1066,7 @@ export function HabitList({
onOpenChange={setShowForceLogConfirm}
title={t('habits.forceLogTitle')}
description={t('habits.forceLogMessage')}
- confirmLabel={t('habits.logHabit')}
+ confirmLabel={t('habits.forceLogConfirm')}
cancelLabel={t('common.cancel')}
onConfirm={confirmForceLog}
onCancel={() => {
@@ -723,6 +1075,87 @@ export function HabitList({
}}
variant="warning"
/>
+
+ {/* Auto-log parent when all sub-habits complete */}
+ {
+ setAutoLogParentId(null)
+ setShowAutoLogParent(false)
+ }}
+ variant="success"
+ />
+
+ {/* Move parent picker */}
+ {
+ if (!open) closeMoveParentPicker()
+ }}
+ dismissible={!isMovingParent}
+ title={t('habits.moveParent.title')}
+ description={movingHabit ? t('habits.moveParent.description', { name: movingHabit.title }) : undefined}
+ footer={
+
+
+ {t('common.cancel')}
+
+
+ {isMovingParent ? t('habits.moveParent.moving') : t('habits.moveParent.confirm')}
+
+
+ }
+ >
+ {moveParentOptions.length > 0 ? (
+
+ {moveParentOptions.map((option) => (
+
setSelectedMoveParentId(option.id)}
+ >
+
+ {option.label}
+ {movingHabit && option.id === movingHabit.parentId && (
+
+ {t('habits.moveParent.currentParent')}
+
+ )}
+
+ {option.reason && (
+
+ {option.reason}
+
+ )}
+
+ ))}
+
+ ) : (
+
+ {t('habits.moveParent.noOptions')}
+
+ )}
+
)
-}
+})
diff --git a/apps/web/components/navigation/bottom-nav.tsx b/apps/web/components/navigation/bottom-nav.tsx
index 7e8322582..e6d2dd0c6 100644
--- a/apps/web/components/navigation/bottom-nav.tsx
+++ b/apps/web/components/navigation/bottom-nav.tsx
@@ -4,6 +4,8 @@ import Link from 'next/link'
import { usePathname } from 'next/navigation'
import { Home, MessageCircle, CalendarDays, User, Plus } from 'lucide-react'
import { useTranslations } from 'next-intl'
+import { useUIStore } from '@/stores/ui-store'
+import { formatAPIDate } from '@orbit/shared/utils'
import type { LucideIcon } from 'lucide-react'
interface NavItem {
@@ -19,6 +21,8 @@ interface BottomNavProps {
export function BottomNav({ onCreate }: BottomNavProps) {
const t = useTranslations()
const pathname = usePathname()
+ const setSelectedDate = useUIStore((s) => s.setSelectedDate)
+ const setActiveView = useUIStore((s) => s.setActiveView)
const navItems: NavItem[] = [
{ name: t('nav.habits'), path: '/', icon: Home },
@@ -33,13 +37,29 @@ export function BottomNav({ onCreate }: BottomNavProps) {
return pathname === path || pathname === path + '/'
}
+ function handleNavClick(item: NavItem, event: React.MouseEvent) {
+ if (item.path === '/') {
+ // Reset date to today and view to 'today' when clicking Home
+ setSelectedDate(formatAPIDate(new Date()))
+ setActiveView('today')
+ if (isActive(item.path)) {
+ event.preventDefault()
+ }
+ }
+ }
+
return (
{/* First two nav items */}
{navItems.slice(0, 2).map((item) => (
-
+ handleNavClick(item, e)}
+ />
))}
{/* Central FAB button */}
@@ -55,7 +75,12 @@ export function BottomNav({ onCreate }: BottomNavProps) {
{/* Last two nav items */}
{navItems.slice(2).map((item) => (
-
+ handleNavClick(item, e)}
+ />
))}
@@ -63,7 +88,15 @@ export function BottomNav({ onCreate }: BottomNavProps) {
)
}
-function NavLink({ item, active }: { item: NavItem; active: boolean }) {
+function NavLink({
+ item,
+ active,
+ onClick,
+}: {
+ item: NavItem
+ active: boolean
+ onClick?: (e: React.MouseEvent) => void
+}) {
const Icon = item.icon
return (
@@ -72,6 +105,7 @@ function NavLink({ item, active }: { item: NavItem; active: boolean }) {
className={`relative flex flex-col items-center gap-1 py-2 min-w-[48px] transition-all duration-150 ${
active ? 'text-primary' : 'text-text-secondary hover:text-text-primary'
}`}
+ onClick={onClick}
>
{
if (!profile?.trialEndsAt) return ''
- return format(parseISO(profile.trialEndsAt), locale === 'pt-BR' ? 'dd MMM yyyy' : 'MMM d, yyyy', { locale: dateFnsLocale })
- }, [profile?.trialEndsAt, locale, dateFnsLocale])
+ return format(parseISO(profile.trialEndsAt), 'PPP', { locale: dateFnsLocale })
+ }, [profile?.trialEndsAt, dateFnsLocale])
const recapItems = useMemo(() => {
const items = [
diff --git a/apps/web/components/onboarding/onboarding-create-goal.tsx b/apps/web/components/onboarding/onboarding-create-goal.tsx
index 92b34601f..68060d8e4 100644
--- a/apps/web/components/onboarding/onboarding-create-goal.tsx
+++ b/apps/web/components/onboarding/onboarding-create-goal.tsx
@@ -34,7 +34,7 @@ export function OnboardingCreateGoal({ onCreated, onSkip }: OnboardingCreateGoal
{ key: 'run', title: t('onboarding.flow.createGoal.suggestions.run'), target: 100, unit: 'km' },
{ key: 'books', title: t('onboarding.flow.createGoal.suggestions.books'), target: 12, unit: t('onboarding.flow.createGoal.suggestions.booksUnit') },
{ key: 'save', title: t('onboarding.flow.createGoal.suggestions.save'), target: 5000, unit: '$' },
- ], [])
+ ], [t])
function selectSuggestion(suggestion: GoalSuggestion) {
setDescription(suggestion.title)
diff --git a/apps/web/components/onboarding/onboarding-flow.tsx b/apps/web/components/onboarding/onboarding-flow.tsx
index bd21d0c2b..269c1f434 100644
--- a/apps/web/components/onboarding/onboarding-flow.tsx
+++ b/apps/web/components/onboarding/onboarding-flow.tsx
@@ -4,6 +4,10 @@ import { useState, useMemo, useCallback } from 'react'
import { createPortal } from 'react-dom'
import { useRouter } from 'next/navigation'
import { useTranslations } from 'next-intl'
+import { usePortalContainer } from '@/hooks/use-portal-container'
+import { useQueryClient } from '@tanstack/react-query'
+import { profileKeys } from '@orbit/shared/query'
+import type { Profile } from '@orbit/shared/types/profile'
import { useHasProAccess } from '@/hooks/use-profile'
import { completeOnboarding } from '@/app/actions/profile'
import { OnboardingWelcome } from './onboarding-welcome'
@@ -17,7 +21,9 @@ const TOTAL_STEPS = 6
export function OnboardingFlow() {
const t = useTranslations()
+ const portalContainer = usePortalContainer('onboarding-flow')
const router = useRouter()
+ const queryClient = useQueryClient()
const hasProAccess = useHasProAccess()
const [currentStep, setCurrentStep] = useState(0)
@@ -91,7 +97,10 @@ export function OnboardingFlow() {
await completeOnboarding()
} catch {
// Intentionally ignoring onboarding completion errors -- user should proceed
- // regardless. Next session load will re-show onboarding if needed.
+ // regardless. Set flag locally so user is never stuck re-seeing onboarding.
+ queryClient.setQueryData(profileKeys.detail(), (old) =>
+ old ? { ...old, hasCompletedOnboarding: true } : old,
+ )
}
router.push('/')
}
@@ -219,5 +228,5 @@ export function OnboardingFlow() {
)
- return createPortal(overlay, document.body)
+ return portalContainer ? createPortal(overlay, portalContainer) : null
}
diff --git a/apps/web/components/onboarding/onboarding-welcome.tsx b/apps/web/components/onboarding/onboarding-welcome.tsx
index 73157dc63..946aeed55 100644
--- a/apps/web/components/onboarding/onboarding-welcome.tsx
+++ b/apps/web/components/onboarding/onboarding-welcome.tsx
@@ -1,7 +1,9 @@
'use client'
-import { useMutation } from '@tanstack/react-query'
+import { useMutation, useQueryClient } from '@tanstack/react-query'
import { useTranslations } from 'next-intl'
+import { profileKeys } from '@orbit/shared/query'
+import type { Profile } from '@orbit/shared/types/profile'
import { colorSchemeOptions, type ColorScheme } from '@orbit/shared/theme'
import { useProfile, useHasProAccess } from '@/hooks/use-profile'
import { useColorScheme } from '@/hooks/use-color-scheme'
@@ -9,12 +11,29 @@ import { updateWeekStartDay, updateColorScheme as updateColorSchemeAction } from
export function OnboardingWelcome() {
const t = useTranslations()
+ const queryClient = useQueryClient()
const { profile } = useProfile()
const hasProAccess = useHasProAccess()
const { currentScheme, applyScheme } = useColorScheme()
const weekStartDayMutation = useMutation({
mutationFn: (day: number) => updateWeekStartDay({ weekStartDay: day }),
+ onMutate: async (newDay) => {
+ await queryClient.cancelQueries({ queryKey: profileKeys.all })
+ const prev = queryClient.getQueryData(profileKeys.detail())
+ queryClient.setQueryData(profileKeys.detail(), (old) =>
+ old ? { ...old, weekStartDay: newDay } : old,
+ )
+ return { prev }
+ },
+ onError: (_err, _newDay, context) => {
+ if (context?.prev) {
+ queryClient.setQueryData(profileKeys.detail(), context.prev)
+ }
+ },
+ onSettled: () => {
+ queryClient.invalidateQueries({ queryKey: profileKeys.all })
+ },
})
const colorSchemeMutation = useMutation({
diff --git a/apps/web/components/ui/app-overlay.tsx b/apps/web/components/ui/app-overlay.tsx
index 513f7b520..2651bae4f 100644
--- a/apps/web/components/ui/app-overlay.tsx
+++ b/apps/web/components/ui/app-overlay.tsx
@@ -4,6 +4,39 @@ import { useState, useEffect, useRef, useCallback, useId, type ReactNode } from
import { createPortal } from 'react-dom'
import { X, Expand } from 'lucide-react'
import { useTranslations } from 'next-intl'
+import DOMPurify from 'dompurify'
+import { usePortalContainer } from '@/hooks/use-portal-container'
+
+// ---------------------------------------------------------------------------
+// linkifyText -- converts URLs in plain text to clickable tags
+// ---------------------------------------------------------------------------
+
+function escapeHtml(text: string): string {
+ return text
+ .replaceAll('&', '&')
+ .replaceAll('<', '<')
+ .replaceAll('>', '>')
+ .replaceAll('"', '"')
+}
+
+function linkifyText(text: string): string {
+ const urlRegex = /(https?:\/\/[^\s<]+)/g
+ const parts = text.split(urlRegex)
+
+ const result = parts.map((part, i) => {
+ const escaped = escapeHtml(part)
+ if (i % 2 === 1) {
+ return ` ${escaped} `
+ }
+ return escaped
+ }).join('')
+
+ return DOMPurify.sanitize(result, { ALLOWED_TAGS: ['a'], ALLOWED_ATTR: ['href', 'target', 'rel', 'class'] })
+}
+
+// ---------------------------------------------------------------------------
+// AppOverlay
+// ---------------------------------------------------------------------------
interface AppOverlayProps {
open: boolean
@@ -31,17 +64,35 @@ export function AppOverlay({
onExpandDescription,
}: AppOverlayProps) {
const t = useTranslations()
+ const portalContainer = usePortalContainer('app-overlay')
const titleId = useId()
const panelRef = useRef(null)
const pointerDownOnBackdrop = useRef(false)
const savedScrollY = useRef(0)
const previouslyFocusedElement = useRef(null)
const [mounted, setMounted] = useState(false)
+ const [animState, setAnimState] = useState<'hidden' | 'entering' | 'visible' | 'leaving'>('hidden')
useEffect(() => {
setMounted(true)
}, [])
+ // Transition state machine
+ useEffect(() => {
+ if (open && mounted) {
+ setAnimState('entering')
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ setAnimState('visible')
+ })
+ })
+ } else if (!open && animState === 'visible') {
+ setAnimState('leaving')
+ const timer = setTimeout(() => setAnimState('hidden'), 200)
+ return () => clearTimeout(timer)
+ }
+ }, [open, mounted]) // eslint-disable-line react-hooks/exhaustive-deps
+
const lockBodyScroll = useCallback(() => {
savedScrollY.current = window.scrollY
document.body.style.position = 'fixed'
@@ -139,9 +190,20 @@ export function AppOverlay({
pointerDownOnBackdrop.current = false
}
- if (!open || !mounted) return null
+ if (animState === 'hidden' || !mounted) return null
const hasTitle = !!(title || titleContent)
+ const linkedDescription = description ? linkifyText(description) : ''
+
+ // Transition classes
+ const isEntering = animState === 'entering'
+ const isLeaving = animState === 'leaving'
+ const backdropClass = isEntering || isLeaving ? 'opacity-0' : 'opacity-100'
+ const panelClass = isEntering
+ ? 'translate-y-full sm:translate-y-0 sm:scale-95 opacity-0'
+ : isLeaving
+ ? 'opacity-0'
+ : 'translate-y-0 sm:scale-100 opacity-100'
const overlay = (
{/* Backdrop */}
-
+
{/* Panel - bottom sheet on mobile, centered modal on desktop */}
e.stopPropagation()}
>
{/* Drag handle (mobile) */}
@@ -180,7 +244,7 @@ export function AppOverlay({
{expandable && (
)
- return createPortal(overlay, document.body)
+ return portalContainer ? createPortal(overlay, portalContainer) : null
}
diff --git a/apps/web/components/ui/fresh-start-animation.tsx b/apps/web/components/ui/fresh-start-animation.tsx
index 861609114..5a6f9aa69 100644
--- a/apps/web/components/ui/fresh-start-animation.tsx
+++ b/apps/web/components/ui/fresh-start-animation.tsx
@@ -4,6 +4,7 @@ import { useState, useEffect } from 'react'
import { createPortal } from 'react-dom'
import { RefreshCw } from 'lucide-react'
import { useTranslations } from 'next-intl'
+import { usePortalContainer } from '@/hooks/use-portal-container'
interface FreshStartAnimationProps {
onComplete: () => void
@@ -11,6 +12,7 @@ interface FreshStartAnimationProps {
export function FreshStartAnimation({ onComplete }: FreshStartAnimationProps) {
const t = useTranslations()
+ const portalContainer = usePortalContainer('fresh-start')
const [isVisible, setIsVisible] = useState(false)
const [isFadingOut, setIsFadingOut] = useState(false)
const [mounted, setMounted] = useState(false)
@@ -42,10 +44,7 @@ export function FreshStartAnimation({ onComplete }: FreshStartAnimationProps) {
const overlay = (
{/* Backdrop */}
@@ -54,28 +53,16 @@ export function FreshStartAnimation({ onComplete }: FreshStartAnimationProps) {
{/* Center content */}
{/* Radiating rings */}
- {isVisible && (
- <>
-
-
- >
- )}
+
+
{/* Center orb */}
-
+
{/* Text */}
-
+
{t('profile.freshStart.successTitle')}
@@ -87,5 +74,5 @@ export function FreshStartAnimation({ onComplete }: FreshStartAnimationProps) {
)
- return createPortal(overlay, document.body)
+ return portalContainer ? createPortal(overlay, portalContainer) : null
}
diff --git a/apps/web/components/ui/highlight-text.tsx b/apps/web/components/ui/highlight-text.tsx
index 2442b39ae..312acb544 100644
--- a/apps/web/components/ui/highlight-text.tsx
+++ b/apps/web/components/ui/highlight-text.tsx
@@ -8,21 +8,36 @@ interface Segment {
isMatch: boolean
}
+/**
+ * indexOf-based highlight matching (port of Nuxt utils/highlight.ts).
+ * Avoids the stateful `lastIndex` bug from using regex.test() with the `g` flag.
+ */
function highlightText(text: string, query: string): Segment[] {
- if (!query || !query.trim()) {
- return [{ text, isMatch: false }]
+ if (!query || !text) return [{ text: text || '', isMatch: false }]
+
+ const segments: Segment[] = []
+ const lowerText = text.toLowerCase()
+ const lowerQuery = query.toLowerCase().trim()
+
+ if (!lowerQuery) return [{ text, isMatch: false }]
+
+ let pos = 0
+ let idx = lowerText.indexOf(lowerQuery, pos)
+
+ while (idx !== -1) {
+ if (idx > pos) {
+ segments.push({ text: text.slice(pos, idx), isMatch: false })
+ }
+ segments.push({ text: text.slice(idx, idx + lowerQuery.length), isMatch: true })
+ pos = idx + lowerQuery.length
+ idx = lowerText.indexOf(lowerQuery, pos)
}
- const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
- const regex = new RegExp(`(${escaped})`, 'gi')
- const parts = text.split(regex)
+ if (pos < text.length) {
+ segments.push({ text: text.slice(pos), isMatch: false })
+ }
- return parts
- .filter(Boolean)
- .map((part) => ({
- text: part,
- isMatch: regex.test(part) || part.toLowerCase() === query.toLowerCase(),
- }))
+ return segments.length > 0 ? segments : [{ text, isMatch: false }]
}
export function HighlightText({ text, query }: HighlightTextProps) {
diff --git a/apps/web/components/ui/pro-badge.tsx b/apps/web/components/ui/pro-badge.tsx
index 5504830b8..ab823136e 100644
--- a/apps/web/components/ui/pro-badge.tsx
+++ b/apps/web/components/ui/pro-badge.tsx
@@ -1,9 +1,23 @@
+'use client'
+
+import { useTranslations } from 'next-intl'
+import { useProfile } from '@/hooks/use-profile'
import './pro-badge.css'
-export function ProBadge({ label = 'PRO' }: { label?: string }) {
+export function ProBadge() {
+ const t = useTranslations()
+ const { profile } = useProfile()
+
+ const isTrialActive = profile?.isTrialActive ?? false
+ const hasProAccess = profile?.hasProAccess ?? false
+
+ if (!isTrialActive && !hasProAccess) return null
+
+ const badgeLabel = isTrialActive ? t('trial.proBadge') : t('common.proBadge')
+
return (
- {label}
+ {badgeLabel}
)
}
diff --git a/apps/web/components/ui/push-prompt.tsx b/apps/web/components/ui/push-prompt.tsx
index 2809937ab..3553bea3c 100644
--- a/apps/web/components/ui/push-prompt.tsx
+++ b/apps/web/components/ui/push-prompt.tsx
@@ -16,21 +16,45 @@ function setCookie(name: string, value: string, maxAge: number) {
document.cookie = `${name}=${encodeURIComponent(value)}; path=/; max-age=${maxAge}; SameSite=Strict; Secure`
}
+function urlBase64ToUint8Array(base64String: string): Uint8Array {
+ const padding = '='.repeat((4 - base64String.length % 4) % 4)
+ const base64 = (base64String + padding).replaceAll('-', '+').replaceAll('_', '/')
+ const rawData = atob(base64)
+ const outputArray = new Uint8Array(rawData.length)
+ for (let i = 0; i < rawData.length; ++i) {
+ outputArray[i] = rawData.codePointAt(i) ?? 0
+ }
+ return outputArray
+}
+
export function PushPrompt() {
const t = useTranslations()
const [show, setShow] = useState(false)
const [visible, setVisible] = useState(false)
useEffect(() => {
- // Check conditions
- if (!('Notification' in window) || !('serviceWorker' in navigator)) return
- if (Notification.permission === 'granted') return
+ if (typeof globalThis === 'undefined' || !('serviceWorker' in navigator) || !('PushManager' in globalThis)) return
if (Notification.permission === 'denied') return
if (getCookie(STORAGE_KEY) === '1') return
- setShow(true)
- // Trigger enter animation on next frame
- requestAnimationFrame(() => setVisible(true))
+ // Check if already subscribed
+ navigator.serviceWorker.ready
+ .then((reg) => reg.pushManager.getSubscription())
+ .then((sub) => {
+ if (sub && Notification.permission === 'granted') {
+ // Already subscribed, don't show prompt
+ return
+ }
+ setShow(true)
+ requestAnimationFrame(() => setVisible(true))
+ })
+ .catch(() => {
+ // If we can't check, show the prompt anyway (unless already granted)
+ if (Notification.permission !== 'granted') {
+ setShow(true)
+ requestAnimationFrame(() => setVisible(true))
+ }
+ })
}, [])
const dismiss = useCallback(() => {
@@ -41,9 +65,45 @@ export function PushPrompt() {
const handleEnable = useCallback(async () => {
try {
- await Notification.requestPermission()
+ // Skip the permission prompt if already granted
+ const permission = Notification.permission === 'granted'
+ ? 'granted'
+ : await Notification.requestPermission()
+
+ if (permission !== 'granted') {
+ dismiss()
+ return
+ }
+
+ const registration = await navigator.serviceWorker.ready
+
+ // Unsubscribe any existing subscription first
+ const existing = await registration.pushManager.getSubscription()
+ if (existing) await existing.unsubscribe()
+
+ const vapidKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY
+ if (!vapidKey) {
+ dismiss()
+ return
+ }
+
+ const subscription = await registration.pushManager.subscribe({
+ userVisibleOnly: true,
+ applicationServerKey: urlBase64ToUint8Array(vapidKey).buffer as ArrayBuffer,
+ })
+
+ const keys = subscription.toJSON()
+ await fetch('/api/notifications/subscribe', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ endpoint: subscription.endpoint,
+ p256dh: keys.keys?.p256dh,
+ auth: keys.keys?.auth,
+ }),
+ })
} catch {
- // Permission request failed
+ // Subscribe failed silently
}
dismiss()
}, [dismiss])
diff --git a/apps/web/hooks/use-color-scheme.ts b/apps/web/hooks/use-color-scheme.ts
index 539523223..f06e18ea5 100644
--- a/apps/web/hooks/use-color-scheme.ts
+++ b/apps/web/hooks/use-color-scheme.ts
@@ -3,6 +3,7 @@
import { useState, useEffect, useCallback } from 'react'
import { schemes, type ColorScheme, type ColorSchemeDefinition } from '@orbit/shared'
import type { ThemeMode } from '@orbit/shared'
+import { updateColorScheme as updateColorSchemeAction } from '@/app/actions/profile'
function getCookie(name: string): string | null {
if (typeof document === 'undefined') return null
@@ -121,13 +122,17 @@ export function useColorScheme() {
// Apply scheme on mount and when values change
useEffect(() => {
- applySchemeToDOM(currentScheme, currentTheme)
+ applySchemeToDOM(currentScheme, currentTheme, false)
}, [currentScheme, currentTheme])
- const applyScheme = useCallback((scheme: ColorScheme) => {
+ const applyScheme = useCallback((scheme: ColorScheme, persistToDb = true) => {
setCookie('orbit_color_scheme', scheme)
setCurrentScheme(scheme)
applySchemeToDOM(scheme, currentTheme, true)
+
+ if (persistToDb) {
+ updateColorSchemeAction({ colorScheme: scheme }).catch(() => {})
+ }
}, [currentTheme])
const applyTheme = useCallback((theme: ThemeMode) => {
@@ -141,11 +146,37 @@ export function useColorScheme() {
applyTheme(next)
}, [currentTheme, applyTheme])
+ /**
+ * Sync cookie with DB value (DB is source of truth).
+ * Call this after profile loads to ensure cross-device sync.
+ */
+ const syncSchemeFromProfile = useCallback((dbColorScheme: string | null) => {
+ const dbScheme = (dbColorScheme && VALID_SCHEMES.includes(dbColorScheme as ColorScheme))
+ ? (dbColorScheme as ColorScheme)
+ : null
+ if (dbScheme && dbScheme !== currentScheme) {
+ setCookie('orbit_color_scheme', dbScheme)
+ setCurrentScheme(dbScheme)
+ applySchemeToDOM(dbScheme, currentTheme)
+ }
+ }, [currentScheme, currentTheme])
+
+ /**
+ * First-login detection: if DB colorScheme is null, save current
+ * cookie value (default purple) so future logins are consistent.
+ */
+ const detectAndSaveSchemeIfNeeded = useCallback((dbColorScheme: string | null) => {
+ if (dbColorScheme !== null) return
+ updateColorSchemeAction({ colorScheme: currentScheme }).catch(() => {})
+ }, [currentScheme])
+
return {
currentScheme,
currentTheme,
applyScheme,
applyTheme,
toggleTheme,
+ syncSchemeFromProfile,
+ detectAndSaveSchemeIfNeeded,
}
}
diff --git a/apps/web/hooks/use-gamification.ts b/apps/web/hooks/use-gamification.ts
index 32c063e87..e49842043 100644
--- a/apps/web/hooks/use-gamification.ts
+++ b/apps/web/hooks/use-gamification.ts
@@ -199,18 +199,19 @@ export function useActivateStreakFreeze() {
// Derived selectors
// ---------------------------------------------------------------------------
-export function useStreakFreeze() {
+export function useStreakFreeze(profile?: { streakFreezesAvailable?: number; currentStreak?: number } | null) {
const streakQuery = useStreakInfo()
const streakInfo = streakQuery.data ?? null
- const freezesAvailable = streakInfo?.freezesAvailable ?? 0
+ const freezesAvailable = streakInfo?.freezesAvailable ?? profile?.streakFreezesAvailable ?? 0
const isFrozenToday = streakInfo?.isFrozenToday ?? false
const hasCompletedToday = useMemo(() => {
if (!streakInfo?.lastActiveDate) return false
return streakInfo.lastActiveDate === formatAPIDate(new Date())
}, [streakInfo?.lastActiveDate])
- const canFreeze = freezesAvailable > 0 && !isFrozenToday && !hasCompletedToday && (streakInfo?.currentStreak ?? 0) > 0
+ const currentStreak = streakInfo?.currentStreak ?? profile?.currentStreak ?? 0
+ const canFreeze = freezesAvailable > 0 && !isFrozenToday && !hasCompletedToday && currentStreak > 0
return {
streakQuery,
diff --git a/apps/web/hooks/use-habit-form.ts b/apps/web/hooks/use-habit-form.ts
index 6e0fa3195..90e9de151 100644
--- a/apps/web/hooks/use-habit-form.ts
+++ b/apps/web/hooks/use-habit-form.ts
@@ -24,6 +24,8 @@ import type { FrequencyUnit, ChecklistItem, ScheduledReminderTime } from '@orbit
export interface HabitFormOptions {
/** Initial data for editing an existing habit */
initialData?: Partial
+ /** Week start day from profile: 0 = Sunday, 1 = Monday (default) */
+ weekStartDay?: number
}
export interface HabitFormHelpers {
@@ -63,7 +65,7 @@ export interface HabitFormHelpers {
// ---------------------------------------------------------------------------
export function useHabitForm(options: HabitFormOptions = {}): HabitFormHelpers {
- const { initialData } = options
+ const { initialData, weekStartDay = 1 } = options
const t = useTranslations()
const form = useForm({
@@ -102,7 +104,6 @@ export function useHabitForm(options: HabitFormOptions = {}): HabitFormHelpers {
const showEndDate = !!frequencyUnit && !isGeneral
// -- Day picker list --
- // TODO: Use weekStartDay from profile store when available
const daysList = useMemo(() => {
const mondayFirst = [
{ value: 'Monday', label: t('dates.daysShort.monday') },
@@ -113,9 +114,12 @@ export function useHabitForm(options: HabitFormOptions = {}): HabitFormHelpers {
{ value: 'Saturday', label: t('dates.daysShort.saturday') },
{ value: 'Sunday', label: t('dates.daysShort.sunday') },
]
- // TODO: Check profile weekStartDay === 0 for Sunday-first
+ // weekStartDay === 0 means Sunday-first
+ if (weekStartDay === 0) {
+ return [mondayFirst[6]!, ...mondayFirst.slice(0, 6)]
+ }
return mondayFirst
- }, [t])
+ }, [t, weekStartDay])
// -- Frequency units list --
const frequencyUnits = useMemo(
diff --git a/apps/web/hooks/use-habits.ts b/apps/web/hooks/use-habits.ts
index ec7e4f557..8e889858e 100644
--- a/apps/web/hooks/use-habits.ts
+++ b/apps/web/hooks/use-habits.ts
@@ -417,7 +417,7 @@ export function useLogHabit() {
onSettled: () => {
// Refetch for eventual consistency
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
queryClient.invalidateQueries({ queryKey: goalKeys.lists() })
queryClient.invalidateQueries({ queryKey: profileKeys.all })
queryClient.invalidateQueries({ queryKey: gamificationKeys.all })
@@ -465,7 +465,7 @@ export function useSkipHabit() {
onSettled: () => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
},
})
}
@@ -482,7 +482,7 @@ export function useCreateHabit() {
onSettled: () => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
},
})
}
@@ -497,7 +497,7 @@ export function useUpdateHabit() {
onSettled: (_data, _err, { habitId }) => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
queryClient.invalidateQueries({ queryKey: habitKeys.detail(habitId) })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
},
})
}
@@ -510,7 +510,7 @@ export function useDeleteHabit() {
onSettled: () => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
queryClient.invalidateQueries({ queryKey: goalKeys.lists() })
},
})
@@ -536,7 +536,7 @@ export function useDuplicateHabit() {
onSettled: () => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
},
})
}
@@ -595,7 +595,7 @@ export function useUpdateChecklist() {
onSettled: () => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
},
})
}
@@ -618,7 +618,7 @@ export function useCreateSubHabit() {
onSettled: () => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
},
})
}
@@ -637,7 +637,7 @@ export function useMoveHabitParent() {
onSettled: () => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
},
})
}
@@ -654,7 +654,7 @@ export function useBulkCreateHabits() {
onSettled: () => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
},
})
}
@@ -667,7 +667,7 @@ export function useBulkDeleteHabits() {
onSettled: () => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
queryClient.invalidateQueries({ queryKey: goalKeys.lists() })
},
})
@@ -681,7 +681,7 @@ export function useBulkLogHabits() {
onSettled: () => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
queryClient.invalidateQueries({ queryKey: goalKeys.lists() })
queryClient.invalidateQueries({ queryKey: gamificationKeys.all })
},
@@ -696,11 +696,28 @@ export function useBulkSkipHabits() {
onSettled: () => {
queryClient.invalidateQueries({ queryKey: habitKeys.lists() })
- queryClient.invalidateQueries({ queryKey: habitKeys.summary('', '') })
+ queryClient.invalidateQueries({ queryKey: [...habitKeys.all, 'summary'] })
},
})
}
+// ---------------------------------------------------------------------------
+// Total habit count (lightweight -- fetches page 1 with pageSize=1 to read totalCount)
+// ---------------------------------------------------------------------------
+
+export function useTotalHabitCount(): number {
+ const query = useQuery({
+ queryKey: habitKeys.list({ _count: true } as Record),
+ queryFn: async () => {
+ const url = buildUrl(API.habits.list, 'pageSize=1')
+ const data = await fetchJson>(url)
+ return data.totalCount
+ },
+ staleTime: QUERY_STALE_TIMES.habits,
+ })
+ return query.data ?? 0
+}
+
// ---------------------------------------------------------------------------
// Re-export normalize helpers for drill navigation and other consumers
// ---------------------------------------------------------------------------
diff --git a/apps/web/hooks/use-portal-container.ts b/apps/web/hooks/use-portal-container.ts
new file mode 100644
index 000000000..797c62748
--- /dev/null
+++ b/apps/web/hooks/use-portal-container.ts
@@ -0,0 +1,23 @@
+import { useRef, useEffect, useState } from 'react'
+
+/**
+ * Creates a dedicated DOM container for a portal, avoiding React key warnings
+ * when multiple portals render to document.body simultaneously.
+ */
+export function usePortalContainer(id: string) {
+ const [container, setContainer] = useState(null)
+ const elRef = useRef(null)
+
+ useEffect(() => {
+ let el = document.getElementById(`portal-${id}`)
+ if (!el) {
+ el = document.createElement('div')
+ el.id = `portal-${id}`
+ document.body.appendChild(el)
+ }
+ elRef.current = el
+ setContainer(el)
+ }, [id])
+
+ return container
+}
diff --git a/apps/web/hooks/use-retrospective.ts b/apps/web/hooks/use-retrospective.ts
index eaa1b162d..d15095506 100644
--- a/apps/web/hooks/use-retrospective.ts
+++ b/apps/web/hooks/use-retrospective.ts
@@ -1,7 +1,7 @@
'use client'
import { useState, useCallback } from 'react'
-import { useTranslations } from 'next-intl'
+import { useTranslations, useLocale } from 'next-intl'
import { API } from '@orbit/shared/api'
import { getErrorMessage } from '@orbit/shared/utils'
@@ -14,6 +14,7 @@ interface RetrospectiveResponse {
export function useRetrospective() {
const t = useTranslations()
+ const locale = useLocale()
const [retrospective, setRetrospective] = useState(null)
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState(null)
@@ -28,7 +29,7 @@ export function useRetrospective() {
try {
const params = new URLSearchParams({
period,
- language: 'en',
+ language: locale,
})
const res = await fetch(`${API.habits.retrospective}?${params.toString()}`)
if (!res.ok) {
@@ -43,7 +44,7 @@ export function useRetrospective() {
} finally {
setIsLoading(false)
}
- }, [period, t])
+ }, [period, locale, t])
return {
retrospective,
diff --git a/apps/web/hooks/use-tag-selection.ts b/apps/web/hooks/use-tag-selection.ts
index fa3b8cafa..c855a5ee7 100644
--- a/apps/web/hooks/use-tag-selection.ts
+++ b/apps/web/hooks/use-tag-selection.ts
@@ -69,11 +69,11 @@ export interface TagSelectionState {
* callback functions so this hook stays decoupled from the tags store/API.
*
* @param initialTagIds - Tag IDs to start with (for editing)
- * @param maxTags - Maximum number of tags allowed per habit
+ * @param maxTags - Maximum number of tags allowed per habit (from config.limits.maxTagsPerHabit)
*/
export function useTagSelection(
initialTagIds: string[] = [],
- maxTags = 5,
+ maxTags = 10,
): TagSelectionState {
const [selectedTagIds, setSelectedTagIds] = useState([...initialTagIds])
const [showNewTag, setShowNewTag] = useState(false)
diff --git a/apps/web/lib/supabase.ts b/apps/web/lib/supabase.ts
new file mode 100644
index 000000000..4bc711277
--- /dev/null
+++ b/apps/web/lib/supabase.ts
@@ -0,0 +1,13 @@
+import { createClient, type SupabaseClient } from '@supabase/supabase-js'
+
+let client: SupabaseClient | null = null
+
+export function getSupabaseClient(): SupabaseClient {
+ if (!client) {
+ const url = process.env.NEXT_PUBLIC_SUPABASE_URL
+ const key = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
+ if (!url || !key) throw new Error('Supabase config missing')
+ client = createClient(url, key)
+ }
+ return client
+}
diff --git a/apps/web/package.json b/apps/web/package.json
index c9d51e288..ed4945ecf 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -25,19 +25,22 @@
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.0",
+ "@supabase/supabase-js": "^2.101.1",
"@tanstack/query-sync-storage-persister": "^5.75.0",
"@tanstack/react-query": "^5.75.0",
"@tanstack/react-query-persist-client": "^5.75.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"date-fns": "^4.1.0",
+ "dompurify": "^3.3.3",
"idb": "^8.0.0",
"lucide-react": "^0.487.0",
+ "marked": "^17.0.5",
"next": "^15.3.0",
"next-intl": "^4.1.0",
- "react": "^19.1.0",
+ "react": "19.1.0",
"react-day-picker": "^9.4.0",
- "react-dom": "^19.1.0",
+ "react-dom": "19.1.0",
"react-hook-form": "^7.54.0",
"sonner": "^2.0.0",
"tailwind-merge": "^3.0.0",
@@ -51,6 +54,7 @@
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.6.0",
"@testing-library/react": "^16.3.0",
+ "@types/dompurify": "^3.0.5",
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.0",
"@vitejs/plugin-react": "^4.4.0",
diff --git a/apps/web/stores/chat-store.ts b/apps/web/stores/chat-store.ts
index 3916566d4..0f7a8535b 100644
--- a/apps/web/stores/chat-store.ts
+++ b/apps/web/stores/chat-store.ts
@@ -4,18 +4,15 @@ import type { ChatMessage } from '@orbit/shared/types/chat'
interface ChatState {
messages: ChatMessage[]
isTyping: boolean
- isStreaming: boolean
addMessage: (message: ChatMessage) => void
setIsTyping: (value: boolean) => void
- setIsStreaming: (value: boolean) => void
clearMessages: () => void
}
export const useChatStore = create((set) => ({
messages: [],
isTyping: false,
- isStreaming: false,
addMessage: (message) =>
set((state) => ({
@@ -24,12 +21,9 @@ export const useChatStore = create((set) => ({
setIsTyping: (value) => set({ isTyping: value }),
- setIsStreaming: (value) => set({ isStreaming: value }),
-
clearMessages: () =>
set({
messages: [],
isTyping: false,
- isStreaming: false,
}),
}))
diff --git a/apps/web/stores/ui-store.ts b/apps/web/stores/ui-store.ts
index 3fca40867..ca792fd31 100644
--- a/apps/web/stores/ui-store.ts
+++ b/apps/web/stores/ui-store.ts
@@ -30,15 +30,25 @@ interface UIState {
// Select mode (bulk operations)
isSelectMode: boolean
selectedHabitIds: Set
+ manuallySelectedIds: Set
lastCreatedHabitId: string | null
toggleSelectMode: () => void
toggleHabitSelection: (id: string) => void
+ /** Cascade-aware toggle: selects/deselects all descendants with the parent */
+ toggleSelectionCascade: (
+ habitId: string,
+ getDescendantIds: (id: string) => string[],
+ isAncestorSelected: (id: string) => boolean,
+ ) => void
+ selectAllHabits: (allIds: string[]) => void
clearSelection: () => void
setLastCreatedHabitId: (id: string | null) => void
- // Create modal (shared between layout BottomNav and pages)
+ // Create modals (shared between layout BottomNav and pages)
showCreateModal: boolean
setShowCreateModal: (show: boolean) => void
+ showCreateGoalModal: boolean
+ setShowCreateGoalModal: (show: boolean) => void
// Search
searchQuery: string
@@ -98,12 +108,14 @@ export const useUIStore = create((set, get) => ({
// -- Select mode ------------------------------------------------------------
isSelectMode: false,
selectedHabitIds: new Set(),
+ manuallySelectedIds: new Set(),
lastCreatedHabitId: null,
toggleSelectMode: () =>
set((state) => ({
isSelectMode: !state.isSelectMode,
selectedHabitIds: state.isSelectMode ? new Set() : state.selectedHabitIds,
+ manuallySelectedIds: state.isSelectMode ? new Set() : state.manuallySelectedIds,
})),
toggleHabitSelection: (id) =>
@@ -117,8 +129,40 @@ export const useUIStore = create((set, get) => ({
return { selectedHabitIds: next }
}),
+ toggleSelectionCascade: (habitId, getDescendantIds, isAncestorSelected) =>
+ set((state) => {
+ // If an ancestor is already selected, don't allow toggling the child
+ if (isAncestorSelected(habitId)) return state
+
+ const selected = new Set(state.selectedHabitIds)
+ const manual = new Set(state.manuallySelectedIds)
+ const descendants = getDescendantIds(habitId)
+
+ if (selected.has(habitId)) {
+ // Deselect: remove the habit and auto-selected descendants
+ selected.delete(habitId)
+ manual.delete(habitId)
+ for (const id of descendants) {
+ if (!manual.has(id)) selected.delete(id)
+ }
+ } else {
+ // Select: add the habit and all descendants
+ selected.add(habitId)
+ manual.add(habitId)
+ for (const id of descendants) selected.add(id)
+ }
+
+ return { selectedHabitIds: selected, manuallySelectedIds: manual }
+ }),
+
+ selectAllHabits: (allIds) =>
+ set({
+ selectedHabitIds: new Set(allIds),
+ manuallySelectedIds: new Set(allIds),
+ }),
+
clearSelection: () =>
- set({ isSelectMode: false, selectedHabitIds: new Set() }),
+ set({ isSelectMode: false, selectedHabitIds: new Set(), manuallySelectedIds: new Set() }),
setLastCreatedHabitId: (id) => {
if (createdHabitTimer) clearTimeout(createdHabitTimer)
@@ -128,9 +172,11 @@ export const useUIStore = create((set, get) => ({
}
},
- // -- Create modal -----------------------------------------------------------
+ // -- Create modals ----------------------------------------------------------
showCreateModal: false,
setShowCreateModal: (show) => set({ showCreateModal: show }),
+ showCreateGoalModal: false,
+ setShowCreateGoalModal: (show) => set({ showCreateGoalModal: show }),
// -- Search -----------------------------------------------------------------
searchQuery: '',
diff --git a/package-lock.json b/package-lock.json
index 8584f6224..45fe39bbd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -47,7 +47,7 @@
"fs-extra": "^11.3.4",
"i18next": "^24.2.0",
"lucide-react-native": "^0.475.0",
- "react": "^19.1.0",
+ "react": "19.1.0",
"react-hook-form": "^7.54.0",
"react-i18next": "^15.4.0",
"react-native": "0.81.5",
@@ -82,19 +82,22 @@
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.0",
+ "@supabase/supabase-js": "^2.101.1",
"@tanstack/query-sync-storage-persister": "^5.75.0",
"@tanstack/react-query": "^5.75.0",
"@tanstack/react-query-persist-client": "^5.75.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"date-fns": "^4.1.0",
+ "dompurify": "^3.3.3",
"idb": "^8.0.0",
"lucide-react": "^0.487.0",
+ "marked": "^17.0.5",
"next": "^15.3.0",
"next-intl": "^4.1.0",
- "react": "^19.1.0",
+ "react": "19.1.0",
"react-day-picker": "^9.4.0",
- "react-dom": "^19.1.0",
+ "react-dom": "19.1.0",
"react-hook-form": "^7.54.0",
"sonner": "^2.0.0",
"tailwind-merge": "^3.0.0",
@@ -108,6 +111,7 @@
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.6.0",
"@testing-library/react": "^16.3.0",
+ "@types/dompurify": "^3.0.5",
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.0",
"@vitejs/plugin-react": "^4.4.0",
@@ -117,945 +121,1131 @@
"vitest": "^3.1.0"
}
},
- "apps/web/node_modules/tailwindcss": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz",
- "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@0no-co/graphql.web": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.2.0.tgz",
- "integrity": "sha512-/1iHy9TTr63gE1YcR5idjx8UREz1s0kFhydf3bBLCXyqjhkIc6igAzTOx3zPifCwFR87tsh/4Pa9cNts6d2otw==",
+ "apps/web/node_modules/@radix-ui/react-alert-dialog": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz",
+ "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==",
"license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dialog": "1.1.15",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3"
+ },
"peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
- "graphql": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
"optional": true
}
}
},
- "node_modules/@adobe/css-tools": {
- "version": "4.4.4",
- "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz",
- "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@alloc/quick-lru": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
- "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
- "dev": true,
+ "apps/web/node_modules/@radix-ui/react-arrow": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz",
+ "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==",
"license": "MIT",
- "engines": {
- "node": ">=10"
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.1.3"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@asamuzakjp/css-color": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
- "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==",
- "dev": true,
+ "apps/web/node_modules/@radix-ui/react-checkbox": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz",
+ "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==",
"license": "MIT",
"dependencies": {
- "@csstools/css-calc": "^2.1.3",
- "@csstools/css-color-parser": "^3.0.9",
- "@csstools/css-parser-algorithms": "^3.0.4",
- "@csstools/css-tokenizer": "^3.0.3",
- "lru-cache": "^10.4.3"
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "@radix-ui/react-use-previous": "1.1.1",
+ "@radix-ui/react-use-size": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
- "version": "10.4.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
- "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/@babel/code-frame": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
- "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
+ "apps/web/node_modules/@radix-ui/react-collection": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
+ "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.28.5",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.1.1"
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3"
},
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/compat-data": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz",
- "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
+ "apps/web/node_modules/@radix-ui/react-dialog": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz",
+ "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==",
"license": "MIT",
- "engines": {
- "node": ">=6.9.0"
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-focus-guards": "1.1.3",
+ "@radix-ui/react-focus-scope": "1.1.7",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/core": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
- "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
+ "apps/web/node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
+ "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.29.0",
- "@babel/generator": "^7.29.0",
- "@babel/helper-compilation-targets": "^7.28.6",
- "@babel/helper-module-transforms": "^7.28.6",
- "@babel/helpers": "^7.28.6",
- "@babel/parser": "^7.29.0",
- "@babel/template": "^7.28.6",
- "@babel/traverse": "^7.29.0",
- "@babel/types": "^7.29.0",
- "@jridgewell/remapping": "^2.3.5",
- "convert-source-map": "^2.0.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-escape-keydown": "1.1.1"
},
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/generator": {
- "version": "7.29.1",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
- "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
+ "apps/web/node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
+ "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.29.0",
- "@babel/types": "^7.29.0",
- "@jridgewell/gen-mapping": "^0.3.12",
- "@jridgewell/trace-mapping": "^0.3.28",
- "jsesc": "^3.0.2"
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1"
},
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.27.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
- "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
+ "apps/web/node_modules/@radix-ui/react-popover": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz",
+ "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.27.3"
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-focus-guards": "1.1.3",
+ "@radix-ui/react-focus-scope": "1.1.7",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-popper": "1.2.8",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
},
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
- "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
+ "apps/web/node_modules/@radix-ui/react-popper": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz",
+ "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==",
"license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.28.6",
- "@babel/helper-validator-option": "^7.27.1",
- "browserslist": "^4.24.0",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.1"
+ "@floating-ui/react-dom": "^2.0.0",
+ "@radix-ui/react-arrow": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-layout-effect": "1.1.1",
+ "@radix-ui/react-use-rect": "1.1.1",
+ "@radix-ui/react-use-size": "1.1.1",
+ "@radix-ui/rect": "1.1.1"
},
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz",
- "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==",
+ "apps/web/node_modules/@radix-ui/react-portal": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
+ "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.27.3",
- "@babel/helper-member-expression-to-functions": "^7.28.5",
- "@babel/helper-optimise-call-expression": "^7.27.1",
- "@babel/helper-replace-supers": "^7.28.6",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
- "@babel/traverse": "^7.28.6",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
},
"peerDependencies": {
- "@babel/core": "^7.0.0"
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-create-regexp-features-plugin": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz",
- "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==",
+ "apps/web/node_modules/@radix-ui/react-presence": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
+ "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.27.3",
- "regexpu-core": "^6.3.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
},
"peerDependencies": {
- "@babel/core": "^7.0.0"
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-define-polyfill-provider": {
- "version": "0.6.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz",
- "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==",
+ "apps/web/node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
+ "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-compilation-targets": "^7.28.6",
- "@babel/helper-plugin-utils": "^7.28.6",
- "debug": "^4.4.3",
- "lodash.debounce": "^4.0.8",
- "resolve": "^1.22.11"
+ "@radix-ui/react-slot": "1.2.3"
},
"peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
- }
- },
- "node_modules/@babel/helper-globals": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
- "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-member-expression-to-functions": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz",
- "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==",
+ "apps/web/node_modules/@radix-ui/react-scroll-area": {
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz",
+ "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==",
"license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.28.5",
- "@babel/types": "^7.28.5"
+ "@radix-ui/number": "1.1.1",
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
},
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-module-imports": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
- "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
+ "apps/web/node_modules/@radix-ui/react-select": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz",
+ "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==",
"license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.28.6",
- "@babel/types": "^7.28.6"
+ "@radix-ui/number": "1.1.1",
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-collection": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-focus-guards": "1.1.3",
+ "@radix-ui/react-focus-scope": "1.1.7",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-popper": "1.2.8",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1",
+ "@radix-ui/react-use-previous": "1.1.1",
+ "@radix-ui/react-visually-hidden": "1.2.3",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
},
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
- "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
+ "apps/web/node_modules/@radix-ui/react-separator": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.8.tgz",
+ "integrity": "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==",
"license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.28.6",
- "@babel/helper-validator-identifier": "^7.28.5",
- "@babel/traverse": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@radix-ui/react-primitive": "2.1.4"
},
"peerDependencies": {
- "@babel/core": "^7.0.0"
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-optimise-call-expression": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz",
- "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==",
+ "apps/web/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz",
+ "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.27.1"
+ "@radix-ui/react-slot": "1.2.4"
},
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
- "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-remap-async-to-generator": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz",
- "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==",
+ "apps/web/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz",
+ "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.27.1",
- "@babel/helper-wrap-function": "^7.27.1",
- "@babel/traverse": "^7.27.1"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@radix-ui/react-compose-refs": "1.1.2"
},
"peerDependencies": {
- "@babel/core": "^7.0.0"
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-replace-supers": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz",
- "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==",
+ "apps/web/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
"license": "MIT",
"dependencies": {
- "@babel/helper-member-expression-to-functions": "^7.28.5",
- "@babel/helper-optimise-call-expression": "^7.27.1",
- "@babel/traverse": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@radix-ui/react-compose-refs": "1.1.2"
},
"peerDependencies": {
- "@babel/core": "^7.0.0"
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz",
- "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==",
+ "apps/web/node_modules/@radix-ui/react-switch": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz",
+ "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==",
"license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.27.1",
- "@babel/types": "^7.27.1"
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "@radix-ui/react-use-previous": "1.1.1",
+ "@radix-ui/react-use-size": "1.1.1"
},
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
- "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
- "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-option": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
- "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helper-wrap-function": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz",
- "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==",
+ "apps/web/node_modules/@radix-ui/react-tooltip": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz",
+ "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==",
"license": "MIT",
"dependencies": {
- "@babel/template": "^7.28.6",
- "@babel/traverse": "^7.28.6",
- "@babel/types": "^7.28.6"
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-popper": "1.2.8",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "@radix-ui/react-visually-hidden": "1.2.3"
},
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/helpers": {
- "version": "7.29.2",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz",
- "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==",
+ "apps/web/node_modules/@radix-ui/react-visually-hidden": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz",
+ "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==",
"license": "MIT",
"dependencies": {
- "@babel/template": "^7.28.6",
- "@babel/types": "^7.29.0"
+ "@radix-ui/react-primitive": "2.1.3"
},
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/highlight": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz",
- "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==",
+ "apps/web/node_modules/@testing-library/react": {
+ "version": "16.3.2",
+ "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz",
+ "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.25.9",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
+ "@babel/runtime": "^7.12.5"
},
"engines": {
- "node": ">=6.9.0"
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@testing-library/dom": "^10.0.0",
+ "@types/react": "^18.0.0 || ^19.0.0",
+ "@types/react-dom": "^18.0.0 || ^19.0.0",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/highlight/node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "apps/web/node_modules/@types/react": {
+ "version": "19.2.14",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
+ "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
+ "devOptional": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
+ "csstype": "^3.2.2"
}
},
- "node_modules/@babel/highlight/node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "apps/web/node_modules/@types/react-dom": {
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
+ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
+ "devOptional": true,
"license": "MIT",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/highlight/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "license": "MIT",
- "dependencies": {
- "color-name": "1.1.3"
+ "peer": true,
+ "peerDependencies": {
+ "@types/react": "^19.2.0"
}
},
- "node_modules/@babel/highlight/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "apps/web/node_modules/tailwindcss": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz",
+ "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==",
+ "dev": true,
"license": "MIT"
},
- "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "node_modules/@0no-co/graphql.web": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.2.0.tgz",
+ "integrity": "sha512-/1iHy9TTr63gE1YcR5idjx8UREz1s0kFhydf3bBLCXyqjhkIc6igAzTOx3zPifCwFR87tsh/4Pa9cNts6d2otw==",
"license": "MIT",
- "engines": {
- "node": ">=0.8.0"
+ "peerDependencies": {
+ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
+ },
+ "peerDependenciesMeta": {
+ "graphql": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/highlight/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "node_modules/@adobe/css-tools": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz",
+ "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@alloc/quick-lru": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">=4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/@babel/highlight/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "node_modules/@asamuzakjp/css-color": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
+ "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
+ "@csstools/css-calc": "^2.1.3",
+ "@csstools/css-color-parser": "^3.0.9",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "lru-cache": "^10.4.3"
}
},
- "node_modules/@babel/parser": {
- "version": "7.29.2",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz",
- "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==",
+ "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
+ "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.29.0"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
},
"engines": {
- "node": ">=6.0.0"
+ "node": ">=6.9.0"
}
},
- "node_modules/@babel/plugin-proposal-decorators": {
+ "node_modules/@babel/compat-data": {
"version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.0.tgz",
- "integrity": "sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz",
+ "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
"license": "MIT",
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.28.6",
- "@babel/helper-plugin-utils": "^7.28.6",
- "@babel/plugin-syntax-decorators": "^7.28.6"
- },
"engines": {
"node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-proposal-export-default-from": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.27.1.tgz",
- "integrity": "sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw==",
+ "node_modules/@babel/core": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
+ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
+ "@babel/code-frame": "^7.29.0",
+ "@babel/generator": "^7.29.0",
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-module-transforms": "^7.28.6",
+ "@babel/helpers": "^7.28.6",
+ "@babel/parser": "^7.29.0",
+ "@babel/template": "^7.28.6",
+ "@babel/traverse": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
},
"engines": {
"node": ">=6.9.0"
},
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
}
},
- "node_modules/@babel/plugin-syntax-async-generators": {
- "version": "7.8.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
- "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "node_modules/@babel/generator": {
+ "version": "7.29.1",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
+ "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
+ "@babel/parser": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
},
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "node_modules/@babel/plugin-syntax-bigint": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
- "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.27.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+ "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
+ "@babel/types": "^7.27.3"
},
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "node_modules/@babel/plugin-syntax-class-properties": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
- "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
+ "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/compat-data": "^7.28.6",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
},
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "node_modules/@babel/plugin-syntax-class-static-block": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
- "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz",
+ "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-member-expression-to-functions": "^7.28.5",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.28.6",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/traverse": "^7.28.6",
+ "semver": "^6.3.1"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/plugin-syntax-decorators": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.28.6.tgz",
- "integrity": "sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==",
+ "node_modules/@babel/helper-create-regexp-features-plugin": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz",
+ "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6"
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "regexpu-core": "^6.3.1",
+ "semver": "^6.3.1"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/plugin-syntax-dynamic-import": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
- "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "node_modules/@babel/helper-define-polyfill-provider": {
+ "version": "0.6.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz",
+ "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "debug": "^4.4.3",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.22.11"
},
"peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
- "node_modules/@babel/plugin-syntax-export-default-from": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.28.6.tgz",
- "integrity": "sha512-Svlx1fjJFnNz0LZeUaybRukSxZI3KkpApUmIRzEdXC5k8ErTOz0OD0kNrICi5Vc3GlpP5ZCeRyRO+mfWTSz+iQ==",
+ "node_modules/@babel/helper-globals": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
"license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6"
- },
"engines": {
"node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-flow": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.28.6.tgz",
- "integrity": "sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==",
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz",
+ "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6"
+ "@babel/traverse": "^7.28.5",
+ "@babel/types": "^7.28.5"
},
"engines": {
"node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-import-attributes": {
+ "node_modules/@babel/helper-module-imports": {
"version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz",
- "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
+ "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6"
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-import-meta": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
- "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
+ "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
+ "@babel/helper-module-imports": "^7.28.6",
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "@babel/traverse": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/plugin-syntax-json-strings": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
- "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz",
+ "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
+ "@babel/types": "^7.27.1"
},
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "node_modules/@babel/plugin-syntax-jsx": {
+ "node_modules/@babel/helper-plugin-utils": {
"version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz",
- "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
+ "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
"license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6"
- },
"engines": {
"node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
- "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "node_modules/@babel/helper-remap-async-to-generator": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz",
+ "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-wrap-function": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
},
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
- "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/plugin-syntax-numeric-separator": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
- "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz",
+ "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
+ "@babel/helper-member-expression-to-functions": "^7.28.5",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/traverse": "^7.28.6"
},
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-object-rest-spread": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
- "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/plugin-syntax-optional-catch-binding": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
- "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz",
+ "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
},
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "node_modules/@babel/plugin-syntax-optional-chaining": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
- "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "node_modules/@babel/plugin-syntax-private-property-in-object": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
- "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
"license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
"engines": {
"node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-top-level-await": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
- "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
"license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
"engines": {
"node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-typescript": {
+ "node_modules/@babel/helper-wrap-function": {
"version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz",
- "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz",
+ "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6"
+ "@babel/template": "^7.28.6",
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-arrow-functions": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz",
- "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==",
+ "node_modules/@babel/helpers": {
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz",
+ "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.29.0"
},
"engines": {
"node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-async-generator-functions": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz",
- "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==",
+ "node_modules/@babel/highlight": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz",
+ "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6",
- "@babel/helper-remap-async-to-generator": "^7.27.1",
- "@babel/traverse": "^7.29.0"
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-async-to-generator": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz",
- "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==",
+ "node_modules/@babel/highlight/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.28.6",
- "@babel/helper-plugin-utils": "^7.28.6",
- "@babel/helper-remap-async-to-generator": "^7.27.1"
+ "color-convert": "^1.9.0"
},
"engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "node": ">=4"
}
},
- "node_modules/@babel/plugin-transform-block-scoping": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz",
- "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==",
+ "node_modules/@babel/highlight/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6"
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
},
"engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "node": ">=4"
}
},
- "node_modules/@babel/plugin-transform-class-properties": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz",
- "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==",
+ "node_modules/@babel/highlight/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.28.6",
- "@babel/helper-plugin-utils": "^7.28.6"
- },
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "license": "MIT"
+ },
+ "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "license": "MIT",
"engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "node": ">=0.8.0"
}
},
- "node_modules/@babel/plugin-transform-class-static-block": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz",
- "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==",
+ "node_modules/@babel/highlight/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"license": "MIT",
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.28.6",
- "@babel/helper-plugin-utils": "^7.28.6"
- },
"engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.12.0"
+ "node": ">=4"
}
},
- "node_modules/@babel/plugin-transform-classes": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz",
- "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==",
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.27.3",
- "@babel/helper-compilation-targets": "^7.28.6",
- "@babel/helper-globals": "^7.28.0",
- "@babel/helper-plugin-utils": "^7.28.6",
- "@babel/helper-replace-supers": "^7.28.6",
- "@babel/traverse": "^7.28.6"
+ "has-flag": "^3.0.0"
},
"engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "node": ">=4"
}
},
- "node_modules/@babel/plugin-transform-computed-properties": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz",
- "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==",
+ "node_modules/@babel/parser": {
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz",
+ "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6",
- "@babel/template": "^7.28.6"
+ "@babel/types": "^7.29.0"
},
- "engines": {
- "node": ">=6.9.0"
+ "bin": {
+ "parser": "bin/babel-parser.js"
},
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "engines": {
+ "node": ">=6.0.0"
}
},
- "node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz",
- "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==",
+ "node_modules/@babel/plugin-proposal-decorators": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.0.tgz",
+ "integrity": "sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1",
- "@babel/traverse": "^7.28.5"
+ "@babel/helper-create-class-features-plugin": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/plugin-syntax-decorators": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
@@ -1064,10 +1254,10 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-export-namespace-from": {
+ "node_modules/@babel/plugin-proposal-export-default-from": {
"version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz",
- "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.27.1.tgz",
+ "integrity": "sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw==",
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
@@ -1079,62 +1269,49 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-flow-strip-types": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz",
- "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==",
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1",
- "@babel/plugin-syntax-flow": "^7.27.1"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@babel/helper-plugin-utils": "^7.8.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-for-of": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz",
- "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==",
+ "node_modules/@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@babel/helper-plugin-utils": "^7.8.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-function-name": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz",
- "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==",
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-compilation-targets": "^7.27.1",
- "@babel/helper-plugin-utils": "^7.27.1",
- "@babel/traverse": "^7.27.1"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@babel/helper-plugin-utils": "^7.12.13"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-literals": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz",
- "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==",
+ "node_modules/@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
+ "@babel/helper-plugin-utils": "^7.14.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1143,10 +1320,10 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+ "node_modules/@babel/plugin-syntax-decorators": {
"version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz",
- "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.28.6.tgz",
+ "integrity": "sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==",
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.28.6"
@@ -1158,42 +1335,37 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz",
- "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==",
+ "node_modules/@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.28.6",
- "@babel/helper-plugin-utils": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@babel/helper-plugin-utils": "^7.8.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz",
- "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==",
+ "node_modules/@babel/plugin-syntax-export-default-from": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.28.6.tgz",
+ "integrity": "sha512-Svlx1fjJFnNz0LZeUaybRukSxZI3KkpApUmIRzEdXC5k8ErTOz0OD0kNrICi5Vc3GlpP5ZCeRyRO+mfWTSz+iQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.28.5",
"@babel/helper-plugin-utils": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
- "@babel/core": "^7.0.0"
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+ "node_modules/@babel/plugin-syntax-flow": {
"version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz",
- "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.28.6.tgz",
+ "integrity": "sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==",
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.28.6"
@@ -1205,10 +1377,10 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-numeric-separator": {
+ "node_modules/@babel/plugin-syntax-import-attributes": {
"version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz",
- "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz",
+ "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==",
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.28.6"
@@ -1220,48 +1392,37 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-object-rest-spread": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz",
- "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==",
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
"license": "MIT",
"dependencies": {
- "@babel/helper-compilation-targets": "^7.28.6",
- "@babel/helper-plugin-utils": "^7.28.6",
- "@babel/plugin-transform-destructuring": "^7.28.5",
- "@babel/plugin-transform-parameters": "^7.27.7",
- "@babel/traverse": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@babel/helper-plugin-utils": "^7.10.4"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-optional-catch-binding": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz",
- "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==",
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@babel/helper-plugin-utils": "^7.8.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-optional-chaining": {
+ "node_modules/@babel/plugin-syntax-jsx": {
"version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz",
- "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz",
+ "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+ "@babel/helper-plugin-utils": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
@@ -1270,95 +1431,85 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-parameters": {
- "version": "7.27.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz",
- "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==",
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@babel/helper-plugin-utils": "^7.10.4"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-private-methods": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz",
- "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==",
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.28.6",
- "@babel/helper-plugin-utils": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@babel/helper-plugin-utils": "^7.8.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-private-property-in-object": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz",
- "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==",
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.27.3",
- "@babel/helper-create-class-features-plugin": "^7.28.6",
- "@babel/helper-plugin-utils": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@babel/helper-plugin-utils": "^7.10.4"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-react-display-name": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz",
- "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==",
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@babel/helper-plugin-utils": "^7.8.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-react-jsx": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.28.6.tgz",
- "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==",
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.27.3",
- "@babel/helper-module-imports": "^7.28.6",
- "@babel/helper-plugin-utils": "^7.28.6",
- "@babel/plugin-syntax-jsx": "^7.28.6",
- "@babel/types": "^7.28.6"
+ "@babel/helper-plugin-utils": "^7.8.0"
},
- "engines": {
- "node": ">=6.9.0"
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-react-jsx-development": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz",
- "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==",
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
"license": "MIT",
"dependencies": {
- "@babel/plugin-transform-react-jsx": "^7.27.1"
+ "@babel/helper-plugin-utils": "^7.14.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1367,13 +1518,13 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
- "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
+ "@babel/helper-plugin-utils": "^7.14.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1382,13 +1533,13 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
- "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz",
+ "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
+ "@babel/helper-plugin-utils": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
@@ -1397,13 +1548,12 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-react-pure-annotations": {
+ "node_modules/@babel/plugin-transform-arrow-functions": {
"version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz",
- "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz",
+ "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.27.1",
"@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
@@ -1413,13 +1563,15 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-regenerator": {
+ "node_modules/@babel/plugin-transform-async-generator-functions": {
"version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz",
- "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz",
+ "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6"
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-remap-async-to-generator": "^7.27.1",
+ "@babel/traverse": "^7.29.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1428,18 +1580,15 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-runtime": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.0.tgz",
- "integrity": "sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==",
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz",
+ "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==",
"license": "MIT",
"dependencies": {
"@babel/helper-module-imports": "^7.28.6",
"@babel/helper-plugin-utils": "^7.28.6",
- "babel-plugin-polyfill-corejs2": "^0.4.14",
- "babel-plugin-polyfill-corejs3": "^0.13.0",
- "babel-plugin-polyfill-regenerator": "^0.6.5",
- "semver": "^6.3.1"
+ "@babel/helper-remap-async-to-generator": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1448,13 +1597,13 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-shorthand-properties": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz",
- "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==",
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz",
+ "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
+ "@babel/helper-plugin-utils": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
@@ -1463,14 +1612,14 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-spread": {
+ "node_modules/@babel/plugin-transform-class-properties": {
"version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz",
- "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz",
+ "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.28.6",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+ "@babel/helper-create-class-features-plugin": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
@@ -1479,28 +1628,34 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-sticky-regex": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz",
- "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==",
+ "node_modules/@babel/plugin-transform-class-static-block": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz",
+ "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
+ "@babel/helper-create-class-features-plugin": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "@babel/core": "^7.12.0"
}
},
- "node_modules/@babel/plugin-transform-template-literals": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz",
- "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==",
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz",
+ "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-replace-supers": "^7.28.6",
+ "@babel/traverse": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
@@ -1509,17 +1664,14 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-typescript": {
+ "node_modules/@babel/plugin-transform-computed-properties": {
"version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz",
- "integrity": "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz",
+ "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.27.3",
- "@babel/helper-create-class-features-plugin": "^7.28.6",
"@babel/helper-plugin-utils": "^7.28.6",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
- "@babel/plugin-syntax-typescript": "^7.28.6"
+ "@babel/template": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
@@ -1528,14 +1680,14 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-unicode-regex": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz",
- "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==",
+ "node_modules/@babel/plugin-transform-destructuring": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz",
+ "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==",
"license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.27.1",
- "@babel/helper-plugin-utils": "^7.27.1"
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.28.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1544,18 +1696,13 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/preset-react": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz",
- "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==",
+ "node_modules/@babel/plugin-transform-export-namespace-from": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz",
+ "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1",
- "@babel/helper-validator-option": "^7.27.1",
- "@babel/plugin-transform-react-display-name": "^7.28.0",
- "@babel/plugin-transform-react-jsx": "^7.27.1",
- "@babel/plugin-transform-react-jsx-development": "^7.27.1",
- "@babel/plugin-transform-react-pure-annotations": "^7.27.1"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1564,17 +1711,14 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/preset-typescript": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz",
- "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==",
+ "node_modules/@babel/plugin-transform-flow-strip-types": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz",
+ "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==",
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1",
- "@babel/helper-validator-option": "^7.27.1",
- "@babel/plugin-syntax-jsx": "^7.27.1",
- "@babel/plugin-transform-modules-commonjs": "^7.27.1",
- "@babel/plugin-transform-typescript": "^7.28.5"
+ "@babel/plugin-syntax-flow": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1583,617 +1727,751 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/runtime": {
- "version": "7.29.2",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
- "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
+ "node_modules/@babel/plugin-transform-for-of": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz",
+ "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==",
"license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+ },
"engines": {
"node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/template": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
- "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
+ "node_modules/@babel/plugin-transform-function-name": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz",
+ "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==",
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.28.6",
- "@babel/parser": "^7.28.6",
- "@babel/types": "^7.28.6"
+ "@babel/helper-compilation-targets": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/traverse": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
- "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
+ "node_modules/@babel/plugin-transform-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz",
+ "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==",
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.29.0",
- "@babel/generator": "^7.29.0",
- "@babel/helper-globals": "^7.28.0",
- "@babel/parser": "^7.29.0",
- "@babel/template": "^7.28.6",
- "@babel/types": "^7.29.0",
- "debug": "^4.3.1"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/traverse--for-generate-function-map": {
- "name": "@babel/traverse",
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
- "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
+ "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz",
+ "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==",
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.29.0",
- "@babel/generator": "^7.29.0",
- "@babel/helper-globals": "^7.28.0",
- "@babel/parser": "^7.29.0",
- "@babel/template": "^7.28.6",
- "@babel/types": "^7.29.0",
- "debug": "^4.3.1"
+ "@babel/helper-plugin-utils": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/types": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
- "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz",
+ "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
+ "@babel/helper-module-transforms": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@csstools/color-helpers": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
- "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "license": "MIT-0",
+ "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz",
+ "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
}
},
- "node_modules/@csstools/css-calc": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
- "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
+ "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz",
+ "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==",
"license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^3.0.5",
- "@csstools/css-tokenizer": "^3.0.4"
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@csstools/css-color-parser": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz",
- "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
+ "node_modules/@babel/plugin-transform-numeric-separator": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz",
+ "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==",
"license": "MIT",
"dependencies": {
- "@csstools/color-helpers": "^5.1.0",
- "@csstools/css-calc": "^2.1.4"
+ "@babel/helper-plugin-utils": "^7.28.6"
},
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^3.0.5",
- "@csstools/css-tokenizer": "^3.0.4"
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@csstools/css-parser-algorithms": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
- "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
+ "node_modules/@babel/plugin-transform-object-rest-spread": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz",
+ "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==",
"license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/plugin-transform-destructuring": "^7.28.5",
+ "@babel/plugin-transform-parameters": "^7.27.7",
+ "@babel/traverse": "^7.28.6"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
},
"peerDependencies": {
- "@csstools/css-tokenizer": "^3.0.4"
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@csstools/css-tokenizer": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
- "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
+ "node_modules/@babel/plugin-transform-optional-catch-binding": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz",
+ "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==",
"license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@date-fns/tz": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.4.1.tgz",
- "integrity": "sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==",
- "license": "MIT"
- },
- "node_modules/@egjs/hammerjs": {
- "version": "2.0.17",
- "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
- "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
+ "node_modules/@babel/plugin-transform-optional-chaining": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz",
+ "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==",
"license": "MIT",
"dependencies": {
- "@types/hammerjs": "^2.0.36"
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
},
"engines": {
- "node": ">=0.8.0"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@emnapi/runtime": {
- "version": "1.9.2",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz",
- "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==",
+ "node_modules/@babel/plugin-transform-parameters": {
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz",
+ "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==",
"license": "MIT",
- "optional": true,
"dependencies": {
- "tslib": "^2.4.0"
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
- "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-private-methods": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz",
+ "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==",
"license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/android-arm": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz",
- "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-private-property-in-object": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz",
+ "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==",
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-create-class-features-plugin": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/android-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz",
- "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-react-display-name": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz",
+ "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==",
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/android-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz",
- "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-react-jsx": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.28.6.tgz",
+ "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==",
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-module-imports": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/plugin-syntax-jsx": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz",
- "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-react-jsx-development": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz",
+ "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==",
"license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
+ "dependencies": {
+ "@babel/plugin-transform-react-jsx": "^7.27.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz",
- "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
+ "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
"license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz",
- "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
+ "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
"license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz",
- "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-react-pure-annotations": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz",
+ "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==",
"license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/linux-arm": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz",
- "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-regenerator": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz",
+ "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz",
- "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-runtime": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.0.tgz",
+ "integrity": "sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "babel-plugin-polyfill-corejs2": "^0.4.14",
+ "babel-plugin-polyfill-corejs3": "^0.13.0",
+ "babel-plugin-polyfill-regenerator": "^0.6.5",
+ "semver": "^6.3.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz",
- "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-shorthand-properties": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz",
+ "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz",
- "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-spread": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz",
+ "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz",
- "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-sticky-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz",
+ "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz",
- "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-template-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz",
+ "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz",
- "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-typescript": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz",
+ "integrity": "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-create-class-features-plugin": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/plugin-syntax-typescript": "^7.28.6"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz",
- "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
+ "node_modules/@babel/plugin-transform-unicode-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz",
+ "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/linux-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz",
- "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
+ "node_modules/@babel/preset-react": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz",
+ "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-validator-option": "^7.27.1",
+ "@babel/plugin-transform-react-display-name": "^7.28.0",
+ "@babel/plugin-transform-react-jsx": "^7.27.1",
+ "@babel/plugin-transform-react-jsx-development": "^7.27.1",
+ "@babel/plugin-transform-react-pure-annotations": "^7.27.1"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz",
- "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
+ "node_modules/@babel/preset-typescript": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz",
+ "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==",
"license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-validator-option": "^7.27.1",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.27.1",
+ "@babel/plugin-transform-typescript": "^7.28.5"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz",
- "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
+ "node_modules/@babel/runtime": {
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
+ "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
"license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
+ "peer": true,
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
}
},
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz",
- "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
+ "node_modules/@babel/template": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
+ "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
"license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/parser": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
}
},
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz",
- "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
+ "node_modules/@babel/traverse": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
+ "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
"license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz",
- "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.0",
+ "@babel/generator": "^7.29.0",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.29.0",
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.29.0",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse--for-generate-function-map": {
+ "name": "@babel/traverse",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
+ "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.0",
+ "@babel/generator": "^7.29.0",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.29.0",
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.29.0",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@csstools/color-helpers": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
+ "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@csstools/css-calc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
+ "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-color-parser": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz",
+ "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/color-helpers": "^5.1.0",
+ "@csstools/css-calc": "^2.1.4"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-parser-algorithms": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
+ "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-tokenizer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
+ "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@date-fns/tz": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.4.1.tgz",
+ "integrity": "sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==",
+ "license": "MIT"
+ },
+ "node_modules/@egjs/hammerjs": {
+ "version": "2.0.17",
+ "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
+ "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hammerjs": "^2.0.36"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz",
+ "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
+ "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==",
"cpu": [
- "arm64"
+ "ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "openharmony"
+ "aix"
],
"engines": {
"node": ">=18"
}
},
- "node_modules/@esbuild/sunos-x64": {
+ "node_modules/@esbuild/android-arm": {
"version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz",
- "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz",
+ "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==",
"cpu": [
- "x64"
+ "arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "sunos"
+ "android"
],
"engines": {
"node": ">=18"
}
},
- "node_modules/@esbuild/win32-arm64": {
+ "node_modules/@esbuild/android-arm64": {
"version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz",
- "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz",
+ "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==",
"cpu": [
"arm64"
],
@@ -2201,503 +2479,491 @@
"license": "MIT",
"optional": true,
"os": [
- "win32"
+ "android"
],
"engines": {
"node": ">=18"
}
},
- "node_modules/@esbuild/win32-ia32": {
+ "node_modules/@esbuild/android-x64": {
"version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz",
- "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz",
+ "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==",
"cpu": [
- "ia32"
+ "x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "win32"
+ "android"
],
"engines": {
"node": ">=18"
}
},
- "node_modules/@esbuild/win32-x64": {
+ "node_modules/@esbuild/darwin-arm64": {
"version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz",
- "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz",
+ "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==",
"cpu": [
- "x64"
+ "arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "win32"
+ "darwin"
],
"engines": {
"node": ">=18"
}
},
- "node_modules/@expo/cli": {
- "version": "54.0.23",
- "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.23.tgz",
- "integrity": "sha512-km0h72SFfQCmVycH/JtPFTVy69w6Lx1cHNDmfLfQqgKFYeeHTjx7LVDP4POHCtNxFP2UeRazrygJhlh4zz498g==",
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz",
+ "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@0no-co/graphql.web": "^1.0.8",
- "@expo/code-signing-certificates": "^0.0.6",
- "@expo/config": "~12.0.13",
- "@expo/config-plugins": "~54.0.4",
- "@expo/devcert": "^1.2.1",
- "@expo/env": "~2.0.8",
- "@expo/image-utils": "^0.8.8",
- "@expo/json-file": "^10.0.8",
- "@expo/metro": "~54.2.0",
- "@expo/metro-config": "~54.0.14",
- "@expo/osascript": "^2.3.8",
- "@expo/package-manager": "^1.9.10",
- "@expo/plist": "^0.4.8",
- "@expo/prebuild-config": "^54.0.8",
- "@expo/schema-utils": "^0.1.8",
- "@expo/spawn-async": "^1.7.2",
- "@expo/ws-tunnel": "^1.0.1",
- "@expo/xcpretty": "^4.3.0",
- "@react-native/dev-middleware": "0.81.5",
- "@urql/core": "^5.0.6",
- "@urql/exchange-retry": "^1.3.0",
- "accepts": "^1.3.8",
- "arg": "^5.0.2",
- "better-opn": "~3.0.2",
- "bplist-creator": "0.1.0",
- "bplist-parser": "^0.3.1",
- "chalk": "^4.0.0",
- "ci-info": "^3.3.0",
- "compression": "^1.7.4",
- "connect": "^3.7.0",
- "debug": "^4.3.4",
- "env-editor": "^0.4.1",
- "expo-server": "^1.0.5",
- "freeport-async": "^2.0.0",
- "getenv": "^2.0.0",
- "glob": "^13.0.0",
- "lan-network": "^0.1.6",
- "minimatch": "^9.0.0",
- "node-forge": "^1.3.3",
- "npm-package-arg": "^11.0.0",
- "ora": "^3.4.0",
- "picomatch": "^3.0.1",
- "pretty-bytes": "^5.6.0",
- "pretty-format": "^29.7.0",
- "progress": "^2.0.3",
- "prompts": "^2.3.2",
- "qrcode-terminal": "0.11.0",
- "require-from-string": "^2.0.2",
- "requireg": "^0.2.2",
- "resolve": "^1.22.2",
- "resolve-from": "^5.0.0",
- "resolve.exports": "^2.0.3",
- "semver": "^7.6.0",
- "send": "^0.19.0",
- "slugify": "^1.3.4",
- "source-map-support": "~0.5.21",
- "stacktrace-parser": "^0.1.10",
- "structured-headers": "^0.4.1",
- "tar": "^7.5.2",
- "terminal-link": "^2.1.1",
- "undici": "^6.18.2",
- "wrap-ansi": "^7.0.0",
- "ws": "^8.12.1"
- },
- "bin": {
- "expo-internal": "build/bin/cli"
- },
- "peerDependencies": {
- "expo": "*",
- "expo-router": "*",
- "react-native": "*"
- },
- "peerDependenciesMeta": {
- "expo-router": {
- "optional": true
- },
- "react-native": {
- "optional": true
- }
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/cli/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "node": ">=18"
}
},
- "node_modules/@expo/cli/node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz",
+ "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": ">=18"
}
},
- "node_modules/@expo/cli/node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "license": "MIT"
- },
- "node_modules/@expo/cli/node_modules/semver": {
- "version": "7.7.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
- "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz",
+ "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=10"
+ "node": ">=18"
}
},
- "node_modules/@expo/code-signing-certificates": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz",
- "integrity": "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==",
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz",
+ "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "node-forge": "^1.3.3"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/config": {
- "version": "12.0.13",
- "resolved": "https://registry.npmjs.org/@expo/config/-/config-12.0.13.tgz",
- "integrity": "sha512-Cu52arBa4vSaupIWsF0h7F/Cg//N374nYb7HAxV0I4KceKA7x2UXpYaHOL7EEYYvp7tZdThBjvGpVmr8ScIvaQ==",
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz",
+ "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@babel/code-frame": "~7.10.4",
- "@expo/config-plugins": "~54.0.4",
- "@expo/config-types": "^54.0.10",
- "@expo/json-file": "^10.0.8",
- "deepmerge": "^4.3.1",
- "getenv": "^2.0.0",
- "glob": "^13.0.0",
- "require-from-string": "^2.0.2",
- "resolve-from": "^5.0.0",
- "resolve-workspace-root": "^2.0.0",
- "semver": "^7.6.0",
- "slugify": "^1.3.4",
- "sucrase": "~3.35.1"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/config-plugins": {
- "version": "54.0.4",
- "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-54.0.4.tgz",
- "integrity": "sha512-g2yXGICdoOw5i3LkQSDxl2Q5AlQCrG7oniu0pCPPO+UxGb7He4AFqSvPSy8HpRUj55io17hT62FTjYRD+d6j3Q==",
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz",
+ "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@expo/config-types": "^54.0.10",
- "@expo/json-file": "~10.0.8",
- "@expo/plist": "^0.4.8",
- "@expo/sdk-runtime-versions": "^1.0.0",
- "chalk": "^4.1.2",
- "debug": "^4.3.5",
- "getenv": "^2.0.0",
- "glob": "^13.0.0",
- "resolve-from": "^5.0.0",
- "semver": "^7.5.4",
- "slash": "^3.0.0",
- "slugify": "^1.6.6",
- "xcode": "^3.0.1",
- "xml2js": "0.6.0"
- }
- },
- "node_modules/@expo/config-plugins/node_modules/semver": {
- "version": "7.7.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
- "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=10"
+ "node": ">=18"
}
},
- "node_modules/@expo/config-types": {
- "version": "54.0.10",
- "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-54.0.10.tgz",
- "integrity": "sha512-/J16SC2an1LdtCZ67xhSkGXpALYUVUNyZws7v+PVsFZxClYehDSoKLqyRaGkpHlYrCc08bS0RF5E0JV6g50psA==",
- "license": "MIT"
- },
- "node_modules/@expo/config/node_modules/@babel/code-frame": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
- "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
- "license": "MIT",
- "dependencies": {
- "@babel/highlight": "^7.10.4"
- }
- },
- "node_modules/@expo/config/node_modules/semver": {
- "version": "7.7.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
- "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz",
+ "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=10"
+ "node": ">=18"
}
},
- "node_modules/@expo/devcert": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.2.1.tgz",
- "integrity": "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==",
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz",
+ "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@expo/sudo-prompt": "^9.3.1",
- "debug": "^3.1.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/devcert/node_modules/debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz",
+ "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "ms": "^2.1.1"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/devtools": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/@expo/devtools/-/devtools-0.1.8.tgz",
- "integrity": "sha512-SVLxbuanDjJPgc0sy3EfXUMLb/tXzp6XIHkhtPVmTWJAp+FOr6+5SeiCfJrCzZFet0Ifyke2vX3sFcKwEvCXwQ==",
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz",
+ "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "chalk": "^4.1.2"
- },
- "peerDependencies": {
- "react": "*",
- "react-native": "*"
- },
- "peerDependenciesMeta": {
- "react": {
- "optional": true
- },
- "react-native": {
- "optional": true
- }
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/env": {
- "version": "2.0.11",
- "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.0.11.tgz",
- "integrity": "sha512-xV+ps6YCW7XIPVUwFVCRN2nox09dnRwy8uIjwHWTODu0zFw4kp4omnVkl0OOjuu2XOe7tdgAHxikrkJt9xB/7Q==",
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz",
+ "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "debug": "^4.3.4",
- "dotenv": "~16.4.5",
- "dotenv-expand": "~11.0.6",
- "getenv": "^2.0.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/fingerprint": {
- "version": "0.15.4",
- "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.15.4.tgz",
- "integrity": "sha512-eYlxcrGdR2/j2M6pEDXo9zU9KXXF1vhP+V+Tl+lyY+bU8lnzrN6c637mz6Ye3em2ANy8hhUR03Raf8VsT9Ogng==",
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@expo/spawn-async": "^1.7.2",
- "arg": "^5.0.2",
- "chalk": "^4.1.2",
- "debug": "^4.3.4",
- "getenv": "^2.0.0",
- "glob": "^13.0.0",
- "ignore": "^5.3.1",
- "minimatch": "^9.0.0",
- "p-limit": "^3.1.0",
- "resolve-from": "^5.0.0",
- "semver": "^7.6.0"
- },
- "bin": {
- "fingerprint": "bin/cli.js"
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/fingerprint/node_modules/semver": {
- "version": "7.7.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
- "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz",
+ "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
"engines": {
- "node": ">=10"
+ "node": ">=18"
}
},
- "node_modules/@expo/image-utils": {
- "version": "0.8.12",
- "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.12.tgz",
- "integrity": "sha512-3KguH7kyKqq7pNwLb9j6BBdD/bjmNwXZG/HPWT6GWIXbwrvAJt2JNyYTP5agWJ8jbbuys1yuCzmkX+TU6rmI7A==",
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@expo/spawn-async": "^1.7.2",
- "chalk": "^4.0.0",
- "getenv": "^2.0.0",
- "jimp-compact": "0.16.1",
- "parse-png": "^2.1.0",
- "resolve-from": "^5.0.0",
- "semver": "^7.6.0"
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/image-utils/node_modules/semver": {
- "version": "7.7.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
- "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz",
+ "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
"engines": {
- "node": ">=10"
+ "node": ">=18"
}
},
- "node_modules/@expo/json-file": {
- "version": "10.0.13",
- "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.13.tgz",
- "integrity": "sha512-pX/XjQn7tgNw6zuuV2ikmegmwe/S7uiwhrs2wXrANMkq7ozrA+JcZwgW9Q/8WZgciBzfAhNp5hnackHcrmapQA==",
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz",
+ "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.20.0",
- "json5": "^2.2.3"
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/metro": {
- "version": "54.2.0",
- "resolved": "https://registry.npmjs.org/@expo/metro/-/metro-54.2.0.tgz",
- "integrity": "sha512-h68TNZPGsk6swMmLm9nRSnE2UXm48rWwgcbtAHVMikXvbxdS41NDHHeqg1rcQ9AbznDRp6SQVC2MVpDnsRKU1w==",
- "license": "MIT",
- "dependencies": {
- "metro": "0.83.3",
- "metro-babel-transformer": "0.83.3",
- "metro-cache": "0.83.3",
- "metro-cache-key": "0.83.3",
- "metro-config": "0.83.3",
- "metro-core": "0.83.3",
- "metro-file-map": "0.83.3",
- "metro-minify-terser": "0.83.3",
- "metro-resolver": "0.83.3",
- "metro-runtime": "0.83.3",
- "metro-source-map": "0.83.3",
- "metro-symbolicate": "0.83.3",
- "metro-transform-plugins": "0.83.3",
- "metro-transform-worker": "0.83.3"
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz",
+ "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/metro-config": {
- "version": "54.0.14",
- "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.14.tgz",
- "integrity": "sha512-hxpLyDfOR4L23tJ9W1IbJJsG7k4lv2sotohBm/kTYyiG+pe1SYCAWsRmgk+H42o/wWf/HQjE5k45S5TomGLxNA==",
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz",
+ "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.20.0",
- "@babel/core": "^7.20.0",
- "@babel/generator": "^7.20.5",
- "@expo/config": "~12.0.13",
- "@expo/env": "~2.0.8",
- "@expo/json-file": "~10.0.8",
- "@expo/metro": "~54.2.0",
- "@expo/spawn-async": "^1.7.2",
- "browserslist": "^4.25.0",
- "chalk": "^4.1.0",
- "debug": "^4.3.2",
- "dotenv": "~16.4.5",
- "dotenv-expand": "~11.0.6",
- "getenv": "^2.0.0",
- "glob": "^13.0.0",
- "hermes-parser": "^0.29.1",
- "jsc-safe-url": "^0.2.4",
- "lightningcss": "^1.30.1",
- "minimatch": "^9.0.0",
- "postcss": "~8.4.32",
- "resolve-from": "^5.0.0"
- },
- "peerDependencies": {
- "expo": "*"
- },
- "peerDependenciesMeta": {
- "expo": {
- "optional": true
- }
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@expo/metro-config/node_modules/postcss": {
- "version": "8.4.49",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
- "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz",
+ "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==",
+ "cpu": [
+ "ia32"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
+ "optional": true,
+ "os": [
+ "win32"
+ ],
"engines": {
- "node": "^10 || ^12 || >=14"
+ "node": ">=18"
}
},
- "node_modules/@expo/metro-runtime": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-6.1.2.tgz",
- "integrity": "sha512-nvM+Qv45QH7pmYvP8JB1G8JpScrWND3KrMA6ZKe62cwwNiX/BjHU28Ear0v/4bQWXlOY0mv6B8CDIm8JxXde9g==",
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz",
+ "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@expo/cli": {
+ "version": "54.0.23",
+ "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.23.tgz",
+ "integrity": "sha512-km0h72SFfQCmVycH/JtPFTVy69w6Lx1cHNDmfLfQqgKFYeeHTjx7LVDP4POHCtNxFP2UeRazrygJhlh4zz498g==",
"license": "MIT",
"dependencies": {
- "anser": "^1.4.9",
+ "@0no-co/graphql.web": "^1.0.8",
+ "@expo/code-signing-certificates": "^0.0.6",
+ "@expo/config": "~12.0.13",
+ "@expo/config-plugins": "~54.0.4",
+ "@expo/devcert": "^1.2.1",
+ "@expo/env": "~2.0.8",
+ "@expo/image-utils": "^0.8.8",
+ "@expo/json-file": "^10.0.8",
+ "@expo/metro": "~54.2.0",
+ "@expo/metro-config": "~54.0.14",
+ "@expo/osascript": "^2.3.8",
+ "@expo/package-manager": "^1.9.10",
+ "@expo/plist": "^0.4.8",
+ "@expo/prebuild-config": "^54.0.8",
+ "@expo/schema-utils": "^0.1.8",
+ "@expo/spawn-async": "^1.7.2",
+ "@expo/ws-tunnel": "^1.0.1",
+ "@expo/xcpretty": "^4.3.0",
+ "@react-native/dev-middleware": "0.81.5",
+ "@urql/core": "^5.0.6",
+ "@urql/exchange-retry": "^1.3.0",
+ "accepts": "^1.3.8",
+ "arg": "^5.0.2",
+ "better-opn": "~3.0.2",
+ "bplist-creator": "0.1.0",
+ "bplist-parser": "^0.3.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.3.0",
+ "compression": "^1.7.4",
+ "connect": "^3.7.0",
+ "debug": "^4.3.4",
+ "env-editor": "^0.4.1",
+ "expo-server": "^1.0.5",
+ "freeport-async": "^2.0.0",
+ "getenv": "^2.0.0",
+ "glob": "^13.0.0",
+ "lan-network": "^0.1.6",
+ "minimatch": "^9.0.0",
+ "node-forge": "^1.3.3",
+ "npm-package-arg": "^11.0.0",
+ "ora": "^3.4.0",
+ "picomatch": "^3.0.1",
+ "pretty-bytes": "^5.6.0",
"pretty-format": "^29.7.0",
+ "progress": "^2.0.3",
+ "prompts": "^2.3.2",
+ "qrcode-terminal": "0.11.0",
+ "require-from-string": "^2.0.2",
+ "requireg": "^0.2.2",
+ "resolve": "^1.22.2",
+ "resolve-from": "^5.0.0",
+ "resolve.exports": "^2.0.3",
+ "semver": "^7.6.0",
+ "send": "^0.19.0",
+ "slugify": "^1.3.4",
+ "source-map-support": "~0.5.21",
"stacktrace-parser": "^0.1.10",
- "whatwg-fetch": "^3.0.0"
+ "structured-headers": "^0.4.1",
+ "tar": "^7.5.2",
+ "terminal-link": "^2.1.1",
+ "undici": "^6.18.2",
+ "wrap-ansi": "^7.0.0",
+ "ws": "^8.12.1"
+ },
+ "bin": {
+ "expo-internal": "build/bin/cli"
},
"peerDependencies": {
"expo": "*",
- "react": "*",
- "react-dom": "*",
+ "expo-router": "*",
"react-native": "*"
},
"peerDependenciesMeta": {
- "react-dom": {
+ "expo-router": {
+ "optional": true
+ },
+ "react-native": {
"optional": true
}
}
},
- "node_modules/@expo/metro-runtime/node_modules/ansi-styles": {
+ "node_modules/@expo/cli/node_modules/ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
@@ -2709,7 +2975,7 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/@expo/metro-runtime/node_modules/pretty-format": {
+ "node_modules/@expo/cli/node_modules/pretty-format": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
"integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
@@ -2723,71 +2989,77 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/@expo/metro-runtime/node_modules/react-is": {
+ "node_modules/@expo/cli/node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
"license": "MIT"
},
- "node_modules/@expo/osascript": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.4.2.tgz",
- "integrity": "sha512-/XP7PSYF2hzOZzqfjgkoWtllyeTN8dW3aM4P6YgKcmmPikKL5FdoyQhti4eh6RK5a5VrUXJTOlTNIpIHsfB5Iw==",
- "license": "MIT",
- "dependencies": {
- "@expo/spawn-async": "^1.7.2"
+ "node_modules/@expo/cli/node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
},
"engines": {
- "node": ">=12"
+ "node": ">=10"
}
},
- "node_modules/@expo/package-manager": {
- "version": "1.10.3",
- "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.10.3.tgz",
- "integrity": "sha512-ZuXiK/9fCrIuLjPSe1VYmfp0Sa85kCMwd8QQpgyi5ufppYKRtLBg14QOgUqj8ZMbJTxE0xqzd0XR7kOs3vAK9A==",
+ "node_modules/@expo/code-signing-certificates": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz",
+ "integrity": "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==",
"license": "MIT",
"dependencies": {
- "@expo/json-file": "^10.0.12",
- "@expo/spawn-async": "^1.7.2",
- "chalk": "^4.0.0",
- "npm-package-arg": "^11.0.0",
- "ora": "^3.4.0",
- "resolve-workspace-root": "^2.0.0"
+ "node-forge": "^1.3.3"
}
},
- "node_modules/@expo/plist": {
- "version": "0.4.8",
- "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.8.tgz",
- "integrity": "sha512-pfNtErGGzzRwHP+5+RqswzPDKkZrx+Cli0mzjQaus1ZWFsog5ibL+nVT3NcporW51o8ggnt7x813vtRbPiyOrQ==",
+ "node_modules/@expo/config": {
+ "version": "12.0.13",
+ "resolved": "https://registry.npmjs.org/@expo/config/-/config-12.0.13.tgz",
+ "integrity": "sha512-Cu52arBa4vSaupIWsF0h7F/Cg//N374nYb7HAxV0I4KceKA7x2UXpYaHOL7EEYYvp7tZdThBjvGpVmr8ScIvaQ==",
"license": "MIT",
"dependencies": {
- "@xmldom/xmldom": "^0.8.8",
- "base64-js": "^1.2.3",
- "xmlbuilder": "^15.1.1"
+ "@babel/code-frame": "~7.10.4",
+ "@expo/config-plugins": "~54.0.4",
+ "@expo/config-types": "^54.0.10",
+ "@expo/json-file": "^10.0.8",
+ "deepmerge": "^4.3.1",
+ "getenv": "^2.0.0",
+ "glob": "^13.0.0",
+ "require-from-string": "^2.0.2",
+ "resolve-from": "^5.0.0",
+ "resolve-workspace-root": "^2.0.0",
+ "semver": "^7.6.0",
+ "slugify": "^1.3.4",
+ "sucrase": "~3.35.1"
}
},
- "node_modules/@expo/prebuild-config": {
- "version": "54.0.8",
- "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.8.tgz",
- "integrity": "sha512-EA7N4dloty2t5Rde+HP0IEE+nkAQiu4A/+QGZGT9mFnZ5KKjPPkqSyYcRvP5bhQE10D+tvz6X0ngZpulbMdbsg==",
+ "node_modules/@expo/config-plugins": {
+ "version": "54.0.4",
+ "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-54.0.4.tgz",
+ "integrity": "sha512-g2yXGICdoOw5i3LkQSDxl2Q5AlQCrG7oniu0pCPPO+UxGb7He4AFqSvPSy8HpRUj55io17hT62FTjYRD+d6j3Q==",
"license": "MIT",
"dependencies": {
- "@expo/config": "~12.0.13",
- "@expo/config-plugins": "~54.0.4",
"@expo/config-types": "^54.0.10",
- "@expo/image-utils": "^0.8.8",
- "@expo/json-file": "^10.0.8",
- "@react-native/normalize-colors": "0.81.5",
- "debug": "^4.3.1",
+ "@expo/json-file": "~10.0.8",
+ "@expo/plist": "^0.4.8",
+ "@expo/sdk-runtime-versions": "^1.0.0",
+ "chalk": "^4.1.2",
+ "debug": "^4.3.5",
+ "getenv": "^2.0.0",
+ "glob": "^13.0.0",
"resolve-from": "^5.0.0",
- "semver": "^7.6.0",
+ "semver": "^7.5.4",
+ "slash": "^3.0.0",
+ "slugify": "^1.6.6",
+ "xcode": "^3.0.1",
"xml2js": "0.6.0"
- },
- "peerDependencies": {
- "expo": "*"
}
},
- "node_modules/@expo/prebuild-config/node_modules/semver": {
+ "node_modules/@expo/config-plugins/node_modules/semver": {
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
@@ -2799,526 +3071,597 @@
"node": ">=10"
}
},
- "node_modules/@expo/schema-utils": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-0.1.8.tgz",
- "integrity": "sha512-9I6ZqvnAvKKDiO+ZF8BpQQFYWXOJvTAL5L/227RUbWG1OVZDInFifzCBiqAZ3b67NRfeAgpgvbA7rejsqhY62A==",
- "license": "MIT"
- },
- "node_modules/@expo/sdk-runtime-versions": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz",
- "integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==",
+ "node_modules/@expo/config-types": {
+ "version": "54.0.10",
+ "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-54.0.10.tgz",
+ "integrity": "sha512-/J16SC2an1LdtCZ67xhSkGXpALYUVUNyZws7v+PVsFZxClYehDSoKLqyRaGkpHlYrCc08bS0RF5E0JV6g50psA==",
"license": "MIT"
},
- "node_modules/@expo/spawn-async": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.7.2.tgz",
- "integrity": "sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==",
+ "node_modules/@expo/config/node_modules/@babel/code-frame": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+ "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
"license": "MIT",
"dependencies": {
- "cross-spawn": "^7.0.3"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@expo/sudo-prompt": {
- "version": "9.3.2",
- "resolved": "https://registry.npmjs.org/@expo/sudo-prompt/-/sudo-prompt-9.3.2.tgz",
- "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==",
- "license": "MIT"
- },
- "node_modules/@expo/vector-icons": {
- "version": "15.1.1",
- "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.1.1.tgz",
- "integrity": "sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw==",
- "license": "MIT",
- "peerDependencies": {
- "expo-font": ">=14.0.4",
- "react": "*",
- "react-native": "*"
+ "@babel/highlight": "^7.10.4"
}
},
- "node_modules/@expo/ws-tunnel": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.6.tgz",
- "integrity": "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==",
- "license": "MIT"
- },
- "node_modules/@expo/xcpretty": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.1.tgz",
- "integrity": "sha512-KZNxZvnGCtiM2aYYZ6Wz0Ix5r47dAvpNLApFtZWnSoERzAdOMzVBOPysBoM0JlF6FKWZ8GPqgn6qt3dV/8Zlpg==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "@babel/code-frame": "^7.20.0",
- "chalk": "^4.1.0",
- "js-yaml": "^4.1.0"
- },
+ "node_modules/@expo/config/node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "license": "ISC",
"bin": {
- "excpretty": "build/cli.js"
- }
- },
- "node_modules/@floating-ui/core": {
- "version": "1.7.5",
- "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
- "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/utils": "^0.2.11"
- }
- },
- "node_modules/@floating-ui/dom": {
- "version": "1.7.6",
- "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
- "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/core": "^1.7.5",
- "@floating-ui/utils": "^0.2.11"
- }
- },
- "node_modules/@floating-ui/react-dom": {
- "version": "2.1.8",
- "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz",
- "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/dom": "^1.7.6"
+ "semver": "bin/semver.js"
},
- "peerDependencies": {
- "react": ">=16.8.0",
- "react-dom": ">=16.8.0"
- }
- },
- "node_modules/@floating-ui/utils": {
- "version": "0.2.11",
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
- "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
- "license": "MIT"
- },
- "node_modules/@formatjs/bigdecimal": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@formatjs/bigdecimal/-/bigdecimal-0.2.0.tgz",
- "integrity": "sha512-GeaxHZbUoYvHL9tC5eltHLs+1zU70aPw0s7LwqgktIzF5oMhNY4o4deEtusJMsq7WFJF3Ye2zQEzdG8beVk73w==",
- "license": "MIT"
- },
- "node_modules/@formatjs/ecma402-abstract": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-3.2.0.tgz",
- "integrity": "sha512-dHnqHgBo6GXYGRsepaE1wmsC2etaivOWd5VaJstZd+HI2zR3DCUjbDVZRtoPGkkXZmyHvBwrdEUuqfvzhF/DtQ==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/bigdecimal": "0.2.0",
- "@formatjs/fast-memoize": "3.1.1",
- "@formatjs/intl-localematcher": "0.8.2"
- }
- },
- "node_modules/@formatjs/fast-memoize": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.1.tgz",
- "integrity": "sha512-CbNbf+tlJn1baRnPkNePnBqTLxGliG6DDgNa/UtV66abwIjwsliPMOt0172tzxABYzSuxZBZfcp//qI8AvBWPg==",
- "license": "MIT"
- },
- "node_modules/@formatjs/icu-messageformat-parser": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.3.tgz",
- "integrity": "sha512-HJWZ9S6JWey6iY5+YXE3Kd0ofWU1sC2KTTp56e1168g/xxWvVvr8k9G4fexIgwYV9wbtjY7kGYK5FjoWB3B2OQ==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/ecma402-abstract": "3.2.0",
- "@formatjs/icu-skeleton-parser": "2.1.3"
+ "engines": {
+ "node": ">=10"
}
},
- "node_modules/@formatjs/icu-skeleton-parser": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.3.tgz",
- "integrity": "sha512-9mFp8TJ166ZM2pcjKwsBWXrDnOJGT7vMEScVgLygUODPOsE8S6f/FHoacvrlHK1B4dYZk8vSCNruyPU64AfgJQ==",
+ "node_modules/@expo/devcert": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.2.1.tgz",
+ "integrity": "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==",
"license": "MIT",
"dependencies": {
- "@formatjs/ecma402-abstract": "3.2.0"
+ "@expo/sudo-prompt": "^9.3.1",
+ "debug": "^3.1.0"
}
},
- "node_modules/@formatjs/intl-localematcher": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.8.2.tgz",
- "integrity": "sha512-q05KMYGJLyqFNFtIb8NhWLF5X3aK/k0wYt7dnRFuy6aLQL+vUwQ1cg5cO4qawEiINybeCPXAWlprY2mSBjSXAQ==",
+ "node_modules/@expo/devcert/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"license": "MIT",
"dependencies": {
- "@formatjs/fast-memoize": "3.1.1"
+ "ms": "^2.1.1"
}
},
- "node_modules/@gorhom/bottom-sheet": {
- "version": "5.2.8",
- "resolved": "https://registry.npmjs.org/@gorhom/bottom-sheet/-/bottom-sheet-5.2.8.tgz",
- "integrity": "sha512-+N27SMpbBxXZQ/IA2nlEV6RGxL/qSFHKfdFKcygvW+HqPG5jVNb1OqehLQsGfBP+Up42i0gW5ppI+DhpB7UCzA==",
+ "node_modules/@expo/devtools": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/@expo/devtools/-/devtools-0.1.8.tgz",
+ "integrity": "sha512-SVLxbuanDjJPgc0sy3EfXUMLb/tXzp6XIHkhtPVmTWJAp+FOr6+5SeiCfJrCzZFet0Ifyke2vX3sFcKwEvCXwQ==",
"license": "MIT",
"dependencies": {
- "@gorhom/portal": "1.0.14",
- "invariant": "^2.2.4"
+ "chalk": "^4.1.2"
},
"peerDependencies": {
- "@types/react": "*",
- "@types/react-native": "*",
"react": "*",
- "react-native": "*",
- "react-native-gesture-handler": ">=2.16.1",
- "react-native-reanimated": ">=3.16.0 || >=4.0.0-"
+ "react-native": "*"
},
"peerDependenciesMeta": {
- "@types/react": {
+ "react": {
"optional": true
},
- "@types/react-native": {
+ "react-native": {
"optional": true
}
}
},
- "node_modules/@gorhom/portal": {
- "version": "1.0.14",
- "resolved": "https://registry.npmjs.org/@gorhom/portal/-/portal-1.0.14.tgz",
- "integrity": "sha512-MXyL4xvCjmgaORr/rtryDNFy3kU4qUbKlwtQqqsygd0xX3mhKjOLn6mQK8wfu0RkoE0pBE0nAasRoHua+/QZ7A==",
+ "node_modules/@expo/env": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.0.11.tgz",
+ "integrity": "sha512-xV+ps6YCW7XIPVUwFVCRN2nox09dnRwy8uIjwHWTODu0zFw4kp4omnVkl0OOjuu2XOe7tdgAHxikrkJt9xB/7Q==",
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.1"
- },
- "peerDependencies": {
- "react": "*",
- "react-native": "*"
+ "chalk": "^4.0.0",
+ "debug": "^4.3.4",
+ "dotenv": "~16.4.5",
+ "dotenv-expand": "~11.0.6",
+ "getenv": "^2.0.0"
}
},
- "node_modules/@hookform/resolvers": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-4.1.3.tgz",
- "integrity": "sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ==",
+ "node_modules/@expo/fingerprint": {
+ "version": "0.15.4",
+ "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.15.4.tgz",
+ "integrity": "sha512-eYlxcrGdR2/j2M6pEDXo9zU9KXXF1vhP+V+Tl+lyY+bU8lnzrN6c637mz6Ye3em2ANy8hhUR03Raf8VsT9Ogng==",
"license": "MIT",
"dependencies": {
- "@standard-schema/utils": "^0.3.0"
- },
- "peerDependencies": {
- "react-hook-form": "^7.0.0"
+ "@expo/spawn-async": "^1.7.2",
+ "arg": "^5.0.2",
+ "chalk": "^4.1.2",
+ "debug": "^4.3.4",
+ "getenv": "^2.0.0",
+ "glob": "^13.0.0",
+ "ignore": "^5.3.1",
+ "minimatch": "^9.0.0",
+ "p-limit": "^3.1.0",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.6.0"
+ },
+ "bin": {
+ "fingerprint": "bin/cli.js"
}
},
- "node_modules/@ide/backoff": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@ide/backoff/-/backoff-1.0.0.tgz",
- "integrity": "sha512-F0YfUDjvT+Mtt/R4xdl2X0EYCHMMiJqNLdxHD++jDT5ydEFIyqbCHh51Qx2E211dgZprPKhV7sHmnXKpLuvc5g==",
- "license": "MIT"
+ "node_modules/@expo/fingerprint/node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
},
- "node_modules/@img/colour": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
- "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
+ "node_modules/@expo/image-utils": {
+ "version": "0.8.12",
+ "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.12.tgz",
+ "integrity": "sha512-3KguH7kyKqq7pNwLb9j6BBdD/bjmNwXZG/HPWT6GWIXbwrvAJt2JNyYTP5agWJ8jbbuys1yuCzmkX+TU6rmI7A==",
"license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@expo/spawn-async": "^1.7.2",
+ "chalk": "^4.0.0",
+ "getenv": "^2.0.0",
+ "jimp-compact": "0.16.1",
+ "parse-png": "^2.1.0",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.6.0"
}
},
- "node_modules/@img/sharp-darwin-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
- "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
+ "node_modules/@expo/image-utils/node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=10"
+ }
+ },
+ "node_modules/@expo/json-file": {
+ "version": "10.0.13",
+ "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.13.tgz",
+ "integrity": "sha512-pX/XjQn7tgNw6zuuV2ikmegmwe/S7uiwhrs2wXrANMkq7ozrA+JcZwgW9Q/8WZgciBzfAhNp5hnackHcrmapQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.20.0",
+ "json5": "^2.2.3"
+ }
+ },
+ "node_modules/@expo/metro": {
+ "version": "54.2.0",
+ "resolved": "https://registry.npmjs.org/@expo/metro/-/metro-54.2.0.tgz",
+ "integrity": "sha512-h68TNZPGsk6swMmLm9nRSnE2UXm48rWwgcbtAHVMikXvbxdS41NDHHeqg1rcQ9AbznDRp6SQVC2MVpDnsRKU1w==",
+ "license": "MIT",
+ "dependencies": {
+ "metro": "0.83.3",
+ "metro-babel-transformer": "0.83.3",
+ "metro-cache": "0.83.3",
+ "metro-cache-key": "0.83.3",
+ "metro-config": "0.83.3",
+ "metro-core": "0.83.3",
+ "metro-file-map": "0.83.3",
+ "metro-minify-terser": "0.83.3",
+ "metro-resolver": "0.83.3",
+ "metro-runtime": "0.83.3",
+ "metro-source-map": "0.83.3",
+ "metro-symbolicate": "0.83.3",
+ "metro-transform-plugins": "0.83.3",
+ "metro-transform-worker": "0.83.3"
+ }
+ },
+ "node_modules/@expo/metro-config": {
+ "version": "54.0.14",
+ "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.14.tgz",
+ "integrity": "sha512-hxpLyDfOR4L23tJ9W1IbJJsG7k4lv2sotohBm/kTYyiG+pe1SYCAWsRmgk+H42o/wWf/HQjE5k45S5TomGLxNA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.20.0",
+ "@babel/core": "^7.20.0",
+ "@babel/generator": "^7.20.5",
+ "@expo/config": "~12.0.13",
+ "@expo/env": "~2.0.8",
+ "@expo/json-file": "~10.0.8",
+ "@expo/metro": "~54.2.0",
+ "@expo/spawn-async": "^1.7.2",
+ "browserslist": "^4.25.0",
+ "chalk": "^4.1.0",
+ "debug": "^4.3.2",
+ "dotenv": "~16.4.5",
+ "dotenv-expand": "~11.0.6",
+ "getenv": "^2.0.0",
+ "glob": "^13.0.0",
+ "hermes-parser": "^0.29.1",
+ "jsc-safe-url": "^0.2.4",
+ "lightningcss": "^1.30.1",
+ "minimatch": "^9.0.0",
+ "postcss": "~8.4.32",
+ "resolve-from": "^5.0.0"
},
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "peerDependencies": {
+ "expo": "*"
},
- "optionalDependencies": {
- "@img/sharp-libvips-darwin-arm64": "1.2.4"
+ "peerDependenciesMeta": {
+ "expo": {
+ "optional": true
+ }
}
},
- "node_modules/@img/sharp-darwin-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
- "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
+ "node_modules/@expo/metro-config/node_modules/postcss": {
+ "version": "8.4.49",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
+ "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/@expo/metro-runtime": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-6.1.2.tgz",
+ "integrity": "sha512-nvM+Qv45QH7pmYvP8JB1G8JpScrWND3KrMA6ZKe62cwwNiX/BjHU28Ear0v/4bQWXlOY0mv6B8CDIm8JxXde9g==",
+ "license": "MIT",
+ "dependencies": {
+ "anser": "^1.4.9",
+ "pretty-format": "^29.7.0",
+ "stacktrace-parser": "^0.1.10",
+ "whatwg-fetch": "^3.0.0"
},
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "peerDependencies": {
+ "expo": "*",
+ "react": "*",
+ "react-dom": "*",
+ "react-native": "*"
},
- "optionalDependencies": {
- "@img/sharp-libvips-darwin-x64": "1.2.4"
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@img/sharp-libvips-darwin-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
- "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
+ "node_modules/@expo/metro-runtime/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
"funding": {
- "url": "https://opencollective.com/libvips"
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/@img/sharp-libvips-darwin-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
- "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "node_modules/@expo/metro-runtime/node_modules/pretty-format": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
+ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/@img/sharp-libvips-linux-arm": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
- "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
- "cpu": [
- "arm"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
+ "node_modules/@expo/metro-runtime/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "license": "MIT"
},
- "node_modules/@img/sharp-libvips-linux-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
- "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "node_modules/@expo/osascript": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.4.2.tgz",
+ "integrity": "sha512-/XP7PSYF2hzOZzqfjgkoWtllyeTN8dW3aM4P6YgKcmmPikKL5FdoyQhti4eh6RK5a5VrUXJTOlTNIpIHsfB5Iw==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/spawn-async": "^1.7.2"
+ },
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/@img/sharp-libvips-linux-ppc64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
- "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
- "cpu": [
- "ppc64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "node_modules/@expo/package-manager": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.10.3.tgz",
+ "integrity": "sha512-ZuXiK/9fCrIuLjPSe1VYmfp0Sa85kCMwd8QQpgyi5ufppYKRtLBg14QOgUqj8ZMbJTxE0xqzd0XR7kOs3vAK9A==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/json-file": "^10.0.12",
+ "@expo/spawn-async": "^1.7.2",
+ "chalk": "^4.0.0",
+ "npm-package-arg": "^11.0.0",
+ "ora": "^3.4.0",
+ "resolve-workspace-root": "^2.0.0"
}
},
- "node_modules/@img/sharp-libvips-linux-riscv64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
- "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
- "cpu": [
- "riscv64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "node_modules/@expo/plist": {
+ "version": "0.4.8",
+ "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.8.tgz",
+ "integrity": "sha512-pfNtErGGzzRwHP+5+RqswzPDKkZrx+Cli0mzjQaus1ZWFsog5ibL+nVT3NcporW51o8ggnt7x813vtRbPiyOrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@xmldom/xmldom": "^0.8.8",
+ "base64-js": "^1.2.3",
+ "xmlbuilder": "^15.1.1"
}
},
- "node_modules/@img/sharp-libvips-linux-s390x": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
- "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
- "cpu": [
- "s390x"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "node_modules/@expo/prebuild-config": {
+ "version": "54.0.8",
+ "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.8.tgz",
+ "integrity": "sha512-EA7N4dloty2t5Rde+HP0IEE+nkAQiu4A/+QGZGT9mFnZ5KKjPPkqSyYcRvP5bhQE10D+tvz6X0ngZpulbMdbsg==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/config": "~12.0.13",
+ "@expo/config-plugins": "~54.0.4",
+ "@expo/config-types": "^54.0.10",
+ "@expo/image-utils": "^0.8.8",
+ "@expo/json-file": "^10.0.8",
+ "@react-native/normalize-colors": "0.81.5",
+ "debug": "^4.3.1",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.6.0",
+ "xml2js": "0.6.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
}
},
- "node_modules/@img/sharp-libvips-linux-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
- "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "node_modules/@expo/prebuild-config/node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
}
},
- "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
- "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "node_modules/@expo/schema-utils": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-0.1.8.tgz",
+ "integrity": "sha512-9I6ZqvnAvKKDiO+ZF8BpQQFYWXOJvTAL5L/227RUbWG1OVZDInFifzCBiqAZ3b67NRfeAgpgvbA7rejsqhY62A==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/sdk-runtime-versions": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz",
+ "integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/spawn-async": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.7.2.tgz",
+ "integrity": "sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==",
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/@img/sharp-libvips-linuxmusl-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
- "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "node_modules/@expo/sudo-prompt": {
+ "version": "9.3.2",
+ "resolved": "https://registry.npmjs.org/@expo/sudo-prompt/-/sudo-prompt-9.3.2.tgz",
+ "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/vector-icons": {
+ "version": "15.1.1",
+ "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.1.1.tgz",
+ "integrity": "sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "expo-font": ">=14.0.4",
+ "react": "*",
+ "react-native": "*"
}
},
- "node_modules/@img/sharp-linux-arm": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
- "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
- "cpu": [
- "arm"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node_modules/@expo/ws-tunnel": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.6.tgz",
+ "integrity": "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/xcpretty": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.1.tgz",
+ "integrity": "sha512-KZNxZvnGCtiM2aYYZ6Wz0Ix5r47dAvpNLApFtZWnSoERzAdOMzVBOPysBoM0JlF6FKWZ8GPqgn6qt3dV/8Zlpg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/code-frame": "^7.20.0",
+ "chalk": "^4.1.0",
+ "js-yaml": "^4.1.0"
},
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "bin": {
+ "excpretty": "build/cli.js"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
+ "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.11"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.7.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
+ "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.7.5",
+ "@floating-ui/utils": "^0.2.11"
+ }
+ },
+ "node_modules/@floating-ui/react-dom": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz",
+ "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.7.6"
},
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm": "1.2.4"
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
}
},
- "node_modules/@img/sharp-linux-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
- "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
+ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
+ "license": "MIT"
+ },
+ "node_modules/@formatjs/bigdecimal": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@formatjs/bigdecimal/-/bigdecimal-0.2.0.tgz",
+ "integrity": "sha512-GeaxHZbUoYvHL9tC5eltHLs+1zU70aPw0s7LwqgktIzF5oMhNY4o4deEtusJMsq7WFJF3Ye2zQEzdG8beVk73w==",
+ "license": "MIT"
+ },
+ "node_modules/@formatjs/ecma402-abstract": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-3.2.0.tgz",
+ "integrity": "sha512-dHnqHgBo6GXYGRsepaE1wmsC2etaivOWd5VaJstZd+HI2zR3DCUjbDVZRtoPGkkXZmyHvBwrdEUuqfvzhF/DtQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/bigdecimal": "0.2.0",
+ "@formatjs/fast-memoize": "3.1.1",
+ "@formatjs/intl-localematcher": "0.8.2"
+ }
+ },
+ "node_modules/@formatjs/fast-memoize": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.1.tgz",
+ "integrity": "sha512-CbNbf+tlJn1baRnPkNePnBqTLxGliG6DDgNa/UtV66abwIjwsliPMOt0172tzxABYzSuxZBZfcp//qI8AvBWPg==",
+ "license": "MIT"
+ },
+ "node_modules/@formatjs/icu-messageformat-parser": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.3.tgz",
+ "integrity": "sha512-HJWZ9S6JWey6iY5+YXE3Kd0ofWU1sC2KTTp56e1168g/xxWvVvr8k9G4fexIgwYV9wbtjY7kGYK5FjoWB3B2OQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "3.2.0",
+ "@formatjs/icu-skeleton-parser": "2.1.3"
+ }
+ },
+ "node_modules/@formatjs/icu-skeleton-parser": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.3.tgz",
+ "integrity": "sha512-9mFp8TJ166ZM2pcjKwsBWXrDnOJGT7vMEScVgLygUODPOsE8S6f/FHoacvrlHK1B4dYZk8vSCNruyPU64AfgJQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "3.2.0"
+ }
+ },
+ "node_modules/@formatjs/intl-localematcher": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.8.2.tgz",
+ "integrity": "sha512-q05KMYGJLyqFNFtIb8NhWLF5X3aK/k0wYt7dnRFuy6aLQL+vUwQ1cg5cO4qawEiINybeCPXAWlprY2mSBjSXAQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/fast-memoize": "3.1.1"
+ }
+ },
+ "node_modules/@gorhom/bottom-sheet": {
+ "version": "5.2.8",
+ "resolved": "https://registry.npmjs.org/@gorhom/bottom-sheet/-/bottom-sheet-5.2.8.tgz",
+ "integrity": "sha512-+N27SMpbBxXZQ/IA2nlEV6RGxL/qSFHKfdFKcygvW+HqPG5jVNb1OqehLQsGfBP+Up42i0gW5ppI+DhpB7UCzA==",
+ "license": "MIT",
+ "dependencies": {
+ "@gorhom/portal": "1.0.14",
+ "invariant": "^2.2.4"
},
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-native": "*",
+ "react": "*",
+ "react-native": "*",
+ "react-native-gesture-handler": ">=2.16.1",
+ "react-native-reanimated": ">=3.16.0 || >=4.0.0-"
},
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm64": "1.2.4"
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-native": {
+ "optional": true
+ }
}
},
- "node_modules/@img/sharp-linux-ppc64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
- "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
- "cpu": [
- "ppc64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node_modules/@gorhom/portal": {
+ "version": "1.0.14",
+ "resolved": "https://registry.npmjs.org/@gorhom/portal/-/portal-1.0.14.tgz",
+ "integrity": "sha512-MXyL4xvCjmgaORr/rtryDNFy3kU4qUbKlwtQqqsygd0xX3mhKjOLn6mQK8wfu0RkoE0pBE0nAasRoHua+/QZ7A==",
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.1"
},
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/@hookform/resolvers": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-4.1.3.tgz",
+ "integrity": "sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/utils": "^0.3.0"
},
- "optionalDependencies": {
- "@img/sharp-libvips-linux-ppc64": "1.2.4"
+ "peerDependencies": {
+ "react-hook-form": "^7.0.0"
}
},
- "node_modules/@img/sharp-linux-riscv64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
- "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
- "cpu": [
- "riscv64"
- ],
- "license": "Apache-2.0",
+ "node_modules/@ide/backoff": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@ide/backoff/-/backoff-1.0.0.tgz",
+ "integrity": "sha512-F0YfUDjvT+Mtt/R4xdl2X0EYCHMMiJqNLdxHD++jDT5ydEFIyqbCHh51Qx2E211dgZprPKhV7sHmnXKpLuvc5g==",
+ "license": "MIT"
+ },
+ "node_modules/@img/colour": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
+ "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
+ "license": "MIT",
"optional": true,
- "os": [
- "linux"
- ],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-riscv64": "1.2.4"
+ "node": ">=18"
}
},
- "node_modules/@img/sharp-linux-s390x": {
+ "node_modules/@img/sharp-darwin-arm64": {
"version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
- "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
+ "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
"cpu": [
- "s390x"
+ "arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
- "linux"
+ "darwin"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
@@ -3327,20 +3670,20 @@
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-s390x": "1.2.4"
+ "@img/sharp-libvips-darwin-arm64": "1.2.4"
}
},
- "node_modules/@img/sharp-linux-x64": {
+ "node_modules/@img/sharp-darwin-x64": {
"version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
- "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
+ "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
- "linux"
+ "darwin"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
@@ -3349,1559 +3692,1192 @@
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-x64": "1.2.4"
+ "@img/sharp-libvips-darwin-x64": "1.2.4"
}
},
- "node_modules/@img/sharp-linuxmusl-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
- "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
+ "node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
+ "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
"cpu": [
"arm64"
],
- "license": "Apache-2.0",
+ "license": "LGPL-3.0-or-later",
"optional": true,
"os": [
- "linux"
+ "darwin"
],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
"funding": {
"url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
}
},
- "node_modules/@img/sharp-linuxmusl-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
- "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
+ "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
"cpu": [
"x64"
],
- "license": "Apache-2.0",
+ "license": "LGPL-3.0-or-later",
"optional": true,
"os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-wasm32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
- "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
- "cpu": [
- "wasm32"
+ "darwin"
],
- "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/runtime": "^1.7.0"
- },
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
"funding": {
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/@img/sharp-win32-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
- "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
+ "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
"cpu": [
- "arm64"
+ "arm"
],
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "license": "LGPL-3.0-or-later",
"optional": true,
"os": [
- "win32"
+ "linux"
],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
"funding": {
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/@img/sharp-win32-ia32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
- "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
+ "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
"cpu": [
- "ia32"
+ "arm64"
],
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "license": "LGPL-3.0-or-later",
"optional": true,
"os": [
- "win32"
+ "linux"
],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
"funding": {
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/@img/sharp-win32-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
- "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
+ "node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
+ "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
"cpu": [
- "x64"
+ "ppc64"
],
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "license": "LGPL-3.0-or-later",
"optional": true,
"os": [
- "win32"
+ "linux"
],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
"funding": {
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/@isaacs/fs-minipass": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
- "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.4"
- },
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/@isaacs/ttlcache": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz",
- "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==",
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
- "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
- "license": "ISC",
- "dependencies": {
- "camelcase": "^5.3.1",
- "find-up": "^4.1.0",
- "get-package-type": "^0.1.0",
- "js-yaml": "^3.13.1",
- "resolve-from": "^5.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "license": "MIT",
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
- "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
- "version": "3.14.2",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
- "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
- "license": "MIT",
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/@istanbuljs/schema": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
- "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/create-cache-key-function": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz",
- "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==",
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/environment": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
- "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
- "license": "MIT",
- "dependencies": {
- "@jest/fake-timers": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "jest-mock": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/fake-timers": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
- "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@sinonjs/fake-timers": "^10.0.2",
- "@types/node": "*",
- "jest-message-util": "^29.7.0",
- "jest-mock": "^29.7.0",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node_modules/@img/sharp-libvips-linux-riscv64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
+ "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
+ "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@jest/transform": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
- "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.11.6",
- "@jest/types": "^29.6.3",
- "@jridgewell/trace-mapping": "^0.3.18",
- "babel-plugin-istanbul": "^6.1.1",
- "chalk": "^4.0.0",
- "convert-source-map": "^2.0.0",
- "fast-json-stable-stringify": "^2.1.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "jest-regex-util": "^29.6.3",
- "jest-util": "^29.7.0",
- "micromatch": "^4.0.4",
- "pirates": "^4.0.4",
- "slash": "^3.0.0",
- "write-file-atomic": "^4.0.2"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
+ "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@jest/types": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
- "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^3.0.0",
- "@types/node": "*",
- "@types/yargs": "^17.0.8",
- "chalk": "^4.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
+ "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
+ "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@jridgewell/remapping": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
- "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
+ "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.2.4"
}
},
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "license": "MIT",
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
+ "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=6.0.0"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.2.4"
}
},
- "node_modules/@jridgewell/source-map": {
- "version": "0.3.11",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
- "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25"
+ "node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
+ "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.2.4"
}
},
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
+ "node_modules/@img/sharp-linux-riscv64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
+ "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-riscv64": "1.2.4"
}
},
- "node_modules/@next/env": {
- "version": "15.5.14",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.14.tgz",
- "integrity": "sha512-aXeirLYuASxEgi4X4WhfXsShCFxWDfNn/8ZeC5YXAS2BB4A8FJi1kwwGL6nvMVboE7fZCzmJPNdMvVHc8JpaiA==",
- "license": "MIT"
- },
- "node_modules/@next/swc-darwin-arm64": {
- "version": "15.5.14",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.14.tgz",
- "integrity": "sha512-Y9K6SPzobnZvrRDPO2s0grgzC+Egf0CqfbdvYmQVaztV890zicw8Z8+4Vqw8oPck8r1TjUHxVh8299Cg4TrxXg==",
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
+ "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
"cpu": [
- "arm64"
+ "s390x"
],
- "license": "MIT",
+ "license": "Apache-2.0",
"optional": true,
"os": [
- "darwin"
+ "linux"
],
"engines": {
- "node": ">= 10"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.2.4"
}
},
- "node_modules/@next/swc-darwin-x64": {
- "version": "15.5.14",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.14.tgz",
- "integrity": "sha512-aNnkSMjSFRTOmkd7qoNI2/rETQm/vKD6c/Ac9BZGa9CtoOzy3c2njgz7LvebQJ8iPxdeTuGnAjagyis8a9ifBw==",
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
+ "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
"cpu": [
"x64"
],
- "license": "MIT",
+ "license": "Apache-2.0",
"optional": true,
"os": [
- "darwin"
+ "linux"
],
"engines": {
- "node": ">= 10"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.2.4"
}
},
- "node_modules/@next/swc-linux-arm64-gnu": {
- "version": "15.5.14",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.14.tgz",
- "integrity": "sha512-tjlpia+yStPRS//6sdmlVwuO1Rioern4u2onafa5n+h2hCS9MAvMXqpVbSrjgiEOoCs0nJy7oPOmWgtRRNSM5Q==",
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
+ "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
"cpu": [
"arm64"
],
- "license": "MIT",
+ "license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">= 10"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
}
},
- "node_modules/@next/swc-linux-arm64-musl": {
- "version": "15.5.14",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.14.tgz",
- "integrity": "sha512-8B8cngBaLadl5lbDRdxGCP1Lef8ipD6KlxS3v0ElDAGil6lafrAM3B258p1KJOglInCVFUjk751IXMr2ixeQOQ==",
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
+ "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
"cpu": [
- "arm64"
+ "x64"
],
- "license": "MIT",
+ "license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">= 10"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
}
},
- "node_modules/@next/swc-linux-x64-gnu": {
- "version": "15.5.14",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.14.tgz",
- "integrity": "sha512-bAS6tIAg8u4Gn3Nz7fCPpSoKAexEt2d5vn1mzokcqdqyov6ZJ6gu6GdF9l8ORFrBuRHgv3go/RfzYz5BkZ6YSQ==",
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
+ "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
"cpu": [
- "x64"
+ "wasm32"
],
- "license": "MIT",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
"optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@emnapi/runtime": "^1.7.0"
+ },
"engines": {
- "node": ">= 10"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@next/swc-linux-x64-musl": {
- "version": "15.5.14",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.14.tgz",
- "integrity": "sha512-mMxv/FcrT7Gfaq4tsR22l17oKWXZmH/lVqcvjX0kfp5I0lKodHYLICKPoX1KRnnE+ci6oIUdriUhuA3rBCDiSw==",
+ "node_modules/@img/sharp-win32-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
+ "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
"cpu": [
- "x64"
+ "arm64"
],
- "license": "MIT",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
- "linux"
+ "win32"
],
"engines": {
- "node": ">= 10"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@next/swc-win32-arm64-msvc": {
- "version": "15.5.14",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.14.tgz",
- "integrity": "sha512-OTmiBlYThppnvnsqx0rBqjDRemlmIeZ8/o4zI7veaXoeO1PVHoyj2lfTfXTiiGjCyRDhA10y4h6ZvZvBiynr2g==",
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
+ "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
"cpu": [
- "arm64"
+ "ia32"
],
- "license": "MIT",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
"win32"
],
"engines": {
- "node": ">= 10"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@next/swc-win32-x64-msvc": {
- "version": "15.5.14",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.14.tgz",
- "integrity": "sha512-+W7eFf3RS7m4G6tppVTOSyP9Y6FsJXfOuKzav1qKniiFm3KFByQfPEcouHdjlZmysl4zJGuGLQ/M9XyVeyeNEg==",
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
+ "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
"cpu": [
"x64"
],
- "license": "MIT",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
"win32"
],
"engines": {
- "node": ">= 10"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@isaacs/fs-minipass": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
+ "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
+ "license": "ISC",
"dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
+ "minipass": "^7.0.4"
},
"engines": {
- "node": ">= 8"
+ "node": ">=18.0.0"
}
},
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@isaacs/ttlcache": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz",
+ "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==",
+ "license": "ISC",
"engines": {
- "node": ">= 8"
+ "node": ">=12"
}
},
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "license": "ISC",
"dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
},
"engines": {
- "node": ">= 8"
+ "node": ">=8"
}
},
- "node_modules/@orbit/mobile": {
- "resolved": "apps/mobile",
- "link": true
- },
- "node_modules/@orbit/shared": {
- "resolved": "packages/shared",
- "link": true
- },
- "node_modules/@orbit/web": {
- "resolved": "apps/web",
- "link": true
- },
- "node_modules/@parcel/watcher": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
- "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
- "hasInstallScript": true,
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"license": "MIT",
"dependencies": {
- "detect-libc": "^2.0.3",
- "is-glob": "^4.0.3",
- "node-addon-api": "^7.0.0",
- "picomatch": "^4.0.3"
- },
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "license": "MIT",
"engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "@parcel/watcher-android-arm64": "2.5.6",
- "@parcel/watcher-darwin-arm64": "2.5.6",
- "@parcel/watcher-darwin-x64": "2.5.6",
- "@parcel/watcher-freebsd-x64": "2.5.6",
- "@parcel/watcher-linux-arm-glibc": "2.5.6",
- "@parcel/watcher-linux-arm-musl": "2.5.6",
- "@parcel/watcher-linux-arm64-glibc": "2.5.6",
- "@parcel/watcher-linux-arm64-musl": "2.5.6",
- "@parcel/watcher-linux-x64-glibc": "2.5.6",
- "@parcel/watcher-linux-x64-musl": "2.5.6",
- "@parcel/watcher-win32-arm64": "2.5.6",
- "@parcel/watcher-win32-ia32": "2.5.6",
- "@parcel/watcher-win32-x64": "2.5.6"
+ "node": ">=6"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
}
},
- "node_modules/@parcel/watcher-android-arm64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
- "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
"engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "node": ">=8"
}
},
- "node_modules/@parcel/watcher-darwin-arm64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
- "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@jest/create-cache-key-function": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz",
+ "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==",
"license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
+ "dependencies": {
+ "@jest/types": "^29.6.3"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/@parcel/watcher-darwin-x64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
- "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@jest/environment": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
+ "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
"license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
+ "dependencies": {
+ "@jest/fake-timers": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "jest-mock": "^29.7.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/@parcel/watcher-freebsd-x64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
- "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@jest/fake-timers": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
+ "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
"license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10.0.0"
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@sinonjs/fake-timers": "^10.0.2",
+ "@types/node": "*",
+ "jest-message-util": "^29.7.0",
+ "jest-mock": "^29.7.0",
+ "jest-util": "^29.7.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/@parcel/watcher-linux-arm-glibc": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
- "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
- "cpu": [
- "arm"
- ],
+ "node_modules/@jest/schemas": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
+ "dependencies": {
+ "@sinclair/typebox": "^0.27.8"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/@parcel/watcher-linux-arm-musl": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
- "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
- "cpu": [
- "arm"
- ],
+ "node_modules/@jest/transform": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
+ "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/types": "^29.6.3",
+ "@jridgewell/trace-mapping": "^0.3.18",
+ "babel-plugin-istanbul": "^6.1.1",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "jest-regex-util": "^29.6.3",
+ "jest-util": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.4",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^4.0.2"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/@parcel/watcher-linux-arm64-glibc": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
- "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@jest/types": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
+ "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/@parcel/watcher-linux-arm64-musl": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
- "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
}
},
- "node_modules/@parcel/watcher-linux-x64-glibc": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
- "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
"engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
- "node_modules/@parcel/watcher-linux-x64-musl": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
- "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "node_modules/@parcel/watcher-win32-arm64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
- "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
+ "node_modules/@next/env": {
+ "version": "15.5.14",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.14.tgz",
+ "integrity": "sha512-aXeirLYuASxEgi4X4WhfXsShCFxWDfNn/8ZeC5YXAS2BB4A8FJi1kwwGL6nvMVboE7fZCzmJPNdMvVHc8JpaiA==",
+ "license": "MIT"
+ },
+ "node_modules/@next/swc-darwin-arm64": {
+ "version": "15.5.14",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.14.tgz",
+ "integrity": "sha512-Y9K6SPzobnZvrRDPO2s0grgzC+Egf0CqfbdvYmQVaztV890zicw8Z8+4Vqw8oPck8r1TjUHxVh8299Cg4TrxXg==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
- "win32"
+ "darwin"
],
"engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "node": ">= 10"
}
},
- "node_modules/@parcel/watcher-win32-ia32": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
- "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
+ "node_modules/@next/swc-darwin-x64": {
+ "version": "15.5.14",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.14.tgz",
+ "integrity": "sha512-aNnkSMjSFRTOmkd7qoNI2/rETQm/vKD6c/Ac9BZGa9CtoOzy3c2njgz7LvebQJ8iPxdeTuGnAjagyis8a9ifBw==",
"cpu": [
- "ia32"
+ "x64"
],
"license": "MIT",
"optional": true,
"os": [
- "win32"
+ "darwin"
],
"engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
+ "node": ">= 10"
}
},
- "node_modules/@parcel/watcher-win32-x64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
- "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
+ "node_modules/@next/swc-linux-arm64-gnu": {
+ "version": "15.5.14",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.14.tgz",
+ "integrity": "sha512-tjlpia+yStPRS//6sdmlVwuO1Rioern4u2onafa5n+h2hCS9MAvMXqpVbSrjgiEOoCs0nJy7oPOmWgtRRNSM5Q==",
"cpu": [
- "x64"
+ "arm64"
],
"license": "MIT",
"optional": true,
"os": [
- "win32"
+ "linux"
],
"engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher/node_modules/picomatch": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
- "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/@playwright/test": {
- "version": "1.59.1",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.1.tgz",
- "integrity": "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "playwright": "1.59.1"
- },
- "bin": {
- "playwright": "cli.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@radix-ui/number": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz",
- "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==",
- "license": "MIT"
- },
- "node_modules/@radix-ui/primitive": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
- "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
- "license": "MIT"
- },
- "node_modules/@radix-ui/react-alert-dialog": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz",
- "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-dialog": "1.1.15",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-arrow": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz",
- "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.1.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-checkbox": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz",
- "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-use-previous": "1.1.1",
- "@radix-ui/react-use-size": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "node": ">= 10"
}
},
- "node_modules/@radix-ui/react-collection": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
- "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "node_modules/@next/swc-linux-arm64-musl": {
+ "version": "15.5.14",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.14.tgz",
+ "integrity": "sha512-8B8cngBaLadl5lbDRdxGCP1Lef8ipD6KlxS3v0ElDAGil6lafrAM3B258p1KJOglInCVFUjk751IXMr2ixeQOQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
}
},
- "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@next/swc-linux-x64-gnu": {
+ "version": "15.5.14",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.14.tgz",
+ "integrity": "sha512-bAS6tIAg8u4Gn3Nz7fCPpSoKAexEt2d5vn1mzokcqdqyov6ZJ6gu6GdF9l8ORFrBuRHgv3go/RfzYz5BkZ6YSQ==",
+ "cpu": [
+ "x64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
}
},
- "node_modules/@radix-ui/react-compose-refs": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
- "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "node_modules/@next/swc-linux-x64-musl": {
+ "version": "15.5.14",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.14.tgz",
+ "integrity": "sha512-mMxv/FcrT7Gfaq4tsR22l17oKWXZmH/lVqcvjX0kfp5I0lKodHYLICKPoX1KRnnE+ci6oIUdriUhuA3rBCDiSw==",
+ "cpu": [
+ "x64"
+ ],
"license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
}
},
- "node_modules/@radix-ui/react-context": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
- "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
+ "node_modules/@next/swc-win32-arm64-msvc": {
+ "version": "15.5.14",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.14.tgz",
+ "integrity": "sha512-OTmiBlYThppnvnsqx0rBqjDRemlmIeZ8/o4zI7veaXoeO1PVHoyj2lfTfXTiiGjCyRDhA10y4h6ZvZvBiynr2g==",
+ "cpu": [
+ "arm64"
+ ],
"license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
}
},
- "node_modules/@radix-ui/react-dialog": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz",
- "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==",
+ "node_modules/@next/swc-win32-x64-msvc": {
+ "version": "15.5.14",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.14.tgz",
+ "integrity": "sha512-+W7eFf3RS7m4G6tppVTOSyP9Y6FsJXfOuKzav1qKniiFm3KFByQfPEcouHdjlZmysl4zJGuGLQ/M9XyVeyeNEg==",
+ "cpu": [
+ "x64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-dismissable-layer": "1.1.11",
- "@radix-ui/react-focus-guards": "1.1.3",
- "@radix-ui/react-focus-scope": "1.1.7",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-portal": "1.1.9",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "aria-hidden": "^1.2.4",
- "react-remove-scroll": "^2.6.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
}
},
- "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "engines": {
+ "node": ">= 8"
}
},
- "node_modules/@radix-ui/react-direction": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
- "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
"license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "engines": {
+ "node": ">= 8"
}
},
- "node_modules/@radix-ui/react-dismissable-layer": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
- "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-escape-keydown": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "engines": {
+ "node": ">= 8"
}
},
- "node_modules/@radix-ui/react-focus-guards": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
- "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
+ "node_modules/@orbit/mobile": {
+ "resolved": "apps/mobile",
+ "link": true
+ },
+ "node_modules/@orbit/shared": {
+ "resolved": "packages/shared",
+ "link": true
+ },
+ "node_modules/@orbit/web": {
+ "resolved": "apps/web",
+ "link": true
+ },
+ "node_modules/@parcel/watcher": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
+ "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
+ "hasInstallScript": true,
"license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "dependencies": {
+ "detect-libc": "^2.0.3",
+ "is-glob": "^4.0.3",
+ "node-addon-api": "^7.0.0",
+ "picomatch": "^4.0.3"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.5.6",
+ "@parcel/watcher-darwin-arm64": "2.5.6",
+ "@parcel/watcher-darwin-x64": "2.5.6",
+ "@parcel/watcher-freebsd-x64": "2.5.6",
+ "@parcel/watcher-linux-arm-glibc": "2.5.6",
+ "@parcel/watcher-linux-arm-musl": "2.5.6",
+ "@parcel/watcher-linux-arm64-glibc": "2.5.6",
+ "@parcel/watcher-linux-arm64-musl": "2.5.6",
+ "@parcel/watcher-linux-x64-glibc": "2.5.6",
+ "@parcel/watcher-linux-x64-musl": "2.5.6",
+ "@parcel/watcher-win32-arm64": "2.5.6",
+ "@parcel/watcher-win32-ia32": "2.5.6",
+ "@parcel/watcher-win32-x64": "2.5.6"
}
},
- "node_modules/@radix-ui/react-focus-scope": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
- "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
+ "node_modules/@parcel/watcher-android-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
+ "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
+ "cpu": [
+ "arm64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-id": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
- "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
+ "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
+ "cpu": [
+ "arm64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-popover": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz",
- "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==",
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
+ "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
+ "cpu": [
+ "x64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-dismissable-layer": "1.1.11",
- "@radix-ui/react-focus-guards": "1.1.3",
- "@radix-ui/react-focus-scope": "1.1.7",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-popper": "1.2.8",
- "@radix-ui/react-portal": "1.1.9",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "aria-hidden": "^1.2.4",
- "react-remove-scroll": "^2.6.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
+ "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
+ "cpu": [
+ "x64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-popper": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz",
- "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==",
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
+ "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
+ "cpu": [
+ "arm"
+ ],
"license": "MIT",
- "dependencies": {
- "@floating-ui/react-dom": "^2.0.0",
- "@radix-ui/react-arrow": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-layout-effect": "1.1.1",
- "@radix-ui/react-use-rect": "1.1.1",
- "@radix-ui/react-use-size": "1.1.1",
- "@radix-ui/rect": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-portal": {
- "version": "1.1.9",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
- "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
+ "node_modules/@parcel/watcher-linux-arm-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
+ "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
+ "cpu": [
+ "arm"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-layout-effect": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-presence": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
- "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
+ "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
+ "cpu": [
+ "arm64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-use-layout-effect": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-primitive": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
- "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
+ "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
+ "cpu": [
+ "arm64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-slot": "1.2.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
+ "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
+ "cpu": [
+ "x64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-roving-focus": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz",
- "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==",
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
+ "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
+ "cpu": [
+ "x64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-collection": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-direction": "1.1.1",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-controllable-state": "1.2.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-scroll-area": {
- "version": "1.2.10",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz",
- "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==",
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
+ "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
+ "cpu": [
+ "arm64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/number": "1.1.1",
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-direction": "1.1.1",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-layout-effect": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-select": {
- "version": "2.2.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz",
- "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==",
+ "node_modules/@parcel/watcher-win32-ia32": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
+ "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
+ "cpu": [
+ "ia32"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/number": "1.1.1",
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-collection": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-direction": "1.1.1",
- "@radix-ui/react-dismissable-layer": "1.1.11",
- "@radix-ui/react-focus-guards": "1.1.3",
- "@radix-ui/react-focus-scope": "1.1.7",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-popper": "1.2.8",
- "@radix-ui/react-portal": "1.1.9",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-use-layout-effect": "1.1.1",
- "@radix-ui/react-use-previous": "1.1.1",
- "@radix-ui/react-visually-hidden": "1.2.3",
- "aria-hidden": "^1.2.4",
- "react-remove-scroll": "^2.6.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
+ "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
+ "cpu": [
+ "x64"
+ ],
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-separator": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.8.tgz",
- "integrity": "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==",
+ "node_modules/@parcel/watcher/node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.1.4"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "engines": {
+ "node": ">=12"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz",
- "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==",
- "license": "MIT",
+ "node_modules/@playwright/test": {
+ "version": "1.59.1",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.1.tgz",
+ "integrity": "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "peer": true,
"dependencies": {
- "@radix-ui/react-slot": "1.2.4"
+ "playwright": "1.59.1"
},
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@radix-ui/number": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz",
+ "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/primitive": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
+ "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
+ "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "license": "MIT",
"peerDependencies": {
"@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
- },
- "@types/react-dom": {
- "optional": true
}
}
},
- "node_modules/@radix-ui/react-slot": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz",
- "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==",
+ "node_modules/@radix-ui/react-context": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
+ "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
@@ -4912,103 +4888,59 @@
}
}
},
- "node_modules/@radix-ui/react-switch": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz",
- "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==",
+ "node_modules/@radix-ui/react-direction": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
+ "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
"license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-use-previous": "1.1.1",
- "@radix-ui/react-use-size": "1.1.1"
- },
"peerDependencies": {
"@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
- },
- "@types/react-dom": {
- "optional": true
}
}
},
- "node_modules/@radix-ui/react-tabs": {
- "version": "1.1.13",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz",
- "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==",
+ "node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
+ "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
"license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-direction": "1.1.1",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-roving-focus": "1.1.11",
- "@radix-ui/react-use-controllable-state": "1.2.2"
- },
"peerDependencies": {
"@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
- },
- "@types/react-dom": {
- "optional": true
}
}
},
- "node_modules/@radix-ui/react-tooltip": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz",
- "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==",
+ "node_modules/@radix-ui/react-id": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
+ "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
"license": "MIT",
"dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-dismissable-layer": "1.1.11",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-popper": "1.2.8",
- "@radix-ui/react-portal": "1.1.9",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-visually-hidden": "1.2.3"
+ "@radix-ui/react-use-layout-effect": "1.1.1"
},
"peerDependencies": {
"@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
- },
- "@types/react-dom": {
- "optional": true
}
}
},
- "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@radix-ui/react-slot": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz",
+ "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@radix-ui/react-compose-refs": "1.1.2"
@@ -5159,29 +5091,6 @@
}
}
},
- "node_modules/@radix-ui/react-visually-hidden": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz",
- "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.1.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
"node_modules/@radix-ui/rect": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz",
@@ -5557,6 +5466,7 @@
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.2.2.tgz",
"integrity": "sha512-kem1Ko2BcbAjmbQIv66dNmr6EtfDut3QU0qjsVhMnLLhktwyXb6FzZYp8gTrUb6AvkAbaJoi+BF5Pl55pAUa5w==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@react-navigation/core": "^7.17.2",
"escape-string-regexp": "^4.0.0",
@@ -5990,44 +5900,90 @@
"integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
"license": "MIT"
},
- "node_modules/@swc/core": {
- "version": "1.15.24",
- "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.24.tgz",
- "integrity": "sha512-5Hj8aNasue7yusUt8LGCUe/AjM7RMAce8ZoyDyiFwx7Al+GbYKL+yE7g4sJk8vEr1dKIkTRARkNIJENc4CjkBQ==",
- "hasInstallScript": true,
- "license": "Apache-2.0",
+ "node_modules/@supabase/auth-js": {
+ "version": "2.101.1",
+ "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.101.1.tgz",
+ "integrity": "sha512-Kd0Wey+RkFHgyVep7adS6UOE2pN6MJ3mZ32PAXSvfw6IjUkFRC7IQpdZZjUOcUe5pXr1ejufCRgF6lsGINe4Tw==",
+ "license": "MIT",
"dependencies": {
- "@swc/counter": "^0.1.3",
- "@swc/types": "^0.1.26"
+ "tslib": "2.8.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@supabase/functions-js": {
+ "version": "2.101.1",
+ "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.101.1.tgz",
+ "integrity": "sha512-OZWU7YtaG+NNNFZK8p/FuJ6gpq7pFyrG2fLOopP73HAIDHDGpOttPJapvO8ADu3RkqfQfkwrB354vPkSBbZ20A==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "2.8.1"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/swc"
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@supabase/phoenix": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@supabase/phoenix/-/phoenix-0.4.0.tgz",
+ "integrity": "sha512-RHSx8bHS02xwfHdAbX5Lpbo6PXbgyf7lTaXTlwtFDPwOIw64NnVRwFAXGojHhjtVYI+PEPNSWwkL90f4agN3bw==",
+ "license": "MIT"
+ },
+ "node_modules/@supabase/postgrest-js": {
+ "version": "2.101.1",
+ "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.101.1.tgz",
+ "integrity": "sha512-UW1RajH5jbZoK+ldAJ1I6VZ+HWwZ2oaKjEQ6Gn+AQ67CHQVxGl8wNQoLYyumbyaExm41I+wn7arulcY1eHeZJw==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "2.8.1"
},
- "optionalDependencies": {
- "@swc/core-darwin-arm64": "1.15.24",
- "@swc/core-darwin-x64": "1.15.24",
- "@swc/core-linux-arm-gnueabihf": "1.15.24",
- "@swc/core-linux-arm64-gnu": "1.15.24",
- "@swc/core-linux-arm64-musl": "1.15.24",
- "@swc/core-linux-ppc64-gnu": "1.15.24",
- "@swc/core-linux-s390x-gnu": "1.15.24",
- "@swc/core-linux-x64-gnu": "1.15.24",
- "@swc/core-linux-x64-musl": "1.15.24",
- "@swc/core-win32-arm64-msvc": "1.15.24",
- "@swc/core-win32-ia32-msvc": "1.15.24",
- "@swc/core-win32-x64-msvc": "1.15.24"
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@supabase/realtime-js": {
+ "version": "2.101.1",
+ "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.101.1.tgz",
+ "integrity": "sha512-Oa6dno0OB9I+hv5do5zsZHbFu41ViZnE9IWjmkeeF/8fPmB5fWoHGqeTYEC3/0DAgtpUoFJa4FpvzFH0SBHo1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@supabase/phoenix": "^0.4.0",
+ "@types/ws": "^8.18.1",
+ "tslib": "2.8.1",
+ "ws": "^8.18.2"
},
- "peerDependencies": {
- "@swc/helpers": ">=0.5.17"
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@supabase/storage-js": {
+ "version": "2.101.1",
+ "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.101.1.tgz",
+ "integrity": "sha512-WhTaUOBgeEvnKLy95Cdlp6+D5igSF/65yC727w1olxbet5nzUvMlajKUWyzNtQu2efrz2cQ7FcdVBdQqgT9YKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "iceberg-js": "^0.8.1",
+ "tslib": "2.8.1"
},
- "peerDependenciesMeta": {
- "@swc/helpers": {
- "optional": true
- }
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@supabase/supabase-js": {
+ "version": "2.101.1",
+ "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.101.1.tgz",
+ "integrity": "sha512-Jnhm3LfuACwjIzvk2pfUbGQn7pa7hi6MFzfSyPrRYWVCCu69RPLCFyHSBl7HSBwadbQ3UZOznnD3gPca3ePrRA==",
+ "license": "MIT",
+ "dependencies": {
+ "@supabase/auth-js": "2.101.1",
+ "@supabase/functions-js": "2.101.1",
+ "@supabase/postgrest-js": "2.101.1",
+ "@supabase/realtime-js": "2.101.1",
+ "@supabase/storage-js": "2.101.1"
+ },
+ "engines": {
+ "node": ">=20.0.0"
}
},
"node_modules/@swc/core-darwin-arm64": {
@@ -6582,6 +6538,7 @@
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.96.2.tgz",
"integrity": "sha512-sYyzzJT4G0g02azzJ8o55VFFV31XvFpdUpG+unxS0vSaYsJnSPKGoI6WdPwUucJL1wpgGfwfmntNX/Ub1uOViA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@tanstack/query-core": "5.96.2"
},
@@ -6616,6 +6573,7 @@
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
@@ -6650,40 +6608,12 @@
"yarn": ">=1"
}
},
- "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
- "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@testing-library/react": {
- "version": "16.3.2",
- "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz",
- "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.12.5"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@testing-library/dom": "^10.0.0",
- "@types/react": "^18.0.0 || ^19.0.0",
- "@types/react-dom": "^18.0.0 || ^19.0.0",
- "react": "^18.0.0 || ^19.0.0",
- "react-dom": "^18.0.0 || ^19.0.0"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
+ "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
+ "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@turbo/darwin-64": {
"version": "2.9.3",
@@ -6835,6 +6765,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/dompurify": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz",
+ "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/trusted-types": "*"
+ }
+ },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -6894,28 +6834,35 @@
"version": "19.1.17",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.17.tgz",
"integrity": "sha512-Qec1E3mhALmaspIrhWt9jkQMNdw6bReVu64mjvhbhq2NFPftLPVr+l1SZgmw/66WwBNpDh7ao5AT6gF5v41PFA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
},
- "node_modules/@types/react-dom": {
- "version": "19.2.3",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
- "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "^19.2.0"
- }
- },
"node_modules/@types/stack-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
"license": "MIT"
},
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/ws": {
+ "version": "8.18.1",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
+ "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/yargs": {
"version": "17.0.35",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
@@ -7700,6 +7647,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.10.12",
"caniuse-lite": "^1.0.30001782",
@@ -8345,7 +8293,7 @@
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT"
},
"node_modules/data-urls": {
@@ -8612,6 +8560,15 @@
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
+ "node_modules/dompurify": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.3.tgz",
+ "integrity": "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==",
+ "license": "(MPL-2.0 OR Apache-2.0)",
+ "optionalDependencies": {
+ "@types/trusted-types": "^2.0.7"
+ }
+ },
"node_modules/domutils": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
@@ -8901,6 +8858,7 @@
"resolved": "https://registry.npmjs.org/expo/-/expo-54.0.33.tgz",
"integrity": "sha512-3yOEfAKqo+gqHcV8vKcnq0uA5zxlohnhA3fu4G43likN8ct5ZZ3LjAh9wDdKteEkoad3tFPvwxmXW711S5OHUw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.20.0",
"@expo/cli": "54.0.23",
@@ -8977,6 +8935,7 @@
"resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.13.tgz",
"integrity": "sha512-FnZn12E1dRYKDHlAdIyNFhBurKTS3F9CrfrBDJI5m3D7U17KBHMQ6JEfYlSj7LG7t+Ulr+IKaj58L1k5gBwTcQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@expo/config": "~12.0.13",
"@expo/env": "~2.0.8"
@@ -9019,6 +8978,7 @@
"resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.11.tgz",
"integrity": "sha512-ga0q61ny4s/kr4k8JX9hVH69exVSIfcIc19+qZ7gt71Mqtm7xy2c6kwsPTCyhBW2Ro5yXTT8EaZOpuRi35rHbg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"fontfaceobserver": "^2.1.0"
},
@@ -9049,6 +9009,7 @@
"resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-8.0.11.tgz",
"integrity": "sha512-+VSaNL5om3kOp/SSKO5qe6cFgfSIWnnQDSbA7XLs3ECkYzXRquk5unxNS3pg7eK5kNUmQ4kgLI7MhTggAEUBLA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"expo-constants": "~18.0.12",
"invariant": "^2.2.4"
@@ -9191,6 +9152,146 @@
}
}
},
+ "node_modules/expo-router/node_modules/@radix-ui/react-collection": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
+ "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/expo-router/node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/expo-router/node_modules/@radix-ui/react-presence": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
+ "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/expo-router/node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
+ "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.2.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/expo-router/node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/expo-router/node_modules/@radix-ui/react-roving-focus": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz",
+ "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-collection": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/expo-router/node_modules/@radix-ui/react-slot": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz",
@@ -9209,6 +9310,36 @@
}
}
},
+ "node_modules/expo-router/node_modules/@radix-ui/react-tabs": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz",
+ "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-roving-focus": "1.1.11",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/expo-router/node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@@ -9996,6 +10127,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.26.10"
},
@@ -10008,6 +10140,15 @@
}
}
},
+ "node_modules/iceberg-js": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz",
+ "integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
@@ -11245,6 +11386,18 @@
"tmpl": "1.0.5"
}
},
+ "node_modules/marked": {
+ "version": "17.0.5",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-17.0.5.tgz",
+ "integrity": "sha512-6hLvc0/JEbRjRgzI6wnT2P1XuM1/RrrDEX0kPt0N7jGm1133g6X7DlxFasUIx+72aKAr904GTxhSLDrd5DIlZg==",
+ "license": "MIT",
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 20"
+ }
+ },
"node_modules/marky": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz",
@@ -11908,6 +12061,57 @@
"integrity": "sha512-CAu6Qy6XiCenKsvzyCPm2cZFkGfcvhJi8N93TCnOowmzD4Br3ked7QdROusRRp4MQ1iG9u+KCLgVcM9CLDUOIQ==",
"license": "MIT"
},
+ "node_modules/next-intl/node_modules/@swc/core": {
+ "version": "1.15.24",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.24.tgz",
+ "integrity": "sha512-5Hj8aNasue7yusUt8LGCUe/AjM7RMAce8ZoyDyiFwx7Al+GbYKL+yE7g4sJk8vEr1dKIkTRARkNIJENc4CjkBQ==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/counter": "^0.1.3",
+ "@swc/types": "^0.1.26"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/swc"
+ },
+ "optionalDependencies": {
+ "@swc/core-darwin-arm64": "1.15.24",
+ "@swc/core-darwin-x64": "1.15.24",
+ "@swc/core-linux-arm-gnueabihf": "1.15.24",
+ "@swc/core-linux-arm64-gnu": "1.15.24",
+ "@swc/core-linux-arm64-musl": "1.15.24",
+ "@swc/core-linux-ppc64-gnu": "1.15.24",
+ "@swc/core-linux-s390x-gnu": "1.15.24",
+ "@swc/core-linux-x64-gnu": "1.15.24",
+ "@swc/core-linux-x64-musl": "1.15.24",
+ "@swc/core-win32-arm64-msvc": "1.15.24",
+ "@swc/core-win32-ia32-msvc": "1.15.24",
+ "@swc/core-win32-x64-msvc": "1.15.24"
+ },
+ "peerDependencies": {
+ "@swc/helpers": ">=0.5.17"
+ },
+ "peerDependenciesMeta": {
+ "@swc/helpers": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/next-intl/node_modules/@swc/helpers": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz",
+ "integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
"node_modules/next-intl/node_modules/negotiator": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
@@ -12456,7 +12660,7 @@
"version": "1.59.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz",
"integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==",
- "dev": true,
+ "devOptional": true,
"license": "Apache-2.0",
"dependencies": {
"playwright-core": "1.59.1"
@@ -12475,7 +12679,7 @@
"version": "1.59.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz",
"integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==",
- "dev": true,
+ "devOptional": true,
"license": "Apache-2.0",
"bin": {
"playwright-core": "cli.js"
@@ -12542,6 +12746,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -12595,42 +12800,6 @@
"postcss": "^8.4.21"
}
},
- "node_modules/postcss-load-config": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
- "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "lilconfig": "^3.0.0",
- "yaml": "^2.3.4"
- },
- "engines": {
- "node": ">= 14"
- },
- "peerDependencies": {
- "postcss": ">=8.0.9",
- "ts-node": ">=9.0.0"
- },
- "peerDependenciesMeta": {
- "postcss": {
- "optional": true
- },
- "ts-node": {
- "optional": true
- }
- }
- },
"node_modules/postcss-nested": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
@@ -12859,6 +13028,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -12917,15 +13087,16 @@
}
},
"node_modules/react-dom": {
- "version": "19.2.4",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
- "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
+ "version": "19.1.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
+ "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
"license": "MIT",
+ "peer": true,
"dependencies": {
- "scheduler": "^0.27.0"
+ "scheduler": "^0.26.0"
},
"peerDependencies": {
- "react": "^19.2.4"
+ "react": "^19.1.0"
}
},
"node_modules/react-fast-compare": {
@@ -12951,6 +13122,7 @@
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.72.1.tgz",
"integrity": "sha512-RhwBoy2ygeVZje+C+bwJ8g0NjTdBmDlJvAUHTxRjTmSUKPYsKfMphkS2sgEMotsY03bP358yEYlnUeZy//D9Ig==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18.0.0"
},
@@ -12999,6 +13171,7 @@
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.81.5.tgz",
"integrity": "sha512-1w+/oSjEXZjMqsIvmkCRsOc8UBYv163bTWKTI8+1mxztvQPhCRYGTvZ/PL1w16xXHneIj/SLGfxWg2GWN2uexw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@jest/create-cache-key-function": "^29.7.0",
"@react-native/assets-registry": "0.81.5",
@@ -13070,6 +13243,7 @@
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.28.0.tgz",
"integrity": "sha512-0msfJ1vRxXKVgTgvL+1ZOoYw3/0z1R+Ked0+udoJhyplC2jbVKIJ8Z1bzWdpQRCV3QcQ87Op0zJVE5DhKK2A0A==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@egjs/hammerjs": "^2.0.17",
"hoist-non-react-statics": "^3.3.0",
@@ -13095,6 +13269,7 @@
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.1.7.tgz",
"integrity": "sha512-Q4H6xA3Tn7QL0/E/KjI86I1KK4tcf+ErRE04LH34Etka2oVQhW6oXQ+Q8ZcDCVxiWp5vgbBH6XcH8BOo4w/Rhg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"react-native-is-edge-to-edge": "^1.2.1",
"semver": "^7.7.2"
@@ -13122,6 +13297,7 @@
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz",
"integrity": "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==",
"license": "MIT",
+ "peer": true,
"peerDependencies": {
"react": "*",
"react-native": "*"
@@ -13132,6 +13308,7 @@
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.16.0.tgz",
"integrity": "sha512-yIAyh7F/9uWkOzCi1/2FqvNvK6Wb9Y1+Kzn16SuGfN9YFJDTbwlzGRvePCNTOX0recpLQF3kc2FmvMUhyTCH1Q==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"react-freeze": "^1.0.0",
"react-native-is-edge-to-edge": "^1.2.1",
@@ -13147,6 +13324,7 @@
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.12.1.tgz",
"integrity": "sha512-vCuZJDf8a5aNC2dlMovEv4Z0jjEUET53lm/iILFnFewa15b4atjVxU6Wirm6O9y6dEsdjDZVD7Q3QM4T1wlI8g==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"css-select": "^5.1.0",
"css-tree": "^1.1.3",
@@ -13158,10 +13336,11 @@
}
},
"node_modules/react-native-worklets": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.5.1.tgz",
- "integrity": "sha512-lJG6Uk9YuojjEX/tQrCbcbmpdLCSFxDK1rJlkDhgqkVi1KZzG7cdcBFQRqyNOOzR9Y0CXNuldmtWTGOyM0k0+w==",
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.5.2.tgz",
+ "integrity": "sha512-lCzmuIPAK/UaOJYEPgYpVqrsxby1I54f7PyyZUMEO04nwc00CDrCvv9lCTY1daLHYTF8lS3f9zlzErfVsIKqkA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/plugin-transform-arrow-functions": "^7.0.0-0",
"@babel/plugin-transform-class-properties": "^7.0.0-0",
@@ -13286,12 +13465,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/react-native/node_modules/scheduler": {
- "version": "0.26.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
- "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
- "license": "MIT"
- },
"node_modules/react-native/node_modules/semver": {
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
@@ -13317,8 +13490,8 @@
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
"integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
- "dev": true,
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -13811,9 +13984,9 @@
}
},
"node_modules/scheduler": {
- "version": "0.27.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
- "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+ "version": "0.26.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
+ "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
"license": "MIT"
},
"node_modules/semver": {
@@ -14524,6 +14697,42 @@
"jiti": "bin/jiti.js"
}
},
+ "node_modules/tailwindcss/node_modules/postcss-load-config": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
+ "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "lilconfig": "^3.0.0",
+ "yaml": "^2.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "peerDependencies": {
+ "postcss": ">=8.0.9",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "postcss": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
"node_modules/tapable": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz",
@@ -14584,6 +14793,7 @@
"resolved": "https://registry.npmjs.org/terser/-/terser-5.46.1.tgz",
"integrity": "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==",
"license": "BSD-2-Clause",
+ "peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.15.0",
@@ -14884,8 +15094,9 @@
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
- "dev": true,
+ "devOptional": true,
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -15174,12 +15385,190 @@
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc"
}
},
+ "node_modules/vaul/node_modules/@radix-ui/react-dialog": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz",
+ "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-focus-guards": "1.1.3",
+ "@radix-ui/react-focus-scope": "1.1.7",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vaul/node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
+ "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-escape-keydown": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vaul/node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
+ "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vaul/node_modules/@radix-ui/react-portal": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
+ "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vaul/node_modules/@radix-ui/react-presence": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
+ "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vaul/node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
+ "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.2.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vaul/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/vite": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
diff --git a/package.json b/package.json
index b7eb14979..d9032dd2d 100644
--- a/package.json
+++ b/package.json
@@ -25,5 +25,9 @@
},
"dependencies": {
"react-native-worklets": "^0.5.1"
+ },
+ "overrides": {
+ "react": "19.1.0",
+ "react-dom": "19.1.0"
}
}