riverbankcms 0.17.1 → 0.18.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.
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { $ as readHeaderNavFontSizePreference, $n as cardListFamilyBlocks, $r as isOnColorBackgroundCandidateToken, $t as resolvedButtonColourDeclarations, A as pickShadeTowardBackground, An as resolveSectionBackground, Ar as textColorValue, At as parseCustomCssRules, B as createNavigationRef, Bn as generateCardCoreCss, Br as PUBLIC_BUTTON_ROLES, Bt as FONT_WEIGHT_MAP, C as pagePathForCommand, Cn as composeBoundary, Cr as TokenResolver, Ct as MQ_SM_DOWN, D as bookingPaymentTermsSchema, Dn as transitionCatalogueEntries, Dr as mergeStyles, Dt as getComponentBorderWidthPx, E as bookingPaymentCollectionOptionSchema, En as anglePolygonCss, Er as cssVarValue, Et as headerVariantValues, F as createContentEntryRef, Fn as stripStaleTransitionStyleGroup, Fr as isCssColorLiteral, Ft as NAV_LINK_TEXT_SIZE_MAP, G as slugPart, Gn as cardRoleSchema, Gr as buildThemeTokens, Gt as ACCORDION_SPACING_MAP, H as createSiteCommandSiteRef, Hn as generateCardCss, Hr as unsafeAsOpaqueButtonColourToken, Ht as INPUT_SPACING_MAP, I as createEventCategoryRef, In as mediaIdentifierSchema, Ir as resolveOnColorForThemeToken, It as navLinkHoverColorCandidate, J as headerLeafTextColor, Jn as backgroundAppearanceColorTokenNames, Jr as surfaceForegroundDeclarations, Jt as ICON_CONFIG, K as effectiveHeaderNavLinkStyle, Kn as cardVariantRoleValues, Kr as defaultThemeTokens, Kt as ACCORDION_TRIGGER_FONT_SCALE, L as createEventSeriesRef, Ln as mediaSchema, Lr as resolveThemeColorReferenceValue, Lt as navLinkOwnsHoverForeground, M as createBlockRef, Mn as boxBackgroundSchema, Mr as opaqueSurfaceDeclarations, Mt as NAV_LINK_LETTER_SPACING_MAP, N as createBlocksRef, Nn as pageDesignEditorBackgroundOverrideOwner, Nr as compileButtonColourStates, Nt as NAV_LINK_PADDING_MAP, O as require_jsx_runtime, On as deriveSectionGround, Or as rgbColorValue, Ot as getComponentShadowVar, P as createCommandRef, Pn as siteChromeBackgroundOverrideOwner, Pr as formatButtonColourContractError, Pt as NAV_LINK_PADDING_X_MAP, Q as mergeHeaderNavTypographyPreference, Qn as resolveEffectiveKnobs, Qr as expandPalette, Qt as RESOLVED_BUTTON_DISABLED_DECLARATIONS, R as createFooterRef, Rn as mediaTypeDiscriminants, Rr as resolveTokenOrCssColorValue, Rt as navLinkOwnsUnderline, S as pageIdentifierForCommand, Sn as boundaryLayout, Sr as resolveSurfaceForeground, St as MQ_MD_DOWN, Tn as boundaryRuntimeMetricsForDecorativeTransition, Tr as borderColorStyle, Tt as MQ_TABLET_ONLY, U as createVenueRef, Un as renderCssDeclarations, Ur as selectLogoVariant, Ut as LABEL_FONT_SIZE_MAP, V as createPageRef, Vn as getDefaultCardVariants, Vr as buttonVariantIdSchema, Vt as INPUT_FONT_SIZE_MAP, W as refSlug, Wn as generateShadowValue$1, Wr as surfaceToneFromForegroundToken, Wt as ACCORDION_OPEN_ACCENT_THICKNESS, X as readOpeningForegroundProjection, Xn as parseBackgroundAppearanceColorToken, Xr as surfaceForegroundStyle, Xt as generateButtonActionLayoutCss, Y as transparentHeaderForegroundInput, Yn as backgroundAppearanceQuickColorTokenNames, Yr as surfaceForegroundInputFromResolved, Yt as ICON_SIZE_PX, Z as getNavLinkPreset, Zn as defineBlockDesignMetadata, Zr as surfaceForegroundValue, Zt as generateButtonCss, _ as getSiteCommandMetadata, _n as arrangementSlotNames, _r as testimonialsCompositionTreatmentValues, _t as BREAKPOINT_LG, ai as parseBlockColorToken, an as parseThemeButtonVariantId, ar as asSiteStyleId, at as resolvePublishedLook, b as entryIdentifierForCommand, br as resolveSurface, bt as BREAKPOINT_XL, c as isEventVisibility, ci as hexToRgb, cn as themeButtonVariantClassNames, cr as defineFrameCapability, ct as GRADIENT_PRESET_IDS, d as stableStringify, di as __toESM, dn as skinTokenCssVars, dr as eyebrowTreatmentValues, dt as deriveSiteStyleBlockPolicy, ei as onColorTokenName, en as resolvedButtonFocusDeclarations, er as cardListKnobBlocks, et as headerRootPaint, f as createDryRunReport, fn as buildGoogleFontFamilyQuery, fr as featureCardCompositionTreatmentValues, ft as themeSchema, g as evaluateSiteCommandExposure, gn as arrangementLookHooks, gr as offeringsPreviewCompositionTreatmentValues, gt as renderHeaderPaintTargetRules, h as evaluateSiteCommandBatchExposure, hr as makeBoundaryId, ht as getHeaderPaintTargets, ii as parseThemeColorToken, in as generateInteractiveChildInheritanceCSS, it as resolveModeArrangement, j as generateCssVars, jn as boxBackgroundOverlaySchema, jr as opaqueSurfaceContextFromTheme, jt as NAV_LINK_BORDER_RADIUS_MAP, k as require_react, kn as parseCanonicalRuntimeBackground, kr as textColorStyle, kt as parseBlockCustomCssRules, l as venueManagementFields, li as oklchToHexGamut, ln as parseThemeForPersistence, lr as defineNoBlockDesignCapability, lt as getGradientPreset, m as mapEventCommandContent, mn as getFontWidthRange, mr as introCompositionTreatmentValues, mt as generateMobileOverlayBackdropFilterFix, ni as ORDINARY_TEXT_MIN_CONTRAST_RATIO, nn as generateEffectsCSS, nr as asDesignBlockId, nt as readStoredMode, o as classifySdkEventBookingOffer, oi as parseColorTokenParts, on as themeButtonExtraClassesWithTrailingIcon, or as assertNever$4, ot as requireCuratedSiteStyle, p as parseAndPlanCommandBatchForTypes, pn as generateFontFaceCss, pr as headingDecorationColorTokenValues, pt as generateHeaderScrollTreatmentStyles, q as headerForegroundCandidates, qn as normalizeCardRole, qr as DEFAULT_SURFACE_TEXT_COLOR, qt as ACCORDION_TRIGGER_LETTER_SPACING, ri as contrastRatio, rn as generateBaseInteractiveCSS, rr as asLayoutVariantKey, rt as resolveEffectiveArrangement, si as featuresFromHex, sn as themeButtonSizeClassName, sr as defineBlockDesignCapability, st as gradientToCss, t as classifySdkEventTiming, ti as getTextColorForBackground, tn as generateDefaultButtonSystem, tt as arrangementManifestFromVariants, u as sortRecord, ui as __commonJSMin, un as footerModeSchema, ur as eventListTreatmentValues, ut as parseGradientPresetId, v as blockIdentifierForCommand, vn as resolveItemSurface, vr as tileTreatmentValues, vt as BREAKPOINT_MD, w as hasConfiguredBookingVertical, wn as sectionFactsForContent, wr as backgroundColorStyle, wt as MQ_SM_UP, x as pageIdentifierForBlockCommand, xr as surfaceDecorationColors, xt as MQ_LG_UP, y as blockOrderIdentifiersForCommand, yn as resolveLookSlotSurfaces, yr as visibleHeadingDecorationFamilyValues, yt as BREAKPOINT_SM, z as createFormRef, zn as persistableMediaSchema, zr as generateShadowValue, zt as navEffectPolicy } from "../sdk-event-upsert-JKXlp2Ct.mjs";
3
- import { $ as toBookingTimeZone, $t as unsafeAsCheckoutLineId, At as parsePositiveCents, B as normalizeLocationAddressText, Bt as parseCustomerId, C as parseMailingListBlockId, Ct as publicEventPricingType, D as assessMailingListTargeting, E as parseMailingListRuntimeContext, En as ok, Et as fromArray, F as sameMailingListPlacementTargeting, Ft as formatCurrencyAmount, G as formatBookingDateParts, Gt as parseMembershipId, H as selectCategoryView, Ht as parseDatedOfferingCapacityHoldId, It as parseCurrencyCode, J as formatLocalScheduleTime, Jt as parseSiteId, K as formatBookingTime, Kt as parsePageId, Lt as assertNever, M as parseMailingListPlacementTargeting, Mt as toNonNegativeCents, N as DEFAULT_MAILING_LIST_TARGETING, Nt as unsafeAsNonNegativeCents, O as DEFAULT_MAILING_LIST_SUCCESS_MESSAGE, Ot as isNonNegativeWholeCents$1, P as planMailingListChoicePresentation, Pt as unsafeAsPositiveCents, R as assertAllowedPublicUrl, Rt as formatDurationUnitLabel, S as buildMailingListSignupBlockSourceRef, St as publicEventPricingOptions, T as parseMailingListSignedSourceToken, Tn as err, Tt as resolvePricingOptionsPriceDisplay, U as buildBookingUtcDateWindow, Ut as parseEventSeriesId, V as toLocationCoordinates, Vt as parseDatedOfferingCapacityHoldAuditRef, W as formatBookingDate, Wt as parseMediaAssetId, X as getLocalScheduleDate, Xt as unsafeAsAppointmentResourceId, Y as getBookingLocalDateKey, Yt as parseUserId, Z as getLocalScheduleTime, _ as resolveWholeSeriesBookingPhase, _t as formatBookingPriceDisplay, at as isSettleableFlexibleBalanceContractStatus, b as parseManagementKey, bn as unsafeAsStaffMemberId, bt as publicEventPricingCurrency, c as resolveSiteVerticalBookingConfig, cn as unsafeAsMediaAssetId, ct as clampConfiguredAmount, dn as unsafeAsPassId, dt as getBookingInstalmentProtectedDepositAmountCents, et as toScheduledBookingDateRange, f as SURFACE_EVENT_PRESET_VALUES, fn as unsafeAsPositiveByteCount, ft as omitZeroAmountFutureRows, g as orderedLiveRunSessions, gt as parseEventPageSurfaceSubject, h as CANCELLED_SESSION_STATUS, ht as resolveFlexibleBalanceInitialPaymentCents, i as areConfiguredBookingVerticalConfigsEqual, in as unsafeAsEventInstanceId, it as isLiveOrderInstalmentPlanStatus, j as parseFooterCompositionV1, jt as toCents, k as parseMailingListProviderScope, kt as parseNonNegativeCents, ln as unsafeAsOccurrenceId, lt as getBookingInstalmentDepositRefundability, m as publicReadFreshnessSeconds, mn as unsafeAsPricingOptionId, mt as resolveFlexibleBalanceDueAt, n as EVENT_PRESET_VOCABULARY, ot as isSettleableOrderInstalmentPlanStatus, p as WHOLE_SERIES_EVENT_PRESET_VALUES, pt as splitAmountWithRemainderInFirst, q as formatLocalScheduleDate, qt as parseRetiredCourseId, r as NAVIGATION_LOCATIONS, rt as validateBookingPaymentOptionKinds, st as addIntervalPreservingMonthAnchor, tn as unsafeAsDemoCapability, tt as toScheduledBookingDateTime, u as EVENT_PRESET_VALUES, ut as getBookingInstalmentPlanIntervalCount, v as createSecret, vt as formatEventPricing, w as parseMailingListContentVersionId, wt as resolveExactOrFreePriceDisplay, xt as publicEventPricingDisplay, y as exposeSecret, yt as isPublicEventPricingOptionDisplayable, zt as parseApiKeyId } from "../src-JsJh7WAb.mjs";
4
- import { $ as sdkListEventsResponseSchema, A as resolveMediaTransformForAspect, B as asRecord$1, C as walkAndCollectImageAttrs, D as normalizeWidthCandidates, E as rotateNormalizedPoint, F as buildMediaIdentifierFromFilename, G as parseSafeDownloadFilename, H as FILE_SIZE_LIMITS, I as parseMediaIdentifier, J as createHttpClient, K as ManagementApiError, L as deriveVideoSlotPolicy, M as getDirectImageUrlForSiteScopedPath, N as getImageUrl, O as isExplicitRectCrop, P as isSiteScopedDirectImageStoragePath, Q as sdkGetEventResponseSchema, R as resolveVideoSelectionIntentForMediaField, S as buildRenderableMediaAssetIndex, St as sdkConfiguredBookingVerticalConfigSchema, T as looksLikeUuid$1, U as classifyKnownMimeType, V as parseRelativeStoragePath, W as managementMediaLibraryUploadLimitForMimeType, X as managementTransportError, Y as is404Error, Z as sdkConfigureBookingVerticalResponseSchema, _ as buildSettingsUpdateInput, _t as sdkSavePageDesignResponseSchema, a as prepareLocalMediaForPush, at as customLinkSchema$1, b as isMediaValue, bt as sdkListEventOccurrencesResponseSchema, c as writeBinaryFileAtomic, ct as internalLinkSchema, d as normalizeMediaValueToIdentifierOnly, dt as isInternalResolvedLinkValue, et as sdkTakeEventOfflineResponseSchema, f as walkLocalContentMedia, ft as isResolvedInternalLinkEntityType, g as SETTINGS_FILE_FIELDS, gt as sdkGetPageDesignResponseSchema, h as extractMediaIdentifiers, ht as portablePageDesignSchema, i as applyLocalMediaPush, it as RESOLVED_INTERNAL_LINK_ENTITY_TYPES, j as getDirectImageUrlForRelativePath, k as parseAspectRatioValue, l as sha256, lt as internalResolvedLinkSchema, m as downloadMedia, mt as pageLinkSchema$1, nt as sdkSettingsUpdateSchema, o as admitBinaryWriteDestination, ot as entryLinkSchema$1, p as buildStorageUrl, pt as linkSchema, q as buildRequestInfo, r as syncLocalMediaForPull, rt as linkPayloadSchema, s as readStableBinaryFile, st as externalLinkSchema$1, t as revalidateLocalMediaPushPlan, tt as sdkUpsertEventResponseSchema, u as normalizeMediaIdentifierInput, ut as internalRouteOnlyLinkSchema, v as hasOwnSettingsField, vt as sdkDeleteEventOccurrenceResponseSchema, w as deleteEnvSpecificKeys, x as attachRenderableMediaAssetFields, xt as sdkReorderResponseSchema, y as writeMediaManifest, yt as sdkEventOccurrenceResponseSchema, z as getMimeType } from "../local-sync-C0m2pobl.mjs";
5
- import { n as CliSdkPeerError, r as CLI_VERSION, t as loadConfigFile } from "../load-config-DR5qJgmx.mjs";
6
- import { a as RichTextDocSchema, c as isRecord$16, i as findUnfilledSentinels, n as buildEntryScaffold, o as isRichTextDoc, r as validateEntryInstance, s as isObjectRecord, t as eventUpsertInputSchema } from "../eventUpsertInputSchema-PT5biDSq.mjs";
7
- import { a as prepareScaffoldExecution, c as LOCAL_PACKAGE_VENDOR_DIR, d as loadGeneratedPackageRanges, i as preflightScaffoldTargets, n as createScaffoldCompletion, s as deriveScaffoldLocalManifest, t as deriveScaffoldPlan } from "../plan-BreyfN6E.mjs";
2
+ import { $ as readHeaderNavFontSizePreference, $n as mediaSchema, $r as makeBoundaryId, $t as resolvedButtonColourDeclarations, A as pickShadeTowardBackground, Ai as defaultThemeTokens, An as resolveSectionBackground, Ar as cardVariantRoleValues, At as parseCustomCssRules, B as createNavigationRef, Bi as ORDINARY_TEXT_MIN_CONTRAST_RATIO, Bn as deleteEnvSpecificKeys, Br as asDesignBlockId, Bt as FONT_WEIGHT_MAP, C as pagePathForCommand, Ci as generateShadowValue, Cn as composeBoundary, Cr as parseSafeDownloadFilename, Ct as MQ_SM_DOWN, D as bookingPaymentTermsSchema, Di as selectLogoVariant, Dn as transitionCatalogueEntries, Dr as renderCssDeclarations, Dt as getComponentBorderWidthPx, E as bookingPaymentCollectionOptionSchema, Ei as unsafeAsOpaqueButtonColourToken, En as anglePolygonCss, Er as generateCardCss, Et as headerVariantValues, F as createContentEntryRef, Fi as surfaceForegroundValue, Fn as siteChromeBackgroundOverrideOwner, Fr as defineBlockDesignMetadata, Ft as NAV_LINK_TEXT_SIZE_MAP, G as slugPart, Gi as featuresFromHex, Gn as parseAspectRatioValue, Gr as defineBlockDesignCapability, Gt as ACCORDION_SPACING_MAP, H as createSiteCommandSiteRef, Hi as parseThemeColorToken, Hn as rotateNormalizedPoint, Ht as INPUT_SPACING_MAP, I as createEventCategoryRef, Ii as expandPalette, In as stripStaleTransitionStyleGroup, Ir as resolveEffectiveKnobs, It as navLinkHoverColorCandidate, J as headerLeafTextColor, Ji as __commonJSMin, Jn as getDirectImageUrlForSiteScopedPath, Jr as eventListTreatmentValues, Jt as ICON_CONFIG, K as effectiveHeaderNavLinkStyle, Ki as hexToRgb, Kn as resolveMediaTransformForAspect, Kr as defineFrameCapability, Kt as ACCORDION_TRIGGER_FONT_SCALE, L as createEventSeriesRef, Li as isOnColorBackgroundCandidateToken, Ln as collectPortableMediaReferencesFromContent, Lr as cardListFamilyBlocks, Lt as navLinkOwnsHoverForeground, M as createBlockRef, Mi as surfaceForegroundDeclarations, Mn as boxBackgroundSchema, Mr as backgroundAppearanceColorTokenNames, Mt as NAV_LINK_LETTER_SPACING_MAP, N as createBlocksRef, Ni as surfaceForegroundInputFromResolved, Nn as runtimeBoxBackgroundSchema, Nr as backgroundAppearanceQuickColorTokenNames, Nt as NAV_LINK_PADDING_MAP, O as require_jsx_runtime, Oi as surfaceToneFromForegroundToken, On as deriveSectionGround, Or as generateShadowValue$1, Ot as getComponentShadowVar, P as createCommandRef, Pi as surfaceForegroundStyle, Pn as pageDesignEditorBackgroundOverrideOwner, Pr as parseBackgroundAppearanceColorToken, Pt as NAV_LINK_PADDING_X_MAP, Q as mergeHeaderNavTypographyPreference, Qn as mediaPosterSchema, Qr as introCompositionTreatmentValues, Qt as RESOLVED_BUTTON_DISABLED_DECLARATIONS, R as createFooterRef, Ri as onColorTokenName, Rn as summarizePortableMediaReferences, Rr as cardListKnobBlocks, Rt as navLinkOwnsUnderline, S as pageIdentifierForCommand, Si as resolveTokenOrCssColorValue, Sn as boundaryLayout, Sr as managementMediaLibraryUploadLimitForMimeType, St as MQ_MD_DOWN, Ti as buttonVariantIdSchema, Tn as boundaryRuntimeMetricsForDecorativeTransition, Tr as getDefaultCardVariants, Tt as MQ_TABLET_ONLY, U as createVenueRef, Ui as parseBlockColorToken, Un as normalizeWidthCandidates, Ur as asSiteStyleId, Ut as LABEL_FONT_SIZE_MAP, V as createPageRef, Vi as contrastRatio, Vn as looksLikeUuid$1, Vr as asLayoutVariantKey, Vt as INPUT_FONT_SIZE_MAP, W as refSlug, Wi as parseColorTokenParts, Wn as isExplicitRectCrop, Wr as assertNever$4, Wt as ACCORDION_OPEN_ACCENT_THICKNESS, X as readOpeningForegroundProjection, Xn as isSiteScopedDirectImageStoragePath, Xr as featureCardCompositionTreatmentValues, Xt as generateButtonActionLayoutCss, Y as transparentHeaderForegroundInput, Yi as __toESM, Yn as getImageUrl, Yr as eyebrowTreatmentValues, Yt as ICON_SIZE_PX, Z as getNavLinkPreset, Zn as imageMediaSchema, Zr as headingDecorationColorTokenValues, Zt as generateButtonCss, _ as getSiteCommandMetadata, _i as compileButtonColourStates, _n as arrangementSlotNames, _t as BREAKPOINT_LG, ai as surfaceDecorationColors, an as parseThemeButtonVariantId, ar as mediaTypeDiscriminants, at as resolvePublishedLook, b as entryIdentifierForCommand, bi as resolveOnColorForThemeToken, bt as BREAKPOINT_XL, c as isEventVisibility, ci as backgroundColorStyle, cn as themeButtonVariantClassNames, cr as parseCanonicalMediaIdentifier, ct as GRADIENT_PRESET_IDS, d as stableStringify, di as mergeStyles, dn as skinTokenCssVars, dt as deriveSiteStyleBlockPolicy, ei as offeringsPreviewCompositionTreatmentValues, en as resolvedButtonFocusDeclarations, er as persistableMediaSchema, et as headerRootPaint, f as createDryRunReport, fi as rgbColorValue, fn as buildGoogleFontFamilyQuery, fr as deriveVideoSlotPolicy, ft as themeSchema, g as evaluateSiteCommandExposure, gi as opaqueSurfaceDeclarations, gn as arrangementLookHooks, gr as asRecord$1, gt as renderHeaderPaintTargetRules, h as evaluateSiteCommandBatchExposure, hi as opaqueSurfaceContextFromTheme, hr as getMimeType, ht as getHeaderPaintTargets, ii as resolveSurface, in as generateInteractiveChildInheritanceCSS, ir as resolveManagedMediaReference, it as resolveModeArrangement, j as generateCssVars, ji as DEFAULT_SURFACE_TEXT_COLOR, jn as boxBackgroundOverlaySchema, jr as normalizeCardRole, jt as NAV_LINK_BORDER_RADIUS_MAP, k as require_react, ki as buildThemeTokens, kn as parseCanonicalRuntimeBackground, kr as cardRoleSchema, kt as parseBlockCustomCssRules, l as venueManagementFields, li as borderColorStyle, ln as parseThemeForPersistence, lr as parseMediaIdentifier, lt as getGradientPreset, m as mapEventCommandContent, mi as textColorValue, mn as getFontWidthRange, mt as generateMobileOverlayBackdropFilterFix, ni as tileTreatmentValues, nn as generateEffectsCSS, nr as buildRenderableMediaAssetIndex, nt as readStoredMode, o as classifySdkEventBookingOffer, oi as resolveSurfaceForeground, on as themeButtonExtraClassesWithTrailingIcon, or as mediaIdentifierSchema, ot as requireCuratedSiteStyle, p as parseAndPlanCommandBatchForTypes, pi as textColorStyle, pn as generateFontFaceCss, pr as resolveVideoSelectionIntentForMediaField, pt as generateHeaderScrollTreatmentStyles, q as headerForegroundCandidates, qi as oklchToHexGamut, qn as getDirectImageUrlForRelativePath, qr as defineNoBlockDesignCapability, qt as ACCORDION_TRIGGER_LETTER_SPACING, ri as visibleHeadingDecorationFamilyValues, rn as generateBaseInteractiveCSS, rr as indexRenderableMediaAssets, rt as resolveEffectiveArrangement, si as TokenResolver, sn as themeButtonSizeClassName, sr as buildMediaIdentifierFromFilename, st as gradientToCss, t as classifySdkEventTiming, ti as testimonialsCompositionTreatmentValues, tn as generateDefaultButtonSystem, tr as runtimeMediaSchema, tt as arrangementManifestFromVariants, u as sortRecord, ui as cssVarValue, un as footerModeSchema, ut as parseGradientPresetId, v as blockIdentifierForCommand, vi as formatButtonColourContractError, vn as resolveItemSurface, vr as parseRelativeStoragePath, vt as BREAKPOINT_MD, w as hasConfiguredBookingVertical, wi as PUBLIC_BUTTON_ROLES, wn as sectionFactsForContent, wr as generateCardCoreCss, wt as MQ_SM_UP, x as pageIdentifierForBlockCommand, xi as resolveThemeColorReferenceValue, xr as classifyKnownMimeType, xt as MQ_LG_UP, y as blockOrderIdentifiersForCommand, yi as isCssColorLiteral, yn as resolveLookSlotSurfaces, yr as FILE_SIZE_LIMITS, yt as BREAKPOINT_SM, z as createFormRef, zi as getTextColorForBackground, zn as walkAndCollectImageAttrs, zt as navEffectPolicy } from "../sdk-event-upsert-BamyD2d6.mjs";
3
+ import { $ as toBookingTimeZone, $t as unsafeAsCheckoutLineId, At as parsePositiveCents, B as normalizeLocationAddressText, Bt as parseCustomerId, C as parseMailingListBlockId, Ct as publicEventPricingType, D as assessMailingListTargeting, E as parseMailingListRuntimeContext, En as ok, Et as fromArray, F as sameMailingListPlacementTargeting, Ft as formatCurrencyAmount, G as formatBookingDateParts, Gt as parseMembershipId, H as selectCategoryView, Ht as parseDatedOfferingCapacityHoldId, It as parseCurrencyCode, J as formatLocalScheduleTime, Jt as parseSiteId, K as formatBookingTime, Kt as parsePageId, Lt as assertNever, M as parseMailingListPlacementTargeting, Mt as toNonNegativeCents, N as DEFAULT_MAILING_LIST_TARGETING, Nt as unsafeAsNonNegativeCents, O as DEFAULT_MAILING_LIST_SUCCESS_MESSAGE, Ot as isNonNegativeWholeCents$1, P as planMailingListChoicePresentation, Pt as unsafeAsPositiveCents, R as assertAllowedPublicUrl, Rt as formatDurationUnitLabel, S as buildMailingListSignupBlockSourceRef, St as publicEventPricingOptions, T as parseMailingListSignedSourceToken, Tn as err, Tt as resolvePricingOptionsPriceDisplay, U as buildBookingUtcDateWindow, Ut as parseEventSeriesId, V as toLocationCoordinates, Vt as parseDatedOfferingCapacityHoldAuditRef, W as formatBookingDate, X as getLocalScheduleDate, Xt as unsafeAsAppointmentResourceId, Y as getBookingLocalDateKey, Yt as parseUserId, Z as getLocalScheduleTime, _ as resolveWholeSeriesBookingPhase, _t as formatBookingPriceDisplay, at as isSettleableFlexibleBalanceContractStatus, b as parseManagementKey, bn as unsafeAsStaffMemberId, bt as publicEventPricingCurrency, c as resolveSiteVerticalBookingConfig, cn as unsafeAsMediaAssetId, ct as clampConfiguredAmount, dn as unsafeAsPassId, dt as getBookingInstalmentProtectedDepositAmountCents, et as toScheduledBookingDateRange, f as SURFACE_EVENT_PRESET_VALUES, fn as unsafeAsPositiveByteCount, ft as omitZeroAmountFutureRows, g as orderedLiveRunSessions, gt as parseEventPageSurfaceSubject, h as CANCELLED_SESSION_STATUS, ht as resolveFlexibleBalanceInitialPaymentCents, i as areConfiguredBookingVerticalConfigsEqual, in as unsafeAsEventInstanceId, it as isLiveOrderInstalmentPlanStatus, j as parseFooterCompositionV1, jt as toCents, k as parseMailingListProviderScope, kt as parseNonNegativeCents, ln as unsafeAsOccurrenceId, lt as getBookingInstalmentDepositRefundability, m as publicReadFreshnessSeconds, mn as unsafeAsPricingOptionId, mt as resolveFlexibleBalanceDueAt, n as EVENT_PRESET_VOCABULARY, ot as isSettleableOrderInstalmentPlanStatus, p as WHOLE_SERIES_EVENT_PRESET_VALUES, pt as splitAmountWithRemainderInFirst, q as formatLocalScheduleDate, qt as parseRetiredCourseId, r as NAVIGATION_LOCATIONS, rt as validateBookingPaymentOptionKinds, st as addIntervalPreservingMonthAnchor, tn as unsafeAsDemoCapability, tt as toScheduledBookingDateTime, u as EVENT_PRESET_VALUES, ut as getBookingInstalmentPlanIntervalCount, v as createSecret, vt as formatEventPricing, w as parseMailingListContentVersionId, wt as resolveExactOrFreePriceDisplay, x as stableJsonStringify, xt as publicEventPricingDisplay, y as exposeSecret, yt as isPublicEventPricingOptionDisplayable, zt as parseApiKeyId } from "../src-BhrSG8A4.mjs";
4
+ import { A as sdkUpsertEventResponseSchema, B as isInternalResolvedLinkValue, C as createHttpClient, D as sdkGetEventResponseSchema, E as sdkConfigureBookingVerticalResponseSchema, F as entryLinkSchema$1, G as sdkGetPageDesignResponseSchema, H as linkSchema, I as externalLinkSchema$1, J as sdkEventOccurrenceResponseSchema, K as sdkSavePageDesignResponseSchema, L as internalLinkSchema, M as linkPayloadSchema, N as RESOLVED_INTERNAL_LINK_ENTITY_TYPES, O as sdkListEventsResponseSchema, P as customLinkSchema$1, R as internalResolvedLinkSchema, S as buildRequestInfo, T as managementTransportError, U as pageLinkSchema$1, V as isResolvedInternalLinkEntityType, W as portablePageDesignSchema, X as sdkReorderResponseSchema, Y as sdkListEventOccurrencesResponseSchema, Z as sdkConfiguredBookingVerticalConfigSchema, _ as buildSettingsUpdateInput, a as prepareLocalMediaForPush, b as isMediaValue, c as writeBinaryFileAtomic, d as normalizeMediaValueToIdentifierOnly, f as walkLocalContentMedia, g as SETTINGS_FILE_FIELDS, h as extractMediaIdentifiers, i as applyLocalMediaPush, j as sdkSettingsUpdateSchema, k as sdkTakeEventOfflineResponseSchema, l as sha256, m as downloadMedia, o as admitBinaryWriteDestination, p as buildStorageUrl, q as sdkDeleteEventOccurrenceResponseSchema, r as syncLocalMediaForPull, s as readStableBinaryFile, t as revalidateLocalMediaPushPlan, u as normalizeMediaIdentifierInput, v as hasOwnSettingsField, w as is404Error, x as ManagementApiError, y as writeMediaManifest, z as internalRouteOnlyLinkSchema } from "../local-sync-B3naCvSc.mjs";
5
+ import { n as CliSdkPeerError, r as CLI_VERSION, t as loadConfigFile } from "../load-config-BXspoah3.mjs";
6
+ import { a as RichTextDocSchema, c as isRecord$16, i as findUnfilledSentinels, n as buildEntryScaffold, o as isRichTextDoc, r as validateEntryInstance, s as isObjectRecord, t as eventUpsertInputSchema } from "../eventUpsertInputSchema-BNSzkEID.mjs";
7
+ import { a as prepareScaffoldExecution, c as LOCAL_PACKAGE_VENDOR_DIR, d as loadGeneratedPackageRanges, i as preflightScaffoldTargets, n as createScaffoldCompletion, s as deriveScaffoldLocalManifest, t as deriveScaffoldPlan } from "../plan-DxAHLs05.mjs";
8
8
  import { config } from "dotenv";
9
9
  import { Command, CommanderError } from "commander";
10
10
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -15312,37 +15312,15 @@ function buildPlacementCells(placement) {
15312
15312
  return Array.from({ length: placement.span }, (_, index) => placement.colStart + index);
15313
15313
  }
15314
15314
  function buildOccupancyByCell(placements, columns) {
15315
- const occupancy = new Map();
15316
- let hasCollisions = false;
15317
- for (const placement of placements) {
15318
- for (const col of buildPlacementCells(placement)) {
15319
- const cell = toRowCellKey(placement.row, col, columns);
15320
- const ids = occupancy.get(cell) ?? new Set();
15321
- ids.add(placement.id);
15322
- if (ids.size > 1) {
15323
- hasCollisions = true;
15324
- }
15325
- occupancy.set(cell, ids);
15326
- }
15327
- }
15315
+ const entries = placements.flatMap((placement) => buildPlacementCells(placement).map((col) => [toRowCellKey(placement.row, col, columns), placement.id]));
15316
+ const occupancy = entries.reduce((cells, [cell, id]) => new Map(cells).set(cell, new Set([...cells.get(cell) ?? [], id])), new Map());
15328
15317
  return {
15329
15318
  occupancy,
15330
- hasCollisions
15319
+ hasCollisions: Array.from(occupancy.values()).some((ids) => ids.size > 1)
15331
15320
  };
15332
15321
  }
15333
15322
  function getOverlappingItemIds(input) {
15334
- const overlaps = new Set();
15335
- for (let col = input.colStart; col < input.colStart + input.span; col += 1) {
15336
- const ids = input.occupancy.get(toRowCellKey(input.row, col, input.columns));
15337
- if (!ids) continue;
15338
- for (const id of ids) {
15339
- if (input.excludedIds?.has(id)) {
15340
- continue;
15341
- }
15342
- overlaps.add(id);
15343
- }
15344
- }
15345
- return overlaps;
15323
+ return new Set(buildPlacementCells(input).flatMap((col) => Array.from(input.occupancy.get(toRowCellKey(input.row, col, input.columns)) ?? []).filter((id) => !input.excludedIds?.has(id))));
15346
15324
  }
15347
15325
  function normalizeInputItem(item, columns, sourceIndex) {
15348
15326
  const span = normalizeRepeaterGridSpan(item.span, columns);
@@ -15422,74 +15400,66 @@ function canAppendRepeaterGridItem(input) {
15422
15400
  maxRows: input.maxRows
15423
15401
  }) != null;
15424
15402
  }
15403
+ function placementsOverlap(left, right) {
15404
+ return left.row === right.row && left.colStart < right.colStart + right.span && right.colStart < left.colStart + left.span;
15405
+ }
15406
+ function swapPositionUpdates(active, target) {
15407
+ const adjacent = active.row === target.row && (active.colEnd + 1 === target.colStart || target.colEnd + 1 === active.colStart);
15408
+ const activeCol = adjacent && active.colStart < target.colStart ? active.colStart + target.span : target.colStart;
15409
+ const targetCol = adjacent && target.colStart < active.colStart ? target.colStart + active.span : active.colStart;
15410
+ return [{
15411
+ id: active.id,
15412
+ row: target.row,
15413
+ colStart: activeCol,
15414
+ span: active.span
15415
+ }, {
15416
+ id: target.id,
15417
+ row: active.row,
15418
+ colStart: targetCol,
15419
+ span: target.span
15420
+ }];
15421
+ }
15422
+ function validateGridMove(layout, updates) {
15423
+ const moved = updates;
15424
+ const stationary = layout.placements.filter((placement) => !updates.some((update) => update.id === placement.id));
15425
+ const valid = moved.every((placement, index) => placement.colStart >= 1 && placement.colStart + placement.span - 1 <= layout.columns && placement.row >= 1 && (layout.maxRows == null || placement.row <= layout.maxRows) && !stationary.some((other) => placementsOverlap(placement, other)) && !moved.slice(index + 1).some((other) => placementsOverlap(placement, other)));
15426
+ return valid ? {
15427
+ kind: "move",
15428
+ updates
15429
+ } : { kind: "blocked" };
15430
+ }
15431
+ function decideGridDrop(layout, active, destination) {
15432
+ const occupants = layout.placements.filter((placement) => placement.id !== active.id && placement.row === destination.row && destination.colStart >= placement.colStart && destination.colStart <= placement.colEnd);
15433
+ if (occupants.length > 1) return { kind: "blocked" };
15434
+ const target = occupants[0];
15435
+ if (target) return validateGridMove(layout, swapPositionUpdates(active, target));
15436
+ if (destination.row === active.row && destination.colStart === active.colStart) return { kind: "unchanged" };
15437
+ return validateGridMove(layout, [{
15438
+ id: active.id,
15439
+ row: destination.row,
15440
+ colStart: destination.colStart,
15441
+ span: active.span
15442
+ }]);
15443
+ }
15425
15444
  function buildRepeaterGridDropTargets(input) {
15426
- const { items, draggedId, columns: rawColumns, maxRows: rawMaxRows, rowsToRender } = input;
15427
- const columns = clamp(Math.max(1, Math.trunc(rawColumns)), MIN_COLUMNS, MAX_COLUMNS);
15428
- const maxRows = rawMaxRows != null ? Math.max(1, Math.trunc(rawMaxRows)) : undefined;
15429
- const layout = buildRepeaterGridLayout({
15430
- items,
15431
- columns,
15432
- maxRows
15433
- });
15434
- const draggedPlacement = layout.byId[draggedId];
15435
- if (!draggedPlacement) {
15436
- return [];
15437
- }
15438
- const { occupancy } = buildOccupancyByCell(layout.placements, columns);
15439
- const rowCeiling = maxRows ?? Math.max(1, rowsToRender ?? layout.maxRowUsed + 1, draggedPlacement.row + 1);
15440
- const targets = [];
15441
- for (let row = 1; row <= rowCeiling; row += 1) {
15442
- for (let colStart = 1; colStart <= columns; colStart += 1) {
15443
- const cell = toRowCellKey(row, colStart, columns);
15444
- let valid = false;
15445
- let swapWithId;
15446
- const fitsColumns = colStart + draggedPlacement.span - 1 <= columns;
15447
- const fitsRows = maxRows == null || row <= maxRows;
15448
- if (fitsColumns && fitsRows) {
15449
- const overlaps = getOverlappingItemIds({
15450
- occupancy,
15451
- row,
15452
- colStart,
15453
- span: draggedPlacement.span,
15454
- columns,
15455
- excludedIds: new Set([draggedId])
15456
- });
15457
- if (overlaps.size === 0) {
15458
- valid = true;
15459
- } else if (overlaps.size === 1) {
15460
- const [swapCandidateId] = [...overlaps];
15461
- const swapCandidate = swapCandidateId ? layout.byId[swapCandidateId] : undefined;
15462
- if (swapCandidate) {
15463
- const swapFitsColumns = draggedPlacement.colStart + swapCandidate.span - 1 <= columns;
15464
- const swapFitsRows = maxRows == null || draggedPlacement.row <= maxRows;
15465
- if (swapFitsColumns && swapFitsRows) {
15466
- const swapOverlaps = getOverlappingItemIds({
15467
- occupancy,
15468
- row: draggedPlacement.row,
15469
- colStart: draggedPlacement.colStart,
15470
- span: swapCandidate.span,
15471
- columns,
15472
- excludedIds: new Set([draggedId, swapCandidate.id])
15473
- });
15474
- if (swapOverlaps.size === 0) {
15475
- valid = true;
15476
- swapWithId = swapCandidate.id;
15477
- }
15478
- }
15479
- }
15480
- }
15481
- }
15482
- targets.push({
15483
- id: `repeater-grid-drop-${row}-${colStart}`,
15445
+ const { layout, draggedId, rowsToRender } = input;
15446
+ const active = layout.byId[draggedId];
15447
+ if (!active) return [];
15448
+ const rowCeiling = layout.maxRows ?? Math.max(1, rowsToRender ?? layout.maxRowUsed + 1, active.row + 1);
15449
+ return Array.from({ length: rowCeiling * layout.columns }, (_, index) => {
15450
+ const row = Math.floor(index / layout.columns) + 1;
15451
+ const colStart = index % layout.columns + 1;
15452
+ return {
15453
+ id: `repeater-grid-drop-${row}-${colStart}`,
15454
+ row,
15455
+ colStart,
15456
+ cell: index + 1,
15457
+ decision: decideGridDrop(layout, active, {
15484
15458
  row,
15485
- colStart,
15486
- cell,
15487
- valid,
15488
- ...swapWithId ? { swapWithId } : {}
15489
- });
15490
- }
15491
- }
15492
- return targets.sort((a, b) => a.cell - b.cell);
15459
+ colStart
15460
+ })
15461
+ };
15462
+ });
15493
15463
  }
15494
15464
 
15495
15465
  //#endregion
@@ -18784,6 +18754,12 @@ function parseBackgroundOverlay(value) {
18784
18754
  const result = boxBackgroundOverlaySchema.safeParse(value);
18785
18755
  return result.success ? result.data : undefined;
18786
18756
  }
18757
+ /** Rendering accepts explicit application sources separately from stored references. */
18758
+ const runtimeBackgroundContentSchema = runtimeBoxBackgroundSchema;
18759
+ function parseRuntimeBackgroundContent(value) {
18760
+ const result = runtimeBackgroundContentSchema.safeParse(value);
18761
+ return result.success ? result.data : null;
18762
+ }
18787
18763
 
18788
18764
  //#endregion
18789
18765
  //#region ../blocks/src/system/transforms/registry/_utils/themeColorResolution.ts
@@ -22485,8 +22461,195 @@ function clsx() {
22485
22461
  }
22486
22462
  var clsx_default = clsx;
22487
22463
 
22464
+ //#endregion
22465
+ //#region ../blocks/src/system/runtime/nodes/mediaContext.ts
22466
+ function buildMediaAssetIndex(assets) {
22467
+ return buildRenderableMediaAssetIndex(assets);
22468
+ }
22469
+ function normalizeSupabaseUrl(value) {
22470
+ return value?.replace(/\/$/, "");
22471
+ }
22472
+ function buildResolveImageUrlContext(input) {
22473
+ return {
22474
+ supabaseUrl: normalizeSupabaseUrl(input?.supabaseUrl),
22475
+ siteId: input?.siteId,
22476
+ mediaAssetIndex: input?.mediaAssetIndex ?? buildMediaAssetIndex(input?.mediaAssets)
22477
+ };
22478
+ }
22479
+ /**
22480
+ * Server-side: AsyncLocalStorage for request isolation.
22481
+ * Prevents race conditions when multiple requests are processed concurrently.
22482
+ *
22483
+ * Lazy initialization to avoid issues in environments that don't support async_hooks.
22484
+ */
22485
+ const serverStorageState = {
22486
+ storage: null,
22487
+ checked: false
22488
+ };
22489
+ function getServerStorage() {
22490
+ if (typeof window !== "undefined") return null;
22491
+ if (serverStorageState.checked) return serverStorageState.storage;
22492
+ serverStorageState.checked = true;
22493
+ try {
22494
+ const globalWithNonWebpackRequire = globalThis;
22495
+ const nonWebpackRequire = typeof globalWithNonWebpackRequire.__non_webpack_require__ === "function" ? globalWithNonWebpackRequire.__non_webpack_require__ : new Function("id", "return require(id)");
22496
+ const asyncHooks = nonWebpackRequire("async_hooks");
22497
+ const AsyncLocalStorage$1 = asyncHooks.AsyncLocalStorage;
22498
+ if (AsyncLocalStorage$1) {
22499
+ serverStorageState.storage = new AsyncLocalStorage$1();
22500
+ return serverStorageState.storage;
22501
+ }
22502
+ return null;
22503
+ } catch {
22504
+ if (process.env.NODE_ENV !== "production") {
22505
+ console.warn("[blocks] AsyncLocalStorage not available - using module-level state");
22506
+ }
22507
+ return null;
22508
+ }
22509
+ }
22510
+ /**
22511
+ * Client-side context storage.
22512
+ * Safe because browsers are single-threaded per tab.
22513
+ *
22514
+ * IMPORTANT: This must be shared across bundles.
22515
+ * SDK preview mode can load multiple independently-bundled entrypoints
22516
+ * (e.g. `@riverbankcms/sdk/rendering` + `@riverbankcms/sdk/preview-next/client`),
22517
+ * which can otherwise each get their own module-scoped singleton.
22518
+ */
22519
+ const RB_MEDIA_CONTEXT_KEY = Symbol.for("riverbankcms.blocks.mediaContext");
22520
+ function getClientContextStore() {
22521
+ const g = globalThis;
22522
+ const existing = g[RB_MEDIA_CONTEXT_KEY];
22523
+ if (existing && typeof existing === "object") return existing;
22524
+ const next = {};
22525
+ g[RB_MEDIA_CONTEXT_KEY] = next;
22526
+ return next;
22527
+ }
22528
+ /**
22529
+ * Get the current media context.
22530
+ * Server-side: Uses AsyncLocalStorage for request isolation.
22531
+ * Client-side: Uses module-level state (safe in single-threaded browser).
22532
+ */
22533
+ function getMediaContext() {
22534
+ const storage = getServerStorage();
22535
+ if (storage) {
22536
+ return storage.getStore() ?? {};
22537
+ }
22538
+ return getClientContextStore();
22539
+ }
22540
+ /**
22541
+ * Run a function with the given media context.
22542
+ * On server: Uses AsyncLocalStorage to isolate context per request.
22543
+ * On client: Temporarily sets module-level context for the duration of the call.
22544
+ *
22545
+ * @example
22546
+ * ```tsx
22547
+ * runWithMediaContext(
22548
+ * { supabaseUrl: 'https://...', siteId: 'abc-123' },
22549
+ * () => renderPage(page)
22550
+ * )
22551
+ * ```
22552
+ */
22553
+ function runWithMediaContext(context, fn) {
22554
+ const storage = getServerStorage();
22555
+ if (storage) {
22556
+ return storage.run(context, fn);
22557
+ }
22558
+ const store = getClientContextStore();
22559
+ const prevSupabaseUrl = store.supabaseUrl;
22560
+ const prevSiteId = store.siteId;
22561
+ const prevMediaAssetIndex = store.mediaAssetIndex;
22562
+ store.supabaseUrl = context.supabaseUrl;
22563
+ store.siteId = context.siteId;
22564
+ store.mediaAssetIndex = context.mediaAssetIndex;
22565
+ try {
22566
+ return fn();
22567
+ } finally {
22568
+ store.supabaseUrl = prevSupabaseUrl;
22569
+ store.siteId = prevSiteId;
22570
+ store.mediaAssetIndex = prevMediaAssetIndex;
22571
+ }
22572
+ }
22573
+ /**
22574
+ * Set the Supabase URL in the current context.
22575
+ * @deprecated Use runWithMediaContext instead for request isolation.
22576
+ */
22577
+ function updateMediaContext(patch) {
22578
+ const storage = getServerStorage();
22579
+ const current = storage?.getStore();
22580
+ if (current) {
22581
+ Object.assign(current, patch);
22582
+ } else if (storage?.enterWith) {
22583
+ storage.enterWith(patch);
22584
+ } else {
22585
+ Object.assign(getClientContextStore(), patch);
22586
+ }
22587
+ }
22588
+ function setContextSupabaseUrl(url) {
22589
+ updateMediaContext({ supabaseUrl: normalizeSupabaseUrl(url) });
22590
+ }
22591
+ /** @deprecated Use runWithMediaContext for request isolation. */
22592
+ function setContextSiteId(siteId) {
22593
+ updateMediaContext({ siteId });
22594
+ }
22595
+ function setContextMediaAssetIndex(index) {
22596
+ updateMediaContext({ mediaAssetIndex: index });
22597
+ }
22598
+ function setContextResolveImageUrlContext(context) {
22599
+ setContextSupabaseUrl(context?.supabaseUrl);
22600
+ setContextSiteId(context?.siteId);
22601
+ setContextMediaAssetIndex(context?.mediaAssetIndex);
22602
+ }
22603
+ function getCurrentResolveImageUrlContext() {
22604
+ const context = getMediaContext();
22605
+ if (!context.supabaseUrl && !context.siteId && !context.mediaAssetIndex) {
22606
+ return undefined;
22607
+ }
22608
+ return {
22609
+ supabaseUrl: context.supabaseUrl,
22610
+ siteId: context.siteId,
22611
+ mediaAssetIndex: context.mediaAssetIndex
22612
+ };
22613
+ }
22614
+ function setContextMediaAssets(assets) {
22615
+ setContextMediaAssetIndex(buildMediaAssetIndex(assets));
22616
+ }
22617
+ /**
22618
+ * Get the Supabase URL for constructing direct storage URLs.
22619
+ * Used for serving images directly from Supabase storage CDN.
22620
+ *
22621
+ * Resolution order:
22622
+ * 1. Context URL (set via runWithMediaContext or setContextSupabaseUrl)
22623
+ * 2. Environment variable NEXT_PUBLIC_SUPABASE_URL
22624
+ *
22625
+ * SDK sites receive the URL from the API, so they don't need the env var.
22626
+ * Dashboard and frontend apps use the env var.
22627
+ */
22628
+ function getSupabaseUrl() {
22629
+ const context = getMediaContext();
22630
+ if (context.supabaseUrl) {
22631
+ return context.supabaseUrl;
22632
+ }
22633
+ const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
22634
+ if (!url) {
22635
+ throw new Error("NEXT_PUBLIC_SUPABASE_URL is not configured. " + "Set it to your Supabase project URL (e.g., https://xxx.supabase.co)");
22636
+ }
22637
+ return url.replace(/\/$/, "");
22638
+ }
22639
+ /**
22640
+ * Get the site ID for constructing storage paths.
22641
+ * Required for relative path resolution.
22642
+ */
22643
+ function getSiteId() {
22644
+ return getMediaContext().siteId;
22645
+ }
22646
+ function getMediaAssetIndex(context) {
22647
+ return context?.mediaAssetIndex ?? getMediaContext().mediaAssetIndex;
22648
+ }
22649
+
22488
22650
  //#endregion
22489
22651
  //#region ../blocks/src/system/media/slotContracts.ts
22652
+ var import_jsx_runtime = /* @__PURE__ */ __toESM(require_jsx_runtime());
22490
22653
  const DEFAULT_MIN_SOURCE_WIDTH = 1200;
22491
22654
  const LARGE_MIN_SOURCE_WIDTH = 1400;
22492
22655
  const SECTION_BACKGROUND_MIN_SOURCE_WIDTH = 1920;
@@ -22969,23 +23132,9 @@ function resolveMediaSlotContract({ blockKind, fieldPath, values, fieldAspectRat
22969
23132
 
22970
23133
  //#endregion
22971
23134
  //#region ../blocks/src/system/runtime/nodes/media.tsx
22972
- var import_jsx_runtime = /* @__PURE__ */ __toESM(require_jsx_runtime());
22973
- function buildMediaAssetIndex(assets) {
22974
- return buildRenderableMediaAssetIndex(assets);
22975
- }
22976
23135
  const MAX_RENDER_DIMENSION = 4096;
22977
23136
  const MAX_SRCSET_WIDTH = 2560;
22978
23137
  const RELATIVE_IMG_PROXY_BASE_PATH = "/api/img";
22979
- function normalizeSupabaseUrl(value) {
22980
- return value?.replace(/\/$/, "");
22981
- }
22982
- function buildResolveImageUrlContext(input) {
22983
- return {
22984
- supabaseUrl: normalizeSupabaseUrl(input?.supabaseUrl),
22985
- siteId: input?.siteId,
22986
- mediaAssetIndex: input?.mediaAssetIndex ?? buildMediaAssetIndex(input?.mediaAssets)
22987
- };
22988
- }
22989
23138
  function getValidSourceDimension(value) {
22990
23139
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
22991
23140
  }
@@ -23122,59 +23271,57 @@ function warnForMediaUrlResolution(result) {
23122
23271
  }
23123
23272
  }
23124
23273
  function resolveMediaStorageUrlResult(value, context, transformOptions) {
23125
- const canonical$1 = resolveMediaWithCanonicalAsset(value, context ?? undefined);
23126
- if (!canonical$1.storagePath || canonical$1.storagePath.length === 0) {
23274
+ const canonical$1 = resolveRuntimeMedia(value, context ?? undefined);
23275
+ if (!canonical$1) return {
23276
+ kind: "missing-storage-path",
23277
+ identifier: value.identifier
23278
+ };
23279
+ return resolveResolvedMediaStorageUrlResult(canonical$1, context, transformOptions);
23280
+ }
23281
+ function resolveDirectStoragePathUrl(asset, supabaseUrl, siteId, transformOptions) {
23282
+ const bucket = asset.storageBucket ?? "media";
23283
+ if (isSiteScopedDirectImageStoragePath(asset.storagePath)) {
23127
23284
  return {
23128
- kind: "missing-storage-path",
23129
- assetId: canonical$1.assetId,
23130
- identifier: canonical$1.identifier
23285
+ kind: "resolved",
23286
+ url: getDirectImageUrlForSiteScopedPath(supabaseUrl, asset.storagePath, bucket, transformOptions)
23131
23287
  };
23132
23288
  }
23133
- const siteId = context?.siteId ?? getSiteId();
23134
- const bucket = canonical$1.storageBucket ?? "media";
23135
- const siteScopedPath = isSiteScopedDirectImageStoragePath(canonical$1.storagePath) ? canonical$1.storagePath : null;
23136
- let supabaseUrl;
23289
+ const relativePath = parseRelativeStoragePath(asset.storagePath);
23290
+ if (!relativePath.ok) return {
23291
+ kind: "invalid-storage-path",
23292
+ storagePath: asset.storagePath
23293
+ };
23294
+ if (!siteId) return {
23295
+ kind: "missing-site-context",
23296
+ storagePath: asset.storagePath
23297
+ };
23298
+ return {
23299
+ kind: "resolved",
23300
+ url: getDirectImageUrlForRelativePath(supabaseUrl, relativePath.value, siteId, bucket, transformOptions)
23301
+ };
23302
+ }
23303
+ function resolveResolvedMediaStorageUrlResult(canonical$1, context, transformOptions) {
23304
+ const storagePath = canonical$1.storagePath;
23305
+ if (!storagePath) return {
23306
+ kind: "missing-storage-path",
23307
+ assetId: canonical$1.assetId,
23308
+ identifier: canonical$1.identifier
23309
+ };
23137
23310
  try {
23138
- supabaseUrl = context?.supabaseUrl?.replace(/\/$/, "") ?? getSupabaseUrl();
23311
+ const supabaseUrl = context?.supabaseUrl?.replace(/\/$/, "") ?? getSupabaseUrl();
23312
+ return resolveDirectStoragePathUrl({
23313
+ ...canonical$1,
23314
+ storagePath
23315
+ }, supabaseUrl, context?.siteId ?? getSiteId(), transformOptions);
23139
23316
  } catch (error$1) {
23140
23317
  return {
23141
23318
  kind: "missing-supabase-url",
23142
23319
  message: error$1 instanceof Error ? error$1.message : "Supabase URL is not configured."
23143
23320
  };
23144
23321
  }
23145
- let directUrl;
23146
- if (siteScopedPath) {
23147
- directUrl = getDirectImageUrlForSiteScopedPath(supabaseUrl, siteScopedPath, bucket, transformOptions);
23148
- } else {
23149
- const relativePath = parseRelativeStoragePath(canonical$1.storagePath);
23150
- if (!relativePath.ok) {
23151
- return {
23152
- kind: "invalid-storage-path",
23153
- storagePath: canonical$1.storagePath
23154
- };
23155
- }
23156
- if (!siteId) {
23157
- return {
23158
- kind: "missing-site-context",
23159
- storagePath: canonical$1.storagePath
23160
- };
23161
- }
23162
- directUrl = getDirectImageUrlForRelativePath(supabaseUrl, relativePath.value, siteId, bucket, transformOptions);
23163
- }
23164
- debugMediaNodeLog("resolve:direct-supabase", {
23165
- storagePath: canonical$1.storagePath,
23166
- siteId,
23167
- bucket,
23168
- directUrl,
23169
- transformOptions
23170
- });
23171
- return {
23172
- kind: "resolved",
23173
- url: directUrl
23174
- };
23175
23322
  }
23176
23323
  function getDirectImageUrlForValue(value, options, context) {
23177
- const result = resolveMediaStorageUrlResult(value, context, buildDirectTransformOptions(options));
23324
+ const result = resolveResolvedMediaStorageUrlResult(value, context, buildDirectTransformOptions(options));
23178
23325
  return result.kind === "resolved" ? result.url : undefined;
23179
23326
  }
23180
23327
  function resolveStorageImageUrl(value, options, context, transformAspectRatio, resolved) {
@@ -23210,202 +23357,6 @@ const ImagePresets = {
23210
23357
  resize: "contain"
23211
23358
  }
23212
23359
  };
23213
- /**
23214
- * Server-side: AsyncLocalStorage for request isolation.
23215
- * Prevents race conditions when multiple requests are processed concurrently.
23216
- *
23217
- * Lazy initialization to avoid issues in environments that don't support async_hooks.
23218
- */
23219
- let _serverStorage = null;
23220
- let _serverStorageChecked = false;
23221
- function getServerStorage() {
23222
- if (typeof window !== "undefined") return null;
23223
- if (_serverStorageChecked) return _serverStorage;
23224
- _serverStorageChecked = true;
23225
- try {
23226
- const globalWithNonWebpackRequire = globalThis;
23227
- const nonWebpackRequire = typeof globalWithNonWebpackRequire.__non_webpack_require__ === "function" ? globalWithNonWebpackRequire.__non_webpack_require__ : new Function("id", "return require(id)");
23228
- const asyncHooks = nonWebpackRequire("async_hooks");
23229
- const AsyncLocalStorage$1 = asyncHooks.AsyncLocalStorage;
23230
- if (AsyncLocalStorage$1) {
23231
- _serverStorage = new AsyncLocalStorage$1();
23232
- return _serverStorage;
23233
- }
23234
- return null;
23235
- } catch {
23236
- if (process.env.NODE_ENV !== "production") {
23237
- console.warn("[blocks] AsyncLocalStorage not available - using module-level state");
23238
- }
23239
- return null;
23240
- }
23241
- }
23242
- /**
23243
- * Client-side context storage.
23244
- * Safe because browsers are single-threaded per tab.
23245
- *
23246
- * IMPORTANT: This must be shared across bundles.
23247
- * SDK preview mode can load multiple independently-bundled entrypoints
23248
- * (e.g. `@riverbankcms/sdk/rendering` + `@riverbankcms/sdk/preview-next/client`),
23249
- * which can otherwise each get their own module-scoped singleton.
23250
- */
23251
- const RB_MEDIA_CONTEXT_KEY = Symbol.for("riverbankcms.blocks.mediaContext");
23252
- function getClientContextStore() {
23253
- const g = globalThis;
23254
- const existing = g[RB_MEDIA_CONTEXT_KEY];
23255
- if (existing && typeof existing === "object") return existing;
23256
- const next = {};
23257
- g[RB_MEDIA_CONTEXT_KEY] = next;
23258
- return next;
23259
- }
23260
- /**
23261
- * Get the current media context.
23262
- * Server-side: Uses AsyncLocalStorage for request isolation.
23263
- * Client-side: Uses module-level state (safe in single-threaded browser).
23264
- */
23265
- function getMediaContext() {
23266
- const storage = getServerStorage();
23267
- if (storage) {
23268
- return storage.getStore() ?? {};
23269
- }
23270
- return getClientContextStore();
23271
- }
23272
- /**
23273
- * Run a function with the given media context.
23274
- * On server: Uses AsyncLocalStorage to isolate context per request.
23275
- * On client: Temporarily sets module-level context for the duration of the call.
23276
- *
23277
- * @example
23278
- * ```tsx
23279
- * runWithMediaContext(
23280
- * { supabaseUrl: 'https://...', siteId: 'abc-123' },
23281
- * () => renderPage(page)
23282
- * )
23283
- * ```
23284
- */
23285
- function runWithMediaContext(context, fn) {
23286
- const storage = getServerStorage();
23287
- if (storage) {
23288
- return storage.run(context, fn);
23289
- }
23290
- const store = getClientContextStore();
23291
- const prevSupabaseUrl = store.supabaseUrl;
23292
- const prevSiteId = store.siteId;
23293
- const prevMediaAssetIndex = store.mediaAssetIndex;
23294
- store.supabaseUrl = context.supabaseUrl;
23295
- store.siteId = context.siteId;
23296
- store.mediaAssetIndex = context.mediaAssetIndex;
23297
- try {
23298
- return fn();
23299
- } finally {
23300
- store.supabaseUrl = prevSupabaseUrl;
23301
- store.siteId = prevSiteId;
23302
- store.mediaAssetIndex = prevMediaAssetIndex;
23303
- }
23304
- }
23305
- /**
23306
- * Set the Supabase URL in the current context.
23307
- * @deprecated Use runWithMediaContext instead for request isolation.
23308
- */
23309
- function setContextSupabaseUrl(url) {
23310
- const normalizedUrl = normalizeSupabaseUrl(url);
23311
- const storage = getServerStorage();
23312
- if (storage) {
23313
- const current = storage.getStore();
23314
- if (current) {
23315
- current.supabaseUrl = normalizedUrl;
23316
- } else {
23317
- if (storage.enterWith) {
23318
- const next = { supabaseUrl: normalizedUrl };
23319
- storage.enterWith(next);
23320
- } else {
23321
- getClientContextStore().supabaseUrl = normalizedUrl;
23322
- }
23323
- }
23324
- } else {
23325
- getClientContextStore().supabaseUrl = normalizedUrl;
23326
- }
23327
- }
23328
- /**
23329
- * Set the site ID in the current context.
23330
- * @deprecated Use runWithMediaContext instead for request isolation.
23331
- */
23332
- function setContextSiteId(siteId) {
23333
- const storage = getServerStorage();
23334
- if (storage) {
23335
- const current = storage.getStore();
23336
- if (current) {
23337
- current.siteId = siteId;
23338
- } else {
23339
- if (storage.enterWith) {
23340
- const next = { siteId };
23341
- storage.enterWith(next);
23342
- } else {
23343
- getClientContextStore().siteId = siteId;
23344
- }
23345
- }
23346
- } else {
23347
- getClientContextStore().siteId = siteId;
23348
- }
23349
- }
23350
- function setContextMediaAssetIndex(index) {
23351
- const storage = getServerStorage();
23352
- if (storage) {
23353
- const current = storage.getStore();
23354
- if (current) {
23355
- current.mediaAssetIndex = index;
23356
- } else {
23357
- if (storage.enterWith) {
23358
- const next = { mediaAssetIndex: index };
23359
- storage.enterWith(next);
23360
- } else {
23361
- getClientContextStore().mediaAssetIndex = index;
23362
- }
23363
- }
23364
- } else {
23365
- getClientContextStore().mediaAssetIndex = index;
23366
- }
23367
- }
23368
- function setContextResolveImageUrlContext(context) {
23369
- setContextSupabaseUrl(context?.supabaseUrl);
23370
- setContextSiteId(context?.siteId);
23371
- setContextMediaAssetIndex(context?.mediaAssetIndex);
23372
- }
23373
- function getCurrentResolveImageUrlContext() {
23374
- const context = getMediaContext();
23375
- if (!context.supabaseUrl && !context.siteId && !context.mediaAssetIndex) {
23376
- return undefined;
23377
- }
23378
- return {
23379
- supabaseUrl: context.supabaseUrl,
23380
- siteId: context.siteId,
23381
- mediaAssetIndex: context.mediaAssetIndex
23382
- };
23383
- }
23384
- function setContextMediaAssets(assets) {
23385
- setContextMediaAssetIndex(buildMediaAssetIndex(assets));
23386
- }
23387
- /**
23388
- * Get the Supabase URL for constructing direct storage URLs.
23389
- * Used for serving images directly from Supabase storage CDN.
23390
- *
23391
- * Resolution order:
23392
- * 1. Context URL (set via runWithMediaContext or setContextSupabaseUrl)
23393
- * 2. Environment variable NEXT_PUBLIC_SUPABASE_URL
23394
- *
23395
- * SDK sites receive the URL from the API, so they don't need the env var.
23396
- * Dashboard and frontend apps use the env var.
23397
- */
23398
- function getSupabaseUrl() {
23399
- const context = getMediaContext();
23400
- if (context.supabaseUrl) {
23401
- return context.supabaseUrl;
23402
- }
23403
- const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
23404
- if (!url) {
23405
- throw new Error("NEXT_PUBLIC_SUPABASE_URL is not configured. " + "Set it to your Supabase project URL (e.g., https://xxx.supabase.co)");
23406
- }
23407
- return url.replace(/\/$/, "");
23408
- }
23409
23360
  function resolveDashboardOrigin(raw) {
23410
23361
  if (!raw) return undefined;
23411
23362
  const trimmed = raw.trim();
@@ -23425,51 +23376,41 @@ function getImageProxyBasePath() {
23425
23376
  if (!dashboardOrigin) return RELATIVE_IMG_PROXY_BASE_PATH;
23426
23377
  return `${dashboardOrigin}${RELATIVE_IMG_PROXY_BASE_PATH}`;
23427
23378
  }
23428
- /**
23429
- * Get the site ID for constructing storage paths.
23430
- * Required for relative path resolution.
23431
- */
23432
- function getSiteId() {
23433
- return getMediaContext().siteId;
23434
- }
23435
- function getMediaAssetIndex(context) {
23436
- return context?.mediaAssetIndex ?? getMediaContext().mediaAssetIndex;
23379
+ /** Resolve portable content without exposing runtime metadata as saved values. */
23380
+ function resolveMediaWithContext(reference, context) {
23381
+ return resolveManagedMediaReference(reference, getMediaAssetIndex(context ?? undefined));
23437
23382
  }
23438
- function resolveCanonicalMediaAsset(value, context) {
23439
- const index = getMediaAssetIndex(context);
23440
- if (!index) return undefined;
23441
- if (value.assetId) {
23442
- const hit = index.byId.get(value.assetId);
23443
- if (hit) return hit;
23444
- }
23445
- const identifier = typeof value.identifier === "string" ? value.identifier.trim() : "";
23446
- if (identifier) {
23447
- const hit = index.byIdentifier.get(identifier);
23448
- if (hit) return hit;
23449
- }
23450
- return undefined;
23451
- }
23452
- function resolveMediaWithCanonicalAsset(value, context) {
23453
- const asset = resolveCanonicalMediaAsset(value, context);
23454
- if (!asset) return value;
23455
- return attachRenderableMediaAssetFields(value, asset);
23383
+ function sourceFromAsset(value, asset) {
23384
+ return {
23385
+ type: value.type,
23386
+ alt: value.alt,
23387
+ filename: value.filename,
23388
+ purpose: value.purpose,
23389
+ placeholder: value.placeholder,
23390
+ transform: value.transform,
23391
+ poster: value.poster,
23392
+ identifier: asset.identifier,
23393
+ assetId: asset.id,
23394
+ storageBucket: asset.storageBucket,
23395
+ storagePath: asset.storagePath,
23396
+ mimeType: asset.mimeType,
23397
+ width: asset.width,
23398
+ height: asset.height
23399
+ };
23400
+ }
23401
+ function resolveRuntimeMedia(value, context) {
23402
+ if ("asset" in value && value.asset) return sourceFromAsset(value, value.asset);
23403
+ if ("src" in value && value.src) return value;
23404
+ if (!value.identifier) return undefined;
23405
+ const resolved = resolveMediaWithContext(value, context);
23406
+ return resolved.kind === "resolved" ? sourceFromAsset(resolved.reference, resolved.asset) : undefined;
23456
23407
  }
23457
23408
  function resolveVideoPosterUrl(value, context) {
23458
- if (value.type !== "video") return undefined;
23459
- const poster = value.poster;
23460
- if (!poster) return undefined;
23461
- switch (poster.tag) {
23462
- case "external-src": return poster.src;
23463
- case "storage": return resolveMediaStorageUrl({
23464
- type: "image",
23465
- assetId: poster.assetId,
23466
- storageBucket: poster.storageBucket,
23467
- storagePath: poster.storagePath
23468
- }, context);
23469
- }
23470
- }
23471
- function resolveMediaWithContext(value, context) {
23472
- return resolveMediaWithCanonicalAsset(value, context ?? undefined);
23409
+ if (value.type !== "video" || !value.poster) return undefined;
23410
+ return value.poster.tag === "external-src" ? value.poster.src : resolveMediaStorageUrl({
23411
+ type: "image",
23412
+ identifier: value.poster.identifier
23413
+ }, context);
23473
23414
  }
23474
23415
  const debugMediaNodeLog = (...args) => {
23475
23416
  if (typeof window === "undefined") return;
@@ -23552,7 +23493,7 @@ function renderVideo(value, className, style, context, options = {}) {
23552
23493
  });
23553
23494
  }
23554
23495
  function resolvePublicMediaUrl(value, context) {
23555
- return resolveMediaStorageUrl(value, context) ?? value.src;
23496
+ return resolveMediaStorageUrl(value, context) ?? ("src" in value ? value.src : undefined);
23556
23497
  }
23557
23498
  function renderAudio(value, className, style, context) {
23558
23499
  if (value.type !== "audio") return null;
@@ -23567,44 +23508,44 @@ function renderAudio(value, className, style, context) {
23567
23508
  "aria-label": value.alt ?? "Audio"
23568
23509
  });
23569
23510
  }
23570
- function computeMediaTransformStyle(value, style, targetAspectRatio, options) {
23511
+ function usesProxyFraming(source, transform) {
23512
+ if (!source?.assetId || !isExplicitCropProxyEnabled()) return false;
23513
+ return Boolean(transform.rotation) || isExplicitRectCrop(transform.rect, getValidSourceDimension(source.width), getValidSourceDimension(source.height));
23514
+ }
23515
+ function rectFramingPatch(source, rect, proxy, style) {
23516
+ if (!source || !rect || proxy) return {};
23517
+ const patch = buildCssRectStylePatch(source, rect);
23518
+ return patch ? applyRectTransform(style, patch) : {};
23519
+ }
23520
+ function hotspotFramingPatch(transform, proxy, rectPatch, style) {
23521
+ if (!transform.hotspot || rectPatch.objectPosition !== undefined) return {};
23522
+ const fit = style?.objectFit;
23523
+ if (fit && fit !== "cover" && fit !== "contain") return {};
23524
+ const point = proxy && transform.rotation ? rotateNormalizedPoint(transform.hotspot, transform.rotation) : transform.hotspot;
23525
+ return { objectPosition: `${point.x * 100}% ${point.y * 100}%` };
23526
+ }
23527
+ function rotationFramingPatch(rotation, proxy, rectPatch, style) {
23528
+ if (!rotation || proxy) return {};
23529
+ return {
23530
+ transform: appendTransform(rectPatch.transform ?? style?.transform, `rotate(${rotation}deg)`),
23531
+ transformOrigin: rectPatch.transformOrigin ?? "center"
23532
+ };
23533
+ }
23534
+ /** CSS framing is a pure projection of the resolved source and per-use transform. */
23535
+ function deriveMediaFramingStyle(source, transform, proxy, style) {
23536
+ if (!transform.rect && !transform.hotspot && !transform.rotation) return style;
23537
+ const rectPatch = rectFramingPatch(source, transform.rect, proxy, style);
23538
+ return mergeStyles(style, {
23539
+ ...rectPatch,
23540
+ ...hotspotFramingPatch(transform, proxy, rectPatch, style),
23541
+ ...rotationFramingPatch(transform.rotation, proxy, rectPatch, style)
23542
+ });
23543
+ }
23544
+ function computeMediaTransformStyle(value, style, targetAspectRatio, options, context) {
23545
+ const source = resolveRuntimeMedia(value, context ?? getCurrentResolveImageUrlContext());
23571
23546
  const transform = options?.resolvedTransform ?? resolveMediaTransformForAspect(value.transform, targetAspectRatio);
23572
- const rect = transform.rect;
23573
- const hotspot = transform.hotspot;
23574
- const rotation = transform.rotation;
23575
- if (!rect && !hotspot && !rotation) return style;
23576
- const stylePatch = {};
23577
- const heuristicSuppressCss = Boolean(isExplicitCropProxyEnabled() && value.assetId && (typeof rotation === "number" && rotation !== 0 || isExplicitRectCrop(rect, getValidSourceDimension(value.width), getValidSourceDimension(value.height))));
23578
- const shouldSuppressCss = options?.isProxy ?? heuristicSuppressCss;
23579
- if (rect && !shouldSuppressCss) {
23580
- const rectPatch = buildCssRectStylePatch(value, rect);
23581
- if (rectPatch) {
23582
- const mergedRect = applyRectTransform(style, rectPatch);
23583
- Object.assign(stylePatch, mergedRect);
23584
- }
23585
- }
23586
- if (hotspot) {
23587
- const effectiveObjectFit = stylePatch.objectFit ?? style?.objectFit;
23588
- const shouldApplyHotspot = !effectiveObjectFit || effectiveObjectFit === "cover" || effectiveObjectFit === "contain";
23589
- if (shouldApplyHotspot && stylePatch.objectPosition === undefined) {
23590
- const resolved = shouldSuppressCss && rotation ? rotateNormalizedPoint({
23591
- x: hotspot.x,
23592
- y: hotspot.y
23593
- }, rotation) : {
23594
- x: hotspot.x,
23595
- y: hotspot.y
23596
- };
23597
- stylePatch.objectPosition = `${resolved.x * 100}% ${resolved.y * 100}%`;
23598
- }
23599
- }
23600
- if (rotation && !shouldSuppressCss) {
23601
- const existingTransform = stylePatch.transform ?? style?.transform;
23602
- stylePatch.transform = existingTransform ? `${existingTransform} rotate(${rotation}deg)` : `rotate(${rotation}deg)`;
23603
- if (!stylePatch.transformOrigin) {
23604
- stylePatch.transformOrigin = "center";
23605
- }
23606
- }
23607
- return mergeStyles(style, stylePatch);
23547
+ const proxy = options?.isProxy ?? usesProxyFraming(source, transform);
23548
+ return deriveMediaFramingStyle(source, transform, proxy, style);
23608
23549
  }
23609
23550
  const computeHotspotStyle = computeMediaTransformStyle;
23610
23551
  function resolveTargetAspectRatio(size) {
@@ -23649,7 +23590,7 @@ const MediaNode = ({ "data-slot": dataSlot, "data-surface": dataSurface, value,
23649
23590
  src: imageUrl,
23650
23591
  alt: value.alt ?? "",
23651
23592
  className,
23652
- style: computeMediaTransformStyle(value, style, transformAspectRatio),
23593
+ style: computeMediaTransformStyle(value, style, transformAspectRatio, undefined, resolvedImageContext),
23653
23594
  loading,
23654
23595
  fetchPriority,
23655
23596
  decoding: "async"
@@ -23700,9 +23641,13 @@ function resolveImageUrlWithContextResult(value, options, context, transformAspe
23700
23641
  kind: "resolved",
23701
23642
  url
23702
23643
  };
23703
- const canonical$1 = resolveMediaWithCanonicalAsset(value, context ?? undefined);
23704
- if (canonical$1.storagePath && canonical$1.storagePath.length > 0) {
23705
- return resolveMediaStorageUrlResult(canonical$1, context, buildDirectTransformOptions(options));
23644
+ const canonical$1 = resolveRuntimeMedia(value, context ?? undefined);
23645
+ if (!canonical$1) return {
23646
+ kind: "missing-image-url",
23647
+ identifier: value.identifier
23648
+ };
23649
+ if (canonical$1.storagePath) {
23650
+ return resolveResolvedMediaStorageUrlResult(canonical$1, context, buildDirectTransformOptions(options));
23706
23651
  }
23707
23652
  return {
23708
23653
  kind: "missing-image-url",
@@ -23712,7 +23657,11 @@ function resolveImageUrlWithContextResult(value, options, context, transformAspe
23712
23657
  }
23713
23658
  function resolveImageUrlWithContextInternal(value, options, context, transformAspectRatio, resolved) {
23714
23659
  if (value.type !== "image") return undefined;
23715
- const canonical$1 = resolveMediaWithCanonicalAsset(value, context);
23660
+ const canonical$1 = resolveRuntimeMedia(value, context);
23661
+ if (!canonical$1) return undefined;
23662
+ return resolveImageUrlForSource(canonical$1, options, context, transformAspectRatio, resolved);
23663
+ }
23664
+ function resolveImageUrlForSource(canonical$1, options, context, transformAspectRatio, resolved) {
23716
23665
  debugMediaNodeLog("resolveImageUrl input", {
23717
23666
  assetId: canonical$1.assetId,
23718
23667
  storagePath: canonical$1.storagePath,
@@ -23730,86 +23679,79 @@ function resolveImageUrlWithContextInternal(value, options, context, transformAs
23730
23679
  debugMediaNodeLog("resolve:explicit-src", { src: canonical$1.src });
23731
23680
  return canonical$1.src;
23732
23681
  }
23733
- const legacyUrl = typeof canonical$1 === "object" && canonical$1 !== null ? Reflect.get(canonical$1, "url") : undefined;
23734
- debugMediaNodeLog("resolve:fallback-url", { fallbackUrl: typeof legacyUrl === "string" ? legacyUrl : null });
23735
- return typeof legacyUrl === "string" ? legacyUrl : undefined;
23682
+ return undefined;
23736
23683
  }
23737
- function resolveImageSourceSetWithContext(value, options, context) {
23738
- const normalizedContext = context ?? undefined;
23739
- if (value.type !== "image") return undefined;
23740
- const canonical$1 = resolveMediaWithCanonicalAsset(value, normalizedContext);
23741
- const widthCandidates = normalizeWidthCandidates(options.widthCandidates, MAX_SRCSET_WIDTH);
23742
- if (widthCandidates.length === 0) return undefined;
23684
+ function deriveResponsiveMediaPlan(source, options) {
23743
23685
  const targetAspectRatio = getPositiveAspectRatio(options.targetAspectRatio);
23744
- const quality = options.quality;
23745
- const resize = options.resize;
23746
- const resolvedTransform = resolveMediaTransformForAspect(canonical$1.transform, targetAspectRatio);
23747
- const sourceWidth = getValidSourceDimension(canonical$1.width);
23748
- const sourceHeight = getValidSourceDimension(canonical$1.height);
23749
- const hasExplicitRectCrop = isExplicitRectCrop(resolvedTransform.rect, sourceWidth, sourceHeight);
23686
+ const transform = resolveTransformResolution(source, targetAspectRatio);
23687
+ const explicitRect = isExplicitRectCrop(transform.resolvedTransform.rect, transform.sourceWidth, transform.sourceHeight);
23750
23688
  const coverFactor = resolveCoverFactor({
23751
- resize,
23689
+ resize: options.resize,
23752
23690
  targetAspectRatio,
23753
- hasExplicitRectCrop,
23754
- sourceWidth,
23755
- sourceHeight
23756
- });
23757
- const shouldProxy = Boolean(isExplicitCropProxyEnabled() && canonical$1.assetId && (hasExplicitRectCrop || typeof resolvedTransform.rotation === "number" && resolvedTransform.rotation !== 0));
23758
- const effectiveSizes = coverFactor > 1 && typeof options.sizes === "string" && options.sizes.length > 0 ? scaleSizesAttribute(options.sizes, coverFactor) : options.sizes;
23759
- const srcSetParts = widthCandidates.map((width) => {
23760
- const height = shouldProxy && hasExplicitRectCrop ? getHeightForAspect(width, targetAspectRatio) : undefined;
23761
- const effectiveResize = height ? resize : "contain";
23762
- const url = resolveImageUrlWithContextInternal(canonical$1, height ? {
23763
- width,
23764
- height,
23765
- resize: effectiveResize,
23766
- quality
23767
- } : {
23768
- width,
23769
- resize: effectiveResize,
23770
- quality
23771
- }, normalizedContext, targetAspectRatio, {
23772
- resolvedTransform,
23773
- sourceWidth,
23774
- sourceHeight
23775
- });
23776
- if (!url) return null;
23777
- return `${url} ${width}w`;
23778
- }).filter((entry) => entry !== null);
23779
- if (srcSetParts.length === 0) return undefined;
23780
- const fallbackWidth = widthCandidates[Math.min(2, widthCandidates.length - 1)];
23781
- if (fallbackWidth === undefined) return undefined;
23782
- const defaultWidth = options.defaultWidth ?? fallbackWidth;
23783
- const scaledDefaultWidth = coverFactor > 1 ? Math.round(defaultWidth * coverFactor) : defaultWidth;
23784
- const nearestWidth = widthCandidates.find((candidate) => candidate >= scaledDefaultWidth) ?? widthCandidates[widthCandidates.length - 1];
23785
- if (nearestWidth === undefined) return undefined;
23786
- const defaultHeight = shouldProxy && hasExplicitRectCrop ? getHeightForAspect(nearestWidth, targetAspectRatio) : undefined;
23787
- const effectiveDefaultResize = defaultHeight ? resize : "contain";
23788
- const src = resolveImageUrlWithContextInternal(canonical$1, defaultHeight ? {
23789
- width: nearestWidth,
23790
- height: defaultHeight,
23791
- resize: effectiveDefaultResize,
23792
- quality
23793
- } : {
23794
- width: nearestWidth,
23795
- resize: effectiveDefaultResize,
23796
- quality
23797
- }, normalizedContext, targetAspectRatio, {
23798
- resolvedTransform,
23799
- sourceWidth,
23800
- sourceHeight
23691
+ hasExplicitRectCrop: explicitRect,
23692
+ sourceWidth: transform.sourceWidth,
23693
+ sourceHeight: transform.sourceHeight
23801
23694
  });
23802
- if (!src) return undefined;
23803
- const fallbackSrc = shouldProxy ? getDirectImageUrlForValue(canonical$1, {
23804
- width: nearestWidth,
23695
+ return {
23696
+ widthCandidates: normalizeWidthCandidates(options.widthCandidates, MAX_SRCSET_WIDTH),
23697
+ sizes: scaledResponsiveSizes(options.sizes, coverFactor),
23698
+ targetAspectRatio,
23699
+ quality: options.quality,
23700
+ resize: options.resize,
23701
+ transform,
23702
+ proxy: usesProxyFraming(source, transform.resolvedTransform),
23703
+ explicitRect,
23704
+ coverFactor
23705
+ };
23706
+ }
23707
+ function scaledResponsiveSizes(sizes, factor) {
23708
+ return sizes && factor > 1 ? scaleSizesAttribute(sizes, factor) : sizes;
23709
+ }
23710
+ function responsiveMediaOptions(width, plan) {
23711
+ const height = plan.proxy && plan.explicitRect ? getHeightForAspect(width, plan.targetAspectRatio) : undefined;
23712
+ return height ? {
23713
+ width,
23714
+ height,
23715
+ resize: plan.resize,
23716
+ quality: plan.quality
23717
+ } : {
23718
+ width,
23805
23719
  resize: "contain",
23806
- quality
23807
- }, normalizedContext) : undefined;
23720
+ quality: plan.quality
23721
+ };
23722
+ }
23723
+ function defaultResponsiveWidth(plan, requested) {
23724
+ const fallback = plan.widthCandidates[Math.min(2, plan.widthCandidates.length - 1)];
23725
+ if (fallback === undefined) return undefined;
23726
+ const target = Math.round((requested ?? fallback) * plan.coverFactor);
23727
+ return plan.widthCandidates.find((candidate) => candidate >= target) ?? plan.widthCandidates.at(-1);
23728
+ }
23729
+ function responsiveSourceSet(source, plan, context) {
23730
+ return plan.widthCandidates.flatMap((width) => {
23731
+ const url = resolveImageUrlForSource(source, responsiveMediaOptions(width, plan), context, plan.targetAspectRatio, plan.transform);
23732
+ return url ? [`${url} ${width}w`] : [];
23733
+ }).join(", ");
23734
+ }
23735
+ function resolveImageSourceSetWithContext(value, options, context) {
23736
+ if (value.type !== "image") return undefined;
23737
+ const source = resolveRuntimeMedia(value, context ?? undefined);
23738
+ if (!source) return undefined;
23739
+ const plan = deriveResponsiveMediaPlan(source, options);
23740
+ const width = defaultResponsiveWidth(plan, options.defaultWidth);
23741
+ if (width === undefined) return undefined;
23742
+ const srcSet = responsiveSourceSet(source, plan, context ?? undefined);
23743
+ if (!srcSet) return undefined;
23744
+ const src = resolveImageUrlForSource(source, responsiveMediaOptions(width, plan), context ?? undefined, plan.targetAspectRatio, plan.transform);
23745
+ if (!src) return undefined;
23808
23746
  return {
23809
23747
  src,
23810
- srcSet: srcSetParts.join(", "),
23811
- sizes: effectiveSizes,
23812
- fallbackSrc
23748
+ srcSet,
23749
+ sizes: plan.sizes,
23750
+ fallbackSrc: plan.proxy ? getDirectImageUrlForValue(source, {
23751
+ width,
23752
+ resize: "contain",
23753
+ quality: plan.quality
23754
+ }, context ?? undefined) : undefined
23813
23755
  };
23814
23756
  }
23815
23757
  function resolveCoverFactor(input) {
@@ -25950,40 +25892,17 @@ function getAnchorClasses(position) {
25950
25892
  return POSITION_TO_ANCHOR_CLASSES[normalized] ?? DEFAULT_ANCHOR_CLASSES;
25951
25893
  }
25952
25894
 
25953
- //#endregion
25954
- //#region ../blocks/src/lib/media.ts
25955
- const MEDIA_TYPE_DISCRIMINANTS = mediaTypeDiscriminants;
25956
- const PUBLIC_DOWNLOAD_MEDIA_TYPES = [
25957
- "document",
25958
- "spreadsheet",
25959
- "archive",
25960
- "audio"
25961
- ];
25962
- function isMediaTypeDiscriminant(value) {
25963
- return typeof value === "string" && MEDIA_TYPE_DISCRIMINANTS.includes(value);
25964
- }
25965
- function mediaTypeDiscriminantFromMimeType(mimeType) {
25966
- const classified = classifyKnownMimeType(mimeType);
25967
- if (!classified.ok) return null;
25968
- switch (classified.value.tag) {
25969
- case "image":
25970
- case "video":
25971
- case "audio":
25972
- case "document":
25973
- case "spreadsheet":
25974
- case "archive": return classified.value.tag;
25975
- case "font": return null;
25976
- }
25977
- }
25978
-
25979
25895
  //#endregion
25980
25896
  //#region ../blocks/src/system/helpers/backgroundMedia.ts
25981
25897
  function resolveBackgroundMedia(input) {
25982
- const parsedMedia = mediaSchema.safeParse(input.image);
25898
+ const parsedMedia = runtimeMediaSchema.safeParse(input.image);
25983
25899
  if (!parsedMedia.success) return null;
25984
25900
  switch (parsedMedia.data.type) {
25985
25901
  case "image":
25986
- case "video": return parsedMedia.data;
25902
+ case "video": return {
25903
+ ...parsedMedia.data,
25904
+ type: parsedMedia.data.type
25905
+ };
25987
25906
  case "audio":
25988
25907
  case "document":
25989
25908
  case "spreadsheet":
@@ -26196,11 +26115,11 @@ const backgroundTransforms = [
26196
26115
  resolveOverlayStyleTransform
26197
26116
  ];
26198
26117
  function parseMediaBackground(value) {
26199
- const background = parseBackgroundContent(value);
26118
+ const background = parseRuntimeBackgroundContent(value);
26200
26119
  return background?.type === "image" || background?.type === "video" ? background : null;
26201
26120
  }
26202
26121
  function resolveBackgroundLayerStyle(value, fallbackToken, context) {
26203
- const background = parseBackgroundContent(value);
26122
+ const background = parseRuntimeBackgroundContent(value);
26204
26123
  const style = {};
26205
26124
  const gradient = background?.type === "gradient" ? isString$2(background.gradient) ? background.gradient.trim() : gradientPresetCss(background.gradientPresetId) : null;
26206
26125
  const color = background?.type === "color" && isString$2(background.color) ? background.color.trim() : null;
@@ -27765,7 +27684,7 @@ const publicEventBaseSchema = z.object({
27765
27684
  content: z.object({ body: RichTextDocSchema.nullable().optional() }).optional(),
27766
27685
  presentation: z.object({
27767
27686
  summary: z.string().nullable().optional(),
27768
- image: mediaSchema.nullable().optional()
27687
+ image: runtimeMediaSchema.nullable().optional()
27769
27688
  }).optional(),
27770
27689
  slug: z.string(),
27771
27690
  path: z.string().nullable(),
@@ -28805,6 +28724,49 @@ function renderMarks(text$1, marks, key, linkTarget) {
28805
28724
  }
28806
28725
  }, text$1);
28807
28726
  }
28727
+ function richTextImageOptions(width, height) {
28728
+ if (width) return {
28729
+ width,
28730
+ resize: "contain",
28731
+ quality: 85
28732
+ };
28733
+ if (height) return {
28734
+ height,
28735
+ resize: "contain",
28736
+ quality: 85
28737
+ };
28738
+ return ImagePresets.full;
28739
+ }
28740
+ function resolveRichTextImageSource(attrs, width, height, context) {
28741
+ if (attrs.identifier !== undefined && attrs.identifier !== null) {
28742
+ const parsed = parseCanonicalMediaIdentifier(attrs.identifier);
28743
+ if (!parsed.ok) return undefined;
28744
+ if (context?.mediaAssetIndex) {
28745
+ return resolveImageUrlWithContext({
28746
+ type: "image",
28747
+ identifier: parsed.value
28748
+ }, richTextImageOptions(width, height), context);
28749
+ }
28750
+ return typeof attrs.src === "string" ? attrs.src.trim() || undefined : undefined;
28751
+ }
28752
+ return typeof attrs.src === "string" ? attrs.src.trim() || undefined : undefined;
28753
+ }
28754
+ function renderRichTextImage(node, key, context) {
28755
+ const attrs = node.attrs ?? {};
28756
+ const width = parseDimension(attrs.width);
28757
+ const height = parseDimension(attrs.height);
28758
+ const src = resolveRichTextImageSource(attrs, width, height, context);
28759
+ if (!src) return null;
28760
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
28761
+ src,
28762
+ alt: typeof attrs.alt === "string" ? attrs.alt : "",
28763
+ title: typeof attrs.title === "string" && attrs.title.trim() ? attrs.title : undefined,
28764
+ width,
28765
+ height,
28766
+ loading: "lazy",
28767
+ decoding: "async"
28768
+ }, key);
28769
+ }
28808
28770
  function renderDoc(node, key, imageResolveContext, linkTarget) {
28809
28771
  if (!node || !node.type) return null;
28810
28772
  const children = node.content?.map((child, index) => renderDoc(child, `${key}-${index}`, imageResolveContext, linkTarget));
@@ -28824,37 +28786,7 @@ function renderDoc(node, key, imageResolveContext, linkTarget) {
28824
28786
  case "blockquote": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("blockquote", { children }, key);
28825
28787
  case "horizontalRule": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", {}, key);
28826
28788
  case "hardBreak": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}, key);
28827
- case "image": {
28828
- const attrs = node.attrs ?? {};
28829
- const src = typeof attrs.src === "string" ? attrs.src.trim() : "";
28830
- const identifier = typeof attrs.identifier === "string" ? attrs.identifier.trim() : "";
28831
- const alt = typeof attrs.alt === "string" ? attrs.alt : "";
28832
- const title = typeof attrs.title === "string" && attrs.title.trim().length > 0 ? attrs.title : undefined;
28833
- const width = parseDimension(attrs.width);
28834
- const height = parseDimension(attrs.height);
28835
- const resolvedSrc = src || (identifier ? resolveImageUrlWithContext({
28836
- type: "image",
28837
- identifier
28838
- }, width ? {
28839
- width,
28840
- resize: "contain",
28841
- quality: 85
28842
- } : height ? {
28843
- height,
28844
- resize: "contain",
28845
- quality: 85
28846
- } : ImagePresets.full, imageResolveContext ?? undefined) ?? "" : "");
28847
- if (!resolvedSrc) return null;
28848
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
28849
- src: resolvedSrc,
28850
- alt,
28851
- title,
28852
- width,
28853
- height,
28854
- loading: "lazy",
28855
- decoding: "async"
28856
- }, key);
28857
- }
28789
+ case "image": return renderRichTextImage(node, key, imageResolveContext);
28858
28790
  case "text": return renderMarks(node.text ?? "", node.marks, key, linkTarget);
28859
28791
  default: return null;
28860
28792
  }
@@ -30930,7 +30862,7 @@ const MediaNodeServer = ({ value, "data-slot": dataSlot, "data-surface": dataSur
30930
30862
  const computedStyle = computeMediaTransformStyle(value, style, transformAspectRatio, {
30931
30863
  resolvedTransform,
30932
30864
  isProxy
30933
- });
30865
+ }, imageResolveContext);
30934
30866
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
30935
30867
  ...mediaImageHostProps({
30936
30868
  value,
@@ -30946,6 +30878,32 @@ const MediaNodeServer = ({ value, "data-slot": dataSlot, "data-surface": dataSur
30946
30878
  });
30947
30879
  };
30948
30880
 
30881
+ //#endregion
30882
+ //#region ../blocks/src/lib/media.ts
30883
+ const MEDIA_TYPE_DISCRIMINANTS = mediaTypeDiscriminants;
30884
+ const PUBLIC_DOWNLOAD_MEDIA_TYPES = [
30885
+ "document",
30886
+ "spreadsheet",
30887
+ "archive",
30888
+ "audio"
30889
+ ];
30890
+ function isMediaTypeDiscriminant(value) {
30891
+ return typeof value === "string" && MEDIA_TYPE_DISCRIMINANTS.includes(value);
30892
+ }
30893
+ function mediaTypeDiscriminantFromMimeType(mimeType) {
30894
+ const classified = classifyKnownMimeType(mimeType);
30895
+ if (!classified.ok) return null;
30896
+ switch (classified.value.tag) {
30897
+ case "image":
30898
+ case "video":
30899
+ case "audio":
30900
+ case "document":
30901
+ case "spreadsheet":
30902
+ case "archive": return classified.value.tag;
30903
+ case "font": return null;
30904
+ }
30905
+ }
30906
+
30949
30907
  //#endregion
30950
30908
  //#region ../blocks/src/system/runtime/nodes/file-download.tsx
30951
30909
  function isDownloadableMediaType(type) {
@@ -30984,7 +30942,7 @@ function parseButtonVariant(value) {
30984
30942
  }
30985
30943
  function FileDownloadNode({ value, title, description, buttonLabel, buttonVariant, className }) {
30986
30944
  if (!value || !isDownloadableMediaType(value.type)) return null;
30987
- const href = resolveMediaStorageUrl(value) ?? value.src;
30945
+ const href = resolvePublicMediaUrl(value);
30988
30946
  if (!href) return null;
30989
30947
  const filename = displayFilename(value);
30990
30948
  const heading = title?.trim() || filename;
@@ -32927,7 +32885,7 @@ const publicPricingSchema = z.object({
32927
32885
  });
32928
32886
  const publicAppointmentServiceSchema = z.object({
32929
32887
  id: z.string().min(1),
32930
- image: mediaSchema.nullable().optional(),
32888
+ image: runtimeMediaSchema.nullable().optional(),
32931
32889
  slug: z.string().min(1).optional(),
32932
32890
  title: z.string(),
32933
32891
  description: z.string().nullable().optional(),
@@ -64745,7 +64703,8 @@ function validationContext(options = {}) {
64745
64703
  const isDraft = options.mode === "draft";
64746
64704
  return {
64747
64705
  allowNull: options.allowNull ?? true,
64748
- allowIncomplete: isDraft || (options.allowIncomplete ?? false)
64706
+ allowIncomplete: isDraft || (options.allowIncomplete ?? false),
64707
+ mode: options.mode ?? "strict"
64749
64708
  };
64750
64709
  }
64751
64710
  function strictValidationContext(options = {}) {
@@ -65212,7 +65171,7 @@ function validateNormalizedFieldValue(plan, value, ctx) {
65212
65171
  case "select": return validateSelectPlan(plan, value);
65213
65172
  case "richText": return isValidRichTextDoc(value) ? [] : [issue(plan, "invalidRichText")];
65214
65173
  case "inlineText": return validateInlineTextPlan(plan, value);
65215
- case "media": return isPlainObject$2(value) && mediaIdentifierSchema.safeParse(value.identifier).success && (value.type === undefined || typeof value.type === "string" && plan.allowedMediaTypes.includes(value.type)) ? [] : [issue(plan, "invalidMedia")];
65174
+ case "media": return validateMediaPlan(plan, value, ctx);
65216
65175
  case "link": return linkSchema.safeParse(value).success ? [] : [issue(plan, "invalidLink")];
65217
65176
  case "repeater": return validateRepeaterPlan(plan, value, ctx);
65218
65177
  case "group": return validateGroupPlan(plan, value, ctx);
@@ -65220,6 +65179,15 @@ function validateNormalizedFieldValue(plan, value, ctx) {
65220
65179
  default: return assertNever$5(plan);
65221
65180
  }
65222
65181
  }
65182
+ function validateMediaPlan(plan, value, ctx) {
65183
+ if (!isPlainObject$2(value)) return [issue(plan, "invalidMedia")];
65184
+ const allowedKind = value.type === undefined || typeof value.type === "string" && plan.allowedMediaTypes.includes(value.type);
65185
+ const admitted = ctx.mode === "render" ? runtimeMediaSchema.safeParse({
65186
+ ...value,
65187
+ type: value.type ?? plan.allowedMediaTypes[0]
65188
+ }).success : mediaIdentifierSchema.safeParse(value.identifier).success;
65189
+ return allowedKind && admitted ? [] : [issue(plan, "invalidMedia")];
65190
+ }
65223
65191
  function shouldRequireValue(plan, value, ctx) {
65224
65192
  if (!plan.required || ctx.allowIncomplete) return false;
65225
65193
  if (value === null && ctx.allowNull) return false;
@@ -65354,7 +65322,7 @@ function validateGroupPlan(plan, value, ctx) {
65354
65322
  const childCtx = childValidationContext(plan, ctx);
65355
65323
  const childIssues = selectedGroupChildPlans(plan, value).flatMap((childPlan) => validateNormalizedFieldValue(childPlan, value[childPlan.fieldId], childCtx));
65356
65324
  if (childIssues.length > 0) return childIssues;
65357
- if (plan.valueContract === "boxBackground" && !boxBackgroundSchema.safeParse(value).success) {
65325
+ if (plan.valueContract === "boxBackground" && !(ctx.mode === "render" ? runtimeBoxBackgroundSchema : boxBackgroundSchema).safeParse(value).success) {
65358
65326
  return [issue(plan, "invalidBoxBackground")];
65359
65327
  }
65360
65328
  return [];
@@ -65462,13 +65430,16 @@ function fieldPlanToObjectPropertyZod(plan, options = {}) {
65462
65430
  default: return assertNever$5(presence);
65463
65431
  }
65464
65432
  }
65465
- /** Validate stored field values without applying editor/write normalization. */
65466
- function fieldPlanToStoredObjectPropertyZod(plan) {
65467
- const ctx = strictValidationContext({ allowNull: false });
65433
+ /** Validate stored or runtime fields without applying editor/write normalization. */
65434
+ function fieldPlanToStrictObjectPropertyZod(plan, mode = "strict") {
65435
+ const ctx = strictValidationContext({
65436
+ allowNull: false,
65437
+ mode
65438
+ });
65468
65439
  const schema = z.any().superRefine((value, zodCtx) => {
65469
- for (const validationIssue of validateNormalizedFieldValue(plan, value, ctx)) {
65440
+ validateNormalizedFieldValue(plan, value, ctx).forEach((validationIssue) => {
65470
65441
  addFieldIssueToZodContext(zodCtx, validationIssue, plan.path);
65471
- }
65442
+ });
65472
65443
  });
65473
65444
  return plan.required ? schema : schema.optional();
65474
65445
  }
@@ -65759,7 +65730,7 @@ function deriveContentZodFromManifest(manifestOrFields, options = {}) {
65759
65730
  function compileManifestContentContract(manifestOrFields) {
65760
65731
  const plans = derivePlansFromManifestOrFields(manifestOrFields);
65761
65732
  const strictOptions = { allowNull: false };
65762
- const strictStoredSchema = deriveStrictStoredZodFromPlans(plans);
65733
+ const strictStoredSchema = deriveStrictContentZodFromPlans(plans);
65763
65734
  return Object.freeze({ [compiledManifestContentContract]: Object.freeze({
65764
65735
  plans,
65765
65736
  strictStoredSchema,
@@ -65769,7 +65740,7 @@ function compileManifestContentContract(manifestOrFields) {
65769
65740
  allowIncomplete: true,
65770
65741
  mode: "draft"
65771
65742
  }, normalizeStoredContentValues),
65772
- renderSchema: strictStoredSchema,
65743
+ renderSchema: deriveStrictContentZodFromPlans(plans, "render"),
65773
65744
  findNonPortableMediaPaths: (content) => findNonPortableMediaPaths(plans, content)
65774
65745
  }) });
65775
65746
  }
@@ -65917,11 +65888,8 @@ function deriveContentZodFromPlans(plans, options) {
65917
65888
  }
65918
65889
  return z.object(shape).catchall(z.unknown()).passthrough();
65919
65890
  }
65920
- function deriveStrictStoredZodFromPlans(plans) {
65921
- const shape = {};
65922
- for (const plan of plans) {
65923
- shape[plan.fieldId] = fieldPlanToStoredObjectPropertyZod(plan);
65924
- }
65891
+ function deriveStrictContentZodFromPlans(plans, mode = "strict") {
65892
+ const shape = Object.fromEntries(plans.map((plan) => [plan.fieldId, fieldPlanToStrictObjectPropertyZod(plan, mode)]));
65925
65893
  return z.object(shape).catchall(z.unknown()).passthrough();
65926
65894
  }
65927
65895
  function derivePlansFromManifestOrFields(manifestOrFields) {
@@ -65946,44 +65914,66 @@ function findNonPortableMediaPaths(plans, content) {
65946
65914
  collectNonPortablePlannedMedia(plans, content, [], paths);
65947
65915
  return [...paths].sort();
65948
65916
  }
65949
- function collectNonPortablePlannedMedia(plans, content, parentPath, paths) {
65917
+ /** One descriptor walker covers references and stored portability, including inactive retained fields. */
65918
+ function visitPlannedMedia(plans, content, parentPath, visit) {
65950
65919
  if (!isPlainRecord(content)) return;
65951
- for (const plan of plans) {
65952
- if (!(plan.fieldId in content)) continue;
65920
+ plans.forEach((plan) => {
65921
+ if (!(plan.fieldId in content)) return;
65953
65922
  const value = content[plan.fieldId];
65954
65923
  const path$4 = [...parentPath, plan.fieldId];
65955
65924
  switch (plan.kind) {
65956
65925
  case "media":
65957
- if (isPlainRecord(value) && hasEnvironmentSpecificMediaField(value)) {
65958
- paths.add(formatFieldPath$1(path$4));
65959
- }
65960
- break;
65926
+ visit(isPlainRecord(value) ? {
65927
+ ...value,
65928
+ type: value.type ?? plan.allowedMediaTypes[0]
65929
+ } : value, path$4, "media");
65930
+ return;
65961
65931
  case "richText":
65962
- collectNonPortableRichTextImages(value, path$4, paths);
65963
- break;
65932
+ visit(value, path$4, "richText");
65933
+ return;
65964
65934
  case "group":
65965
- collectNonPortablePlannedMedia(selectedGroupChildPlans(plan, value), value, path$4, paths);
65966
- break;
65935
+ visitPlannedMedia(allGroupChildPlans(plan), value, path$4, visit);
65936
+ return;
65967
65937
  case "repeater":
65968
- collectNonPortableRepeaterMedia(plan, value, path$4, paths);
65969
- break;
65970
- case "string":
65971
- case "number":
65938
+ visitRepeatedMedia(plan, value, path$4, visit);
65939
+ return;
65972
65940
  case "boolean":
65973
65941
  case "inlineText":
65974
65942
  case "link":
65943
+ case "number":
65944
+ case "passthrough":
65975
65945
  case "select":
65976
- case "passthrough": break;
65946
+ case "string": return;
65977
65947
  }
65978
- }
65948
+ });
65979
65949
  }
65980
- function collectNonPortableRepeaterMedia(plan, value, path$4, paths) {
65950
+ function visitRepeatedMedia(plan, value, path$4, visit) {
65981
65951
  if (!Array.isArray(value)) return;
65982
65952
  value.forEach((item, index) => {
65983
65953
  if (!isPlainRecord(item)) return;
65984
- const childPlans = plan.repeatedItemVariants ? plan.repeatedItemVariants.find((variant) => variant.typeId === item._type)?.fields : plan.repeatedItemPlan;
65985
- if (childPlans) {
65986
- collectNonPortablePlannedMedia(childPlans, item, [...path$4, index], paths);
65954
+ const fields$2 = plan.repeatedItemVariants ? plan.repeatedItemVariants.find((variant) => variant.typeId === item._type)?.fields : plan.repeatedItemPlan;
65955
+ if (fields$2) visitPlannedMedia(fields$2, item, [...path$4, index], visit);
65956
+ });
65957
+ }
65958
+ function collectManifestMediaReferences(contract, content) {
65959
+ const references = [];
65960
+ visitPlannedMedia(contract[compiledManifestContentContract].plans, content, [], (value, path$4, kind) => {
65961
+ if (value === null || value === undefined) return;
65962
+ const prefix = formatFieldPath$1(path$4);
65963
+ const collected = collectPortableMediaReferencesFromContent(kind === "media" ? mediaSchema.parse(value) : value);
65964
+ references.push(...collected.references.map((reference) => ({
65965
+ ...reference,
65966
+ location: reference.location ? `${prefix}.${reference.location}` : prefix
65967
+ })));
65968
+ });
65969
+ return summarizePortableMediaReferences(references);
65970
+ }
65971
+ function collectNonPortablePlannedMedia(plans, content, parentPath, paths) {
65972
+ visitPlannedMedia(plans, content, parentPath, (value, path$4, kind) => {
65973
+ if (kind === "richText") {
65974
+ collectNonPortableRichTextImages(value, path$4, paths);
65975
+ } else if (isPlainRecord(value) && (hasEnvironmentSpecificMediaField(value) || hasNonPortablePoster(value))) {
65976
+ paths.add(formatFieldPath$1(path$4));
65987
65977
  }
65988
65978
  });
65989
65979
  }
@@ -66003,6 +65993,10 @@ function isPlainRecord(value) {
66003
65993
  function hasEnvironmentSpecificMediaField(value) {
66004
65994
  return "assetId" in value || "storageBucket" in value || "storagePath" in value || "src" in value || "mimeType" in value || looksLikeUuid$1(value.id);
66005
65995
  }
65996
+ function hasNonPortablePoster(value) {
65997
+ if (value.poster === undefined) return false;
65998
+ return !mediaPosterSchema.safeParse(value.poster).success;
65999
+ }
66006
66000
 
66007
66001
  //#endregion
66008
66002
  //#region ../blocks/src/system/manifest/variantKey.ts
@@ -73491,7 +73485,7 @@ const memberPhotoClassName = (baseClass) => cardRoleChildClass({
73491
73485
  baseClass,
73492
73486
  stylesFrom: "content._cardStyles"
73493
73487
  });
73494
- const teamMemberPhotoSchema = mediaSchema.refine((media$1) => media$1.type === "image", { message: "Team member photos must be image media" }).nullable();
73488
+ const teamMemberPhotoSchema = runtimeMediaSchema.refine((media$1) => media$1.type === "image", { message: "Team member photos must be image media" }).nullable();
73495
73489
  const teamMemberDataSchema = z.object({
73496
73490
  _type: z.literal("teamMember"),
73497
73491
  id: z.string(),
@@ -98505,28 +98499,11 @@ const RichText = RichText$1;
98505
98499
 
98506
98500
  //#endregion
98507
98501
  //#region ../blocks/src/system/runtime/nodes/mergeResolveImageUrlContexts.ts
98508
- function normalizedIdentifier(asset) {
98509
- const identifier = typeof asset.identifier === "string" ? asset.identifier.trim() : "";
98510
- return identifier || undefined;
98511
- }
98512
- function indexAssets(index) {
98513
- if (!index) return [];
98514
- const assetsById = new Map();
98515
- for (const asset of [...index.byId.values(), ...index.byIdentifier.values()]) {
98516
- assetsById.set(asset.id, asset);
98517
- }
98518
- return [...assetsById.values()];
98519
- }
98520
98502
  function mergeAssetIndexes(baseline, live) {
98521
98503
  if (!baseline) return live;
98522
98504
  if (!live) return baseline;
98523
- let merged = [...indexAssets(baseline)];
98524
- for (const liveAsset of indexAssets(live)) {
98525
- const liveIdentifier = normalizedIdentifier(liveAsset);
98526
- merged = merged.filter((asset) => asset.id !== liveAsset.id && (liveIdentifier === undefined || normalizedIdentifier(asset) !== liveIdentifier));
98527
- merged.push(liveAsset);
98528
- }
98529
- return buildRenderableMediaAssetIndex(merged);
98505
+ const retained = [...baseline.byId.values()].filter((asset) => !live.byId.has(asset.id) && !live.byIdentifier.has(asset.identifier));
98506
+ return indexRenderableMediaAssets([...retained, ...live.byId.values()]);
98530
98507
  }
98531
98508
  /**
98532
98509
  * Combines a render snapshot with client registrations without changing the
@@ -98684,7 +98661,7 @@ function parseScale(scale) {
98684
98661
  * ```
98685
98662
  */
98686
98663
  function resolveBackground(input, theme, options) {
98687
- const background = parseBackgroundContent(input);
98664
+ const background = parseRuntimeBackgroundContent(input);
98688
98665
  if (!background) return emptyResolvedBackground();
98689
98666
  const color = background.type === "color" ? resolveColor(background.color, theme) : null;
98690
98667
  const gradient = resolveGradient(background, theme);
@@ -98719,7 +98696,7 @@ function resolveMediaLayer(background, opacity, options) {
98719
98696
  imageStyle: {},
98720
98697
  imageClassName: defaultImageClassName
98721
98698
  };
98722
- const resolvedMedia = resolveMediaWithContext(background.image, options?.imageResolveContext);
98699
+ const resolvedMedia = background.image;
98723
98700
  if (!isSupportedBackgroundMedia(resolvedMedia)) {
98724
98701
  return {
98725
98702
  image: null,
@@ -98739,7 +98716,7 @@ function resolveMediaLayer(background, opacity, options) {
98739
98716
  const baseStyle = resolveMediaStyle(objectFit, position, scaleValue, opacity);
98740
98717
  return {
98741
98718
  image: resolvedMediaDescriptor(resolvedMedia, url, background, options),
98742
- imageStyle: computeMediaTransformStyle(resolvedMedia, baseStyle, options?.targetAspectRatio) ?? baseStyle,
98719
+ imageStyle: computeMediaTransformStyle(resolvedMedia, baseStyle, options?.targetAspectRatio, undefined, options?.imageResolveContext) ?? baseStyle,
98743
98720
  imageClassName: buildImageClassName(objectFit, position, scaleValue, background)
98744
98721
  };
98745
98722
  }
@@ -98753,22 +98730,39 @@ function resolveMediaStyle(objectFit, position, scaleValue, opacity) {
98753
98730
  if (position && !isBackgroundPositionPreset(position)) style.objectPosition = position;
98754
98731
  return style;
98755
98732
  }
98756
- function resolvedMediaDescriptor(media$1, url, background, options) {
98757
- const base = {
98758
- kind: media$1.type,
98759
- url,
98760
- alt: media$1.alt ?? "",
98733
+ function backgroundMediaDimensions(media$1, context) {
98734
+ if ("asset" in media$1 && media$1.asset) return {
98735
+ width: media$1.asset.width ?? undefined,
98736
+ height: media$1.asset.height ?? undefined
98737
+ };
98738
+ if (!media$1.identifier) return {
98761
98739
  width: media$1.width,
98762
98740
  height: media$1.height
98763
98741
  };
98764
- if (media$1.type !== "video") return base;
98765
- const poster = resolveVideoPosterUrl(media$1, options?.imageResolveContext);
98766
- return !poster ? base : {
98767
- ...base,
98742
+ const resolved = resolveMediaWithContext(media$1, context);
98743
+ return resolved.kind === "resolved" ? {
98744
+ width: resolved.asset.width ?? undefined,
98745
+ height: resolved.asset.height ?? undefined
98746
+ } : {};
98747
+ }
98748
+ function backgroundVideoDescriptor(media$1, background, context) {
98749
+ if (media$1.type !== "video") return {};
98750
+ const poster = resolveVideoPosterUrl(media$1, context);
98751
+ if (!poster) return {};
98752
+ return {
98768
98753
  poster,
98769
98754
  ...background.type === "video" && background.showVideoOnMobile === true ? {} : { mobileFallbackPoster: poster }
98770
98755
  };
98771
98756
  }
98757
+ function resolvedMediaDescriptor(media$1, url, background, options) {
98758
+ return {
98759
+ kind: media$1.type,
98760
+ url,
98761
+ alt: media$1.alt ?? "",
98762
+ ...backgroundMediaDimensions(media$1, options?.imageResolveContext),
98763
+ ...backgroundVideoDescriptor(media$1, background, options?.imageResolveContext)
98764
+ };
98765
+ }
98772
98766
  function resolveOverlay(background, theme) {
98773
98767
  const overlay = background?.overlay;
98774
98768
  if (!overlay || overlay.type === "none") return null;
@@ -98784,7 +98778,7 @@ function isSupportedBackgroundMedia(media$1) {
98784
98778
  }
98785
98779
  function resolveBackgroundMediaUrl(media$1, context) {
98786
98780
  if (media$1.type === "video") {
98787
- return resolveMediaStorageUrl(media$1, context) ?? media$1.src;
98781
+ return resolvePublicMediaUrl(media$1, context);
98788
98782
  }
98789
98783
  return resolveImageUrl(media$1, ImagePresets.full, context);
98790
98784
  }
@@ -98921,10 +98915,7 @@ function serializeBackgroundOverride(override) {
98921
98915
  case "image": return {
98922
98916
  contentOwner: pageDesignEditorBackgroundOverrideOwner,
98923
98917
  type: "image",
98924
- image: {
98925
- type: "image",
98926
- assetId: override.mediaId
98927
- }
98918
+ image: override.reference
98928
98919
  };
98929
98920
  }
98930
98921
  }
@@ -98996,12 +98987,12 @@ function backgroundOverrideEquals(left, right) {
98996
98987
  case "default": return true;
98997
98988
  case "color": return right.kind === "color" && left.token === right.token;
98998
98989
  case "gradient": return right.kind === "gradient" && left.gradientId === right.gradientId;
98999
- case "image": return right.kind === "image" && left.mediaId === right.mediaId;
98990
+ case "image": return right.kind === "image" && stableJsonStringify(JSON.parse(JSON.stringify(left.reference))) === stableJsonStringify(JSON.parse(JSON.stringify(right.reference)));
99000
98991
  }
99001
98992
  }
99002
98993
  function imagePoolForOverride(override) {
99003
98994
  return override.kind === "image" ? [{
99004
- mediaId: override.mediaId,
98995
+ reference: override.reference,
99005
98996
  source: "current"
99006
98997
  }] : [];
99007
98998
  }
@@ -99026,7 +99017,7 @@ function defaultBackgroundOverrideForMode(mode, capability) {
99026
99017
  const image = rankBackgroundImagePoolItems(capability.imagePool ?? [])[0];
99027
99018
  return image ? {
99028
99019
  kind: "image",
99029
- mediaId: image.mediaId
99020
+ reference: image.reference
99030
99021
  } : DEFAULT_BACKGROUND_OVERRIDE;
99031
99022
  }
99032
99023
  }
@@ -99099,123 +99090,106 @@ function parseCanonicalSectionBackground(content) {
99099
99090
  if (background === null || background === undefined) {
99100
99091
  return { kind: "none" };
99101
99092
  }
99102
- const canonical$1 = parseBackgroundContent(background);
99103
- if (!canonical$1) return { kind: "none" };
99104
- if (canonical$1.contentOwner !== pageDesignEditorBackgroundOverrideOwner) {
99093
+ if (isRecord$17(background) && background.contentOwner === pageDesignEditorBackgroundOverrideOwner) {
99105
99094
  return {
99106
- kind: "block-authored",
99107
- background: canonical$1
99095
+ kind: "page-design-override",
99096
+ parsed: parseBackgroundOverride(background)
99108
99097
  };
99109
99098
  }
99110
- return {
99111
- kind: "page-design-override",
99112
- parsed: parseBackgroundOverride(background)
99113
- };
99099
+ const canonical$1 = parseBackgroundContent(background);
99100
+ return canonical$1 ? {
99101
+ kind: "block-authored",
99102
+ background: canonical$1
99103
+ } : { kind: "none" };
99114
99104
  }
99115
- function parseBackgroundOverride(value) {
99116
- if (value === null || value === undefined) {
99105
+ function parseGradientBackgroundOverride(background) {
99106
+ if (typeof background.gradient === "string" && background.gradient.trim()) {
99117
99107
  return {
99118
- kind: "supported",
99119
- override: DEFAULT_BACKGROUND_OVERRIDE
99108
+ kind: "unsupported",
99109
+ reason: "arbitrary-gradient-css",
99110
+ background
99120
99111
  };
99121
99112
  }
99122
- if (!isRecord$17(value)) {
99113
+ if (background.gradientPresetId === undefined || background.gradientPresetId === null) {
99123
99114
  return {
99124
99115
  kind: "unsupported",
99125
- reason: "unsupported-shape",
99126
- background: {}
99116
+ reason: "missing-gradient-preset-id",
99117
+ background
99127
99118
  };
99128
99119
  }
99129
- if (Object.keys(value).length === 0) {
99130
- return {
99120
+ const gradientId = parseGradientPresetId(background.gradientPresetId);
99121
+ return gradientId ? {
99122
+ kind: "supported",
99123
+ override: {
99124
+ kind: "gradient",
99125
+ gradientId
99126
+ }
99127
+ } : {
99128
+ kind: "unsupported",
99129
+ reason: "invalid-gradient-preset-id",
99130
+ background
99131
+ };
99132
+ }
99133
+ function parseImageBackgroundOverride(background) {
99134
+ const reference = parseImageReference(background.image);
99135
+ switch (reference.kind) {
99136
+ case "valid": return {
99131
99137
  kind: "supported",
99132
- override: DEFAULT_BACKGROUND_OVERRIDE
99138
+ override: {
99139
+ kind: "image",
99140
+ reference: reference.reference
99141
+ }
99142
+ };
99143
+ case "missing": return {
99144
+ kind: "unsupported",
99145
+ reason: "missing-image-reference",
99146
+ background
99147
+ };
99148
+ case "invalid": return {
99149
+ kind: "unsupported",
99150
+ reason: "invalid-image-reference",
99151
+ background
99133
99152
  };
99134
99153
  }
99154
+ }
99155
+ function parseBackgroundOverride(value) {
99156
+ if (value === null || value === undefined) return {
99157
+ kind: "supported",
99158
+ override: DEFAULT_BACKGROUND_OVERRIDE
99159
+ };
99160
+ if (!isRecord$17(value)) return {
99161
+ kind: "unsupported",
99162
+ reason: "unsupported-shape",
99163
+ background: {}
99164
+ };
99165
+ if (!Object.keys(value).length) return {
99166
+ kind: "supported",
99167
+ override: DEFAULT_BACKGROUND_OVERRIDE
99168
+ };
99135
99169
  const type = typeof value.type === "string" ? value.type.trim() : null;
99136
99170
  switch (type) {
99137
- case null: return {
99138
- kind: "unsupported",
99139
- reason: "unsupported-mode",
99140
- background: value
99141
- };
99142
99171
  case "color": {
99143
99172
  const token = parseBackgroundColorToken(value.color);
99144
- if (!token) {
99145
- return {
99146
- kind: "unsupported",
99147
- reason: "invalid-color-token",
99148
- background: value
99149
- };
99150
- }
99151
- return {
99173
+ return token ? {
99152
99174
  kind: "supported",
99153
99175
  override: {
99154
99176
  kind: "color",
99155
99177
  token
99156
99178
  }
99179
+ } : {
99180
+ kind: "unsupported",
99181
+ reason: "invalid-color-token",
99182
+ background: value
99157
99183
  };
99158
99184
  }
99159
- case "gradient": {
99160
- if (typeof value.gradient === "string" && value.gradient.trim()) {
99161
- return {
99162
- kind: "unsupported",
99163
- reason: "arbitrary-gradient-css",
99164
- background: value
99165
- };
99166
- }
99167
- if (value.gradientPresetId === undefined || value.gradientPresetId === null) {
99168
- return {
99169
- kind: "unsupported",
99170
- reason: "missing-gradient-preset-id",
99171
- background: value
99172
- };
99173
- }
99174
- const gradientId = parseGradientPresetId(value.gradientPresetId);
99175
- if (!gradientId) {
99176
- return {
99177
- kind: "unsupported",
99178
- reason: "invalid-gradient-preset-id",
99179
- background: value
99180
- };
99181
- }
99182
- return {
99183
- kind: "supported",
99184
- override: {
99185
- kind: "gradient",
99186
- gradientId
99187
- }
99188
- };
99189
- }
99190
- case "image": {
99191
- const mediaIdResult = parseImageMediaAssetId(value.image);
99192
- if (mediaIdResult.kind === "missing") {
99193
- return {
99194
- kind: "unsupported",
99195
- reason: "missing-image-media-id",
99196
- background: value
99197
- };
99198
- }
99199
- if (mediaIdResult.kind === "invalid") {
99200
- return {
99201
- kind: "unsupported",
99202
- reason: "invalid-image-media-id",
99203
- background: value
99204
- };
99205
- }
99206
- return {
99207
- kind: "supported",
99208
- override: {
99209
- kind: "image",
99210
- mediaId: mediaIdResult.mediaId
99211
- }
99212
- };
99213
- }
99185
+ case "gradient": return parseGradientBackgroundOverride(value);
99186
+ case "image": return parseImageBackgroundOverride(value);
99214
99187
  case "video": return {
99215
99188
  kind: "unsupported",
99216
99189
  reason: "video-background",
99217
99190
  background: value
99218
99191
  };
99192
+ case null:
99219
99193
  default: return {
99220
99194
  kind: "unsupported",
99221
99195
  reason: "unsupported-mode",
@@ -99252,9 +99226,9 @@ function planBackgroundTransition(current, capability, action) {
99252
99226
  kind: "blocked",
99253
99227
  reason: "value-unavailable"
99254
99228
  };
99255
- case "choose-image": return imageAllowed(action.mediaId, capability.imagePool) ? applyPlan({
99229
+ case "choose-image": return imageAllowed(action.reference.identifier, capability.imagePool) ? applyPlan({
99256
99230
  kind: "image",
99257
- mediaId: action.mediaId
99231
+ reference: action.reference
99258
99232
  }) : {
99259
99233
  kind: "blocked",
99260
99234
  reason: "value-unavailable"
@@ -99343,10 +99317,10 @@ function planApplyMode(current, capability, mode) {
99343
99317
  }
99344
99318
  case "image": {
99345
99319
  const rankedImages = rankBackgroundImagePoolItems(capability.imagePool ?? []);
99346
- const mediaId = current.kind === "image" && imageAllowed(current.mediaId, rankedImages) ? current.mediaId : rankedImages[0]?.mediaId;
99347
- return mediaId ? applyPlan({
99320
+ const reference = current.kind === "image" && imageAllowed(current.reference.identifier, rankedImages) ? current.reference : rankedImages[0]?.reference;
99321
+ return reference ? applyPlan({
99348
99322
  kind: "image",
99349
- mediaId
99323
+ reference
99350
99324
  }) : {
99351
99325
  kind: "blocked",
99352
99326
  reason: "empty-image-pool"
@@ -99382,10 +99356,11 @@ function planCycleValue(current, capability, direction) {
99382
99356
  }
99383
99357
  case "image": {
99384
99358
  const rankedImages = rankBackgroundImagePoolItems(capability.imagePool ?? []);
99385
- const mediaId = cycleInList(rankedImages.map((item) => item.mediaId), current.mediaId, direction);
99386
- return mediaId ? applyPlan({
99359
+ const identifier = cycleInList(rankedImages.map((item) => item.reference.identifier), current.reference.identifier, direction);
99360
+ const reference = rankedImages.find((item) => item.reference.identifier === identifier)?.reference;
99361
+ return reference ? applyPlan({
99387
99362
  kind: "image",
99388
- mediaId
99363
+ reference
99389
99364
  }) : {
99390
99365
  kind: "blocked",
99391
99366
  reason: "value-unavailable"
@@ -99417,7 +99392,7 @@ function canCycleBackgroundOverrideValue(override, capability) {
99417
99392
  function backgroundPersistenceSideEffects(override) {
99418
99393
  return override.kind === "image" ? [{
99419
99394
  kind: "mark-background-used",
99420
- mediaId: override.mediaId
99395
+ identifier: override.reference.identifier
99421
99396
  }] : [];
99422
99397
  }
99423
99398
  function overrideValueAllowed(override, capability) {
@@ -99425,7 +99400,7 @@ function overrideValueAllowed(override, capability) {
99425
99400
  case "default": return true;
99426
99401
  case "color": return valueAllowed(override.token, capability.colorTokens);
99427
99402
  case "gradient": return valueAllowed(override.gradientId, capability.gradientIds);
99428
- case "image": return imageAllowed(override.mediaId, capability.imagePool);
99403
+ case "image": return imageAllowed(override.reference.identifier, capability.imagePool);
99429
99404
  }
99430
99405
  }
99431
99406
  function blockSupportsRichBackgroundModes(block) {
@@ -99461,20 +99436,20 @@ function valueAllowed(value, allowedValues) {
99461
99436
  function valueInList(value, values) {
99462
99437
  return value !== null && values.includes(value);
99463
99438
  }
99464
- function imageAllowed(mediaId, pool) {
99465
- return pool?.some((item) => item.mediaId === mediaId) ?? false;
99439
+ function imageAllowed(identifier, pool) {
99440
+ return pool?.some((item) => item.reference.identifier === identifier) ?? false;
99466
99441
  }
99467
- function parseImageMediaAssetId(value) {
99468
- if (!isRecord$17(value)) return { kind: "missing" };
99469
- if (value.type !== undefined && value.type !== "image") return { kind: "missing" };
99470
- const parsed = parseMediaAssetId(value.assetId);
99471
- if (!parsed.ok) {
99472
- return value.assetId === undefined || value.assetId === null ? { kind: "missing" } : { kind: "invalid" };
99473
- }
99474
- return {
99442
+ function parseImageReference(value) {
99443
+ if (!isRecord$17(value) || value.identifier === undefined || value.identifier === null) return { kind: "missing" };
99444
+ if (value.type !== undefined && value.type !== "image") return { kind: "invalid" };
99445
+ const parsed = imageMediaSchema.safeParse({
99446
+ ...value,
99447
+ type: "image"
99448
+ });
99449
+ return parsed.success ? {
99475
99450
  kind: "valid",
99476
- mediaId: parsed.value
99477
- };
99451
+ reference: parsed.data
99452
+ } : { kind: "invalid" };
99478
99453
  }
99479
99454
  function compareBackgroundImagePoolItems(left, right) {
99480
99455
  const sourceDifference = sourceRank(left.source) - sourceRank(right.source);
@@ -99492,7 +99467,7 @@ function sourceRank(source) {
99492
99467
  }
99493
99468
  }
99494
99469
  function itemSortLabel(item) {
99495
- return `${item.label ?? ""}:${item.mediaId}`;
99470
+ return `${item.label ?? ""}:${item.reference.identifier}`;
99496
99471
  }
99497
99472
  function normalizePaletteColorValue(value) {
99498
99473
  const normalized = value?.trim().toLowerCase();
@@ -118969,7 +118944,7 @@ async function loadConfig(configPath, output) {
118969
118944
  return { errorMessage: "No config path provided." };
118970
118945
  }
118971
118946
  try {
118972
- const { loadConfigFile: loadConfigFile$1 } = await import("../load-config-CyzQYQmx.mjs");
118947
+ const { loadConfigFile: loadConfigFile$1 } = await import("../load-config-s-HOXD6E.mjs");
118973
118948
  const rawConfig = await loadConfigFile$1(configPath);
118974
118949
  const parsed = riverbankSiteConfigSchema.safeParse(rawConfig);
118975
118950
  if (!parsed.success) {