+13
app/api/categories/[categoryId]/route.ts
+13
app/api/categories/[categoryId]/route.ts
···
9
9
import { getOrganizationRole } from '@/lib/repositories/user-repository';
10
10
import { Category } from '@/lib/types';
11
11
import { z } from 'zod';
12
+
import { verifyBotId } from '@/lib/botid-verification';
12
13
13
14
export const runtime = 'nodejs';
14
15
···
23
24
{ params }: { params: Promise<{ categoryId: string }> }
24
25
) {
25
26
try {
27
+
// Check for bot before proceeding
28
+
const botVerification = await verifyBotId();
29
+
if (botVerification) {
30
+
return botVerification;
31
+
}
32
+
26
33
const { categoryId } = await params;
27
34
const session = await auth();
28
35
if (!session?.user?.id) {
···
123
130
{ params }: { params: Promise<{ categoryId: string }> }
124
131
) {
125
132
try {
133
+
// Check for bot before proceeding
134
+
const botVerification = await verifyBotId();
135
+
if (botVerification) {
136
+
return botVerification;
137
+
}
138
+
126
139
const { categoryId } = await params;
127
140
const session = await auth();
128
141
if (!session?.user?.id) {
+7
app/api/dashboard/data/route.ts
+7
app/api/dashboard/data/route.ts
···
1
1
import { NextRequest, NextResponse } from 'next/server';
2
2
import { getUserWithOrganizations } from '@/lib/auth-context';
3
+
import { verifyBotId } from '@/lib/botid-verification';
3
4
4
5
export const runtime = 'nodejs';
5
6
6
7
export async function GET(request: NextRequest) {
7
8
try {
9
+
// Check for bot before proceeding
10
+
const botVerification = await verifyBotId();
11
+
if (botVerification) {
12
+
return botVerification;
13
+
}
14
+
8
15
const { searchParams } = new URL(request.url);
9
16
const include = searchParams.get('include')?.split(',') || [];
10
17
+19
app/api/github-app/installations/[installationId]/route.ts
+19
app/api/github-app/installations/[installationId]/route.ts
···
7
7
import { auth } from '@/auth'
8
8
import { getService } from '@/lib/core/container/di-container'
9
9
import { IGitHubAppService } from '@/lib/core/ports'
10
+
import { verifyBotId } from '@/lib/botid-verification'
10
11
11
12
export const runtime = 'nodejs'
12
13
···
19
20
{ params }: { params: Promise<{ installationId: string }> }
20
21
) {
21
22
try {
23
+
// Check for bot before proceeding
24
+
const botVerification = await verifyBotId();
25
+
if (botVerification) {
26
+
return botVerification;
27
+
}
28
+
22
29
const { installationId } = await params
23
30
const session = await auth()
24
31
···
84
91
{ params }: { params: Promise<{ installationId: string }> }
85
92
) {
86
93
try {
94
+
// Check for bot before proceeding
95
+
const botVerification = await verifyBotId();
96
+
if (botVerification) {
97
+
return botVerification;
98
+
}
99
+
87
100
const { installationId } = await params
88
101
const session = await auth()
89
102
···
150
163
{ params }: { params: Promise<{ installationId: string }> }
151
164
) {
152
165
try {
166
+
// Check for bot before proceeding
167
+
const botVerification = await verifyBotId();
168
+
if (botVerification) {
169
+
return botVerification;
170
+
}
171
+
153
172
const { installationId } = await params
154
173
const session = await auth()
155
174
+13
app/api/github-app/installations/route.ts
+13
app/api/github-app/installations/route.ts
···
7
7
import { auth } from '@/auth'
8
8
import { getService } from '@/lib/core/container/di-container'
9
9
import { IGitHubAppService } from '@/lib/core/ports'
10
+
import { verifyBotId } from '@/lib/botid-verification'
10
11
11
12
export const runtime = 'nodejs'
12
13
···
16
17
*/
17
18
export async function GET() {
18
19
try {
20
+
// Check for bot before proceeding
21
+
const botVerification = await verifyBotId();
22
+
if (botVerification) {
23
+
return botVerification;
24
+
}
25
+
19
26
const session = await auth()
20
27
21
28
if (!session || !session.user) {
···
71
78
*/
72
79
export async function POST() {
73
80
try {
81
+
// Check for bot before proceeding
82
+
const botVerification = await verifyBotId();
83
+
if (botVerification) {
84
+
return botVerification;
85
+
}
86
+
74
87
const session = await auth()
75
88
76
89
if (!session || !session.user) {
+7
app/api/github/organizations/[orgName]/repositories/route.ts
+7
app/api/github/organizations/[orgName]/repositories/route.ts
···
2
2
import { auth } from '@/auth';
3
3
import { getService } from '@/lib/core/container/di-container';
4
4
import { IGitHubService } from '@/lib/core/ports';
5
+
import { verifyBotId } from '@/lib/botid-verification';
5
6
6
7
// Use the context object directly with proper typing for Next.js route handler
7
8
export async function GET(
8
9
request: NextRequest,
9
10
{ params }: { params: Promise<{ orgName: string }> }
10
11
) {
12
+
// Check for bot before proceeding
13
+
const botVerification = await verifyBotId();
14
+
if (botVerification) {
15
+
return botVerification;
16
+
}
17
+
11
18
const { orgName } = await params;
12
19
13
20
const session = await auth();
+7
app/api/github/organizations/route.ts
+7
app/api/github/organizations/route.ts
···
2
2
import { auth } from '@/auth';
3
3
import { getService } from '@/lib/core/container/di-container';
4
4
import { IGitHubService } from '@/lib/core/ports';
5
+
import { verifyBotId } from '@/lib/botid-verification';
5
6
6
7
export async function GET() {
8
+
// Check for bot before proceeding
9
+
const botVerification = await verifyBotId();
10
+
if (botVerification) {
11
+
return botVerification;
12
+
}
13
+
7
14
const session = await auth();
8
15
9
16
if (!session || !session.user) {
+7
app/api/github/repositories/sync/route.ts
+7
app/api/github/repositories/sync/route.ts
···
2
2
import { auth } from '@/auth';
3
3
import { GitHubService } from '@/lib/services';
4
4
import { findUserById, findUserByEmail } from '@/lib/repositories';
5
+
import { verifyBotId } from '@/lib/botid-verification';
5
6
6
7
export const runtime = 'nodejs';
7
8
8
9
export async function POST() {
10
+
// Check for bot before proceeding
11
+
const botVerification = await verifyBotId();
12
+
if (botVerification) {
13
+
return botVerification;
14
+
}
15
+
9
16
const session = await auth();
10
17
11
18
if (!session || !session.user) {
+7
app/api/github/user/route.ts
+7
app/api/github/user/route.ts
···
2
2
import { auth } from '@/auth';
3
3
import { getService } from '@/lib/core/container/di-container';
4
4
import { IGitHubService } from '@/lib/core/ports';
5
+
import { verifyBotId } from '@/lib/botid-verification';
5
6
6
7
export async function GET() {
8
+
// Check for bot before proceeding
9
+
const botVerification = await verifyBotId();
10
+
if (botVerification) {
11
+
return botVerification;
12
+
}
13
+
7
14
const session = await auth();
8
15
9
16
if (!session || !session.user) {
+13
app/api/organizations/[orgId]/ai-settings/route.ts
+13
app/api/organizations/[orgId]/ai-settings/route.ts
···
3
3
import { AiSettingsService } from '@/lib/services/ai-settings-service';
4
4
import { z } from 'zod';
5
5
import { unauthorized, badRequest, errorResponse } from '@/lib/api-errors';
6
+
import { verifyBotId } from '@/lib/botid-verification';
6
7
7
8
const updateAiSettingsSchema = z.object({
8
9
provider: z.enum(['openai', 'google', 'anthropic']).nullable().optional(),
···
19
20
{ params }: { params: Promise<{ orgId: string }> }
20
21
) {
21
22
try {
23
+
// Check for bot before proceeding
24
+
const botVerification = await verifyBotId();
25
+
if (botVerification) {
26
+
return botVerification;
27
+
}
28
+
22
29
const { orgId } = await params;
23
30
const session = await auth();
24
31
if (!session?.user?.id) throw unauthorized();
···
39
46
{ params }: { params: Promise<{ orgId: string }> }
40
47
) {
41
48
try {
49
+
// Check for bot before proceeding
50
+
const botVerification = await verifyBotId();
51
+
if (botVerification) {
52
+
return botVerification;
53
+
}
54
+
42
55
const { orgId } = await params;
43
56
const session = await auth();
44
57
if (!session?.user?.id) throw unauthorized();
+7
app/api/organizations/[orgId]/members/route.ts
+7
app/api/organizations/[orgId]/members/route.ts
···
2
2
import { auth } from '@/auth';
3
3
import { getOrganizationMembers, searchUsers } from '@/lib/repositories/team-repository';
4
4
import { getOrganizationRole } from '@/lib/repositories/user-repository';
5
+
import { verifyBotId } from '@/lib/botid-verification';
5
6
6
7
export const runtime = 'nodejs';
7
8
···
11
12
{ params }: { params: Promise<{ orgId: string }> }
12
13
) {
13
14
try {
15
+
// Check for bot before proceeding
16
+
const botVerification = await verifyBotId();
17
+
if (botVerification) {
18
+
return botVerification;
19
+
}
20
+
14
21
const { orgId } = await params;
15
22
const session = await auth();
16
23
if (!session?.user?.id) {
+10
-16
app/dashboard/lifecycle/page.tsx
+10
-16
app/dashboard/lifecycle/page.tsx
···
1
1
"use client";
2
2
3
3
import { useState, useEffect } from "react";
4
-
import { DateRange } from "react-day-picker";
5
4
import { AppSidebar } from "@/components/app-sidebar"
6
5
import { ChartAreaEngineering } from "@/components/chart-area-engineering"
7
-
import { DateRangePickerWithPresets } from "@/components/date-range-picker"
6
+
import { SimpleTimeRangePicker, type TimeRangeValue } from "@/components/simple-time-range-picker"
8
7
import { PRQualityDetails } from "@/components/pr-quality-details"
9
8
import { RepositoryFilter } from "@/components/repository-filter"
10
9
import { SiteHeader } from "@/components/site-header"
···
16
15
17
16
export default function LifecyclePage() {
18
17
const [selectedRepository, setSelectedRepository] = useState<string>("all");
19
-
const [dateRange, setDateRange] = useState<DateRange | undefined>();
18
+
const [timeRange, setTimeRange] = useState<TimeRangeValue>("30d");
20
19
const [chartData, setChartData] = useState<TimeSeriesDataPoint[]>([]);
21
20
const [loading, setLoading] = useState(true);
22
21
const [error, setError] = useState<string | null>(null);
···
35
34
params.append("repositoryId", selectedRepository);
36
35
}
37
36
38
-
if (dateRange?.from) {
39
-
params.append("startDate", dateRange.from.toISOString());
40
-
}
41
-
42
-
if (dateRange?.to) {
43
-
params.append("endDate", dateRange.to.toISOString());
44
-
}
37
+
// Use timeRange instead of specific dates
38
+
params.append("timeRange", timeRange);
45
39
46
40
const url = `/api/metrics/time-series${params.toString() ? `?${params.toString()}` : ''}`;
47
41
const response = await fetch(url);
···
61
55
};
62
56
63
57
fetchChartData();
64
-
}, [selectedRepository, dateRange]);
58
+
}, [selectedRepository, timeRange]);
65
59
66
60
const handleRepositoryChange = (repositoryId: string) => {
67
61
setSelectedRepository(repositoryId);
68
62
};
69
63
70
-
const handleDateRangeChange = (range: DateRange | undefined) => {
71
-
setDateRange(range);
64
+
const handleTimeRangeChange = (range: TimeRangeValue) => {
65
+
setTimeRange(range);
72
66
};
73
67
74
68
return (
···
92
86
onRepositoryChange={handleRepositoryChange}
93
87
selectedRepository={selectedRepository}
94
88
/>
95
-
<DateRangePickerWithPresets
96
-
onDateRangeChange={handleDateRangeChange}
97
-
selectedRange={dateRange}
89
+
<SimpleTimeRangePicker
90
+
value={timeRange}
91
+
onValueChange={handleTimeRangeChange}
98
92
/>
99
93
</div>
100
94
</div>
+61
components/simple-time-range-picker.tsx
+61
components/simple-time-range-picker.tsx
···
1
+
"use client"
2
+
3
+
import { CalendarIcon } from "lucide-react"
4
+
import { Button } from "@/components/ui/button"
5
+
import {
6
+
Select,
7
+
SelectContent,
8
+
SelectItem,
9
+
SelectTrigger,
10
+
SelectValue,
11
+
} from "@/components/ui/select"
12
+
13
+
export type TimeRangeValue = "7d" | "14d" | "30d" | "90d"
14
+
15
+
interface TimeRangeOption {
16
+
value: TimeRangeValue;
17
+
label: string;
18
+
description: string;
19
+
}
20
+
21
+
interface SimpleTimeRangePickerProps {
22
+
value?: TimeRangeValue;
23
+
onValueChange: (value: TimeRangeValue) => void;
24
+
className?: string;
25
+
}
26
+
27
+
const timeRangeOptions: TimeRangeOption[] = [
28
+
{ value: "7d", label: "Last 7 days", description: "Past week" },
29
+
{ value: "14d", label: "Last 14 days", description: "Past 2 weeks" },
30
+
{ value: "30d", label: "Last 30 days", description: "Past month" },
31
+
{ value: "90d", label: "Last 90 days", description: "Past quarter" },
32
+
];
33
+
34
+
export function SimpleTimeRangePicker({
35
+
value = "30d",
36
+
onValueChange,
37
+
className = ""
38
+
}: SimpleTimeRangePickerProps) {
39
+
const selectedOption = timeRangeOptions.find(option => option.value === value);
40
+
41
+
return (
42
+
<Select value={value} onValueChange={onValueChange}>
43
+
<SelectTrigger className={`w-[200px] ${className}`}>
44
+
<CalendarIcon className="mr-2 h-4 w-4" />
45
+
<SelectValue>
46
+
{selectedOption?.label || "Select time range"}
47
+
</SelectValue>
48
+
</SelectTrigger>
49
+
<SelectContent>
50
+
{timeRangeOptions.map((option) => (
51
+
<SelectItem key={option.value} value={option.value}>
52
+
<div className="flex flex-col">
53
+
<span className="font-medium">{option.label}</span>
54
+
<span className="text-xs text-muted-foreground">{option.description}</span>
55
+
</div>
56
+
</SelectItem>
57
+
))}
58
+
</SelectContent>
59
+
</Select>
60
+
)
61
+
}
+4
-6
components/ui/calendar.tsx
+4
-6
components/ui/calendar.tsx
···
60
60
...classNames,
61
61
}}
62
62
components={{
63
-
IconLeft: ({ className, ...props }) => (
64
-
<ChevronLeft className={cn("size-4", className)} {...props} />
65
-
),
66
-
IconRight: ({ className, ...props }) => (
67
-
<ChevronRight className={cn("size-4", className)} {...props} />
68
-
),
63
+
Chevron: ({ orientation, className, ...props }: { orientation?: 'up' | 'right' | 'left' | 'down'; className?: string; size?: number; disabled?: boolean }) => {
64
+
const Icon = orientation === 'left' ? ChevronLeft : ChevronRight
65
+
return <Icon className={cn("size-4", className)} {...props} />
66
+
},
69
67
}}
70
68
{...props}
71
69
/>
+62
instrumentation-client.ts
+62
instrumentation-client.ts
···
1
+
import { initBotId } from 'botid/client/core';
2
+
3
+
initBotId({
4
+
protect: [
5
+
{
6
+
path: '/api/organizations/*/teams',
7
+
method: 'POST',
8
+
},
9
+
{
10
+
path: '/api/organizations/*/teams/*',
11
+
method: 'PUT',
12
+
},
13
+
{
14
+
path: '/api/organizations/*/teams/*',
15
+
method: 'DELETE',
16
+
},
17
+
{
18
+
path: '/api/organizations/*/teams/*/members',
19
+
method: 'POST',
20
+
},
21
+
{
22
+
path: '/api/organizations/*/teams/*/members',
23
+
method: 'PUT',
24
+
},
25
+
{
26
+
path: '/api/organizations/*/teams/*/members',
27
+
method: 'DELETE',
28
+
},
29
+
{
30
+
path: '/api/organizations/*/ai-settings',
31
+
method: 'PUT',
32
+
},
33
+
{
34
+
path: '/api/organizations/*/categories',
35
+
method: 'POST',
36
+
},
37
+
{
38
+
path: '/api/categories/*',
39
+
method: 'PUT',
40
+
},
41
+
{
42
+
path: '/api/categories/*',
43
+
method: 'DELETE',
44
+
},
45
+
{
46
+
path: '/api/github/organizations/sync',
47
+
method: 'POST',
48
+
},
49
+
{
50
+
path: '/api/github/organizations/*/sync',
51
+
method: 'POST',
52
+
},
53
+
{
54
+
path: '/api/github/repositories/*/webhook',
55
+
method: 'POST',
56
+
},
57
+
{
58
+
path: '/api/github/repositories/*/webhook',
59
+
method: 'DELETE',
60
+
},
61
+
],
62
+
});
+41
lib/botid-verification.ts
+41
lib/botid-verification.ts
···
1
+
import { checkBotId } from 'botid/server';
2
+
import { NextRequest, NextResponse } from 'next/server';
3
+
4
+
/**
5
+
* Utility function to verify botid and return 403 if request is from a bot
6
+
* @returns Promise<NextResponse | null> - Returns 403 response if bot detected, null if verification passes
7
+
*/
8
+
export async function verifyBotId(): Promise<NextResponse | null> {
9
+
try {
10
+
// Check if the request is from a bot
11
+
const verification = await checkBotId();
12
+
13
+
if (verification.isBot) {
14
+
return NextResponse.json({ error: 'Access denied' }, { status: 403 });
15
+
}
16
+
17
+
return null; // Verification passed
18
+
} catch (error) {
19
+
console.error('BotId verification error:', error);
20
+
// In case of verification error, allow request to proceed to avoid blocking legitimate users
21
+
return null;
22
+
}
23
+
}
24
+
25
+
/**
26
+
* Higher-order function to wrap API route handlers with botid verification
27
+
*/
28
+
export function withBotIdVerification<T extends (...args: any[]) => Promise<NextResponse>>(
29
+
handler: T
30
+
): T {
31
+
return (async (...args: any[]) => {
32
+
// Check for bot before executing the handler
33
+
const botVerification = await verifyBotId();
34
+
if (botVerification) {
35
+
return botVerification;
36
+
}
37
+
38
+
// If verification passes, execute the original handler
39
+
return await handler(...args);
40
+
}) as T;
41
+
}
+13
lib/core/application/auth-middleware.ts
+13
lib/core/application/auth-middleware.ts
···
13
13
createAnonymousContext,
14
14
UserPermissions
15
15
} from './context'
16
+
import { verifyBotId } from '../../botid-verification'
16
17
17
18
export type AuthenticatedHandler<TRequest = NextRequest, TResponse = NextResponse> =
18
19
(context: ApplicationContext, request: TRequest) => Promise<TResponse>
···
28
29
): (request: TRequest) => Promise<TResponse | NextResponse> {
29
30
return async (request: TRequest) => {
30
31
try {
32
+
// Check for bot before proceeding
33
+
const botVerification = await verifyBotId();
34
+
if (botVerification) {
35
+
return botVerification;
36
+
}
37
+
31
38
const context = await createAuthenticatedContext(request)
32
39
33
40
if (!context) {
···
50
57
): (request: TRequest) => Promise<TResponse> {
51
58
return async (request: TRequest) => {
52
59
try {
60
+
// Check for bot before proceeding
61
+
const botVerification = await verifyBotId();
62
+
if (botVerification) {
63
+
return botVerification as TResponse;
64
+
}
65
+
53
66
const context = await createRequestContext(request)
54
67
return await handler(context, request)
55
68
} catch (error) {
+2
-1
next.config.ts
+2
-1
next.config.ts
+2
-1
package.json
+2
-1
package.json
···
47
47
"@tanstack/react-table": "^8.21.3",
48
48
"@types/jsonwebtoken": "^9.0.9",
49
49
"ai": "^4.3.15",
50
+
"botid": "^1.5.3",
50
51
"class-variance-authority": "^0.7.1",
51
52
"clsx": "^2.1.1",
52
53
"cmdk": "^1.1.1",
···
59
60
"next-auth": "5.0.0-beta.29",
60
61
"next-themes": "^0.4.6",
61
62
"react": "19.1.1",
62
-
"react-day-picker": "8.10.1",
63
+
"react-day-picker": "9.9.0",
63
64
"react-dom": "19.1.1",
64
65
"recharts": "^2.15.3",
65
66
"sonner": "^2.0.3",
+38
-7
pnpm-lock.yaml
+38
-7
pnpm-lock.yaml
···
106
106
ai:
107
107
specifier: ^4.3.15
108
108
version: 4.3.15(react@19.1.1)(zod@3.24.3)
109
+
botid:
110
+
specifier: ^1.5.3
111
+
version: 1.5.3(next@15.4.6(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)
109
112
class-variance-authority:
110
113
specifier: ^0.7.1
111
114
version: 0.7.1
···
143
146
specifier: 19.1.1
144
147
version: 19.1.1
145
148
react-day-picker:
146
-
specifier: 8.10.1
147
-
version: 8.10.1(date-fns@4.1.0)(react@19.1.1)
149
+
specifier: 9.9.0
150
+
version: 9.9.0(react@19.1.1)
148
151
react-dom:
149
152
specifier: 19.1.1
150
153
version: 19.1.1(react@19.1.1)
···
498
501
'@csstools/css-tokenizer@3.0.4':
499
502
resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==}
500
503
engines: {node: '>=18'}
504
+
505
+
'@date-fns/tz@1.4.1':
506
+
resolution: {integrity: sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==}
501
507
502
508
'@dnd-kit/accessibility@3.1.1':
503
509
resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==}
···
2350
2356
before-after-hook@3.0.2:
2351
2357
resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==}
2352
2358
2359
+
botid@1.5.3:
2360
+
resolution: {integrity: sha512-QMU3icRKLEjJIUxtCuMkzAzVc32lg97qTNN66VJnjPMBUB79YT0N7bA5RFdvxsw+iUMAh+uNnB/2KBneVwkxEA==}
2361
+
peerDependencies:
2362
+
next: '*'
2363
+
react: ^18.0.0 || ^19.0.0
2364
+
peerDependenciesMeta:
2365
+
next:
2366
+
optional: true
2367
+
react:
2368
+
optional: true
2369
+
2353
2370
brace-expansion@1.1.11:
2354
2371
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
2355
2372
···
2556
2573
resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
2557
2574
engines: {node: '>= 0.4'}
2558
2575
2576
+
date-fns-jalali@4.1.0-0:
2577
+
resolution: {integrity: sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==}
2578
+
2559
2579
date-fns@4.1.0:
2560
2580
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
2561
2581
···
4005
4025
queue-microtask@1.2.3:
4006
4026
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
4007
4027
4008
-
react-day-picker@8.10.1:
4009
-
resolution: {integrity: sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==}
4028
+
react-day-picker@9.9.0:
4029
+
resolution: {integrity: sha512-NtkJbuX6cl/VaGNb3sVVhmMA6LSMnL5G3xNL+61IyoZj0mUZFWTg4hmj7PHjIQ8MXN9dHWhUHFoJWG6y60DKSg==}
4030
+
engines: {node: '>=18'}
4010
4031
peerDependencies:
4011
-
date-fns: ^2.28.0 || ^3.0.0
4012
-
react: ^16.8.0 || ^17.0.0 || ^18.0.0
4032
+
react: '>=16.8.0'
4013
4033
4014
4034
react-dom@19.1.1:
4015
4035
resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==}
···
4968
4988
'@csstools/css-tokenizer': 3.0.4
4969
4989
4970
4990
'@csstools/css-tokenizer@3.0.4': {}
4991
+
4992
+
'@date-fns/tz@1.4.1': {}
4971
4993
4972
4994
'@dnd-kit/accessibility@3.1.1(react@19.1.1)':
4973
4995
dependencies:
···
6905
6927
6906
6928
before-after-hook@3.0.2: {}
6907
6929
6930
+
botid@1.5.3(next@15.4.6(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1):
6931
+
optionalDependencies:
6932
+
next: 15.4.6(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
6933
+
react: 19.1.1
6934
+
6908
6935
brace-expansion@1.1.11:
6909
6936
dependencies:
6910
6937
balanced-match: 1.0.2
···
7108
7135
call-bound: 1.0.4
7109
7136
es-errors: 1.3.0
7110
7137
is-data-view: 1.0.2
7138
+
7139
+
date-fns-jalali@4.1.0-0: {}
7111
7140
7112
7141
date-fns@4.1.0: {}
7113
7142
···
8840
8869
8841
8870
queue-microtask@1.2.3: {}
8842
8871
8843
-
react-day-picker@8.10.1(date-fns@4.1.0)(react@19.1.1):
8872
+
react-day-picker@9.9.0(react@19.1.1):
8844
8873
dependencies:
8874
+
'@date-fns/tz': 1.4.1
8845
8875
date-fns: 4.1.0
8876
+
date-fns-jalali: 4.1.0-0
8846
8877
react: 19.1.1
8847
8878
8848
8879
react-dom@19.1.1(react@19.1.1):