From d7b105fa18615dd5d929801f3216053d4cb35dcd Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Tue, 19 May 2026 14:52:59 -0700 Subject: [PATCH 01/12] Add service locations and SSR initial data Introduce a static service locations module and wire server-side rendering to hydrate initial data for the appointment booking UI. Added src/data/service-locations.ts with ServiceLocation models and API-to-model mapping helpers; App.tsx refactored to render a public locations directory, location detail pages, and a booking landing page driven by the service locations list or a slug. entry-server.tsx now fetches visible offices from the API, maps them to ServiceLocation, and returns initialData; server.js injects a serialized initialData script into the HTML (with '<' escaped). entry-client.tsx reads window.__APPOINTMENT_BOOKING_INITIAL_DATA__ and passes locations and the current path into App for hydration. Also: updated styles (App.css, index.css) for layout and components, adjusted booking-api typing for getOffices, and updated tests to mock design system components and assert directory/detail/404 renderings. --- appointment-booking/src/App.css | 51 +++- appointment-booking/src/App.test.tsx | 73 ++++-- appointment-booking/src/App.tsx | 231 +++++++++++++++--- .../src/data/service-locations.ts | 121 +++++++++ appointment-booking/src/main.tsx | 18 +- .../src/services/booking-api.service.ts | 3 +- 6 files changed, 434 insertions(+), 63 deletions(-) create mode 100644 appointment-booking/src/data/service-locations.ts diff --git a/appointment-booking/src/App.css b/appointment-booking/src/App.css index 8e9b847e8..c2149cc8a 100644 --- a/appointment-booking/src/App.css +++ b/appointment-booking/src/App.css @@ -1,4 +1,53 @@ -/* App-specific styles - keep minimal */ #app { width: 100%; } + +.intro-paragraph { + max-width: 70ch; + font-size: 1.05rem; +} + +.content-section + .content-section { + margin-top: 2rem; +} + +.card-grid { + display: grid; + gap: 1rem; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); +} + +.location-card { + border: 1px solid #d8d8d8; + border-radius: 0.5rem; + padding: 1.25rem; + background: #fff; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); +} + +.location-card h3 { + margin-top: 0; +} + +.tag-list { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + list-style: none; + padding: 0; + margin: 1rem 0 0; +} + +.service-tag-item { + margin: 0; + padding: 0; +} + +.cta-paragraph { + margin-top: 1rem; +} + +.cta-paragraph button, +.cta-paragraph a { + display: inline-block; +} diff --git a/appointment-booking/src/App.test.tsx b/appointment-booking/src/App.test.tsx index 542d61e67..5b3895466 100644 --- a/appointment-booking/src/App.test.tsx +++ b/appointment-booking/src/App.test.tsx @@ -1,4 +1,4 @@ -import { render, screen, waitFor } from '@testing-library/react' +import { render, screen } from '@testing-library/react' import type { ReactNode } from 'react' import { describe, expect, it, vi, beforeEach } from 'vitest' import App from './App' @@ -13,15 +13,34 @@ vi.mock('@/components/common', () => ({ ), })) -const loadRuntimeConfigMock = vi.fn() -const getOfficesMock = vi.fn() - -vi.mock('@/services/runtime-config.service', () => ({ - loadRuntimeConfig: () => loadRuntimeConfigMock(), -})) - -vi.mock('@/services/booking-api.service', () => ({ - getOffices: () => getOfficesMock(), +vi.mock('@bcgov/design-system-react-components', () => ({ + Button: ({ children, variant, ...props }: any) => ( + + ), + Callout: ({ title, children }: any) => ( +
+

{title}

+ {children} +
+ ), + Heading: ({ level, children, ...props }: any) => { + const Tag = `h${level}` as any + return {children} + }, + Link: ({ children, href, ...props }: any) => ( + + {children} + + ), + TagGroup: ({ children, ...props }: any) =>
{children}
, + TagList: ({ children, items = [], ...props }: any) => ( +
+ {typeof children === 'function' ? items.map((item: any) => children(item)) : children} +
+ ), + Tag: ({ children }: any) => {children}, })) describe('App', () => { @@ -29,20 +48,30 @@ describe('App', () => { vi.clearAllMocks() }) - it('shows successful API bootstrap state', async () => { - loadRuntimeConfigMock.mockResolvedValue({ - apiBaseUrl: '/api/v1', - requestTimeoutMs: 10000, - }) - getOfficesMock.mockResolvedValue({ offices: [], errors: {} }) + it('renders the public Service BC locations directory', () => { + render() - render() + expect(screen.getByRole('heading', { name: 'Service BC Locations' })).toBeInTheDocument() + expect(screen.getByRole('link', { name: 'Service BC - Victoria Courthouse' })).toHaveAttribute( + 'href', + '/locations/victoria-courthouse', + ) + expect(screen.getAllByText('Monday to Friday, 8:30 a.m. to 4:30 p.m.')[0]).toBeInTheDocument() + expect(screen.getByText('Continue to the appointment booking flow')).toBeInTheDocument() + }) + + it('renders a public location detail page', () => { + render() + + expect(screen.getByRole('heading', { name: 'Service BC - Nanaimo Service Centre' })).toBeInTheDocument() + expect(screen.getByRole('heading', { name: 'Services at this location' })).toBeInTheDocument() + expect(screen.getByText('Start booking an appointment')).toBeInTheDocument() + }) - expect(screen.getByRole('heading', { name: 'Appointment Booking' })).toBeInTheDocument() + it('shows a public not found page for unknown locations', () => { + render() - await waitFor(() => { - expect(screen.getByText('API base URL: /api/v1')).toBeInTheDocument() - expect(screen.getByText('Booking API connection established.')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Location not found' })).toBeInTheDocument() + expect(screen.getByText('View all Service BC locations')).toBeInTheDocument() }) }) diff --git a/appointment-booking/src/App.tsx b/appointment-booking/src/App.tsx index 29393bc78..2f8700538 100644 --- a/appointment-booking/src/App.tsx +++ b/appointment-booking/src/App.tsx @@ -1,47 +1,202 @@ -import { useEffect, useState } from 'react' import { Layout, Page } from '@/components/common' -import { ApiClient, ApiClientError } from '@/services/api-client.service' -import { getOffices } from '@/services/booking-api.service' -import { loadRuntimeConfig } from '@/services/runtime-config.service' -import type { RuntimeConfig } from '@/models/runtime-config' +import { + getServiceLocationBySlug, + getServiceLocations, + type ServiceLocation, +} from '@/data/service-locations' +import { Button, Callout, Heading, Link, Tag, TagGroup, TagList } from '@bcgov/design-system-react-components' import './App.css' -function App() { - const [config, setConfig] = useState(null) - const [configError, setConfigError] = useState(null) - const [apiStatus, setApiStatus] = useState('Loading app settings...') - - useEffect(() => { - async function bootstrap() { - try { - const runtimeConfig = await loadRuntimeConfig() - setConfig(runtimeConfig) - setConfigError(null) - - const apiClient = new ApiClient(runtimeConfig) - await getOffices(apiClient) - setApiStatus('Booking API connection established.') - } catch (error) { - if (error instanceof ApiClientError) { - setApiStatus(`Booking API unavailable: ${error.message}`) - } else { - setConfigError('Failed to initialize application settings.') - setApiStatus('Booking API connection not attempted due to config error.') - } - } - } - - void bootstrap() - }, []) +type AppProps = { + initialPath?: string + locations?: ServiceLocation[] +} + +function getCurrentPath(initialPath?: string) { + if (initialPath) { + return initialPath + } + + if (typeof window !== 'undefined') { + return `${window.location.pathname}${window.location.search}${window.location.hash}` + } + + return '/locations' +} + +function renderServiceTags(location: ServiceLocation) { + const serviceItems = location.services.map((service) => ({ id: service, label: service })) + + return ( + +
+ + {(item: { id: string; label: string }) => ( + + {item.label} + + )} + +
+
+ ) +} + +function renderDirectoryPage(locations: ServiceLocation[]) { + + return ( + +

+ Browse Service BC locations, hours of operation, and the services available at each office. +

+ +
+ All locations +
+ {locations.map((location) => ( +
+ + {location.name} + +

{location.address}

+

+ Hours: {location.hours} +

+

{location.summary}

+ {renderServiceTags(location)} +
+ ))} +
+
+ +
+ +

+ Start from a service selection when you are ready to book. The location directory is + available separately for people who only need office information. +

+

+ + + +

+
+
+
+ ) +} + +function renderLocationDetailPage(location: ServiceLocation) { + return ( + +

View office details for {location.name}.

+ +
+ Location details +

{location.address}

+

+ Hours: {location.hours} +

+

{location.summary}

+
+ +
+ Services at this location + {renderServiceTags(location)} +
+ +
+ {location.appointmentsEnabledInd === 1 ? ( + +

+ Booking starts with choosing a service, then choosing an eligible location, then a date + and time. +

+

+ + + +

+
+ ) : ( + +

+ Online appointment booking is currently unavailable for this office. +

+
+ )} +
+
+ ) +} + +function renderBookingLandingPage() { + return ( + +

+ Start by choosing a service. The appointment flow will continue with eligible locations + and available times. +

+ +
+ +

+ This foundation keeps the booking flow service-focused so people can continue to a + location, then choose a date and time. +

+

+ + + +

+
+
+
+ ) +} + +function App({ initialPath, locations = getServiceLocations() }: AppProps) { + const currentPath = getCurrentPath(initialPath) + const locationMatch = currentPath.match(/^\/locations\/([^/?#]+)\/?$/) + const locationSlug = locationMatch?.[1] + const location = locationSlug ? getServiceLocationBySlug(locationSlug, locations) : null + + if (currentPath === '/book-an-appointment' || currentPath === '/book-an-appointment/') { + return ( + + {renderBookingLandingPage()} + + ) + } + + if (locationSlug && !location) { + return ( + + +

+ The Service BC location you requested does not exist in this directory. +

+

+ + + +

+
+
+ ) + } return ( - -

Check below if the API is working

-

{config ? `API base URL: ${config.apiBaseUrl}` : 'API base URL: loading...'}

-

{apiStatus}

- {configError ?

{configError}

: null} -
+ {location ? renderLocationDetailPage(location) : renderDirectoryPage(locations)}
) } diff --git a/appointment-booking/src/data/service-locations.ts b/appointment-booking/src/data/service-locations.ts new file mode 100644 index 000000000..3313599f3 --- /dev/null +++ b/appointment-booking/src/data/service-locations.ts @@ -0,0 +1,121 @@ +export interface ServiceLocation { + officeId: number + slug: string + name: string + address: string + hours: string + summary: string + services: string[] + appointmentsEnabledInd: 0 | 1 +} + +type OfficeApiService = { + service_name?: string + serviceName?: string + external_service_name?: string + externalServiceName?: string +} + +export interface OfficeApiModel { + office_id: number + office_name: string + civic_address?: string | null + office_appointment_message?: string | null + online_status?: string | null + appointments_enabled_ind?: number | null + quick_list?: OfficeApiService[] + back_office_list?: OfficeApiService[] +} + +const serviceLocations: ServiceLocation[] = [ + { + officeId: 94, + slug: 'victoria-courthouse', + name: 'Service BC - Victoria Courthouse', + address: '800 Fort St, Victoria, BC', + hours: 'Monday to Friday, 8:30 a.m. to 4:30 p.m.', + summary: 'Central downtown location serving residents and visitors across greater Victoria.', + services: ['BCID services', 'Driver licensing support', 'Housing and tenancy information'], + appointmentsEnabledInd: 1, + }, + { + officeId: 95, + slug: 'nanaimo-service-centre', + name: 'Service BC - Nanaimo Service Centre', + address: '4601 Rutherford Rd, Nanaimo, BC', + hours: 'Monday to Friday, 8:30 a.m. to 4:30 p.m.', + summary: 'A regional office supporting mid-Island service needs and public counter visits.', + services: ['Property tax support', 'Income assistance', 'Identity document assistance'], + appointmentsEnabledInd: 1, + }, + { + officeId: 96, + slug: 'kelowna-civic-centre', + name: 'Service BC - Kelowna Civic Centre', + address: '1435 Water St, Kelowna, BC', + hours: 'Monday to Friday, 8:30 a.m. to 4:30 p.m.', + summary: 'An Okanagan location with general counter services for the public.', + services: ['Accessible parking information', 'General office services', 'Public information support'], + appointmentsEnabledInd: 1, + }, +] + +function slugifyOfficeName(name: string) { + return name + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, '') +} + +function toOfficeServices(office: OfficeApiModel) { + const merged = [...(office.quick_list || []), ...(office.back_office_list || [])] + const services = merged + .map((service) => { + return ( + service.service_name || + service.serviceName || + service.external_service_name || + service.externalServiceName || + '' + ) + }) + .filter((name) => Boolean(name)) + + return Array.from(new Set(services)) +} + +function normalizeAppointmentsEnabled(value: number | null | undefined): 0 | 1 { + return value === 1 ? 1 : 0 +} + +export function mapApiOfficeToServiceLocation(office: OfficeApiModel): ServiceLocation { + const normalizedName = office.office_name.startsWith('Service BC - ') + ? office.office_name + : `Service BC - ${office.office_name}` + + return { + officeId: office.office_id, + slug: `${slugifyOfficeName(office.office_name)}-${office.office_id}`, + name: normalizedName, + address: office.civic_address || 'Address information unavailable', + hours: 'Hours not published online for this office.', + summary: office.office_appointment_message || 'Visit this office for in-person services and support.', + services: toOfficeServices(office), + appointmentsEnabledInd: normalizeAppointmentsEnabled(office.appointments_enabled_ind), + } +} + +export function mapApiOfficesToVisibleLocations(offices: OfficeApiModel[]): ServiceLocation[] { + return offices + .filter((office) => office.online_status === 'Status.SHOW') + .map(mapApiOfficeToServiceLocation) + .sort((a, b) => a.name.localeCompare(b.name)) +} + +export function getServiceLocations() { + return serviceLocations +} + +export function getServiceLocationBySlug(slug: string, locations: ServiceLocation[] = serviceLocations) { + return locations.find((location) => location.slug === slug) ?? null +} \ No newline at end of file diff --git a/appointment-booking/src/main.tsx b/appointment-booking/src/main.tsx index 43168c1bb..53311a3bc 100644 --- a/appointment-booking/src/main.tsx +++ b/appointment-booking/src/main.tsx @@ -4,9 +4,25 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App' +import type { ServiceLocation } from './data/service-locations' + +type InitialRenderData = { + locations?: ServiceLocation[] +} + +declare global { + interface Window { + __APPOINTMENT_BOOKING_INITIAL_DATA__?: InitialRenderData + } +} + +const initialData = window.__APPOINTMENT_BOOKING_INITIAL_DATA__ createRoot(document.getElementById('app')!).render( - + , ) diff --git a/appointment-booking/src/services/booking-api.service.ts b/appointment-booking/src/services/booking-api.service.ts index 8ab9b44a1..a121c95c9 100644 --- a/appointment-booking/src/services/booking-api.service.ts +++ b/appointment-booking/src/services/booking-api.service.ts @@ -1,5 +1,6 @@ import { ApiClient } from '@/services/api-client.service' +import type { OfficeApiModel } from '@/data/service-locations' export async function getOffices(client: ApiClient) { - return client.get('/offices/') + return client.get<{ offices: OfficeApiModel[] }>('/offices/') } From fc6c8aa2ec58afe261a6d53183f2598ed92cca53 Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Thu, 21 May 2026 13:59:22 -0700 Subject: [PATCH 02/12] Add office hours/email and UI/location changes Add office_hours and office_contact_email to the Office model and schema, with an Alembic migration to add/drop the new columns. Seed additional offices (Nanaimo, Kelowna), update existing office contact info and time slots in manage.py, and wire the new fields into the API-to-frontend mapping. Improve JWT setup in qsystem.py to skip initialization if well-known/jwks config is missing and log a warning. Frontend changes: overhaul appointment-booking styles and App.tsx to add a search bar, convert the card grid to an accessible location list, show contact/hours/email/phone with actions, handle empty service lists, and update sample location data. Expose Postgres on host port 5433 in compose.yaml. --- appointment-booking/src/App.css | 254 ++++++++++++++++-- appointment-booking/src/App.tsx | 144 ++++++++-- .../src/data/service-locations.ts | 33 ++- appointment-booking/src/index.css | 2 +- 4 files changed, 372 insertions(+), 61 deletions(-) diff --git a/appointment-booking/src/App.css b/appointment-booking/src/App.css index c2149cc8a..24389fe55 100644 --- a/appointment-booking/src/App.css +++ b/appointment-booking/src/App.css @@ -3,46 +3,211 @@ } .intro-paragraph { - max-width: 70ch; - font-size: 1.05rem; + max-width: 72ch; + font-size: var(--typography-font-size-large-body); + color: var(--typography-color-secondary); + margin-bottom: 1.5rem; } .content-section + .content-section { - margin-top: 2rem; + margin-top: 2.5rem; } -.card-grid { - display: grid; - gap: 1rem; - grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); +/* ── Search bar ────────────────────────────────────────────── */ +.search-bar-wrapper { + margin: 1.5rem 0 2rem; } -.location-card { - border: 1px solid #d8d8d8; - border-radius: 0.5rem; - padding: 1.25rem; - background: #fff; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); +.search-label { + display: block; + font-weight: var(--typography-font-weights-bold); + margin-bottom: 0.4rem; + font-size: var(--typography-font-size-body); } -.location-card h3 { - margin-top: 0; +.search-input-group { + position: relative; + max-width: 480px; } -.tag-list { - display: flex; - flex-wrap: wrap; - gap: 0.5rem; +.search-icon { + position: absolute; + left: 0.75rem; + top: 50%; + transform: translateY(-50%); + width: 1.1rem; + height: 1.1rem; + color: #767676; + pointer-events: none; +} + +.search-input { + width: 100%; + padding: 0.6rem 0.75rem 0.6rem 2.4rem; + border: var(--layout-border-width-medium) solid var(--surface-color-border-default); + border-radius: 0.375rem; + font-size: var(--typography-font-size-body); + font-family: var(--typography-font-families-bc-sans); + background: var(--surface-color-background-white); + box-sizing: border-box; + transition: border-color 0.15s; + color: var(--typography-color-primary); +} + +.search-input:focus { + outline: none; + border-color: var(--surface-color-border-active); + box-shadow: 0 0 0 3px rgba(46, 93, 215, 0.2); +} + +/* ── Location count badge ───────────────────────────────────── */ +.location-count { + font-size: var(--typography-font-size-body); + font-weight: var(--typography-font-weights-regular); + color: var(--typography-color-secondary); +} + +/* ── Location list (replaces card-grid) ────────────────────── */ +.location-list { list-style: none; padding: 0; margin: 1rem 0 0; + display: flex; + flex-direction: column; + gap: 0; + border-top: var(--layout-border-width-small) solid var(--surface-color-border-default); +} + +/* ── Location row ───────────────────────────────────────────── */ +.location-row { + border-bottom: var(--layout-border-width-small) solid var(--surface-color-border-default); + padding: 1.5rem 0; +} + +.location-row:hover { + background: var(--support-surface-color-info); + margin: 0 -1rem; + padding: 1.5rem 1rem; +} + +.location-row-title { + margin: 0 0 0.85rem; + font-size: var(--typography-font-size-h5) !important; +} + +.location-row-title a { + color: var(--typography-color-link); + text-decoration: none; + font-weight: var(--typography-font-weights-bold); +} + +.location-row-title a:hover { + text-decoration: underline; +} + +/* ── Three-column row body ──────────────────────────────────── */ +.location-row-body { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: 1rem 1.5rem; + align-items: start; +} + +@media (max-width: 860px) { + .location-row-body { + grid-template-columns: 1fr 1fr; + } + .location-col-services { + grid-column: 1 / -1; + } +} + +@media (max-width: 540px) { + .location-row-body { + grid-template-columns: 1fr; + } + .location-col-services { + grid-column: auto; + } +} + +/* ── Column label ───────────────────────────────────────────── */ +.col-label { + margin: 0 0 0.5rem; + font-size: var(--typography-font-size-label); + font-weight: var(--typography-font-weights-bold); + color: var(--typography-color-secondary); + text-transform: uppercase; + letter-spacing: 0.06em; +} + +/* ── Row action links ───────────────────────────────────────── */ +.location-row-actions { + display: flex; + align-items: center; + gap: 0.5rem; + margin-top: 0.85rem; + flex-wrap: wrap; +} + +.row-action-link { + font-size: var(--typography-font-size-small-body); + color: var(--typography-color-link); + text-decoration: none; +} + +.row-action-link:hover { + text-decoration: underline; +} + +.action-sep { + color: var(--typography-color-secondary); + font-size: var(--typography-font-size-small-body); +} + +/* ── Meta items (icon + text) ───────────────────────────────── */ +.location-meta-item { + display: flex; + align-items: flex-start; + gap: 0.45rem; + font-size: var(--typography-font-size-small-body); + color: var(--typography-color-primary); + margin-bottom: 0.4rem; + line-height: 1.4; } -.service-tag-item { +.location-meta-item:last-child { + margin-bottom: 0; +} + +.meta-icon { + width: var(--icons-size-small); + height: var(--icons-size-small); + flex-shrink: 0; + margin-top: 0.1rem; + color: var(--icons-color-secondary); +} + +.location-meta-item a { + color: var(--typography-color-link); + word-break: break-all; +} + +.no-services-text { + font-size: var(--typography-font-size-small-body); + color: var(--typography-color-placeholder); margin: 0; - padding: 0; + font-style: italic; } +/* ── Service tags ───────────────────────────────────────────── */ +/* Tags here are read-only labels — override the default pointer cursor */ +.location-col-services .bcds-react-aria-Tag, +.detail-services .bcds-react-aria-Tag { + cursor: default; +} + +/* ── CTA ────────────────────────────────────────────────────── */ .cta-paragraph { margin-top: 1rem; } @@ -51,3 +216,50 @@ .cta-paragraph a { display: inline-block; } + +/* ── Detail page ────────────────────────────────────────────── */ +.detail-list { + display: grid; + grid-template-columns: max-content 1fr; + gap: 0.25rem 1.5rem; + margin: 0.5rem 0 0; + padding: 0; +} + +.detail-item { + display: contents; +} + +.detail-item dt { + font-weight: var(--typography-font-weights-bold); + color: var(--typography-color-secondary); + font-size: var(--typography-font-size-small-body); + padding: 0.35rem 0; + white-space: nowrap; +} + +.detail-item dd { + margin: 0; + padding: 0.35rem 0; + font-size: var(--typography-font-size-body); + line-height: 1.5; +} + +.detail-item dd a { + color: var(--typography-color-link); +} + +@media (max-width: 480px) { + .detail-list { + grid-template-columns: 1fr; + gap: 0; + } + .detail-item dt { + padding-bottom: 0; + } + .detail-item dd { + padding-top: 0; + padding-bottom: 0.6rem; + } +} + diff --git a/appointment-booking/src/App.tsx b/appointment-booking/src/App.tsx index 2f8700538..0ecb9abfe 100644 --- a/appointment-booking/src/App.tsx +++ b/appointment-booking/src/App.tsx @@ -25,48 +25,111 @@ function getCurrentPath(initialPath?: string) { } function renderServiceTags(location: ServiceLocation) { - const serviceItems = location.services.map((service) => ({ id: service, label: service })) + if (location.services.length === 0) { + return

Contact this office for service information.

+ } + + const serviceItems = location.services.map((service) => ({ id: service, textValue: service })) return ( - -
- - {(item: { id: string; label: string }) => ( - - {item.label} - - )} - -
+ + + {(item) => } + ) } function renderDirectoryPage(locations: ServiceLocation[]) { - return (

Browse Service BC locations, hours of operation, and the services available at each office.

+
+ +
+ + +
+
+
- All locations -
+ + All locations ({locations.length}) + +
    {locations.map((location) => ( -
    - +
  • + {location.name} -

    {location.address}

    -

    - Hours: {location.hours} -

    -

    {location.summary}

    - {renderServiceTags(location)} -
  • +
    +
    +

    Contact

    +
    + + {location.address} +
    + {location.phone && ( +
    + + {location.phone} +
    + )} + {location.email && ( +
    + + {location.email} +
    + )} + +
    +
    +

    Hours of operation

    +
    + + {location.hours} +
    +
    +
    +

    Services available

    + {renderServiceTags(location)} +
    +
    + ))} -
+
@@ -95,11 +158,34 @@ function renderLocationDetailPage(location: ServiceLocation) {
Location details -

{location.address}

-

- Hours: {location.hours} -

-

{location.summary}

+
+
+
Address
+
{location.address}
+
+
+
Hours
+
{location.hours}
+
+ {location.phone && ( +
+
Phone
+
{location.phone}
+
+ )} + {location.email && ( +
+
Email
+
{location.email}
+
+ )} + {location.summary && ( +
+
About
+
{location.summary}
+
+ )} +
diff --git a/appointment-booking/src/data/service-locations.ts b/appointment-booking/src/data/service-locations.ts index 3313599f3..25265b5ac 100644 --- a/appointment-booking/src/data/service-locations.ts +++ b/appointment-booking/src/data/service-locations.ts @@ -4,6 +4,8 @@ export interface ServiceLocation { name: string address: string hours: string + phone: string + email: string summary: string services: string[] appointmentsEnabledInd: 0 | 1 @@ -23,6 +25,9 @@ export interface OfficeApiModel { office_appointment_message?: string | null online_status?: string | null appointments_enabled_ind?: number | null + telephone?: string | null + office_hours?: string | null + office_contact_email?: string | null quick_list?: OfficeApiService[] back_office_list?: OfficeApiService[] } @@ -32,8 +37,10 @@ const serviceLocations: ServiceLocation[] = [ officeId: 94, slug: 'victoria-courthouse', name: 'Service BC - Victoria Courthouse', - address: '800 Fort St, Victoria, BC', - hours: 'Monday to Friday, 8:30 a.m. to 4:30 p.m.', + address: '403-771 Vernon Ave, Victoria, BC V8W 9V1', + hours: 'Monday to Friday, 9 am to 4:30 pm', + phone: '250-387-6121', + email: 'ServiceBC.Victoria@gov.bc.ca', summary: 'Central downtown location serving residents and visitors across greater Victoria.', services: ['BCID services', 'Driver licensing support', 'Housing and tenancy information'], appointmentsEnabledInd: 1, @@ -42,9 +49,11 @@ const serviceLocations: ServiceLocation[] = [ officeId: 95, slug: 'nanaimo-service-centre', name: 'Service BC - Nanaimo Service Centre', - address: '4601 Rutherford Rd, Nanaimo, BC', - hours: 'Monday to Friday, 8:30 a.m. to 4:30 p.m.', - summary: 'A regional office supporting mid-Island service needs and public counter visits.', + address: '460 Selby St, Nanaimo, BC V9R 2R7', + hours: 'Monday to Friday, 9 am to 4:30 pm', + phone: '250-741-3636', + email: 'ServiceBC.Nanaimo@gov.bc.ca', + summary: 'Serving mid-Island residents and visitors.', services: ['Property tax support', 'Income assistance', 'Identity document assistance'], appointmentsEnabledInd: 1, }, @@ -52,9 +61,11 @@ const serviceLocations: ServiceLocation[] = [ officeId: 96, slug: 'kelowna-civic-centre', name: 'Service BC - Kelowna Civic Centre', - address: '1435 Water St, Kelowna, BC', - hours: 'Monday to Friday, 8:30 a.m. to 4:30 p.m.', - summary: 'An Okanagan location with general counter services for the public.', + address: '305-478 Bernard Ave, Kelowna, BC V1Y 6N7', + hours: 'Monday to Friday, 9 am to 4:30 pm', + phone: '250-861-7500', + email: 'ServiceBC.Kelowna@gov.bc.ca', + summary: 'Okanagan location with general counter services for the public.', services: ['Accessible parking information', 'General office services', 'Public information support'], appointmentsEnabledInd: 1, }, @@ -97,8 +108,10 @@ export function mapApiOfficeToServiceLocation(office: OfficeApiModel): ServiceLo officeId: office.office_id, slug: `${slugifyOfficeName(office.office_name)}-${office.office_id}`, name: normalizedName, - address: office.civic_address || 'Address information unavailable', - hours: 'Hours not published online for this office.', + address: office.civic_address || 'Address not available', + hours: office.office_hours || 'Hours not published online for this office.', + phone: office.telephone || '', + email: office.office_contact_email || '', summary: office.office_appointment_message || 'Visit this office for in-person services and support.', services: toOfficeServices(office), appointmentsEnabledInd: normalizeAppointmentsEnabled(office.appointments_enabled_ind), diff --git a/appointment-booking/src/index.css b/appointment-booking/src/index.css index 5e99c4717..0480fe3a3 100644 --- a/appointment-booking/src/index.css +++ b/appointment-booking/src/index.css @@ -3,7 +3,7 @@ line-height: 1.5; font-weight: 400; color: var(--typography-color-primary, #2d2d2d); - background-color: #f5f5f5; + background-color: var(--surface-color-background-light-gray); } body { From 159239418490beac85188d492abcaa393d832232 Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Wed, 20 May 2026 23:40:01 -0700 Subject: [PATCH 03/12] Use Buttons for navigation; update styles and tests Replace anchor-wrapped buttons with Button components that call a new navigateTo() helper (guards window access). Simplify tag rendering by removing the explicit Tag render and unused Tag import (use TagList directly). Update CSS to underline link elements and remove the service-tag cursor override. Adjust a location row Button to small. Update unit test expectation to reflect the changed hours string format. --- appointment-booking/src/App.css | 11 ++------- appointment-booking/src/App.test.tsx | 2 +- appointment-booking/src/App.tsx | 34 ++++++++++++++-------------- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/appointment-booking/src/App.css b/appointment-booking/src/App.css index 24389fe55..17af8ea75 100644 --- a/appointment-booking/src/App.css +++ b/appointment-booking/src/App.css @@ -97,7 +97,7 @@ .location-row-title a { color: var(--typography-color-link); - text-decoration: none; + text-decoration: underline; font-weight: var(--typography-font-weights-bold); } @@ -153,7 +153,7 @@ .row-action-link { font-size: var(--typography-font-size-small-body); color: var(--typography-color-link); - text-decoration: none; + text-decoration: underline; } .row-action-link:hover { @@ -200,13 +200,6 @@ font-style: italic; } -/* ── Service tags ───────────────────────────────────────────── */ -/* Tags here are read-only labels — override the default pointer cursor */ -.location-col-services .bcds-react-aria-Tag, -.detail-services .bcds-react-aria-Tag { - cursor: default; -} - /* ── CTA ────────────────────────────────────────────────────── */ .cta-paragraph { margin-top: 1rem; diff --git a/appointment-booking/src/App.test.tsx b/appointment-booking/src/App.test.tsx index 5b3895466..79525080b 100644 --- a/appointment-booking/src/App.test.tsx +++ b/appointment-booking/src/App.test.tsx @@ -56,7 +56,7 @@ describe('App', () => { 'href', '/locations/victoria-courthouse', ) - expect(screen.getAllByText('Monday to Friday, 8:30 a.m. to 4:30 p.m.')[0]).toBeInTheDocument() + expect(screen.getAllByText('Monday to Friday, 9 am to 4:30 pm')[0]).toBeInTheDocument() expect(screen.getByText('Continue to the appointment booking flow')).toBeInTheDocument() }) diff --git a/appointment-booking/src/App.tsx b/appointment-booking/src/App.tsx index 0ecb9abfe..b4da90e7b 100644 --- a/appointment-booking/src/App.tsx +++ b/appointment-booking/src/App.tsx @@ -4,7 +4,7 @@ import { getServiceLocations, type ServiceLocation, } from '@/data/service-locations' -import { Button, Callout, Heading, Link, Tag, TagGroup, TagList } from '@bcgov/design-system-react-components' +import { Button, Callout, Heading, Link, TagGroup, TagList } from '@bcgov/design-system-react-components' import './App.css' type AppProps = { @@ -12,6 +12,12 @@ type AppProps = { locations?: ServiceLocation[] } +function navigateTo(path: string) { + if (typeof window !== 'undefined') { + window.location.assign(path) + } +} + function getCurrentPath(initialPath?: string) { if (initialPath) { return initialPath @@ -32,10 +38,8 @@ function renderServiceTags(location: ServiceLocation) { const serviceItems = location.services.map((service) => ({ id: service, textValue: service })) return ( - - - {(item) => } - + + ) } @@ -108,9 +112,9 @@ function renderDirectoryPage(locations: ServiceLocation[]) { Get directions - +
@@ -139,11 +143,9 @@ function renderDirectoryPage(locations: ServiceLocation[]) { available separately for people who only need office information.

- - - +

@@ -201,11 +203,9 @@ function renderLocationDetailPage(location: ServiceLocation) { and time.

- - - +

) : ( From affe1ff4b3d01c77578ca5fdc75b99e47a0d486e Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Tue, 26 May 2026 21:36:49 -0700 Subject: [PATCH 04/12] Hide booking CTAs, add test office, update defaults Hide per-location "Book an appointment" CTAs when appointments are disabled and remove the global booking callouts from directory and detail pages. Add a non-bookable test office to the serviceLocations fixture and extend tests to cover the non-bookable state; update test expectations accordingly. Adjust intro copy/title and add a CSS rule for the directory intro paragraph. Change API fallback values to explicit "TODO - Data not available from API" placeholders. Update compose.yaml to use postgres:16 and expose port 5432 for local development. --- appointment-booking/src/App.css | 4 ++ appointment-booking/src/App.test.tsx | 26 +++++++++- appointment-booking/src/App.tsx | 51 ++++--------------- .../src/data/service-locations.ts | 22 ++++++-- compose.yaml | 1 + 5 files changed, 56 insertions(+), 48 deletions(-) diff --git a/appointment-booking/src/App.css b/appointment-booking/src/App.css index 17af8ea75..728276b3f 100644 --- a/appointment-booking/src/App.css +++ b/appointment-booking/src/App.css @@ -9,6 +9,10 @@ margin-bottom: 1.5rem; } +.directory-intro-paragraph { + max-width: none; +} + .content-section + .content-section { margin-top: 2.5rem; } diff --git a/appointment-booking/src/App.test.tsx b/appointment-booking/src/App.test.tsx index 79525080b..1aa9e552b 100644 --- a/appointment-booking/src/App.test.tsx +++ b/appointment-booking/src/App.test.tsx @@ -2,6 +2,7 @@ import { render, screen } from '@testing-library/react' import type { ReactNode } from 'react' import { describe, expect, it, vi, beforeEach } from 'vitest' import App from './App' +import type { ServiceLocation } from './data/service-locations' vi.mock('@/components/common', () => ({ Layout: ({ children }: { children: ReactNode }) =>
{children}
, @@ -57,7 +58,7 @@ describe('App', () => { '/locations/victoria-courthouse', ) expect(screen.getAllByText('Monday to Friday, 9 am to 4:30 pm')[0]).toBeInTheDocument() - expect(screen.getByText('Continue to the appointment booking flow')).toBeInTheDocument() + expect(screen.getAllByText('Book an appointment')).toHaveLength(3) }) it('renders a public location detail page', () => { @@ -65,7 +66,28 @@ describe('App', () => { expect(screen.getByRole('heading', { name: 'Service BC - Nanaimo Service Centre' })).toBeInTheDocument() expect(screen.getByRole('heading', { name: 'Services at this location' })).toBeInTheDocument() - expect(screen.getByText('Start booking an appointment')).toBeInTheDocument() + expect(screen.queryByText('Start booking an appointment')).not.toBeInTheDocument() + }) + + it('hides booking button and shows unavailable state for non-bookable office', () => { + const nonBookableOffice: ServiceLocation = { + officeId: 999, + slug: 'test-office', + name: 'Service BC - Test Office', + address: '123 Test St, Victoria, BC V8V 1A1', + hours: 'Monday to Friday, 9 am to 4:30 pm', + phone: '250-000-0000', + email: 'ServiceBC.TestOffice@gov.bc.ca', + summary: 'Test office for verifying non-bookable location behavior.', + services: ['General information'], + appointmentsEnabledInd: 0, + } + + render() + + expect(screen.getByRole('heading', { name: 'Service BC - Test Office' })).toBeInTheDocument() + expect(screen.queryByText('Start booking an appointment')).not.toBeInTheDocument() + expect(screen.queryByText('Online appointment booking is currently unavailable for this office.')).not.toBeInTheDocument() }) it('shows a public not found page for unknown locations', () => { diff --git a/appointment-booking/src/App.tsx b/appointment-booking/src/App.tsx index b4da90e7b..83590d03c 100644 --- a/appointment-booking/src/App.tsx +++ b/appointment-booking/src/App.tsx @@ -46,8 +46,8 @@ function renderServiceTags(location: ServiceLocation) { function renderDirectoryPage(locations: ServiceLocation[]) { return ( - -

+ +

Browse Service BC locations, hours of operation, and the services available at each office.

@@ -111,10 +111,14 @@ function renderDirectoryPage(locations: ServiceLocation[]) { > Get directions - - + {location.appointmentsEnabledInd === 1 && ( + <> + + + + )}
@@ -136,19 +140,6 @@ function renderDirectoryPage(locations: ServiceLocation[]) {
-
- -

- Start from a service selection when you are ready to book. The location directory is - available separately for people who only need office information. -

-

- -

-
-
) } @@ -194,28 +185,6 @@ function renderLocationDetailPage(location: ServiceLocation) { Services at this location {renderServiceTags(location)} - -
- {location.appointmentsEnabledInd === 1 ? ( - -

- Booking starts with choosing a service, then choosing an eligible location, then a date - and time. -

-

- -

-
- ) : ( - -

- Online appointment booking is currently unavailable for this office. -

-
- )} -
) } diff --git a/appointment-booking/src/data/service-locations.ts b/appointment-booking/src/data/service-locations.ts index 25265b5ac..f666af86f 100644 --- a/appointment-booking/src/data/service-locations.ts +++ b/appointment-booking/src/data/service-locations.ts @@ -69,6 +69,18 @@ const serviceLocations: ServiceLocation[] = [ services: ['Accessible parking information', 'General office services', 'Public information support'], appointmentsEnabledInd: 1, }, + { + officeId: 999, + slug: 'test-office', + name: 'Service BC - Test Office', + address: '123 Test St, Victoria, BC V8V 1A1', + hours: 'Monday to Friday, 9 am to 4:30 pm', + phone: '250-000-0000', + email: 'ServiceBC.TestOffice@gov.bc.ca', + summary: 'Test office for verifying non-bookable location behavior.', + services: ['General information'], + appointmentsEnabledInd: 0, + }, ] function slugifyOfficeName(name: string) { @@ -108,11 +120,11 @@ export function mapApiOfficeToServiceLocation(office: OfficeApiModel): ServiceLo officeId: office.office_id, slug: `${slugifyOfficeName(office.office_name)}-${office.office_id}`, name: normalizedName, - address: office.civic_address || 'Address not available', - hours: office.office_hours || 'Hours not published online for this office.', - phone: office.telephone || '', - email: office.office_contact_email || '', - summary: office.office_appointment_message || 'Visit this office for in-person services and support.', + address: office.civic_address || 'TODO - Data not available from API', + hours: office.office_hours || 'TODO - Data not available from API', + phone: office.telephone || 'TODO - Data not available from API', + email: office.office_contact_email || 'TODO - Data not available from API', + summary: office.office_appointment_message || 'TODO - Data not available from API', services: toOfficeServices(office), appointmentsEnabledInd: normalizeAppointmentsEnabled(office.appointments_enabled_ind), } diff --git a/compose.yaml b/compose.yaml index 6ef7cb034..98ceb542d 100644 --- a/compose.yaml +++ b/compose.yaml @@ -36,6 +36,7 @@ services: POSTGRES_DB: postgres POSTGRES_PASSWORD: postgres POSTGRES_USER: postgres + healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"] interval: 5s From ca71f916aedb433055472357a20b0dffcca1f822 Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Thu, 28 May 2026 17:03:46 -0700 Subject: [PATCH 05/12] Squashed commit of the following: commit d0e2d3c2ff776a07fd75a52c6ddd5d4ff4744677 Author: Veenu Punyani Date: Thu May 28 14:58:05 2026 -0700 Use nginx to serve appointment-booking Switch to nginx and serve built assets statically. Added nginx.conf and public/config/runtime-config.json, removed the custom Node server and in-image logos, and updated Dockerfile to copy dist into /app and run nginx on 8080. Updated package.json preview script to use vite preview, adjusted docker compose port mapping (5173:8080) and README instructions, and added ci_output.txt to .gitignore while deleting the file. Also expanded local CORS origins in api/config.py to include Vite ports 5173/5174. commit ce05eee9bc7e80ef40b237bdbca80c424c8cc41a Author: Veenu Punyani Date: Tue May 26 23:18:37 2026 -0700 Switch appointment-booking to Vite client app Replace SSR setup with a client-side Vite React app and simplify runtime server. Removed server-side entry and SSR rendering, renamed client entry to main.tsx using createRoot, and updated index.html to remove SSR outlet. package.json scripts now use vite for dev and build. server.js simplified to a static file server that serves dist files and exposes /config/runtime-config.json. Dockerfile and compose.yaml adjusted to run the frontend image (added appointment-booking service in compose, exposed port 5173, and updated Postgres image/ports). Documentation updated across README files to document the new React Vite app and dev/run instructions. --- appointment-booking/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appointment-booking/README.md b/appointment-booking/README.md index e4aebadd3..2260bad5f 100644 --- a/appointment-booking/README.md +++ b/appointment-booking/README.md @@ -76,12 +76,13 @@ docker run -p 5173:8080 appointment-booking ## Runtime Config -The app fetches `/config/configuration.json` on startup to get its configuration. The default file is at [`public/config/configuration.json`](./public/config/configuration.json) and is served as a static file by nginx. +The app fetches `/config/runtime-config.json` on startup to get its configuration. The default file is at [`public/config/runtime-config.json`](./public/config/runtime-config.json) and is served as a static file by nginx. In OpenShift, a ConfigMap mounts over this file to provide environment-specific values without rebuilding the image. ```json { + "apiBaseUrl": "http://localhost:5000/api/v1", "apiBaseUrl": "http://localhost:5000/api/v1", "requestTimeoutMs": 10000 } From d8ec7f6916031a3596cc223e57fb3de48396e709 Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Mon, 8 Jun 2026 00:38:42 -0700 Subject: [PATCH 06/12] locations directory added design changed, search added, maps added --- api/manage.py | 40 +- appointment-booking/index.html | 4 +- appointment-booking/package-lock.json | 73 ++- appointment-booking/package.json | 5 +- appointment-booking/src/App.css | 123 ++++- appointment-booking/src/App.test.tsx | 148 +++++- appointment-booking/src/App.tsx | 435 +++++++++++++++--- .../src/data/service-locations.test.ts | 33 ++ .../src/data/service-locations.ts | 74 +-- appointment-booking/src/index.css | 9 +- appointment-booking/src/main.tsx | 46 +- .../src/services/booking-api.service.ts | 9 + 12 files changed, 803 insertions(+), 196 deletions(-) create mode 100644 appointment-booking/src/data/service-locations.test.ts diff --git a/api/manage.py b/api/manage.py index 99f8fba55..19dfa836e 100644 --- a/api/manage.py +++ b/api/manage.py @@ -503,7 +503,7 @@ def bootstrap(): sb_id=smartboard_call_ticket.sb_id, exams_enabled_ind=1, timezone_id=timezone_one.timezone_id, - appointments_enabled_ind=1, + appointments_enabled_ind=0, latitude=48.458359, longitude=-123.377106, office_appointment_message='Test Message', @@ -773,7 +773,45 @@ def bootstrap(): office_100.services.append(service_ptax4) office_100.services.append(service_ptax5) office_100.services.append(service_dlkt) + + # Seed quick and back-office service lists used by the public locations directory. + office_test.quick_list.extend([ + service_msp1, + service_msp2, + service_msp6, + service_ptax1, + service_dlkt, + ]) + office_test.back_office_list.extend([ + service_bo1, + service_bo2, + ]) + + office_victoria.quick_list.extend([ + service_msp1, + service_msp2, + service_msp6, + service_dlkt, + ]) + office_victoria.back_office_list.extend([ + service_bo1, + service_bo2, + ]) + + office_100.quick_list.extend([ + service_ptax1, + service_ptax2, + service_ptax4, + service_ptax5, + service_dlkt, + ]) + office_100.back_office_list.extend([ + service_bo1, + service_bo2, + ]) + db.session.commit() + theq.Office.clear_offices_cache() # -- Booking / Rooms ------------------------------------------- logging.info('--> Booking: Rooms') diff --git a/appointment-booking/index.html b/appointment-booking/index.html index 9f7a58db0..c5a457156 100644 --- a/appointment-booking/index.html +++ b/appointment-booking/index.html @@ -4,7 +4,9 @@ - appointment-booking + Service BC Locations | Government of British Columbia + +
diff --git a/appointment-booking/package-lock.json b/appointment-booking/package-lock.json index 43d15e996..f5d912ee0 100644 --- a/appointment-booking/package-lock.json +++ b/appointment-booking/package-lock.json @@ -10,8 +10,11 @@ "dependencies": { "@bcgov/design-system-react-components": "^0.7.0", "@bcgov/design-tokens": "^4.0.0", + "@types/leaflet": "^1.9.21", + "leaflet": "^1.9.4", "react": "^19.2.6", - "react-dom": "^19.2.6" + "react-dom": "^19.2.6", + "react-leaflet": "^5.0.0" }, "devDependencies": { "@eslint/js": "^10.0.1", @@ -602,27 +605,6 @@ "node": ">=20.19.0" } }, - "node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@emnapi/wasi-threads": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", @@ -1288,6 +1270,17 @@ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, + "node_modules/@react-leaflet/core": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz", + "integrity": "sha512-3EWmekh4Nz+pGcr+xjf0KNyYfC3U2JjnkWsh0zcqaexYqmmB5ZhH37kz41JXGmKzpaMZCnPofBBm64i+YrEvGQ==", + "license": "Hippocratic-2.1", + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, "node_modules/@react-spectrum/button": { "version": "3.18.0", "resolved": "https://registry.npmjs.org/@react-spectrum/button/-/button-3.18.0.tgz", @@ -2074,6 +2067,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -2081,6 +2080,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/leaflet": { + "version": "1.9.21", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.21.tgz", + "integrity": "sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/node": { "version": "24.12.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.4.tgz", @@ -3777,6 +3785,13 @@ "json-buffer": "3.0.1" } }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "license": "BSD-2-Clause", + "peer": true + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4720,6 +4735,20 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, + "node_modules/react-leaflet": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0.tgz", + "integrity": "sha512-CWbTpr5vcHw5bt9i4zSlPEVQdTVcML390TjeDG0cK59z1ylexpqC6M1PJFjV8jD7CF+ACBFsLIDs6DRMoLEofw==", + "license": "Hippocratic-2.1", + "dependencies": { + "@react-leaflet/core": "^3.0.0" + }, + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, "node_modules/react-stately": { "version": "3.46.0", "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.46.0.tgz", diff --git a/appointment-booking/package.json b/appointment-booking/package.json index 0944c0690..b972c1e92 100644 --- a/appointment-booking/package.json +++ b/appointment-booking/package.json @@ -20,8 +20,11 @@ "dependencies": { "@bcgov/design-system-react-components": "^0.7.0", "@bcgov/design-tokens": "^4.0.0", + "@types/leaflet": "^1.9.21", + "leaflet": "^1.9.4", "react": "^19.2.6", - "react-dom": "^19.2.6" + "react-dom": "^19.2.6", + "react-leaflet": "^5.0.0" }, "devDependencies": { "@eslint/js": "^10.0.1", diff --git a/appointment-booking/src/App.css b/appointment-booking/src/App.css index 728276b3f..d3fdd50be 100644 --- a/appointment-booking/src/App.css +++ b/appointment-booking/src/App.css @@ -31,7 +31,43 @@ .search-input-group { position: relative; - max-width: 480px; + width: 100%; +} + +.search-input-row { + max-width: 760px; + display: flex; + align-items: center; + gap: 0.75rem; +} + +.nearest-office-action-row { + display: flex; + align-items: center; + justify-content: flex-end; + flex-shrink: 0; +} + +.nearest-button-content { + display: inline-flex; + align-items: center; + gap: 0.35rem; +} + +.nearest-button-icon { + width: 1rem; + height: 1rem; +} + +@media (max-width: 700px) { + .search-input-row { + flex-direction: column; + align-items: stretch; + } + + .nearest-office-action-row { + justify-content: flex-start; + } } .search-icon { @@ -47,7 +83,7 @@ .search-input { width: 100%; - padding: 0.6rem 0.75rem 0.6rem 2.4rem; + padding: 0.6rem 2.8rem 0.6rem 2.4rem; border: var(--layout-border-width-medium) solid var(--surface-color-border-default); border-radius: 0.375rem; font-size: var(--typography-font-size-body); @@ -105,6 +141,17 @@ font-weight: var(--typography-font-weights-bold); } +.nearest-badge { + display: inline-block; + margin-left: 0.5rem; + padding: 0.1rem 0.45rem; + border-radius: 999px; + font-size: var(--typography-font-size-small-body); + font-weight: var(--typography-font-weights-bold); + color: var(--typography-color-primary); + background: #e6f0ff; +} + .location-row-title a:hover { text-decoration: underline; } @@ -154,6 +201,22 @@ flex-wrap: wrap; } +.location-row-actions .row-action-link, +.location-row-actions .action-sep, +.location-row-actions .walkin-label, +.location-row-actions button { + display: inline-flex; + align-items: center; +} + +.location-row-actions button { + margin: 0; +} + +.location-row-actions-hours { + margin-top: 0.6rem; +} + .row-action-link { font-size: var(--typography-font-size-small-body); color: var(--typography-color-link); @@ -169,6 +232,11 @@ font-size: var(--typography-font-size-small-body); } +.walkin-label { + font-size: var(--typography-font-size-small-body); + color: var(--typography-color-secondary); +} + /* ── Meta items (icon + text) ───────────────────────────────── */ .location-meta-item { display: flex; @@ -204,6 +272,52 @@ font-style: italic; } +.services-detail-link-wrap { + margin: 0.45rem 0 0; +} + +.location-details-layout { + display: grid; + grid-template-columns: minmax(0, 1.2fr) minmax(280px, 1fr); + gap: 1.25rem; + align-items: start; +} + +.location-details-text { + grid-column: 1; +} + +.location-map-panel { + grid-column: 2; +} + +.location-map-wrapper { + margin-top: 0; + border: var(--layout-border-width-small) solid var(--surface-color-border-default); + border-radius: 0.5rem; + overflow: hidden; +} + +.location-map { + height: 320px; + width: 100%; +} + +@media (max-width: 540px) { + .location-details-layout { + grid-template-columns: 1fr; + } + + .location-details-text, + .location-map-panel { + grid-column: 1; + } + + .location-map { + height: 260px; + } +} + /* ── CTA ────────────────────────────────────────────────────── */ .cta-paragraph { margin-top: 1rem; @@ -246,6 +360,10 @@ color: var(--typography-color-link); } +.detail-book-cta { + margin: 0.8rem 0 0; +} + @media (max-width: 480px) { .detail-list { grid-template-columns: 1fr; @@ -259,4 +377,3 @@ padding-bottom: 0.6rem; } } - diff --git a/appointment-booking/src/App.test.tsx b/appointment-booking/src/App.test.tsx index 1aa9e552b..15086ceaf 100644 --- a/appointment-booking/src/App.test.tsx +++ b/appointment-booking/src/App.test.tsx @@ -1,9 +1,27 @@ -import { render, screen } from '@testing-library/react' +import { render, screen, fireEvent } from '@testing-library/react' import type { ReactNode } from 'react' import { describe, expect, it, vi, beforeEach } from 'vitest' import App from './App' import type { ServiceLocation } from './data/service-locations' +type MockBaseProps = { + children?: ReactNode +} & Record + +type MockHeadingProps = MockBaseProps & { + level: 1 | 2 | 3 | 4 | 5 | 6 +} + +type MockTagItem = { + id: string + textValue: string +} + +type MockTagListProps = MockBaseProps & { + children?: ReactNode | ((item: MockTagItem) => ReactNode) + items?: MockTagItem[] +} + vi.mock('@/components/common', () => ({ Layout: ({ children }: { children: ReactNode }) =>
{children}
, Page: ({ children, title }: { children: ReactNode; title: string }) => ( @@ -15,42 +33,81 @@ vi.mock('@/components/common', () => ({ })) vi.mock('@bcgov/design-system-react-components', () => ({ - Button: ({ children, variant, ...props }: any) => ( - - ), - Callout: ({ title, children }: any) => ( + Button: ({ children, ...props }: MockBaseProps) => , + Callout: ({ title, children }: MockBaseProps) => (

{title}

{children}
), - Heading: ({ level, children, ...props }: any) => { - const Tag = `h${level}` as any - return {children} + Heading: ({ level, children, ...props }: MockHeadingProps) => { + if (level === 1) return

{children}

+ if (level === 2) return

{children}

+ if (level === 3) return

{children}

+ if (level === 4) return

{children}

+ if (level === 5) return
{children}
+ return
{children}
}, - Link: ({ children, href, ...props }: any) => ( + Link: ({ children, href, ...props }: MockBaseProps) => ( {children} ), - TagGroup: ({ children, ...props }: any) =>
{children}
, - TagList: ({ children, items = [], ...props }: any) => ( + TagGroup: ({ children, ...props }: MockBaseProps) =>
{children}
, + TagList: ({ children, items = [], ...props }: MockTagListProps) => (
- {typeof children === 'function' ? items.map((item: any) => children(item)) : children} + {typeof children === 'function' ? items.map((item) => children(item)) : children}
), - Tag: ({ children }: any) => {children}, + Tag: ({ children }: MockBaseProps) => {children}, })) +const testLocations: ServiceLocation[] = [ + { + officeId: 94, + slug: 'victoria-courthouse', + name: 'Service BC - Victoria Courthouse', + address: '403-771 Vernon Ave, Victoria, BC V8W 9V1', + hours: 'Monday to Friday, 9 am to 4:30 pm', + phone: '', + email: '', + summary: '', + services: [], + appointmentsEnabledInd: 0, + }, + { + officeId: 95, + slug: 'nanaimo-service-centre', + name: 'Service BC - Nanaimo Service Centre', + address: '460 Selby St, Nanaimo, BC V9R 2R7', + hours: 'Monday to Friday, 9 am to 4:30 pm', + phone: '', + email: '', + summary: '', + services: [], + appointmentsEnabledInd: 0, + }, + { + officeId: 96, + slug: 'kelowna-civic-centre', + name: 'Service BC - Kelowna Civic Centre', + address: '305-478 Bernard Ave, Kelowna, BC V1Y 6N7', + hours: 'Monday to Friday, 9 am to 4:30 pm', + phone: '', + email: '', + summary: '', + services: [], + appointmentsEnabledInd: 0, + }, +] + describe('App', () => { beforeEach(() => { vi.clearAllMocks() }) it('renders the public Service BC locations directory', () => { - render() + render() expect(screen.getByRole('heading', { name: 'Service BC Locations' })).toBeInTheDocument() expect(screen.getByRole('link', { name: 'Service BC - Victoria Courthouse' })).toHaveAttribute( @@ -58,13 +115,60 @@ describe('App', () => { '/locations/victoria-courthouse', ) expect(screen.getAllByText('Monday to Friday, 9 am to 4:30 pm')[0]).toBeInTheDocument() - expect(screen.getAllByText('Book an appointment')).toHaveLength(3) + expect(screen.queryAllByText('Book an appointment')).toHaveLength(0) + expect(screen.getAllByText('Walk-in service available')).toHaveLength(3) + }) + + it('filters locations by search query', () => { + render() + + const searchInput = screen.getByRole('searchbox', { name: 'Search Service BC locations' }) + fireEvent.change(searchInput, { target: { value: 'Victoria' } }) + + expect( + screen.getByRole('link', { name: 'Service BC - Victoria Courthouse' }), + ).toBeInTheDocument() + expect( + screen.queryByRole('link', { name: 'Service BC - Nanaimo Service Centre' }), + ).not.toBeInTheDocument() + expect( + screen.queryByRole('link', { name: 'Service BC - Kelowna Civic Centre' }), + ).not.toBeInTheDocument() + }) + + it('shows no-results message when search matches nothing', () => { + render() + + const searchInput = screen.getByRole('searchbox', { name: 'Search Service BC locations' }) + fireEvent.change(searchInput, { target: { value: 'zzznomatch' } }) + + expect(screen.getByText(/No locations found for/)).toBeInTheDocument() + }) + + it('filters locations by postal code text in office address', () => { + render() + + const searchInput = screen.getByRole('searchbox', { name: 'Search Service BC locations' }) + + fireEvent.change(searchInput, { target: { value: 'V9R 2R7' } }) + + expect( + screen.getByRole('link', { name: 'Service BC - Nanaimo Service Centre' }), + ).toBeInTheDocument() + expect( + screen.queryByRole('link', { name: 'Service BC - Victoria Courthouse' }), + ).not.toBeInTheDocument() + expect( + screen.queryByRole('link', { name: 'Service BC - Kelowna Civic Centre' }), + ).not.toBeInTheDocument() }) it('renders a public location detail page', () => { - render() + render() - expect(screen.getByRole('heading', { name: 'Service BC - Nanaimo Service Centre' })).toBeInTheDocument() + expect( + screen.getByRole('heading', { name: 'Service BC - Nanaimo Service Centre' }), + ).toBeInTheDocument() expect(screen.getByRole('heading', { name: 'Services at this location' })).toBeInTheDocument() expect(screen.queryByText('Start booking an appointment')).not.toBeInTheDocument() }) @@ -87,11 +191,13 @@ describe('App', () => { expect(screen.getByRole('heading', { name: 'Service BC - Test Office' })).toBeInTheDocument() expect(screen.queryByText('Start booking an appointment')).not.toBeInTheDocument() - expect(screen.queryByText('Online appointment booking is currently unavailable for this office.')).not.toBeInTheDocument() + expect( + screen.queryByText('Online appointment booking is currently unavailable for this office.'), + ).not.toBeInTheDocument() }) it('shows a public not found page for unknown locations', () => { - render() + render() expect(screen.getByRole('heading', { name: 'Location not found' })).toBeInTheDocument() expect(screen.getByText('View all Service BC locations')).toBeInTheDocument() diff --git a/appointment-booking/src/App.tsx b/appointment-booking/src/App.tsx index 83590d03c..40ce53d44 100644 --- a/appointment-booking/src/App.tsx +++ b/appointment-booking/src/App.tsx @@ -1,17 +1,55 @@ +import { useState, useEffect } from 'react' +import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet' +import { Icon } from 'leaflet' import { Layout, Page } from '@/components/common' import { getServiceLocationBySlug, getServiceLocations, type ServiceLocation, } from '@/data/service-locations' -import { Button, Callout, Heading, Link, TagGroup, TagList } from '@bcgov/design-system-react-components' +import { + Button, + Callout, + Heading, + Link, + TagGroup, + TagList, +} from '@bcgov/design-system-react-components' +import { ApiClient } from '@/services/api-client.service' +import { getServicesByOfficeId } from '@/services/booking-api.service' +import { loadRuntimeConfig } from '@/services/runtime-config.service' import './App.css' +import 'leaflet/dist/leaflet.css' + +const locationPinIcon = new Icon({ + iconUrl: new URL('leaflet/dist/images/marker-icon.png', import.meta.url).toString(), + shadowUrl: new URL('leaflet/dist/images/marker-shadow.png', import.meta.url).toString(), + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + shadowSize: [41, 41], +}) + +function RemoveLeafletAttributionPrefix() { + const map = useMap() + + useEffect(() => { + map.attributionControl.setPrefix(false) + }, [map]) + + return null +} type AppProps = { initialPath?: string locations?: ServiceLocation[] } +type Coordinates = { + latitude: number + longitude: number +} + function navigateTo(path: string) { if (typeof window !== 'undefined') { window.location.assign(path) @@ -20,11 +58,12 @@ function navigateTo(path: string) { function getCurrentPath(initialPath?: string) { if (initialPath) { - return initialPath + const normalized = initialPath.split(/[?#]/)[0] + return normalized || '/locations' } if (typeof window !== 'undefined') { - return `${window.location.pathname}${window.location.search}${window.location.hash}` + return window.location.pathname } return '/locations' @@ -44,26 +83,113 @@ function renderServiceTags(location: ServiceLocation) { ) } -function renderDirectoryPage(locations: ServiceLocation[]) { +function hasCoordinates( + location: ServiceLocation, +): location is ServiceLocation & { latitude: number; longitude: number } { + return location.latitude != null && location.longitude != null +} + +function distanceKm(from: Coordinates, to: Coordinates) { + const toRadians = (value: number) => (value * Math.PI) / 180 + const earthRadiusKm = 6371 + const dLat = toRadians(to.latitude - from.latitude) + const dLon = toRadians(to.longitude - from.longitude) + const a = + Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.cos(toRadians(from.latitude)) * + Math.cos(toRadians(to.latitude)) * + Math.sin(dLon / 2) * + Math.sin(dLon / 2) + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) + return earthRadiusKm * c +} + +function LocationMap({ location }: { location: ServiceLocation }) { + if (location.latitude == null || location.longitude == null) { + return null + } + return ( - + + ) +} + +function renderDirectoryPage( + locations: ServiceLocation[], + searchQuery: string, + onSearchChange: (query: string) => void, + onFindNearestOffice: () => void, + nearestLocationSlug: string | null, +) { + return ( +

Browse Service BC locations, hours of operation, and the services available at each office.

- -
- - + +
+
+ + onSearchChange(e.target.value)} + /> +
+
+ +
@@ -71,33 +197,62 @@ function renderDirectoryPage(locations: ServiceLocation[]) { All locations ({locations.length}) + {locations.length === 0 && searchQuery.trim() && ( +

No locations found for “{searchQuery}”.

+ )}
    {locations.map((location) => (
  • {location.name} + {nearestLocationSlug === location.slug && ( + Nearest + )}

    Contact

    - {location.address}
    {location.phone && ( )} {location.email && (
    -
    @@ -111,12 +266,12 @@ function renderDirectoryPage(locations: ServiceLocation[]) { > Get directions - {location.appointmentsEnabledInd === 1 && ( + {location.appointmentsEnabledInd !== 1 && ( <> - - + + Walk-in service available )}
    @@ -124,66 +279,133 @@ function renderDirectoryPage(locations: ServiceLocation[]) {

    Hours of operation

    - {location.hours}
    + {location.appointmentsEnabledInd === 1 && ( +
    + +
    + )}

    Services available

    {renderServiceTags(location)} +

    + + Check all services + +

  • ))}
- ) } -function renderLocationDetailPage(location: ServiceLocation) { +function LocationDetailPage({ location }: { location: ServiceLocation }) { + const [services, setServices] = useState(location.services) + + useEffect(() => { + loadRuntimeConfig() + .then((config) => { + const client = new ApiClient(config) + return getServicesByOfficeId(client, location.officeId) + }) + .then((result) => { + const names = result.services.map((s) => s.service_name).filter(Boolean) + if (names.length > 0) setServices(names) + }) + .catch(() => {}) + }, [location.officeId]) + + const serviceLocation = { ...location, services } + return (

View office details for {location.name}.

- Location details -
-
-
Address
-
{location.address}
-
-
-
Hours
-
{location.hours}
+ + Location details + +
+
+
+
+
Address
+
{location.address}
+
+
+
Hours
+
{location.hours}
+
+ {location.phone && ( +
+
Phone
+
+ {location.phone} +
+
+ )} + {location.email && ( +
+
Email
+
+ {location.email} +
+
+ )} + {location.summary && ( +
+
About
+
{location.summary}
+
+ )} +
+ {location.appointmentsEnabledInd === 1 && ( +

+ +

+ )}
- {location.phone && ( -
-
Phone
-
{location.phone}
-
- )} - {location.email && ( -
-
Email
-
{location.email}
-
- )} - {location.summary && ( -
-
About
-
{location.summary}
-
- )} -
+ +
- Services at this location - {renderServiceTags(location)} + + Services at this location + + {renderServiceTags(serviceLocation)}
) @@ -193,8 +415,8 @@ function renderBookingLandingPage() { return (

- Start by choosing a service. The appointment flow will continue with eligible locations - and available times. + Start by choosing a service. The appointment flow will continue with eligible locations and + available times.

@@ -205,9 +427,7 @@ function renderBookingLandingPage() {

- +

@@ -217,19 +437,74 @@ function renderBookingLandingPage() { } function App({ initialPath, locations = getServiceLocations() }: AppProps) { + const [searchQuery, setSearchQuery] = useState('') + const [currentLocationCoords, setCurrentLocationCoords] = useState(null) const currentPath = getCurrentPath(initialPath) const locationMatch = currentPath.match(/^\/locations\/([^/?#]+)\/?$/) const locationSlug = locationMatch?.[1] const location = locationSlug ? getServiceLocationBySlug(locationSlug, locations) : null - if (currentPath === '/book-an-appointment' || currentPath === '/book-an-appointment/') { - return ( - - {renderBookingLandingPage()} - + const normalizedQuery = searchQuery.trim().toLowerCase() + const textFilteredLocations = normalizedQuery + ? locations.filter( + (loc) => + loc.name.toLowerCase().includes(normalizedQuery) || + loc.address.toLowerCase().includes(normalizedQuery), + ) + : locations + + const sortedByNearest = currentLocationCoords + ? [...textFilteredLocations].sort((a, b) => { + const aHasCoords = hasCoordinates(a) + const bHasCoords = hasCoordinates(b) + + if (!aHasCoords && !bHasCoords) { + return a.name.localeCompare(b.name) + } + if (!aHasCoords) { + return 1 + } + if (!bHasCoords) { + return -1 + } + + const aDistance = distanceKm(currentLocationCoords, { + latitude: a.latitude, + longitude: a.longitude, + }) + const bDistance = distanceKm(currentLocationCoords, { + latitude: b.latitude, + longitude: b.longitude, + }) + return aDistance - bDistance + }) + : textFilteredLocations + + const nearestLocationSlug = currentLocationCoords + ? (sortedByNearest.find((location) => hasCoordinates(location))?.slug ?? null) + : null + + const handleFindNearestOffice = () => { + if (typeof navigator === 'undefined' || !navigator.geolocation) { + return + } + + navigator.geolocation.getCurrentPosition( + (position) => { + setCurrentLocationCoords({ + latitude: position.coords.latitude, + longitude: position.coords.longitude, + }) + }, + undefined, + { enableHighAccuracy: true, timeout: 10000 }, ) } + if (currentPath === '/book-an-appointment' || currentPath === '/book-an-appointment/') { + return {renderBookingLandingPage()} + } + if (locationSlug && !location) { return ( @@ -239,9 +514,7 @@ function App({ initialPath, locations = getServiceLocations() }: AppProps) {

- +

@@ -251,7 +524,17 @@ function App({ initialPath, locations = getServiceLocations() }: AppProps) { return ( - {location ? renderLocationDetailPage(location) : renderDirectoryPage(locations)} + {location ? ( + + ) : ( + renderDirectoryPage( + sortedByNearest, + searchQuery, + setSearchQuery, + handleFindNearestOffice, + nearestLocationSlug, + ) + )} ) } diff --git a/appointment-booking/src/data/service-locations.test.ts b/appointment-booking/src/data/service-locations.test.ts new file mode 100644 index 000000000..26b84fa54 --- /dev/null +++ b/appointment-booking/src/data/service-locations.test.ts @@ -0,0 +1,33 @@ +import { describe, expect, it } from 'vitest' +import { mapApiOfficesToVisibleLocations, type OfficeApiModel } from './service-locations' + +describe('mapApiOfficesToVisibleLocations', () => { + it('excludes offices where online_status is HIDE or Status.HIDE', () => { + const offices: OfficeApiModel[] = [ + { + office_id: 1, + office_name: 'Visible Office', + online_status: 'SHOW', + appointments_enabled_ind: 1, + }, + { + office_id: 2, + office_name: 'Hidden Office', + online_status: 'HIDE', + appointments_enabled_ind: 1, + }, + { + office_id: 3, + office_name: 'Hidden Enum Office', + online_status: 'Status.HIDE', + appointments_enabled_ind: 1, + }, + ] + + const locations = mapApiOfficesToVisibleLocations(offices) + + expect(locations).toHaveLength(1) + expect(locations[0].officeId).toBe(1) + expect(locations[0].name).toBe('Service BC - Visible Office') + }) +}) diff --git a/appointment-booking/src/data/service-locations.ts b/appointment-booking/src/data/service-locations.ts index f666af86f..88237172a 100644 --- a/appointment-booking/src/data/service-locations.ts +++ b/appointment-booking/src/data/service-locations.ts @@ -9,6 +9,9 @@ export interface ServiceLocation { summary: string services: string[] appointmentsEnabledInd: 0 | 1 + latitude?: number | null + longitude?: number | null + externalMapLink?: string | null } type OfficeApiService = { @@ -28,60 +31,14 @@ export interface OfficeApiModel { telephone?: string | null office_hours?: string | null office_contact_email?: string | null + latitude?: number | null + longitude?: number | null + external_map_link?: string | null quick_list?: OfficeApiService[] back_office_list?: OfficeApiService[] } -const serviceLocations: ServiceLocation[] = [ - { - officeId: 94, - slug: 'victoria-courthouse', - name: 'Service BC - Victoria Courthouse', - address: '403-771 Vernon Ave, Victoria, BC V8W 9V1', - hours: 'Monday to Friday, 9 am to 4:30 pm', - phone: '250-387-6121', - email: 'ServiceBC.Victoria@gov.bc.ca', - summary: 'Central downtown location serving residents and visitors across greater Victoria.', - services: ['BCID services', 'Driver licensing support', 'Housing and tenancy information'], - appointmentsEnabledInd: 1, - }, - { - officeId: 95, - slug: 'nanaimo-service-centre', - name: 'Service BC - Nanaimo Service Centre', - address: '460 Selby St, Nanaimo, BC V9R 2R7', - hours: 'Monday to Friday, 9 am to 4:30 pm', - phone: '250-741-3636', - email: 'ServiceBC.Nanaimo@gov.bc.ca', - summary: 'Serving mid-Island residents and visitors.', - services: ['Property tax support', 'Income assistance', 'Identity document assistance'], - appointmentsEnabledInd: 1, - }, - { - officeId: 96, - slug: 'kelowna-civic-centre', - name: 'Service BC - Kelowna Civic Centre', - address: '305-478 Bernard Ave, Kelowna, BC V1Y 6N7', - hours: 'Monday to Friday, 9 am to 4:30 pm', - phone: '250-861-7500', - email: 'ServiceBC.Kelowna@gov.bc.ca', - summary: 'Okanagan location with general counter services for the public.', - services: ['Accessible parking information', 'General office services', 'Public information support'], - appointmentsEnabledInd: 1, - }, - { - officeId: 999, - slug: 'test-office', - name: 'Service BC - Test Office', - address: '123 Test St, Victoria, BC V8V 1A1', - hours: 'Monday to Friday, 9 am to 4:30 pm', - phone: '250-000-0000', - email: 'ServiceBC.TestOffice@gov.bc.ca', - summary: 'Test office for verifying non-bookable location behavior.', - services: ['General information'], - appointmentsEnabledInd: 0, - }, -] +const serviceLocations: ServiceLocation[] = [] function slugifyOfficeName(name: string) { return name @@ -111,6 +68,11 @@ function normalizeAppointmentsEnabled(value: number | null | undefined): 0 | 1 { return value === 1 ? 1 : 0 } +function isOfficeVisible(office: OfficeApiModel): boolean { + const onlineStatus = (office.online_status || '').trim().toUpperCase() + return !onlineStatus.endsWith('HIDE') +} + export function mapApiOfficeToServiceLocation(office: OfficeApiModel): ServiceLocation { const normalizedName = office.office_name.startsWith('Service BC - ') ? office.office_name @@ -127,12 +89,15 @@ export function mapApiOfficeToServiceLocation(office: OfficeApiModel): ServiceLo summary: office.office_appointment_message || 'TODO - Data not available from API', services: toOfficeServices(office), appointmentsEnabledInd: normalizeAppointmentsEnabled(office.appointments_enabled_ind), + latitude: office.latitude, + longitude: office.longitude, + externalMapLink: office.external_map_link, } } export function mapApiOfficesToVisibleLocations(offices: OfficeApiModel[]): ServiceLocation[] { return offices - .filter((office) => office.online_status === 'Status.SHOW') + .filter(isOfficeVisible) .map(mapApiOfficeToServiceLocation) .sort((a, b) => a.name.localeCompare(b.name)) } @@ -141,6 +106,9 @@ export function getServiceLocations() { return serviceLocations } -export function getServiceLocationBySlug(slug: string, locations: ServiceLocation[] = serviceLocations) { +export function getServiceLocationBySlug( + slug: string, + locations: ServiceLocation[] = serviceLocations, +) { return locations.find((location) => location.slug === slug) ?? null -} \ No newline at end of file +} diff --git a/appointment-booking/src/index.css b/appointment-booking/src/index.css index 0480fe3a3..5ba997d73 100644 --- a/appointment-booking/src/index.css +++ b/appointment-booking/src/index.css @@ -1,5 +1,12 @@ :root { - font-family: var(--typography-font-families-bc-sans, 'BC Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif); + font-family: var( + --typography-font-families-bc-sans, + 'BC Sans', + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + sans-serif + ); line-height: 1.5; font-weight: 400; color: var(--typography-color-primary, #2d2d2d); diff --git a/appointment-booking/src/main.tsx b/appointment-booking/src/main.tsx index 53311a3bc..e71c7c842 100644 --- a/appointment-booking/src/main.tsx +++ b/appointment-booking/src/main.tsx @@ -4,25 +4,37 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App' -import type { ServiceLocation } from './data/service-locations' +import { getServiceLocations, mapApiOfficesToVisibleLocations } from './data/service-locations' +import { ApiClient } from './services/api-client.service' +import { getOffices } from './services/booking-api.service' +import { loadRuntimeConfig } from './services/runtime-config.service' -type InitialRenderData = { - locations?: ServiceLocation[] -} +const container = document.getElementById('app')! +const initialPath = `${window.location.pathname}${window.location.search}${window.location.hash}` + +const root = createRoot(container) -declare global { - interface Window { - __APPOINTMENT_BOOKING_INITIAL_DATA__?: InitialRenderData - } +function renderApp(locations = getServiceLocations()) { + root.render( + + + , + ) } -const initialData = window.__APPOINTMENT_BOOKING_INITIAL_DATA__ +renderApp() -createRoot(document.getElementById('app')!).render( - - - , -) +loadRuntimeConfig() + .then((config) => { + const client = new ApiClient(config) + return getOffices(client) + }) + .then((result) => { + const apiLocations = mapApiOfficesToVisibleLocations(result.offices) + if (apiLocations.length > 0) { + renderApp(apiLocations) + } + }) + .catch(() => { + // API unreachable — fixtures already showing, nothing to do. + }) diff --git a/appointment-booking/src/services/booking-api.service.ts b/appointment-booking/src/services/booking-api.service.ts index a121c95c9..386a7c808 100644 --- a/appointment-booking/src/services/booking-api.service.ts +++ b/appointment-booking/src/services/booking-api.service.ts @@ -1,6 +1,15 @@ import { ApiClient } from '@/services/api-client.service' import type { OfficeApiModel } from '@/data/service-locations' +export interface ServiceApiModel { + service_id: number + service_name: string +} + export async function getOffices(client: ApiClient) { return client.get<{ offices: OfficeApiModel[] }>('/offices/') } + +export async function getServicesByOfficeId(client: ApiClient, officeId: number) { + return client.get<{ services: ServiceApiModel[] }>(`/services/?office_id=${officeId}`) +} From e5d80a975f712f197df125d0fa699be0f2380070 Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Mon, 8 Jun 2026 00:47:51 -0700 Subject: [PATCH 07/12] Update package-lock.json --- appointment-booking/package-lock.json | 40 +++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/appointment-booking/package-lock.json b/appointment-booking/package-lock.json index f5d912ee0..2b6fc8540 100644 --- a/appointment-booking/package-lock.json +++ b/appointment-booking/package-lock.json @@ -606,9 +606,9 @@ } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", "dev": true, "license": "MIT", "optional": true, @@ -1831,6 +1831,40 @@ "node": "^20.19.0 || >=22.12.0" } }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@rolldown/binding-win32-arm64-msvc": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0.tgz", From 1e7b463302bf23e94ae3f41a403d6e49d6a08e1c Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Wed, 10 Jun 2026 17:08:20 -0700 Subject: [PATCH 08/12] updated packages, fixed type errors --- 11.16.0 | 4 +++ appointment-booking/.dockerignore | 4 +++ appointment-booking/Dockerfile | 2 +- appointment-booking/package-lock.json | 48 +++++++++++++++------------ appointment-booking/src/App.test.tsx | 2 +- 5 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 11.16.0 create mode 100644 appointment-booking/.dockerignore diff --git a/11.16.0 b/11.16.0 new file mode 100644 index 000000000..cc532fe7c --- /dev/null +++ b/11.16.0 @@ -0,0 +1,4 @@ +Unknown command: "notice" + +To see a list of supported npm commands, run: + npm help diff --git a/appointment-booking/.dockerignore b/appointment-booking/.dockerignore new file mode 100644 index 000000000..27c0c8134 --- /dev/null +++ b/appointment-booking/.dockerignore @@ -0,0 +1,4 @@ +node_modules +dist +.env* +*.local diff --git a/appointment-booking/Dockerfile b/appointment-booking/Dockerfile index 7e1358bfc..aff83198f 100644 --- a/appointment-booking/Dockerfile +++ b/appointment-booking/Dockerfile @@ -1,5 +1,5 @@ # Stage 1: Builder -FROM node:22-alpine AS builder +FROM node:24-alpine AS builder WORKDIR /app diff --git a/appointment-booking/package-lock.json b/appointment-booking/package-lock.json index 2b6fc8540..f7f824415 100644 --- a/appointment-booking/package-lock.json +++ b/appointment-booking/package-lock.json @@ -54,7 +54,6 @@ "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.47.0.tgz", "integrity": "sha512-EDQuMzz0kUeiMUUlxoeLFQyyxOXaAC7qlBw2PYOUfFLYd87xcV7VVV0JxiYx8zGk1IIY3UgQHgXrS1fv7CgezQ==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@internationalized/date": "^3.12.1", "@react-types/shared": "^3.34.0", @@ -194,7 +193,6 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -551,7 +549,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" }, @@ -600,11 +597,35 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" } }, + "node_modules/@emnapi/core": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.0.tgz", + "integrity": "sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.0.tgz", + "integrity": "sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@emnapi/wasi-threads": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", @@ -612,6 +633,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -2129,7 +2151,6 @@ "integrity": "sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -2140,7 +2161,6 @@ "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -2151,7 +2171,6 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "dev": true, "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -2201,7 +2220,6 @@ "integrity": "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.59.3", "@typescript-eslint/types": "8.59.3", @@ -2552,7 +2570,6 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2725,7 +2742,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", @@ -3054,7 +3070,6 @@ "integrity": "sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", @@ -3111,7 +3126,6 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -3823,8 +3837,7 @@ "version": "1.9.4", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", - "license": "BSD-2-Clause", - "peer": true + "license": "BSD-2-Clause" }, "node_modules/levn": { "version": "0.4.1", @@ -4545,7 +4558,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -4598,7 +4610,6 @@ "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -4683,7 +4694,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -4755,7 +4765,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -5298,7 +5307,6 @@ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5422,7 +5430,6 @@ "integrity": "sha512-w2dDofOWv2QB09ZITZBsvKTVAlYvPR4IAmrY/v0ir9KvLs0xybR7i48wxhM1/oyBWO34wPns+bPGw5ZrZqDpZg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", @@ -5726,7 +5733,6 @@ "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", "dev": true, "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/appointment-booking/src/App.test.tsx b/appointment-booking/src/App.test.tsx index 15086ceaf..14e1890c6 100644 --- a/appointment-booking/src/App.test.tsx +++ b/appointment-booking/src/App.test.tsx @@ -6,7 +6,7 @@ import type { ServiceLocation } from './data/service-locations' type MockBaseProps = { children?: ReactNode -} & Record +} & Record type MockHeadingProps = MockBaseProps & { level: 1 | 2 | 3 | 4 | 5 | 6 From b711cd38d1a3291d6c354a6c84a43ef53d048836 Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Wed, 10 Jun 2026 17:10:55 -0700 Subject: [PATCH 09/12] fixed type errors --- appointment-booking/src/App.test.tsx | 2 +- appointment-booking/src/App.tsx | 12 ++---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/appointment-booking/src/App.test.tsx b/appointment-booking/src/App.test.tsx index 14e1890c6..0339cd2e5 100644 --- a/appointment-booking/src/App.test.tsx +++ b/appointment-booking/src/App.test.tsx @@ -6,7 +6,7 @@ import type { ServiceLocation } from './data/service-locations' type MockBaseProps = { children?: ReactNode -} & Record + [key: string]: ReactNode type MockHeadingProps = MockBaseProps & { level: 1 | 2 | 3 | 4 | 5 | 6 diff --git a/appointment-booking/src/App.tsx b/appointment-booking/src/App.tsx index 40ce53d44..e0927970a 100644 --- a/appointment-booking/src/App.tsx +++ b/appointment-booking/src/App.tsx @@ -294,11 +294,7 @@ function renderDirectoryPage( {location.appointmentsEnabledInd === 1 && (
-
@@ -387,11 +383,7 @@ function LocationDetailPage({ location }: { location: ServiceLocation }) { {location.appointmentsEnabledInd === 1 && (

-

From 1849072a2cd4b9e14e880fa519c4413947bb9cf4 Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Wed, 10 Jun 2026 17:12:32 -0700 Subject: [PATCH 10/12] missed bracket --- appointment-booking/src/App.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/appointment-booking/src/App.test.tsx b/appointment-booking/src/App.test.tsx index 0339cd2e5..42a665a31 100644 --- a/appointment-booking/src/App.test.tsx +++ b/appointment-booking/src/App.test.tsx @@ -7,6 +7,7 @@ import type { ServiceLocation } from './data/service-locations' type MockBaseProps = { children?: ReactNode [key: string]: ReactNode +} type MockHeadingProps = MockBaseProps & { level: 1 | 2 | 3 | 4 | 5 | 6 From dd369b75a8c664df599f90aa181e848a4c44f1e5 Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Wed, 10 Jun 2026 17:17:16 -0700 Subject: [PATCH 11/12] upgrade packeages --- appointment-booking/package-lock.json | 1423 +++++++++++++------------ appointment-booking/src/App.test.tsx | 6 +- 2 files changed, 719 insertions(+), 710 deletions(-) diff --git a/appointment-booking/package-lock.json b/appointment-booking/package-lock.json index f7f824415..5f4c02346 100644 --- a/appointment-booking/package-lock.json +++ b/appointment-booking/package-lock.json @@ -43,28 +43,29 @@ } }, "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==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz", + "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==", "dev": true, "license": "MIT" }, "node_modules/@adobe/react-spectrum": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.47.0.tgz", - "integrity": "sha512-EDQuMzz0kUeiMUUlxoeLFQyyxOXaAC7qlBw2PYOUfFLYd87xcV7VVV0JxiYx8zGk1IIY3UgQHgXrS1fv7CgezQ==", + "version": "3.47.1", + "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.47.1.tgz", + "integrity": "sha512-mijNyd8XmA6KoBMbqKc4Rp+S2voKdZkPydJFjQbG0SkOjOKcgqVpJdKGsKdLMZBn9Jk5SgEuklyrhc7Uvot2tA==", "license": "Apache-2.0", + "peer": true, "dependencies": { - "@internationalized/date": "^3.12.1", - "@react-types/shared": "^3.34.0", - "@spectrum-icons/ui": "^3.7.0", - "@spectrum-icons/workflow": "^4.3.0", + "@internationalized/date": "^3.12.2", + "@react-types/shared": "^3.35.0", + "@spectrum-icons/ui": "^3.7.1", + "@spectrum-icons/workflow": "^4.3.1", "@swc/helpers": "^0.5.0", "client-only": "^0.0.1", "clsx": "^2.0.0", - "react-aria": "3.48.0", - "react-aria-components": "1.17.0", - "react-stately": "3.46.0", + "react-aria": "3.49.0", + "react-aria-components": "1.18.0", + "react-stately": "3.47.0", "react-transition-group": "^4.4.5", "use-sync-external-store": "^1.6.0" }, @@ -94,17 +95,17 @@ } }, "node_modules/@adobe/react-spectrum/node_modules/react-aria-components": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.17.0.tgz", - "integrity": "sha512-0EyisMgvsFJ2aML3crDYv2tW5vT2Ryf8PGzY/g63JjDdCbLshlwazhS8JNtPF1vkTkungJJ6sVJbKyX+YKSoFA==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.18.0.tgz", + "integrity": "sha512-FhRQjuDkH4WhgFv+O2sYTzK3JzdZTGpBeaqfRlfTo+DcSZzD8elJEkytHe7SDpcexVKeire8NVd7OruZHfCVoA==", "license": "Apache-2.0", "dependencies": { - "@internationalized/date": "^3.12.1", - "@react-types/shared": "^3.34.0", + "@internationalized/date": "^3.12.2", + "@react-types/shared": "^3.35.0", "@swc/helpers": "^0.5.0", "client-only": "^0.0.1", - "react-aria": "3.48.0", - "react-stately": "3.46.0" + "react-aria": "3.49.0", + "react-stately": "3.47.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -163,13 +164,13 @@ "license": "MIT" }, "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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -178,9 +179,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", - "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "dev": true, "license": "MIT", "engines": { @@ -188,21 +189,22 @@ } }, "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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "dev": true, "license": "MIT", + "peer": true, "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", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -218,15 +220,25 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.0", - "@babel/types": "^7.29.0", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -236,14 +248,14 @@ } }, "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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -252,10 +264,20 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "dev": true, "license": "MIT", "engines": { @@ -263,29 +285,29 @@ } }, "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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.6" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -295,9 +317,9 @@ } }, "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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "dev": true, "license": "MIT", "engines": { @@ -305,9 +327,9 @@ } }, "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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "dev": true, "license": "MIT", "engines": { @@ -315,9 +337,9 @@ } }, "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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "dev": true, "license": "MIT", "engines": { @@ -325,27 +347,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", - "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", - "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.29.0" + "@babel/types": "^7.29.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -355,42 +377,42 @@ } }, "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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", "license": "MIT", "engines": { "node": ">=6.9.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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.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==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", "dev": true, "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", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", "debug": "^4.3.1" }, "engines": { @@ -398,14 +420,14 @@ } }, "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -506,9 +528,9 @@ } }, "node_modules/@csstools/css-color-parser": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.1.tgz", - "integrity": "sha512-eZ5XOtyhK+mggRafYUWzA0tvaYOFgdY8AkgQiCJF9qNAePnUo/zmsqqYubBBb3sQ8uNUaSKTY9s9klfRaAXL0g==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.3.tgz", + "integrity": "sha512-DOgvIPkikIOixQRlD4YF31VN6fLLUTdrzhfRbis8vm0kMTgIbEPX0Ip/YX9fOeV9iywAS4sUUbTclpan7yYP8Q==", "dev": true, "funding": [ { @@ -549,6 +571,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=20.19.0" }, @@ -557,9 +580,9 @@ } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.4.tgz", - "integrity": "sha512-wgsqt92b7C7tQhIdPNxj0n9zuUbQlvAuI1exyzeNrOKOi62SD7ren8zqszmpVREjAOqg8cD2FqYhQfAuKjk4sw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.5.tgz", + "integrity": "sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==", "dev": true, "funding": [ { @@ -597,27 +620,28 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=20.19.0" } }, "node_modules/@emnapi/core": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.0.tgz", - "integrity": "sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "dev": true, "license": "MIT", "optional": true, "peer": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.2", + "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.0.tgz", - "integrity": "sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "dev": true, "license": "MIT", "optional": true, @@ -627,13 +651,12 @@ } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", - "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -657,19 +680,6 @@ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@eslint-community/regexpp": { "version": "4.12.2", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", @@ -696,9 +706,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz", - "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", + "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -753,9 +763,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz", - "integrity": "sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -767,9 +777,9 @@ } }, "node_modules/@exodus/bytes": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz", - "integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz", + "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==", "dev": true, "license": "MIT", "engines": { @@ -902,18 +912,18 @@ } }, "node_modules/@internationalized/date": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.12.1.tgz", - "integrity": "sha512-6IedsVWXyq4P9Tj+TxuU8WGWM70hYLl12nbYU8jkikVpa6WXapFazPUcHUMDMoWftIDE2ILDkFFte6W2nFCkRQ==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.12.2.tgz", + "integrity": "sha512-FY1Y+H64NDs+HAF6omlnWxm3mEpfgaCSWtL5l551ZZfImA+kGjPFgrnJrGjH6lfmLL0g8Z/mBu1R3kufeCp6Jw==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" } }, "node_modules/@internationalized/message": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.9.tgz", - "integrity": "sha512-x03MSVTaB/4JHtW1VAYaY/2cCuBrHbWM6ZvlgpKdnSdW28tZbqpR673RJrVJyXWRw1bpgYN89Tz7ohX5tgNgPA==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.10.tgz", + "integrity": "sha512-nc0Or6EdWHqZRcsXb6P9hBIpLsfSl/ILh0rk5h/OVBpzmhdExXtPy2cQtWsq8XKRBpRHwDNnAHt4OpolcB7dog==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", @@ -921,18 +931,18 @@ } }, "node_modules/@internationalized/number": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.6.tgz", - "integrity": "sha512-iFgmQaXHE0vytNfpLZWOC2mEJCBRzcUxt53Xf/yCXG93lRvqas237i3r7X4RKMwO3txiyZD4mQjKAByFv6UGSQ==", + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.7.tgz", + "integrity": "sha512-3ji1fcrT+FPAK86UqEhB/psHixYo6niWPJtt7+qRaYFynt/BaJG8GhAPimtWUpEiVSTq8ZM8L5psMxGquiB/Vg==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" } }, "node_modules/@internationalized/string": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.8.tgz", - "integrity": "sha512-NdbMQUSfXLYIQol5VyMtinm9pZDciiMfN7RtmSuSB78io1hqwJ0naYfxyW6vgxWBkzWymQa/3uLDlbfmshtCaA==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.9.tgz", + "integrity": "sha512-kzP/M/mbQxODlmOt4bIQZ2SBVUWUSqMLXooXixnX7noche8WHaQcA+nwFN1K2KCF/cp+LDUhcJsCicwkvhD1pg==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" @@ -989,14 +999,14 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", - "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz", + "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@tybys/wasm-util": "^0.10.1" + "@tybys/wasm-util": "^0.10.2" }, "funding": { "type": "github", @@ -1008,9 +1018,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.129.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.129.0.tgz", - "integrity": "sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg==", + "version": "0.133.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", + "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", "dev": true, "license": "MIT", "funding": { @@ -1018,13 +1028,13 @@ } }, "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz", + "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==", "dev": true, "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + "node": "^14.18.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/pkgr" @@ -1057,13 +1067,13 @@ } }, "node_modules/@react-aria/button": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.15.0.tgz", - "integrity": "sha512-p8KehQ+OmhvhYmsjkp4K/Yv0tufyEBOHu6woJlRYL6kq5m6GKY5MZp8pyO26FpSiOyjhnZe6wbTyvCifvaokwQ==", + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.15.1.tgz", + "integrity": "sha512-SBMn8ZLvjuWCpSqi6o1hOjsqQqkdYFfzIdl/0LgNPUpTclkJuMx7gNXfM3mjgxzSCoS5CD/XdicvqJanMw6jCw==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1071,13 +1081,13 @@ } }, "node_modules/@react-aria/collections": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@react-aria/collections/-/collections-3.1.0.tgz", - "integrity": "sha512-OwWoxHaAN0jNw7oo17TfTPY2KZksDme4p5a8KCnNBfm/a0zo+y4wiOUaFpGDmDT6HxwznyBcu3x3oSN7orTtvA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@react-aria/collections/-/collections-3.1.1.tgz", + "integrity": "sha512-54NpHYVnv1+47L5e2DZ34WvzPSOg6dgl4E78EfZo3kNdyM8xhM2vCuYuS8uUs1xCPr7HcBBmnn/maHOxfSabeg==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1085,13 +1095,13 @@ } }, "node_modules/@react-aria/combobox": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.16.0.tgz", - "integrity": "sha512-yPPLduVUluCBuIFSZ+WgBMgl5oH7A5oQTemSpvf9ZmJ2oABIe+h6VQcwkEtMdokveHrdbmWIB9BL0E5jdDczAA==", + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.16.1.tgz", + "integrity": "sha512-Ufoos0z66dRx8bxN3OJ25ASqksukPQaxVP5thr7dnu2QqqhxlZb1Va1ebaVxzMAnSrB78oQh3h1d9/hS4uhcPQ==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1099,14 +1109,14 @@ } }, "node_modules/@react-aria/dnd": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.12.0.tgz", - "integrity": "sha512-FqAaxIMCgpq83UQhJRpSR+o3K4XQQYbJMKxhBWGL84Wn1p6m8QmWGvRKAiHeUoQXlY8R6KNxlMR/KjJvV8/lBA==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.12.1.tgz", + "integrity": "sha512-gAFsHChr2K9enfTOyY3h+7c+hb8fM7GGSWRlcE63If+jrdBRPicQ0wyiRr1ChFU3KVH3Nk2PZUUMET58QlUYVQ==", "license": "Apache-2.0", "dependencies": { "@react-types/shared": "^3.34.0", "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1114,13 +1124,13 @@ } }, "node_modules/@react-aria/focus": { - "version": "3.22.0", - "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.22.0.tgz", - "integrity": "sha512-ZfDOVuVhqDsM9mkNji3QUZ/d40JhlVgXrDkrfXylM1035QCrcTHN7m2DpbE95sU2A8EQb4wikvt5jM6K/73BPg==", + "version": "3.22.1", + "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.22.1.tgz", + "integrity": "sha512-CPxtkyrBi/HYY5P3lE/57sQ6qfa0lN8E55TOm89H0kNGv0lKt+/0zP7lWERzBjRr5IxBVrQX4gFEowBN52LPaA==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1128,16 +1138,16 @@ } }, "node_modules/@react-aria/i18n": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.13.0.tgz", - "integrity": "sha512-APjw4EwmvlnIyDxixSWfjHvOFFkW2rVTyKZ4l9FV0v7hOerh+FWLE6mF1XnnX3pgz3yARkKWwhSR9xYcRK6tpg==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.13.1.tgz", + "integrity": "sha512-z56ZYcbfpNmMyiGLhyEjytpmEfoTlBaksk84q4kds3HvNkf7QWKj+DJVfVDrJX+c1LyuBsszLSX7yxJRiHsYKQ==", "license": "Apache-2.0", "dependencies": { "@internationalized/date": "^3.12.1", "@internationalized/message": "^3.1.9", "@internationalized/string": "^3.2.8", "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1145,14 +1155,14 @@ } }, "node_modules/@react-aria/interactions": { - "version": "3.28.0", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.28.0.tgz", - "integrity": "sha512-OXwdU1EWFdMxmr/K1CXNGJzmNlCClByb+PuCaqUyzBymHPCGVhawirLIon/CrIN5psh3AiWpHSh4H0WeJdVpng==", + "version": "3.28.1", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.28.1.tgz", + "integrity": "sha512-Bqb+HrD5I5MHS2SKBhISYqo2SW8Y2dfzgF/Y1lIJq7xqLxheo9vzxPGEHhz+XzkgGfoqEJx8A6a3C7uiqS3HWA==", "license": "Apache-2.0", "dependencies": { "@react-types/shared": "^3.34.0", "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1160,13 +1170,13 @@ } }, "node_modules/@react-aria/listbox": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.16.0.tgz", - "integrity": "sha512-Jv6aTJECRntBvG+0ZQtXniAtHEQjvEi2QSm35FxRcsB8kgv7TmcinUOSZuHe5r8RDY2djILwdrqmfy6ApX0MDA==", + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.16.1.tgz", + "integrity": "sha512-FbNeUXmo/H2Qp+yKboNod1eVhfmQDv1YexzEIAHsKL5Cx8uA7wZID9Pbq28jPC4plPISgS5KLBodaDikOXqviA==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1174,13 +1184,13 @@ } }, "node_modules/@react-aria/live-announcer": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@react-aria/live-announcer/-/live-announcer-3.5.0.tgz", - "integrity": "sha512-1b+Txq00WQ/PJPCsZT+CI5qP86DrfFGPuJL5ifKtdMVXrxNGJWrfu7jTj6q9AbAOOXLG11BJ6blILu7sZeRPxg==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@react-aria/live-announcer/-/live-announcer-3.5.1.tgz", + "integrity": "sha512-kLvwHjM3D7KgdquiAhUpRnMLKFrvl2r8naDXqPUlSWGRG15wsJRLhQOHLxGp0Umyg7KcSA+OD1mhQV5aRv0P1w==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1188,13 +1198,13 @@ } }, "node_modules/@react-aria/overlays": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.32.0.tgz", - "integrity": "sha512-H9meBB14/M0bDwk8gZl8Fu8bwZN2El9LDlk5cNkgAozbEiRuQvTFOeE3RoP6XI6bwEnSBvb0ovPmx3/kNyOehQ==", + "version": "3.32.1", + "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.32.1.tgz", + "integrity": "sha512-jjVLcEK5qaGsz3SmW+eLV3QFiJzdDFzgNofPwvzBS1KTPox0a2x5u1ITUPmHwyUNiyexy531h5eVjN3tULEzHQ==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1202,13 +1212,13 @@ } }, "node_modules/@react-aria/searchfield": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.9.0.tgz", - "integrity": "sha512-B8oOFhwGDotb7enoQ0bmXjhVkx8BkzK/ZnMmr4aF2ezexSFpG/ELkWqJPlfwknCwoBgBzhmpIKZvkoxQHR/iIw==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.9.1.tgz", + "integrity": "sha512-BBJMq07CCcn7uaAyKKzFPRafX2x16gWluGNwMvpvuK9E0JNeTqQXKxYVzJ6EE39dYN9D97Icc1/2MtUaKJFETA==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1216,13 +1226,13 @@ } }, "node_modules/@react-aria/ssr": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.10.0.tgz", - "integrity": "sha512-mnelvACtfNWWKFCT1YHebxJRmfBmmANGwHQhCFPByMVTx1L8RumcaLxChYkE87g2KPuP5xX2il/oRn1DytW+qQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.10.1.tgz", + "integrity": "sha512-jn038/ZYmu6DpfXJ6r2U9zFFppjbc9wnApPJSCxao2RZVEqep4YyoniHSy8qv6V21/xyS4IV7W9a+X2jOjSuag==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "engines": { "node": ">= 12" @@ -1233,13 +1243,13 @@ } }, "node_modules/@react-aria/textfield": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.19.0.tgz", - "integrity": "sha512-P5Da8QFV/bCp3oCXQAqaTWhXNtx4vWEjvoqa49oG5TM1blodLjFrzNyiRM7TmQU0VLwiQPAQrqD4yaDLXZ0Nqg==", + "version": "3.19.1", + "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.19.1.tgz", + "integrity": "sha512-zYxQvOgN2CkvNvKchHEDu9UAOrwYzsaeUKVbrFcXJ2iIeZuZnEcNNJpp7WVCfV+9XeP+Jzjjnmjg9BH1H52ebg==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1264,14 +1274,14 @@ } }, "node_modules/@react-aria/utils": { - "version": "3.34.0", - "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.34.0.tgz", - "integrity": "sha512-ZM1ZXIqpwGTJjjL6o3JhlZkEaBpQdxuOCqLEvwEwooaj5GsYI3E9UfOl5vy3UW6bYiEEWl9pNBntrb9CR9kItQ==", + "version": "3.34.1", + "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.34.1.tgz", + "integrity": "sha512-H6+rGZL+0f58bBNaUMfctEnT+NogqwAk+nHiB8sR3K+YlQ37GTuCijy2U/pPvQtFMS5mURrjZeBH5JNNXsx14A==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0", - "react-stately": "3.46.0" + "react-aria": "^3.48.0", + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1279,13 +1289,13 @@ } }, "node_modules/@react-aria/virtualizer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@react-aria/virtualizer/-/virtualizer-4.2.0.tgz", - "integrity": "sha512-j4Dj/PMQK+d/2E2Dxyr5ifPdg8IG/NYsfZJtPnvKHXeKlI3vj7F/InamujwCuEFHZBK3YmxlRPRGcoMdS66qfw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@react-aria/virtualizer/-/virtualizer-4.2.1.tgz", + "integrity": "sha512-6zwKVC64Z/wpo8XGIZ/IUzyjSb23iKDBfQQYpvzk9YSLA5MDqNj5//esc3cYud1iKYRPoBjNkXT23fufDoikKA==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria": "3.48.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1304,12 +1314,12 @@ } }, "node_modules/@react-spectrum/button": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@react-spectrum/button/-/button-3.18.0.tgz", - "integrity": "sha512-SmjsXt+mLK2cf8PGstNZvLBfjqE5TjHW15yPIATI6ddqMdcC9JZ3ldnBTdFji9P/B6Rlop4ajnAdDV6bpxLtXA==", + "version": "3.18.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/button/-/button-3.18.1.tgz", + "integrity": "sha512-FW+1d6zfKesMLaBrsRsnnYnsLfvf2qFKuatkCo62o1oGUBtEYI/kae+lwGwlfiX5q9P5OgR2y1IqKtxabf/JKQ==", "license": "Apache-2.0", "dependencies": { - "@adobe/react-spectrum": "3.47.0", + "@adobe/react-spectrum": "^3.47.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1318,14 +1328,14 @@ } }, "node_modules/@react-spectrum/combobox": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/@react-spectrum/combobox/-/combobox-3.17.0.tgz", - "integrity": "sha512-HuJjm7m5W/lvpak0KQXAdqkvO17GpIfQ6/AuddnXEyltWhl481oRok04b9VQKdZAy9xrmmpReFcvXJ4zFDIGvg==", + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/combobox/-/combobox-3.17.1.tgz", + "integrity": "sha512-687FgU6lYIFSUducoqp77YJaAL5BZDhuwB6q7B01pNMuq6oAa6PAW6b2iNA8QGbI/JBw/UMVga8DAziiZchcug==", "license": "Apache-2.0", "dependencies": { - "@adobe/react-spectrum": "3.47.0", + "@adobe/react-spectrum": "^3.47.0", "@swc/helpers": "^0.5.0", - "react-stately": "3.46.0" + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1333,12 +1343,12 @@ } }, "node_modules/@react-spectrum/form": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@react-spectrum/form/-/form-3.8.0.tgz", - "integrity": "sha512-zNFA1zRFvoEZAhK6HxWyo2yUDlUXqCaaySxHvuCaevq4Zw3DKndbxq72ax9YDaUAvYlhgnb/bI616JBCZUAhdA==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/form/-/form-3.8.1.tgz", + "integrity": "sha512-hH98Izifw6F7MgIY0VPLG7h1FR/My+BHc6OavYJQJw3VxODNJjIqMcO49bKDqdMvLQWE2tNJqul0wocKbKoSpw==", "license": "Apache-2.0", "dependencies": { - "@adobe/react-spectrum": "3.47.0", + "@adobe/react-spectrum": "^3.47.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1347,13 +1357,13 @@ } }, "node_modules/@react-spectrum/provider": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@react-spectrum/provider/-/provider-3.11.0.tgz", - "integrity": "sha512-W2Gxbj8AcG5OR2K5Ua3K8qQqxdsiytEiz+2rhr6oQyBM8VafEgDcNPYSOTtfjrQM3snl2Uhp8LzwN0jwQe/6nQ==", + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/provider/-/provider-3.11.1.tgz", + "integrity": "sha512-TsoNdVdmlQ7L+75ILq5Yb3+wp/I1AtIeat0o+Y+ZBxP+TtWpwT1ZtCB5l3cplFVzHzOpZlzO0VaDrDP9ElGYDw==", "license": "Apache-2.0", "peer": true, "dependencies": { - "@adobe/react-spectrum": "3.47.0", + "@adobe/react-spectrum": "^3.47.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1362,12 +1372,12 @@ } }, "node_modules/@react-spectrum/searchfield": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@react-spectrum/searchfield/-/searchfield-3.9.0.tgz", - "integrity": "sha512-so1IeolnYPsgjoIJmoGakUuQv+Ij5NVoWx2VTBc3o2sUva1GkxtFp6Woiow2Qqw0mFyoTwwoKi6zQJHLMqHhvQ==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/searchfield/-/searchfield-3.9.1.tgz", + "integrity": "sha512-h8Mf43aECw/0TE+Jq31YrGzjWmuYDdDduIdXGnCP42qlQTOw66skbwmh1TxDtY9aZAxKT7+Z80IBhipCbHCuJw==", "license": "Apache-2.0", "dependencies": { - "@adobe/react-spectrum": "3.47.0", + "@adobe/react-spectrum": "^3.47.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1376,14 +1386,14 @@ } }, "node_modules/@react-spectrum/table": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@react-spectrum/table/-/table-3.18.0.tgz", - "integrity": "sha512-ckvjjz/Tp8Y/Ck/OOOXX/dTs8PtoWCy7+QDBxWzNpqvxcLiLviudNKJFhGfeyGGDi3IOMWRSaG5yWN9wrvItNQ==", + "version": "3.18.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/table/-/table-3.18.1.tgz", + "integrity": "sha512-rLXJ58EYQjQt4iUZh1cXiXBX64XkDwZKIfU0mipQ3p0Us1X3ubZN5UuaPmmCLEUa+8UBpazmSVUjMFNQ8yjjCg==", "license": "Apache-2.0", "dependencies": { - "@adobe/react-spectrum": "3.47.0", + "@adobe/react-spectrum": "^3.47.0", "@swc/helpers": "^0.5.0", - "react-stately": "3.46.0" + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1404,13 +1414,13 @@ } }, "node_modules/@react-stately/combobox": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.14.0.tgz", - "integrity": "sha512-WYWJK9IzWKDqnFk1HF6FGISrhPh/bzYkRLgd40Psyke5dwYusOrEUzG161P8v9vxAzs621pYB4hz2UhrRWsMPQ==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.14.1.tgz", + "integrity": "sha512-Sko1oHiKt07LERxUgpgmbQOYh5Yk8cU1dgRZlcE1wmmaxSVZBzBnd3fGZrEGRKSDezVOKHLibsmuYYDbxPEc+Q==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-stately": "3.46.0" + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1418,13 +1428,13 @@ } }, "node_modules/@react-stately/grid": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.12.0.tgz", - "integrity": "sha512-MLCN3hyxRpaj4tUnQyc+aFR2/QBP2rmFcXGdADHO1c0kvxd9Vk+bEe88uA9MJTz2VClQ+AN7yRGCTIuME+QvNQ==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.12.1.tgz", + "integrity": "sha512-GvOXlPtzoswhyV3bZK3habHdHBGR7qdzOy2WumYiNG7DAj8J+9WvAObrPmquuI2VrZYMSNzgFb3IoL+sQsMI8A==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-stately": "3.46.0" + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1432,13 +1442,13 @@ } }, "node_modules/@react-stately/layout": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-4.7.0.tgz", - "integrity": "sha512-63VvOKI8KXeD3SO7yt41511CdZ+9wK2LVY2mpY+c87ML5fVVgMTc/o1IsYWI07rW3IjEFcWoW93eItgMbJCXyg==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-4.7.1.tgz", + "integrity": "sha512-71fNbW2LoaRpy337wYhdANkx0E4xbqQuelW39msV//ZZ6SVEK/AuOHEKwgyympKkYXi6Ri/op0snOzH0LmXvyw==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-stately": "3.46.0" + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1446,13 +1456,13 @@ } }, "node_modules/@react-stately/searchfield": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.6.0.tgz", - "integrity": "sha512-cSSDXynj3oQdILHSthEaB2pAIXG0POHKqjZZ07k6L/A0fkyhkwAbR/hyg+idHCH7Ah9hWnS+YhicWE1b6nw1zg==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.6.1.tgz", + "integrity": "sha512-5POKE91Tc5E2nCL9CP8+cVFb1xxHI6M7RkMTbJ0kahQuBlF8EQVN9gjCH7CwnCey5T73TLouS+pdZ3OlkrlqtA==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-stately": "3.46.0" + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1460,13 +1470,13 @@ } }, "node_modules/@react-stately/selection": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.21.0.tgz", - "integrity": "sha512-SBafuZoJgDr7L9dCgMjat1Mx85xOnRO7E5UCtAj6TF/7yhisJVnrNkfnryOH2CunPyXCUgfUlUebkxeXjbW+lw==", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.21.1.tgz", + "integrity": "sha512-Tq8UfAOG5SCxnTYivyYQH5NRpiuEJG2k20wmJ/s4Db0FnnjYg1xbKe55vu2A9ni/nUTLKUMj7MFaJytMIXPwxg==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-stately": "3.46.0" + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1474,13 +1484,13 @@ } }, "node_modules/@react-stately/table": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.16.0.tgz", - "integrity": "sha512-xuvkFuRj8SYE36T+hEed+30oPCzbkcGNduVBAOJGr9K0z7y/a3OxFdOnAv/OsCvKW1sLK231oTSFvZ36zRFndA==", + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.16.1.tgz", + "integrity": "sha512-p4DriyWS05M66EkKIw5VF8H8CKs7WTafmdsrEK+zO5VngKAv9CKYLl2jxlCLxT5+u9aFgkUtdafadAhKrfH/5Q==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-stately": "3.46.0" + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1488,13 +1498,13 @@ } }, "node_modules/@react-stately/utils": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.12.0.tgz", - "integrity": "sha512-7q+iHz9cENvro1dVKgdTxNh1i1mtWuLUI6UHp10TAgpxM9DyRDvmuN35zLXYCmMDgx3WLY2xkwqoez8xd+CdxQ==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.12.1.tgz", + "integrity": "sha512-NqKfzrknpfwiewx7R2vk1P+CneClInPDsIhw15+jOcUYSEfej0nta4cJywuKQJ2gsPwqX/ojDNixedCve9FWGw==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-stately": "3.46.0" + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1502,13 +1512,13 @@ } }, "node_modules/@react-stately/virtualizer": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-4.5.0.tgz", - "integrity": "sha512-Yf1xA9U7PuuaHgxWExwO5MrWCqzDZZTPCzo9YCcsilkOFk2GxMcGNysM71funj+d4CMqsWjCNmgNhZQjBXKjNw==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-4.5.1.tgz", + "integrity": "sha512-lNP20ZDf4GLFYe5WGeWtacjvxqtIAnDudvzW6sBRlfQcQJb4D/DAEl6zvHVUOZ9oPznPg6COxrGmncdY7Pdh8Q==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", - "react-stately": "3.46.0" + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -1606,9 +1616,9 @@ } }, "node_modules/@react-types/shared": { - "version": "3.34.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.34.0.tgz", - "integrity": "sha512-gp6xo/s2lX54AlTjOiqwDnxA7UW79BNvI9dB9pr3LZTzRKCd1ZA+ZbgKw/ReIiWuvvVw/8QFJpnqeeFyLocMcQ==", + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.35.0.tgz", + "integrity": "sha512-iNWvuzEwANttpQpdlu8nPBtdHb0mcCMj1ZTH//iRB5E/14IAnyRlR25rxH7pNLyzHINsPGEKnWvpwDMCT6vziQ==", "license": "Apache-2.0", "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" @@ -1631,9 +1641,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0.tgz", - "integrity": "sha512-TWMZnRLMe63C2Lhyicviu7ZHaU4kxa6PS3rofvc9GmcvptzNN11BcfQ4Sl7MwTOsisQoa2keB/EBdNCAnUo8vA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", + "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", "cpu": [ "arm64" ], @@ -1648,9 +1658,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0.tgz", - "integrity": "sha512-6XcD+8k0gPVItNagEw78/qqcBDwKcwDYS8V2hRmVsfUSIrd8cWe/CBvRDI5toqFyPfj+FJr6t8U6Xj2P2prEew==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", + "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", "cpu": [ "arm64" ], @@ -1665,9 +1675,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0.tgz", - "integrity": "sha512-iN/tWVXRQDWvmZlKdceP1Dwug9GDpEymhb9p4xnEe6zvCg5lFmzVljl+1qR1NVx3yfGpr2Na+CuLmv5IU8uzfQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", + "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", "cpu": [ "x64" ], @@ -1682,9 +1692,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0.tgz", - "integrity": "sha512-jjQMDvvwSOuhOwMszD/klSOjyWMM3zI64hWTj9KT5x4MxRbZAf+7vLQ6qouRhtsLVFHr3f0ILaJAfgENPiQdAQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", + "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", "cpu": [ "x64" ], @@ -1699,9 +1709,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0.tgz", - "integrity": "sha512-d//Dtg2x6/m3mbV64yUGNnDGNZaDGRpDLLNGerHQUVObuNaIQaaDp25yUiqGXtHEXX+NP2d0wAlmKgpYgIAJ2A==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", + "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", "cpu": [ "arm" ], @@ -1716,9 +1726,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0.tgz", - "integrity": "sha512-n7Ofp0mx+aB2cC+Sdy5YtMnXtY9lchnHbY+3Yt0uq9JsWQExf4f5Whu0tK0R8Jdc9S6RchTHjIFY7uc92puOVQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", + "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", "cpu": [ "arm64" ], @@ -1733,9 +1743,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0.tgz", - "integrity": "sha512-EIVjy2cgd7uuMMo94FVkBp7F6DhcZAUwNURkSG3RwUmvAXR6s0ISxM81U+IydcZByPG0pZIHsf1b6kTxoFDgJA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", + "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", "cpu": [ "arm64" ], @@ -1750,9 +1760,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0.tgz", - "integrity": "sha512-JEwwOPcwTLAcpDQlqSmjEmfs63xJnSiUNIGvLcDLUHCWK4XowpS/7c7tUsUH6uT/ct6bMUTdXKfI8967FYj6mg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", + "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", "cpu": [ "ppc64" ], @@ -1767,9 +1777,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0.tgz", - "integrity": "sha512-0wjCFhLrihtAubnT9iA0N++0pSV0z5Hg7tNGdNJ4RFaINceHadoF+kiFGyY1qSSNVIAZtLotG8Ju1bgDPkjnFA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", + "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", "cpu": [ "s390x" ], @@ -1784,9 +1794,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0.tgz", - "integrity": "sha512-Dfn7iak9BcMMePxcoJfpSbWqnEyrp/dRF63/8qW/eHBdOZov6x5aShLLEYGYdIeSJ6vMLK/XCVB+lGIxm41bQA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", + "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", "cpu": [ "x64" ], @@ -1801,9 +1811,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0.tgz", - "integrity": "sha512-5/utzzDmD/pD/bmuaUcbTf/sZYy0aztwIVlfpoW1fTjCZ0BaPOMVWGZL1zvgxyi7ZIVYWlxKONHmSbHuiOh8Jw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", + "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", "cpu": [ "x64" ], @@ -1818,9 +1828,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0.tgz", - "integrity": "sha512-ouJs8VcUomfLfpbUECqFMRqdV4x6aeAK3MA4m6vTrJJjKyWTV5KnxZx7Jd9G+GlDaQQxubcba00x16OyJ1meig==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", + "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", "cpu": [ "arm64" ], @@ -1835,9 +1845,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0.tgz", - "integrity": "sha512-E+oHKGiDA+lsKMmFtffDDw91EryDT7uJocrIuCHqhm6bCTM6xFK+3gaCkYOHfPwQr0cCNarSM2xaELoQDz9jJg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", + "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", "cpu": [ "wasm32" ], @@ -1853,44 +1863,10 @@ "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0.tgz", - "integrity": "sha512-yYK02n8Rngo+gbm1y6G0+7jk1sJ/2Wt7K0me0Y7k/ErBpyf+LJ2gFpqWVTcRV1rUepBlQRmpgWkTQCiiwrK0Ow==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", + "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", "cpu": [ "arm64" ], @@ -1905,9 +1881,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0.tgz", - "integrity": "sha512-14bpChMahXRRXiTwahSl+zzHPW6qQTXtkMuJBFlbo+pqSAews2d4BdCSHfrJ/MBsCZtpmTafsY+1QhBzitcmdg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", + "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", "cpu": [ "x64" ], @@ -1922,16 +1898,16 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.7", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz", - "integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", "dev": true, "license": "MIT" }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.4.tgz", - "integrity": "sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.1.tgz", + "integrity": "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==", "cpu": [ "x64" ], @@ -1942,9 +1918,9 @@ ] }, "node_modules/@spectrum-icons/ui": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@spectrum-icons/ui/-/ui-3.7.0.tgz", - "integrity": "sha512-86iQSDfJb3Ama1WSJ/mEiFy4DJT7e/v4pSmEuX4aKKMzbNYft+O40N18S2POUnmblrb7MQneLC/pgIp1SDBwEQ==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@spectrum-icons/ui/-/ui-3.7.1.tgz", + "integrity": "sha512-veQymocUYo5OciXQajSailOdbWe+k6+2ehfF8D4d0V923D4xOUadtT253xXZ5vEQjPat6Kyp2WDKeQNjd7kL1w==", "license": "Apache-2.0", "dependencies": { "@adobe/react-spectrum-ui": "1.2.1", @@ -1958,9 +1934,9 @@ } }, "node_modules/@spectrum-icons/workflow": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@spectrum-icons/workflow/-/workflow-4.3.0.tgz", - "integrity": "sha512-ILuhgWh9jMXaEVMRuOYgTAjMc22cKyvCtUDyZmc8OEMfOYuejj+Gcp5t6DhaCfE0M9rORtVxCrRgsO2WyEgfUw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@spectrum-icons/workflow/-/workflow-4.3.1.tgz", + "integrity": "sha512-kDF+/EbFVyLGytotqqdYt4uSij4j/PQmDQO5km/C6DyzKjyuic3FnSBFinR+mA6oFv1OjMcLvrrDBqK3wbqRlA==", "license": "Apache-2.0", "dependencies": { "@adobe/react-spectrum-workflow": "2.3.5", @@ -1980,9 +1956,9 @@ "license": "MIT" }, "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==", + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" @@ -1994,6 +1970,7 @@ "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -2008,23 +1985,6 @@ "node": ">=18" } }, - "node_modules/@testing-library/dom/node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/@testing-library/dom/node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", - "dev": true, - "license": "MIT" - }, "node_modules/@testing-library/jest-dom": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", @@ -2045,6 +2005,13 @@ "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", @@ -2146,21 +2113,23 @@ } }, "node_modules/@types/node": { - "version": "24.12.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.4.tgz", - "integrity": "sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==", + "version": "24.13.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.2.tgz", + "integrity": "sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "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==", + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -2171,22 +2140,23 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "dev": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.59.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.3.tgz", - "integrity": "sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.0.tgz", + "integrity": "sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.59.3", - "@typescript-eslint/type-utils": "8.59.3", - "@typescript-eslint/utils": "8.59.3", - "@typescript-eslint/visitor-keys": "8.59.3", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/type-utils": "8.61.0", + "@typescript-eslint/utils": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -2199,32 +2169,23 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.59.3", + "@typescript-eslint/parser": "^8.61.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "8.59.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.3.tgz", - "integrity": "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.0.tgz", + "integrity": "sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.59.3", - "@typescript-eslint/types": "8.59.3", - "@typescript-eslint/typescript-estree": "8.59.3", - "@typescript-eslint/visitor-keys": "8.59.3", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", "debug": "^4.4.3" }, "engines": { @@ -2240,14 +2201,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.59.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.3.tgz", - "integrity": "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.0.tgz", + "integrity": "sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.59.3", - "@typescript-eslint/types": "^8.59.3", + "@typescript-eslint/tsconfig-utils": "^8.61.0", + "@typescript-eslint/types": "^8.61.0", "debug": "^4.4.3" }, "engines": { @@ -2262,14 +2223,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.59.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.3.tgz", - "integrity": "sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.0.tgz", + "integrity": "sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.3", - "@typescript-eslint/visitor-keys": "8.59.3" + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2280,9 +2241,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.59.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.3.tgz", - "integrity": "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.0.tgz", + "integrity": "sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==", "dev": true, "license": "MIT", "engines": { @@ -2297,15 +2258,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.59.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.3.tgz", - "integrity": "sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.0.tgz", + "integrity": "sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.3", - "@typescript-eslint/typescript-estree": "8.59.3", - "@typescript-eslint/utils": "8.59.3", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/utils": "8.61.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -2322,9 +2283,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.59.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.3.tgz", - "integrity": "sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.0.tgz", + "integrity": "sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==", "dev": true, "license": "MIT", "engines": { @@ -2336,16 +2297,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.59.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.3.tgz", - "integrity": "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.0.tgz", + "integrity": "sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.59.3", - "@typescript-eslint/tsconfig-utils": "8.59.3", - "@typescript-eslint/types": "8.59.3", - "@typescript-eslint/visitor-keys": "8.59.3", + "@typescript-eslint/project-service": "8.61.0", + "@typescript-eslint/tsconfig-utils": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -2363,30 +2324,17 @@ "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/utils": { - "version": "8.59.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.3.tgz", - "integrity": "sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.0.tgz", + "integrity": "sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.59.3", - "@typescript-eslint/types": "8.59.3", - "@typescript-eslint/typescript-estree": "8.59.3" + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2401,13 +2349,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.59.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.3.tgz", - "integrity": "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.0.tgz", + "integrity": "sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/types": "8.61.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -2418,14 +2366,27 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@vitejs/plugin-react": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz", - "integrity": "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.2.tgz", + "integrity": "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==", "dev": true, "license": "MIT", "dependencies": { - "@rolldown/pluginutils": "1.0.0-rc.7" + "@rolldown/pluginutils": "^1.0.0" }, "engines": { "node": "^20.19.0 || >=22.12.0" @@ -2445,16 +2406,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.6.tgz", - "integrity": "sha512-7EHDquPthALSV0jhhjgEW8FXaviMx7rSqu8W6oqCoAuOhKov814P99QDV1pxMA3QPv21YudvJngIhjrNI4opLg==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.8.tgz", + "integrity": "sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.6", - "@vitest/utils": "4.1.6", + "@vitest/spy": "4.1.8", + "@vitest/utils": "4.1.8", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -2463,13 +2424,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.6.tgz", - "integrity": "sha512-MCFc63czMjEInOlcY2cpQCvCN+KgbAn+60xu9cMgP4sKaLC5JNAKw7JH8QdAnoAC88hW1IiSNZ+GgVXlN1UcMQ==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.8.tgz", + "integrity": "sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.6", + "@vitest/spy": "4.1.8", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -2490,9 +2451,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.6.tgz", - "integrity": "sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.8.tgz", + "integrity": "sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==", "dev": true, "license": "MIT", "dependencies": { @@ -2503,13 +2464,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.6.tgz", - "integrity": "sha512-nOPCmn2+yD0ZNmKdsXGv/UxMMWbMuKeD6GyYncNwdkYDxpQvrPSKYj2rWuDjC2Y4b6w6hjip5dBKFzEUuZe3vA==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.8.tgz", + "integrity": "sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.6", + "@vitest/utils": "4.1.8", "pathe": "^2.0.3" }, "funding": { @@ -2517,14 +2478,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.6.tgz", - "integrity": "sha512-YhsdE6xAVfTDmzjxL2ZDUvjj+ZsgyOKe+TdQzqkD72wIOmHka8NuGQ6NpTNZv9D2Z63fbwWKJPeVpEw4EQgYxw==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.8.tgz", + "integrity": "sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.6", - "@vitest/utils": "4.1.6", + "@vitest/pretty-format": "4.1.8", + "@vitest/utils": "4.1.8", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -2533,9 +2494,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.6.tgz", - "integrity": "sha512-JFKxMx6udhwKh/Ldo270e17QX710vgunMkuPAvXjHSvC6oqLWAHhVhjg/I71q0u0CBSErIODV1Kjv0FQNSWjdg==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.8.tgz", + "integrity": "sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==", "dev": true, "license": "MIT", "funding": { @@ -2543,13 +2504,13 @@ } }, "node_modules/@vitest/utils": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.6.tgz", - "integrity": "sha512-FxIY+U81R3LGKCxaHHFRQ5+g6/iRgGLmeHWdp2Amj4ljQRrEIWHmZyDfDYBRZlpyqA7qKxtS9DD1dhk8RnRIVQ==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.8.tgz", + "integrity": "sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.6", + "@vitest/pretty-format": "4.1.8", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -2570,6 +2531,7 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2640,13 +2602,13 @@ } }, "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" + "dependencies": { + "dequal": "^2.0.3" } }, "node_modules/array-find-index": { @@ -2687,9 +2649,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.29", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz", - "integrity": "sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==", + "version": "2.10.35", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.35.tgz", + "integrity": "sha512-honAfLBde0HAFLdNyBEfuuENkF6zR+ozxqxa/2zJKHBe1qzLqyTSeRKpdPEHAP03rlDGyQOPnCSxnVpVqQo9Mg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2742,6 +2704,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", @@ -2757,9 +2720,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001792", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", - "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==", + "version": "1.0.30001797", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001797.tgz", + "integrity": "sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==", "dev": true, "funding": [ { @@ -2988,9 +2951,9 @@ } }, "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==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, "license": "MIT" }, @@ -3005,9 +2968,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.354", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.354.tgz", - "integrity": "sha512-JaBHwWcfIdmSAfWM5l3uwjGd431j8YEMikZ+K/2nXVuBqJKyZ0f+2h4n4JY5AyNiZmnY9qQr2RU3v9DxDmHMNg==", + "version": "1.5.371", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.371.tgz", + "integrity": "sha512-e9htk9mAYL6AzmkEhSvVVw7IWGSBJ/Bqdn2eRyRLrj1g6sncN4WbFt5qnILYoCktktr45pyjIrOiRvBThQ808w==", "dev": true, "license": "ISC" }, @@ -3065,18 +3028,19 @@ } }, "node_modules/eslint": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.3.0.tgz", - "integrity": "sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.4.1.tgz", + "integrity": "sha512-AyIKhnOBuOAdueD7RB3xB+YeAWScb9jHsJBgH2Hcde8InP5JYhqrRR6iTMHyTEwgENK54Cp44e4v8BwNhsuHuw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.5", - "@eslint/config-helpers": "^0.5.5", + "@eslint/config-helpers": "^0.6.0", "@eslint/core": "^1.2.1", - "@eslint/plugin-kit": "^0.7.1", + "@eslint/plugin-kit": "^0.7.2", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -3126,6 +3090,7 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -3137,14 +3102,14 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.5.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz", - "integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==", + "version": "5.5.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.6.tgz", + "integrity": "sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ==", "dev": true, "license": "MIT", "dependencies": { "prettier-linter-helpers": "^1.0.1", - "synckit": "^0.11.12" + "synckit": "^0.11.13" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -3217,6 +3182,19 @@ } }, "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", @@ -3229,6 +3207,16 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/espree": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", @@ -3247,6 +3235,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/esquery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", @@ -3495,9 +3496,9 @@ "license": "MIT" }, "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", "dev": true, "license": "MIT", "dependencies": { @@ -3549,9 +3550,9 @@ } }, "node_modules/hasown": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", - "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "dev": true, "license": "MIT", "dependencies": { @@ -3599,9 +3600,9 @@ } }, "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, "license": "MIT", "engines": { @@ -3760,9 +3761,9 @@ } }, "node_modules/jsdom/node_modules/lru-cache": { - "version": "11.3.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", - "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", + "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -3837,7 +3838,8 @@ "version": "1.9.4", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", - "license": "BSD-2-Clause" + "license": "BSD-2-Clause", + "peer": true }, "node_modules/levn": { "version": "0.4.1", @@ -4304,11 +4306,14 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.44", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.44.tgz", - "integrity": "sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==", + "version": "2.0.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", + "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/nopt": { "version": "4.0.3", @@ -4337,28 +4342,6 @@ "validate-npm-package-license": "^3.0.1" } }, - "node_modules/normalize-package-data/node_modules/resolve": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", - "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/normalize-package-data/node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -4386,15 +4369,18 @@ } }, "node_modules/obug": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.2.tgz", + "integrity": "sha512-AWGB9WFcRXOQs48Z/udjI5ZcZMHXwX8XPByNpOydgcGsDLIzjGizhoMWJyKAWze7AVW/2W1i+/gPX4YtKe5cyg==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" ], - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } }, "node_modules/once": { "version": "1.4.0", @@ -4558,6 +4544,7 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -4566,9 +4553,9 @@ } }, "node_modules/postcss": { - "version": "8.5.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", - "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", "dev": true, "funding": [ { @@ -4586,7 +4573,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -4605,11 +4592,12 @@ } }, "node_modules/prettier": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", - "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.4.tgz", + "integrity": "sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -4661,13 +4649,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-format/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "license": "MIT" - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -4679,6 +4660,12 @@ "react-is": "^16.13.1" } }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -4690,28 +4677,29 @@ } }, "node_modules/react": { - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", - "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/react-aria": { - "version": "3.48.0", - "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.48.0.tgz", - "integrity": "sha512-jQjd4rBEIMqecBaAKYJbVGK6EqIHLa5znVQ7jwFyK5vCyljoj6KhgtiahmcIPsG5vG5vEDLw+ba+bEWn6A2P4w==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.49.0.tgz", + "integrity": "sha512-4+oK9FwJQWYhyA5zLfj/feOGY0zZbkE1muoF4gyxMroHVypjcYaRSTlJwvxph2zIlxt757KX6xIK2wJ5Aw1Kog==", "license": "Apache-2.0", "dependencies": { - "@internationalized/date": "^3.12.1", - "@internationalized/number": "^3.6.6", - "@internationalized/string": "^3.2.8", - "@react-types/shared": "^3.34.0", + "@internationalized/date": "^3.12.2", + "@internationalized/number": "^3.6.7", + "@internationalized/string": "^3.2.9", + "@react-types/shared": "^3.35.0", "@swc/helpers": "^0.5.0", "aria-hidden": "^1.2.3", "clsx": "^2.0.0", - "react-stately": "3.46.0", + "react-stately": "3.47.0", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { @@ -4761,21 +4749,23 @@ } }, "node_modules/react-dom": { - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", - "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.6" + "react": "^19.2.7" } }, "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, "license": "MIT" }, "node_modules/react-leaflet": { @@ -4793,15 +4783,15 @@ } }, "node_modules/react-stately": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.46.0.tgz", - "integrity": "sha512-OdxhWvHgs2L4OJGIs7hnuTr5WjjMM6enhNEAMRqiekhF8+ITvA2LRwNftOZwcogaoCslGYq5S2VQTQwnm0GbCA==", + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.47.0.tgz", + "integrity": "sha512-H3ar+SOWP920EbVg7qWfP3fZjZiwhlEJAEJQqjt+w8oKijCwFgr0+R4941PIHscOXRNRvEOjvWilitImC0DdBg==", "license": "Apache-2.0", "dependencies": { - "@internationalized/date": "^3.12.1", - "@internationalized/number": "^3.6.6", - "@internationalized/string": "^3.2.8", - "@react-types/shared": "^3.34.0", + "@internationalized/date": "^3.12.2", + "@internationalized/number": "^3.6.7", + "@internationalized/string": "^3.2.9", + "@react-types/shared": "^3.35.0", "@swc/helpers": "^0.5.0", "use-sync-external-store": "^1.6.0" }, @@ -4906,15 +4896,37 @@ "node": ">=0.10.0" } }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/rolldown": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0.tgz", - "integrity": "sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", + "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.129.0", - "@rolldown/pluginutils": "1.0.0" + "@oxc-project/types": "=0.133.0", + "@rolldown/pluginutils": "^1.0.0" }, "bin": { "rolldown": "bin/cli.mjs" @@ -4923,29 +4935,22 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0", - "@rolldown/binding-darwin-arm64": "1.0.0", - "@rolldown/binding-darwin-x64": "1.0.0", - "@rolldown/binding-freebsd-x64": "1.0.0", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0", - "@rolldown/binding-linux-arm64-gnu": "1.0.0", - "@rolldown/binding-linux-arm64-musl": "1.0.0", - "@rolldown/binding-linux-ppc64-gnu": "1.0.0", - "@rolldown/binding-linux-s390x-gnu": "1.0.0", - "@rolldown/binding-linux-x64-gnu": "1.0.0", - "@rolldown/binding-linux-x64-musl": "1.0.0", - "@rolldown/binding-openharmony-arm64": "1.0.0", - "@rolldown/binding-wasm32-wasi": "1.0.0", - "@rolldown/binding-win32-arm64-msvc": "1.0.0", - "@rolldown/binding-win32-x64-msvc": "1.0.0" - } - }, - "node_modules/rolldown/node_modules/@rolldown/pluginutils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0.tgz", - "integrity": "sha512-aKs/3GSWyV0mrhNmt/96/Z3yczC3yvrzYATCiCXQebBsGyYzjNdUphRVLeJQ67ySKVXRfMxt2lm12pmXvbPFQQ==", - "dev": true, - "license": "MIT" + "@rolldown/binding-android-arm64": "1.0.3", + "@rolldown/binding-darwin-arm64": "1.0.3", + "@rolldown/binding-darwin-x64": "1.0.3", + "@rolldown/binding-freebsd-x64": "1.0.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", + "@rolldown/binding-linux-arm64-gnu": "1.0.3", + "@rolldown/binding-linux-arm64-musl": "1.0.3", + "@rolldown/binding-linux-ppc64-gnu": "1.0.3", + "@rolldown/binding-linux-s390x-gnu": "1.0.3", + "@rolldown/binding-linux-x64-gnu": "1.0.3", + "@rolldown/binding-linux-x64-musl": "1.0.3", + "@rolldown/binding-openharmony-arm64": "1.0.3", + "@rolldown/binding-wasm32-wasi": "1.0.3", + "@rolldown/binding-win32-arm64-msvc": "1.0.3", + "@rolldown/binding-win32-x64-msvc": "1.0.3" + } }, "node_modules/saxes": { "version": "6.0.0", @@ -4967,13 +4972,16 @@ "license": "MIT" }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/shebang-command": { @@ -5154,13 +5162,13 @@ "license": "MIT" }, "node_modules/synckit": { - "version": "0.11.12", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", - "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.13.tgz", + "integrity": "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==", "dev": true, "license": "MIT", "dependencies": { - "@pkgr/core": "^0.2.9" + "@pkgr/core": "^0.3.6" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -5177,9 +5185,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", - "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", "dev": true, "license": "MIT", "engines": { @@ -5187,9 +5195,9 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", - "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "dev": true, "license": "MIT", "dependencies": { @@ -5214,22 +5222,22 @@ } }, "node_modules/tldts": { - "version": "7.0.30", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.30.tgz", - "integrity": "sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.2.tgz", + "integrity": "sha512-kCwffuaH8ntKtygnWe1b4BJKWiCUH30n5KfoTr6IchcXOwR7chAOFJxFrH3vjANafUYrIA4a7SDL+nn7SiR4Sw==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.0.30" + "tldts-core": "^7.4.2" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.0.30", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.30.tgz", - "integrity": "sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.2.tgz", + "integrity": "sha512-nwEyF4vl4RSJjwSjBUmOSxc3BFPoIFdlRthJ6e+5v9P3bHNsoD06UjuqMUspqp7vsEZ1beaHi1km+optiE17yA==", "dev": true, "license": "MIT" }, @@ -5307,6 +5315,7 @@ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5316,16 +5325,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.59.3", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.3.tgz", - "integrity": "sha512-KgusgyDgG4LI8Ih/sWaCtZ06tckLAS5CvT5A4D1Q7bYVoAAyzwiZvE4BmwDHkhRVkvhRBepKeASoFzQetha7Fg==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.61.0.tgz", + "integrity": "sha512-8y31Rd0eGTrDKqhy6vT0HtzhN+YLjQizwX3aA3hPXP/ynSfnrBXcQY5IzsP9/DM7+klX4IUncZZjkchP0z+rUw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.59.3", - "@typescript-eslint/parser": "8.59.3", - "@typescript-eslint/typescript-estree": "8.59.3", - "@typescript-eslint/utils": "8.59.3" + "@typescript-eslint/eslint-plugin": "8.61.0", + "@typescript-eslint/parser": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/utils": "8.61.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5340,9 +5349,9 @@ } }, "node_modules/undici": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", - "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.27.2.tgz", + "integrity": "sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==", "dev": true, "license": "MIT", "engines": { @@ -5350,9 +5359,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true, "license": "MIT" }, @@ -5425,17 +5434,18 @@ } }, "node_modules/vite": { - "version": "8.0.12", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.12.tgz", - "integrity": "sha512-w2dDofOWv2QB09ZITZBsvKTVAlYvPR4IAmrY/v0ir9KvLs0xybR7i48wxhM1/oyBWO34wPns+bPGw5ZrZqDpZg==", + "version": "8.0.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", + "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", - "postcss": "^8.5.14", - "rolldown": "1.0.0", - "tinyglobby": "^0.2.16" + "postcss": "^8.5.15", + "rolldown": "1.0.3", + "tinyglobby": "^0.2.17" }, "bin": { "vite": "bin/vite.js" @@ -5503,19 +5513,19 @@ } }, "node_modules/vitest": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.6.tgz", - "integrity": "sha512-6lvjbS3p9b4CrdCmguzbh2/4uoXhGE2q71R4OX5sqF9R1bo9Xd6fGrMAfvp5wnCzlBnFVdCOp6onuTQVbo8iUQ==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.8.tgz", + "integrity": "sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.1.6", - "@vitest/mocker": "4.1.6", - "@vitest/pretty-format": "4.1.6", - "@vitest/runner": "4.1.6", - "@vitest/snapshot": "4.1.6", - "@vitest/spy": "4.1.6", - "@vitest/utils": "4.1.6", + "@vitest/expect": "4.1.8", + "@vitest/mocker": "4.1.8", + "@vitest/pretty-format": "4.1.8", + "@vitest/runner": "4.1.8", + "@vitest/snapshot": "4.1.8", + "@vitest/spy": "4.1.8", + "@vitest/utils": "4.1.8", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -5543,12 +5553,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.6", - "@vitest/browser-preview": "4.1.6", - "@vitest/browser-webdriverio": "4.1.6", - "@vitest/coverage-istanbul": "4.1.6", - "@vitest/coverage-v8": "4.1.6", - "@vitest/ui": "4.1.6", + "@vitest/browser-playwright": "4.1.8", + "@vitest/browser-preview": "4.1.8", + "@vitest/browser-webdriverio": "4.1.8", + "@vitest/coverage-istanbul": "4.1.8", + "@vitest/coverage-v8": "4.1.8", + "@vitest/ui": "4.1.8", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -5733,6 +5743,7 @@ "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", "dev": true, "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/appointment-booking/src/App.test.tsx b/appointment-booking/src/App.test.tsx index 42a665a31..e56a096ac 100644 --- a/appointment-booking/src/App.test.tsx +++ b/appointment-booking/src/App.test.tsx @@ -49,10 +49,8 @@ vi.mock('@bcgov/design-system-react-components', () => ({ if (level === 5) return
{children}
return
{children}
}, - Link: ({ children, href, ...props }: MockBaseProps) => ( - - {children} - + Link: ({ children, href }: { children?: ReactNode; href?: string }) => ( + {children} ), TagGroup: ({ children, ...props }: MockBaseProps) =>
{children}
, TagList: ({ children, items = [], ...props }: MockTagListProps) => ( From d919121432660c675475946fa7f793b4fcf7009c Mon Sep 17 00:00:00 2001 From: Veenu Punyani Date: Wed, 10 Jun 2026 17:19:09 -0700 Subject: [PATCH 12/12] Update package.json --- appointment-booking/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appointment-booking/package.json b/appointment-booking/package.json index b972c1e92..7ffe36b09 100644 --- a/appointment-booking/package.json +++ b/appointment-booking/package.json @@ -14,7 +14,7 @@ "format:check": "prettier --check src", "type-check": "tsc --noEmit", "preview": "vite preview", - "license-check": "license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;0BSD\" --excludePackages \"appointment-booking@0.0.0;@bcgov/bc-sans@2.1.0\"", + "license-check": "license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;0BSD\" --excludePackages \"appointment-booking@0.0.0;@bcgov/bc-sans@2.1.0;@react-leaflet/core@3.0.0;react-leaflet@5.0.0\"", "ci:check": "npm run lint && npm run type-check && npm run test && npm run build && npm run license-check" }, "dependencies": {