From 59faeab34a981548ee9cc6b744bba89171a1f332 Mon Sep 17 00:00:00 2001 From: web Date: Tue, 2 Sep 2025 06:00:28 -0700 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20Update=20compo?= =?UTF-8?q?nent=20imports=20and=20improve=20code=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Refactored sidebar component to include additional sheet elements and improved accessibility with SheetHeader, SheetTitle, and SheetDescription. - Updated skeleton component for better readability and consistency in class names. - Refined slider component by standardizing import statements and enhancing class name formatting. - Enhanced sonner component with consistent import statements and improved class name formatting. - Standardized switch component imports and class names for better readability. - Improved table component structure and class name consistency across various elements. - Refactored tabs component for better readability and consistent class name formatting. - Updated textarea component for improved readability and consistency in class names. - Fixed timeline component to safely access getBoundingClientRect. - Refactored toggle group and toggle components for improved readability and consistency in class names. - Updated tooltip component for better readability and consistent class name formatting. - Enhanced enhanced-input component to support generic types for better type safety. - Refactored use-mobile hook for improved readability and consistency. - Updated countries utility to make certain properties optional for better flexibility. - Refined tailwind configuration for improved readability and consistency in theme settings. --- .../auth-control/forms/device-form.tsx | 4 +- .../forms/email-settings-form.tsx | 14 +- .../auth-control/forms/google-form.tsx | 4 +- .../forms/phone-settings-form.tsx | 4 +- .../app/dashboard/coupon/coupon-form.tsx | 2 +- .../dashboard/log/traffic-details/page.tsx | 7 +- .../marketing/email/broadcast-form.tsx | 2 +- apps/admin/app/dashboard/nodes/node-form.tsx | 46 ++-- .../app/dashboard/payment/payment-form.tsx | 8 +- .../app/dashboard/product/subscribe-form.tsx | 35 +-- .../app/dashboard/servers/server-config.tsx | 4 +- .../app/dashboard/subscribe/protocol-form.tsx | 6 +- apps/admin/app/dashboard/user/user-form.tsx | 2 +- .../user-subscription/subscription-form.tsx | 2 +- .../(main)/(user)/profile/notify-settings.tsx | 8 +- apps/user/app/(main)/(user)/sidebar-right.tsx | 37 ++-- bun.lockb | Bin 640408 -> 652408 bytes packages/ui/package.json | 94 ++++----- packages/ui/src/components/calendar.tsx | 199 ++++++++++++++---- packages/ui/src/components/command.tsx | 1 - packages/ui/src/components/context-menu.tsx | 4 +- packages/ui/src/components/drawer.tsx | 12 +- packages/ui/src/components/dropdown-menu.tsx | 6 +- packages/ui/src/components/form.tsx | 8 +- packages/ui/src/components/hover-card.tsx | 2 +- packages/ui/src/components/menubar.tsx | 24 ++- .../ui/src/components/navigation-menu.tsx | 2 +- packages/ui/src/components/popover.tsx | 2 +- packages/ui/src/components/select.tsx | 4 +- packages/ui/src/components/sidebar.tsx | 28 ++- packages/ui/src/components/timeline.tsx | 2 +- packages/ui/src/components/tooltip.tsx | 2 +- .../src/custom-components/enhanced-input.tsx | 35 ++- packages/ui/src/utils/countries.ts | 8 +- 34 files changed, 366 insertions(+), 252 deletions(-) diff --git a/apps/admin/app/dashboard/auth-control/forms/device-form.tsx b/apps/admin/app/dashboard/auth-control/forms/device-form.tsx index 6ca62ed..d718e3a 100644 --- a/apps/admin/app/dashboard/auth-control/forms/device-form.tsx +++ b/apps/admin/app/dashboard/auth-control/forms/device-form.tsx @@ -34,8 +34,8 @@ import { z } from 'zod'; const deviceSchema = z.object({ id: z.number(), - method: z.string().default('device'), - enabled: z.boolean().default(false), + method: z.string(), + enabled: z.boolean(), config: z .object({ show_ads: z.boolean().optional(), diff --git a/apps/admin/app/dashboard/auth-control/forms/email-settings-form.tsx b/apps/admin/app/dashboard/auth-control/forms/email-settings-form.tsx index b3af6e1..6cd57f7 100644 --- a/apps/admin/app/dashboard/auth-control/forms/email-settings-form.tsx +++ b/apps/admin/app/dashboard/auth-control/forms/email-settings-form.tsx @@ -40,23 +40,23 @@ import { z } from 'zod'; const emailSettingsSchema = z.object({ id: z.number(), - method: z.string().default('email'), - enabled: z.boolean().default(false), + method: z.string(), + enabled: z.boolean(), config: z .object({ - enable_verify: z.boolean().default(false), - enable_domain_suffix: z.boolean().default(false), + enable_verify: z.boolean(), + enable_domain_suffix: z.boolean(), domain_suffix_list: z.string().optional(), verify_email_template: z.string().optional(), expiration_email_template: z.string().optional(), maintenance_email_template: z.string().optional(), traffic_exceed_email_template: z.string().optional(), - platform: z.string().default('smtp'), + platform: z.string(), platform_config: z .object({ host: z.string().optional(), - port: z.coerce.number().optional(), - ssl: z.boolean().default(false), + port: z.number().optional(), + ssl: z.boolean(), user: z.string().optional(), pass: z.string().optional(), from: z.string().optional(), diff --git a/apps/admin/app/dashboard/auth-control/forms/google-form.tsx b/apps/admin/app/dashboard/auth-control/forms/google-form.tsx index 8376389..66bec45 100644 --- a/apps/admin/app/dashboard/auth-control/forms/google-form.tsx +++ b/apps/admin/app/dashboard/auth-control/forms/google-form.tsx @@ -33,8 +33,8 @@ import { z } from 'zod'; const googleSchema = z.object({ id: z.number(), - method: z.string().default('google'), - enabled: z.boolean().default(false), + method: z.string().default('google').optional(), + enabled: z.boolean().default(false).optional(), config: z .object({ client_id: z.string().optional(), diff --git a/apps/admin/app/dashboard/auth-control/forms/phone-settings-form.tsx b/apps/admin/app/dashboard/auth-control/forms/phone-settings-form.tsx index d892d49..8772026 100644 --- a/apps/admin/app/dashboard/auth-control/forms/phone-settings-form.tsx +++ b/apps/admin/app/dashboard/auth-control/forms/phone-settings-form.tsx @@ -49,8 +49,8 @@ import { z } from 'zod'; const phoneSettingsSchema = z.object({ id: z.number(), - method: z.string().default('mobile'), - enabled: z.boolean().default(false), + method: z.string(), + enabled: z.boolean(), config: z .object({ enable_whitelist: z.boolean().optional(), diff --git a/apps/admin/app/dashboard/coupon/coupon-form.tsx b/apps/admin/app/dashboard/coupon/coupon-form.tsx index 0bc20c7..13a88cc 100644 --- a/apps/admin/app/dashboard/coupon/coupon-form.tsx +++ b/apps/admin/app/dashboard/coupon/coupon-form.tsx @@ -267,7 +267,7 @@ export default function CouponForm>({ date < new Date(Date.now() - 24 * 60 * 60 * 1000)} + disabled={(date: Date) => date < new Date(Date.now() - 24 * 60 * 60 * 1000)} onChange={(value) => { form.setValue(field.name, value); }} diff --git a/apps/admin/app/dashboard/log/traffic-details/page.tsx b/apps/admin/app/dashboard/log/traffic-details/page.tsx index 92a3509..2e24b57 100644 --- a/apps/admin/app/dashboard/log/traffic-details/page.tsx +++ b/apps/admin/app/dashboard/log/traffic-details/page.tsx @@ -1,5 +1,6 @@ 'use client'; +import { UserDetail } from '@/app/dashboard/user/user-detail'; import { ProTable } from '@/components/pro-table'; import { filterTrafficLogDetails } from '@/services/admin/log'; import { formatBytes, formatDate } from '@workspace/ui/utils'; @@ -22,7 +23,11 @@ export default function TrafficDetailsPage() { initialFilters={initialFilters} columns={[ { accessorKey: 'server_id', header: t('column.serverId') }, - { accessorKey: 'user_id', header: t('column.userId') }, + { + accessorKey: 'user_id', + header: t('column.userId'), + cell: ({ row }) => , + }, { accessorKey: 'subscribe_id', header: t('column.subscribeId') }, { accessorKey: 'upload', diff --git a/apps/admin/app/dashboard/marketing/email/broadcast-form.tsx b/apps/admin/app/dashboard/marketing/email/broadcast-form.tsx index 7919fb9..efba34e 100644 --- a/apps/admin/app/dashboard/marketing/email/broadcast-form.tsx +++ b/apps/admin/app/dashboard/marketing/email/broadcast-form.tsx @@ -47,7 +47,7 @@ export default function EmailBroadcastForm() { const emailBroadcastSchema = z.object({ subject: z.string().min(1, t('subject') + ' ' + t('cannotBeEmpty')), content: z.string().min(1, t('content') + ' ' + t('cannotBeEmpty')), - scope: z.string().default('all'), + scope: z.string(), register_start_time: z.string().optional(), register_end_time: z.string().optional(), additional: z diff --git a/apps/admin/app/dashboard/nodes/node-form.tsx b/apps/admin/app/dashboard/nodes/node-form.tsx index 65d65aa..34fa15b 100644 --- a/apps/admin/app/dashboard/nodes/node-form.tsx +++ b/apps/admin/app/dashboard/nodes/node-form.tsx @@ -42,39 +42,31 @@ export type ProtocolName = type ServerRow = API.Server; -export type NodeFormValues = { - name: string; - server_id?: number; - protocol: ProtocolName | ''; - address: string; - port: number; - tags: string[]; -}; +const buildSchema = (t: ReturnType) => + z.object({ + name: z.string().trim().min(1, t('errors.nameRequired')), + server_id: z + .number({ message: t('errors.serverRequired') }) + .int() + .gt(0, t('errors.serverRequired')) + .optional(), + protocol: z.string().min(1, t('errors.protocolRequired')), + address: z.string().trim().min(1, t('errors.serverAddrRequired')), + port: z + .number({ message: t('errors.portRange') }) + .int() + .min(1, t('errors.portRange')) + .max(65535, t('errors.portRange')), + tags: z.array(z.string()), + }); + +export type NodeFormValues = z.infer>; async function getServers(): Promise { const { data } = await filterServerList({ page: 1, size: 1000 }); return (data?.data?.list || []) as ServerRow[]; } -const buildSchema = (t: ReturnType) => - z.object({ - name: z.string().trim().min(1, t('errors.nameRequired')), - server_id: z.coerce - .number({ invalid_type_error: t('errors.serverRequired') }) - .int() - .gt(0, t('errors.serverRequired')), - protocol: z.custom((v) => typeof v === 'string' && v.length > 0, { - message: t('errors.protocolRequired'), - }), - address: z.string().trim().min(1, t('errors.serverAddrRequired')), - port: z.coerce - .number({ invalid_type_error: t('errors.portRange') }) - .int() - .min(1, t('errors.portRange')) - .max(65535, t('errors.portRange')), - tags: z.array(z.string()).default([]), - }); - export default function NodeForm(props: { trigger: string; title: string; diff --git a/apps/admin/app/dashboard/payment/payment-form.tsx b/apps/admin/app/dashboard/payment/payment-form.tsx index c1a44b3..868f05a 100644 --- a/apps/admin/app/dashboard/payment/payment-form.tsx +++ b/apps/admin/app/dashboard/payment/payment-form.tsx @@ -75,9 +75,9 @@ export default function PaymentForm({ icon: z.string().optional(), domain: z.string().optional(), config: z.any(), - fee_mode: z.coerce.number().min(0).max(2), - fee_percent: z.coerce.number().optional(), - fee_amount: z.coerce.number().optional(), + fee_mode: z.number().min(0).max(2), + fee_percent: z.number().optional(), + fee_amount: z.number().optional(), description: z.string().optional(), }); @@ -319,7 +319,7 @@ export default function PaymentForm({ }} defaultValue={field.value} value={field.value} - // @ts-expect-error + // @ts-expect-error - disabled prop type mismatch with SelectTrigger component disabled={isEdit && Boolean(initialValues?.platform)} > diff --git a/apps/admin/app/dashboard/product/subscribe-form.tsx b/apps/admin/app/dashboard/product/subscribe-form.tsx index 79cd8d6..13c9c65 100644 --- a/apps/admin/app/dashboard/product/subscribe-form.tsx +++ b/apps/admin/app/dashboard/product/subscribe-form.tsx @@ -87,7 +87,7 @@ export default function SubscribeForm>({ name: z.string(), description: z.string().optional(), unit_price: z.number(), - unit_time: z.string().default('Month'), + unit_time: z.string(), replacement: z.number().optional(), discount: z .array( @@ -97,22 +97,22 @@ export default function SubscribeForm>({ }), ) .optional(), - inventory: z.number().optional().default(-1), - speed_limit: z.number().optional().default(0), - device_limit: z.number().optional().default(0), - traffic: z.number().optional().default(0), - quota: z.number().optional().default(0), + inventory: z.number().optional(), + speed_limit: z.number().optional(), + device_limit: z.number().optional(), + traffic: z.number().optional(), + quota: z.number().optional(), group_id: z.number().optional().nullish(), // Use tags as group identifiers; accept string (tag) or number (legacy id) - node_tags: z.array(z.string()).optional().default([]), - nodes: z.array(z.number()).optional().default([]), - deduction_ratio: z.number().optional().default(0), - allow_deduction: z.boolean().optional().default(false), - reset_cycle: z.number().optional().default(0), - renewal_reset: z.boolean().optional().default(false), + node_tags: z.array(z.string()).optional(), + nodes: z.array(z.number()).optional(), + deduction_ratio: z.number().optional(), + allow_deduction: z.boolean().optional(), + reset_cycle: z.number().optional(), + renewal_reset: z.boolean().optional(), }); - const form = useForm({ + const form = useForm>({ resolver: zodResolver(formSchema), defaultValues: assign( defaultValues, @@ -204,7 +204,7 @@ export default function SubscribeForm>({ }); if (hasChanges) { - form.setValue(fieldName, calculatedValues, { shouldDirty: true }); + form.setValue(fieldName as any, calculatedValues, { shouldDirty: true }); } }, 300); }, @@ -321,6 +321,7 @@ export default function SubscribeForm>({ placeholder={t('form.selectSubscribeGroup')} {...field} + value={field.value ?? undefined} onChange={(value) => { form.setValue(field.name, value || 0); }} @@ -665,7 +666,8 @@ export default function SubscribeForm>({ min: 0, step: 0.01, formatInput: (value) => unitConversion('centsToDollars', value), - formatOutput: (value) => unitConversion('dollarsToCents', value), + formatOutput: (value) => + unitConversion('dollarsToCents', value).toString(), }, ]} value={field.value} @@ -911,7 +913,8 @@ export default function SubscribeForm>({ const keys = Object.keys(errors); for (const key of keys) { const formattedKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()); - toast.error(`${t(`form.${formattedKey}`)} is ${errors[key]?.message}`); + const error = (errors as any)[key]; + toast.error(`${t(`form.${formattedKey}`)} is ${error?.message}`); return false; } })} diff --git a/apps/admin/app/dashboard/servers/server-config.tsx b/apps/admin/app/dashboard/servers/server-config.tsx index 3473ca5..061fb51 100644 --- a/apps/admin/app/dashboard/servers/server-config.tsx +++ b/apps/admin/app/dashboard/servers/server-config.tsx @@ -96,8 +96,8 @@ function getTimeRangeData(slots: API.TimePeriod[]) { const nodeConfigSchema = z.object({ node_secret: z.string().optional(), - node_pull_interval: z.number().or(z.string().pipe(z.coerce.number())).optional(), - node_push_interval: z.number().or(z.string().pipe(z.coerce.number())).optional(), + node_pull_interval: z.number().optional(), + node_push_interval: z.number().optional(), }); type NodeConfigFormData = z.infer; diff --git a/apps/admin/app/dashboard/subscribe/protocol-form.tsx b/apps/admin/app/dashboard/subscribe/protocol-form.tsx index 2308105..686dc92 100644 --- a/apps/admin/app/dashboard/subscribe/protocol-form.tsx +++ b/apps/admin/app/dashboard/subscribe/protocol-form.tsx @@ -64,9 +64,9 @@ const createClientFormSchema = (t: any) => description: z.string().optional(), icon: z.string().optional(), user_agent: z.string().min(1, `User-Agent ${t('form.validation.userAgentRequiredSuffix')}`), - scheme: z.string().default(''), - template: z.string().default(''), - output_format: z.string().default(''), + scheme: z.string(), + template: z.string(), + output_format: z.string(), download_link: z.object({ windows: z.string().optional(), mac: z.string().optional(), diff --git a/apps/admin/app/dashboard/user/user-form.tsx b/apps/admin/app/dashboard/user/user-form.tsx index d8e2045..2a4d750 100644 --- a/apps/admin/app/dashboard/user/user-form.tsx +++ b/apps/admin/app/dashboard/user/user-form.tsx @@ -142,7 +142,7 @@ export default function UserForm>({ placeholder={t('areaCodePlaceholder')} value={field.value} onChange={(value) => { - form.setValue(field.name, value.phone); + form.setValue(field.name, value.phone as string); }} /> diff --git a/apps/admin/app/dashboard/user/user-subscription/subscription-form.tsx b/apps/admin/app/dashboard/user/user-subscription/subscription-form.tsx index 32881e7..25349ac 100644 --- a/apps/admin/app/dashboard/user/user-subscription/subscription-form.tsx +++ b/apps/admin/app/dashboard/user/user-subscription/subscription-form.tsx @@ -205,7 +205,7 @@ export function SubscriptionForm({ trigger, title, loading, initialData, onSubmi { if (value === field.value) { form.setValue(field.name, 0); diff --git a/apps/user/app/(main)/(user)/profile/notify-settings.tsx b/apps/user/app/(main)/(user)/profile/notify-settings.tsx index 0699048..3d0d9c2 100644 --- a/apps/user/app/(main)/(user)/profile/notify-settings.tsx +++ b/apps/user/app/(main)/(user)/profile/notify-settings.tsx @@ -13,10 +13,10 @@ import { toast } from 'sonner'; import { z } from 'zod'; const FormSchema = z.object({ - enable_balance_notify: z.boolean().default(false), - enable_login_notify: z.boolean().default(false), - enable_subscribe_notify: z.boolean().default(false), - enable_trade_notify: z.boolean().default(false), + enable_balance_notify: z.boolean(), + enable_login_notify: z.boolean(), + enable_subscribe_notify: z.boolean(), + enable_trade_notify: z.boolean(), }); export default function NotifySettings() { diff --git a/apps/user/app/(main)/(user)/sidebar-right.tsx b/apps/user/app/(main)/(user)/sidebar-right.tsx index f834d00..231e5d8 100644 --- a/apps/user/app/(main)/(user)/sidebar-right.tsx +++ b/apps/user/app/(main)/(user)/sidebar-right.tsx @@ -6,12 +6,6 @@ import useGlobalStore from '@/config/use-global'; import { Button } from '@workspace/ui/components/button'; import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card'; import { Sidebar, SidebarContent } from '@workspace/ui/components/sidebar'; -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from '@workspace/ui/components/tooltip'; import { Icon } from '@workspace/ui/custom-components/icon'; import { isBrowser } from '@workspace/ui/utils'; import { useTranslations } from 'next-intl'; @@ -54,25 +48,18 @@ export function SidebarRight({ ...props }: React.ComponentProps) {t('inviteCode')} - - - - { - if (result) { - toast.success(t('copySuccess')); - } - }} - > - - - - {t('copyInviteLink')} - - + { + if (result) { + toast.success(t('copySuccess')); + } + }} + > + + {user?.refer_code} diff --git a/bun.lockb b/bun.lockb index 094c46171183b500611d81a0a9d450d2fdc86d20..1fa0dd1e281ef667a063c8d566755ee3bfa8c5c5 100755 GIT binary patch delta 47213 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 delta 40599 zcmeFad0frg_dotRr!yjBD1}Hel?Dw|$Tbr(4@pU*iUuj9gb*PI+dK~$LZ-~~JkRqy zi;&sH^?R<@Yo9tU_kP}=@Avn6Jbr(?&%Mjq>$%t7d+oK?9$v5WI=wzWvzax~W~yE7 zb-RvuP8^%O@104g)Bd4nZ)`5TH|QcY%%OuvVatab}OIM!mi&a}t|W zPcGR_Ce##!lvCiA;Q3u;LN)N!-DN^`@KKP>z(@GV1QYNrkS)L~fR_V5&*eGb=8(g{ zO~JeOlIrOUxgul_@Cx9y!KvJ*-ZG)MAS9>6_mK%D0Xzjz8vFuydGP+eG6D9c?1W4e zC{VC0_?IqX!4zX~s%U=)NgnAZ$%z4x5!A~l$W)&{IMv^o^Zb4?p%~=BVZn)lP*)JH z1E8KY=L!wMVOdIja8is8kO{`%*1G#v6=e-{U#zOuo)jpR85|Z95Em3HL=K}S1;KBC zR5mU&D2nRuqVuZJq|NnU$%H8(l1cBt$w#T+RP$5t65vtbWXWmhlk5+fOm7BW1-!2A zc#W!B>w!|KI9)-F`qh?&OLfhSl**=oll!8;sf`{wFYAiQ?I2N&GoW1xyuo0ZPzk&W zIE~7%pp@QHTEsbuu7%3X&f|Ju90CxZ{15VNL7s`?IKM#^DR6(ZJ?#0OjEAXq} zGUW zaPr~cfSA}IXF&*xiVKSi3yPHkC!eRJNnLn@awOjdC;jwsk}KoE$pU{aA45L5^!<3L z{ycDs-_!}>*d(W%fKSK;ozi7O8SuT}RA3D_RpbaxVU|BpYVZa)H5d~V7#a{07yIWV zsp6X%QaSg@QZSu@OhL7qbM+KSZylFMgO|jpr!3?^rU(cr1DtFF2Sp5u8KRTbvPnLk zDHQ`67Zw>LfCt3H1SC$FCJpU6OQM4ibF191|1}7-t(6%d)T}(n=H<5t~4hcq9Bo!JIu)YH)B&SZri?tndXgg}@;u z#qb(%idFq2nFE>pnhH*ix1BBdWfEj6ryr2N51=$ab&Ez)AH@1~L2p3BprH|AA)#^8 zbUw8!$`ZKTCiB+`p$fV zOy%{R)f=zxl)jU^bCn9cu^knXH0Zx^i2Pfb4?d5C+lKzd=f;6n50TDE= zVNuaT!eWBT#mqY{nH(26Sgg?Ugf88#X4%(W1u;By$fht!Kd!rBS2I~(ZT|>SS?E6` zIGD@|3knKyb#5SJoR-wLqC2#vwLc@7wF;cfo&`>h434!8N{EXIXt+{p#tZsn?)ZL! znE&XkRDQ`hseDvWTx3A(z%Ifo0HhdyUTP?k^N^r8+aWPwg5L#cWV(Tq-J_vT`-mGF zAUSg2fUp?!^yo#&pq&?WH|p0+?tEFQb~-qndIkhZ9jtOia&I|sYId+~WB~bT1B#P; zQ5EU2Mmf6TUZRk$nmkaB*P~{rU*5@EjcnS);4O;fFL3Fjx^oR?-VerJcN{`0BHK? zz{vxnIgjN$kn?Wfv_7;0CxgB2=o&fL$zMLug*(`l4R|C?y0VX@N!sPnrqvD~ZFE_^ z>@_PVTYHSf&^^>l2UrYP2hp$s=yxJ-3Q^=0o8xnkN zShrwxX1_9%o~E1o%KFtT|MlX<7M{a5?6^Gc(&@p?YTec)^v%-Q`z7c$_*t5MwB3-> z>B;S(Nse|^50o>i-fEv88(zL{jPA3arOvXSy>4(n%TDFnJnn8ht;WOH39bLyyu8MU z5;iAI`z~B;xn|Yl7)En|*6 zZ?pXV_8uu6&ORJv-@bzHHQl0qO?999x#^nv*V1+BXIZ*$(rV{kBTH1jQnF!G+4Ak$ zY?|s{ZMO1j>*}SASU_)O9o@YzWt5g}3dKcv+D*0p9A8XnQG{6rYI2_`WNqpzi~kIU zHjrs6D!&v}Mw(geWZGKFGTOo_0UBF&kqPxNmPUwdQ=LO_T^&$uN1*mVWjco_SLJ$0 zZFP|Y-L?I@$%JqT4|Y|)gyhE}&1D{n?lQq&m%q|odkU%kdJU~z51G&jl3bS)=BgYC zsiiJE)LnT9sqQR$8%p++3C%^!52@~AYBN$@DW%o)k_jF3c4&t}^4Hg`yb7tksAYxg zoVFrfFu_$D35m*}&B3l(H(Vn%raYEYOy;J6gw+*N!8A!~Etbof>8dR4D-$~FvM0MM z2O`x-mmTJ=T#i(CUF2YQGD5%DEgv8oo$G_b~sX!aXCS*+9!~jpfV#C-Ad-F z%=AO1&Nkd#c^4^rUH(9KWvPBL!AqAP?5^#E6xpHD6$HC#r$cH1sTBP0s{I7XL$s>k zvzx|W8VI@0A&C*8Wlgk; zaCzs00)j4jzN@wXk_#k-&LPuPX){13)FV%5!;lh3MQm~tB+@d{MTfX*pBLs)mu-SD z7Ge!Kp{}wB7B&iv%m-)(P^O~+KglJf&S9CG27+WTb;c8ygAGJQhheVTOi1Ket&P18E2ZPKa>T+<`G6NQ3A%prJ8V=&{34oTTKs0;s6%5 zwhM?W@{8*nrnqX~L2`ry+ag?*j<}p{Mlq(zM2cozkrnTNP|xLJD>f05WTbNlch&ac z5@t6nn8GEwE_$n*0)jn@oF((nAVqFK5h$&XG?>WRACNkWl}G2eX`&=WIdkyAoPyL{ z%!2o1KUnPv7%!(m(jaOmie-^(6+q2OfGwd}6s#Qv%LHE_(m1S!gp&w`UX-i0L$tm> z@TxWy60HPcAS<0>WJ0Jea*KxoiS|0%WgZ$N(xv?MZkkwW(Gr!l`H*PVA|%l-cU*1L z@JPK(hD3cvlW>#K5Sb7qRf0f_hQtFA(!hAhR5&f#Re2OrSC$_IuMNeLSXd?zlH?~i zLwgbubx*RxCc)6EOh~;8TaHRJ=$`h>Pm=`l-7B&@bPsWwK zlT<0Xx)BmZ5*DannVT9C&4r?f2_7L6+5kbMVHT{198we*g@$M@0TE5tYisM^zCy6rAdSizNHk(btRNfV zJ4PR7l;;VFoTL_Ak_L&E0E;g+CwVxa@lcGy_h%{lSPpDj6it4heU2rQN7CM<0%BQ z=OP4=qM$<=Xvrr?b}DJb(6)p`?TIU(W)36@cQFRoy|GxEfHVc77PpIlbZKA3c5~28 z1A(d)yQry&8yw;o6z)CoKn74{qMz@5)M@}wZIwV>J7z8hO!iN>fb?aIodkecbTgWR>+nffCM&FqGddO@p{E_$S^b}uCAi+DhgsoC>o zSm+xw$!tC+$7>Y;{OGi(^qhrdPfRhS+Oz!Q@D5VaX^vKUkJ(bh%4nh0CP1P+1E;wq z@CPK(AIzaTRirnpnHMb%|m1rRLD4yY3;3RlbmoC+R5qPWN2IK)-kXs+ZQw2j$60MEJW)vWJb09gAO`?SlA<^6ybmYT| z^SQm^{Ot>g&tHV=Ge~5;R-6$77D%2eM^7oD#l_Y0J|tRQ#8pCDf1%#`97KJ#B@kBilU^v1gRy<&cH}4Gu$8(AW7REt$!CF z{k*7DU(Od5{W4>m2Ba10RSSaP0^_CYmFGZd@4}k*9bQ;bxZ(!8%4e-$;W@I#$}>Ql zv&bBoySD5~X(h*2H^Noh6%vKLC@H5=9?SQG+8rdRM}oNYRLYVG&X7uq2ZsZYX!J0{ z;Azz=X}*cOp|&L?X;p`-WvT4>CTzyn0P5$RtG2>wsepJ0RCb5tp^JRvuAGJxF14^~ z-9m~M35-{gtIULjZ9ye1*BBf^WGU=9K;vA1v@gLU!gbxf{*p_+a8-omBWycsCD&?n z(YRK51gSqtNK(sesVkC{4#{3@mrgbpAmIWCmoc^0AqH6fCYifDWgW}gDQhghy^ht{ z1<%%4k6_Z-9&^_&N6J?+8Ue9EKat5rn<3HCARaoEuOM~MW$*RSC%1_B)-;LPD}imhVVNO$cNq-ac~ z+D}93BpP2iS1OBnG0;^T0*R)*jOF-ZUm{7DjnbvI@vbw6LBJukr;BXmDx`er3R9`v zE-s2*m^Mh!!Y9?Z29mVcV+mHigVb5PJa4f>KToOM`H-ZeI4yJUAccoI*iQuna-oM}7bVD=iAbSWu=gfXwCv$pGQm~eZa2$23a?Mzjdg`0MEe{m$s4#H zR@&^53GQ^Us~JowloQu~=@JMCO%QBklU?Oc_ptEeSY%!H8lcJ;NKHjAY(xsT4Pe1% zr0AT0vs!6{f#*Ic@QaD7YbGSxuTilw6FpGs;zNcYxJ7gBXthKMmsw4j8yk-r*oy4OE_akmXVCgM<3T6{j1y^&z$z zWwmLCq;|@&f*LUQ7)0_zIi15USEbQmEGNvig3MhRi{u|-QhON5rqGcwhhn&kQ053k z>CAu>-vcn27D6goOm0J>JqM?@ktlPN78AOA;f<7?&i0#!1_@fM5T`gsK7vGTU~1vC zRpXdc6)xD*T{Zo=RJ8Ul0>T$F>=d^kQBC6UL}Phe+WLyLI|HFrOQS28h_f{$a;c~- zFF4NfF2F6dPZX{M;jZ$)6D<59(6vBapo_&8vHJiL*@#$s=_WhL>Rf_K-;+{76^kx| z-JeU?#b>%|&T~mJ#ece1bE@!Y1G~K-(W-`%JPrWSknAAg41{|e3n9@Ofq{qSYe?i; z1;Z7eo8~lbS&$^=^@2o>Rrd2Zs_u6H6*fF+_mJ7&a>4w;pM6qq!O4%IB^YzLhe%#RL?OPEm!uA3qG2EMf+VgXEV>$0 zQz25gz}A_r@*S60oja&64=7!?%2@OuC{?~JZM^UbOy~=VE@N?Vh0$6DiRyzvShF8P zlE#%rvfdSatkNaNU`XUZ@rHm}2S_uqYB~{HUe|j(2T{=-66H}vuG(3J5^B=i;8Nkms@CF$)RH(N z%ASyLtMQ75n!|~hH}ypdQr$F#0$DO15|2o2#~7VrcccNpa0I$4pFrxNvrTZ9d){TMpCEtY zU1>T=r`4N~$nDrU5lv?I^b!q84@k6)V`I$1IM4h^R9=SIoY}@>i@LA(f6h8rZ8t7y zm_r4+(F)OCJdN&0ibfwtGF;5OhD0+LW`w%R%^$GU&#_xAeSm`^%YKfo2@i3?5R=+g zNYWr7rjEF3CqR;xT69qU@gd90leJPh{dC`4oBoI|1+>M>_dH^&UtmA*e9ZEQXFSfW z^HNr)7V|ZcyRi`_a!u}Z6M2d(SuO}dXMD*+AL2^z9^fkQz8ohmgY3t7KaLZpEh~)6 z{|7u-Y%q#fK->rwMsps=apGja5O6YhD9<0p@!{a~Ax?&m;&>|Oqrs`(G;sP5FAYAk zc(T;vxd2K6Sj82HQ-QUduLmd3Z02$Fs ze-z-wNZ?%T0GCUElU$O^#K}{oB%Umk=0F+F%W__ha}#iCz!aPes0>aOR^_}JIJvYI zIDHH`m8%DwhO$1-|CwX_2_TE?Id|aP5u7~Z$$4vVYPc=WZ^vbCaQgg?ljpke{NHgI z+84U>3VZMhdvV?eoMIpxoO%!mPKHK-(}y_8gSbqbH?-;k5uIG#U&=Nob=KZ)bS$s^Oj31`N5nu~yi0H~tHT#+~_ zECZ)8%mODvS8;qTIDLM{X~=T9{x+^>$O$^k^N$#l|M58jfDAbUPKKN#EzSwQ#$`iJ z23-eE)9eK}$uGGcagy`7Oq}X{&G9#!7bNqiSsXoElVcS;=KJIDLrY*$2Vclq;B#0?Rg+S7f`)<(l99BgTpaui$r_hO8>p173~m z8FCs*Yv5#PO>lE?FRn+N%KgD*JqIK%Xjs&82fma&xB2f5MlSj94))(2j5aQ;;Q!sh z{=0+ycL&3|hi=wCSAtUsK9{-;fa!V`bK3-POnM zPt+=#e_&=}*Gfb79GrT_vwhlzUJte1ibdW_yfC}xjyQLl z4mo19p1lO*<>CdTkAj8DrXMSm>tOnS;_gKEG|Z zzs<8nyVtqb-1q5wzGu5a{?zah zSMJ++Ck|U#BKOtxeB1Pj+ZVPUm+U+BVXcl;KaaJjkYs)F>?5mD{R13-T&z3UF2EwP zigJJc5$hkP)2(bgFyb;n8hKY1Pzl}DR6=(TS3>_AvNGlXwh=JI9DqC9Pe7>JpjH(Cj|phO9I67iM!<}! z09vv81dOi=poJxXHZ0Q;fSV-sxsntivo878?-o~->%P>`m#EhhVuf`=5iwZ8KX%auT`2@#>pDGQ@ zHMSmbdxp`4KJ&X+f6rPrJGbHOGgD1iMm2?La?|=v#*RtQMQ6Hs+DTdQINuY=TR!+-ea}KS$Iz8spjqZKY8ktY_-q`t$^SErwYaXRzQVq=WF*NT(&;<{> zevW@_*}Y~}%ckkY%}X7sWYK*@rKx3V*pE88qWQ(qS@R<1`kUo>+}ph2$^Gp^qpR(U zUKgJ|cFDLlZgpetR%Q7xkKL|?;qSs~*T(Q?Sz-7yYGatX8Md_XbiH>?n_Ya?;0tSb z>*RwO$1et0EqO3tU3veG{$F)&K1+}0b?x$G;OteCTov2%?v`lZD`b4h&=}W*j0t=hhe>U+I(?%wY&ba*Y5&~wR|M+d&M!iQ(jf!W0$WEi>}E`Er-{= zbUrrzT=;;-kN!CIzTI2T>;2D1Ip>s{|7C{r5c^HJ>^tgBHoCi9Qz10;Kv36}Wz?Rt z)Rt+V>%`}-+Bfg`>B#kLLPW@v)t{}s!bcvnUwlv&)UjRTtI@^R%AT&B)}OiC%4^j$ z@NX|e>-t9i*gbH(Z~UI??JZ*cWoOKa6A9)-dl}uVsnb20r_|c6iMof1_;M`YQ)*J2_{L zZtcAFFS^`$aj;lG)Z|{5n%`*Ve%@tPVAQLZN!H=Fm^>BrbMb^UVtZX-GkK%q=%ZlUt zuk5^iHK)m(+soHfT5Vma_v(W)x?b_xx$nBG~KOND0Q%GQ(h0<E z`sI+9)g~L57s#~s=yk2y3gh+@_vFVI&F#PE^R0B7;ynj$Ogua1)WMd?wLg1J&uKUE z@%rNxl6ECmnDp-8+vj~(#2!eT+U!*Cy49@Oo?LK$qDhmdhQk)bdeuj@*HCTp$JhBy zbr!{g)7ETc%R<*XMh2&@d)9m!TT%MW&^jH5e*So+$;UJCD?B?^$V{*qi?0@|c~`$% zam>q9d7l5fg1P$*tPL@A=Ba_pCImbzbFNt{>({lbEb&#S@|Hij{=!aZysX5t-Nll( z^jo?9mLkjS;k~s1i~g)I@%#EWrOQ9BGq1_lFMZ{k)_;G?lIkE>Lq6?%o8{u)>uKM^ zyWW)4&UO#JC)}F4{n<0WGkz0;Gu3ytS@*8<#3@TC*SLHv8|pVB+P!$$@^6oYj`;Fv z(x--v49p8NG;hQ8t{1bGT>a=9G4z|&d7Gzc9s9KC&%RCRUb24Eqe_=X$Bxbq+z@}* zjQL!vT>L<_{+-wN-W=@Tc>KgBLGIti+rygLF`qZOjQcRBLgtgBf0UL_|EqT9)1yb`nlGxq<&)F>a7B!j&9bhaDjS$L z(9paVrWq~j9DHkC-EZ6K?~_9wet%GI|GU-r_Wp%Q+meCZXSjSF9v+g* zc@1i1ZF6c@>5CQWDO%c3`S9J+r+(vC_lD)z84bTwc1V7n&C(GTlMKv@G&HYtXJ^;< zxq%g$_xaN1TT)~8z2x!dJ8>g@*R4Kg(E`L)Rd1&{kb?l_fc z6+JNf{9@G&HtZ^o?=d;RPkIuXHF>m{N z_cO<8XJ1aeCePTbl$BiF$f?^z?Z}VSon{)C7j0SGs8IlvU~4A&=n>%qhQz zv+wPy`$Fbb9oH%*YhRruJzELGkC;8FVWp_?;F{*#s&!w>2hBA~RNOW*`m*8FD3(v= z)pdCu{eAA?Hsiky+WqkE#NBm|=;|E{n|y1_UhAbck(7bKQxd&(YEjkdns?#F>7d^Y~m+QKoS=Ykm z-2Kffb#;7gE8LjlyS>L4vo<^I-n>7$WRX?mr9*Z5H8mUDeQ-OU$KlPJvH5l|&!>IE za^v>id{x6_|JN^*I<$zMnOeMO-a(I^ld3(g;G0(VRcGUIS1NkG`L<`pUbR!>HA7a^ ztvfLO(~9O9sb@5=qPiHEH^k7q3r>&w#SiQ>KGI&*U~bn@3wzbFN~^Q6Uf%Wgl{?o^ zUK&`X&9v)^k2}l;o%C+^JonoAgn&KvM=p!Xcdr>Y&-G;?sC z;IYg9h3$~;2dB)uSJiZ(+<8+!hy1jjt9^ERZ28)+w6?P?&So9&$4s#Ix&N1SzX#8XGi4n=2h7Mmk?u6|9!mVv5JsdFh*v3oO;!fQ2Z@5D@_VlxpRo9zsJ9^k+ zQH}X=tttmK|1kV&+goia*19ySYAGw0Z4dLz7VV6TGke_AYx5O87A0>=Y2bSGhrh-zDWXH;>l^$#T2)UsFmJe_c~dXD znWX!g>}xmmvBjtdwh2j%ejI40JYxDRcgy&dD@*v#avs&=c7r-*+F9?WzHqv`ZTR{- zO+KC14cc0*?A{Rr%Jv_``Z~b8%Nc8}{LY=O+41S2z)CkB&3KVB46zkOpK!Ov1-2{wgT6X}o8UToN z2QZdxC*T?Zl|2BAV__Zu#ybNz4ZwSXp|!8iz5bdwy5hDy*Rvkx*LGZ9eOy{!->6<6 z+=ADy-l=@GU`1rR4_7ONFJD<|gZ}|<^8;-i6xCjSO#JS>`_YX0@$co#)&<61_C!My zS+&M!=$Q)|8rv8^20Kr{ELWUN`etlDIj{5HZ;B;r4;~+Ks$7b4WXsm)zUQ7@9C3TR zD-BGhI_BH6?Y(wiR5AJ>4dRIN4zS}!1Q-;NUJ9Fvky7$8D zTTMML7QYwy!z6cQz311K+%X$eX;u%$v)!E#XZ()P|UA3HQ!t+X*oB1W>sZfQ3x!1K=0|LkL*R z0tiTG44_*F088284ghL30r0pjfaPpEXjn-_qj z)&SP9;{-e-z_ty5Y?jytz^rBfZWFMc)ou%*^&bE-sFfUcpDO)KK#TSOHnGh10J53` z_&~rG=H(5bXA1z!y#eI10s=HG0Vq2H*v@=90@y~t76NuMStkIYtpEgd0FRXanFhIp`n@>kOb)TLP%JhnZOy0M`ge>H^>>J5Ip( zb^vU<0yxeRy8>`)58yTdCt2-o0G<($(G9?9cAbD(-T*wi131ejbO+G71Au%2&a;L+ z0DLB3eh&Z_*>eK2Is)+S3E(oD-4j61P5{0WaFw;`1wi8iAiEcU>+A~w+X(2}8^BGr zsyBep&H#-20JzP1^#Neo1;B0s?lP?}fMWzi`U1GmwiA%h6+q>_03Nciz5r@<18|yv z$IQ$Rz%>Gr{BWP{sgj-W!+pB(-GSKl1M*zShV=vD)&t0GLS86Y9e*It2+8mVlCNYp z2$|Irh-Uzh*GiTi0Hk#`y|r5z;pZ$X6v>9Rwt_FA(EkAm5d&cQ6oBKOnma`JrUR zLVz42Br*hDm$B_3^K4A0~94#y>LZ) znU*Dn190mPjoabSD9&mR1n>+%ZpJ{x)n3YgApBf9w@i}a4_U5#lEPGm-yJD(j~!Lq zD`F7AI0ZfMsi>g;g??Z}m>vCb1^Pbp<^fjawjz!4*{<6P z6M5KSwt9o2IztN{Vzrio72D(_PGVC>DipaR?khA(WfC3-GN!8gjeGV)k^Ah4a+VD{ z+h2LO*sQP8>gZ91nVP5?Cja$A`p|8^1bjt{g-U$T!cZnl=TLqXsgOrcWxz=uw4f92?Cs zdL(5A$Hs7so&=c6EgTDs8pcyA!gP*}6ZK#keUCPagX391c~!aO30$8HpU1N%0;5io z;VU^dnd{Ma>8Ch0RjgNfFyI`=s1M{=dN#)f9-=h$fw&3Cg?mjWVafCdAOtrKP6tTF z(*r!i;U!AX&@YMm4MCQ*j$d$ckifi9>7 z_PU}<>3NWY^#NYu6XOua?15e3*kO)206WI9Bh0~6RnGG$&vHW6Ur5vE7{~BPtf1j1 zrQ^WJcKn`193?Q}6dOfVoaX9y##JDH)8`C0bsrCG3gmD4oa1_U(P^52U?;(X@ZevF1p3=Xy^#)&f{Bjy>gA zOJMCd_6!&q(+Z@ahm2^=$m3vZr2VOD_`Kv;8>C;;B8JZ^USV6L7jf)0$Jzlq!e`hU zj7&vxz$20W=sOtpya7{d!ZcmgWGOx+ zIYzTk#j#Qx>jmsjQo^S+FmiuykX%NONZ?bJEA~O!h!-x$F<)SvIA#Lu66C%hAC5ia zdVat9r(QF zdIOL?4x)AG4c7}odKUC*gTDnvMS?-IIrf2<4Wa(e;T3-5U?{NN9Q(wvFkrx)5}W(r}&Ifk>780>_VP+|PZnmCXZ$QESG6={rA zJc3JdEFRcnr0G+NV?&XC!LiaDO8|DAV`Vs&2<#@u%5rQN#h(i@=u?h^!;z+FZUAn= zu@Oj9G!s^yV@XI4!;sLY0>?%o9nP_e9HSv_j5$s#tSK=3FQkB)5Js6*xZ)_Jn**dz zRgR@19RiG&VoQ#VM!Fxzs&Q-#FnTDJ^r{1+p&JXz=JnO!dTGGcbIcl8GGav-2igFT z*6~`r@OY#*a;y$8(whLvcHsZ%=I#nE+{5Kf(tMjiD{s<9Bah&bif9S z82syIUs9*UBO%O!gGR6Ko#@v^&-rU%vOGlJ{wL7JX)9t)ntvAsxNfLElPgl>4**7=X&gI?v=u_077`uD&LLe77_B4IId&fD#u!(c zvNJe#0cj78&E#0}MS%E)t*FR2cnR26t~iThmw|N$whVkW$F3ml$FVuUV1sZK)PrLS zxZX8jy*RcI7?R@D>@7#Qk%f!7;tizL$R%tE$8I7m=h#w?-2&DD*h=ta9J`HlKbqwD zEa%uAr2BAe1;_3Jqs@puD^(bO%D)GqIG|4!SGv$T<Si`Wfd;txmYdJRAQ6+t>8BPm|jQDJiLEskj*Q(?kxbBqoZ zRF+(Q2N(@!F~~#E%`ZsPMgvhOj(lFS()# z(p!06KF31KAc2piZSLf{s#h{k`n`-Ds6NOZ^H&;GZSnJrLb&_zM0FM86aK4w3hu>II@7qS76e08oEWASehF3obJp}bh>P_|_=bL{yRA4o;Gr5> zax`?tfEI(67_$zZs_w>gFP?6x)9vy}Y`Le(rj0YQT|o5n8f#EoF=MDCF#1Au2bJ3iq~t|UrkhvO48+HanMlEN_B3_ zrYbu{`8sf~2@Ij*`fDsFv`XG%nax!d*@osS3vX{!JO~sEN&*c7(P^4a&vaNm5279T zD2NWlbO@$H?`+Tv5dCz}7JN61k78ymR5oQdp{b1^8SIdQveYcRh3bx@2L9^?Rodix zf>J?;K~()UP-9e~H-+#u#w@L+>P|7jTVhCC$yt0W)t+LVY^7z`L)S&|_C|pcoK6z&02}&)G$R=yAXZ5Iwa>4_3B^0rdQ5FenH#0OSwq2I>Op3{rwR zfm}h}poXCKAbPUDF^KNWyMf*qu7t#XDk5yH~*R9GpRjgDoONvuD0m+F|y-21ic7e#Y zP&k%s<6l0Cj4*d#jsAv{>t5Ivmg4Aa^u z1!fhmG7A^`0V6shvjd1^N@GL>Ur;*`J#nwsBTi23YJibm2M`TN56T1Y0`dV-d2dj6 zC94vls>J*gRVLoPQ0fDs3{oVe)}YRy-oSf-dV=)c&^J!`gpsVz-^%(Xswz74g}Pp? zAJTrD$Sw*DYNkIpHAPQgw_*W_s&bVnI}oDY5>nB3yEUs8fyLoogi6EW5>=K;Qf?=L zvJOlZp(>}<7wyhG6IE7~^^VYY{?`W0s1C}eF6w;~T4;~hm~}X0Lp^;p`qoIlvt%5( z)2lD)qcZyDyFvc@SQysP3Hj9Fjv%UwTW{Db4V}ISskUYX@P)PBD$1rF7^;w0i+UpO zqF{cBstWAQK$VHShmy%7R4&$f3;*sQ!=6dj6spp5qK1Q~S1lUE7G#wk)~mJwM*X9{ zQmgv7)W;+hCm&JRk^j1h@gRn$I7WJXy`|zitsB&|MM zK*>mt0udh#qKQQO@8k?@5{OnN(xIiF(iw!aHX~K$$(cw#N7hvEDWHm2Y(iil?Hq(p z2c`o}162S<`BcUdGz%mHy$9_FtpXhY(beHu@I|15pt+zqAiBt+d>7P1H)&8NS=bGL z3ckfkw-}rXEd)`a`Jj2Ad?*twKspO_0Jpm++koi}%H{dQcYtQ1ak{g+3+bIaZx8rB&|VN-Jq`xp&tHjm9OpuRCy4Gs(8c{> z=rqCz9RlBh7!XLI0hG^3fGD3tT3_f0(xiM0bQE*~bR2XaWtPD3MIcH?p&p8k)5tpo zqI%zg(-(HPLDxZ7Km&na1it_}ulxh2EhKsaq#Lc5kp9`lMIQbq?_OrIQ3%DWC`yOm zYv6RSxdl!KVrtVL_R+mLa?DN0H$e35=0ot;pjV)L&~wmz&`Z!$&r-~>|dDH;qQ(BMxo$Jez4iWjJ07RX72i^>$C!>=f z=m+E#=;U9@2Ds9M@D218^e5;G=riaO=mSW>7G7KSO%H_GCW=uL%w*l1pfoZxr5w5G$*xef2yi}Ir?srs+>x<`tk9* zu4YD~Rn~xnT$|CVt#^!^?3~!W0CfeGqn(4joip3lLR~>&Z`VLz{@>LVjO^_kS^fU% z)DHH82gSzW6-a__z?l;-+iOPElKHvWHLz>YP!L~)gc_$ly>`cJ>Y?e#acF2~Z)Y!f zm`N|`7;ftRXV|!|!G$^OM}M`wkt^DE3{Z6Cn99WI7_IQr1reUw0&1AO< zb67!;x`HcNEqFu645d|ZJu|)QUA|XTum0^oXKMYi>CE-m+WOM0aj?1~9Eqm&FBI}i zXnFSSqda$B7)|S6Ikb%pdAIb=!Xg*5j9|5sOkn$i)n=7od}qlet<;fq`Zub2p4Z^Q z-UqAus~iw3@Q!bY+QG;f@isL?-Oi|is}s8uq7E^K^@C8nG^{`NxVUrEO)C%wZWJ&M z%s*6JQQ_PGWrl~U?UV>%J6E<2Ni_!4!5Ja-FjT!k2^1=`!qkC?G{*)gC<|BH;z9lT z;c7E&GJcU_kJ`U5ABZvq+kaGDo~4AV6|xE}XRErr5wn8GXNEs5%8vem3qq`Kcf)-_?B+MG=~@M~*ZSU^-^ zYkzO_H!V4_sXNv6{@xB(?9R^TsLRicR=4E}yu!cN%T519y|A}CS!6UEc7b`tsw=Sh z(dx>wr)(!dpV;MSbqlQ=-+s8jS@Fy&2Hlpk^D*jbta}VhlhU&O>|Kn3qF7aktgy){ zY;cUaEDU=ci(x&UYZa$1E|Xca`a{&-vidA(2+)QsX9${X&Q5}v>t6tAKj`f2%!*0Q za;!$qh&X$}pZy>O{Tm}KoXWacpQ|w+3J7Q93nQ6Ry!x!U{!Nj~CoHn6(_u+tC^Qh) zNgs*f2n!)CP6(B_9dz-$^6*O zM0H*5$^p{*jl`_FO1#}buwhfAK30IwFnJ8qgf0^W~f$g@A%)S)}BU~jTBn4Sr zHfS33^e>Ivb9?Z*%DIdFr0z<3{_HL)l0~sTDPXBAU^v(mW=rfTbC_8KzGK6G1-S}u z?J4_CDqNbu97aG|#@da5|0PW}YXo}EOIb6om4(fi#|@O0=?1A&tGS=uU$e-eyy(^> zc&HsapM*i}!K#i#(I^%@2`r7383i_%Ehg}1iK|F??A1urkt9>B zvbK5OoXfq+pj{`)H~6cp$B*Irb*VC>tC^XqWZ0m^A1g~0-F$f6n(sN<=CjvXi)#QL0gNlezT_RYxRrX zZym&q=7arH7i40^PI^PHvLsmeFXr$r++$@XqbEOk{$B=^>#bqlqY)Xr$y|0j19kj7 zvgcT}u>ha2%47c34mIY{X7mo_xK<3 zL@)j};(iOpvvw2Eo1Yd9XZ@>HonOpcGVIWU!RQ8`jry0hZVn8&t*R0?q$sB?J53dJ zXHO?!7X-X;!}|M~Yo6PNIAM!F8g`|6Ro} zM)?B5FM8#TQX&&-}<|LyNdLrQQ=FktZ;#)q0+C%`j_ZxXM8B@KD*ro6#n~q z%++ZN{H2ajQxO9{SIj4X6a~y8Q{6x|mHA|f<1X$WJZC{BVui1Ye7ECUMIuvAL$zGu zTY$8;I_qDxd&RSpMce*9Zm`!)TC4Rh=~d4??YMMYWMWay8@3zUGEO%EOAw=PrlDOE zR&_Zbz8OrN4#aGfW{Bg+ArLc}4ntpDVH^`Z|=bM@9UrBu0XvM%5&KuHEm~V=mSVsm&Nn^(5 zF&Oic$@rn-3x>GVzvTGw_oqGH)i_WZHQ>5}wpBi)eDHs2-dz9c<0)tUoMQ9Fu47TV z`D`&A3HZr?m*Sq`ZjeCcF&j1=V?Ac$>>?d|*d9Qp{C&eI`qxQvhd8i1>A3a(X13Y_ z=Vs$MXygv_BKDH?A@(O5GDlrkreTXo(y*O#)JtVUSiiYgq@-6YXbBF|zomKkhLDSC@+Zx>Ik*wSM+iGRUmYSpKb^TPP@gfMhQIuPyO1e9cefV5TJmjcbOD#4xSkXi zuxbl2OxbMELUmoMta`Pnrc^GlDax^B87Qi6 z386)jKf6f{{$^_N*%8l5Erwn?tG!rUP5Kg>#xfVHTPSnp<4>PUmlk3Y9W9F3^6W>F zS}Ci?Y_Uq2>t8C})X|~wE&uC%U>09lq-9LTx8WXa#u7AOu#mBDOVl0oGm`JceCeCD zv?zzqLBrK(9P5bH$XWjy>BS>&Rc|#?LGzY3t$)$<-1f)TWMl^r2dg@Nk)d6xD?yAvU z8R0J$Neeh%1*D6MqK)YFa`@!$D&ivkltr&Vxc#(cnd{%UJ>i*UrRKixFTxzYP%dD` zxM=#9!!^IE`o{W@-fzN;yY4BQ0)^kjAy@cK9CF|CtB>ErI9EtzWwPLlNvtlIx&Gbf zwk?{wnO^U1a2DozfAIJ@0dYaL!BMfE z(GqG0TAO=v74AF8FRf&GtJRLOj;!(;7#Pf4*PyAvY#=0a z{fn+!@z>|V>2%GH<#8Na2n84Y%gH-wjZ4W#cGW_Ge1)%v^{+1<7MM3z;WKM6a_9yY zc9zXqxv$o!TgzCApIXBdJ#e2wx>wauf3IrvTInUkZI13~o_%Q#?j*R`p0gSje`zst9N41!YE$KoY}~;VR|lRXpR+}==!o4`btU=nb*$}H+=lw~Hk*QO zv$3h`)F#!$+m3?%P3mh~ZEpU|ruZ?e(voY1|MV`LbX!WEww~?Vr#3}E{3rL{q?=Q0 zz#w%?Y}0gWu9*JTT)PeI)i$-Mx&9UI`qwd&Ws=SOMwr39!Jlu_b=Th^Q#9uKebjBUjjvbfe2u--X}R;8J+s?O*zCwvip! zp>8h^+Q>@pRGT`-ZIrVuqn}4D2_Ebm=a*idLcj%YhU9C)F$l%Rf&D?mj-z4{l-h=XkvQ+7&)zR{E)s zyjA*I!Mt>r&to<&9bYufe(9ejMdLqP@tf}cZU_v``_G)tW5{4FDhvzh>k9LK?!-R~ znDj-4`Tt^Z{bim=R{b1hzx%>N&O5B4`Kw=q|CjOie==HP`21@$>K6iTOyOYYzqcs# z@-LBKP`7x&@V^NP-l~2L!}qy@VMzQMv4v(B%(DM6B!08CibntM2i~Bs|1W*F^$#&= z(7k^hwx2`p=Sly66J&*c{?$Hl{qe!GvL-k;?XrF6ijE5J}nLU^`FiBU%t`Q2Q581ARf}x(t(H1ApYg47-MGa!2ZIsQ=x1BC2plj zCVKjRu`K;Vbn=bZz!m>8uMGUczwG^w##?M!>X3dV`Iklvy7xZ?l3~T%v;R`@uhxs@ zf0<2&lb5@vaK-!AJ^$ZUzpAv)|MTkilXvtRfq0Pnmkt?N&ddLg3-tdORz;T;3W``< z;+SaZv|coO4V^B29sc|8xc}AL|H%r#Hs4WK5XXWK!mpkvywb4P%_8oq>nO#GRq=AF zr~bONF`j+L;c;4_y~aYMY()e|T!pth1#?j&IMPfd@J8IFc~8x^$b(XzxY$xI!(B#r zk9ue#J}`rH)2S*Gw(hZ7Bj-)CSEy31Ji>}SRR^;RE_lEs@TIz&eE3ne<0Zy8?I?To z61|;vlxgzSj%?a;utvM!7JwT0A@|usB&j^dFrhe!||e3 za+rLW@z(U}rRml(^#w=5w4*a$NY+$(f#xz!vvV(C71^yJ74j)t`~>%0X0e@MW~=a& zC4PXCa&4xU`NxEbZN+h<`w>j`Qr(e7<*QTWkIu5U`RY0H(dXFYSKv#|u{y8O_gCkb zAGk&2dFkHl|I^o%M@3ae@$&}py*mmhjL14pq+}*CvKcB#rkNQoEQunTd$^Ddgc24Y zTyB{ynsrh$$Byy<5r&b)2nazLL>xJY8Xcl>A+k`r-+PZkf5jiX@4oN%-Tk{W z=X-Z%j9u0p+xR&4ypB$@S$tA1z3sp{e1_L~LNISVpVh!^tl!ES1=yJ!@v3aV zjC=gA|8;uyebQHUdaWw*D%u{9to>JU*%}wV&-W3u+$`VjUq^gl9)24A?#3qxpnjWrtMTXu-Gs zq<*YaeGx zJoD-*RZDMVh;F?o9cL)S@mpR#9hJal_x_sTe}g$D=at zS2jaPY=r!HKvH};%`i_*Zwo6gI((~8@zezBqqkx)TbrdIV$*tVyQH6Dk6)D-?o(#? zFo&Bt$0qBQ8A{==tvL7}ioZw*)-35BrdEaUscJ&#$IY=q_I3ZLwthn$WzQTTc z8#`cSCxWU^+i-F(uTyol;o@F?45M>;`2c$h{qCrf1hKzE!y(dZpE7)Oi}zMVwWH=S z^@%QR7uz56ot(<~Hr7Ao$GD8WE!SP+HTL;4YFljK4>$=k&czBFIIabM;)D@&>7dK9 zam(e5y&jWxZ2n1|dnnOtn`RD=aeS%?vQ8(O`Kvs1Nz{~-iI#LK8Z0GJYfkrW*>pE} z2hmcAU*9;bb#=g?6s4%-ca6HV@1Brw=rXQR3EK39H)J^n^1O|%+l-@D63w<~^s4AZ z>g==TM53AJ(m$JM`PCfp?M?-sT97w-UbU_1AkplFZuZpqwFYzOo^O=-7a{cM(Ua51 z8I^hCjg2lZPxJh#glLul>wI!uKP+84>1YkzaHbo$&GgNsGvjM-675R#iTbWDPAwT@ z>L!{Bc}8`|O>^4neO0Cw*>^eSZBy+8ajG4xjiMIe04%K$e8kId!V_nD^F-a0^j*;J zqyG^I6NjyV5x(4bF*p|zc(E1XB!{Ncf)g=}7K%oH_8z)g_bHTB0~iCS*r zlsL@|18*l*&?s$mn>XuNUBWZ9;ElD%K@g))z#M!0{dLf)f+k?5PVm96Ps7_%x2U5L zOxX4u_@K>5|JZ2Q^7Sj$`uq8_iyuqlAW2Bh1PDZJ1q5Ma1zDpP!I!fmYp|{eG`Kz= z-p5VF5PrRFub!7-z@()MyxldrM(BW-g*wkg3ktQVL$oKs}B&)2O?*5Bx$jIAOM#V)<$nnQtp0 zvYsGZFxt$p03Uwd=dGtvV2|k+!3BNq_T4jIq@eaQyA%Zu=u<`>>tB{w2EG{hq)%R2 z6e(9%2JVtilsJ@=O8d`|U2m6@1DUhriR=nmD{0-#M*V_%BPkXWE6GI3Y(phX600gf zWyb|#W}Pq!_0^P^kw1e2hgH=Oq1Cg5Sw@+Xw9=5YE+HvdDxiUSy?%U1PzVOszy>Tk zMZ!1#Li?h#22wcu>KCZMAU9HmMgs1xBh!;Qi7cfN?Ykhf)IpjP4H)y)EcsR@Cga{& z;3J-{2R9D8+yo7N+e}MZ3xolf;UKtTat_7Bvx&YOyRMmx7}o@^U}+O%;><>P2_H7Y z6wKX9;9ZT7hP9swju?I&Mq+p?XvD}X(8J;3Six2Fw!lyhf8Hs0Vqz1_WeYuU(KUE1 zW?hD{94=^v&;#L=OX+6>7xcJ7R;{=W?yl-fW~y=YXEUSv0b~3CMyvG~<(s-PvH2ct bJoVf%`NsA#hFYwqh)Ju2a?$Vr26F!b7yl+& diff --git a/packages/ui/package.json b/packages/ui/package.json index ed91c4f..93f1345 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -15,12 +15,12 @@ "./utils/*": "./src/utils/*.ts" }, "scripts": { - "lint": "eslint . --max-warnings 0" + "lint": "eslint ." }, "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", - "@hookform/resolvers": "^3.10.0", + "@hookform/resolvers": "^5.2.1", "@iconify-json/flagpack": "^1.2.2", "@iconify-json/logos": "^1.2.4", "@iconify-json/mdi": "^1.2.2", @@ -28,78 +28,78 @@ "@iconify-json/uil": "^1.2.3", "@iconify/react": "^5.2.0", "@monaco-editor/react": "^4.6.0", - "@radix-ui/react-accordion": "^1.2.2", - "@radix-ui/react-alert-dialog": "^1.1.4", - "@radix-ui/react-aspect-ratio": "^1.1.1", - "@radix-ui/react-avatar": "^1.1.2", - "@radix-ui/react-checkbox": "^1.1.3", - "@radix-ui/react-collapsible": "^1.1.2", - "@radix-ui/react-context-menu": "^2.2.4", - "@radix-ui/react-dialog": "^1.1.4", - "@radix-ui/react-dropdown-menu": "^2.1.4", - "@radix-ui/react-hover-card": "^1.1.4", - "@radix-ui/react-label": "^2.1.1", - "@radix-ui/react-menubar": "^1.1.4", - "@radix-ui/react-navigation-menu": "^1.2.3", - "@radix-ui/react-popover": "^1.1.4", - "@radix-ui/react-progress": "^1.1.1", - "@radix-ui/react-radio-group": "^1.2.2", - "@radix-ui/react-scroll-area": "^1.2.2", - "@radix-ui/react-select": "^2.1.4", - "@radix-ui/react-separator": "^1.1.1", - "@radix-ui/react-slider": "^1.2.2", - "@radix-ui/react-slot": "^1.1.1", - "@radix-ui/react-switch": "^1.1.2", - "@radix-ui/react-tabs": "^1.1.2", + "@radix-ui/react-accordion": "^1.2.12", + "@radix-ui/react-alert-dialog": "^1.1.15", + "@radix-ui/react-aspect-ratio": "^1.1.7", + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-collapsible": "^1.1.12", + "@radix-ui/react-context-menu": "^2.2.16", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-hover-card": "^1.1.15", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-menubar": "^1.1.16", + "@radix-ui/react-navigation-menu": "^1.2.14", + "@radix-ui/react-popover": "^1.1.15", + "@radix-ui/react-progress": "^1.1.7", + "@radix-ui/react-radio-group": "^1.3.8", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-select": "^2.2.6", + "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-slider": "^1.3.6", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-toast": "^1.2.4", - "@radix-ui/react-toggle": "^1.1.1", - "@radix-ui/react-toggle-group": "^1.1.1", - "@radix-ui/react-tooltip": "^1.1.6", + "@radix-ui/react-toggle": "^1.1.10", + "@radix-ui/react-toggle-group": "^1.1.11", + "@radix-ui/react-tooltip": "^1.2.8", "@tanstack/react-table": "^8.20.6", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "cmdk": "1.0.4", + "cmdk": "^1.1.1", "date-fns": "^4.1.0", - "embla-carousel-react": "^8.5.2", + "embla-carousel-react": "^8.6.0", "framer-motion": "^11.18.1", "input-otp": "^1.4.2", - "lucide-react": "^0.473.0", + "lucide-react": "^0.542.0", "mathjs": "^14.0.1", "monaco-themes": "^0.4.6", "motion": "^11.18.1", - "next-themes": "^0.4.4", - "react-day-picker": "8.10.1", - "react-hook-form": "^7.54.2", + "next-themes": "^0.4.6", + "react-day-picker": "^9.9.0", + "react-hook-form": "^7.62.0", "react-markdown": "^9.0.3", - "react-resizable-panels": "^2.1.7", + "react-resizable-panels": "^3.0.5", "react-syntax-highlighter": "^15.6.1", - "recharts": "^2.15.0", + "recharts": "2.15.4", "rehype-katex": "^7.0.1", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.0", "remark-math": "^6.0.0", "remark-toc": "^9.0.0", "rtl-detect": "^1.1.2", - "sonner": "^1.7.2", + "sonner": "^2.0.7", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7", "vaul": "^1.1.2", - "zod": "^3.24.1" + "zod": "^4.1.5" }, "devDependencies": { - "@turbo/gen": "^2.3.3", - "@types/node": "^22.10.5", - "@types/react": "^19.0.4", - "@types/react-dom": "^19.0.2", + "@turbo/gen": "^2.5.6", + "@types/node": "^24.3.0", + "@types/react": "^19.1.12", + "@types/react-dom": "^19.1.9", "@types/react-syntax-highlighter": "^15.5.13", "@types/rtl-detect": "^1.0.3", "@workspace/eslint-config": "workspace:*", "@workspace/typescript-config": "workspace:*", - "autoprefixer": "^10.4.20", - "postcss": "^8.4.49", - "react": "^19.0.0", - "react-dom": "^19.0.0", + "autoprefixer": "^10.4.21", + "postcss": "^8.5.6", + "react": "^19.1.1", + "react-dom": "^19.1.1", "tailwindcss": "^3.4.17", - "typescript": "^5.7.3" + "typescript": "^5.9.2" } } diff --git a/packages/ui/src/components/calendar.tsx b/packages/ui/src/components/calendar.tsx index 019b6f5..e7efbb0 100644 --- a/packages/ui/src/components/calendar.tsx +++ b/packages/ui/src/components/calendar.tsx @@ -1,69 +1,178 @@ 'use client'; -import { ChevronLeft, ChevronRight } from 'lucide-react'; +import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'; import * as React from 'react'; -import { DayPicker } from 'react-day-picker'; +import { DayButton, DayPicker, getDefaultClassNames } from 'react-day-picker'; -import { buttonVariants } from '@workspace/ui/components/button'; +import { Button, buttonVariants } from '@workspace/ui/components/button'; import { cn } from '@workspace/ui/lib/utils'; - export type CalendarProps = React.ComponentProps; -function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) { +function Calendar({ + className, + classNames, + showOutsideDays = true, + captionLayout = 'label', + buttonVariant = 'ghost', + formatters, + components, + ...props +}: React.ComponentProps & { + buttonVariant?: React.ComponentProps['variant']; +}) { + const defaultClassNames = getDefaultClassNames(); + return ( svg]:rotate-180`, + String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`, + className, + )} + captionLayout={captionLayout} + formatters={{ + formatMonthDropdown: (date) => date.toLocaleString('default', { month: 'short' }), + ...formatters, + }} classNames={{ - months: 'flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0', - month: 'space-y-4', - caption: 'flex justify-center pt-1 relative items-center', - caption_label: 'text-sm font-medium', - nav: 'space-x-1 flex items-center', - nav_button: cn( - buttonVariants({ variant: 'outline' }), - 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100', + root: cn('w-fit', defaultClassNames.root), + months: cn('relative flex flex-col gap-4 md:flex-row', defaultClassNames.months), + month: cn('flex w-full flex-col gap-4', defaultClassNames.month), + nav: cn( + 'absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1', + defaultClassNames.nav, ), - nav_button_previous: 'absolute left-1', - nav_button_next: 'absolute right-1', - table: 'w-full border-collapse space-y-1', - head_row: 'flex', - head_cell: 'text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]', - row: 'flex w-full mt-2', - cell: cn( - 'relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md', - props.mode === 'range' - ? '[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md' - : '[&:has([aria-selected])]:rounded-md', + button_previous: cn( + buttonVariants({ variant: buttonVariant }), + 'h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50', + defaultClassNames.button_previous, + ), + button_next: cn( + buttonVariants({ variant: buttonVariant }), + 'h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50', + defaultClassNames.button_next, + ), + month_caption: cn( + 'flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]', + defaultClassNames.month_caption, + ), + dropdowns: cn( + 'flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-sm font-medium', + defaultClassNames.dropdowns, + ), + dropdown_root: cn( + 'has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border', + defaultClassNames.dropdown_root, + ), + dropdown: cn('bg-popover absolute inset-0 opacity-0', defaultClassNames.dropdown), + caption_label: cn( + 'select-none font-medium', + captionLayout === 'label' + ? 'text-sm' + : '[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5', + defaultClassNames.caption_label, + ), + table: 'w-full border-collapse', + weekdays: cn('flex', defaultClassNames.weekdays), + weekday: cn( + 'text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal', + defaultClassNames.weekday, + ), + week: cn('mt-2 flex w-full', defaultClassNames.week), + week_number_header: cn('w-[--cell-size] select-none', defaultClassNames.week_number_header), + week_number: cn( + 'text-muted-foreground select-none text-[0.8rem]', + defaultClassNames.week_number, ), day: cn( - buttonVariants({ variant: 'ghost' }), - 'h-8 w-8 p-0 font-normal aria-selected:opacity-100', + 'group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md', + defaultClassNames.day, ), - day_range_start: 'day-range-start', - day_range_end: 'day-range-end', - day_selected: - 'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground', - day_today: 'bg-accent text-accent-foreground', - day_outside: - 'day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground', - day_disabled: 'text-muted-foreground opacity-50', - day_range_middle: 'aria-selected:bg-accent aria-selected:text-accent-foreground', - day_hidden: 'invisible', + range_start: cn('bg-accent rounded-l-md', defaultClassNames.range_start), + range_middle: cn('rounded-none', defaultClassNames.range_middle), + range_end: cn('bg-accent rounded-r-md', defaultClassNames.range_end), + today: cn( + 'bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none', + defaultClassNames.today, + ), + outside: cn( + 'text-muted-foreground aria-selected:text-muted-foreground', + defaultClassNames.outside, + ), + disabled: cn('text-muted-foreground opacity-50', defaultClassNames.disabled), + hidden: cn('invisible', defaultClassNames.hidden), ...classNames, }} components={{ - IconLeft: ({ className, ...props }) => ( - - ), - IconRight: ({ className, ...props }) => ( - - ), + Root: ({ className, rootRef, ...props }) => { + return
; + }, + Chevron: ({ className, orientation, ...props }) => { + if (orientation === 'left') { + return ; + } + + if (orientation === 'right') { + return ; + } + + return ; + }, + DayButton: CalendarDayButton, + WeekNumber: ({ children, ...props }) => { + return ( + +
+ {children} +
+ + ); + }, + ...components, }} {...props} /> ); } -Calendar.displayName = 'Calendar'; -export { Calendar }; +function CalendarDayButton({ + className, + day, + modifiers, + ...props +}: React.ComponentProps) { + const defaultClassNames = getDefaultClassNames(); + + const ref = React.useRef(null); + React.useEffect(() => { + if (modifiers.focused) ref.current?.focus(); + }, [modifiers.focused]); + + return ( +