@riverbankcms/sdk 0.91.0 → 0.93.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.
Files changed (118) hide show
  1. package/dist/{PreviewEditorSidebar-3TT47WCF.mjs → PreviewEditorSidebar-D3PAF7NW.mjs} +3 -3
  2. package/dist/{PreviewEditorUI-ORCLLUNZ.mjs → PreviewEditorUI-G5JVJEIJ.mjs} +3 -3
  3. package/dist/SdkPreviewModeRuntime-NHTLRNQD.mjs +8 -0
  4. package/dist/_dts/api/src/bookingConfig.d.ts +13 -1
  5. package/dist/_dts/api/src/bookingOperations.d.ts +1 -0
  6. package/dist/_dts/api/src/bookingRefundOutcomes.d.ts +6 -6
  7. package/dist/_dts/api/src/common/envelope.d.ts +10 -0
  8. package/dist/_dts/api/src/customerMembershipOutcomes.d.ts +4 -4
  9. package/dist/_dts/api/src/index.d.ts +2 -2
  10. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +6 -0
  11. package/dist/_dts/api/src/request.d.ts +1 -1
  12. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +32 -0
  13. package/dist/_dts/blocks/src/system/blocks/courses/shared/pricing.d.ts +12 -1
  14. package/dist/_dts/blocks/src/system/blocks/courses/shared/schemas.d.ts +12 -0
  15. package/dist/_dts/blocks/src/system/blocks/courses/shared/types.d.ts +4 -1
  16. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +44 -0
  17. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +8 -0
  18. package/dist/_dts/blocks/src/system/runtime/api/types.d.ts +8 -1
  19. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +8 -1
  20. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.d.ts +1 -0
  21. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +4 -0
  22. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.interactive.d.ts +40 -0
  23. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.reserved-fields.d.ts +1 -1
  24. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +29 -0
  25. package/dist/_dts/blocks/src/system/runtime/nodes/booking-runtime-sources.d.ts +1 -0
  26. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/components.d.ts +6 -0
  27. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.d.ts +8 -0
  28. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +8 -0
  29. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +1 -0
  30. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +1 -1
  31. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +1 -0
  32. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +9 -0
  33. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +14 -14
  34. package/dist/_dts/content-editor/src/controller/useEntrySyncHelpers.d.ts +1 -1
  35. package/dist/_dts/content-editor/src/hooks/useEntryActions.d.ts +5 -15
  36. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +46 -0
  37. package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +43 -36
  38. package/dist/_dts/content-model/src/entry-slots/types.d.ts +110 -2
  39. package/dist/_dts/core/src/branded.d.ts +3 -0
  40. package/dist/_dts/core/src/event-pricing.d.ts +18 -1
  41. package/dist/_dts/core/src/money-input.d.ts +34 -4
  42. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +70 -0
  43. package/dist/_dts/media-core/src/fileAssetCompatibility.d.ts +1 -1
  44. package/dist/_dts/media-core/src/filePersistence.d.ts +5 -1
  45. package/dist/_dts/media-core/src/fileStorage.d.ts +1 -0
  46. package/dist/_dts/media-core/src/fileUploadFinalization.d.ts +29 -1
  47. package/dist/_dts/media-core/src/index.d.ts +1 -0
  48. package/dist/_dts/media-core/src/legacyMediaValue.d.ts +11 -0
  49. package/dist/_dts/media-core/src/videoPrep.d.ts +15 -6
  50. package/dist/_dts/media-core/src/videoSlotPolicy.d.ts +5 -5
  51. package/dist/_dts/media-react/src/hooks/useApiMediaUploader.d.ts +2 -1
  52. package/dist/_dts/sdk/src/cli/commands/push/execute/diff.d.ts +2 -0
  53. package/dist/_dts/sdk/src/cli/commands/push/execute/localMediaReporting.d.ts +23 -0
  54. package/dist/_dts/sdk/src/cli/commands/push/scopes/commandBackedDatedOfferingScope.d.ts +54 -0
  55. package/dist/_dts/sdk/src/cli/commands/push/scopes/mediaPrep.d.ts +7 -2
  56. package/dist/_dts/sdk/src/cli/commands/push/scopes/types.d.ts +6 -0
  57. package/dist/_dts/sdk/src/cli/media/local-sync.d.ts +35 -0
  58. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +23 -1
  59. package/dist/_dts/sdk/src/version.d.ts +1 -1
  60. package/dist/{chunk-GDT2QGIL.mjs → chunk-A63UXN3P.mjs} +21 -19
  61. package/dist/{chunk-U5YM4AWE.mjs → chunk-AJZGT6YG.mjs} +1 -1
  62. package/dist/{chunk-AFPMCLS7.mjs → chunk-AQ6RT6LZ.mjs} +2 -2
  63. package/dist/{chunk-ZA2S7H34.mjs → chunk-NT76QGIJ.mjs} +98 -1
  64. package/dist/{chunk-RQUZYSES.mjs → chunk-PCNCETBI.mjs} +1196 -426
  65. package/dist/{chunk-S3YHJWEU.mjs → chunk-XIK2HYI3.mjs} +7 -7
  66. package/dist/cli/index.mjs +749 -166
  67. package/dist/client/{accordion-AFX37652.mjs → accordion-RNQIPG55.mjs} +2 -2
  68. package/dist/client/{bookingForm-32V5QCOW.mjs → bookingForm-HYEEVRLP.mjs} +89 -14
  69. package/dist/client/bookings.mjs +243 -17
  70. package/dist/client/{carousel-TJGQJ7ER.mjs → carousel-W7DQ3YPU.mjs} +3 -3
  71. package/dist/client/{cart-JUU2JEW4.mjs → cart-PXJ3SXXO.mjs} +7 -7
  72. package/dist/client/{checkout-RD6BTFX4.mjs → checkout-X3JYSOXI.mjs} +7 -7
  73. package/dist/client/{chunk-MLBNVN4H.mjs → chunk-6SYGVVWA.mjs} +67 -4
  74. package/dist/client/{chunk-E6VIWZUG.mjs → chunk-DUOHLWLF.mjs} +3 -3
  75. package/dist/client/{chunk-6QZIBNGV.mjs → chunk-IXDSXF2D.mjs} +154 -16
  76. package/dist/client/{chunk-CKXEUWWA.mjs → chunk-J6TMMMXW.mjs} +3 -3
  77. package/dist/client/{chunk-PMNAV6LO.mjs → chunk-JNE6UI6U.mjs} +7 -6
  78. package/dist/client/{chunk-ISAUXU5R.mjs → chunk-OLAOAZEO.mjs} +1 -1
  79. package/dist/client/{chunk-RWYFG625.mjs → chunk-PCHACQEB.mjs} +30 -2
  80. package/dist/client/{chunk-FMZZHAIR.mjs → chunk-PICR3NTQ.mjs} +52 -5
  81. package/dist/client/{chunk-6RN62XBV.mjs → chunk-Q47XGAGS.mjs} +1 -1
  82. package/dist/client/{chunk-WHZQDPBZ.mjs → chunk-TNGL2WJF.mjs} +1 -0
  83. package/dist/client/{chunk-C4LP6BPG.mjs → chunk-WERRJXNJ.mjs} +1 -1
  84. package/dist/client/{chunk-RMOFBBNA.mjs → chunk-YYVGSYBO.mjs} +6 -6
  85. package/dist/client/client.mjs +641 -54
  86. package/dist/client/{courseRegistration-X63QAIVV.mjs → courseRegistration-QZ67PVHO.mjs} +111 -11
  87. package/dist/client/{eventCalendar-5T24GCZL.mjs → eventCalendar-V3BDHQNT.mjs} +9 -9
  88. package/dist/client/{eventCombined-AZVTF22X.mjs → eventCombined-XYFRN2RG.mjs} +9 -9
  89. package/dist/client/{eventDetails-7GPFNLGF.mjs → eventDetails-TFE5TWKV.mjs} +9 -9
  90. package/dist/client/{eventListing-QEUMTMUM.mjs → eventListing-IQ6AGWZ6.mjs} +9 -9
  91. package/dist/client/{eventRegistration-P2EDKCQZ.mjs → eventRegistration-WGJVFKQJ.mjs} +9 -9
  92. package/dist/client/{form-NUJ7H4IN.mjs → form-6UZY6RUA.mjs} +3 -3
  93. package/dist/client/{headerSection-JB7LECPL.mjs → headerSection-RSFXY6V3.mjs} +3 -3
  94. package/dist/client/hooks.mjs +57 -5
  95. package/dist/client/{locationMap-UEYWUCSW.mjs → locationMap-24FH67I4.mjs} +3 -3
  96. package/dist/client/{newsletterForm-S2YZQ2X7.mjs → newsletterForm-QVL3MLTN.mjs} +3 -3
  97. package/dist/client/{productDetail-H5MADGG7.mjs → productDetail-ZDYN3G4T.mjs} +7 -7
  98. package/dist/client/{productList-DK7YON7H.mjs → productList-4BMJLQHZ.mjs} +7 -7
  99. package/dist/client/rendering/client.mjs +503 -36
  100. package/dist/client/rendering/islands.mjs +19 -19
  101. package/dist/client/rendering.mjs +583 -39
  102. package/dist/client/{shop-6PA7RDRJ.mjs → shop-U5C634FF.mjs} +7 -7
  103. package/dist/preview-next/client/runtime.mjs +5 -5
  104. package/dist/{sdk-runtime-JP5347OB.mjs → sdk-runtime-VGV46WVB.mjs} +6 -6
  105. package/dist/server/components.mjs +287 -68
  106. package/dist/server/config-validation.mjs +58 -5
  107. package/dist/server/config.mjs +58 -5
  108. package/dist/server/data.mjs +57 -5
  109. package/dist/server/index.mjs +104 -29
  110. package/dist/server/next.mjs +347 -85
  111. package/dist/server/page-converter.mjs +22 -5
  112. package/dist/server/prebuild.mjs +1 -1
  113. package/dist/server/rendering/server.mjs +287 -68
  114. package/dist/server/rendering.mjs +287 -68
  115. package/dist/server/routing.mjs +131 -67
  116. package/dist/server/server.mjs +189 -94
  117. package/package.json +1 -1
  118. package/dist/SdkPreviewModeRuntime-GMCDQPZZ.mjs +0 -8
@@ -1,4 +1,4 @@
1
- import { parseAspectRatioValue, parseColorTokenParts, toBookingTimeZone, formatBookingDate, toScheduledBookingDateTime, formatBookingTime, toScheduledBookingDateRange, formatBookingDateParts, formatEventPricing, ImagePresets, getBookingLocalDateKey, publicEventPricingType, formatCurrencyAmount, getCurrentResolveImageUrlContext, renderVideo, renderAudio, resolveMediaNodeResponsiveImage, MediaPlaceholder, computeMediaTransformStyle, rgbColorValue } from './chunk-RWYFG625.mjs';
1
+ import { parseAspectRatioValue, parseColorTokenParts, toBookingTimeZone, formatBookingDate, toScheduledBookingDateTime, formatBookingTime, toScheduledBookingDateRange, formatBookingDateParts, formatEventPricing, ImagePresets, getBookingLocalDateKey, publicEventPricingType, formatCurrencyAmount, getCurrentResolveImageUrlContext, renderVideo, renderAudio, resolveMediaNodeResponsiveImage, MediaPlaceholder, computeMediaTransformStyle, rgbColorValue } from './chunk-PCHACQEB.mjs';
2
2
  import z2, { z } from 'zod';
3
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
4
 
@@ -323,9 +323,12 @@ var coursePricingOptionSchema = z.object({
323
323
  });
324
324
  var coursePricingSchema = z.object({
325
325
  bookingRequirement: z.enum(["none", "required"]),
326
- pricingStrategy: z.enum(["free", "single", "tiered"]),
326
+ pricingStrategy: z.enum(["free", "single", "tiered", "sliding_scale"]),
327
327
  currency: z.string(),
328
328
  singlePriceAmount: z.number().nullable(),
329
+ slidingMinAmount: z.number().nullable().optional(),
330
+ slidingMaxAmount: z.number().nullable().optional(),
331
+ slidingSuggestedAmount: z.number().nullable().optional(),
329
332
  paymentTerms: blockBookingPaymentTermsSchema,
330
333
  options: z.array(coursePricingOptionSchema)
331
334
  });
@@ -479,6 +482,19 @@ var publicEventPricingSchema = z.discriminatedUnion("kind", [
479
482
  ticketTypes: z.array(publicEventTicketTypeSchema),
480
483
  display: publicEventTicketTypePriceDisplaySchema
481
484
  }),
485
+ z.object({
486
+ kind: z.literal("sliding_scale"),
487
+ minAmount: z.number(),
488
+ maxAmount: z.number(),
489
+ suggestedAmount: z.number().nullable(),
490
+ currency: z.string(),
491
+ display: z.object({
492
+ kind: z.literal("range"),
493
+ minAmount: z.number(),
494
+ maxAmount: z.number(),
495
+ currency: z.string()
496
+ })
497
+ }),
482
498
  z.object({
483
499
  kind: z.literal("course"),
484
500
  display: z.object({ kind: z.literal("course"), display: publicCoursePriceDisplaySchema })
@@ -4301,6 +4317,7 @@ var BOOKING_FORM_DATA_RESERVED_KEY_VALUES = [
4301
4317
  "selectedDate",
4302
4318
  "selectedSlot",
4303
4319
  "discountCode",
4320
+ "selectedSlidingAmountInput",
4304
4321
  "selectedCollectionOptionKind",
4305
4322
  "selectedAppointmentPackageId"
4306
4323
  ];
@@ -4584,6 +4601,32 @@ function readOptionalString(value) {
4584
4601
  function readOptionalNumber(value) {
4585
4602
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
4586
4603
  }
4604
+ function getBookingServiceSlidingScale(service) {
4605
+ const pricing = service?.pricing;
4606
+ if (!pricing || pricing.pricingStrategy !== "sliding_scale" || pricing.slidingMinAmount === null || pricing.slidingMinAmount === void 0 || pricing.slidingMaxAmount === null || pricing.slidingMaxAmount === void 0) {
4607
+ return null;
4608
+ }
4609
+ return {
4610
+ minAmount: pricing.slidingMinAmount,
4611
+ maxAmount: pricing.slidingMaxAmount,
4612
+ suggestedAmount: pricing.slidingSuggestedAmount ?? null,
4613
+ currency: pricing.currency
4614
+ };
4615
+ }
4616
+ function parseBookingCurrencyInputToCents(value) {
4617
+ const trimmed = value?.trim() ?? "";
4618
+ if (!trimmed) return null;
4619
+ if (!/^(?:\d+(?:\.\d{0,2})?|\.\d{1,2})$/.test(trimmed)) return null;
4620
+ const parsed = Number(trimmed);
4621
+ if (!Number.isFinite(parsed) || parsed < 0) return null;
4622
+ return Math.round(parsed * 100);
4623
+ }
4624
+ function formatBookingCentsAsCurrencyInput(amount) {
4625
+ return amount % 100 === 0 ? String(amount / 100) : (amount / 100).toFixed(2);
4626
+ }
4627
+ function isBookingServiceSlidingAmountInRange(slidingScale, selectedAmount) {
4628
+ return selectedAmount !== null && selectedAmount >= slidingScale.minAmount && selectedAmount <= slidingScale.maxAmount;
4629
+ }
4587
4630
  function readStringArray(value) {
4588
4631
  if (!Array.isArray(value)) return void 0;
4589
4632
  const strings = value.filter((item) => typeof item === "string");
@@ -4772,6 +4815,20 @@ function prepareBookingSubmission(input) {
4772
4815
  };
4773
4816
  }
4774
4817
  const paymentSelectionMode = getBookingServicePaymentSelectionMode(selectedService);
4818
+ const slidingScale = getBookingServiceSlidingScale(selectedService);
4819
+ const selectedSlidingAmount = parseBookingCurrencyInputToCents(
4820
+ input.data.selectedSlidingAmountInput
4821
+ );
4822
+ if (slidingScale && !isBookingServiceSlidingAmountInRange(slidingScale, selectedSlidingAmount)) {
4823
+ return {
4824
+ ok: false,
4825
+ error: {
4826
+ tag: selectedSlidingAmount === null ? "sliding-amount-required" : "sliding-amount-out-of-range",
4827
+ serviceId,
4828
+ serviceTitle: selectedService.title || serviceId
4829
+ }
4830
+ };
4831
+ }
4775
4832
  if (paymentSelectionMode === "choice_required" && !toSelectedCollectionOptionKind(input.data.selectedCollectionOptionKind)) {
4776
4833
  return {
4777
4834
  ok: false,
@@ -4799,6 +4856,7 @@ function prepareBookingSubmission(input) {
4799
4856
  ...common,
4800
4857
  kind: "standard",
4801
4858
  ...discountCode ? { discountCode } : {},
4859
+ ...slidingScale && selectedSlidingAmount !== null ? { selectedSlidingAmount } : {},
4802
4860
  ...selectedCollectionOptionKind ? { selectedCollectionOptionKind } : {},
4803
4861
  altchaSolution: input.altchaSolution ?? null
4804
4862
  }
@@ -4812,6 +4870,10 @@ function formatBookingSubmissionPreparationError(error) {
4812
4870
  return `Service not found: ${error.serviceId}`;
4813
4871
  case "payment-option-required":
4814
4872
  return `Please choose how you want to pay for "${error.serviceTitle}".`;
4873
+ case "sliding-amount-required":
4874
+ return `Please choose an amount for "${error.serviceTitle}".`;
4875
+ case "sliding-amount-out-of-range":
4876
+ return `Please choose an amount within the sliding scale for "${error.serviceTitle}".`;
4815
4877
  case "payment-option-unsupported":
4816
4878
  return `Service "${error.serviceTitle}" has a payment option that is not supported yet.`;
4817
4879
  case "service-missing-duration":
@@ -4908,6 +4970,7 @@ var bookingServiceSchema = z.object({
4908
4970
  title: z.string(),
4909
4971
  description: z.string().nullable().optional().transform((value) => value ?? void 0),
4910
4972
  durationMinutes: z.number().optional(),
4973
+ pricing: z.custom().optional(),
4911
4974
  priceAmount: z.number().nullable().optional(),
4912
4975
  priceCurrency: z.string().nullable().optional(),
4913
4976
  paymentTerms: blockBookingPaymentTermsSchema.optional(),
@@ -5791,7 +5854,7 @@ function isRecord4(value) {
5791
5854
  }
5792
5855
  function isPublicEventPricing(value) {
5793
5856
  if (!isRecord4(value) || typeof value.kind !== "string") return false;
5794
- return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "ticket_types" || value.kind === "course" || value.kind === "external";
5857
+ return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "sliding_scale" || value.kind === "ticket_types" || value.kind === "course" || value.kind === "external";
5795
5858
  }
5796
5859
  function isPublicEventTicketType(value) {
5797
5860
  return isRecord4(value) && typeof value.id === "string";
@@ -8973,4 +9036,4 @@ function defineIslandPropsDecoder(kind) {
8973
9036
  };
8974
9037
  }
8975
9038
 
8976
- export { BOOKING_FORM_DATA_RESERVED_KEYS, DateTimeTile, EMPTY_COMMERCE_CART_STATE, EmptyState, EventCard, EventCompactRow, MAX_EVENTS_PER_DAY, MONTH_NAMES, WIZARD_STEPS, addMonths, assertNever, buildCalendarViewport, buildCartDisplay, buildEventCalendarListingRender, buildEventRuntimeFilters, buildPassCartItem, buildProductCardDisplay, buildProductCartItem, buildProductDetailDisplay, buildTimetableModel, clearWorkflowFeedback, createRichTextDocFromMarkdown, defineIslandPropsDecoder, deriveBookingFormViewState, deriveCommerceCheckoutState, err, findEventByOccurrenceId, findPreSelectedEvent, formatBookingSubmissionPreparationError, formatCommercePrice, formatDate, formatDateKey, formatEventDateParts, formatEventPrice, formatEventPriceDisplay, formatEventTeacherLine, formatInterval, formatTime, getBookingRedirectStateFromLocation, getBookingSuccessMessage, getCardOrientation, getContainerClass, getEventAvailability, getEventRuntimeFiltersKey, getOrderedDayNames, getShopDisplayForItems, getStepNumber, getThreeMonthRange, getWizardStepsForContext, groupEventsByDate, isEventContentType, isRecord, isToday, logger, normalizeCsvIds, normalizeCsvString, normalizeEventBlockKind, normalizeOptionalId, ok, okWith, parseStoredCommerceCartState, prepareBookingSubmission, productItemKey, reduceCommerceCart, reportWorkflowError, reportWorkflowSuccess, resolveAppointmentCheckoutVerificationState, resolveBookingPaymentStep, resolveBookingSiteId, resolveDefaultBookingServiceId, resolveDiscountContext, resolveEventLinkProps, resolveEventRequiresPayment, resolveRegistrationTarget, resolveRuntimeEventPricing, shiftCalendarAnchorDate, themeButtonClassName, toRegistrationEvents, toSelectedCollectionOptionKind, unwrapRichTextRoot };
9039
+ export { BOOKING_FORM_DATA_RESERVED_KEYS, DateTimeTile, EMPTY_COMMERCE_CART_STATE, EmptyState, EventCard, EventCompactRow, MAX_EVENTS_PER_DAY, MONTH_NAMES, WIZARD_STEPS, addMonths, assertNever, buildCalendarViewport, buildCartDisplay, buildEventCalendarListingRender, buildEventRuntimeFilters, buildPassCartItem, buildProductCardDisplay, buildProductCartItem, buildProductDetailDisplay, buildTimetableModel, clearWorkflowFeedback, createRichTextDocFromMarkdown, defineIslandPropsDecoder, deriveBookingFormViewState, deriveCommerceCheckoutState, err, findEventByOccurrenceId, findPreSelectedEvent, formatBookingCentsAsCurrencyInput, formatBookingSubmissionPreparationError, formatCommercePrice, formatDate, formatDateKey, formatEventDateParts, formatEventPrice, formatEventPriceDisplay, formatEventTeacherLine, formatInterval, formatTime, getBookingRedirectStateFromLocation, getBookingServiceSlidingScale, getBookingSuccessMessage, getCardOrientation, getContainerClass, getEventAvailability, getEventRuntimeFiltersKey, getOrderedDayNames, getShopDisplayForItems, getStepNumber, getThreeMonthRange, getWizardStepsForContext, groupEventsByDate, isBookingServiceSlidingAmountInRange, isEventContentType, isRecord, isToday, logger, normalizeCsvIds, normalizeCsvString, normalizeEventBlockKind, normalizeOptionalId, ok, okWith, parseBookingCurrencyInputToCents, parseStoredCommerceCartState, prepareBookingSubmission, productItemKey, reduceCommerceCart, reportWorkflowError, reportWorkflowSuccess, resolveAppointmentCheckoutVerificationState, resolveBookingPaymentStep, resolveBookingSiteId, resolveDefaultBookingServiceId, resolveDiscountContext, resolveEventLinkProps, resolveEventRequiresPayment, resolveRegistrationTarget, resolveRuntimeEventPricing, shiftCalendarAnchorDate, themeButtonClassName, toRegistrationEvents, toSelectedCollectionOptionKind, unwrapRichTextRoot };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { formatPrice } from './chunk-CKXEUWWA.mjs';
3
- import { assertNever } from './chunk-MLBNVN4H.mjs';
4
- import { resolveFlexibleBalanceInitialPaymentCents, resolveFlexibleBalanceDueAt, getBookingInstalmentDepositRefundability, splitAmountWithRemainderInFirst, addIntervalPreservingMonthAnchor, clampConfiguredAmount, getBookingInstalmentPlanIntervalCount, omitZeroAmountFutureRows } from './chunk-RWYFG625.mjs';
2
+ import { formatPrice } from './chunk-J6TMMMXW.mjs';
3
+ import { assertNever } from './chunk-6SYGVVWA.mjs';
4
+ import { resolveFlexibleBalanceInitialPaymentCents, resolveFlexibleBalanceDueAt, getBookingInstalmentDepositRefundability, splitAmountWithRemainderInFirst, addIntervalPreservingMonthAnchor, clampConfiguredAmount, getBookingInstalmentPlanIntervalCount, omitZeroAmountFutureRows } from './chunk-PCHACQEB.mjs';
5
5
  import { useReducer, useRef, useCallback, useEffect } from 'react';
6
6
 
7
7
  // ../blocks/src/system/runtime/shared/bookingPaymentOptionCopy.ts
@@ -1,16 +1,16 @@
1
1
  "use client";
2
- import { LeafletStaticMap } from './chunk-C4LP6BPG.mjs';
3
- import { resolveCoursePricingState, useWaitlistClaim, MagicLinkForm, formatCoursePriceAmount, formatCoursePriceDisplay } from './chunk-FMZZHAIR.mjs';
2
+ import { LeafletStaticMap } from './chunk-WERRJXNJ.mjs';
3
+ import { resolveCoursePricingState, useWaitlistClaim, MagicLinkForm, formatCoursePriceAmount, formatCoursePriceDisplay } from './chunk-PICR3NTQ.mjs';
4
4
  import { CreditCard, Ticket, Star, Sparkles } from './chunk-6N7YRNYU.mjs';
5
- import { usePolling, buildBookingPaymentSelectionViewModel } from './chunk-E6VIWZUG.mjs';
6
- import { SpinnerNode } from './chunk-ISAUXU5R.mjs';
7
- import { createBodyThemePortalRoot, TabBarFragment, useDiscountCodeUi, logoutPortal, consumeSearchParam, StepIndicator, DiscountCodeDisclosure, TerminalPanel, StateIcon, formatPrice, CrossIcon, ClockIcon, LoggedInAsUser, CheckIcon } from './chunk-CKXEUWWA.mjs';
5
+ import { usePolling, buildBookingPaymentSelectionViewModel } from './chunk-DUOHLWLF.mjs';
6
+ import { SpinnerNode } from './chunk-OLAOAZEO.mjs';
7
+ import { createBodyThemePortalRoot, TabBarFragment, useDiscountCodeUi, logoutPortal, consumeSearchParam, StepIndicator, DiscountCodeDisclosure, TerminalPanel, StateIcon, formatPrice, CrossIcon, ClockIcon, LoggedInAsUser, CheckIcon } from './chunk-J6TMMMXW.mjs';
8
8
  import { getFieldValidationControlProps, FieldValidationMessage } from './chunk-3DCJ45Z2.mjs';
9
9
  import { ModalShell } from './chunk-WBQG7VJA.mjs';
10
10
  import { isSpamProtectionEnabled, AltchaWidget, getChallengeUrl } from './chunk-LJCX6V7Q.mjs';
11
- import { useBlockApi, FeedbackMessage } from './chunk-WHZQDPBZ.mjs';
12
- import { buildEventRuntimeFilters, buildEventCalendarListingRender, groupEventsByDate, getOrderedDayNames, formatDateKey, getEventRuntimeFiltersKey, themeButtonClassName, normalizeCsvIds, normalizeOptionalId, normalizeEventBlockKind, normalizeCsvString, EventCompactRow, EmptyState, getContainerClass, getCardOrientation, isToday, MAX_EVENTS_PER_DAY, formatTime, WIZARD_STEPS, getWizardStepsForContext, getStepNumber, formatEventPriceDisplay, resolveRuntimeEventPricing, formatEventPrice, formatEventDateParts, resolveEventLinkProps, DateTimeTile, assertNever, EventCard, buildCalendarViewport, shiftCalendarAnchorDate, addMonths, getThreeMonthRange, buildTimetableModel, formatDate, MONTH_NAMES, getEventAvailability, formatEventTeacherLine, toRegistrationEvents, isEventContentType, findPreSelectedEvent, resolveRegistrationTarget, findEventByOccurrenceId, resolveEventRequiresPayment, resolveDiscountContext } from './chunk-MLBNVN4H.mjs';
13
- import { publicEventPricingType, getBookingLocalDateKey, toScheduledBookingDateTime, toBookingTimeZone, publicEventPricingCurrency, formatBookingDateTime, publicEventPricingMode, publicEventScalarPrice, publicEventTicketTypes, formatCurrencyAmount, formatBookingDate, formatBookingTime } from './chunk-RWYFG625.mjs';
11
+ import { useBlockApi, FeedbackMessage } from './chunk-TNGL2WJF.mjs';
12
+ import { buildEventRuntimeFilters, buildEventCalendarListingRender, groupEventsByDate, getOrderedDayNames, formatDateKey, getEventRuntimeFiltersKey, themeButtonClassName, normalizeCsvIds, normalizeOptionalId, normalizeEventBlockKind, normalizeCsvString, EventCompactRow, EmptyState, getContainerClass, getCardOrientation, isToday, MAX_EVENTS_PER_DAY, formatTime, WIZARD_STEPS, getWizardStepsForContext, getStepNumber, formatEventPriceDisplay, resolveRuntimeEventPricing, formatEventPrice, formatEventDateParts, resolveEventLinkProps, DateTimeTile, assertNever, EventCard, buildCalendarViewport, shiftCalendarAnchorDate, addMonths, getThreeMonthRange, buildTimetableModel, formatDate, MONTH_NAMES, getEventAvailability, formatEventTeacherLine, toRegistrationEvents, isEventContentType, findPreSelectedEvent, resolveRegistrationTarget, findEventByOccurrenceId, resolveEventRequiresPayment, resolveDiscountContext } from './chunk-6SYGVVWA.mjs';
13
+ import { publicEventPricingType, getBookingLocalDateKey, toScheduledBookingDateTime, toBookingTimeZone, publicEventPricingCurrency, formatBookingDateTime, publicEventPricingMode, publicEventScalarPrice, publicEventTicketTypes, formatCurrencyAmount, formatBookingDate, formatBookingTime } from './chunk-PCHACQEB.mjs';
14
14
  import React9, { createContext, useId, useMemo, useReducer, useState, useRef, useEffect, useCallback, useContext } from 'react';
15
15
  import { createPortal } from 'react-dom';
16
16
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -525,6 +525,7 @@ function useEligibility(params) {
525
525
  occurrenceId: params.occurrenceId,
526
526
  attendanceMode: params.attendanceMode ?? void 0,
527
527
  ticketTypeId: params.ticketTypeId ?? void 0,
528
+ selectedSlidingAmount: params.selectedSlidingAmount ?? void 0,
528
529
  email: params.email.trim().toLowerCase(),
529
530
  ticketsCount: params.ticketsCount
530
531
  });
@@ -545,7 +546,7 @@ function useEligibility(params) {
545
546
  return () => {
546
547
  cancelled = true;
547
548
  };
548
- }, [api, params.enabled, params.occurrenceId, params.attendanceMode, params.ticketTypeId, params.email, params.ticketsCount]);
549
+ }, [api, params.enabled, params.occurrenceId, params.attendanceMode, params.ticketTypeId, params.selectedSlidingAmount, params.email, params.ticketsCount]);
549
550
  return {
550
551
  state,
551
552
  eligibility: state.eligibility,
@@ -868,6 +869,41 @@ function TicketCounterLimit(props) {
868
869
  ] }) : null
869
870
  ] });
870
871
  }
872
+ function formatCurrencyInputAmount(amount) {
873
+ const major = amount / 100;
874
+ return Number.isInteger(major) ? String(major) : major.toFixed(2);
875
+ }
876
+ function SlidingScaleAmountField(props) {
877
+ const minLabel = formatPrice(props.slidingScale.minAmount, props.currency);
878
+ const maxLabel = formatPrice(props.slidingScale.maxAmount, props.currency);
879
+ const suggestedLabel = props.slidingScale.suggestedAmount !== null ? formatPrice(props.slidingScale.suggestedAmount, props.currency) : null;
880
+ return /* @__PURE__ */ jsxs("div", { className: "er-field", children: [
881
+ /* @__PURE__ */ jsx("label", { htmlFor: "er-sliding-amount", className: "er-label", children: "Amount" }),
882
+ /* @__PURE__ */ jsx(
883
+ "input",
884
+ {
885
+ id: "er-sliding-amount",
886
+ type: "number",
887
+ min: formatCurrencyInputAmount(props.slidingScale.minAmount),
888
+ max: formatCurrencyInputAmount(props.slidingScale.maxAmount),
889
+ step: "0.01",
890
+ inputMode: "decimal",
891
+ className: "er-input",
892
+ value: props.value,
893
+ onChange: (event) => props.onChange?.(event.target.value)
894
+ }
895
+ ),
896
+ /* @__PURE__ */ jsxs("p", { className: "er-text er-text--muted", children: [
897
+ "Choose between ",
898
+ minLabel,
899
+ " and ",
900
+ maxLabel,
901
+ suggestedLabel ? `; suggested ${suggestedLabel}` : "",
902
+ "."
903
+ ] }),
904
+ props.message ? /* @__PURE__ */ jsx("p", { className: "er-text er-text--muted", children: props.message }) : null
905
+ ] });
906
+ }
871
907
  function getTicketTypeCounterAvailabilityLabel(input) {
872
908
  if (input.selectedRemainingCapacity !== null) {
873
909
  return `${input.selectedRemainingCapacity} remaining for this ticket type`;
@@ -931,6 +967,10 @@ var TicketSelectionStep = ({
931
967
  maxTickets,
932
968
  selectedTicketTypeId = null,
933
969
  onTicketTypeChange,
970
+ slidingScale = null,
971
+ selectedSlidingAmountInput = "",
972
+ slidingScaleSelectionMessage = null,
973
+ onSlidingAmountChange,
934
974
  onTicketsChange
935
975
  }) => {
936
976
  const deliveryMode = event?.deliveryMode ?? "in_person";
@@ -1046,6 +1086,16 @@ var TicketSelectionStep = ({
1046
1086
  ] })
1047
1087
  ] })
1048
1088
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1089
+ slidingScale ? /* @__PURE__ */ jsx(
1090
+ SlidingScaleAmountField,
1091
+ {
1092
+ slidingScale,
1093
+ currency: eventPricingCurrency ?? DEFAULT_EVENT_CURRENCY,
1094
+ value: selectedSlidingAmountInput,
1095
+ message: slidingScaleSelectionMessage,
1096
+ onChange: onSlidingAmountChange
1097
+ }
1098
+ ) : null,
1049
1099
  /* @__PURE__ */ jsx("h3", { className: "er-title", children: canJoinWaitlist ? "How many waitlist spots?" : "How many tickets?" }),
1050
1100
  /* @__PURE__ */ jsxs("div", { className: "er-ticket-counter-group", children: [
1051
1101
  /* @__PURE__ */ jsx(
@@ -1898,6 +1948,10 @@ function EventRegistrationWizardContent(props) {
1898
1948
  maxTickets: wizard.maxTicketsNum,
1899
1949
  selectedTicketTypeId: wizard.selectedTicketTypeId,
1900
1950
  onTicketTypeChange: wizard.setSelectedTicketTypeId,
1951
+ slidingScale: wizard.selectedEventSlidingScale,
1952
+ selectedSlidingAmountInput: wizard.selectedSlidingAmountInput,
1953
+ slidingScaleSelectionMessage: wizard.slidingScaleSelectionMessage,
1954
+ onSlidingAmountChange: wizard.setSelectedSlidingAmountInput,
1901
1955
  onTicketsChange: wizard.setTicketsCount
1902
1956
  }
1903
1957
  )
@@ -2091,7 +2145,7 @@ function EventRegistrationSummaryBar(props) {
2091
2145
  const summaryTimeZone = wizard.occurrenceContext?.timeZone ?? summaryEvent?.timeZone ?? null;
2092
2146
  const occurrenceOverrideTitle = wizard.occurrenceContext?.overrides?.title;
2093
2147
  const summaryTitle = occurrenceOverrideTitle ?? summaryEvent?.title ?? "";
2094
- const summaryPrice = wizard.selectedTicketType?.priceAmount ?? wizard.eligibility?.price ?? (summaryEvent ? publicEventScalarPrice(summaryEvent.pricing) : null) ?? 0;
2148
+ const summaryPrice = wizard.selectedTicketType?.priceAmount ?? wizard.eligibility?.price ?? (wizard.selectedEventSlidingScale ? wizard.selectedSlidingAmount : null) ?? (summaryEvent ? publicEventScalarPrice(summaryEvent.pricing) : null) ?? 0;
2095
2149
  const summaryCurrency = (summaryEvent ? publicEventPricingCurrency(summaryEvent.pricing) : null) ?? DEFAULT_EVENT_CURRENCY;
2096
2150
  const teamMemberNames = (summaryEvent?.teamMembers ?? []).map((teamMember) => teamMember.name).filter(Boolean);
2097
2151
  const subtotalCents = Math.max(0, summaryPrice * wizard.ticketsCount);
@@ -2347,6 +2401,7 @@ function useEventRegistrationSubmit(options) {
2347
2401
  occurrenceId: submitOccurrenceId,
2348
2402
  attendanceMode: options.selectedAttendanceMode ?? void 0,
2349
2403
  ticketTypeId: options.selectedTicketTypeId ?? void 0,
2404
+ selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
2350
2405
  email: options.formData.email.trim().toLowerCase(),
2351
2406
  name: options.formData.name.trim(),
2352
2407
  ticketsCount: options.ticketsCount,
@@ -2448,6 +2503,35 @@ function useEventRegistrationSubmit(options) {
2448
2503
  }
2449
2504
 
2450
2505
  // ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
2506
+ function parseCurrencyInputToCents(value) {
2507
+ const trimmed = value.trim();
2508
+ if (!trimmed) return null;
2509
+ const amount = Number(trimmed);
2510
+ if (!Number.isFinite(amount) || amount < 0) return null;
2511
+ return Math.round(amount * 100);
2512
+ }
2513
+ function formatCentsAsCurrencyInput(amount) {
2514
+ const major = amount / 100;
2515
+ return Number.isInteger(major) ? String(major) : major.toFixed(2);
2516
+ }
2517
+ function getSlidingScaleForEvent(event) {
2518
+ const pricing = event ? resolveRuntimeEventPricing(event) : null;
2519
+ return pricing?.kind === "sliding_scale" ? {
2520
+ minAmount: pricing.minAmount,
2521
+ maxAmount: pricing.maxAmount,
2522
+ suggestedAmount: pricing.suggestedAmount
2523
+ } : null;
2524
+ }
2525
+ function getSlidingScaleSelectionMessage(input) {
2526
+ if (!input.slidingScale) return null;
2527
+ if (input.selectedAmount === null) {
2528
+ return "Choose an amount to continue.";
2529
+ }
2530
+ if (input.selectedAmount < input.slidingScale.minAmount || input.selectedAmount > input.slidingScale.maxAmount) {
2531
+ return "Choose an amount within the sliding scale.";
2532
+ }
2533
+ return null;
2534
+ }
2451
2535
  function useEventRegistrationWizard(options) {
2452
2536
  const api = useBlockApi();
2453
2537
  const registrationEvents = useMemo(
@@ -2492,6 +2576,10 @@ function useEventRegistrationWizard(options) {
2492
2576
  preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null
2493
2577
  );
2494
2578
  const [selectedTicketTypeId, setSelectedTicketTypeId] = useState(null);
2579
+ const [selectedSlidingAmountInput, setSelectedSlidingAmountInput] = useState(() => {
2580
+ const slidingScale = getSlidingScaleForEvent(preSelectedEvent ?? null);
2581
+ return slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(slidingScale.suggestedAmount) : "";
2582
+ });
2495
2583
  const [registrationResult, setRegistrationResult] = useState(null);
2496
2584
  const [errorMessage, setErrorMessage] = useState("");
2497
2585
  const [altchaSolution, setAltchaSolution] = useState(null);
@@ -2528,6 +2616,7 @@ function useEventRegistrationWizard(options) {
2528
2616
  occurrenceId,
2529
2617
  attendanceMode: selectedAttendanceMode,
2530
2618
  ticketTypeId: selectedTicketTypeId,
2619
+ selectedSlidingAmount: parseCurrencyInputToCents(selectedSlidingAmountInput),
2531
2620
  email: formData.email,
2532
2621
  ticketsCount
2533
2622
  });
@@ -2663,6 +2752,18 @@ function useEventRegistrationWizard(options) {
2663
2752
  }),
2664
2753
  [selectedAttendanceMode, selectedEvent, preSelectedEvent, eligibility, selectedTicketTypeId]
2665
2754
  );
2755
+ const selectedSlidingAmount = useMemo(
2756
+ () => parseCurrencyInputToCents(selectedSlidingAmountInput),
2757
+ [selectedSlidingAmountInput]
2758
+ );
2759
+ const selectedEventSlidingScale = useMemo(
2760
+ () => getSlidingScaleForEvent(selectedEvent ?? preSelectedEvent),
2761
+ [selectedEvent, preSelectedEvent]
2762
+ );
2763
+ const slidingScaleSelectionMessage = getSlidingScaleSelectionMessage({
2764
+ slidingScale: selectedEventSlidingScale,
2765
+ selectedAmount: selectedSlidingAmount
2766
+ });
2666
2767
  const ticketTypeSelectionRequired = useMemo(() => {
2667
2768
  const event = selectedEvent ?? preSelectedEvent;
2668
2769
  if (!event || publicEventPricingMode(resolveRuntimeEventPricing(event)) !== "ticket_types") {
@@ -2731,12 +2832,24 @@ function useEventRegistrationWizard(options) {
2731
2832
  setGuestSectionShake(false);
2732
2833
  };
2733
2834
  const eventRequiresPayment = useMemo(
2734
- () => resolveEventRequiresPayment({
2835
+ () => {
2836
+ if (selectedEventSlidingScale) {
2837
+ return (selectedSlidingAmount ?? 0) > 0;
2838
+ }
2839
+ return resolveEventRequiresPayment({
2840
+ eligibility,
2841
+ selectedTicketType,
2842
+ event: selectedEvent ?? preSelectedEvent
2843
+ });
2844
+ },
2845
+ [
2735
2846
  eligibility,
2736
2847
  selectedTicketType,
2737
- event: selectedEvent ?? preSelectedEvent
2738
- }),
2739
- [eligibility, selectedTicketType, selectedEvent, preSelectedEvent]
2848
+ selectedEvent,
2849
+ preSelectedEvent,
2850
+ selectedEventSlidingScale,
2851
+ selectedSlidingAmount
2852
+ ]
2740
2853
  );
2741
2854
  const handleDetailsComplete = async () => {
2742
2855
  if (ticketTypeSelectionRequired && !hasValidSelectedTicketType) {
@@ -2745,6 +2858,11 @@ function useEventRegistrationWizard(options) {
2745
2858
  setStep("error");
2746
2859
  return { ok: false, reason: "blocked", message };
2747
2860
  }
2861
+ if (slidingScaleSelectionMessage) {
2862
+ setErrorMessage(slidingScaleSelectionMessage);
2863
+ setStep("error");
2864
+ return { ok: false, reason: "blocked", message: slidingScaleSelectionMessage };
2865
+ }
2748
2866
  if (!validateForm()) {
2749
2867
  setGuestSectionShake(true);
2750
2868
  return {
@@ -2829,9 +2947,18 @@ function useEventRegistrationWizard(options) {
2829
2947
  const discountSubtotalCents = useMemo(() => {
2830
2948
  if (discountContext?.type !== "event") return void 0;
2831
2949
  const event = selectedEvent ?? preSelectedEvent;
2832
- const eventPriceCents = selectedTicketType?.priceAmount ?? eligibility?.price ?? (event ? publicEventScalarPrice(resolveRuntimeEventPricing(event)) : null) ?? 0;
2950
+ const eventPriceCents = selectedTicketType?.priceAmount ?? eligibility?.price ?? (selectedEventSlidingScale ? selectedSlidingAmount : null) ?? (event ? publicEventScalarPrice(resolveRuntimeEventPricing(event)) : null) ?? 0;
2833
2951
  return Math.max(0, eventPriceCents * ticketsCount);
2834
- }, [discountContext, selectedTicketType, eligibility, selectedEvent, preSelectedEvent, ticketsCount]);
2952
+ }, [
2953
+ discountContext,
2954
+ selectedTicketType,
2955
+ eligibility,
2956
+ selectedEvent,
2957
+ preSelectedEvent,
2958
+ selectedEventSlidingScale,
2959
+ selectedSlidingAmount,
2960
+ ticketsCount
2961
+ ]);
2835
2962
  const discountUi = useDiscountCodeUi({ api, discountContext, subtotalCents: discountSubtotalCents });
2836
2963
  const selectionMethod = paymentSelection.method;
2837
2964
  const shouldShowDiscountToggle = discountContext !== null && discountUi.manualCodeEntryAllowed && (selectionMethod === "stripe" || selectionMethod === "pass_bundle" || selectionMethod === "membership_bundle");
@@ -2840,6 +2967,7 @@ function useEventRegistrationWizard(options) {
2840
2967
  registrationTarget,
2841
2968
  selectedAttendanceMode,
2842
2969
  selectedTicketTypeId,
2970
+ selectedSlidingAmount,
2843
2971
  ticketsCount,
2844
2972
  formData,
2845
2973
  altchaSolution,
@@ -2854,6 +2982,10 @@ function useEventRegistrationWizard(options) {
2854
2982
  });
2855
2983
  const handleEventSelect = (event) => {
2856
2984
  setSelectedEvent(event);
2985
+ const slidingScale = getSlidingScaleForEvent(event);
2986
+ setSelectedSlidingAmountInput(
2987
+ slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(slidingScale.suggestedAmount) : ""
2988
+ );
2857
2989
  setSelectedAttendanceMode(
2858
2990
  (event.deliveryMode ?? "in_person") === "hybrid" ? null : (event.deliveryMode ?? "in_person") === "online" ? "online" : "in_person"
2859
2991
  );
@@ -2863,6 +2995,7 @@ function useEventRegistrationWizard(options) {
2863
2995
  const handleRetry = () => {
2864
2996
  dispatchFlow({ type: "reset", hasPreSelectedContext });
2865
2997
  setSelectedTicketTypeId(null);
2998
+ setSelectedSlidingAmountInput("");
2866
2999
  setSelectedAttendanceMode(
2867
3000
  preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null
2868
3001
  );
@@ -2899,6 +3032,11 @@ function useEventRegistrationWizard(options) {
2899
3032
  setSelectedAttendanceMode,
2900
3033
  selectedTicketTypeId,
2901
3034
  setSelectedTicketTypeId,
3035
+ selectedSlidingAmountInput,
3036
+ setSelectedSlidingAmountInput,
3037
+ selectedSlidingAmount,
3038
+ selectedEventSlidingScale,
3039
+ slidingScaleSelectionMessage,
2902
3040
  selectedTicketType,
2903
3041
  visibleTicketTypes,
2904
3042
  ticketTypeSelectionRequired,
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { FeedbackMessage, discountAvailabilityHasDiscounts, getAutoAppliedDiscountPreview, discountAvailabilityAllowsManualEntry } from './chunk-WHZQDPBZ.mjs';
3
- import { themeButtonClassName } from './chunk-MLBNVN4H.mjs';
4
- import { formatCurrencyAmount, clsx_default } from './chunk-RWYFG625.mjs';
2
+ import { FeedbackMessage, discountAvailabilityHasDiscounts, getAutoAppliedDiscountPreview, discountAvailabilityAllowsManualEntry } from './chunk-TNGL2WJF.mjs';
3
+ import { themeButtonClassName } from './chunk-6SYGVVWA.mjs';
4
+ import { formatCurrencyAmount, clsx_default } from './chunk-PCHACQEB.mjs';
5
5
  import { useReducer, useEffect, useId, useRef } from 'react';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { ChevronLeft, ChevronRight } from './chunk-6N7YRNYU.mjs';
3
- import { clsx_default } from './chunk-RWYFG625.mjs';
3
+ import { clsx_default } from './chunk-PCHACQEB.mjs';
4
4
  import React, { useRef, useState, useCallback, useEffect } from 'react';
5
5
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
6
6
 
@@ -1987,12 +1987,13 @@ var CarouselNodeClient = ({
1987
1987
  ]
1988
1988
  );
1989
1989
  const resolvedSlides = resolveSlidesToShowMobile(normalized.slidesToShow);
1990
+ const canAutoplay = normalized.autoplay && slides.length > 1;
1990
1991
  const cssVars = React.useMemo(
1991
1992
  () => getCarouselSlidesToShowCssVars(normalized.slidesToShow),
1992
1993
  [normalized.slidesToShow]
1993
1994
  );
1994
1995
  const plugins = React.useMemo(() => {
1995
- if (!normalized.autoplay) return void 0;
1996
+ if (!canAutoplay) return void 0;
1996
1997
  return [
1997
1998
  Autoplay({
1998
1999
  delay: normalized.autoplayDelay,
@@ -2002,7 +2003,7 @@ var CarouselNodeClient = ({
2002
2003
  // Continue after manual navigation
2003
2004
  })
2004
2005
  ];
2005
- }, [normalized.autoplay, normalized.autoplayDelay]);
2006
+ }, [canAutoplay, normalized.autoplayDelay]);
2006
2007
  const [viewportRef, api] = useEmblaCarousel(
2007
2008
  {
2008
2009
  align: "start",
@@ -2041,7 +2042,7 @@ var CarouselNodeClient = ({
2041
2042
  };
2042
2043
  }, [api]);
2043
2044
  React.useEffect(() => {
2044
- if (!api || !normalized.autoplay) return;
2045
+ if (!api || !canAutoplay) return;
2045
2046
  const autoplayPlugin = api.plugins()?.autoplay;
2046
2047
  if (!autoplayPlugin) return;
2047
2048
  const handleVisibility = () => {
@@ -2050,7 +2051,7 @@ var CarouselNodeClient = ({
2050
2051
  };
2051
2052
  document.addEventListener("visibilitychange", handleVisibility);
2052
2053
  return () => document.removeEventListener("visibilitychange", handleVisibility);
2053
- }, [api, normalized.autoplay]);
2054
+ }, [api, canAutoplay]);
2054
2055
  const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
2055
2056
  /* @__PURE__ */ jsx("div", { className: "carousel-frame rb-overflow-hidden rb-w-full", children: /* @__PURE__ */ jsx(
2056
2057
  "div",
@@ -2101,7 +2102,7 @@ var CarouselNodeClient = ({
2101
2102
  "data-show-controls": normalized.showControls ? "true" : "false",
2102
2103
  "data-show-dots": normalized.showDots ? "true" : "false",
2103
2104
  "data-arrow-visibility": normalized.arrowVisibility,
2104
- "data-autoplay": normalized.autoplay ? "true" : "false",
2105
+ "data-autoplay": canAutoplay ? "true" : "false",
2105
2106
  "data-loop": normalized.loop ? "true" : "false",
2106
2107
  children: inner
2107
2108
  }
@@ -1,4 +1,4 @@
1
- import { clsx_default } from './chunk-RWYFG625.mjs';
1
+ import { clsx_default } from './chunk-PCHACQEB.mjs';
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
3
 
4
4
  function resolveColorStyle(color) {
@@ -15,6 +15,7 @@ function err(error) {
15
15
 
16
16
  // ../core/src/branded.ts
17
17
  var unsafeAsMediaAssetId = (id) => id;
18
+ var unsafeAsStoragePath = (value) => value;
18
19
  var unsafeAsFormId = (id) => id;
19
20
  var unsafeAsPassId = (id) => id;
20
21
  var unsafeAsCustomerPassId = (id) => id;
@@ -86,6 +87,7 @@ function publicEventPricingType(pricing) {
86
87
  return "free";
87
88
  case "single_paid":
88
89
  case "ticket_types":
90
+ case "sliding_scale":
89
91
  case "course":
90
92
  return isFreePublicEventPriceDisplay(pricing.display) ? "free" : "paid";
91
93
  case "external":
@@ -98,6 +100,7 @@ function publicEventPricingCurrency(pricing) {
98
100
  case "free_registration":
99
101
  case "single_paid":
100
102
  case "ticket_types":
103
+ case "sliding_scale":
101
104
  return pricing.currency;
102
105
  case "course":
103
106
  return pricing.display.display.currency;
@@ -115,6 +118,8 @@ function publicEventPricingMode(pricing) {
115
118
  return "single";
116
119
  case "ticket_types":
117
120
  return "ticket_types";
121
+ case "sliding_scale":
122
+ return "sliding_scale";
118
123
  case "drop_in":
119
124
  case "course":
120
125
  case "external":
@@ -148,6 +153,8 @@ function formatCoursePriceDisplayLabel(display, options) {
148
153
  return `Course (${formatCurrencyAmount(display.amount, display.currency, options)})`;
149
154
  case "from":
150
155
  return `Course (From ${formatCurrencyAmount(display.amount, display.currency, options)})`;
156
+ case "range":
157
+ return `Course (${formatCurrencyAmount(display.minAmount, display.currency, options)} - ${formatCurrencyAmount(display.maxAmount, display.currency, options)})`;
151
158
  default:
152
159
  return assertNever(display);
153
160
  }
@@ -623,6 +630,27 @@ function clsx() {
623
630
  }
624
631
  var clsx_default = clsx;
625
632
 
633
+ // ../media-core/src/fileSafety.ts
634
+ var CONTROL_CHARACTER_PATTERN = /[\u0000-\u001f\u007f]/u;
635
+ function containsUnsafePathSegmentCharacter(value) {
636
+ return value.includes("/") || value.includes("\\") || CONTROL_CHARACTER_PATTERN.test(value);
637
+ }
638
+ function isReservedPathSegment(value) {
639
+ return value === "." || value === "..";
640
+ }
641
+ function isUnsafePathSegment(segment) {
642
+ return segment.trim().length === 0 || segment !== segment.trim() || isReservedPathSegment(segment) || containsUnsafePathSegmentCharacter(segment);
643
+ }
644
+ function parseStoragePath(value) {
645
+ return joinStoragePathSegments(value.split("/"));
646
+ }
647
+ function joinStoragePathSegments(segments) {
648
+ if (segments.some(isUnsafePathSegment)) {
649
+ return err("unsafe-path-segment");
650
+ }
651
+ return ok(unsafeAsStoragePath(segments.join("/")));
652
+ }
653
+
626
654
  // ../media-core/src/typeGuards.ts
627
655
  function isRecord(value) {
628
656
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -639,10 +667,10 @@ var RELATIVE_STORAGE_PATH_PREFIXES = [
639
667
  "imports/"
640
668
  ];
641
669
  function isRelativeDirectImageStoragePath(storagePath) {
642
- return RELATIVE_STORAGE_PATH_PREFIXES.some((prefix) => storagePath.startsWith(prefix));
670
+ return RELATIVE_STORAGE_PATH_PREFIXES.some((prefix) => storagePath.startsWith(prefix)) && parseStoragePath(storagePath).ok;
643
671
  }
644
672
  function isSiteScopedDirectImageStoragePath(storagePath) {
645
- return storagePath.startsWith("sites/");
673
+ return storagePath.startsWith("sites/") && parseStoragePath(storagePath).ok;
646
674
  }
647
675
  function encodeStoragePath(storagePath) {
648
676
  return storagePath.split("/").map((segment) => encodeURIComponent(segment)).join("/");