@medplum/react-scheduling 5.1.30 → 5.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,13 +2,100 @@ import type { Appointment } from '@medplum/fhirtypes';
2
2
  import type { HealthcareService } from '@medplum/fhirtypes';
3
3
  import type { HealthcareServiceAvailableTime } from '@medplum/fhirtypes';
4
4
  import type { JSX } from 'react';
5
+ import type { Location as Location_2 } from '@medplum/fhirtypes';
6
+ import type { MantineThemeColors } from '@mantine/core';
7
+ import type { MedplumClient } from '@medplum/core';
8
+ import type { Patient } from '@medplum/fhirtypes';
5
9
  import type { Reference } from '@medplum/fhirtypes';
10
+ import type { Resource } from '@medplum/fhirtypes';
6
11
  import type { Schedule } from '@medplum/fhirtypes';
7
12
  import type { Slot } from '@medplum/fhirtypes';
8
13
  import type { WithId } from '@medplum/core';
9
14
 
15
+ /**
16
+ * One way of holding an appointment: a set of actors whose schedules `$find`
17
+ * intersects in a single request. A role contributes as many actors as were
18
+ * chosen for it, since everything chosen attends.
19
+ */
20
+ export declare interface ActorCombination {
21
+ /** Matches `getActorGroupKey` of the appointments offered for these actors. */
22
+ readonly key: string;
23
+ readonly label: string;
24
+ readonly actors: readonly SchedulingActor[];
25
+ readonly schedules: readonly Reference<Schedule>[];
26
+ }
27
+
28
+ /**
29
+ * What an appointment is being asked for: the schedules chosen, per role.
30
+ * Everything named attends.
31
+ */
32
+ export declare type ActorSelections = Partial<Record<SchedulingRole, readonly ScheduleCandidate[]>>;
33
+
10
34
  export declare function addDays(date: Date, days: number): Date;
11
35
 
36
+ /**
37
+ * Chooses the actors an appointment is held on, for one role.
38
+ *
39
+ * Everything chosen attends: `$find` intersects the schedules behind them,
40
+ * so naming a second actor narrows the times to the ones both are free for.
41
+ *
42
+ * Schedules are searched for as the name is typed (via `AsyncAutocomplete`).
43
+ *
44
+ * @param props - The React props.
45
+ * @returns The field for one role.
46
+ */
47
+ export declare function AppointmentActorSelect(props: AppointmentActorSelectProps): JSX.Element;
48
+
49
+ export declare interface AppointmentActorSelectProps {
50
+ /** The role being filled. */
51
+ readonly role: SchedulingRole;
52
+ /** The service being booked. Nothing is offered until it resolves. */
53
+ readonly service: Reference<HealthcareService> | WithId<HealthcareService> | undefined;
54
+ /**
55
+ * The site being booked at. Actors sited elsewhere are left out: a room or a
56
+ * device anywhere inside it counts, a provider only if one of their
57
+ * PractitionerRoles names it.
58
+ */
59
+ readonly location?: Reference<Location_2> | WithId<Location_2>;
60
+ readonly defaultValue?: readonly ScheduleCandidate[];
61
+ readonly onChange: (candidates: readonly ScheduleCandidate[]) => void;
62
+ readonly error?: string;
63
+ readonly disabled?: boolean;
64
+ }
65
+
66
+ /** What a booking wrote, as `Appointment/$book` returned it. */
67
+ export declare interface AppointmentBooking {
68
+ readonly appointment: WithId<Appointment>;
69
+ /** The times reserved for it, one per schedule it is held on. */
70
+ readonly slots: readonly WithId<Slot>[];
71
+ }
72
+
73
+ /**
74
+ * The booking form, writing the booking itself.
75
+ *
76
+ * Wraps {@link AppointmentProposalForm}: posts `Appointment/$book`, announces the
77
+ * appointment and every time it reserved so views reading them refresh, then
78
+ * reports what was written through `onBooked` — the only required prop.
79
+ *
80
+ * A host doing something else with the proposal mounts the proposal form instead.
81
+ *
82
+ * @param props - The React props.
83
+ * @returns The form.
84
+ */
85
+ export declare function AppointmentBookingForm(props: AppointmentBookingFormProps): JSX.Element;
86
+
87
+ export declare interface AppointmentBookingFormProps extends Omit<AppointmentProposalFormProps, 'onBook'> {
88
+ /**
89
+ * Called with what the booking wrote.
90
+ *
91
+ * The answers stay on screen and the form stops offering to book until one of
92
+ * them changes, so a host can keep this mounted without it writing twice. A
93
+ * failure here is logged rather than shown as a refusal: the appointment exists
94
+ * by the time it runs.
95
+ */
96
+ readonly onBooked: (booking: AppointmentBooking) => void | Promise<void>;
97
+ }
98
+
12
99
  export declare interface AppointmentDay {
13
100
  /** `YYYY-MM-DD` in the scheduling timezone. */
14
101
  readonly key: string;
@@ -39,6 +126,105 @@ export declare interface AppointmentDayTimesProps {
39
126
  readonly selected?: Appointment;
40
127
  }
41
128
 
129
+ /**
130
+ * One option in an appointment pick list: what it is called, over what tells it
131
+ * apart from the others.
132
+ * @param props - The React props.
133
+ * @returns The row.
134
+ */
135
+ export declare function AppointmentOptionRow(props: AppointmentOptionRowProps): JSX.Element;
136
+
137
+ export declare interface AppointmentOptionRowProps {
138
+ readonly label: string;
139
+ /** What tells this option apart from one of the same name. Omitted when there is nothing on file. */
140
+ readonly detail?: string;
141
+ }
142
+
143
+ /**
144
+ * Gathers what a visit is held on, finds a time every one of them is free, and
145
+ * hands the proposal out to be booked.
146
+ *
147
+ * One field per scheduling role, each searching the schedules bookable for the
148
+ * chosen visit type. Everything named attends, because `$find` intersects their
149
+ * schedules — so naming a second room narrows the times rather than widening them.
150
+ *
151
+ * Only a time the search offered can be chosen: the field holding it accepts no
152
+ * input, so nothing can be booked onto time nobody checked availability for.
153
+ *
154
+ * Writes nothing and announces nothing: `onBook` owns that. Mount this to do
155
+ * something other than `$book` with the proposal — hold it through `$hold`, or
156
+ * write it inside a transaction of your own. {@link AppointmentBookingForm} is the
157
+ * one that books.
158
+ *
159
+ * @param props - The React props.
160
+ * @returns The form.
161
+ */
162
+ export declare function AppointmentProposalForm(props: AppointmentProposalFormProps): JSX.Element;
163
+
164
+ export declare interface AppointmentProposalFormProps {
165
+ /** Pre-fills where the visit is, for a host that already knows. */
166
+ readonly defaultLocation?: WithId<Location_2>;
167
+ /** Pre-fills the visit type, for a deep link or a reschedule. */
168
+ readonly defaultService?: WithId<HealthcareService>;
169
+ /** Pre-fills who the visit is for, for a host launching from a patient's chart. */
170
+ readonly defaultPatient?: WithId<Patient>;
171
+ /**
172
+ * The day the time search opens on. Defaults to today.
173
+ *
174
+ * A day, not a time: only a time `$find` offered can be chosen.
175
+ */
176
+ readonly defaultStart?: Date;
177
+ /**
178
+ * The `Identifier.system` a project issues medical record numbers under.
179
+ *
180
+ * Only needed where identifiers carry no `type`. Which identifier is the
181
+ * medical record number is a project's own convention, and there is nothing on
182
+ * an untyped one to recognise it by.
183
+ */
184
+ readonly mrnSystem?: string;
185
+ /**
186
+ * Called when the time search opens or closes.
187
+ *
188
+ * The times render beside the form, not under it, so a host in a side panel has
189
+ * to widen it to fit them.
190
+ */
191
+ readonly onToggleTimeFinder?: (open: boolean) => void;
192
+ /** Called with the visit type as it changes. */
193
+ readonly onChangeService?: (service: WithId<HealthcareService> | undefined) => void;
194
+ /**
195
+ * Performs the booking with the proposal the form assembled.
196
+ *
197
+ * Resolving marks the form booked, so it stops offering to book until an answer
198
+ * changes; rejecting shows the reason as the booking's refusal, every answer kept.
199
+ */
200
+ readonly onBook: (proposal: Appointment) => void | Promise<void>;
201
+ }
202
+
203
+ /**
204
+ * Chooses the service an appointment is for.
205
+ *
206
+ * Only services configured for scheduling are offered. A `HealthcareService`
207
+ * without a `SchedulingParameters` extension has no duration or alignment for
208
+ * `$find` to work from, so booking against it cannot succeed.
209
+ *
210
+ * A chosen site narrows the list to the visit types it can hold: the ones naming
211
+ * that site, and the ones naming no location at all.
212
+ *
213
+ * @param props - The React props.
214
+ * @returns The service field.
215
+ */
216
+ export declare function AppointmentServiceSelect(props: AppointmentServiceSelectProps): JSX.Element;
217
+
218
+ export declare interface AppointmentServiceSelectProps {
219
+ readonly defaultValue?: WithId<HealthcareService>;
220
+ readonly onChange: (service: WithId<HealthcareService> | undefined) => void;
221
+ /** A chosen site, which narrows the services on offer to the ones held there. */
222
+ readonly location?: WithId<Location_2> | Reference<Location_2>;
223
+ readonly label?: string;
224
+ readonly error?: string;
225
+ readonly disabled?: boolean;
226
+ }
227
+
42
228
  /** A calendar day's worth of available times, split by the actors offering them. */
43
229
  export declare interface AppointmentSlotGroup {
44
230
  /** Stable key derived from the actors, so React keys survive a refetch. */
@@ -65,6 +251,17 @@ export declare interface AppointmentSlotGroupCardProps {
65
251
  readonly disabled?: boolean;
66
252
  }
67
253
 
254
+ /**
255
+ * Actor types whose schedules may be offered for booking.
256
+ *
257
+ * Does not include `PractitionerRole` to prevent double-booking
258
+ * a `Practitioner` who holds multiple roles. See `getSchedulingRole` for how
259
+ * `PractitionerRole` is still used to determine eligibility for a schedule.
260
+ */
261
+ export declare const BOOKABLE_ACTOR_TYPES: readonly ["Practitioner", "Location", "Device"];
262
+
263
+ export declare type BookableActorType = (typeof BOOKABLE_ACTOR_TYPES)[number];
264
+
68
265
  export declare function Calendar(props: CalendarProps): JSX.Element;
69
266
 
70
267
  export declare interface CalendarProps {
@@ -135,6 +332,25 @@ export declare function enumerateDateRange(range: DateRange, limit?: number): Da
135
332
  */
136
333
  export declare function filterByTimeOfDay(appointments: readonly Appointment[], timeOfDay: TimeOfDay, timezone?: string): Appointment[];
137
334
 
335
+ /**
336
+ * Narrows candidates to the ones available at one location.
337
+ *
338
+ * A candidate that says nothing about where it is, or whose ancestry cannot be
339
+ * read, is kept: hiding something the caller may be entitled to book is worse
340
+ * than offering something at the wrong site.
341
+ *
342
+ * @param medplum - The Medplum client.
343
+ * @param candidates - Candidates to narrow.
344
+ * @param location - The site being booked at, or undefined to keep everything.
345
+ * @param options - Abort signal.
346
+ * @returns The candidates, minus the ones sited elsewhere.
347
+ */
348
+ export declare function filterCandidatesByLocation(medplum: MedplumClient, candidates: readonly ScheduleCandidate[], location: Reference<Location_2> | WithId<Location_2> | undefined, options?: FilterCandidatesOptions): Promise<ScheduleCandidate[]>;
349
+
350
+ export declare interface FilterCandidatesOptions {
351
+ readonly signal?: AbortSignal;
352
+ }
353
+
138
354
  /**
139
355
  * Says in words which days a search covers.
140
356
  * @param range - The days asked for.
@@ -157,6 +373,18 @@ export declare function formatDayHeading(date: Date): string;
157
373
  */
158
374
  export declare function formatZonedTime(date: Date, timezone?: string): string;
159
375
 
376
+ /**
377
+ * Builds the sets of actors an appointment could be held on.
378
+ *
379
+ * One combination is one `$find` request: the schedules within it are
380
+ * intersected, so its times are the times all of those actors are free.
381
+ *
382
+ * @param selections - What has been chosen.
383
+ * @returns One combination holding every chosen actor, in role order, or an
384
+ * empty list when nothing is chosen.
385
+ */
386
+ export declare function getActorCombinations(selections: ActorSelections): ActorCombination[];
387
+
160
388
  /**
161
389
  * Builds a key identifying the set of actors an appointment is offered by.
162
390
  * @param appointment - The proposed appointment.
@@ -193,6 +421,20 @@ export declare function getActorsKey(actors: readonly Reference[]): string;
193
421
  */
194
422
  export declare function getAppointmentKey(appointment: Appointment): string;
195
423
 
424
+ /**
425
+ * Names a candidate's actor, for use in plain-text option lists.
426
+ * @param candidate - The candidate to name.
427
+ * @returns The name to show.
428
+ */
429
+ export declare function getCandidateDisplay(candidate: ScheduleCandidate): string;
430
+
431
+ /**
432
+ * Returns the role a candidate fills, from the type of its actor.
433
+ * @param candidate - The candidate to read.
434
+ * @returns The role, or undefined for an actor of a type nothing books against.
435
+ */
436
+ export declare function getCandidateRole(candidate: ScheduleCandidate): SchedulingRole | undefined;
437
+
196
438
  /**
197
439
  * Returns an appointment's length in whole minutes.
198
440
  * @param appointment - The proposed appointment.
@@ -222,6 +464,14 @@ export declare function getDurationMinutes(appointment: Appointment | undefined)
222
464
  */
223
465
  export declare function getEffectiveAvailability(service: WithId<HealthcareService> | undefined, schedule?: Schedule): HealthcareServiceAvailableTime[] | undefined;
224
466
 
467
+ /**
468
+ * Reports a window `$find` will not answer, before a request is made for it.
469
+ *
470
+ * @param range - The days asked for.
471
+ * @returns The message to show, or undefined when the range can be searched.
472
+ */
473
+ export declare function getFindWindowError(range: DateRange): string | undefined;
474
+
225
475
  /**
226
476
  * Returns the input type to use for a date or time field.
227
477
  *
@@ -241,6 +491,20 @@ export declare function getNativeInputType(type: 'date' | 'time'): string;
241
491
  */
242
492
  export declare function getSchedulingRole(actorType: SchedulingActorType): SchedulingRole;
243
493
 
494
+ /**
495
+ * Returns everything chosen, across roles.
496
+ * @param selections - What has been chosen.
497
+ * @returns The chosen candidates, in `SCHEDULING_ROLES` order.
498
+ */
499
+ export declare function getSelectedCandidates(selections: ActorSelections): ScheduleCandidate[];
500
+
501
+ /**
502
+ * Reports why the current selections cannot be searched, if they cannot.
503
+ * @param selections - What has been chosen.
504
+ * @returns A message to show the user, or undefined when the search can run.
505
+ */
506
+ export declare function getSelectionError(selections: ActorSelections): string | undefined;
507
+
244
508
  /**
245
509
  * Groups proposed appointments into days, and each day into the sets of actors
246
510
  * offering those times.
@@ -251,6 +515,15 @@ export declare function getSchedulingRole(actorType: SchedulingActorType): Sched
251
515
  */
252
516
  export declare function groupAppointmentsByDay(appointments: readonly Appointment[], timezone?: string): AppointmentDay[];
253
517
 
518
+ export declare function isBookableActorType(value: string | undefined): value is BookableActorType;
519
+
520
+ /**
521
+ * Reports whether a role has to be filled.
522
+ * @param role - The role being filled.
523
+ * @returns Whether a search can run without it.
524
+ */
525
+ export declare function isRoleRequired(role: SchedulingRole): boolean;
526
+
254
527
  /**
255
528
  * Returns whether two instants fall on the same local day.
256
529
  * @param left - The first instant.
@@ -267,6 +540,37 @@ export declare function isSchedulingActorType(value: string | undefined): value
267
540
  */
268
541
  export declare const MAX_FIND_WINDOW_DAYS = 31;
269
542
 
543
+ /**
544
+ * A component that can display appointments and slots from several color-coded calendars.
545
+ *
546
+ * If you pass a Schedule as an attribute of a source, it will be passed back
547
+ * to event handlers alongside the interacted Appointment/Slot resources. It may also
548
+ * specify a color override via a Extension
549
+ * ("https://medplum.com/fhir/StructureDefinition/SchedulingColor").
550
+ *
551
+ * @param props - Component props
552
+ * @returns A React Node with the Calendar UI in it
553
+ */
554
+ export declare function MultiCalendar(props: MultiCalendarProps): JSX.Element;
555
+
556
+ export declare interface MultiCalendarProps {
557
+ sources: MultiCalendarSource[];
558
+ onSelectInterval?: (slotInfo: DateTimeRange) => void;
559
+ onSelectSlot?: (slot: Slot, schedule?: WithId<Schedule>) => void;
560
+ onSelectAppointment?: (appointment: Appointment, schedule?: WithId<Schedule>) => void;
561
+ onDoubleClickAppointment?: (appointment: Appointment, schedule?: WithId<Schedule>) => void;
562
+ onRangeChange?: (range: DateTimeRange) => void;
563
+ className?: string;
564
+ availableTime?: HealthcareServiceAvailableTime[];
565
+ }
566
+
567
+ export declare interface MultiCalendarSource {
568
+ schedule?: WithId<Schedule>;
569
+ slots: Slot[];
570
+ appointments: Appointment[];
571
+ color?: keyof MantineThemeColors;
572
+ }
573
+
270
574
  /**
271
575
  * Converts a `YYYY-MM-DD` key into local midnight of that calendar day.
272
576
  * @param key - A `YYYY-MM-DD` day key.
@@ -304,6 +608,16 @@ export declare function ScheduleAvailabilityEditor(props: ScheduleAvailabilityEd
304
608
  */
305
609
  export declare type ScheduleAvailabilityEditorProps = ScheduleOverrideEditorProps | ServiceDefaultEditorProps;
306
610
 
611
+ /**
612
+ * A Schedule that can be booked for a service, paired with the actor it belongs
613
+ * to.
614
+ */
615
+ export declare interface ScheduleCandidate {
616
+ readonly schedule: WithId<Schedule>;
617
+ /** The actor itself, when the search was able to include it. */
618
+ readonly actorResource: WithId<Resource> | undefined;
619
+ }
620
+
307
621
  /**
308
622
  * Props for editing the availability override a Schedule holds for one service.
309
623
  * @param schedule - The Schedule holding the availability override. Must have exactly one actor, as scheduling requires.
@@ -338,6 +652,32 @@ export declare type SchedulingActorType = (typeof SCHEDULING_ACTOR_TYPES)[number
338
652
 
339
653
  export declare type SchedulingRole = (typeof SCHEDULING_ROLES)[number];
340
654
 
655
+ /**
656
+ * Finds the Schedules that can be booked for one role of a HealthcareService,
657
+ * narrowed to the actors whose name matches what was typed.
658
+ * @param medplum - The Medplum client.
659
+ * @param service - The HealthcareService being booked.
660
+ * @param options - The role, the text typed, the site, an abort signal, and a page size.
661
+ * @returns The matching schedules, each with its actor, by display name.
662
+ */
663
+ export declare function searchScheduleCandidates(medplum: MedplumClient, service: WithId<HealthcareService>, options: SearchScheduleCandidatesOptions): Promise<ScheduleCandidate[]>;
664
+
665
+ export declare interface SearchScheduleCandidatesOptions {
666
+ /** Which of the service's actors to offer. */
667
+ readonly role: SchedulingRole;
668
+ /** What the user typed. Empty offers whatever the role has, unfiltered by name. */
669
+ readonly query: string;
670
+ /**
671
+ * The site being booked at. Actors sited elsewhere are left out: a room or a
672
+ * device anywhere inside it counts, a provider only if one of their
673
+ * PractitionerRoles names it.
674
+ */
675
+ readonly location?: Reference<Location_2> | WithId<Location_2>;
676
+ readonly signal?: AbortSignal;
677
+ /** Maximum schedules to consider. Defaults to 25. */
678
+ readonly count?: number;
679
+ }
680
+
341
681
  /**
342
682
  * Props for editing a service's own default hours, in place of any one calendar's override.
343
683
  * @param schedule - Omitted, which is what selects this mode.
@@ -375,4 +715,34 @@ export declare function setScheduleAvailability(schedule: Schedule, service: Wit
375
715
 
376
716
  export declare type TimeOfDay = 'any' | 'morning' | 'afternoon';
377
717
 
718
+ /**
719
+ * Searches for the times an appointment could be held at.
720
+ * @param options - The service, actor combinations, days, and page size.
721
+ * @returns The times offered, plus load and error state.
722
+ */
723
+ export declare function useProposedAppointments(options: UseProposedAppointmentsOptions): UseProposedAppointmentsResult;
724
+
725
+ export declare interface UseProposedAppointmentsOptions {
726
+ /** The service being booked, as a reference or the resource itself. */
727
+ readonly service: Reference<HealthcareService> | WithId<HealthcareService> | undefined;
728
+ /** The sets of actors to search for, from `getActorCombinations`. */
729
+ readonly combinations: readonly ActorCombination[];
730
+ /** The days to search. Both ends are needed; `$find` refuses an open range. */
731
+ readonly range: DateRange;
732
+ /** Times to ask for per combination. Defaults to 20. */
733
+ readonly count?: number;
734
+ }
735
+
736
+ export declare interface UseProposedAppointmentsResult {
737
+ /**
738
+ * Every time offered, never persisted — `$find` proposes.
739
+ */
740
+ readonly appointments: readonly Appointment[];
741
+ /** How many `$find` requests the current combinations take. */
742
+ readonly requestCount: number;
743
+ readonly loading: boolean;
744
+ /** Set only when every combination failed. */
745
+ readonly error: Error | undefined;
746
+ }
747
+
378
748
  export { }
@@ -1,2 +1,2 @@
1
- .AppointmentFinder_timeGrid{row-gap:var(--mantine-spacing-xs)}:root{--fc-sticky-header-footer-z: 3;--fc-popover-z: 4}.fc-nH{z-index:var(--fc-popover-z)!important}.fc-7s{isolation:isolate}.fc-wa,.fc-wa *,.fc-wa *:before,.fc-wa *:after{box-sizing:border-box!important}.fc-4m,.fc-4m *{cursor:not-allowed!important}.fc-eM{-ms-overflow-style:none!important;scrollbar-width:none!important}.fc-eM::-webkit-scrollbar{display:none!important}.fc-Qo{flex-shrink:0!important}.fc-fi .fc-fl{display:flex!important;flex-direction:row!important;flex-wrap:wrap!important}.fc-Jf .fc-fl>*{float:left!important}[dir=rtl] .fc-Jf .fc-fl>*,.fc-Jf[dir=rtl] .fc-fl>*{float:right!important}.fc-Jf .fc-fl:after{content:""!important;display:block!important;clear:both!important}.fc-DP{cursor:pointer!important}.fc-An{cursor:n-resize!important}.fc-lZ{cursor:s-resize!important}.fc-9V{cursor:w-resize!important}[dir=rtl] .fc-9V,.fc-70{cursor:e-resize!important}[dir=rtl] .fc-70{cursor:w-resize!important}.fc-gQ{cursor:col-resize!important}.fc-mN,.fc-2d,.fc-B0{position:absolute!important;box-sizing:content-box!important;width:100%!important;height:100%!important}.fc-mN{padding:10px!important;margin:-10px!important}.fc-2d{padding-left:10px!important;padding-right:10px!important;margin-left:-10px!important;margin-right:-10px!important}.fc-B0{padding-top:10px!important;padding-bottom:10px!important;margin-top:-10px!important;margin-bottom:-10px!important}.fc-Z1{position:absolute;inset:0 -5px}.fc-1Y{-webkit-user-select:none;-moz-user-select:none;user-select:none}.fc-a9{visibility:hidden}.fc-Tu{border:0!important}.fc-hU{border-left:0!important;border-right:0!important;border-bottom:0!important}.fc-3e{border-top:0!important;border-left:0!important;border-right:0!important}.fc-PB,.fc-II{border-top:0!important;border-bottom:0!important}.fc-PB{border-inline-end:0!important}.fc-II{border-inline-start:0!important}.fc-MQ{border-left:0!important;border-right:0!important}.fc-Vo{border-top:0!important;border-bottom:0!important}.fc-2l{border-inline-start:1px solid transparent!important}.fc-Ao{display:flex!important;flex-direction:row!important}.fc-HH{display:flex!important;flex-direction:column!important}.fc-GV{flex-grow:1!important}.fc-g2{flex-grow:1!important;flex-basis:0!important;min-width:0!important;min-height:0!important}.fc-Ot{min-height:0!important}.fc-hp{flex-grow:1!important;flex-basis:0!important;min-width:0!important}.fc-fi .fc-uD,.fc-fi .fc-jM{display:flex!important;flex-direction:column!important}.fc-OJ{padding:0!important}.fc-oE{margin:0!important}.fc-V3{margin-top:0!important;margin-bottom:0!important}.fc-SS{margin-left:0!important;margin-right:0!important}.fc-y2{white-space:nowrap!important}.fc-CN{white-space:pre!important}.fc-gZ{overflow-anchor:none}.fc-FA{overflow:hidden!important}.fc-7T{white-space:nowrap!important;overflow:hidden!important}.fc-cc{position:relative!important}.fc-H0{position:absolute!important}.fc-6t{inset-inline-start:0!important}.fc-ct{position:absolute!important;inset:0!important}.fc-iv,.fc-Uu{position:absolute!important;left:0!important;right:0!important}.fc-7k,.fc-Yw{position:absolute!important;top:0!important;bottom:0!important}.fc-iv{top:0!important}.fc-Yw{left:0!important;right:0!important;width:0!important}@media not print{.fc-Ip{position:sticky!important}.fc-CS{position:sticky!important;top:0!important}.fc-tT{position:sticky!important;inset-inline-start:0!important}.fc-hy{position:sticky!important;top:0!important;z-index:var(--fc-sticky-header-footer-z)!important}}.fc-Np{box-sizing:content-box!important}.fc-aP{position:absolute!important;left:-10000px!important}.fc-6H{align-items:center!important}.fc-K8{align-items:flex-start!important}.fc-E3{align-items:flex-end!important}.fc-Px{position:sticky!important;bottom:0!important;z-index:var(--fc-sticky-header-footer-z)!important}.fc-J4>*{margin-top:-1px!important}.fc-J4>*>*{height:1px!important}.fc-Jf .fc-Yi{-moz-column-break-inside:avoid!important;break-inside:avoid!important}.fc-Jf .fc-uD{display:table!important;table-layout:fixed!important;width:100%!important;border-spacing:0!important;border-collapse:separate!important}.fc-Jf .fc-jM{display:table-header-group!important;-moz-column-break-inside:avoid!important;break-inside:avoid!important;background:#fff!important;z-index:9999!important;position:relative!important}.fc-fx{min-height:6em!important}.fc-BS{z-index:0}.fc-iu{z-index:1}.fc-Bk:focus-visible{z-index:2}:root{--fc-classic-button: #334155;--fc-classic-button-border: #334155;--fc-classic-button-strong: #1e293b;--fc-classic-button-strong-border: #0f172a;--fc-classic-button-outline: #47556980;--fc-classic-button-foreground: #fff;--fc-classic-primary: #3788d8;--fc-classic-primary-foreground: #fff;--fc-classic-event: var(--fc-classic-primary);--fc-classic-event-contrast: var(--fc-classic-primary-foreground);--fc-classic-background-event: #22c55e;--fc-classic-background-event-opacity: 15%;--fc-classic-background-event-foreground-opacity: 50%;--fc-classic-highlight: #cffafe66;--fc-classic-today: #facc1526;--fc-classic-now: #ef4444;--fc-classic-small-dot-width: 8px;--fc-classic-large-dot-width: 10px;--fc-classic-background: #ffffff;--fc-classic-faint: #0000000A;--fc-classic-muted: #00000014;--fc-classic-strong: #00000024;--fc-classic-foreground: #030712;--fc-classic-faint-foreground: #9ca3af;--fc-classic-muted-foreground: #6b7280;--fc-classic-border: #ddd;--fc-classic-strong-border: #9ca3af}@media not print{[data-color-scheme=dark]{--fc-classic-highlight: #3b82f633;--fc-classic-today: #fef08a1A;--fc-classic-background: #030712;--fc-classic-faint: #ffffff0A;--fc-classic-muted: #ffffff14;--fc-classic-strong: #ffffff24;--fc-classic-foreground: #fff;--fc-classic-faint-foreground: #4b5563;--fc-classic-muted-foreground: #9ca3af;--fc-classic-border: #1f2937;--fc-classic-strong-border: #374151}}.fc-classic-n5m{font-size:16px;line-height:1.5;--fc-classic-border-style: solid}.fc-classic-Z9U{appearance:button;font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0;margin:0;border:0;padding:0}.fc-classic-JiE{color:inherit;text-decoration:inherit}.fc-classic-3Lc{pointer-events:none}.fc-classic-1EY{position:absolute}.fc-classic-eYX{position:relative}.fc-classic-OUe{position:sticky}.fc-classic-MaV{inset-inline:0}.fc-classic-AWB{inset-block:0}.fc-classic-11a{inset-inline-start:-4px}.fc-classic-rbS{inset-inline-start:0}.fc-classic-bEw{inset-inline-end:-4px}.fc-classic-2w8{inset-inline-end:2px}.fc-classic-dnf{inset-inline-end:-3px}.fc-classic-YDC{top:-4px}.fc-classic-n9G{top:0}.fc-classic-2ik{top:2px}.fc-classic-ERR{top:50%}.fc-classic-fJL{bottom:-4px}.fc-classic-jGI{bottom:0}.fc-classic-1V6{left:50%}.fc-classic-88I{order:-1}.fc-classic-gMS{margin:4px}.fc-classic-bvX{margin:8px}.fc-classic-jD5{margin:16px}.fc-classic-J04{margin-inline:-5px}.fc-classic-cKZ{margin-inline:2px}.fc-classic-rVY{margin-inline:4px}.fc-classic-fn8{margin-inline:8px}.fc-classic-148{margin-inline:1px}.fc-classic-cJ3{margin-block:2px}.fc-classic-V9v{margin-block:4px}.fc-classic-2tF{margin-block:8px}.fc-classic-Jzj{margin-inline-start:2px}.fc-classic-Mde{margin-inline-start:8px}.fc-classic-qvL{margin-inline-start:1px}.fc-classic-kp0{margin-inline-end:-4px}.fc-classic-3e1{margin-inline-end:2px}.fc-classic-B3G{margin-inline-end:2.5%}.fc-classic-9hC{margin-inline-end:1px}.fc-classic-Dq8{margin-top:-4px}.fc-classic-a10{margin-top:-5px}.fc-classic-Ika{margin-bottom:1px}.fc-classic-nHS{margin-bottom:-1px}.fc-classic-F99{margin-left:-4px}.fc-classic-eF2{display:contents}.fc-classic-I48{display:block}.fc-classic-dl1{display:flex}.fc-classic-i3N{display:grid}.fc-classic-pps{display:none}.fc-classic-3wQ{width:8px;height:8px}.fc-classic-vnf{width:16px;height:16px}.fc-classic-XUJ{width:20px;height:20px}.fc-classic-uuA{height:8px}.fc-classic-zrJ{height:12px}.fc-classic-84e{min-height:2px}.fc-classic-mhE{min-height:12px}.fc-classic-toR{min-height:1px}.fc-classic-roZ{width:50%}.fc-classic-hza{width:8px}.fc-classic-4Tv{width:5px}.fc-classic-kMV{max-width:200px}.fc-classic-2KU{min-width:0}.fc-classic-aNc{min-width:220px}.fc-classic-yi0{flex-shrink:0}.fc-classic-1Zl{flex-shrink:1}.fc-classic-OLq{flex-shrink:100}.fc-classic-1El{flex-grow:1}.fc-classic-jmT{rotate:180deg}.fc-classic-sgX{flex-direction:column}.fc-classic-1sP{flex-direction:row}.fc-classic-dNl{flex-wrap:wrap}.fc-classic-XpK{align-items:center}.fc-classic-N2M{justify-content:space-between}.fc-classic-E9P{justify-content:center}.fc-classic-LMv{justify-content:flex-end}.fc-classic-aTF{gap:2px}.fc-classic-NWN{gap:4px}.fc-classic-wwb{gap:12px}.fc-classic-yth{gap:20px}.fc-classic-sI7{align-self:flex-start}.fc-classic-pKG{overflow:hidden}.fc-classic-Ig4{border-radius:4px}.fc-classic-AAA{border-radius:3.40282e38px}.fc-classic-Fvv{border-radius:4px}.fc-classic-kmj{border-start-start-radius:4px;border-end-start-radius:4px}.fc-classic-Skl{border-start-end-radius:4px;border-end-end-radius:4px}.fc-classic-C2g{border-end-end-radius:4px}.fc-classic-Z7Q{border-top-left-radius:4px;border-top-right-radius:4px}.fc-classic-2qh{border-bottom-right-radius:4px;border-bottom-left-radius:4px}.fc-classic-wsy{border-style:var(--fc-classic-border-style);border-width:1px}.fc-classic-5JF{border-style:var(--fc-classic-border-style);border-width:4px}.fc-classic-yDA{border-style:var(--fc-classic-border-style);border-width:5px}.fc-classic-Mjo{border-style:var(--fc-classic-border-style);border-width:calc(var(--fc-classic-small-dot-width) / 2)}.fc-classic-GOm{border-style:var(--fc-classic-border-style);border-width:calc(var(--fc-classic-large-dot-width) / 2)}.fc-classic-1Wx{border-inline-style:var(--fc-classic-border-style);border-inline-width:1px}.fc-classic-ybF{border-inline-style:var(--fc-classic-border-style);border-inline-width:5px}.fc-classic-JIC{border-block-style:var(--fc-classic-border-style);border-block-width:1px}.fc-classic-XM3{border-block-style:var(--fc-classic-border-style);border-block-width:5px}.fc-classic-3J4{border-inline-start-style:var(--fc-classic-border-style);border-inline-start-width:1px}.fc-classic-hhi{border-inline-start-style:var(--fc-classic-border-style);border-inline-start-width:5px}.fc-classic-jIH{border-inline-start-style:var(--fc-classic-border-style);border-inline-start-width:6px}.fc-classic-USt{border-inline-end-style:var(--fc-classic-border-style);border-inline-end-width:1px}.fc-classic-Bda{border-inline-end-style:var(--fc-classic-border-style);border-inline-end-width:5px}.fc-classic-ku3{border-top-style:var(--fc-classic-border-style);border-top-width:1px}.fc-classic-bLA{border-top-style:var(--fc-classic-border-style);border-top-width:6px}.fc-classic-zi1{border-bottom-style:var(--fc-classic-border-style);border-bottom-width:1px}.fc-classic-TN2{--fc-classic-border-style: dotted;border-style:dotted}.fc-classic-C1x{border-color:var(--fc-classic-border)}.fc-classic-sYT{border-color:var(--fc-classic-now)}.fc-classic-0Pr{border-color:var(--fc-classic-primary)}.fc-classic-vXO{border-color:var(--fc-classic-button-border)}.fc-classic-rQI{border-color:var(--fc-classic-button-strong-border)}.fc-classic-C0k{border-color:var(--fc-classic-strong-border)}.fc-classic-lNM{border-color:var(--fc-event-color)}.fc-classic-d0j{border-color:#0000}.fc-classic-Pqk{border-inline-color:#0000}.fc-classic-rif{border-block-color:#0000}.fc-classic-0qY{border-inline-start-color:var(--fc-classic-now)}.fc-classic-LaM{border-inline-start-color:#000}.fc-classic-5JV{border-inline-end-color:#000}.fc-classic-1Aa{border-top-color:var(--fc-classic-now)}.fc-classic-Jk3{background-color:var(--fc-classic-background)}.fc-classic-iYS{background-color:var(--fc-classic-faint)}.fc-classic-hLU{background-color:var(--fc-classic-highlight)}.fc-classic-k3f{background-color:var(--fc-classic-muted)}.fc-classic-YjJ{background-color:var(--fc-event-color)}@media not print{@supports (color:color-mix(in lab,red,red)){.fc-classic-hsC{background-color:color-mix(in oklab,var(--fc-event-color) var(--fc-classic-background-event-opacity),transparent)}}@supports not (color:color-mix(in lab,red,red)){.fc-classic-hsC{position:relative;isolation:isolate}.fc-classic-hsC:before{content:"";position:absolute;inset:0;background-color:var(--fc-event-color);opacity:var(--fc-classic-background-event-opacity);z-index:-1}}}.fc-classic-JWq{background-color:var(--fc-classic-button)}.fc-classic-Adi{background-color:var(--fc-classic-button-strong)}.fc-classic-KUX{padding:2px}.fc-classic-XJa{padding:6px}.fc-classic-3N5{padding:8px}.fc-classic-7A6{padding:1px}.fc-classic-oQ2{padding-inline:2px}.fc-classic-Eaq{padding-inline:10px}.fc-classic-Apf{padding-inline:12px}.fc-classic-F1o{padding-inline:1px}.fc-classic-2rx{padding-block:2px}.fc-classic-Jhn{padding-block:4px}.fc-classic-End{padding-block:6px}.fc-classic-dl6{padding-block:8px}.fc-classic-P9h{padding-block:60px}.fc-classic-z5u{padding-block:1px}.fc-classic-a7i{padding-inline-start:2px}.fc-classic-166{padding-top:2px}.fc-classic-8ub{padding-bottom:2px}.fc-classic-cM0{padding-bottom:16px}.fc-classic-HXA{text-align:center}.fc-classic-2HE{text-align:end}.fc-classic-AVD{font-size:24px;line-height:calc(2/1.5)}.fc-classic-vQz{font-size:11px;line-height:1.09091}.fc-classic-1Po{font-size:16px;line-height:1.5}.fc-classic-9yp{font-size:14px;line-height:calc(1.25/.875)}.fc-classic-a3B{font-size:12px;line-height:calc(1/.75)}.fc-classic-DIS{font-weight:700}.fc-classic-IPx{text-overflow:ellipsis}.fc-classic-TZ4{white-space:nowrap}.fc-classic-jm6{white-space:pre}.fc-classic-taq{color:var(--fc-classic-faint-foreground)}.fc-classic-m9h{color:var(--fc-classic-muted-foreground)}.fc-classic-GAX{color:var(--fc-classic-foreground)}.fc-classic-RnT{color:var(--fc-classic-button-foreground)}.fc-classic-i9F{color:var(--fc-event-contrast-color)}.fc-classic-L1Y{font-style:italic}.fc-classic-lMo{opacity:.5}.fc-classic-Q3Z{opacity:.65}.fc-classic-iTG{opacity:.75}.fc-classic-MGT{opacity:var(--fc-classic-background-event-foreground-opacity)}.fc-classic-1kP{box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.fc-classic-tkw{box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.fc-classic-qNs{box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a}.fc-classic-A3h{box-shadow:0 0 0 1px var(--fc-classic-ring-color, currentcolor)}.fc-classic-yKG{--fc-classic-ring-color: var(--fc-classic-background) }.fc-classic-2R2{outline-style:solid;outline-width:1px}.fc-classic-0Bj{outline-style:solid;outline-width:2px}.fc-classic-fFh{outline-offset:-2px}.fc-classic-3Xj{outline-offset:2px}.fc-classic-lYz{outline-color:var(--fc-classic-button-outline)}.fc-classic-zIi{outline-color:var(--fc-classic-primary)}.fc-classic-SDU{background:linear-gradient(var(--fc-classic-muted),var(--fc-classic-muted))var(--fc-classic-background)}.fc-classic-BaR{background:linear-gradient(var(--fc-classic-strong),var(--fc-classic-strong))var(--fc-classic-background)}.fc-classic-mAY:not(:is(:where(.fc-classic-bCs):hover *)){opacity:.65}@media not all and (hover:hover){.fc-classic-mAY{opacity:.65}}@media not print{.fc-classic-hbn{background-color:var(--fc-classic-today)}}@media(hover:hover){.fc-classic-vs6:is(:where(.fc-classic-bCs):hover *){display:block}.fc-classic-Ogp:is(:where(.fc-classic-bCs):hover *){text-decoration-line:underline}}.fc-classic-uk6:first-child{border-start-start-radius:4px;border-end-start-radius:4px}.fc-classic-Tuc:last-child{border-start-end-radius:4px;border-end-end-radius:4px}@media(hover:hover){.fc-classic-bqK:hover{border-color:var(--fc-classic-button-strong-border)}.fc-classic-9Rj:hover{background-color:var(--fc-classic-button-strong)}.fc-classic-Ubk:hover{background-color:var(--fc-classic-faint)}.fc-classic-4yP:hover{background-color:var(--fc-classic-muted)}.fc-classic-Eu0:hover{text-decoration-line:underline}}.fc-classic-OIx:focus-visible{background-color:var(--fc-classic-faint)}.fc-classic-tCP:focus-visible{background-color:var(--fc-classic-muted)}.fc-classic-uqo:focus-visible{outline-style:solid;outline-width:2px}.fc-classic-sOR:focus-visible{outline-style:solid;outline-width:3px}.fc-classic-aIH:active{border-color:var(--fc-classic-button-strong-border)}.fc-classic-5ky:active{background-color:var(--fc-classic-button-strong)}.fc-classic-28F:active{background-color:var(--fc-classic-muted)}.fc-classic-8gz:active{background-color:var(--fc-classic-strong)}@media print{.fc-classic-jsy{border-width:1px}.fc-classic-nQ5{border-color:var(--fc-classic-button-strong-border)}.fc-classic-DO7{border-color:var(--fc-event-color)}.fc-classic-4MR{border-color:#000}.fc-classic-vwH{background-color:#fff}.fc-classic-cfp{color:#000}}[dir=rtl] .fc-classic-jY6{rotate:none}[dir=rtl] .fc-classic-asP{rotate:180deg}.Calendar_wrapper{height:100%;display:flex;flex-direction:column}.Calendar_calendar{flex-grow:1;min-width:0}.dayGridMonth.Calendar_calendar,.timeGridWeek.Calendar_calendar{min-width:480px}.dayGridMonth.Calendar_calendar .Calendar_listItemEventBefore{display:none}.Calendar_interactiveEvent{cursor:pointer}.Calendar_eventTitle{order:1}.Calendar_eventTime{order:2}.Calendar_eventInner{overflow:hidden}.Calendar_eventTitle{white-space:normal;overflow:visible}.Calendar_eventTitle{font-weight:500}.Calendar_eventTime{font-size:10px}.Calendar_shortEvent{.Calendar_eventInner{flex-direction:column;align-items:inherit}}.Calendar_backgroundEventInner>div{opacity:1}.Calendar_backgroundEvent{container-type:size}@container (height < 50px){.Calendar_backgroundEventInner>div{font-size:10px;padding-top:2px}}.Calendar_backgroundEvent{border-radius:var(--mantine-radius-sm)}:root{--fc-classic-today: #b8e0ff4d;[data-color-scheme=dark]{--fc-classic-today: #406e934d}}.Calendar_appointment{--cal-color: light-dark(var(--mantine-color-white), var(--mantine-color-white));--cal-background-color: light-dark(var(--mantine-color-blue-6), var(--mantine-color-blue-8))}.Calendar_slot{--cal-color: light-dark(var(--mantine-color-dark-4), var(--mantine-color-gray-4));--cal-background-color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-gray-7))}.dayGridMonth .Calendar_event:hover{background-color:var(--cal-background-color)}.Calendar_appointment.Calendar_pending{--cal-color: light-dark(var(--mantine-color-blue-8), var(--mantine-color-blue-6));--cal-background-color: light-dark(var(--mantine-color-white), var(--mantine-color-black));border:1px solid var(--cal-color)}.Calendar_slot.Calendar_free{--cal-color: light-dark(var(--mantine-color-dark-7), var(--mantine-color-gray-1));--cal-background-color: light-dark(var(--mantine-color-green-1), var(--mantine-color-green-9))}.Calendar_event,.Calendar_backgroundEvent{background-color:var(--cal-background-color);.Calendar_eventInner{color:var(--cal-color)}.Calendar_backgroundEventInner>div{color:var(--cal-color)}}.Calendar_nonBusinessHours{background-color:light-dark(#0000000A,#FFFFFF2A)}.ScheduleAvailabilityEditor_week{display:grid;grid-template-columns:repeat(5,max-content) 1fr;align-items:center;column-gap:var(--mantine-spacing-xs);row-gap:var(--mantine-spacing-xs);grid-auto-rows:minmax(calc(2.25rem * var(--mantine-scale)),auto)}.ScheduleAvailabilityEditor_dayCell{grid-column:1;padding-right:var(--mantine-spacing-sm)}.ScheduleAvailabilityEditor_rangeStart{grid-column:2}.ScheduleAvailabilityEditor_rangeSeparator{grid-column:3}.ScheduleAvailabilityEditor_rangeEnd{grid-column:4}.ScheduleAvailabilityEditor_addAction{grid-column:5}.ScheduleAvailabilityEditor_removeAction{grid-column:6}.ScheduleAvailabilityEditor_unavailable{grid-column:2 / -1}.ScheduleAvailabilityEditor_overrideToggle{min-height:calc(2.25rem * var(--mantine-scale))}
1
+ .AppointmentFinder_timeGrid{row-gap:var(--mantine-spacing-xs)}.AppointmentFinder_layout{display:flex;flex-wrap:wrap;gap:var(--mantine-spacing-lg);align-items:flex-start}.AppointmentFinder_form{flex:1 1 300px;min-width:0;max-width:420px}.AppointmentFinder_results{flex:1 1 380px;min-width:0}:root{--fc-sticky-header-footer-z: 3;--fc-popover-z: 4}.fc-nH{z-index:var(--fc-popover-z)!important}.fc-7s{isolation:isolate}.fc-wa,.fc-wa *,.fc-wa *:before,.fc-wa *:after{box-sizing:border-box!important}.fc-4m,.fc-4m *{cursor:not-allowed!important}.fc-eM{-ms-overflow-style:none!important;scrollbar-width:none!important}.fc-eM::-webkit-scrollbar{display:none!important}.fc-Qo{flex-shrink:0!important}.fc-fi .fc-fl{display:flex!important;flex-direction:row!important;flex-wrap:wrap!important}.fc-Jf .fc-fl>*{float:left!important}[dir=rtl] .fc-Jf .fc-fl>*,.fc-Jf[dir=rtl] .fc-fl>*{float:right!important}.fc-Jf .fc-fl:after{content:""!important;display:block!important;clear:both!important}.fc-DP{cursor:pointer!important}.fc-An{cursor:n-resize!important}.fc-lZ{cursor:s-resize!important}.fc-9V{cursor:w-resize!important}[dir=rtl] .fc-9V,.fc-70{cursor:e-resize!important}[dir=rtl] .fc-70{cursor:w-resize!important}.fc-gQ{cursor:col-resize!important}.fc-mN,.fc-2d,.fc-B0{position:absolute!important;box-sizing:content-box!important;width:100%!important;height:100%!important}.fc-mN{padding:10px!important;margin:-10px!important}.fc-2d{padding-left:10px!important;padding-right:10px!important;margin-left:-10px!important;margin-right:-10px!important}.fc-B0{padding-top:10px!important;padding-bottom:10px!important;margin-top:-10px!important;margin-bottom:-10px!important}.fc-Z1{position:absolute;inset:0 -5px}.fc-1Y{-webkit-user-select:none;-moz-user-select:none;user-select:none}.fc-a9{visibility:hidden}.fc-Tu{border:0!important}.fc-hU{border-left:0!important;border-right:0!important;border-bottom:0!important}.fc-3e{border-top:0!important;border-left:0!important;border-right:0!important}.fc-PB,.fc-II{border-top:0!important;border-bottom:0!important}.fc-PB{border-inline-end:0!important}.fc-II{border-inline-start:0!important}.fc-MQ{border-left:0!important;border-right:0!important}.fc-Vo{border-top:0!important;border-bottom:0!important}.fc-2l{border-inline-start:1px solid transparent!important}.fc-Ao{display:flex!important;flex-direction:row!important}.fc-HH{display:flex!important;flex-direction:column!important}.fc-GV{flex-grow:1!important}.fc-g2{flex-grow:1!important;flex-basis:0!important;min-width:0!important;min-height:0!important}.fc-Ot{min-height:0!important}.fc-hp{flex-grow:1!important;flex-basis:0!important;min-width:0!important}.fc-fi .fc-uD,.fc-fi .fc-jM{display:flex!important;flex-direction:column!important}.fc-OJ{padding:0!important}.fc-oE{margin:0!important}.fc-V3{margin-top:0!important;margin-bottom:0!important}.fc-SS{margin-left:0!important;margin-right:0!important}.fc-y2{white-space:nowrap!important}.fc-CN{white-space:pre!important}.fc-gZ{overflow-anchor:none}.fc-FA{overflow:hidden!important}.fc-7T{white-space:nowrap!important;overflow:hidden!important}.fc-cc{position:relative!important}.fc-H0{position:absolute!important}.fc-6t{inset-inline-start:0!important}.fc-ct{position:absolute!important;inset:0!important}.fc-iv,.fc-Uu{position:absolute!important;left:0!important;right:0!important}.fc-7k,.fc-Yw{position:absolute!important;top:0!important;bottom:0!important}.fc-iv{top:0!important}.fc-Yw{left:0!important;right:0!important;width:0!important}@media not print{.fc-Ip{position:sticky!important}.fc-CS{position:sticky!important;top:0!important}.fc-tT{position:sticky!important;inset-inline-start:0!important}.fc-hy{position:sticky!important;top:0!important;z-index:var(--fc-sticky-header-footer-z)!important}}.fc-Np{box-sizing:content-box!important}.fc-aP{position:absolute!important;left:-10000px!important}.fc-6H{align-items:center!important}.fc-K8{align-items:flex-start!important}.fc-E3{align-items:flex-end!important}.fc-Px{position:sticky!important;bottom:0!important;z-index:var(--fc-sticky-header-footer-z)!important}.fc-J4>*{margin-top:-1px!important}.fc-J4>*>*{height:1px!important}.fc-Jf .fc-Yi{-moz-column-break-inside:avoid!important;break-inside:avoid!important}.fc-Jf .fc-uD{display:table!important;table-layout:fixed!important;width:100%!important;border-spacing:0!important;border-collapse:separate!important}.fc-Jf .fc-jM{display:table-header-group!important;-moz-column-break-inside:avoid!important;break-inside:avoid!important;background:#fff!important;z-index:9999!important;position:relative!important}.fc-fx{min-height:6em!important}.fc-BS{z-index:0}.fc-iu{z-index:1}.fc-Bk:focus-visible{z-index:2}:root{--fc-classic-button: #334155;--fc-classic-button-border: #334155;--fc-classic-button-strong: #1e293b;--fc-classic-button-strong-border: #0f172a;--fc-classic-button-outline: #47556980;--fc-classic-button-foreground: #fff;--fc-classic-primary: #3788d8;--fc-classic-primary-foreground: #fff;--fc-classic-event: var(--fc-classic-primary);--fc-classic-event-contrast: var(--fc-classic-primary-foreground);--fc-classic-background-event: #22c55e;--fc-classic-background-event-opacity: 15%;--fc-classic-background-event-foreground-opacity: 50%;--fc-classic-highlight: #cffafe66;--fc-classic-today: #facc1526;--fc-classic-now: #ef4444;--fc-classic-small-dot-width: 8px;--fc-classic-large-dot-width: 10px;--fc-classic-background: #ffffff;--fc-classic-faint: #0000000A;--fc-classic-muted: #00000014;--fc-classic-strong: #00000024;--fc-classic-foreground: #030712;--fc-classic-faint-foreground: #9ca3af;--fc-classic-muted-foreground: #6b7280;--fc-classic-border: #ddd;--fc-classic-strong-border: #9ca3af}@media not print{[data-color-scheme=dark]{--fc-classic-highlight: #3b82f633;--fc-classic-today: #fef08a1A;--fc-classic-background: #030712;--fc-classic-faint: #ffffff0A;--fc-classic-muted: #ffffff14;--fc-classic-strong: #ffffff24;--fc-classic-foreground: #fff;--fc-classic-faint-foreground: #4b5563;--fc-classic-muted-foreground: #9ca3af;--fc-classic-border: #1f2937;--fc-classic-strong-border: #374151}}.fc-classic-n5m{font-size:16px;line-height:1.5;--fc-classic-border-style: solid}.fc-classic-Z9U{appearance:button;font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0;margin:0;border:0;padding:0}.fc-classic-JiE{color:inherit;text-decoration:inherit}.fc-classic-3Lc{pointer-events:none}.fc-classic-1EY{position:absolute}.fc-classic-eYX{position:relative}.fc-classic-OUe{position:sticky}.fc-classic-MaV{inset-inline:0}.fc-classic-AWB{inset-block:0}.fc-classic-11a{inset-inline-start:-4px}.fc-classic-rbS{inset-inline-start:0}.fc-classic-bEw{inset-inline-end:-4px}.fc-classic-2w8{inset-inline-end:2px}.fc-classic-dnf{inset-inline-end:-3px}.fc-classic-YDC{top:-4px}.fc-classic-n9G{top:0}.fc-classic-2ik{top:2px}.fc-classic-ERR{top:50%}.fc-classic-fJL{bottom:-4px}.fc-classic-jGI{bottom:0}.fc-classic-1V6{left:50%}.fc-classic-88I{order:-1}.fc-classic-gMS{margin:4px}.fc-classic-bvX{margin:8px}.fc-classic-jD5{margin:16px}.fc-classic-J04{margin-inline:-5px}.fc-classic-cKZ{margin-inline:2px}.fc-classic-rVY{margin-inline:4px}.fc-classic-fn8{margin-inline:8px}.fc-classic-148{margin-inline:1px}.fc-classic-cJ3{margin-block:2px}.fc-classic-V9v{margin-block:4px}.fc-classic-2tF{margin-block:8px}.fc-classic-Jzj{margin-inline-start:2px}.fc-classic-Mde{margin-inline-start:8px}.fc-classic-qvL{margin-inline-start:1px}.fc-classic-kp0{margin-inline-end:-4px}.fc-classic-3e1{margin-inline-end:2px}.fc-classic-B3G{margin-inline-end:2.5%}.fc-classic-9hC{margin-inline-end:1px}.fc-classic-Dq8{margin-top:-4px}.fc-classic-a10{margin-top:-5px}.fc-classic-Ika{margin-bottom:1px}.fc-classic-nHS{margin-bottom:-1px}.fc-classic-F99{margin-left:-4px}.fc-classic-eF2{display:contents}.fc-classic-I48{display:block}.fc-classic-dl1{display:flex}.fc-classic-i3N{display:grid}.fc-classic-pps{display:none}.fc-classic-3wQ{width:8px;height:8px}.fc-classic-vnf{width:16px;height:16px}.fc-classic-XUJ{width:20px;height:20px}.fc-classic-uuA{height:8px}.fc-classic-zrJ{height:12px}.fc-classic-84e{min-height:2px}.fc-classic-mhE{min-height:12px}.fc-classic-toR{min-height:1px}.fc-classic-roZ{width:50%}.fc-classic-hza{width:8px}.fc-classic-4Tv{width:5px}.fc-classic-kMV{max-width:200px}.fc-classic-2KU{min-width:0}.fc-classic-aNc{min-width:220px}.fc-classic-yi0{flex-shrink:0}.fc-classic-1Zl{flex-shrink:1}.fc-classic-OLq{flex-shrink:100}.fc-classic-1El{flex-grow:1}.fc-classic-jmT{rotate:180deg}.fc-classic-sgX{flex-direction:column}.fc-classic-1sP{flex-direction:row}.fc-classic-dNl{flex-wrap:wrap}.fc-classic-XpK{align-items:center}.fc-classic-N2M{justify-content:space-between}.fc-classic-E9P{justify-content:center}.fc-classic-LMv{justify-content:flex-end}.fc-classic-aTF{gap:2px}.fc-classic-NWN{gap:4px}.fc-classic-wwb{gap:12px}.fc-classic-yth{gap:20px}.fc-classic-sI7{align-self:flex-start}.fc-classic-pKG{overflow:hidden}.fc-classic-Ig4{border-radius:4px}.fc-classic-AAA{border-radius:3.40282e38px}.fc-classic-Fvv{border-radius:4px}.fc-classic-kmj{border-start-start-radius:4px;border-end-start-radius:4px}.fc-classic-Skl{border-start-end-radius:4px;border-end-end-radius:4px}.fc-classic-C2g{border-end-end-radius:4px}.fc-classic-Z7Q{border-top-left-radius:4px;border-top-right-radius:4px}.fc-classic-2qh{border-bottom-right-radius:4px;border-bottom-left-radius:4px}.fc-classic-wsy{border-style:var(--fc-classic-border-style);border-width:1px}.fc-classic-5JF{border-style:var(--fc-classic-border-style);border-width:4px}.fc-classic-yDA{border-style:var(--fc-classic-border-style);border-width:5px}.fc-classic-Mjo{border-style:var(--fc-classic-border-style);border-width:calc(var(--fc-classic-small-dot-width) / 2)}.fc-classic-GOm{border-style:var(--fc-classic-border-style);border-width:calc(var(--fc-classic-large-dot-width) / 2)}.fc-classic-1Wx{border-inline-style:var(--fc-classic-border-style);border-inline-width:1px}.fc-classic-ybF{border-inline-style:var(--fc-classic-border-style);border-inline-width:5px}.fc-classic-JIC{border-block-style:var(--fc-classic-border-style);border-block-width:1px}.fc-classic-XM3{border-block-style:var(--fc-classic-border-style);border-block-width:5px}.fc-classic-3J4{border-inline-start-style:var(--fc-classic-border-style);border-inline-start-width:1px}.fc-classic-hhi{border-inline-start-style:var(--fc-classic-border-style);border-inline-start-width:5px}.fc-classic-jIH{border-inline-start-style:var(--fc-classic-border-style);border-inline-start-width:6px}.fc-classic-USt{border-inline-end-style:var(--fc-classic-border-style);border-inline-end-width:1px}.fc-classic-Bda{border-inline-end-style:var(--fc-classic-border-style);border-inline-end-width:5px}.fc-classic-ku3{border-top-style:var(--fc-classic-border-style);border-top-width:1px}.fc-classic-bLA{border-top-style:var(--fc-classic-border-style);border-top-width:6px}.fc-classic-zi1{border-bottom-style:var(--fc-classic-border-style);border-bottom-width:1px}.fc-classic-TN2{--fc-classic-border-style: dotted;border-style:dotted}.fc-classic-C1x{border-color:var(--fc-classic-border)}.fc-classic-sYT{border-color:var(--fc-classic-now)}.fc-classic-0Pr{border-color:var(--fc-classic-primary)}.fc-classic-vXO{border-color:var(--fc-classic-button-border)}.fc-classic-rQI{border-color:var(--fc-classic-button-strong-border)}.fc-classic-C0k{border-color:var(--fc-classic-strong-border)}.fc-classic-lNM{border-color:var(--fc-event-color)}.fc-classic-d0j{border-color:#0000}.fc-classic-Pqk{border-inline-color:#0000}.fc-classic-rif{border-block-color:#0000}.fc-classic-0qY{border-inline-start-color:var(--fc-classic-now)}.fc-classic-LaM{border-inline-start-color:#000}.fc-classic-5JV{border-inline-end-color:#000}.fc-classic-1Aa{border-top-color:var(--fc-classic-now)}.fc-classic-Jk3{background-color:var(--fc-classic-background)}.fc-classic-iYS{background-color:var(--fc-classic-faint)}.fc-classic-hLU{background-color:var(--fc-classic-highlight)}.fc-classic-k3f{background-color:var(--fc-classic-muted)}.fc-classic-YjJ{background-color:var(--fc-event-color)}@media not print{@supports (color:color-mix(in lab,red,red)){.fc-classic-hsC{background-color:color-mix(in oklab,var(--fc-event-color) var(--fc-classic-background-event-opacity),transparent)}}@supports not (color:color-mix(in lab,red,red)){.fc-classic-hsC{position:relative;isolation:isolate}.fc-classic-hsC:before{content:"";position:absolute;inset:0;background-color:var(--fc-event-color);opacity:var(--fc-classic-background-event-opacity);z-index:-1}}}.fc-classic-JWq{background-color:var(--fc-classic-button)}.fc-classic-Adi{background-color:var(--fc-classic-button-strong)}.fc-classic-KUX{padding:2px}.fc-classic-XJa{padding:6px}.fc-classic-3N5{padding:8px}.fc-classic-7A6{padding:1px}.fc-classic-oQ2{padding-inline:2px}.fc-classic-Eaq{padding-inline:10px}.fc-classic-Apf{padding-inline:12px}.fc-classic-F1o{padding-inline:1px}.fc-classic-2rx{padding-block:2px}.fc-classic-Jhn{padding-block:4px}.fc-classic-End{padding-block:6px}.fc-classic-dl6{padding-block:8px}.fc-classic-P9h{padding-block:60px}.fc-classic-z5u{padding-block:1px}.fc-classic-a7i{padding-inline-start:2px}.fc-classic-166{padding-top:2px}.fc-classic-8ub{padding-bottom:2px}.fc-classic-cM0{padding-bottom:16px}.fc-classic-HXA{text-align:center}.fc-classic-2HE{text-align:end}.fc-classic-AVD{font-size:24px;line-height:calc(2/1.5)}.fc-classic-vQz{font-size:11px;line-height:1.09091}.fc-classic-1Po{font-size:16px;line-height:1.5}.fc-classic-9yp{font-size:14px;line-height:calc(1.25/.875)}.fc-classic-a3B{font-size:12px;line-height:calc(1/.75)}.fc-classic-DIS{font-weight:700}.fc-classic-IPx{text-overflow:ellipsis}.fc-classic-TZ4{white-space:nowrap}.fc-classic-jm6{white-space:pre}.fc-classic-taq{color:var(--fc-classic-faint-foreground)}.fc-classic-m9h{color:var(--fc-classic-muted-foreground)}.fc-classic-GAX{color:var(--fc-classic-foreground)}.fc-classic-RnT{color:var(--fc-classic-button-foreground)}.fc-classic-i9F{color:var(--fc-event-contrast-color)}.fc-classic-L1Y{font-style:italic}.fc-classic-lMo{opacity:.5}.fc-classic-Q3Z{opacity:.65}.fc-classic-iTG{opacity:.75}.fc-classic-MGT{opacity:var(--fc-classic-background-event-foreground-opacity)}.fc-classic-1kP{box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.fc-classic-tkw{box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.fc-classic-qNs{box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a}.fc-classic-A3h{box-shadow:0 0 0 1px var(--fc-classic-ring-color, currentcolor)}.fc-classic-yKG{--fc-classic-ring-color: var(--fc-classic-background) }.fc-classic-2R2{outline-style:solid;outline-width:1px}.fc-classic-0Bj{outline-style:solid;outline-width:2px}.fc-classic-fFh{outline-offset:-2px}.fc-classic-3Xj{outline-offset:2px}.fc-classic-lYz{outline-color:var(--fc-classic-button-outline)}.fc-classic-zIi{outline-color:var(--fc-classic-primary)}.fc-classic-SDU{background:linear-gradient(var(--fc-classic-muted),var(--fc-classic-muted))var(--fc-classic-background)}.fc-classic-BaR{background:linear-gradient(var(--fc-classic-strong),var(--fc-classic-strong))var(--fc-classic-background)}.fc-classic-mAY:not(:is(:where(.fc-classic-bCs):hover *)){opacity:.65}@media not all and (hover:hover){.fc-classic-mAY{opacity:.65}}@media not print{.fc-classic-hbn{background-color:var(--fc-classic-today)}}@media(hover:hover){.fc-classic-vs6:is(:where(.fc-classic-bCs):hover *){display:block}.fc-classic-Ogp:is(:where(.fc-classic-bCs):hover *){text-decoration-line:underline}}.fc-classic-uk6:first-child{border-start-start-radius:4px;border-end-start-radius:4px}.fc-classic-Tuc:last-child{border-start-end-radius:4px;border-end-end-radius:4px}@media(hover:hover){.fc-classic-bqK:hover{border-color:var(--fc-classic-button-strong-border)}.fc-classic-9Rj:hover{background-color:var(--fc-classic-button-strong)}.fc-classic-Ubk:hover{background-color:var(--fc-classic-faint)}.fc-classic-4yP:hover{background-color:var(--fc-classic-muted)}.fc-classic-Eu0:hover{text-decoration-line:underline}}.fc-classic-OIx:focus-visible{background-color:var(--fc-classic-faint)}.fc-classic-tCP:focus-visible{background-color:var(--fc-classic-muted)}.fc-classic-uqo:focus-visible{outline-style:solid;outline-width:2px}.fc-classic-sOR:focus-visible{outline-style:solid;outline-width:3px}.fc-classic-aIH:active{border-color:var(--fc-classic-button-strong-border)}.fc-classic-5ky:active{background-color:var(--fc-classic-button-strong)}.fc-classic-28F:active{background-color:var(--fc-classic-muted)}.fc-classic-8gz:active{background-color:var(--fc-classic-strong)}@media print{.fc-classic-jsy{border-width:1px}.fc-classic-nQ5{border-color:var(--fc-classic-button-strong-border)}.fc-classic-DO7{border-color:var(--fc-event-color)}.fc-classic-4MR{border-color:#000}.fc-classic-vwH{background-color:#fff}.fc-classic-cfp{color:#000}}[dir=rtl] .fc-classic-jY6{rotate:none}[dir=rtl] .fc-classic-asP{rotate:180deg}.CalendarBase_wrapper{height:100%;display:flex;flex-direction:column}.CalendarBase_calendar{flex-grow:1;min-width:0}.dayGridMonth.CalendarBase_calendar,.timeGridWeek.CalendarBase_calendar{min-width:480px}.dayGridMonth.CalendarBase_calendar .CalendarBase_listItemEventBefore{display:none}.CalendarBase_interactiveEvent{cursor:pointer}.CalendarBase_eventTitle{order:1}.CalendarBase_eventTime{order:2}.CalendarBase_eventInner{overflow:hidden}.CalendarBase_eventTitle{white-space:normal;overflow:visible}.CalendarBase_eventTitle{font-weight:500}.CalendarBase_eventTime{font-size:10px}.CalendarBase_shortEvent{.CalendarBase_eventInner{flex-direction:column;align-items:inherit}}.CalendarBase_backgroundEventInner>div{opacity:1}.CalendarBase_backgroundEvent{container-type:size}@container (height < 50px){.CalendarBase_backgroundEventInner>div{font-size:10px;padding-top:2px}}.CalendarBase_backgroundEvent{border-radius:var(--mantine-radius-sm)}:root{--fc-classic-today: #b8e0ff4d;[data-color-scheme=dark]{--fc-classic-today: #406e934d}}.CalendarBase_nonBusinessHours{background-color:light-dark(#0000000A,#FFFFFF2A)}.Calendar_wrapper{.appointment{--cal-color: light-dark(var(--mantine-color-white), var(--mantine-color-white));--cal-background-color: light-dark(var(--mantine-color-blue-6), var(--mantine-color-blue-8))}.slot{--cal-color: light-dark(var(--mantine-color-dark-4), var(--mantine-color-gray-4));--cal-background-color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-gray-7))}.dayGridMonth .Calendar_event:hover{background-color:var(--cal-background-color)}.appointment.pending{--cal-color: light-dark(var(--mantine-color-blue-8), var(--mantine-color-blue-6));--cal-background-color: light-dark(var(--mantine-color-white), var(--mantine-color-black));border:1px solid var(--cal-color)}.slot.free{--cal-color: light-dark(var(--mantine-color-dark-7), var(--mantine-color-gray-1));--cal-background-color: light-dark(var(--mantine-color-green-1), var(--mantine-color-green-9))}.Calendar_event,.Calendar_backgroundEvent{background-color:var(--cal-background-color);.Calendar_eventInner{color:var(--cal-color)}.Calendar_backgroundEventInner>div{color:var(--cal-color)}}.Calendar_eventTitle:after{opacity:.7}.appointment.proposed{.Calendar_eventTitle:after{content:" (proposed)"}}.appointment.cancelled{.Calendar_eventTitle:after{content:" (cancelled)"}}.appointment.noshow{.Calendar_eventTitle:after{content:" (no show)"}}.appointment.entered-in-error{.Calendar_eventTitle:after{content:" (entered in error)"}}.appointment.checked-in{.Calendar_eventTitle:after{content:" (checked in)"}}.appointment.waitlist{.Calendar_eventTitle:after{content:" (waitlist)"}}}.appointment .MultiCalendar_eventInner{margin-left:8px;&:before{content:"";width:4px;position:absolute;top:2px;left:2px;bottom:2px;border-radius:8px;background-color:var(--status-color)}}.appointment.pending,.appointment.proposed{--status-color: var(--mantine-color-yellow-3)}.appointment.booked,.appointment.arrived,.appointment.fulfilled,.appointment.checked-in{--status-color: var(--mantine-color-blue-3)}.appointment.cancelled,.appointment.noshow{--status-color: var(--mantine-color-red-3)}.MultiCalendar_eventTime{color:var(--mantine-color-gray-2)}.ScheduleAvailabilityEditor_week{display:grid;grid-template-columns:repeat(5,max-content) 1fr;align-items:center;column-gap:var(--mantine-spacing-xs);row-gap:var(--mantine-spacing-xs);grid-auto-rows:minmax(calc(2.25rem * var(--mantine-scale)),auto)}.ScheduleAvailabilityEditor_dayCell{grid-column:1;padding-right:var(--mantine-spacing-sm)}.ScheduleAvailabilityEditor_rangeStart{grid-column:2}.ScheduleAvailabilityEditor_rangeSeparator{grid-column:3}.ScheduleAvailabilityEditor_rangeEnd{grid-column:4}.ScheduleAvailabilityEditor_addAction{grid-column:5}.ScheduleAvailabilityEditor_removeAction{grid-column:6}.ScheduleAvailabilityEditor_unavailable{grid-column:2 / -1}.ScheduleAvailabilityEditor_overrideToggle{min-height:calc(2.25rem * var(--mantine-scale))}
2
2
  /*# sourceMappingURL=index.css.map */