riverbankcms 0.28.0 → 0.29.0

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.
@@ -22,7 +22,7 @@ function err(error) {
22
22
  }
23
23
 
24
24
  //#endregion
25
- //#region ../core/src/branded.ts
25
+ //#region ../core/src/branded/uuid.ts
26
26
  const UUID_PATTERN$1 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
27
27
  function parseUuidBrand(value, unsafeConstructor) {
28
28
  if (typeof value !== "string") {
@@ -43,22 +43,10 @@ function expectParsedBrandedId(result) {
43
43
  }
44
44
  return result.value;
45
45
  }
46
- const unsafeAsEntryId = (id) => id;
47
- /**
48
- * Mint a preview-fixture entry id. Unsafe at the type level because the
49
- * function can't verify the input string is actually shaped as a preview
50
- * id — the predicate `isPreviewEntryId` is the recommended narrowing path.
51
- */
52
- const unsafeAsPreviewEntryId = (id) => id;
46
+
47
+ //#endregion
48
+ //#region ../core/src/branded/events.ts
53
49
  const unsafeAsEventInstanceId = (id) => id;
54
- const unsafeAsSiteId = (id) => id;
55
- const unsafeAsApiKeyId = (id) => id;
56
- const unsafeAsSiteRouteId = (id) => id;
57
- const unsafeAsPageId = (id) => id;
58
- const unsafeAsPageSurfaceId = (id) => id;
59
- const unsafeAsEditLeaseToken = (id) => id;
60
- const unsafeAsEditorClientId = (id) => id;
61
- const unsafeAsEditorSessionGeneration = (id) => id;
62
50
  const unsafeAsOccurrenceId = (id) => id;
63
51
  const unsafeAsEventOfferingId = (id) => id;
64
52
  const unsafeAsEventSeriesId = (id) => id;
@@ -68,11 +56,87 @@ const unsafeAsEventSeriesRegistrationId = (id) => id;
68
56
  const unsafeAsEventCategoryId = (id) => id;
69
57
  const unsafeAsVenueId = (id) => id;
70
58
  const unsafeAsPricingOptionId = (id) => id;
59
+ const unsafeAsAttendeeId = (id) => id;
60
+ const unsafeAsEventRegistrationCommandId = (id) => id;
61
+ const unsafeAsEventRegistrationCommandRowId = (id) => id;
62
+ const parseOccurrenceId = (value) => parseUuidBrand(value, unsafeAsOccurrenceId);
63
+ const parseEventOfferingId = (value) => parseUuidBrand(value, unsafeAsEventOfferingId);
64
+ const parseEventAttendeeTicketLineId = (value) => parseUuidBrand(value, unsafeAsEventAttendeeTicketLineId);
65
+ const parsePricingOptionId = (value) => parseUuidBrand(value, unsafeAsPricingOptionId);
66
+ const asRetiredCourseId = (id) => id;
67
+ const parseRetiredCourseId = (value) => parseUuidBrand(value, asRetiredCourseId);
68
+ const parseAttendeeId = (value) => parseUuidBrand(value, unsafeAsAttendeeId);
69
+ const parseEventRegistrationCommandId = (value) => parseUuidBrand(value, unsafeAsEventRegistrationCommandId);
70
+ const parseEventRegistrationCommandRowId = (value) => parseUuidBrand(value, unsafeAsEventRegistrationCommandRowId);
71
+ const parseEventSeriesId = (value) => parseUuidBrand(value, unsafeAsEventSeriesId);
72
+ const parseEventSeriesRegistrationId = (value) => parseUuidBrand(value, unsafeAsEventSeriesRegistrationId);
73
+
74
+ //#endregion
75
+ //#region ../core/src/branded/identity.ts
76
+ const unsafeAsSiteId = (id) => id;
77
+ const unsafeAsApiKeyId = (id) => id;
78
+ const unsafeAsUserId = (id) => id;
79
+ const unsafeAsActivityLogEntryId = (id) => id;
80
+ const parseSiteId = (value) => parseUuidBrand(value, unsafeAsSiteId);
81
+ const parseApiKeyId = (value) => parseUuidBrand(value, unsafeAsApiKeyId);
82
+ const parseUserId = (value) => parseUuidBrand(value, unsafeAsUserId);
83
+
84
+ //#endregion
85
+ //#region ../core/src/branded/site.ts
86
+ const unsafeAsSiteRouteId = (id) => id;
87
+ const unsafeAsPageId = (id) => id;
88
+ const unsafeAsPageSurfaceId = (id) => id;
89
+ const unsafeAsEditLeaseToken = (id) => id;
90
+ const unsafeAsEditorClientId = (id) => id;
91
+ const unsafeAsEditorSessionGeneration = (id) => id;
92
+ const unsafeAsSiteFontId = (id) => id;
93
+ const unsafeAsNavigationMenuId = (id) => id;
94
+ const unsafeAsNavigationItemId = (id) => id;
95
+ const parseSiteRouteId = (value) => parseUuidBrand(value, unsafeAsSiteRouteId);
96
+ const parsePageId = (value) => parseUuidBrand(value, unsafeAsPageId);
97
+ const parsePageSurfaceId = (value) => parseUuidBrand(value, unsafeAsPageSurfaceId);
98
+ const parseEditLeaseToken = (value) => parseUuidBrand(value, unsafeAsEditLeaseToken);
99
+ const parseEditorClientId = (value) => parseUuidBrand(value, unsafeAsEditorClientId);
100
+ const parseEditorSessionGeneration = (value) => parseUuidBrand(value, unsafeAsEditorSessionGeneration);
101
+ const parseNavigationMenuId = (value) => parseUuidBrand(value, unsafeAsNavigationMenuId);
102
+ const parseNavigationItemId = (value) => parseUuidBrand(value, unsafeAsNavigationItemId);
103
+
104
+ //#endregion
105
+ //#region ../core/src/branded/orders.ts
71
106
  const unsafeAsMoneyDateString = (value) => value;
72
107
  const unsafeAsStripeCheckoutSessionId = (value) => value;
108
+ const unsafeAsOrderRetirementOperationId = (id) => id;
109
+ const unsafeAsOrderId = (id) => id;
110
+ const unsafeAsOrderItemId = (id) => id;
111
+ const unsafeAsOrderRefundId = (id) => id;
112
+ const unsafeAsOrderPaymentReceiptId = (id) => id;
113
+ const unsafeAsOrderFlexibleBalanceContractId = (id) => id;
114
+ const unsafeAsOrderPaymentPlanId = (id) => id;
115
+ const unsafeAsOrderPaymentPlanInstalmentId = (id) => id;
116
+ const unsafeAsManualPaymentOperationId = (id) => id;
117
+ const unsafeAsCheckoutLineId = (id) => id;
118
+ const unsafeAsShipmentId = (id) => id;
119
+ const parseOrderItemId = (value) => parseUuidBrand(value, unsafeAsOrderItemId);
120
+ const parseOrderRetirementOperationId = (value) => parseUuidBrand(value, unsafeAsOrderRetirementOperationId);
121
+ const parseOrderId = (value) => parseUuidBrand(value, unsafeAsOrderId);
122
+ const parseOrderRefundId = (value) => parseUuidBrand(value, unsafeAsOrderRefundId);
123
+ const parseOrderPaymentReceiptId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentReceiptId);
124
+ const parseOrderFlexibleBalanceContractId = (value) => parseUuidBrand(value, unsafeAsOrderFlexibleBalanceContractId);
125
+ const parseOrderPaymentPlanId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentPlanId);
126
+ const parseOrderPaymentPlanInstalmentId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentPlanInstalmentId);
127
+ const parseManualPaymentOperationId = (value) => parseUuidBrand(value, unsafeAsManualPaymentOperationId);
128
+
129
+ //#endregion
130
+ //#region ../core/src/branded/products.ts
73
131
  const unsafeAsProductId = (id) => id;
74
132
  const unsafeAsProductVariantId = (id) => id;
75
133
  const unsafeAsProductCategoryId = (id) => id;
134
+ const parseProductId = (value) => parseUuidBrand(value, unsafeAsProductId);
135
+ const parseProductVariantId = (value) => parseUuidBrand(value, unsafeAsProductVariantId);
136
+ const parseProductCategoryId = (value) => parseUuidBrand(value, unsafeAsProductCategoryId);
137
+
138
+ //#endregion
139
+ //#region ../core/src/branded/media.ts
76
140
  const unsafeAsMediaAssetId = (id) => id;
77
141
  const unsafeAsUploadSessionId = (id) => id;
78
142
  const unsafeAsStorageBucketName = (value) => value;
@@ -86,6 +150,10 @@ const unsafeAsOriginalFilename = (value) => value;
86
150
  const unsafeAsSafeDownloadFilename = (value) => value;
87
151
  const unsafeAsPositiveByteCount = (value) => value;
88
152
  const unsafeAsPositiveSeconds = (value) => value;
153
+ const parseMediaAssetId = (value) => parseUuidBrand(value, unsafeAsMediaAssetId);
154
+
155
+ //#endregion
156
+ //#region ../core/src/branded/bookings.ts
89
157
  const unsafeAsBookingSessionId = (id) => id;
90
158
  const unsafeAsDatedOfferingCapacityHoldId = (value) => value;
91
159
  const unsafeAsDatedOfferingCapacityHoldAuditRef = (value) => value;
@@ -93,31 +161,46 @@ const unsafeAsDatedOfferingRevocationAuditEventId = (value) => value;
93
161
  const unsafeAsDatedOfferingWaitlistCapacityEffectId = (value) => value;
94
162
  const unsafeAsDatedOfferingWaitlistCapacityEffectClaimToken = (value) => value;
95
163
  const unsafeAsDatedOfferingRunCancellationOperationId = (value) => value;
164
+ const unsafeAsWaitlistEntryId = (id) => id;
165
+ const unsafeAsWaitlistHoldId = (id) => id;
166
+ const parseDatedOfferingCapacityHoldId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingCapacityHoldId);
167
+ const parseDatedOfferingCapacityHoldAuditRef = (value) => parseUuidBrand(value, unsafeAsDatedOfferingCapacityHoldAuditRef);
168
+ const parseDatedOfferingRevocationAuditEventId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingRevocationAuditEventId);
169
+ const parseDatedOfferingWaitlistCapacityEffectId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingWaitlistCapacityEffectId);
170
+ const parseDatedOfferingWaitlistCapacityEffectClaimToken = (value) => parseUuidBrand(value, unsafeAsDatedOfferingWaitlistCapacityEffectClaimToken);
171
+ const parseDatedOfferingRunCancellationOperationId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingRunCancellationOperationId);
172
+
173
+ //#endregion
174
+ //#region ../core/src/branded/entitlements.ts
96
175
  const unsafeAsEntitlementId = (id) => id;
97
- const unsafeAsSiteFontId = (id) => id;
98
- const unsafeAsUserId = (id) => id;
99
- const unsafeAsFormId = (id) => id;
100
- const unsafeAsFormSubmissionId = (id) => id;
101
176
  const unsafeAsPassId = (id) => id;
102
177
  const unsafeAsMembershipId = (id) => id;
178
+ const unsafeAsCustomerPassId = (id) => id;
179
+ const unsafeAsCustomerMembershipId = (id) => id;
180
+ const parsePassId = (value) => parseUuidBrand(value, unsafeAsPassId);
181
+ const parseMembershipId = (value) => parseUuidBrand(value, unsafeAsMembershipId);
182
+ const parseCustomerPassId = (value) => parseUuidBrand(value, unsafeAsCustomerPassId);
183
+ const parseCustomerMembershipId = (value) => parseUuidBrand(value, unsafeAsCustomerMembershipId);
184
+
185
+ //#endregion
186
+ //#region ../core/src/branded/communications.ts
187
+ const unsafeAsFormId = (id) => id;
188
+ const unsafeAsFormSubmissionId = (id) => id;
189
+ const unsafeAsNewsletterSubscriberId = (id) => id;
190
+ const unsafeAsEmailAuditRowId = (id) => id;
191
+ const parseFormId = (value) => parseUuidBrand(value, unsafeAsFormId);
192
+
193
+ //#endregion
194
+ //#region ../core/src/branded/customers.ts
103
195
  const unsafeAsCustomerId = (id) => id;
104
196
  const unsafeAsSiteTermsVersionId = (id) => id;
105
197
  const unsafeAsSiteTermsAgreementId = (id) => id;
106
- const unsafeAsOrderRetirementOperationId = (id) => id;
107
- const unsafeAsOrderId = (id) => id;
108
- const unsafeAsOrderItemId = (id) => id;
109
- const unsafeAsOrderRefundId = (id) => id;
110
- const unsafeAsOrderPaymentReceiptId = (id) => id;
111
- const unsafeAsOrderFlexibleBalanceContractId = (id) => id;
112
- const unsafeAsOrderPaymentPlanId = (id) => id;
113
- const unsafeAsOrderPaymentPlanInstalmentId = (id) => id;
114
- const unsafeAsManualPaymentOperationId = (id) => id;
115
- const unsafeAsCheckoutLineId = (id) => id;
116
- const unsafeAsAttendeeId = (id) => id;
117
- const unsafeAsEventRegistrationCommandId = (id) => id;
118
- const unsafeAsEventRegistrationCommandRowId = (id) => id;
119
- const unsafeAsCustomerPassId = (id) => id;
120
- const unsafeAsCustomerMembershipId = (id) => id;
198
+ const parseCustomerId = (value) => parseUuidBrand(value, unsafeAsCustomerId);
199
+ const parseSiteTermsVersionId = (value) => parseUuidBrand(value, unsafeAsSiteTermsVersionId);
200
+ const parseSiteTermsAgreementId = (value) => parseUuidBrand(value, unsafeAsSiteTermsAgreementId);
201
+
202
+ //#endregion
203
+ //#region ../core/src/branded/appointments.ts
121
204
  const unsafeAsAppointmentId = (id) => id;
122
205
  const unsafeAsAppointmentServiceId = (id) => id;
123
206
  const unsafeAsAppointmentResourceId = (id) => id;
@@ -125,25 +208,44 @@ const unsafeAsAppointmentReservationId = (id) => id;
125
208
  const unsafeAsAppointmentReservationRunId = (id) => id;
126
209
  const unsafeAsAppointmentPaymentRequestId = (id) => id;
127
210
  const unsafeAsStaffMemberId = (id) => id;
211
+ const parseAppointmentId = (value) => parseUuidBrand(value, unsafeAsAppointmentId);
212
+ const parseAppointmentServiceId = (value) => parseUuidBrand(value, unsafeAsAppointmentServiceId);
213
+ const parseAppointmentResourceId = (value) => parseUuidBrand(value, unsafeAsAppointmentResourceId);
214
+ const parseAppointmentReservationId = (value) => parseUuidBrand(value, unsafeAsAppointmentReservationId);
215
+ const parseAppointmentReservationRunId = (value) => parseUuidBrand(value, unsafeAsAppointmentReservationRunId);
216
+
217
+ //#endregion
218
+ //#region ../core/src/branded/calendar.ts
128
219
  const unsafeAsBookingCalendarFeedTokenId = (id) => id;
129
220
  const unsafeAsBookingCalendarFeedTokenPublicId = (id) => id;
130
221
  const unsafeAsBookingCalendarFeedTokenSecret = (value) => value;
131
222
  const unsafeAsBookingCalendarFeedTokenSecretHash = (value) => value;
223
+
224
+ //#endregion
225
+ //#region ../core/src/branded/content.ts
226
+ const unsafeAsEntryId = (id) => id;
227
+ /**
228
+ * Mint a preview-fixture entry id. Unsafe at the type level because the
229
+ * function can't verify the input string is actually shaped as a preview
230
+ * id — the predicate `isPreviewEntryId` is the recommended narrowing path.
231
+ */
232
+ const unsafeAsPreviewEntryId = (id) => id;
132
233
  const unsafeAsContentEntryId = (id) => id;
133
234
  const unsafeAsContentBlockId = (id) => id;
134
235
  const unsafeAsContentVersionId = (id) => id;
135
236
  const unsafeAsEntryContentHash = (value) => value;
237
+ const parseContentEntryId = (value) => parseUuidBrand(value, unsafeAsContentEntryId);
238
+ const parseContentBlockId = (value) => parseUuidBrand(value, unsafeAsContentBlockId);
239
+ const parseContentVersionId = (value) => parseUuidBrand(value, unsafeAsContentVersionId);
240
+
241
+ //#endregion
242
+ //#region ../core/src/branded/billing.ts
136
243
  const unsafeAsStripeInvoiceId = (id) => id;
137
244
  const unsafeAsStripeCustomerId = (id) => id;
138
245
  const unsafeAsStripeSubscriptionId = (id) => id;
139
- const unsafeAsNewsletterSubscriberId = (id) => id;
140
- const unsafeAsNavigationMenuId = (id) => id;
141
- const unsafeAsNavigationItemId = (id) => id;
142
- const unsafeAsEmailAuditRowId = (id) => id;
143
- const unsafeAsWaitlistEntryId = (id) => id;
144
- const unsafeAsWaitlistHoldId = (id) => id;
145
- const unsafeAsShipmentId = (id) => id;
146
- const unsafeAsActivityLogEntryId = (id) => id;
246
+
247
+ //#endregion
248
+ //#region ../core/src/branded/demo.ts
147
249
  const unsafeAsDemoBlueprintId = (id) => id;
148
250
  const unsafeAsDemoBlueprintVersionId = (id) => id;
149
251
  const unsafeAsDemoInstanceId = (id) => id;
@@ -152,8 +254,14 @@ const unsafeAsDemoLifecycleAuditEventId = (id) => id;
152
254
  const unsafeAsDemoRuntimeId = (id) => id;
153
255
  const unsafeAsDemoCapability = (value) => value;
154
256
  const unsafeAsDemoPaymentFlowId = (id) => id;
257
+
258
+ //#endregion
259
+ //#region ../core/src/branded/gifting.ts
155
260
  const unsafeAsGiftingOfferId = (id) => id;
156
261
  const unsafeAsGiftingInstrumentId = (id) => id;
262
+
263
+ //#endregion
264
+ //#region ../core/src/branded/participants.ts
157
265
  const unsafeAsBookingRequirementId = (id) => id;
158
266
  const unsafeAsBookingRequirementEvidenceId = (id) => id;
159
267
  const unsafeAsBookingRequirementDocumentUploadId = (id) => id;
@@ -162,69 +270,15 @@ const unsafeAsParticipantId = (id) => id;
162
270
  const unsafeAsParticipantParticipationId = (id) => id;
163
271
  const unsafeAsParticipantRosterAssertionJobId = (id) => id;
164
272
  const unsafeAsParticipantBookingQuestionsTaskId = (id) => id;
273
+ const parseParticipantId = (value) => parseUuidBrand(value, unsafeAsParticipantId);
274
+ const parseParticipantParticipationId = (value) => parseUuidBrand(value, unsafeAsParticipantParticipationId);
275
+
276
+ //#endregion
277
+ //#region ../core/src/branded/records.ts
165
278
  const unsafeAsPersonRecordId = (id) => id;
166
279
  const unsafeAsEncounterRecordId = (id) => id;
167
280
  const unsafeAsRecordEntryId = (id) => id;
168
281
  const unsafeAsProtectedPayloadKeyVersion = (id) => id;
169
- const parseSiteId = (value) => parseUuidBrand(value, unsafeAsSiteId);
170
- const parseApiKeyId = (value) => parseUuidBrand(value, unsafeAsApiKeyId);
171
- const parseSiteRouteId = (value) => parseUuidBrand(value, unsafeAsSiteRouteId);
172
- const parsePageId = (value) => parseUuidBrand(value, unsafeAsPageId);
173
- const parsePageSurfaceId = (value) => parseUuidBrand(value, unsafeAsPageSurfaceId);
174
- const parseEditLeaseToken = (value) => parseUuidBrand(value, unsafeAsEditLeaseToken);
175
- const parseEditorClientId = (value) => parseUuidBrand(value, unsafeAsEditorClientId);
176
- const parseEditorSessionGeneration = (value) => parseUuidBrand(value, unsafeAsEditorSessionGeneration);
177
- const parseOccurrenceId = (value) => parseUuidBrand(value, unsafeAsOccurrenceId);
178
- const parseEventOfferingId = (value) => parseUuidBrand(value, unsafeAsEventOfferingId);
179
- const parseEventAttendeeTicketLineId = (value) => parseUuidBrand(value, unsafeAsEventAttendeeTicketLineId);
180
- const parsePricingOptionId = (value) => parseUuidBrand(value, unsafeAsPricingOptionId);
181
- const parseUserId = (value) => parseUuidBrand(value, unsafeAsUserId);
182
- const parseProductId = (value) => parseUuidBrand(value, unsafeAsProductId);
183
- const parseProductVariantId = (value) => parseUuidBrand(value, unsafeAsProductVariantId);
184
- const parseProductCategoryId = (value) => parseUuidBrand(value, unsafeAsProductCategoryId);
185
- const parseMediaAssetId = (value) => parseUuidBrand(value, unsafeAsMediaAssetId);
186
- const parseContentEntryId = (value) => parseUuidBrand(value, unsafeAsContentEntryId);
187
- const parseContentBlockId = (value) => parseUuidBrand(value, unsafeAsContentBlockId);
188
- const parseContentVersionId = (value) => parseUuidBrand(value, unsafeAsContentVersionId);
189
- const parseNavigationMenuId = (value) => parseUuidBrand(value, unsafeAsNavigationMenuId);
190
- const parseNavigationItemId = (value) => parseUuidBrand(value, unsafeAsNavigationItemId);
191
- const parsePassId = (value) => parseUuidBrand(value, unsafeAsPassId);
192
- const parseMembershipId = (value) => parseUuidBrand(value, unsafeAsMembershipId);
193
- const asRetiredCourseId = (id) => id;
194
- const parseRetiredCourseId = (value) => parseUuidBrand(value, asRetiredCourseId);
195
- const parseFormId = (value) => parseUuidBrand(value, unsafeAsFormId);
196
- const parseAppointmentId = (value) => parseUuidBrand(value, unsafeAsAppointmentId);
197
- const parseAppointmentServiceId = (value) => parseUuidBrand(value, unsafeAsAppointmentServiceId);
198
- const parseAppointmentResourceId = (value) => parseUuidBrand(value, unsafeAsAppointmentResourceId);
199
- const parseAppointmentReservationId = (value) => parseUuidBrand(value, unsafeAsAppointmentReservationId);
200
- const parseAppointmentReservationRunId = (value) => parseUuidBrand(value, unsafeAsAppointmentReservationRunId);
201
- const parseAttendeeId = (value) => parseUuidBrand(value, unsafeAsAttendeeId);
202
- const parseEventRegistrationCommandId = (value) => parseUuidBrand(value, unsafeAsEventRegistrationCommandId);
203
- const parseEventRegistrationCommandRowId = (value) => parseUuidBrand(value, unsafeAsEventRegistrationCommandRowId);
204
- const parseDatedOfferingCapacityHoldId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingCapacityHoldId);
205
- const parseDatedOfferingCapacityHoldAuditRef = (value) => parseUuidBrand(value, unsafeAsDatedOfferingCapacityHoldAuditRef);
206
- const parseDatedOfferingRevocationAuditEventId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingRevocationAuditEventId);
207
- const parseDatedOfferingWaitlistCapacityEffectId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingWaitlistCapacityEffectId);
208
- const parseDatedOfferingWaitlistCapacityEffectClaimToken = (value) => parseUuidBrand(value, unsafeAsDatedOfferingWaitlistCapacityEffectClaimToken);
209
- const parseDatedOfferingRunCancellationOperationId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingRunCancellationOperationId);
210
- const parseCustomerId = (value) => parseUuidBrand(value, unsafeAsCustomerId);
211
- const parseSiteTermsVersionId = (value) => parseUuidBrand(value, unsafeAsSiteTermsVersionId);
212
- const parseSiteTermsAgreementId = (value) => parseUuidBrand(value, unsafeAsSiteTermsAgreementId);
213
- const parseCustomerPassId = (value) => parseUuidBrand(value, unsafeAsCustomerPassId);
214
- const parseCustomerMembershipId = (value) => parseUuidBrand(value, unsafeAsCustomerMembershipId);
215
- const parseEventSeriesId = (value) => parseUuidBrand(value, unsafeAsEventSeriesId);
216
- const parseEventSeriesRegistrationId = (value) => parseUuidBrand(value, unsafeAsEventSeriesRegistrationId);
217
- const parseParticipantId = (value) => parseUuidBrand(value, unsafeAsParticipantId);
218
- const parseParticipantParticipationId = (value) => parseUuidBrand(value, unsafeAsParticipantParticipationId);
219
- const parseOrderItemId = (value) => parseUuidBrand(value, unsafeAsOrderItemId);
220
- const parseOrderRetirementOperationId = (value) => parseUuidBrand(value, unsafeAsOrderRetirementOperationId);
221
- const parseOrderId = (value) => parseUuidBrand(value, unsafeAsOrderId);
222
- const parseOrderRefundId = (value) => parseUuidBrand(value, unsafeAsOrderRefundId);
223
- const parseOrderPaymentReceiptId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentReceiptId);
224
- const parseOrderFlexibleBalanceContractId = (value) => parseUuidBrand(value, unsafeAsOrderFlexibleBalanceContractId);
225
- const parseOrderPaymentPlanId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentPlanId);
226
- const parseOrderPaymentPlanInstalmentId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentPlanInstalmentId);
227
- const parseManualPaymentOperationId = (value) => parseUuidBrand(value, unsafeAsManualPaymentOperationId);
228
282
 
229
283
  //#endregion
230
284
  //#region ../core/src/date-math.ts
@@ -320,6 +374,12 @@ function clampDurationMinutes(value, min, max) {
320
374
  return result;
321
375
  }
322
376
 
377
+ //#endregion
378
+ //#region ../core/src/assert-never.ts
379
+ function assertNever(value, message = "Unexpected variant") {
380
+ throw new Error(`${message}: ${String(value)}`);
381
+ }
382
+
323
383
  //#endregion
324
384
  //#region ../core/src/demo-capability-policy.ts
325
385
  const demoSurfaceClassificationValues = [
@@ -535,12 +595,6 @@ function dedupeStrings(values) {
535
595
  return [...new Set(values)];
536
596
  }
537
597
 
538
- //#endregion
539
- //#region ../core/src/assert-never.ts
540
- function assertNever(value, message = "Unexpected variant") {
541
- throw new Error(`${message}: ${String(value)}`);
542
- }
543
-
544
598
  //#endregion
545
599
  //#region ../core/src/event-booking-offer.ts
546
600
  const EVENT_PRICING_STRATEGIES = [
@@ -1632,12 +1686,29 @@ function createOriginalPaymentRefundCommand(options) {
1632
1686
  function isAcceptedEventScheduleUpdate(response) {
1633
1687
  return "kind" in response && response.kind === "accepted_unavailable";
1634
1688
  }
1635
-
1636
- //#endregion
1637
- //#region ../core/src/booking-instalments.ts
1638
- function isDepositBearingBookingInstalmentPlan(plan) {
1639
- switch (plan.kind) {
1640
- case "deposit_plus_one_remainder":
1689
+ function refundDestinationAmounts(destination, amountCents) {
1690
+ return {
1691
+ cardCents: destination === "card" ? amountCents : 0,
1692
+ directCents: destination === "direct" ? amountCents : 0,
1693
+ creditCents: destination === "credit" ? amountCents : 0
1694
+ };
1695
+ }
1696
+ function addRefundDestinationAmounts(a, b) {
1697
+ return {
1698
+ cardCents: a.cardCents + b.cardCents,
1699
+ directCents: a.directCents + b.directCents,
1700
+ creditCents: a.creditCents + b.creditCents
1701
+ };
1702
+ }
1703
+ function hasDirectRefundFunding(funding) {
1704
+ return funding?.some((line$1) => line$1.destination === "direct" && line$1.remainingCents > 0) ?? false;
1705
+ }
1706
+
1707
+ //#endregion
1708
+ //#region ../core/src/booking-instalments.ts
1709
+ function isDepositBearingBookingInstalmentPlan(plan) {
1710
+ switch (plan.kind) {
1711
+ case "deposit_plus_one_remainder":
1641
1712
  case "deposit_plus_scheduled_instalments": return true;
1642
1713
  case "equal_scheduled_instalments": return false;
1643
1714
  default: return assertNever$4(plan);
@@ -1850,6 +1921,13 @@ function decideContractClosure(status, reason) {
1850
1921
 
1851
1922
  //#endregion
1852
1923
  //#region ../core/src/booking-payment-options.ts
1924
+ /**
1925
+ * One way a customer may pay for a booking. This is the single definition of
1926
+ * the option type; `booking-payment-schemas.typetest.ts` keeps it equal to the
1927
+ * schema's output in both directions.
1928
+ */
1929
+ /** When a course's instalments must all be paid by: before its first or its last live session. */
1930
+ const BOOKING_COURSE_INSTALMENT_DEADLINES = ["first_session", "last_session"];
1853
1931
  /** Automatic instalments and a flexible balance cannot share one booking offer. */
1854
1932
  function validateBookingPaymentOptionKinds(kinds) {
1855
1933
  if (kinds.length === 0) return err("no_options");
@@ -1861,6 +1939,30 @@ function validateBookingPaymentOptionKinds(kinds) {
1861
1939
  return ok(undefined);
1862
1940
  }
1863
1941
 
1942
+ //#endregion
1943
+ //#region ../core/src/booking-date-time/instant.ts
1944
+ function parseUtcIsoDateTimeString(value) {
1945
+ const normalized = value.trim();
1946
+ const hasUtcSuffix = normalized.endsWith("Z");
1947
+ const hasExplicitOffset = /[+-]\d{2}:\d{2}$/u.test(normalized);
1948
+ if (!hasUtcSuffix && !hasExplicitOffset) {
1949
+ return err("missing-timezone-offset");
1950
+ }
1951
+ const date = new Date(normalized);
1952
+ if (Number.isNaN(date.getTime())) {
1953
+ return err("invalid-date-time");
1954
+ }
1955
+ return ok(date.toISOString());
1956
+ }
1957
+ function toUtcIsoDateTimeString(value) {
1958
+ const parsed = parseUtcIsoDateTimeString(value);
1959
+ if (!parsed.ok) {
1960
+ const message = parsed.error === "missing-timezone-offset" ? `Expected an offset-aware ISO datetime, received "${value}"` : `Expected a valid ISO datetime, received "${value}"`;
1961
+ throw new Error(message);
1962
+ }
1963
+ return parsed.value;
1964
+ }
1965
+
1864
1966
  //#endregion
1865
1967
  //#region ../core/src/date-time-formatter.ts
1866
1968
  /** Shared Intl engine, internal to core's date presentation owners. */
@@ -1906,6 +2008,12 @@ function formatIntlRange(formatter, start, end) {
1906
2008
  return output;
1907
2009
  }
1908
2010
 
2011
+ //#endregion
2012
+ //#region ../core/src/booking-date-time/parts.ts
2013
+ function formatToPartsLookup(date, locale, timeZone, format) {
2014
+ return new Map(getDateTimeFormatter(locale, timeZone, format).formatToParts(date).map((part) => [part.type, part.value]));
2015
+ }
2016
+
1909
2017
  //#endregion
1910
2018
  //#region ../core/src/booking-time-zone.ts
1911
2019
  const TIME_ZONE_VALIDITY_CACHE_LIMIT = 100;
@@ -1939,40 +2047,42 @@ function parseBookingTimeZone(timeZone) {
1939
2047
  }
1940
2048
 
1941
2049
  //#endregion
1942
- //#region ../core/src/booking-date-time.ts
1943
- const DEFAULT_LOCALE$1 = "en-US";
2050
+ //#region ../core/src/booking-date-time/time-zone.ts
1944
2051
  const FALLBACK_TIMEZONE = "UTC";
1945
- const DEFAULT_BOOKING_DATE_TIME_FORMAT = {
1946
- weekday: "short",
1947
- month: "short",
1948
- day: "numeric",
1949
- hour: "numeric",
1950
- minute: "2-digit"
1951
- };
1952
- const START_OF_DAY = {
1953
- hour: 0,
1954
- minute: 0,
1955
- second: 0
1956
- };
1957
- const LOCAL_DATE_PATTERN = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/u;
1958
2052
  function getSafeTimeZone(timeZone) {
1959
2053
  const normalized = typeof timeZone === "string" ? timeZone.trim() : "";
1960
2054
  return normalized.length > 0 && isValidBookingTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
1961
2055
  }
1962
- function parseStrictBookingTimeZone(timeZone) {
1963
- const parsed = parseBookingTimeZone(timeZone);
1964
- return parsed.ok ? parsed.value : null;
2056
+ function toBookingTimeZone(timeZone) {
2057
+ return getSafeTimeZone(timeZone);
1965
2058
  }
1966
- function formatParseError(error) {
1967
- switch (error.reason) {
1968
- case "invalid_starts_at": return `Expected a valid UTC/offset-aware ISO datetime in startsAt, received "${error.value}"`;
1969
- case "invalid_ends_at": return `Expected a valid UTC/offset-aware ISO datetime in endsAt, received "${error.value ?? ""}"`;
1970
- case "invalid_time_zone": return `Expected a valid IANA timezone in timeZone, received "${error.value}"`;
1971
- }
2059
+ const DEFAULT_BOOKING_TIME_ZONE = FALLBACK_TIMEZONE;
2060
+ function resolveBookingTimezone(venueTimezone, siteDefaultTimezone) {
2061
+ return venueTimezone ?? siteDefaultTimezone;
1972
2062
  }
1973
- function formatToPartsLookup(date, locale, timeZone, format) {
1974
- return new Map(getDateTimeFormatter(locale, timeZone, format).formatToParts(date).map((part) => [part.type, part.value]));
2063
+ function resolveBookingTimeZoneId(...candidates) {
2064
+ const normalized = candidates.map((candidate$1) => typeof candidate$1 === "string" ? candidate$1.trim() : "");
2065
+ return normalized.find((candidate$1) => candidate$1.length > 0 && isValidBookingTimeZone(candidate$1)) ?? FALLBACK_TIMEZONE;
2066
+ }
2067
+ /** Canonical business-zone admission, shared by server and public wire boundaries. */
2068
+ const DEFAULT_BOOKING_BUSINESS_TIME_ZONE = "Europe/London";
2069
+ /** Stored site zones must be valid; a broken read must not silently choose another zone. */
2070
+ function requireBookingTimeZone(value) {
2071
+ const parsed = parseBookingTimeZone(value);
2072
+ if (!parsed.ok) throw new Error("Expected a valid canonical site time zone");
2073
+ return parsed.value;
1975
2074
  }
2075
+ /** Effect boundary for browser-authored local inputs; formats no displayed date. */
2076
+ function getRuntimeBookingTimeZone() {
2077
+ return resolveBookingTimeZoneId(new Intl.DateTimeFormat("en-GB").resolvedOptions().timeZone);
2078
+ }
2079
+ function resolveBookingBusinessTimeZone(value) {
2080
+ return resolveBookingTimeZoneId(value, DEFAULT_BOOKING_BUSINESS_TIME_ZONE);
2081
+ }
2082
+
2083
+ //#endregion
2084
+ //#region ../core/src/booking-date-time/local.ts
2085
+ const LOCAL_DATE_PATTERN = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/u;
1976
2086
  function getZonedDateTimeParts(date, timeZone) {
1977
2087
  const parts = formatToPartsLookup(date, "en-GB", timeZone, {
1978
2088
  year: "numeric",
@@ -1999,70 +2109,201 @@ function formatDateKey(date) {
1999
2109
  const day = String(date.day).padStart(2, "0");
2000
2110
  return `${year}-${month}-${day}`;
2001
2111
  }
2002
- function toBookingTimeZone(timeZone) {
2003
- return getSafeTimeZone(timeZone);
2112
+ function getBookingLocalDateKey(input) {
2113
+ return formatDateKey(getLocalScheduleDate(new Date(input.startsAt), input.timeZone));
2004
2114
  }
2005
- const DEFAULT_BOOKING_TIME_ZONE = FALLBACK_TIMEZONE;
2006
- function resolveBookingTimezone(venueTimezone, siteDefaultTimezone) {
2007
- return venueTimezone ?? siteDefaultTimezone;
2115
+ function compareLocalScheduleDates(left, right) {
2116
+ return Date.UTC(left.year, left.month - 1, left.day) - Date.UTC(right.year, right.month - 1, right.day);
2008
2117
  }
2009
- function resolveBookingTimeZoneId(...candidates) {
2010
- for (const candidate$1 of candidates) {
2011
- const normalized = typeof candidate$1 === "string" ? candidate$1.trim() : "";
2012
- if (normalized && isValidBookingTimeZone(normalized)) {
2013
- return normalized;
2014
- }
2118
+ function parseBookingLocalDate(value) {
2119
+ const match = LOCAL_DATE_PATTERN.exec(value.trim());
2120
+ if (match === null || match.groups === undefined) {
2121
+ throw new Error(`Invalid booking date format: "${value}" (expected YYYY-MM-DD)`);
2122
+ }
2123
+ const year = Number(match.groups.year);
2124
+ const month = Number(match.groups.month);
2125
+ const day = Number(match.groups.day);
2126
+ const candidate$1 = new Date(Date.UTC(year, month - 1, day, 12, 0, 0));
2127
+ if (Number.isNaN(candidate$1.getTime()) || candidate$1.getUTCFullYear() !== year || candidate$1.getUTCMonth() + 1 !== month || candidate$1.getUTCDate() !== day) {
2128
+ throw new Error(`Invalid booking date format: "${value}" (expected YYYY-MM-DD)`);
2015
2129
  }
2016
- return FALLBACK_TIMEZONE;
2130
+ return {
2131
+ year,
2132
+ month,
2133
+ day
2134
+ };
2017
2135
  }
2018
- /** Canonical business-zone admission, shared by server and public wire boundaries. */
2019
- const DEFAULT_BOOKING_BUSINESS_TIME_ZONE = "Europe/London";
2020
- /** Stored site zones must be valid; a broken read must not silently choose another zone. */
2021
- function requireBookingTimeZone(value) {
2022
- const parsed = parseBookingTimeZone(value);
2023
- if (!parsed.ok) throw new Error("Expected a valid canonical site time zone");
2024
- return parsed.value;
2136
+ /** Canonical schedule text at command and SDK boundaries: HH:MM or HH:MM:SS. */
2137
+ const localScheduleTimePattern = /^([01]\d|2[0-3]):[0-5]\d(:[0-5]\d)?$/u;
2138
+ function parseLocalScheduleTime(value) {
2139
+ const match = /^(?<hour>[01]?\d|2[0-3]):(?<minute>[0-5]\d)(?::(?<second>[0-5]\d))?$/u.exec(value.trim());
2140
+ if (match === null || match.groups === undefined) {
2141
+ throw new Error(`Invalid start time format: "${value}" (expected HH:MM or HH:MM:SS)`);
2142
+ }
2143
+ const hour = Number(match.groups.hour);
2144
+ const minute = Number(match.groups.minute);
2145
+ const second = Number(match.groups.second ?? "0");
2146
+ return {
2147
+ hour,
2148
+ minute,
2149
+ second
2150
+ };
2025
2151
  }
2026
- /** Effect boundary for browser-authored local inputs; formats no displayed date. */
2027
- function getRuntimeBookingTimeZone() {
2028
- return resolveBookingTimeZoneId(new Intl.DateTimeFormat("en-GB").resolvedOptions().timeZone);
2152
+ function getLocalScheduleDate(date, timeZone) {
2153
+ const parts = getZonedDateTimeParts(date, getSafeTimeZone(timeZone));
2154
+ return {
2155
+ year: parts.year,
2156
+ month: parts.month,
2157
+ day: parts.day
2158
+ };
2029
2159
  }
2030
- function resolveBookingBusinessTimeZone(value) {
2031
- return resolveBookingTimeZoneId(value, DEFAULT_BOOKING_BUSINESS_TIME_ZONE);
2160
+ function getLocalScheduleTime(date, timeZone) {
2161
+ const parts = getZonedDateTimeParts(date, getSafeTimeZone(timeZone));
2162
+ return {
2163
+ hour: parts.hour,
2164
+ minute: parts.minute,
2165
+ second: parts.second
2166
+ };
2032
2167
  }
2033
- function parseUtcIsoDateTimeString(value) {
2034
- const normalized = value.trim();
2035
- const hasUtcSuffix = normalized.endsWith("Z");
2036
- const hasExplicitOffset = /[+-]\d{2}:\d{2}$/u.test(normalized);
2037
- if (!hasUtcSuffix && !hasExplicitOffset) {
2038
- return err("missing-timezone-offset");
2168
+ function formatLocalScheduleDate(date) {
2169
+ return formatDateKey(date);
2170
+ }
2171
+ function formatLocalScheduleTime(time) {
2172
+ return `${String(time.hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}`;
2173
+ }
2174
+ function getDaysInLocalMonth(year, month) {
2175
+ return new Date(Date.UTC(year, month, 0)).getUTCDate();
2176
+ }
2177
+ function addLocalScheduleDays(date, days) {
2178
+ const utcDate = new Date(Date.UTC(date.year, date.month - 1, date.day + days, 12, 0, 0));
2179
+ return {
2180
+ year: utcDate.getUTCFullYear(),
2181
+ month: utcDate.getUTCMonth() + 1,
2182
+ day: utcDate.getUTCDate()
2183
+ };
2184
+ }
2185
+ function addLocalScheduleMonths(date, months) {
2186
+ const targetMonthIndex = date.month - 1 + months;
2187
+ const base = new Date(Date.UTC(date.year, targetMonthIndex, 1, 12, 0, 0));
2188
+ const year = base.getUTCFullYear();
2189
+ const month = base.getUTCMonth() + 1;
2190
+ const day = Math.min(date.day, getDaysInLocalMonth(year, month));
2191
+ return {
2192
+ year,
2193
+ month,
2194
+ day
2195
+ };
2196
+ }
2197
+ function getLocalScheduleDayOfWeek(date) {
2198
+ return new Date(Date.UTC(date.year, date.month - 1, date.day, 12, 0, 0)).getUTCDay();
2199
+ }
2200
+ function localScheduleDateTimeToUtcDate(localDate, localTime, timeZone) {
2201
+ const resolvedTimeZone = getSafeTimeZone(timeZone);
2202
+ const targetLocalMs = Date.UTC(localDate.year, localDate.month - 1, localDate.day, localTime.hour, localTime.minute, localTime.second, 0);
2203
+ return resolveLocalInstant(targetLocalMs, resolvedTimeZone, targetLocalMs, []);
2204
+ }
2205
+ function resolveLocalInstant(targetLocalMs, timeZone, guess, seen) {
2206
+ if (seen.length === 4) return new Date(guess);
2207
+ const actual = getZonedDateTimeParts(new Date(guess), timeZone);
2208
+ const actualLocalMs = Date.UTC(actual.year, actual.month - 1, actual.day, actual.hour, actual.minute, actual.second, 0);
2209
+ const diff = actualLocalMs - targetLocalMs;
2210
+ if (diff === 0) return new Date(guess);
2211
+ const nextGuess = guess - diff;
2212
+ if (nextGuess === guess || seen.includes(nextGuess)) return new Date(Math.max(guess, nextGuess));
2213
+ return resolveLocalInstant(targetLocalMs, timeZone, nextGuess, [...seen, guess]);
2214
+ }
2215
+
2216
+ //#endregion
2217
+ //#region ../core/src/booking-date-time/window.ts
2218
+ const START_OF_DAY = {
2219
+ hour: 0,
2220
+ minute: 0,
2221
+ second: 0
2222
+ };
2223
+ function parseWindowDate(value, field) {
2224
+ try {
2225
+ return {
2226
+ ok: true,
2227
+ value: parseBookingLocalDate(value)
2228
+ };
2229
+ } catch {
2230
+ return {
2231
+ ok: false,
2232
+ field,
2233
+ reason: "invalid_date_format",
2234
+ value
2235
+ };
2039
2236
  }
2040
- const date = new Date(normalized);
2041
- if (Number.isNaN(date.getTime())) {
2042
- return err("invalid-date-time");
2237
+ }
2238
+ function parseBookingUtcDateWindow(input) {
2239
+ const timeZone = resolveBookingTimeZoneId(input.timeZone);
2240
+ const start = parseWindowDate(input.startDate, "startDate");
2241
+ if (!start.ok) return start;
2242
+ const end = parseWindowDate(input.endDate, "endDate");
2243
+ if (!end.ok) return end;
2244
+ const startLocalDate = start.value;
2245
+ const endLocalDate = end.value;
2246
+ if (compareLocalScheduleDates(startLocalDate, endLocalDate) > 0) {
2247
+ return {
2248
+ ok: false,
2249
+ field: "endDate",
2250
+ reason: "invalid_date_range",
2251
+ value: input.endDate
2252
+ };
2043
2253
  }
2044
- return ok(date.toISOString());
2254
+ return {
2255
+ ok: true,
2256
+ value: {
2257
+ timeZone,
2258
+ startLocalDate,
2259
+ endLocalDate,
2260
+ startAt: localScheduleDateTimeToUtcDate(startLocalDate, START_OF_DAY, timeZone),
2261
+ endExclusive: localScheduleDateTimeToUtcDate(addLocalScheduleDays(endLocalDate, 1), START_OF_DAY, timeZone)
2262
+ }
2263
+ };
2045
2264
  }
2046
- function toUtcIsoDateTimeString(value) {
2047
- const parsed = parseUtcIsoDateTimeString(value);
2048
- if (!parsed.ok) {
2049
- const message = parsed.error === "missing-timezone-offset" ? `Expected an offset-aware ISO datetime, received "${value}"` : `Expected a valid ISO datetime, received "${value}"`;
2050
- throw new Error(message);
2265
+ function buildBookingUtcDateWindow(input) {
2266
+ const result = parseBookingUtcDateWindow(input);
2267
+ if (result.ok) {
2268
+ return result.value;
2051
2269
  }
2052
- return parsed.value;
2270
+ if (result.reason === "invalid_date_range") {
2271
+ throw new Error(`Invalid booking date range: startDate "${input.startDate}" must be on or before endDate "${input.endDate}"`);
2272
+ }
2273
+ throw new Error(`Invalid booking date format: "${result.value}" (expected YYYY-MM-DD)`);
2053
2274
  }
2054
- function parseScheduledBookingDateTime(input) {
2055
- let startsAt;
2275
+
2276
+ //#endregion
2277
+ //#region ../core/src/booking-date-time/scheduled.ts
2278
+ function parseStrictBookingTimeZone(timeZone) {
2279
+ const parsed = parseBookingTimeZone(timeZone);
2280
+ return parsed.ok ? parsed.value : null;
2281
+ }
2282
+ function formatParseError(error) {
2283
+ switch (error.reason) {
2284
+ case "invalid_starts_at": return `Expected a valid UTC/offset-aware ISO datetime in startsAt, received "${error.value}"`;
2285
+ case "invalid_ends_at": return `Expected a valid UTC/offset-aware ISO datetime in endsAt, received "${error.value ?? ""}"`;
2286
+ case "invalid_time_zone": return `Expected a valid IANA timezone in timeZone, received "${error.value}"`;
2287
+ }
2288
+ }
2289
+ function parseScheduledStart(value) {
2056
2290
  try {
2057
- startsAt = toUtcIsoDateTimeString(input.startsAt);
2291
+ return {
2292
+ ok: true,
2293
+ value: toUtcIsoDateTimeString(value)
2294
+ };
2058
2295
  } catch {
2059
2296
  return {
2060
2297
  ok: false,
2061
2298
  field: "startsAt",
2062
2299
  reason: "invalid_starts_at",
2063
- value: input.startsAt
2300
+ value
2064
2301
  };
2065
2302
  }
2303
+ }
2304
+ function parseScheduledBookingDateTime(input) {
2305
+ const startsAt = parseScheduledStart(input.startsAt);
2306
+ if (!startsAt.ok) return startsAt;
2066
2307
  const timeZone = parseStrictBookingTimeZone(input.timeZone);
2067
2308
  if (timeZone === null) {
2068
2309
  return {
@@ -2075,7 +2316,7 @@ function parseScheduledBookingDateTime(input) {
2075
2316
  return {
2076
2317
  ok: true,
2077
2318
  value: {
2078
- startsAt,
2319
+ startsAt: startsAt.value,
2079
2320
  timeZone,
2080
2321
  locale: input.locale
2081
2322
  }
@@ -2123,6 +2364,17 @@ function toScheduledBookingDateRange(input) {
2123
2364
  }
2124
2365
  throw new Error(formatParseError(result));
2125
2366
  }
2367
+
2368
+ //#endregion
2369
+ //#region ../core/src/booking-date-time/formatting.ts
2370
+ const DEFAULT_LOCALE$1 = "en-US";
2371
+ const DEFAULT_BOOKING_DATE_TIME_FORMAT = {
2372
+ weekday: "short",
2373
+ month: "short",
2374
+ day: "numeric",
2375
+ hour: "numeric",
2376
+ minute: "2-digit"
2377
+ };
2126
2378
  function formatBookingInstant(isoString, options) {
2127
2379
  const date = new Date(isoString);
2128
2380
  if (Number.isNaN(date.getTime())) {
@@ -2214,83 +2466,6 @@ function formatBookingDateParts(input, options) {
2214
2466
  })
2215
2467
  };
2216
2468
  }
2217
- function getBookingLocalDateKey(input) {
2218
- return formatDateKey(getLocalScheduleDate(new Date(input.startsAt), input.timeZone));
2219
- }
2220
- function compareLocalScheduleDates(left, right) {
2221
- return Date.UTC(left.year, left.month - 1, left.day) - Date.UTC(right.year, right.month - 1, right.day);
2222
- }
2223
- function parseBookingLocalDate(value) {
2224
- const match = LOCAL_DATE_PATTERN.exec(value.trim());
2225
- if (match === null || match.groups === undefined) {
2226
- throw new Error(`Invalid booking date format: "${value}" (expected YYYY-MM-DD)`);
2227
- }
2228
- const year = Number(match.groups.year);
2229
- const month = Number(match.groups.month);
2230
- const day = Number(match.groups.day);
2231
- const candidate$1 = new Date(Date.UTC(year, month - 1, day, 12, 0, 0));
2232
- if (Number.isNaN(candidate$1.getTime()) || candidate$1.getUTCFullYear() !== year || candidate$1.getUTCMonth() + 1 !== month || candidate$1.getUTCDate() !== day) {
2233
- throw new Error(`Invalid booking date format: "${value}" (expected YYYY-MM-DD)`);
2234
- }
2235
- return {
2236
- year,
2237
- month,
2238
- day
2239
- };
2240
- }
2241
- function parseBookingUtcDateWindow(input) {
2242
- const timeZone = resolveBookingTimeZoneId(input.timeZone);
2243
- let startLocalDate;
2244
- try {
2245
- startLocalDate = parseBookingLocalDate(input.startDate);
2246
- } catch {
2247
- return {
2248
- ok: false,
2249
- field: "startDate",
2250
- reason: "invalid_date_format",
2251
- value: input.startDate
2252
- };
2253
- }
2254
- let endLocalDate;
2255
- try {
2256
- endLocalDate = parseBookingLocalDate(input.endDate);
2257
- } catch {
2258
- return {
2259
- ok: false,
2260
- field: "endDate",
2261
- reason: "invalid_date_format",
2262
- value: input.endDate
2263
- };
2264
- }
2265
- if (compareLocalScheduleDates(startLocalDate, endLocalDate) > 0) {
2266
- return {
2267
- ok: false,
2268
- field: "endDate",
2269
- reason: "invalid_date_range",
2270
- value: input.endDate
2271
- };
2272
- }
2273
- return {
2274
- ok: true,
2275
- value: {
2276
- timeZone,
2277
- startLocalDate,
2278
- endLocalDate,
2279
- startAt: localScheduleDateTimeToUtcDate(startLocalDate, START_OF_DAY, timeZone),
2280
- endExclusive: localScheduleDateTimeToUtcDate(addLocalScheduleDays(endLocalDate, 1), START_OF_DAY, timeZone)
2281
- }
2282
- };
2283
- }
2284
- function buildBookingUtcDateWindow(input) {
2285
- const result = parseBookingUtcDateWindow(input);
2286
- if (result.ok) {
2287
- return result.value;
2288
- }
2289
- if (result.reason === "invalid_date_range") {
2290
- throw new Error(`Invalid booking date range: startDate "${input.startDate}" must be on or before endDate "${input.endDate}"`);
2291
- }
2292
- throw new Error(`Invalid booking date format: "${result.value}" (expected YYYY-MM-DD)`);
2293
- }
2294
2469
  function formatBookingRange(input, options) {
2295
2470
  if (input.endsAt == null) {
2296
2471
  const parts = formatBookingDateParts(input, options);
@@ -2320,94 +2495,6 @@ function formatBookingRange(input, options) {
2320
2495
  });
2321
2496
  return `${startDate}, ${startTime} - ${endDate}, ${endTime}`;
2322
2497
  }
2323
- /** Canonical schedule text at command and SDK boundaries: HH:MM or HH:MM:SS. */
2324
- const localScheduleTimePattern = /^([01]\d|2[0-3]):[0-5]\d(:[0-5]\d)?$/u;
2325
- function parseLocalScheduleTime(value) {
2326
- const match = /^(?<hour>\d{1,2}):(?<minute>\d{2})(?::(?<second>\d{2}))?$/u.exec(value.trim());
2327
- if (match === null || match.groups === undefined) {
2328
- throw new Error(`Invalid start time format: "${value}" (expected HH:MM or HH:MM:SS)`);
2329
- }
2330
- const hour = Number(match.groups.hour);
2331
- const minute = Number(match.groups.minute);
2332
- const second = match.groups.second !== undefined ? Number(match.groups.second) : 0;
2333
- if (Number.isNaN(hour) || Number.isNaN(minute) || Number.isNaN(second) || hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59) {
2334
- throw new Error(`Invalid start time format: "${value}" (expected HH:MM or HH:MM:SS)`);
2335
- }
2336
- return {
2337
- hour,
2338
- minute,
2339
- second
2340
- };
2341
- }
2342
- function getLocalScheduleDate(date, timeZone) {
2343
- const parts = getZonedDateTimeParts(date, getSafeTimeZone(timeZone));
2344
- return {
2345
- year: parts.year,
2346
- month: parts.month,
2347
- day: parts.day
2348
- };
2349
- }
2350
- function getLocalScheduleTime(date, timeZone) {
2351
- const parts = getZonedDateTimeParts(date, getSafeTimeZone(timeZone));
2352
- return {
2353
- hour: parts.hour,
2354
- minute: parts.minute,
2355
- second: parts.second
2356
- };
2357
- }
2358
- function formatLocalScheduleDate(date) {
2359
- return formatDateKey(date);
2360
- }
2361
- function formatLocalScheduleTime(time) {
2362
- return `${String(time.hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}`;
2363
- }
2364
- function getDaysInLocalMonth(year, month) {
2365
- return new Date(Date.UTC(year, month, 0)).getUTCDate();
2366
- }
2367
- function addLocalScheduleDays(date, days) {
2368
- const utcDate = new Date(Date.UTC(date.year, date.month - 1, date.day + days, 12, 0, 0));
2369
- return {
2370
- year: utcDate.getUTCFullYear(),
2371
- month: utcDate.getUTCMonth() + 1,
2372
- day: utcDate.getUTCDate()
2373
- };
2374
- }
2375
- function addLocalScheduleMonths(date, months) {
2376
- const targetMonthIndex = date.month - 1 + months;
2377
- const base = new Date(Date.UTC(date.year, targetMonthIndex, 1, 12, 0, 0));
2378
- const year = base.getUTCFullYear();
2379
- const month = base.getUTCMonth() + 1;
2380
- const day = Math.min(date.day, getDaysInLocalMonth(year, month));
2381
- return {
2382
- year,
2383
- month,
2384
- day
2385
- };
2386
- }
2387
- function getLocalScheduleDayOfWeek(date) {
2388
- return new Date(Date.UTC(date.year, date.month - 1, date.day, 12, 0, 0)).getUTCDay();
2389
- }
2390
- function localScheduleDateTimeToUtcDate(localDate, localTime, timeZone) {
2391
- const resolvedTimeZone = getSafeTimeZone(timeZone);
2392
- const targetLocalMs = Date.UTC(localDate.year, localDate.month - 1, localDate.day, localTime.hour, localTime.minute, localTime.second, 0);
2393
- let guess = targetLocalMs;
2394
- const seenGuesses = new Set();
2395
- for (let iteration = 0; iteration < 4; iteration += 1) {
2396
- seenGuesses.add(guess);
2397
- const actual = getZonedDateTimeParts(new Date(guess), resolvedTimeZone);
2398
- const actualLocalMs = Date.UTC(actual.year, actual.month - 1, actual.day, actual.hour, actual.minute, actual.second, 0);
2399
- const diff = actualLocalMs - targetLocalMs;
2400
- if (diff === 0) {
2401
- return new Date(guess);
2402
- }
2403
- const nextGuess = guess - diff;
2404
- if (seenGuesses.has(nextGuess)) {
2405
- return new Date(Math.max(guess, nextGuess));
2406
- }
2407
- guess = nextGuess;
2408
- }
2409
- return new Date(guess);
2410
- }
2411
2498
 
2412
2499
  //#endregion
2413
2500
  //#region ../core/src/date-display.ts
@@ -2430,6 +2517,31 @@ function resolveBookingDisplayContext(input) {
2430
2517
  zone: input.surface !== "dashboard" && input.isOnline || input.sessionTimeZone !== input.siteTimeZone ? "always" : "omit"
2431
2518
  };
2432
2519
  }
2520
+ /** Dashboard and assistant site dates read in British English, whatever the site's own language. */
2521
+ const SITE_DISPLAY_LOCALE = "en-GB";
2522
+ /** The site display policy: `en-GB` in the given zone, falling back to the business zone the server uses. */
2523
+ function siteDisplayContext(timeZone) {
2524
+ return {
2525
+ locale: SITE_DISPLAY_LOCALE,
2526
+ timeZone: resolveBookingBusinessTimeZone(timeZone)
2527
+ };
2528
+ }
2529
+ /** A stored instant as a site date, `22 Sept 2026` by default; an unparseable value is shown as it came. */
2530
+ function formatSiteInstantDate(iso, timeZone, options = {}) {
2531
+ const parsed = parseUtcIsoDateTimeString(iso);
2532
+ return parsed.ok ? formatDate({
2533
+ kind: "instant",
2534
+ value: parsed.value
2535
+ }, siteDisplayContext(timeZone), {
2536
+ date: "short",
2537
+ ...options
2538
+ }) : iso;
2539
+ }
2540
+ /** A stored instant as a site time, `2:05pm` without a zone label by default; an unparseable value is shown as it came. */
2541
+ function formatSiteInstantTime(iso, timeZone, options = { zone: "omit" }) {
2542
+ const parsed = parseUtcIsoDateTimeString(iso);
2543
+ return parsed.ok ? formatTime(parsed.value, siteDisplayContext(timeZone), options) : iso;
2544
+ }
2433
2545
  const SDK_STANDARD_TIME_FORMAT = {
2434
2546
  hour: "numeric",
2435
2547
  minute: "2-digit"
@@ -3350,6 +3462,16 @@ const locationAddressSchema = z.strictObject({
3350
3462
  postalCode: addressPart,
3351
3463
  country: addressPart.transform((value) => value?.length === 2 ? value.toUpperCase() : value)
3352
3464
  }).readonly().transform((address) => Object.values(address).some((part) => part !== null) ? address : null);
3465
+ /** Town, then county, then a complete UK postcode's outward half. Never geocodes. */
3466
+ function deriveLocationArea(address) {
3467
+ if (address === null) return null;
3468
+ const namedArea = [address.locality, address.region].map(trimmedStringOrNull).find((part) => part !== null);
3469
+ if (namedArea !== undefined) return namedArea;
3470
+ if (address.country !== null && !sameLocationCountry(address.country, "GB")) return null;
3471
+ const postcode = address.postalCode?.trim().toUpperCase() ?? "";
3472
+ const match = /^((?:[A-PR-UWYZ][0-9][0-9A-HJKPSTUW]?|[A-PR-UWYZ][A-HK-Y][0-9][0-9ABEHMNPRVWXY]?)|GIR)\s*[0-9][ABD-HJLNP-UW-Z]{2}$/.exec(postcode);
3473
+ return match?.[1] ?? null;
3474
+ }
3353
3475
  const locationAddressMatchSchema = z.strictObject({
3354
3476
  point: locationPinSchema,
3355
3477
  precision: z.enum([
@@ -3489,6 +3611,52 @@ function resolvePermittedLocation(permission, location, siteCountry) {
3489
3611
  };
3490
3612
  }
3491
3613
 
3614
+ //#endregion
3615
+ //#region ../core/src/venue-location.ts
3616
+ /**
3617
+ * Release 1 gate: anon can still read the legacy address columns until release 2's migration,
3618
+ * so "Only people who've booked" isn't offered or accepted yet. Release 2 deletes this.
3619
+ */
3620
+ const BOOKED_ONLY_VENUE_ADDRESS_AVAILABLE = false;
3621
+ const venueLocationAudience = Symbol("venue-location-audience");
3622
+ /** Eligibility to read the venue is decided by the resource owner before disclosure. */
3623
+ function decidePublicVenueLocation(venue, siteCountry) {
3624
+ const audience = { [venueLocationAudience]: "public" };
3625
+ if (venue.location === null) return {
3626
+ ...audience,
3627
+ kind: "none",
3628
+ name: venue.name
3629
+ };
3630
+ if (venue.addressVisibility === "booked") {
3631
+ return {
3632
+ ...audience,
3633
+ kind: "area",
3634
+ name: venue.name,
3635
+ area: deriveLocationArea(venue.location.address)
3636
+ };
3637
+ }
3638
+ return {
3639
+ ...audience,
3640
+ kind: "full",
3641
+ name: venue.name,
3642
+ ...projectPublicLocation(venue.location, siteCountry)
3643
+ };
3644
+ }
3645
+ /** Caller must already hold confirmed-booking or staff authorisation. */
3646
+ function decideArrivalVenueLocation(venue, siteCountry) {
3647
+ const audience = { [venueLocationAudience]: "arrival" };
3648
+ return venue.location === null ? {
3649
+ ...audience,
3650
+ kind: "none",
3651
+ name: venue.name
3652
+ } : {
3653
+ ...audience,
3654
+ kind: "full",
3655
+ name: venue.name,
3656
+ ...projectPublicLocation(venue.location, siteCountry)
3657
+ };
3658
+ }
3659
+
3492
3660
  //#endregion
3493
3661
  //#region ../core/src/locationLinks.ts
3494
3662
  /** Both outbound actions use the arrival pin, never match evidence. */
@@ -3655,65 +3823,21 @@ function planLocationOpeningEvidence(previous, evidence) {
3655
3823
  }
3656
3824
 
3657
3825
  //#endregion
3658
- //#region ../core/src/location-migration.ts
3659
- /** Offline expand/contract conversions, not runtime fallback readers. */
3660
- const legacyText = z.string().nullable().optional();
3661
- const legacyCoordinatesSchema = z.strictObject({
3826
+ //#region ../core/src/location-conversion.ts
3827
+ /** Shared by the business address input and the offline location data migration. */
3828
+ const conversionText = z.string().nullable().optional();
3829
+ const conversionCoordinatesSchema = z.strictObject({
3662
3830
  lat: z.number().min(-90).max(90).nullable().optional(),
3663
3831
  lng: z.number().min(-180).max(180).nullable().optional()
3664
3832
  }).superRefine((value, context) => {
3665
3833
  if (value.lat == null !== (value.lng == null)) {
3666
3834
  context.addIssue({
3667
3835
  code: "custom",
3668
- message: "Legacy pin is incomplete."
3836
+ message: "The pin is incomplete."
3669
3837
  });
3670
3838
  }
3671
3839
  });
3672
- const venueAddressSchema = z.strictObject({
3673
- street: legacyText,
3674
- line1: legacyText,
3675
- line2: legacyText,
3676
- city: legacyText,
3677
- state: legacyText,
3678
- region: legacyText,
3679
- postalCode: legacyText,
3680
- postal_code: legacyText,
3681
- postcode: legacyText,
3682
- country: legacyText,
3683
- formatted: legacyText,
3684
- summary: legacyText
3685
- }).superRefine((value, context) => {
3686
- const aliases = [
3687
- [value.street, value.line1],
3688
- [value.state, value.region],
3689
- [
3690
- value.postalCode,
3691
- value.postal_code,
3692
- value.postcode
3693
- ],
3694
- [value.formatted, value.summary]
3695
- ];
3696
- aliases.forEach((parts) => {
3697
- const meaningful = parts.filter((part) => displayComparison(part) !== "");
3698
- if (meaningful.some((part) => displayComparison(part) !== displayComparison(meaningful[0]))) {
3699
- context.addIssue({
3700
- code: "custom",
3701
- message: "Legacy address aliases disagree."
3702
- });
3703
- }
3704
- });
3705
- }).nullable();
3706
- const businessAddressSchema = legacyCoordinatesSchema.safeExtend({
3707
- addressLine1: legacyText,
3708
- addressLine2: legacyText,
3709
- locality: legacyText,
3710
- region: legacyText,
3711
- postalCode: legacyText,
3712
- countryCode: legacyText,
3713
- displayAddress: legacyText
3714
- });
3715
- const customLocationSchema = legacyCoordinatesSchema.safeExtend({ addressText: legacyText });
3716
- function finishConversion(address, coordinates) {
3840
+ function finishLocationConversion(address, coordinates) {
3717
3841
  const parsedAddress = locationAddressSchema.nullable().safeParse(address);
3718
3842
  if (!parsedAddress.success) return err({
3719
3843
  kind: "invalid_legacy_location",
@@ -3735,34 +3859,6 @@ function finishConversion(address, coordinates) {
3735
3859
  issues: result.error.issues
3736
3860
  });
3737
3861
  }
3738
- function convertVenue(input) {
3739
- const address = venueAddressSchema.safeParse(input.addressJson ?? null);
3740
- const coordinates = legacyCoordinatesSchema.safeParse(input.locationJson ?? {});
3741
- if (!address.success) return err({
3742
- kind: "invalid_legacy_location",
3743
- issues: address.error.issues
3744
- });
3745
- if (!coordinates.success) return err({
3746
- kind: "invalid_legacy_location",
3747
- issues: coordinates.error.issues
3748
- });
3749
- const result = finishConversion(mapVenueAddress(address.data), coordinates.data);
3750
- return checkDisplayText(result, firstText(address.data?.formatted, address.data?.summary));
3751
- }
3752
- const displayComparison = (text) => (text ?? "").trim().replace(/\s+/g, " ").toLowerCase();
3753
- const firstText = (...parts) => parts.find((part) => part != null && part.trim().length > 0)?.trim() ?? null;
3754
- function mapVenueAddress(address) {
3755
- if (address === null) return null;
3756
- const structured = {
3757
- street: firstText(address.street, address.line1),
3758
- unit: address.line2,
3759
- locality: address.city,
3760
- region: firstText(address.state, address.region),
3761
- postalCode: firstText(address.postalCode, address.postal_code, address.postcode),
3762
- country: address.country
3763
- };
3764
- return Object.values(structured).some((part) => displayComparison(part) !== "") ? structured : { street: firstText(address.formatted, address.summary) };
3765
- }
3766
3862
  const displayTokens = (text) => (text ?? "").toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
3767
3863
  /** Only redundant trailing country text is disposable; ordered address words must all survive. */
3768
3864
  function comparableDisplay(text, countries) {
@@ -3770,7 +3866,8 @@ function comparableDisplay(text, countries) {
3770
3866
  const suffixIndex = tokens.findIndex((_token, index) => countries.some((country) => sameLocationCountry(tokens.slice(index).join(" "), country)));
3771
3867
  return (suffixIndex < 0 ? tokens : tokens.slice(0, suffixIndex)).join(" ");
3772
3868
  }
3773
- function checkDisplayText(result, text, siteCountry) {
3869
+ /** Refuses a conversion whose formatted address loses words from the stored display text. */
3870
+ function checkConvertedDisplayText(result, text, siteCountry) {
3774
3871
  if (!result.ok) return result;
3775
3872
  const original = text?.trim() ?? "";
3776
3873
  const derived = formatLocationAddress(result.value?.address ?? null);
@@ -3781,39 +3878,6 @@ function checkDisplayText(result, text, siteCountry) {
3781
3878
  derived
3782
3879
  }) : result;
3783
3880
  }
3784
- function convertBusiness(value, siteCountry) {
3785
- if (value == null) return ok(null);
3786
- const parsed = businessAddressSchema.safeParse(value);
3787
- if (!parsed.success) return err({
3788
- kind: "invalid_legacy_location",
3789
- issues: parsed.error.issues
3790
- });
3791
- const result = finishConversion({
3792
- street: parsed.data.addressLine1,
3793
- unit: parsed.data.addressLine2,
3794
- locality: parsed.data.locality,
3795
- region: parsed.data.region,
3796
- postalCode: parsed.data.postalCode,
3797
- country: parsed.data.countryCode
3798
- }, parsed.data);
3799
- return checkDisplayText(result, parsed.data.displayAddress, siteCountry);
3800
- }
3801
- function convertCustom(value) {
3802
- if (value == null) return ok(null);
3803
- const parsed = customLocationSchema.safeParse(value);
3804
- return parsed.success ? finishConversion({ street: parsed.data.addressText }, parsed.data) : err({
3805
- kind: "invalid_legacy_location",
3806
- issues: parsed.error.issues
3807
- });
3808
- }
3809
- /** Preserve pins exactly; never split free text or fabricate match evidence. */
3810
- function convertLegacyLocation(input) {
3811
- switch (input.kind) {
3812
- case "venue": return convertVenue(input);
3813
- case "business": return convertBusiness(input.value, input.siteCountry);
3814
- case "custom": return convertCustom(input.value);
3815
- }
3816
- }
3817
3881
 
3818
3882
  //#endregion
3819
3883
  //#region ../core/src/business-address.ts
@@ -3942,10 +4006,7 @@ function editBusinessPin(previous, address) {
3942
4006
  }) : err({ kind: "invalid_location" });
3943
4007
  }
3944
4008
  function convertLegacyBusinessEdit(previous, address) {
3945
- const converted = convertLegacyLocation({
3946
- kind: "business",
3947
- value: address
3948
- });
4009
+ const converted = businessAddressToLocation(address);
3949
4010
  if (!converted.ok || converted.value === null) return converted;
3950
4011
  return editLocationValue(previous, {
3951
4012
  address: converted.value.address,
@@ -3980,6 +4041,32 @@ function businessPinErrors(lat, lng) {
3980
4041
  const longitude = lng === null ? ["missing_longitude"] : !isLongitude(lng) ? ["invalid_longitude"] : [];
3981
4042
  return [...latitude, ...longitude];
3982
4043
  }
4044
+ const businessAddressSchema = conversionCoordinatesSchema.safeExtend({
4045
+ addressLine1: conversionText,
4046
+ addressLine2: conversionText,
4047
+ locality: conversionText,
4048
+ region: conversionText,
4049
+ postalCode: conversionText,
4050
+ countryCode: conversionText,
4051
+ displayAddress: conversionText
4052
+ });
4053
+ function businessAddressToLocation(value, siteCountry) {
4054
+ if (value == null) return ok(null);
4055
+ const parsed = businessAddressSchema.safeParse(value);
4056
+ if (!parsed.success) return err({
4057
+ kind: "invalid_legacy_location",
4058
+ issues: parsed.error.issues
4059
+ });
4060
+ const result = finishLocationConversion({
4061
+ street: parsed.data.addressLine1,
4062
+ unit: parsed.data.addressLine2,
4063
+ locality: parsed.data.locality,
4064
+ region: parsed.data.region,
4065
+ postalCode: parsed.data.postalCode,
4066
+ country: parsed.data.countryCode
4067
+ }, parsed.data);
4068
+ return checkConvertedDisplayText(result, parsed.data.displayAddress, siteCountry);
4069
+ }
3983
4070
 
3984
4071
  //#endregion
3985
4072
  //#region ../core/src/try-async.ts
@@ -4005,11 +4092,14 @@ const unsafeAsEditorSiteId = (value) => value;
4005
4092
  const unsafeAsEditorPageId = (value) => value;
4006
4093
  const unsafeAsEditorEntryId = (value) => value;
4007
4094
  const unsafeAsEditorBlockId = (value) => value;
4095
+ /** The document id a slot owner names: the entry's or the surface's. */
4096
+ function slotOwnerDocumentId(owner) {
4097
+ return owner.kind === "entry" ? owner.entryId : owner.surfaceId;
4098
+ }
4008
4099
  function editorBlockCollectionOwnerKey(owner) {
4009
4100
  switch (owner.kind) {
4010
4101
  case "page": return `page:${owner.pageId}`;
4011
- case "entry-slot": return `entry-slot:${owner.type}:${owner.entryId}:${owner.slotKey}`;
4012
- case "surface-slot": return `surface-slot:${owner.pageSurfaceId}:${owner.slotKey}`;
4102
+ case "slot": return owner.owner.kind === "entry" ? `entry-slot:${owner.owner.contentType}:${owner.owner.entryId}:${owner.slotKey}` : `surface-slot:${owner.owner.surfaceId}:${owner.slotKey}`;
4013
4103
  case "site-footer": return `site-footer:${owner.siteId}`;
4014
4104
  }
4015
4105
  }
@@ -5246,6 +5336,37 @@ function emptyPublicProfile() {
5246
5336
  premises: null
5247
5337
  };
5248
5338
  }
5339
+ /** Preserve omitted parts, then use the profile parser as the only validation authority. */
5340
+ function mergeOpeningHoursPatch(profile, patch) {
5341
+ const current = profile.openingHours;
5342
+ if (current === null && (patch.timeZone === undefined || patch.timeZone === "" || publicProfileWeekdays.some((day) => patch.days?.[day] === undefined))) {
5343
+ return err({
5344
+ code: "invalid_weekdays",
5345
+ path: "openingHours",
5346
+ message: "No opening hours are saved yet. Ask for all seven days (including closed days) and the time zone."
5347
+ });
5348
+ }
5349
+ const days = publicProfileWeekdays.map((weekday) => {
5350
+ const intervals = patch.days?.[weekday];
5351
+ return intervals === undefined ? current?.days.find((day) => day.weekday === weekday) : intervals.length === 0 ? {
5352
+ kind: "closed",
5353
+ weekday
5354
+ } : {
5355
+ kind: "open",
5356
+ weekday,
5357
+ intervals
5358
+ };
5359
+ });
5360
+ const hours = parseWeeklyOpeningHours({
5361
+ days,
5362
+ timeZone: patch.timeZone ?? current?.timeZone,
5363
+ note: patch.note === undefined ? current?.note : patch.note
5364
+ });
5365
+ return hours.ok ? ok({
5366
+ ...profile,
5367
+ openingHours: hours.value
5368
+ }) : hours;
5369
+ }
5249
5370
 
5250
5371
  //#endregion
5251
5372
  //#region ../core/src/opening-hours.ts
@@ -5864,30 +5985,34 @@ const centredSectionKinds = [
5864
5985
  "opening-hours",
5865
5986
  "social-links",
5866
5987
  "engagement",
5867
- "legal",
5868
- "legal-navigation"
5988
+ "legal-navigation",
5989
+ "legal"
5869
5990
  ];
5870
5991
  /** Section ownership is exhaustive for both arrangements; content never changes placement. */
5871
5992
  const rowSectionGroups = {
5872
5993
  brand: "identity",
5873
5994
  "supporting-text": "identity",
5874
- "social-links": "identity",
5995
+ "social-links": "contact",
5875
5996
  navigation: "main-navigation",
5876
5997
  "business-address": "visit",
5877
- contact: "visit",
5878
- "opening-hours": "visit",
5998
+ contact: "contact",
5999
+ "opening-hours": "hours",
5879
6000
  engagement: "engagement",
5880
6001
  "legal-navigation": "legal-ending",
5881
6002
  legal: "legal-ending"
5882
6003
  };
5883
6004
  const centredSectionGroups = {
5884
6005
  ...rowSectionGroups,
6006
+ contact: "visit",
6007
+ "opening-hours": "visit",
5885
6008
  "social-links": "social"
5886
6009
  };
5887
6010
  const rowGroupOrder = [
5888
6011
  "identity",
5889
6012
  "main-navigation",
5890
6013
  "visit",
6014
+ "hours",
6015
+ "contact",
5891
6016
  "engagement",
5892
6017
  "legal-ending"
5893
6018
  ];
@@ -5903,6 +6028,8 @@ const groupSlots = {
5903
6028
  identity: "head",
5904
6029
  "main-navigation": "navigation",
5905
6030
  visit: "contact",
6031
+ hours: "contact",
6032
+ contact: "contact",
5906
6033
  social: "social",
5907
6034
  engagement: "panel",
5908
6035
  "legal-ending": "base"
@@ -5917,20 +6044,25 @@ function footerArrangementPolicy(input) {
5917
6044
  const arrangement = input.arrangement ?? "simple";
5918
6045
  return {
5919
6046
  arrangement,
5920
- kind: arrangement === "centred" || input.legalRegion === "separate" ? "separate-legal-region" : "integrated-legal",
5921
6047
  navigationLayout: effectiveFooterNavigationLayout(arrangement, normalizeFooterNavigationLayout(input.storedNavigationLayout))
5922
6048
  };
5923
6049
  }
6050
+ /** Address and hours pair up only in row arrangements, and only when both have content. */
6051
+ function placementFor(kind, sections, policy) {
6052
+ if (kind === "engagement" || kind === "main-navigation" && policy.navigationLayout === "inline-wrap") return "full-row";
6053
+ const paired = policy.arrangement !== "centred" && (kind === "visit" || kind === "hours") && sections.some((section) => section.kind === "business-address") && sections.some((section) => section.kind === "opening-hours");
6054
+ return paired ? "paired-column" : "column";
6055
+ }
5924
6056
  function buildGroups(sections, policy) {
5925
6057
  const centred = policy.arrangement === "centred";
5926
6058
  const order = centred ? centredGroupOrder : rowGroupOrder;
5927
6059
  const owners = centred ? centredSectionGroups : rowSectionGroups;
5928
- const sectionOrder = centred ? centredSectionKinds : sectionKinds;
6060
+ const sectionOrder = centred ? centredSectionKinds : [...sectionKinds.filter((kind) => kind !== "social-links"), "social-links"];
5929
6061
  return order.flatMap((kind) => {
5930
6062
  const groupSections = sections.filter((section) => owners[section.kind] === kind).sort((left, right) => sectionOrder.indexOf(left.kind) - sectionOrder.indexOf(right.kind));
5931
6063
  return groupSections.length === 0 ? [] : [{
5932
6064
  kind,
5933
- width: kind === "main-navigation" && policy.navigationLayout === "inline-wrap" ? "full-row" : "column",
6065
+ placement: placementFor(kind, sections, policy),
5934
6066
  sections: groupSections,
5935
6067
  ...centred ? { slot: groupSlots[kind] } : {}
5936
6068
  }];
@@ -5945,7 +6077,7 @@ function footerMembershipKey(sections) {
5945
6077
  }
5946
6078
  function renderRegion(kind, groups, policy) {
5947
6079
  if (groups.length === 0) return [];
5948
- const columns = kind !== "main" || policy.arrangement === "centred" ? 1 : Math.max(1, Math.min(groups.filter((group) => group.width === "column").length, 5));
6080
+ const columns = kind !== "main" || policy.arrangement === "centred" ? 1 : Math.max(1, Math.min(groups.filter((group) => group.placement !== "full-row").length, 5));
5949
6081
  return [{
5950
6082
  kind,
5951
6083
  columns,
@@ -5958,9 +6090,9 @@ function planFooterArrangement(renderableSections, policy) {
5958
6090
  const groups = buildGroups(selectedSections, policy);
5959
6091
  const separateEngagement = groups.filter((group) => group.kind === "engagement" && group.sections.some((section) => section.kind === "engagement" && section.treatment === "separate-row"));
5960
6092
  const layoutGroups = groups.filter((group) => !separateEngagement.includes(group));
5961
- const legalGroups = policy.kind === "separate-legal-region" ? layoutGroups.filter((group) => group.kind === "legal-ending") : [];
6093
+ const legalGroups = layoutGroups.filter((group) => group.kind === "legal-ending");
5962
6094
  const unsortedMainGroups = layoutGroups.filter((group) => !legalGroups.includes(group));
5963
- const mainGroups = policy.arrangement === "centred" ? unsortedMainGroups : [...unsortedMainGroups.filter((group) => group.width === "column"), ...unsortedMainGroups.filter((group) => group.width === "full-row")];
6095
+ const mainGroups = policy.arrangement === "centred" ? unsortedMainGroups : [...unsortedMainGroups.filter((group) => group.placement !== "full-row"), ...unsortedMainGroups.filter((group) => group.placement === "full-row")];
5964
6096
  return {
5965
6097
  membershipKey: footerMembershipKey(selectedSections),
5966
6098
  regions: [
@@ -7313,6 +7445,37 @@ function parseBoundedInt(value, min, max) {
7313
7445
  if (truncated > max) return null;
7314
7446
  return truncated;
7315
7447
  }
7448
+ function clampToBounds(value, bounds) {
7449
+ const floor = bounds.min ?? Number.NEGATIVE_INFINITY;
7450
+ const ceiling = bounds.max ?? Number.POSITIVE_INFINITY;
7451
+ return Math.min(ceiling, Math.max(floor, value));
7452
+ }
7453
+ /** Decimal places in a step, so 0.5 steps don't drift into 1.4999999. */
7454
+ function stepPrecision(step) {
7455
+ const [, decimals = ""] = String(step).split(".");
7456
+ return decimals.length;
7457
+ }
7458
+ /** One press of − or +: moves by `step` and stays inside the bounds. */
7459
+ function stepNumber(value, direction, bounds = {}) {
7460
+ const step = bounds.step ?? 1;
7461
+ const next = Number((value + direction * step).toFixed(stepPrecision(step)));
7462
+ return clampToBounds(next, bounds);
7463
+ }
7464
+ /**
7465
+ * The same press for a number box that holds text. An empty or unreadable box
7466
+ * starts from the lowest allowed value (or 0), so the first + gives a real number.
7467
+ */
7468
+ function stepNumericInput(raw, direction, bounds = {}) {
7469
+ const current = typeof raw === "number" ? raw : Number.parseFloat(raw);
7470
+ if (!Number.isFinite(current)) return String(clampToBounds(bounds.min ?? 0, bounds));
7471
+ return String(stepNumber(current, direction, bounds));
7472
+ }
7473
+ /** Whether a press would change the value; a button that wouldn't is disabled. */
7474
+ function canStepNumericInput(raw, direction, bounds = {}) {
7475
+ const current = typeof raw === "number" ? raw : Number.parseFloat(raw);
7476
+ if (!Number.isFinite(current)) return true;
7477
+ return stepNumber(current, direction, bounds) !== current;
7478
+ }
7316
7479
 
7317
7480
  //#endregion
7318
7481
  //#region ../core/src/field-errors.ts
@@ -8183,6 +8346,15 @@ function resolveWholeSeriesBookingPhase(run, now) {
8183
8346
  }
8184
8347
  }
8185
8348
  }
8349
+ /** Resolve the course's two distinct dates from its surviving schedule once. */
8350
+ function resolveWholeSeriesPaymentDates(input) {
8351
+ const live = orderedLiveRunSessions(input.sessions);
8352
+ const option = input.paymentTerms.allowedOptions.find((option$1) => option$1.kind === "instalment_plan");
8353
+ return {
8354
+ bookingStartAt: live[0]?.startsAt ?? null,
8355
+ instalmentCollectionDeadlineAt: (option?.courseDeadline === "last_session" ? live[live.length - 1] : live[0])?.startsAt ?? null
8356
+ };
8357
+ }
8186
8358
 
8187
8359
  //#endregion
8188
8360
  //#region ../core/src/public-read-cache-contract.ts
@@ -10353,4 +10525,20 @@ function captureEditorValue(value, previous) {
10353
10525
  }
10354
10526
 
10355
10527
  //#endregion
10356
- export { parseLocationValue as $, unsafeAsStorageBucketName as $n, resolveExactOrFreePriceDisplay as $t, parseMailingListRuntimeContext as A, unsafeAsBookingSessionId as An, parseBookingTimeZone as At, DEFAULT_MAILING_LIST_TARGETING as B, unsafeAsMediaAssetId as Bn, omitZeroAmountFutureRows as Bt, createSecret as C, parsePageId as Cn, parseLocalScheduleTime as Ct, parseMailingListBlockId as D, parseUserId as Dn, toBookingTimeZone as Dt, slugify as E, parseSiteTermsVersionId as En, resolveBookingTimeZoneId as Et, DEFAULT_MAILING_LIST_SUCCESS_MESSAGE as F, unsafeAsEntitlementId as Fn, addIntervalPreservingMonthAnchor as Ft, parseWeeklyOpeningHours as G, unsafeAsPositiveSeconds as Gn, parseEventPageSurfaceSubject as Gt, isCanonicalRichTextDoc as H, unsafeAsOriginalFilename as Hn, resolveFlexibleBalanceDueAt as Ht, parseMailingListProviderScope as I, unsafeAsEventInstanceId as In, clampConfiguredAmount as It, decideLocationSave as J, unsafeAsSafeDownloadFilename as Jn, isPublicEventPricingOptionDisplayable as Jt, assertAllowedPublicUrl as K, unsafeAsPricingOptionId as Kn, formatBookingPriceDisplay as Kt, parseFooterCompositionV1 as L, unsafeAsEventOfferingId as Ln, getBookingInstalmentDepositRefundability as Lt, parseConfiguredMailingListProvider as M, unsafeAsDeclaredMimeType as Mn, isLiveOrderInstalmentPlanStatus as Mt, parseMailingListGlobalForm as N, unsafeAsDemoCapability as Nn, isSettleableFlexibleBalanceContractStatus as Nt, parseMailingListContentVersionId as O, unsafeAsAppointmentResourceId as On, toScheduledBookingDateTime as Ot, DEFAULT_MAILING_LIST_PRIVACY_NOTE as P, unsafeAsDetectedMimeType as Pn, isSettleableOrderInstalmentPlanStatus as Pt, normalizeLocationAddressText as Q, unsafeAsStaffMemberId as Qn, publicEventPricingType as Qt, footerNavigationLayouts as R, unsafeAsEventSeriesId as Rn, getBookingInstalmentPlanIntervalCount as Rt, resolveWholeSeriesRunLifecycle as S, parseMembershipId as Sn, parseBookingLocalDate as St, parseManagementKey as T, parseSiteId as Tn, resolveBookingBusinessTimeZone as Tt, formatOpeningHoursRows as U, unsafeAsPassId as Un, resolveFlexibleBalanceInitialPaymentCents as Ut, planMailingListChoicePresentation as V, unsafeAsOccurrenceId as Vn, splitAmountWithRemainderInFirst as Vt, parsePublicContactDetails as W, unsafeAsPositiveByteCount as Wn, deriveTotalTicketQuantity as Wt, locationMapLinks as X, unsafeAsSiteId as Xn, publicEventPricingDisplay as Xt, stableJsonStringify as Y, unsafeAsSiteFontId as Yn, publicEventPricingCurrency as Yt, locationValueSchema as Z, unsafeAsSiteScopedStoragePath as Zn, publicEventPricingOptions as Zt, publicReadFreshnessSeconds as _, parseDatedOfferingCapacityHoldAuditRef as _n, formatLocalScheduleTime as _t, NAVIGATION_LOCATIONS as a, parseNonNegativeCents as an, blockInteractionContextSchema as ar, selectCategoryView as at, orderedLiveRunSessions as b, parseEventSeriesId as bn, getLocalScheduleTime as bt, parseVerticalId as c, toNonNegativeCents as cn, formatDateTime as ct, DEFAULT_EVENT_TYPE_PRESETS as d, formatCurrencyAmount as dn, formatTimeRange as dt, resolvePricingOptionsPriceDisplay as en, unsafeAsStoragePath as er, projectPublicLocation as et, EVENT_PRESET_VALUES as f, parseCurrencyCode as fn, inferSiteDateLocale as ft, getPublicReadCachePolicy as g, parseCustomerId as gn, formatLocalScheduleDate as gt, WHOLE_SERIES_EVENT_PRESET_VALUES as h, parseApiKeyId as hn, compareLocalScheduleDates as ht, EVENT_PRESET_VOCABULARY as i, isNonNegativeWholeCents as in, ok as ir, mapDrawingSchema as it, assessMailingListTargeting as j, unsafeAsCheckoutLineId as jn, validateBookingPaymentOptionKinds as jt, parseMailingListSignedSourceToken as k, unsafeAsBookingRequirementId as kn, toUtcIsoDateTimeString as kt, parseVerticalPresetId as l, unsafeAsNonNegativeCents as ln, formatDateTimeRange as lt, SURFACE_EVENT_PRESET_VALUES as m, formatDurationUnitLabel as mn, buildBookingUtcDateWindow as mt, authoredValuesEqual as n, mapNonEmptyArray as nn, unsafeAsUserId as nr, toLocationCoordinates as nt, areConfiguredBookingVerticalConfigsEqual as o, parsePositiveCents as on, formatDate as ot, ORDINARY_EVENT_PRESET_VALUES as p, assertNever as pn, resolveBookingDisplayContext as pt, SENSITIVE_COLLECTION_MODES as q, unsafeAsProductId as qn, formatEventPricing as qt, resolveEventCatalogue as r, mapReadonlyNonEmptyArray as rn, err as rr, isPresent as rt, canonicalizeConfiguredBookingVerticalConfig as s, toCents as sn, formatDateRange as st, committedWriteProofSchema as t, fromArray as tn, unsafeAsUploadSessionId as tr, publicLocationSchema as tt, resolveSiteVerticalBookingConfig as u, unsafeAsPositiveCents as un, formatTime as ut, CANCELLED_SESSION_STATUS as v, parseDatedOfferingCapacityHoldId as vn, getBookingLocalDateKey as vt, exposeSecret as w, parseRetiredCourseId as wn, parseUtcIsoDateTimeString as wt, resolveWholeSeriesBookingPhase as x, parseMediaAssetId as xn, localScheduleTimePattern as xt, nextLiveRunSessionStartMs as y, parseEditorSessionGeneration as yn, getLocalScheduleDate as yt, parseMailingListPlacementTargeting as z, unsafeAsFileChecksumSha256 as zn, getBookingInstalmentProtectedDepositAmountCents as zt };
10528
+ //#region ../core/src/offline-payment-method.ts
10529
+ /** How money was received outside the online card checkout. */
10530
+ const OFFLINE_PAYMENT_METHODS = [
10531
+ "cash",
10532
+ "bank_transfer",
10533
+ "card_machine",
10534
+ "other"
10535
+ ];
10536
+ const OFFLINE_PAYMENT_METHOD_LABELS = {
10537
+ cash: "Cash",
10538
+ bank_transfer: "Bank transfer",
10539
+ card_machine: "Card machine",
10540
+ other: "Other"
10541
+ };
10542
+
10543
+ //#endregion
10544
+ export { locationValueSchema as $, parseEventSeriesId as $n, publicEventPricingDisplay as $t, parseMailingListContentVersionId as A, parseMediaAssetId as An, parseBookingTimeZone as At, footerNavigationLayouts as B, unsafeAsStorageBucketName as Bn, getBookingInstalmentDepositRefundability as Bt, resolveWholeSeriesBookingPhase as C, parseSiteTermsVersionId as Cn, getLocalScheduleTime as Ct, parseManagementKey as D, parseDatedOfferingCapacityHoldAuditRef as Dn, resolveBookingBusinessTimeZone as Dt, exposeSecret as E, unsafeAsPassId as En, parseLocalScheduleTime as Et, parseMailingListGlobalForm as F, unsafeAsOriginalFilename as Fn, isLiveOrderInstalmentPlanStatus as Ft, formatOpeningHoursRows as G, parseEditorSessionGeneration as Gn, resolveFlexibleBalanceDueAt as Gt, DEFAULT_MAILING_LIST_TARGETING as H, unsafeAsUploadSessionId as Hn, getBookingInstalmentProtectedDepositAmountCents as Ht, DEFAULT_MAILING_LIST_PRIVACY_NOTE as I, unsafeAsPositiveByteCount as In, isSettleableFlexibleBalanceContractStatus as It, assertAllowedPublicUrl as J, parseApiKeyId as Jn, parseEventPageSurfaceSubject as Jt, parsePublicContactDetails as K, parsePageId as Kn, resolveFlexibleBalanceInitialPaymentCents as Kt, DEFAULT_MAILING_LIST_SUCCESS_MESSAGE as L, unsafeAsPositiveSeconds as Ln, isSettleableOrderInstalmentPlanStatus as Lt, parseMailingListRuntimeContext as M, unsafeAsDetectedMimeType as Mn, toUtcIsoDateTimeString as Mt, assessMailingListTargeting as N, unsafeAsFileChecksumSha256 as Nn, BOOKING_COURSE_INSTALMENT_DEADLINES as Nt, slugify as O, parseDatedOfferingCapacityHoldId as On, resolveBookingTimeZoneId as Ot, parseConfiguredMailingListProvider as P, unsafeAsMediaAssetId as Pn, validateBookingPaymentOptionKinds as Pt, locationMapLinks as Q, unsafeAsUserId as Qn, publicEventPricingCurrency as Qt, parseMailingListProviderScope as R, unsafeAsSafeDownloadFilename as Rn, addIntervalPreservingMonthAnchor as Rt, orderedLiveRunSessions as S, parseCustomerId as Sn, getLocalScheduleDate as St, createSecret as T, unsafeAsEntitlementId as Tn, parseBookingLocalDate as Tt, planMailingListChoicePresentation as U, unsafeAsProductId as Un, omitZeroAmountFutureRows as Ut, parseMailingListPlacementTargeting as V, unsafeAsStoragePath as Vn, getBookingInstalmentPlanIntervalCount as Vt, isCanonicalRichTextDoc as W, unsafeAsCheckoutLineId as Wn, splitAmountWithRemainderInFirst as Wt, decideLocationSave as X, parseUserId as Xn, formatEventPricing as Xt, SENSITIVE_COLLECTION_MODES as Y, parseSiteId as Yn, formatBookingPriceDisplay as Yt, stableJsonStringify as Z, unsafeAsSiteId as Zn, isPublicEventPricingOptionDisplayable as Zt, WHOLE_SERIES_EVENT_PRESET_VALUES as _, formatDurationUnitLabel as _n, buildBookingUtcDateWindow as _t, resolveEventCatalogue as a, mapNonEmptyArray as an, unsafeAsPricingOptionId as ar, isPresent as at, CANCELLED_SESSION_STATUS as b, unsafeAsAppointmentResourceId as bn, formatLocalScheduleTime as bt, areConfiguredBookingVerticalConfigsEqual as c, parseNonNegativeCents as cn, blockInteractionContextSchema as cr, formatDate as ct, parseVerticalPresetId as d, toNonNegativeCents as dn, formatDateTimeRange as dt, publicEventPricingOptions as en, parseRetiredCourseId as er, normalizeLocationAddressText as et, resolveSiteVerticalBookingConfig as f, unsafeAsNonNegativeCents as fn, formatTime as ft, SURFACE_EVENT_PRESET_VALUES as g, assertNever as gn, toScheduledBookingDateTime as gt, ORDINARY_EVENT_PRESET_VALUES as h, parseCurrencyCode as hn, resolveBookingDisplayContext as ht, authoredValuesEqual as i, fromArray as in, unsafeAsOccurrenceId as ir, toLocationCoordinates as it, parseMailingListSignedSourceToken as j, unsafeAsDeclaredMimeType as jn, parseUtcIsoDateTimeString as jt, parseMailingListBlockId as k, unsafeAsBookingSessionId as kn, toBookingTimeZone as kt, canonicalizeConfiguredBookingVerticalConfig as l, parsePositiveCents as ln, formatDateRange as lt, EVENT_PRESET_VALUES as m, formatCurrencyAmount as mn, inferSiteDateLocale as mt, committedWriteProofSchema as n, resolveExactOrFreePriceDisplay as nn, unsafeAsEventOfferingId as nr, projectPublicLocation as nt, EVENT_PRESET_VOCABULARY as o, mapReadonlyNonEmptyArray as on, err as or, mapDrawingSchema as ot, DEFAULT_EVENT_TYPE_PRESETS as p, unsafeAsPositiveCents as pn, formatTimeRange as pt, parseWeeklyOpeningHours as q, unsafeAsSiteFontId as qn, deriveTotalTicketQuantity as qt, isRecord as r, resolvePricingOptionsPriceDisplay as rn, unsafeAsEventSeriesId as rr, publicLocationSchema as rt, NAVIGATION_LOCATIONS as s, isNonNegativeWholeCents as sn, ok as sr, selectCategoryView as st, OFFLINE_PAYMENT_METHODS as t, publicEventPricingType as tn, unsafeAsEventInstanceId as tr, parseLocationValue as tt, parseVerticalId as u, toCents as un, formatDateTime as ut, getPublicReadCachePolicy as v, unsafeAsBookingRequirementId as vn, compareLocalScheduleDates as vt, resolveWholeSeriesRunLifecycle as w, parseMembershipId as wn, localScheduleTimePattern as wt, nextLiveRunSessionStartMs as x, unsafeAsStaffMemberId as xn, getBookingLocalDateKey as xt, publicReadFreshnessSeconds as y, unsafeAsDemoCapability as yn, formatLocalScheduleDate as yt, parseFooterCompositionV1 as z, unsafeAsSiteScopedStoragePath as zn, clampConfiguredAmount as zt };