riverbankcms 0.9.0 → 0.10.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.
- package/dist/acceptance/matrix.mjs +3 -3
- package/dist/cli/index.mjs +872 -652
- package/dist/{eventUpsertInputSchema-CqHIJp9H.mjs → eventUpsertInputSchema-yErCHdr6.mjs} +2 -2
- package/dist/load-config-BToL9PfS.mjs +4 -0
- package/dist/{load-config-Cf5uPEAn.mjs → load-config-Bzc6Qo24.mjs} +2 -2
- package/dist/{local-sync-DF-2DL_D.mjs → local-sync-3ZG1khGb.mjs} +2 -2
- package/dist/{plan-By0bjnd3.mjs → plan-C1Frmu6F.mjs} +1 -1
- package/dist/scaffold/index.mjs +2 -2
- package/dist/{sdk-event-upsert-BNxbxaA0.mjs → sdk-event-upsert-DhdlT2ko.mjs} +2187 -1806
- package/dist/{src-DbmhanBI.mjs → src-DIAVNRwo.mjs} +120 -1
- package/dist/testing.mjs +3 -3
- package/package.json +1 -1
- package/dist/load-config-CKBdp8M0.mjs +0 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { A as parseFooterCompositionV1, Ht as
|
|
2
|
+
import { A as parseFooterCompositionV1, Ht as err, M as isCanonicalRichTextDoc, P as isPresent, Ut as ok, Z as parseBookingTimeZone, b as stableJsonStringify, k as footerNavigationLayouts, l as EVENT_PRESET_VALUES, n as NAVIGATION_LOCATIONS, q as parseUtcIsoDateTimeString, s as resolveSiteVerticalBookingConfig, u as ORDINARY_EVENT_PRESET_VALUES, ut as assertNever } from "./src-DIAVNRwo.mjs";
|
|
3
3
|
import "node:module";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
@@ -61,41 +61,6 @@ function siteCommandResourceResult(ref, resourceId, effect) {
|
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
//#endregion
|
|
65
|
-
//#region ../site-commands/src/capabilityGaps.ts
|
|
66
|
-
const staticExecutionGapCodes = [
|
|
67
|
-
"event_occurrence_required",
|
|
68
|
-
"event_occurrence_invalid",
|
|
69
|
-
"event_occurrence_venue_mapping_unsupported",
|
|
70
|
-
"event_booking_offer_invalid",
|
|
71
|
-
"event_ticket_single_occurrence_scope_unsupported",
|
|
72
|
-
"event_manual_payment_unsupported",
|
|
73
|
-
"event_external_payment_unsupported",
|
|
74
|
-
"event_waitlist_requires_waitlist_adapter",
|
|
75
|
-
"event_media_content_requires_media_adapter",
|
|
76
|
-
"event_linked_content_requires_content_adapter",
|
|
77
|
-
"event_delivery_mode_requires_booking_surface_adapter",
|
|
78
|
-
"event_whole_series_page_fields_unsupported",
|
|
79
|
-
"event_whole_series_passes_unsupported",
|
|
80
|
-
"event_whole_series_pricing_unsupported",
|
|
81
|
-
"event_whole_series_schedule_update_unsupported",
|
|
82
|
-
"event_whole_series_staff_update_unsupported"
|
|
83
|
-
];
|
|
84
|
-
const plannerCapabilityGapCodes = ["command_metadata_support_gap"];
|
|
85
|
-
const adapterCapabilityGapCodes = [
|
|
86
|
-
"demo_recipe_adapter_missing",
|
|
87
|
-
"media_manifest_storage_resolution_missing",
|
|
88
|
-
"navigation_content_entry_refs_unsupported",
|
|
89
|
-
"staff_site_user_requires_dashboard_user",
|
|
90
|
-
"team_member_profile_requires_dashboard_user",
|
|
91
|
-
"generated_navigation_command_unsupported"
|
|
92
|
-
];
|
|
93
|
-
const siteCommandCapabilityGapCodes = [
|
|
94
|
-
...staticExecutionGapCodes,
|
|
95
|
-
...plannerCapabilityGapCodes,
|
|
96
|
-
...adapterCapabilityGapCodes
|
|
97
|
-
];
|
|
98
|
-
|
|
99
64
|
//#endregion
|
|
100
65
|
//#region ../site-commands/src/refs.ts
|
|
101
66
|
const resourceKinds = [
|
|
@@ -123,6 +88,7 @@ const resourceKinds = [
|
|
|
123
88
|
"pass-redemption",
|
|
124
89
|
"order",
|
|
125
90
|
"appointment-service",
|
|
91
|
+
"appointment-service-category",
|
|
126
92
|
"appointment-resource",
|
|
127
93
|
"availability"
|
|
128
94
|
];
|
|
@@ -167,6 +133,9 @@ function createVenueRef(parts) {
|
|
|
167
133
|
function createEventCategoryRef(parts) {
|
|
168
134
|
return `event-category:${joinRefSlugParts(parts)}`;
|
|
169
135
|
}
|
|
136
|
+
function createAppointmentServiceCategoryRef(parts) {
|
|
137
|
+
return `appointment-service-category:${joinRefSlugParts(parts)}`;
|
|
138
|
+
}
|
|
170
139
|
function createEventSeriesRef(parts) {
|
|
171
140
|
return `event:${joinRefSlugParts(parts)}`;
|
|
172
141
|
}
|
|
@@ -245,6 +214,118 @@ function isValidIanaTimezone(value) {
|
|
|
245
214
|
}
|
|
246
215
|
}
|
|
247
216
|
|
|
217
|
+
//#endregion
|
|
218
|
+
//#region ../site-commands/src/appointmentServiceCategoryCommands.ts
|
|
219
|
+
const appointmentServiceCategoryRefSchema = resourceRefSchema("appointment-service-category");
|
|
220
|
+
/**
|
|
221
|
+
* Creates or updates one appointment-service category (issue 1403).
|
|
222
|
+
*
|
|
223
|
+
* The category's `identifier` is its stable key: it never changes after the
|
|
224
|
+
* category is created, so a rename in the dashboard doesn't break a rerun.
|
|
225
|
+
* When a command leaves it out, the identifier is the ref's slug, which keeps
|
|
226
|
+
* reruns of the same command pointed at the same category.
|
|
227
|
+
*
|
|
228
|
+
* `description` and `sortOrder` describe the wanted state. An omitted
|
|
229
|
+
* description means no description. An omitted `sortOrder` puts a new
|
|
230
|
+
* category last and leaves an existing one where it is.
|
|
231
|
+
*/
|
|
232
|
+
const upsertAppointmentServiceCategoryCommandSchema = z.object({
|
|
233
|
+
type: z.literal("upsertAppointmentServiceCategory"),
|
|
234
|
+
ref: appointmentServiceCategoryRefSchema,
|
|
235
|
+
input: z.object({
|
|
236
|
+
identifier: recipeIdentifierSchema.optional(),
|
|
237
|
+
name: z.string().trim().min(1),
|
|
238
|
+
description: z.string().trim().nullable().optional(),
|
|
239
|
+
sortOrder: nonNegativeIntegerSchema.optional()
|
|
240
|
+
}).strict()
|
|
241
|
+
}).strict();
|
|
242
|
+
/**
|
|
243
|
+
* The three ways a service can be placed among the categories. Each variant
|
|
244
|
+
* forbids the other key, so a command naming both a `categoryRef` and a
|
|
245
|
+
* `categoryIdentifier` can't be represented.
|
|
246
|
+
*/
|
|
247
|
+
const noAppointmentServiceCategoryFields = {
|
|
248
|
+
categoryRef: z.undefined().optional(),
|
|
249
|
+
categoryIdentifier: z.undefined().optional()
|
|
250
|
+
};
|
|
251
|
+
const appointmentServiceCategoryRefFields = {
|
|
252
|
+
categoryRef: appointmentServiceCategoryRefSchema,
|
|
253
|
+
categoryIdentifier: z.undefined().optional()
|
|
254
|
+
};
|
|
255
|
+
const appointmentServiceCategoryIdentifierFields = {
|
|
256
|
+
categoryRef: z.undefined().optional(),
|
|
257
|
+
categoryIdentifier: recipeIdentifierSchema
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* Rejects a command that names both category keys with one clear message,
|
|
261
|
+
* before the union reports that no variant matched.
|
|
262
|
+
*/
|
|
263
|
+
function rejectBothAppointmentServiceCategoryKeys(value, ctx) {
|
|
264
|
+
if (typeof value !== "object" || value === null || !("categoryRef" in value) || !("categoryIdentifier" in value) || value.categoryRef === undefined || value.categoryIdentifier === undefined) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
ctx.addIssue({
|
|
268
|
+
code: "custom",
|
|
269
|
+
path: ["categoryIdentifier"],
|
|
270
|
+
message: "Use categoryRef for a category upserted in this batch, or categoryIdentifier for one that already exists, not both."
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
/** Where an `upsertAppointmentService` command puts the service. */
|
|
274
|
+
function appointmentServiceCategoryPlacement(input) {
|
|
275
|
+
if (input.categoryRef !== undefined) {
|
|
276
|
+
return {
|
|
277
|
+
kind: "batch_ref",
|
|
278
|
+
categoryRef: input.categoryRef
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
if (input.categoryIdentifier !== undefined) {
|
|
282
|
+
return {
|
|
283
|
+
kind: "identifier",
|
|
284
|
+
identifier: input.categoryIdentifier
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
return { kind: "uncategorized" };
|
|
288
|
+
}
|
|
289
|
+
/** The stable key an `upsertAppointmentServiceCategory` command writes to. */
|
|
290
|
+
function appointmentServiceCategoryIdentifierForCommand(command) {
|
|
291
|
+
return command.input.identifier ?? refSlug(command.ref);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
//#endregion
|
|
295
|
+
//#region ../site-commands/src/capabilityGaps.ts
|
|
296
|
+
const staticExecutionGapCodes = [
|
|
297
|
+
"event_occurrence_required",
|
|
298
|
+
"event_occurrence_invalid",
|
|
299
|
+
"event_occurrence_venue_mapping_unsupported",
|
|
300
|
+
"event_booking_offer_invalid",
|
|
301
|
+
"event_ticket_single_occurrence_scope_unsupported",
|
|
302
|
+
"event_manual_payment_unsupported",
|
|
303
|
+
"event_external_payment_unsupported",
|
|
304
|
+
"event_waitlist_requires_waitlist_adapter",
|
|
305
|
+
"event_media_content_requires_media_adapter",
|
|
306
|
+
"event_linked_content_requires_content_adapter",
|
|
307
|
+
"event_delivery_mode_requires_booking_surface_adapter",
|
|
308
|
+
"event_whole_series_page_fields_unsupported",
|
|
309
|
+
"event_whole_series_passes_unsupported",
|
|
310
|
+
"event_whole_series_pricing_unsupported",
|
|
311
|
+
"event_whole_series_schedule_update_unsupported",
|
|
312
|
+
"event_whole_series_staff_update_unsupported"
|
|
313
|
+
];
|
|
314
|
+
const plannerCapabilityGapCodes = ["command_metadata_support_gap"];
|
|
315
|
+
const adapterCapabilityGapCodes = [
|
|
316
|
+
"demo_recipe_adapter_missing",
|
|
317
|
+
"media_manifest_storage_resolution_missing",
|
|
318
|
+
"navigation_content_entry_refs_unsupported",
|
|
319
|
+
"staff_site_user_requires_dashboard_user",
|
|
320
|
+
"team_member_profile_requires_dashboard_user",
|
|
321
|
+
"generated_navigation_command_unsupported"
|
|
322
|
+
];
|
|
323
|
+
const siteCommandCapabilityGapCodes = [
|
|
324
|
+
...staticExecutionGapCodes,
|
|
325
|
+
...plannerCapabilityGapCodes,
|
|
326
|
+
...adapterCapabilityGapCodes
|
|
327
|
+
];
|
|
328
|
+
|
|
248
329
|
//#endregion
|
|
249
330
|
//#region ../site-commands/src/bookingCommandValues.ts
|
|
250
331
|
const bookingPassProductUseCases = ["event_pass", "appointment_package"];
|
|
@@ -2449,8 +2530,8 @@ const BACKGROUND_ROLE_NAMES = new Set([
|
|
|
2449
2530
|
"muted",
|
|
2450
2531
|
"neutral"
|
|
2451
2532
|
]);
|
|
2452
|
-
function onColorTokenName(backgroundToken) {
|
|
2453
|
-
return `on${backgroundToken.split("-").filter((part) => part.length > 0).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")}`;
|
|
2533
|
+
function onColorTokenName(backgroundToken$1) {
|
|
2534
|
+
return `on${backgroundToken$1.split("-").filter((part) => part.length > 0).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")}`;
|
|
2454
2535
|
}
|
|
2455
2536
|
function isOnColorBackgroundCandidateToken(token) {
|
|
2456
2537
|
const role = token.match(/^(.*?)(?:-\d{2,3})?$/)?.[1] ?? token;
|
|
@@ -2584,8 +2665,8 @@ function resolveDeterministicForeground(backgroundReference, candidates, palette
|
|
|
2584
2665
|
if (!backgroundHex) {
|
|
2585
2666
|
return resolveTrustedTreatmentForeground(candidates, palette);
|
|
2586
2667
|
}
|
|
2587
|
-
const backgroundToken = paletteToken(backgroundReference);
|
|
2588
|
-
const derivedOnToken = backgroundToken ? onColorTokenName(backgroundToken) : null;
|
|
2668
|
+
const backgroundToken$1 = paletteToken(backgroundReference);
|
|
2669
|
+
const derivedOnToken = backgroundToken$1 ? onColorTokenName(backgroundToken$1) : null;
|
|
2589
2670
|
const text = firstSafeToken([
|
|
2590
2671
|
candidates.text,
|
|
2591
2672
|
derivedOnToken,
|
|
@@ -4616,16 +4697,18 @@ const themeV2RuntimeStyleFieldNames = [
|
|
|
4616
4697
|
"_frameStyles",
|
|
4617
4698
|
"_sectionStyles",
|
|
4618
4699
|
"_containerStyles",
|
|
4619
|
-
"_cardStyles"
|
|
4620
|
-
"_transitionStyles",
|
|
4621
|
-
"styleGroup"
|
|
4700
|
+
"_cardStyles"
|
|
4622
4701
|
];
|
|
4623
4702
|
const themeV2BlockSpecificRawStyleFieldNames = [
|
|
4624
4703
|
"_contentCardStyles",
|
|
4625
4704
|
"_heroLayoutStyles",
|
|
4626
4705
|
"_textCardStyles"
|
|
4627
4706
|
];
|
|
4628
|
-
const themeV2NormalEditorRawStyleFieldNames = [
|
|
4707
|
+
const themeV2NormalEditorRawStyleFieldNames = [
|
|
4708
|
+
...themeV2RuntimeStyleFieldNames,
|
|
4709
|
+
...themeV2BlockSpecificRawStyleFieldNames,
|
|
4710
|
+
"styleGroup"
|
|
4711
|
+
];
|
|
4629
4712
|
const themeV2NormalEditorRawStyleFieldNameSet = new Set(themeV2NormalEditorRawStyleFieldNames);
|
|
4630
4713
|
const themeV2CompilerOwnedFieldNames = [...themeV2RuntimeStyleFieldNames, ...themeV2BlockSpecificRawStyleFieldNames];
|
|
4631
4714
|
const pageDesignEditorBackgroundOverrideOwner = "page-design-editor";
|
|
@@ -4637,6 +4720,21 @@ function isThemeV2NormalEditorRawStylePath(fieldPath) {
|
|
|
4637
4720
|
const rootField = fieldPath.split(".")[0] ?? "";
|
|
4638
4721
|
return isThemeV2NormalEditorRawStyleFieldName(rootField);
|
|
4639
4722
|
}
|
|
4723
|
+
const staleTransitionStyleGroupPrefix = "site-style-transition-";
|
|
4724
|
+
/**
|
|
4725
|
+
* A `styleGroup` in the retired `site-style-transition-*` namespace is residue
|
|
4726
|
+
* from the old per-block transition path (issue 1422). Any other value is
|
|
4727
|
+
* authored and must survive.
|
|
4728
|
+
*/
|
|
4729
|
+
function isStaleTransitionStyleGroup(value) {
|
|
4730
|
+
return typeof value === "string" && value.startsWith(staleTransitionStyleGroupPrefix);
|
|
4731
|
+
}
|
|
4732
|
+
/** Drops a stale transition `styleGroup`, leaving authored values untouched. */
|
|
4733
|
+
function stripStaleTransitionStyleGroup(content) {
|
|
4734
|
+
if (!isStaleTransitionStyleGroup(content.styleGroup)) return { ...content };
|
|
4735
|
+
const { styleGroup: _stale, ...rest } = content;
|
|
4736
|
+
return rest;
|
|
4737
|
+
}
|
|
4640
4738
|
|
|
4641
4739
|
//#endregion
|
|
4642
4740
|
//#region ../theme-core/src/utils/tokenOrColor.ts
|
|
@@ -6700,10 +6798,10 @@ function resolveFocusIndicator(colour) {
|
|
|
6700
6798
|
};
|
|
6701
6799
|
}
|
|
6702
6800
|
}
|
|
6703
|
-
function resolveSolid(input, backgroundToken) {
|
|
6704
|
-
const backgroundHex = paletteHex(input, backgroundToken);
|
|
6801
|
+
function resolveSolid(input, backgroundToken$1) {
|
|
6802
|
+
const backgroundHex = paletteHex(input, backgroundToken$1);
|
|
6705
6803
|
if (!backgroundHex.ok) return backgroundHex;
|
|
6706
|
-
const foregroundToken = unsafeAsOpaqueButtonColourToken(onColorTokenName(backgroundToken));
|
|
6804
|
+
const foregroundToken = unsafeAsOpaqueButtonColourToken(onColorTokenName(backgroundToken$1));
|
|
6707
6805
|
const foregroundHex = input.palette[foregroundToken];
|
|
6708
6806
|
if (typeof foregroundHex !== "string") {
|
|
6709
6807
|
return {
|
|
@@ -6712,14 +6810,14 @@ function resolveSolid(input, backgroundToken) {
|
|
|
6712
6810
|
tag: "missing_on_colour",
|
|
6713
6811
|
variantId: input.variantId,
|
|
6714
6812
|
state: input.state,
|
|
6715
|
-
backgroundToken,
|
|
6813
|
+
backgroundToken: backgroundToken$1,
|
|
6716
6814
|
foregroundToken
|
|
6717
6815
|
}
|
|
6718
6816
|
};
|
|
6719
6817
|
}
|
|
6720
6818
|
const contrast = validateButtonTextContrast({
|
|
6721
6819
|
...input,
|
|
6722
|
-
background: backgroundToken,
|
|
6820
|
+
background: backgroundToken$1,
|
|
6723
6821
|
backgroundHex: backgroundHex.hex,
|
|
6724
6822
|
foreground: foregroundToken,
|
|
6725
6823
|
foregroundHex
|
|
@@ -6737,9 +6835,9 @@ function resolveSolid(input, backgroundToken) {
|
|
|
6737
6835
|
ok: true,
|
|
6738
6836
|
colour: {
|
|
6739
6837
|
kind: "solid",
|
|
6740
|
-
backgroundToken,
|
|
6838
|
+
backgroundToken: backgroundToken$1,
|
|
6741
6839
|
foregroundToken,
|
|
6742
|
-
backgroundCss: tokenCss(backgroundToken),
|
|
6840
|
+
backgroundCss: tokenCss(backgroundToken$1),
|
|
6743
6841
|
foregroundCss: tokenCss(foregroundToken)
|
|
6744
6842
|
}
|
|
6745
6843
|
};
|
|
@@ -13438,11 +13536,11 @@ const TEXT_CONTRAST_THRESHOLD = 3;
|
|
|
13438
13536
|
* @param palette - Palette with color tokens (either ExpandedPalette or simple Record<string, string>)
|
|
13439
13537
|
* @returns Array of text color token names that meet contrast threshold (3:1)
|
|
13440
13538
|
*/
|
|
13441
|
-
function getLegibleTextColors(backgroundToken, palette) {
|
|
13442
|
-
if (!backgroundToken) {
|
|
13539
|
+
function getLegibleTextColors(backgroundToken$1, palette) {
|
|
13540
|
+
if (!backgroundToken$1) {
|
|
13443
13541
|
return getAllColorTokens(palette);
|
|
13444
13542
|
}
|
|
13445
|
-
const bgHex = palette[backgroundToken];
|
|
13543
|
+
const bgHex = palette[backgroundToken$1];
|
|
13446
13544
|
if (!bgHex || typeof bgHex !== "string") {
|
|
13447
13545
|
return getAllColorTokens(palette);
|
|
13448
13546
|
}
|
|
@@ -15331,12 +15429,12 @@ function resolveAccessibleSurface(input) {
|
|
|
15331
15429
|
const rejectedCandidates = [];
|
|
15332
15430
|
const recipe = surfaceRecipes[input.surface];
|
|
15333
15431
|
const threshold = contrastThresholdByPolicy[input.policy ?? "body-aa"];
|
|
15334
|
-
for (const backgroundToken of recipe.backgroundCandidates) {
|
|
15335
|
-
const backgroundHex = readPaletteHex(input.palette, backgroundToken);
|
|
15432
|
+
for (const backgroundToken$1 of recipe.backgroundCandidates) {
|
|
15433
|
+
const backgroundHex = readPaletteHex(input.palette, backgroundToken$1);
|
|
15336
15434
|
if (!backgroundHex) {
|
|
15337
15435
|
rejectedCandidates.push({
|
|
15338
15436
|
kind: "background-candidate",
|
|
15339
|
-
token: backgroundToken,
|
|
15437
|
+
token: backgroundToken$1,
|
|
15340
15438
|
reason: "missing-token"
|
|
15341
15439
|
});
|
|
15342
15440
|
continue;
|
|
@@ -15344,7 +15442,7 @@ function resolveAccessibleSurface(input) {
|
|
|
15344
15442
|
const heading = resolveRequiredForeground({
|
|
15345
15443
|
role: "heading",
|
|
15346
15444
|
candidates: recipe.headingCandidates,
|
|
15347
|
-
backgroundToken,
|
|
15445
|
+
backgroundToken: backgroundToken$1,
|
|
15348
15446
|
backgroundHex,
|
|
15349
15447
|
palette: input.palette,
|
|
15350
15448
|
threshold,
|
|
@@ -15353,7 +15451,7 @@ function resolveAccessibleSurface(input) {
|
|
|
15353
15451
|
const text = resolveRequiredForeground({
|
|
15354
15452
|
role: "text",
|
|
15355
15453
|
candidates: recipe.textCandidates,
|
|
15356
|
-
backgroundToken,
|
|
15454
|
+
backgroundToken: backgroundToken$1,
|
|
15357
15455
|
backgroundHex,
|
|
15358
15456
|
palette: input.palette,
|
|
15359
15457
|
threshold,
|
|
@@ -15362,7 +15460,7 @@ function resolveAccessibleSurface(input) {
|
|
|
15362
15460
|
const link = resolveRequiredForeground({
|
|
15363
15461
|
role: "link",
|
|
15364
15462
|
candidates: recipe.linkCandidates,
|
|
15365
|
-
backgroundToken,
|
|
15463
|
+
backgroundToken: backgroundToken$1,
|
|
15366
15464
|
backgroundHex,
|
|
15367
15465
|
palette: input.palette,
|
|
15368
15466
|
threshold,
|
|
@@ -15371,7 +15469,7 @@ function resolveAccessibleSurface(input) {
|
|
|
15371
15469
|
if (!heading || !text || !link) continue;
|
|
15372
15470
|
const supporting = resolveSupportingForeground({
|
|
15373
15471
|
candidates: recipe.supportingCandidates,
|
|
15374
|
-
backgroundToken,
|
|
15472
|
+
backgroundToken: backgroundToken$1,
|
|
15375
15473
|
backgroundHex,
|
|
15376
15474
|
text,
|
|
15377
15475
|
palette: input.palette,
|
|
@@ -15382,7 +15480,7 @@ function resolveAccessibleSurface(input) {
|
|
|
15382
15480
|
kind: "resolved-accessible-surface",
|
|
15383
15481
|
surface: input.surface,
|
|
15384
15482
|
background: {
|
|
15385
|
-
token: asAccessibleSurfaceToken(backgroundToken),
|
|
15483
|
+
token: asAccessibleSurfaceToken(backgroundToken$1),
|
|
15386
15484
|
hex: backgroundHex,
|
|
15387
15485
|
inherited: recipe.inheritedBackground
|
|
15388
15486
|
},
|
|
@@ -15481,23 +15579,23 @@ function resolveSafeToken(input) {
|
|
|
15481
15579
|
}
|
|
15482
15580
|
return null;
|
|
15483
15581
|
}
|
|
15484
|
-
function expandForegroundCandidates(candidates, backgroundToken) {
|
|
15582
|
+
function expandForegroundCandidates(candidates, backgroundToken$1) {
|
|
15485
15583
|
const seen = new Set();
|
|
15486
15584
|
const expanded = [];
|
|
15487
15585
|
for (const candidate$1 of candidates) {
|
|
15488
|
-
const token = expandForegroundCandidate(candidate$1, backgroundToken);
|
|
15586
|
+
const token = expandForegroundCandidate(candidate$1, backgroundToken$1);
|
|
15489
15587
|
if (seen.has(token)) continue;
|
|
15490
15588
|
seen.add(token);
|
|
15491
15589
|
expanded.push(token);
|
|
15492
15590
|
}
|
|
15493
15591
|
return expanded;
|
|
15494
15592
|
}
|
|
15495
|
-
function expandForegroundCandidate(candidate$1, backgroundToken) {
|
|
15593
|
+
function expandForegroundCandidate(candidate$1, backgroundToken$1) {
|
|
15496
15594
|
if (typeof candidate$1 === "string") {
|
|
15497
15595
|
return candidate$1;
|
|
15498
15596
|
}
|
|
15499
15597
|
switch (candidate$1.kind) {
|
|
15500
|
-
case "on-background": return onColorTokenName(backgroundToken);
|
|
15598
|
+
case "on-background": return onColorTokenName(backgroundToken$1);
|
|
15501
15599
|
}
|
|
15502
15600
|
}
|
|
15503
15601
|
function readPaletteHex(palette, token) {
|
|
@@ -15631,7 +15729,6 @@ function blockDesignPlanFromAppearancePreset(preset, input) {
|
|
|
15631
15729
|
return {
|
|
15632
15730
|
...planInput,
|
|
15633
15731
|
appearancePresetId: asAppearancePresetId(preset.id),
|
|
15634
|
-
transitionAfter: "none",
|
|
15635
15732
|
emphasis: "medium",
|
|
15636
15733
|
...resolveBlockAppearancePresetDesign(preset, layoutProfile ?? null)
|
|
15637
15734
|
};
|
|
@@ -16506,235 +16603,339 @@ function cardRoleFromLegacyVocabulary(value) {
|
|
|
16506
16603
|
const cardRoleWithLegacyAliasSchema = z.preprocess((value) => cardRoleFromLegacyVocabulary(value) ?? value, cardRoleSchema);
|
|
16507
16604
|
|
|
16508
16605
|
//#endregion
|
|
16509
|
-
//#region ../theme-core/src/site-styles/
|
|
16510
|
-
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16514
|
-
|
|
16515
|
-
|
|
16516
|
-
|
|
16517
|
-
|
|
16518
|
-
|
|
16519
|
-
|
|
16520
|
-
|
|
16521
|
-
|
|
16606
|
+
//#region ../theme-core/src/site-styles/runtimeBackgroundResolution.ts
|
|
16607
|
+
function parseCanonicalRuntimeBackground(content) {
|
|
16608
|
+
const sectionStyles = readRecord(content._sectionStyles);
|
|
16609
|
+
const background = readRecord(sectionStyles?.background);
|
|
16610
|
+
if (!background) return { kind: "none" };
|
|
16611
|
+
const parsed = boxBackgroundSchema.safeParse(background);
|
|
16612
|
+
if (!parsed.success) return { kind: "none" };
|
|
16613
|
+
return parsed.data.contentOwner === pageDesignEditorBackgroundOverrideOwner ? {
|
|
16614
|
+
kind: "page-design-override",
|
|
16615
|
+
background: parsed.data
|
|
16616
|
+
} : {
|
|
16617
|
+
kind: "block-authored",
|
|
16618
|
+
background: parsed.data
|
|
16522
16619
|
};
|
|
16523
16620
|
}
|
|
16524
|
-
|
|
16525
|
-
|
|
16526
|
-
|
|
16527
|
-
|
|
16528
|
-
|
|
16529
|
-
|
|
16530
|
-
}
|
|
16531
|
-
function isRatioExceeded(actualCount, totalItems, allowedRatio) {
|
|
16532
|
-
return actualCount > maxCompositionItemsWithinRatio(totalItems, allowedRatio);
|
|
16533
|
-
}
|
|
16534
|
-
function issueWhenRatioExceeded(input) {
|
|
16535
|
-
const actualRatio = ratio(input.blockIds.length, input.totalBlocks);
|
|
16536
|
-
if (!isRatioExceeded(input.blockIds.length, input.totalBlocks, input.allowedRatio)) {
|
|
16537
|
-
return null;
|
|
16621
|
+
function resolveSectionBackground(source, lookDefault) {
|
|
16622
|
+
if (source.kind === "page-design-override") {
|
|
16623
|
+
return {
|
|
16624
|
+
kind: "page-design-override",
|
|
16625
|
+
background: source.background
|
|
16626
|
+
};
|
|
16538
16627
|
}
|
|
16539
|
-
|
|
16540
|
-
kind
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
|
|
16544
|
-
|
|
16545
|
-
|
|
16546
|
-
|
|
16628
|
+
if (lookDefault) {
|
|
16629
|
+
if (source.kind === "block-authored" && (source.background.type === "image" || source.background.type === "video")) {
|
|
16630
|
+
return {
|
|
16631
|
+
kind: "block-authored",
|
|
16632
|
+
background: mergeLookForegroundWithAuthoredMedia(lookDefault, source.background)
|
|
16633
|
+
};
|
|
16634
|
+
}
|
|
16635
|
+
return {
|
|
16636
|
+
kind: "look-default",
|
|
16637
|
+
background: lookDefault
|
|
16638
|
+
};
|
|
16639
|
+
}
|
|
16640
|
+
if (source.kind === "block-authored" && (source.background.type === "image" || source.background.type === "video")) {
|
|
16641
|
+
return {
|
|
16642
|
+
kind: "block-authored",
|
|
16643
|
+
background: source.background
|
|
16644
|
+
};
|
|
16645
|
+
}
|
|
16646
|
+
return source.kind === "block-authored" ? {
|
|
16647
|
+
kind: "block-authored",
|
|
16648
|
+
background: source.background
|
|
16649
|
+
} : { kind: "none" };
|
|
16547
16650
|
}
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
return block.appliedContentFrame.kind !== "plain" || block.appliedCardRole != null && block.appliedCardRole !== "none";
|
|
16651
|
+
function resolveSectionForeground(background, palette) {
|
|
16652
|
+
return resolveSurfaceForeground(background.kind === "none" ? null : background.background, palette, {}, { compositeBase: "background" });
|
|
16551
16653
|
}
|
|
16552
|
-
/**
|
|
16553
|
-
|
|
16554
|
-
|
|
16654
|
+
/**
|
|
16655
|
+
* Read foreground authority from post-compiler block content. The preview
|
|
16656
|
+
* compiler has already materialized any Look-owned background into
|
|
16657
|
+
* `_sectionStyles`; raw authored content must be composed with its Look through
|
|
16658
|
+
* `resolveSectionBackground` instead.
|
|
16659
|
+
*/
|
|
16660
|
+
function resolveCompiledSectionForegroundFromContent(content, palette) {
|
|
16661
|
+
if (!content) return resolveSurfaceForeground(null, palette);
|
|
16662
|
+
return resolveSectionForeground(resolveSectionBackground(parseCanonicalRuntimeBackground(content), null), palette);
|
|
16555
16663
|
}
|
|
16556
|
-
|
|
16557
|
-
|
|
16558
|
-
|
|
16664
|
+
function mergeLookForegroundWithAuthoredMedia(lookDefault, authored) {
|
|
16665
|
+
const merged = boxBackgroundSchema.safeParse({
|
|
16666
|
+
...lookDefault,
|
|
16667
|
+
type: authored.type,
|
|
16668
|
+
image: authored.image,
|
|
16669
|
+
objectFit: authored.objectFit,
|
|
16670
|
+
scale: authored.scale,
|
|
16671
|
+
position: authored.position
|
|
16672
|
+
});
|
|
16673
|
+
return merged.success ? merged.data : authored;
|
|
16559
16674
|
}
|
|
16560
|
-
function
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
|
|
16565
|
-
|
|
16566
|
-
|
|
16567
|
-
|
|
16568
|
-
|
|
16569
|
-
|
|
16570
|
-
|
|
16571
|
-
|
|
16572
|
-
|
|
16573
|
-
|
|
16574
|
-
|
|
16675
|
+
function readRecord(value) {
|
|
16676
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
16677
|
+
}
|
|
16678
|
+
|
|
16679
|
+
//#endregion
|
|
16680
|
+
//#region ../theme-core/src/site-styles/transitionCatalogue.ts
|
|
16681
|
+
/**
|
|
16682
|
+
* Family order for pickers. Entries below are listed family by family in this
|
|
16683
|
+
* same order, so the flat option list and the grouped families agree.
|
|
16684
|
+
*/
|
|
16685
|
+
const transitionCatalogueFamilies = [
|
|
16686
|
+
{
|
|
16687
|
+
id: "gradient",
|
|
16688
|
+
label: "Gradient"
|
|
16689
|
+
},
|
|
16690
|
+
{
|
|
16691
|
+
id: "wave",
|
|
16692
|
+
label: "Wave"
|
|
16693
|
+
},
|
|
16694
|
+
{
|
|
16695
|
+
id: "angle",
|
|
16696
|
+
label: "Angle"
|
|
16575
16697
|
}
|
|
16576
|
-
|
|
16577
|
-
|
|
16578
|
-
|
|
16579
|
-
|
|
16580
|
-
budget: budget.accentDensity,
|
|
16581
|
-
blockIds: accentBlockIds,
|
|
16582
|
-
totalBlocks,
|
|
16583
|
-
allowedRatio: compositionDensityRatioLimits[budget.accentDensity]
|
|
16584
|
-
});
|
|
16585
|
-
if (accentIssue) {
|
|
16586
|
-
issues.push(accentIssue);
|
|
16587
|
-
}
|
|
16588
|
-
const panelBlockIds = resolved.blocks.filter(hasPanelFrameOrCardSurface).map((block) => block.blockId);
|
|
16589
|
-
const panelIssue = issueWhenRatioExceeded({
|
|
16590
|
-
kind: "panel-density-exceeded",
|
|
16591
|
-
policy,
|
|
16592
|
-
budget: budget.panelDensity,
|
|
16593
|
-
blockIds: panelBlockIds,
|
|
16594
|
-
totalBlocks,
|
|
16595
|
-
allowedRatio: compositionDensityRatioLimits[budget.panelDensity]
|
|
16596
|
-
});
|
|
16597
|
-
if (panelIssue) {
|
|
16598
|
-
issues.push(panelIssue);
|
|
16599
|
-
}
|
|
16600
|
-
const transitionBlockIds = resolved.blocks.filter((block) => block.appliedTransitionAfter !== "none").map((block) => block.blockId);
|
|
16601
|
-
const transitionIssue = issueWhenRatioExceeded({
|
|
16602
|
-
kind: "transition-mix-exceeded",
|
|
16603
|
-
policy,
|
|
16604
|
-
budget: budget.transitionMix,
|
|
16605
|
-
blockIds: transitionBlockIds,
|
|
16606
|
-
totalBlocks,
|
|
16607
|
-
allowedRatio: compositionTransitionMixRatioLimits[budget.transitionMix]
|
|
16608
|
-
});
|
|
16609
|
-
if (transitionIssue) {
|
|
16610
|
-
issues.push(transitionIssue);
|
|
16611
|
-
}
|
|
16612
|
-
const ctaContexts = knownBlockContexts.filter((context) => (context.primaryCtaCount ?? 0) > 0);
|
|
16613
|
-
const actualPrimaryCtaCount = ctaContexts.reduce((sum, context) => sum + (context.primaryCtaCount ?? 0), 0);
|
|
16614
|
-
if (actualPrimaryCtaCount > budget.primaryCtaLimit) {
|
|
16615
|
-
issues.push({
|
|
16616
|
-
kind: "primary-cta-limit-exceeded",
|
|
16617
|
-
actualCount: actualPrimaryCtaCount,
|
|
16618
|
-
allowedCount: budget.primaryCtaLimit,
|
|
16619
|
-
blockIds: ctaContexts.map((context) => context.blockId),
|
|
16620
|
-
...issueMetadata(policy, ["reduce-primary-ctas"])
|
|
16621
|
-
});
|
|
16622
|
-
}
|
|
16623
|
-
const mediaBlockIds = resolved.blocks.filter((block) => hasMediaAnnotation(contextsByBlockId.get(block.blockId))).map((block) => block.blockId);
|
|
16624
|
-
const mediaIssue = issueWhenRatioExceeded({
|
|
16625
|
-
kind: "media-density-exceeded",
|
|
16626
|
-
policy,
|
|
16627
|
-
budget: budget.mediaDensity,
|
|
16628
|
-
blockIds: mediaBlockIds,
|
|
16629
|
-
totalBlocks,
|
|
16630
|
-
allowedRatio: compositionDensityRatioLimits[budget.mediaDensity]
|
|
16631
|
-
});
|
|
16632
|
-
if (mediaIssue) {
|
|
16633
|
-
issues.push(mediaIssue);
|
|
16634
|
-
}
|
|
16635
|
-
const decorativeBlockIds = resolved.blocks.filter((block) => hasDecorativeAnnotation(contextsByBlockId.get(block.blockId))).map((block) => block.blockId);
|
|
16636
|
-
const decorativeIssue = issueWhenRatioExceeded({
|
|
16637
|
-
kind: "decorative-repetition-exceeded",
|
|
16638
|
-
policy,
|
|
16639
|
-
budget: budget.decorativeRepetition,
|
|
16640
|
-
blockIds: decorativeBlockIds,
|
|
16641
|
-
totalBlocks,
|
|
16642
|
-
allowedRatio: compositionDensityRatioLimits[budget.decorativeRepetition]
|
|
16643
|
-
});
|
|
16644
|
-
if (decorativeIssue) {
|
|
16645
|
-
issues.push(decorativeIssue);
|
|
16646
|
-
}
|
|
16647
|
-
return issues;
|
|
16648
|
-
}
|
|
16649
|
-
|
|
16650
|
-
//#endregion
|
|
16651
|
-
//#region ../theme-core/src/site-styles/compilationPlan.ts
|
|
16652
|
-
const defaultHeaderBrandPreferences = {
|
|
16653
|
-
brandDisplay: "auto",
|
|
16654
|
-
logoSize: "auto"
|
|
16655
|
-
};
|
|
16656
|
-
function headerBrandPreferencesFromTheme(theme) {
|
|
16657
|
-
return {
|
|
16658
|
-
brandDisplay: theme?.header.logo?.brandDisplay ?? defaultHeaderBrandPreferences.brandDisplay,
|
|
16659
|
-
logoSize: theme?.header.logo?.size ?? defaultHeaderBrandPreferences.logoSize
|
|
16660
|
-
};
|
|
16661
|
-
}
|
|
16662
|
-
function replaceSiteStyleCompilationPlan(input) {
|
|
16663
|
-
return {
|
|
16664
|
-
kind: "replace-site-style",
|
|
16665
|
-
buttons: {
|
|
16666
|
-
kind: "recompile",
|
|
16667
|
-
selection: input.buttonStyleSelection ?? null,
|
|
16668
|
-
reason: "site-style-replacement"
|
|
16669
|
-
},
|
|
16670
|
-
header: {
|
|
16671
|
-
kind: "recompile",
|
|
16672
|
-
selection: input.headerSelection,
|
|
16673
|
-
brandPresentation: input.headerLogo === undefined ? { kind: "use-compiled-defaults" } : {
|
|
16674
|
-
kind: "apply-logo-context",
|
|
16675
|
-
logo: input.headerLogo
|
|
16676
|
-
}
|
|
16677
|
-
},
|
|
16678
|
-
footerLookId: input.footerLookId ?? null
|
|
16679
|
-
};
|
|
16680
|
-
}
|
|
16698
|
+
];
|
|
16699
|
+
const mediumHeight = "6rem + 2px";
|
|
16700
|
+
const compactHeight = "4.5rem + 2px";
|
|
16701
|
+
const largeHeight = "7rem + 2px";
|
|
16681
16702
|
/**
|
|
16682
|
-
*
|
|
16703
|
+
* The single source of transition vocabulary. Order is significant: it is the
|
|
16704
|
+
* order of `boundaryOptions` (after `none`) and of each family's variants,
|
|
16705
|
+
* which persisted pins, page-flow presets and the editor picker all rely on.
|
|
16683
16706
|
*
|
|
16684
|
-
*
|
|
16685
|
-
*
|
|
16707
|
+
* Shapes match what `generateLayoutCss` draws today. Structured
|
|
16708
|
+
* amplitude/frequency treatments (issue 826) extend this list later.
|
|
16686
16709
|
*/
|
|
16687
|
-
|
|
16688
|
-
|
|
16689
|
-
|
|
16690
|
-
|
|
16691
|
-
|
|
16692
|
-
|
|
16693
|
-
|
|
16694
|
-
|
|
16695
|
-
|
|
16696
|
-
|
|
16697
|
-
|
|
16698
|
-
|
|
16699
|
-
|
|
16700
|
-
|
|
16701
|
-
|
|
16702
|
-
|
|
16710
|
+
const transitionCatalogueEntries = defineExactCatalog()([
|
|
16711
|
+
{
|
|
16712
|
+
intent: "soft-fade-short",
|
|
16713
|
+
optionId: asBoundaryOptionId("break:soft"),
|
|
16714
|
+
family: "gradient",
|
|
16715
|
+
variantId: "soft",
|
|
16716
|
+
label: "Soft",
|
|
16717
|
+
variantLabel: "Soft",
|
|
16718
|
+
treatment: {
|
|
16719
|
+
kind: "soft-fade",
|
|
16720
|
+
height: "medium",
|
|
16721
|
+
curve: "soft"
|
|
16722
|
+
},
|
|
16723
|
+
size: "medium",
|
|
16724
|
+
heightExpression: mediumHeight,
|
|
16725
|
+
shape: { kind: "fade" }
|
|
16726
|
+
},
|
|
16727
|
+
{
|
|
16728
|
+
intent: "soft-fade-long",
|
|
16729
|
+
optionId: asBoundaryOptionId("break:spacious"),
|
|
16730
|
+
family: "gradient",
|
|
16731
|
+
variantId: "spacious",
|
|
16732
|
+
label: "Spacious",
|
|
16733
|
+
variantLabel: "Spacious",
|
|
16734
|
+
treatment: {
|
|
16735
|
+
kind: "soft-fade",
|
|
16736
|
+
height: "large",
|
|
16737
|
+
curve: "spacious"
|
|
16738
|
+
},
|
|
16739
|
+
size: "spacious",
|
|
16740
|
+
heightExpression: "10rem",
|
|
16741
|
+
shape: { kind: "fade" }
|
|
16742
|
+
},
|
|
16743
|
+
{
|
|
16744
|
+
intent: "soft-fade-expansive",
|
|
16745
|
+
optionId: asBoundaryOptionId("break:expansive"),
|
|
16746
|
+
family: "gradient",
|
|
16747
|
+
variantId: "expansive",
|
|
16748
|
+
label: "Expansive",
|
|
16749
|
+
variantLabel: "Expansive",
|
|
16750
|
+
treatment: {
|
|
16751
|
+
kind: "soft-fade",
|
|
16752
|
+
height: "expansive",
|
|
16753
|
+
curve: "expansive"
|
|
16754
|
+
},
|
|
16755
|
+
size: "expansive",
|
|
16756
|
+
heightExpression: "14rem",
|
|
16757
|
+
shape: { kind: "fade" }
|
|
16758
|
+
},
|
|
16759
|
+
{
|
|
16760
|
+
intent: "wave-edge-balanced",
|
|
16761
|
+
optionId: asBoundaryOptionId("break:wave-balanced"),
|
|
16762
|
+
family: "wave",
|
|
16763
|
+
variantId: "balanced",
|
|
16764
|
+
label: "Balanced wave",
|
|
16765
|
+
variantLabel: "Balanced",
|
|
16766
|
+
treatment: {
|
|
16767
|
+
kind: "wave-edge",
|
|
16768
|
+
height: "medium",
|
|
16769
|
+
amplitude: "balanced",
|
|
16770
|
+
rhythm: "double",
|
|
16771
|
+
symmetry: "symmetrical"
|
|
16772
|
+
},
|
|
16773
|
+
size: "medium",
|
|
16774
|
+
heightExpression: mediumHeight,
|
|
16775
|
+
shape: {
|
|
16776
|
+
kind: "wave",
|
|
16777
|
+
mask: "balanced"
|
|
16778
|
+
}
|
|
16779
|
+
},
|
|
16780
|
+
{
|
|
16781
|
+
intent: "wave-edge",
|
|
16782
|
+
optionId: asBoundaryOptionId("break:wave"),
|
|
16783
|
+
family: "wave",
|
|
16784
|
+
variantId: "classic",
|
|
16785
|
+
label: "Classic wave",
|
|
16786
|
+
variantLabel: "Classic",
|
|
16787
|
+
treatment: {
|
|
16788
|
+
kind: "wave-edge",
|
|
16789
|
+
height: "medium",
|
|
16790
|
+
amplitude: "balanced",
|
|
16791
|
+
rhythm: "double",
|
|
16792
|
+
symmetry: "asymmetrical"
|
|
16793
|
+
},
|
|
16794
|
+
size: "medium",
|
|
16795
|
+
heightExpression: mediumHeight,
|
|
16796
|
+
shape: {
|
|
16797
|
+
kind: "wave",
|
|
16798
|
+
mask: "classic"
|
|
16799
|
+
}
|
|
16800
|
+
},
|
|
16801
|
+
{
|
|
16802
|
+
intent: "wave-edge-gentle",
|
|
16803
|
+
optionId: asBoundaryOptionId("break:wave-gentle"),
|
|
16804
|
+
family: "wave",
|
|
16805
|
+
variantId: "gentle",
|
|
16806
|
+
label: "Gentle wave",
|
|
16807
|
+
variantLabel: "Gentle",
|
|
16808
|
+
treatment: {
|
|
16809
|
+
kind: "wave-edge",
|
|
16810
|
+
height: "compact",
|
|
16811
|
+
amplitude: "subtle",
|
|
16812
|
+
rhythm: "single",
|
|
16813
|
+
symmetry: "symmetrical"
|
|
16814
|
+
},
|
|
16815
|
+
size: "compact",
|
|
16816
|
+
heightExpression: compactHeight,
|
|
16817
|
+
shape: {
|
|
16818
|
+
kind: "wave",
|
|
16819
|
+
mask: "gentle"
|
|
16820
|
+
}
|
|
16821
|
+
},
|
|
16822
|
+
{
|
|
16823
|
+
intent: "wave-edge-bold",
|
|
16824
|
+
optionId: asBoundaryOptionId("break:wave-bold"),
|
|
16825
|
+
family: "wave",
|
|
16826
|
+
variantId: "bold",
|
|
16827
|
+
label: "Bold wave",
|
|
16828
|
+
variantLabel: "Bold",
|
|
16829
|
+
treatment: {
|
|
16830
|
+
kind: "wave-edge",
|
|
16831
|
+
height: "large",
|
|
16832
|
+
amplitude: "bold",
|
|
16833
|
+
rhythm: "double",
|
|
16834
|
+
symmetry: "symmetrical"
|
|
16835
|
+
},
|
|
16836
|
+
size: "large",
|
|
16837
|
+
heightExpression: largeHeight,
|
|
16838
|
+
shape: {
|
|
16839
|
+
kind: "wave",
|
|
16840
|
+
mask: "bold"
|
|
16841
|
+
}
|
|
16842
|
+
},
|
|
16843
|
+
{
|
|
16844
|
+
intent: "wave-edge-drift",
|
|
16845
|
+
optionId: asBoundaryOptionId("break:wave-drift"),
|
|
16846
|
+
family: "wave",
|
|
16847
|
+
variantId: "drift",
|
|
16848
|
+
label: "Drift wave",
|
|
16849
|
+
variantLabel: "Drift",
|
|
16850
|
+
treatment: {
|
|
16851
|
+
kind: "wave-edge",
|
|
16852
|
+
height: "medium",
|
|
16853
|
+
amplitude: "balanced",
|
|
16854
|
+
rhythm: "double",
|
|
16855
|
+
symmetry: "drift"
|
|
16856
|
+
},
|
|
16857
|
+
size: "medium",
|
|
16858
|
+
heightExpression: mediumHeight,
|
|
16859
|
+
shape: {
|
|
16860
|
+
kind: "wave",
|
|
16861
|
+
mask: "drift"
|
|
16862
|
+
}
|
|
16863
|
+
},
|
|
16864
|
+
{
|
|
16865
|
+
intent: "angle-edge-subtle",
|
|
16866
|
+
optionId: asBoundaryOptionId("break:angle-subtle"),
|
|
16867
|
+
family: "angle",
|
|
16868
|
+
variantId: "subtle",
|
|
16869
|
+
label: "Subtle angle",
|
|
16870
|
+
variantLabel: "Subtle",
|
|
16871
|
+
treatment: {
|
|
16872
|
+
kind: "angle-edge",
|
|
16873
|
+
height: "compact",
|
|
16874
|
+
slope: "subtle",
|
|
16875
|
+
direction: "forward"
|
|
16876
|
+
},
|
|
16877
|
+
size: "compact",
|
|
16878
|
+
heightExpression: compactHeight,
|
|
16879
|
+
shape: {
|
|
16880
|
+
kind: "angle",
|
|
16881
|
+
polygon: {
|
|
16882
|
+
startTopPercent: 34,
|
|
16883
|
+
endTopPercent: 18
|
|
16703
16884
|
}
|
|
16704
16885
|
}
|
|
16705
|
-
}
|
|
16706
|
-
|
|
16707
|
-
|
|
16708
|
-
|
|
16709
|
-
|
|
16710
|
-
|
|
16711
|
-
|
|
16712
|
-
|
|
16713
|
-
|
|
16714
|
-
|
|
16715
|
-
|
|
16716
|
-
|
|
16717
|
-
|
|
16718
|
-
|
|
16719
|
-
|
|
16886
|
+
},
|
|
16887
|
+
{
|
|
16888
|
+
intent: "angle-edge",
|
|
16889
|
+
optionId: asBoundaryOptionId("break:angle-balanced"),
|
|
16890
|
+
family: "angle",
|
|
16891
|
+
variantId: "balanced",
|
|
16892
|
+
label: "Balanced angle",
|
|
16893
|
+
variantLabel: "Balanced",
|
|
16894
|
+
treatment: {
|
|
16895
|
+
kind: "angle-edge",
|
|
16896
|
+
height: "medium",
|
|
16897
|
+
slope: "balanced",
|
|
16898
|
+
direction: "forward"
|
|
16899
|
+
},
|
|
16900
|
+
size: "medium",
|
|
16901
|
+
heightExpression: mediumHeight,
|
|
16902
|
+
shape: {
|
|
16903
|
+
kind: "angle",
|
|
16904
|
+
polygon: {
|
|
16905
|
+
startTopPercent: 42,
|
|
16906
|
+
endTopPercent: 8
|
|
16720
16907
|
}
|
|
16721
|
-
}
|
|
16722
|
-
}
|
|
16723
|
-
|
|
16724
|
-
|
|
16725
|
-
|
|
16726
|
-
|
|
16727
|
-
|
|
16728
|
-
|
|
16729
|
-
|
|
16730
|
-
|
|
16908
|
+
}
|
|
16909
|
+
},
|
|
16910
|
+
{
|
|
16911
|
+
intent: "angle-edge-steep",
|
|
16912
|
+
optionId: asBoundaryOptionId("break:angle-steep"),
|
|
16913
|
+
family: "angle",
|
|
16914
|
+
variantId: "steep",
|
|
16915
|
+
label: "Steep angle",
|
|
16916
|
+
variantLabel: "Steep",
|
|
16917
|
+
treatment: {
|
|
16918
|
+
kind: "angle-edge",
|
|
16919
|
+
height: "large",
|
|
16920
|
+
slope: "steep",
|
|
16921
|
+
direction: "forward"
|
|
16922
|
+
},
|
|
16923
|
+
size: "large",
|
|
16924
|
+
heightExpression: largeHeight,
|
|
16925
|
+
shape: {
|
|
16926
|
+
kind: "angle",
|
|
16927
|
+
polygon: {
|
|
16928
|
+
startTopPercent: 54,
|
|
16929
|
+
endTopPercent: 0
|
|
16731
16930
|
}
|
|
16732
|
-
}
|
|
16931
|
+
}
|
|
16733
16932
|
}
|
|
16734
|
-
|
|
16735
|
-
|
|
16736
|
-
|
|
16737
|
-
|
|
16933
|
+
]);
|
|
16934
|
+
const transitionCatalogueCoversEveryIntentOnce = true;
|
|
16935
|
+
void transitionCatalogueCoversEveryIntentOnce;
|
|
16936
|
+
/** CSS `clip-path` value for an angle shape, as `generateLayoutCss` draws it. */
|
|
16937
|
+
function anglePolygonCss(polygon) {
|
|
16938
|
+
return `polygon(0 ${polygon.startTopPercent}%, 100% ${polygon.endTopPercent}%, 100% 100%, 0 100%)`;
|
|
16738
16939
|
}
|
|
16739
16940
|
|
|
16740
16941
|
//#endregion
|
|
@@ -16747,22 +16948,27 @@ function boundaryRuntimeMetrics(family, size, heightExpression) {
|
|
|
16747
16948
|
reserveCss: `calc((${heightExpression}) / 2)`
|
|
16748
16949
|
};
|
|
16749
16950
|
}
|
|
16750
|
-
const
|
|
16751
|
-
|
|
16752
|
-
|
|
16753
|
-
|
|
16754
|
-
|
|
16755
|
-
|
|
16756
|
-
|
|
16757
|
-
|
|
16758
|
-
|
|
16759
|
-
|
|
16760
|
-
|
|
16761
|
-
|
|
16762
|
-
|
|
16763
|
-
|
|
16764
|
-
|
|
16765
|
-
|
|
16951
|
+
const catalogueEntryByIntent = new Map(transitionCatalogueEntries.map((entry) => [entry.intent, entry]));
|
|
16952
|
+
const metricsByIntent = new Map(transitionCatalogueEntries.map((entry) => [entry.intent, boundaryRuntimeMetrics(entry.family, entry.size, entry.heightExpression)]));
|
|
16953
|
+
/**
|
|
16954
|
+
* The catalogue's compile-time coverage check guarantees an entry per
|
|
16955
|
+
* decorative intent, so a miss here is a broken invariant, not bad input.
|
|
16956
|
+
*/
|
|
16957
|
+
function requireCatalogueValue(values, intent) {
|
|
16958
|
+
const value = values.get(intent);
|
|
16959
|
+
if (value === undefined) {
|
|
16960
|
+
throw new Error(`Transition catalogue has no entry for ${intent}`);
|
|
16961
|
+
}
|
|
16962
|
+
return value;
|
|
16963
|
+
}
|
|
16964
|
+
function transitionCatalogueEntryForIntent(intent) {
|
|
16965
|
+
return requireCatalogueValue(catalogueEntryByIntent, intent);
|
|
16966
|
+
}
|
|
16967
|
+
function isDecorativeTransitionIntent(transition) {
|
|
16968
|
+
return transition !== "none";
|
|
16969
|
+
}
|
|
16970
|
+
function boundaryRuntimeMetricsForDecorativeTransition(transition) {
|
|
16971
|
+
return requireCatalogueValue(metricsByIntent, transition);
|
|
16766
16972
|
}
|
|
16767
16973
|
const noneBoundaryOption = {
|
|
16768
16974
|
id: asBoundaryOptionId("break:none"),
|
|
@@ -16770,264 +16976,63 @@ const noneBoundaryOption = {
|
|
|
16770
16976
|
transitionAfter: "none",
|
|
16771
16977
|
treatment: { kind: "none" }
|
|
16772
16978
|
};
|
|
16773
|
-
const
|
|
16774
|
-
id:
|
|
16775
|
-
label:
|
|
16776
|
-
transitionAfter:
|
|
16777
|
-
treatment:
|
|
16778
|
-
|
|
16779
|
-
|
|
16780
|
-
|
|
16781
|
-
|
|
16782
|
-
|
|
16783
|
-
const spaciousBoundaryOption =
|
|
16784
|
-
|
|
16785
|
-
|
|
16786
|
-
|
|
16787
|
-
|
|
16788
|
-
|
|
16789
|
-
|
|
16790
|
-
|
|
16791
|
-
|
|
16792
|
-
|
|
16793
|
-
|
|
16794
|
-
|
|
16795
|
-
|
|
16796
|
-
|
|
16797
|
-
treatment: {
|
|
16798
|
-
kind: "soft-fade",
|
|
16799
|
-
height: "expansive",
|
|
16800
|
-
curve: "expansive"
|
|
16801
|
-
}
|
|
16802
|
-
};
|
|
16803
|
-
const waveBoundaryOption = {
|
|
16804
|
-
id: asBoundaryOptionId("break:wave"),
|
|
16805
|
-
label: "Classic wave",
|
|
16806
|
-
transitionAfter: "wave-edge",
|
|
16807
|
-
treatment: {
|
|
16808
|
-
kind: "wave-edge",
|
|
16809
|
-
height: "medium",
|
|
16810
|
-
amplitude: "balanced",
|
|
16811
|
-
rhythm: "double",
|
|
16812
|
-
symmetry: "asymmetrical"
|
|
16813
|
-
}
|
|
16814
|
-
};
|
|
16815
|
-
const balancedWaveBoundaryOption = {
|
|
16816
|
-
id: asBoundaryOptionId("break:wave-balanced"),
|
|
16817
|
-
label: "Balanced wave",
|
|
16818
|
-
transitionAfter: "wave-edge-balanced",
|
|
16819
|
-
treatment: {
|
|
16820
|
-
kind: "wave-edge",
|
|
16821
|
-
height: "medium",
|
|
16822
|
-
amplitude: "balanced",
|
|
16823
|
-
rhythm: "double",
|
|
16824
|
-
symmetry: "symmetrical"
|
|
16825
|
-
}
|
|
16826
|
-
};
|
|
16827
|
-
const gentleWaveBoundaryOption = {
|
|
16828
|
-
id: asBoundaryOptionId("break:wave-gentle"),
|
|
16829
|
-
label: "Gentle wave",
|
|
16830
|
-
transitionAfter: "wave-edge-gentle",
|
|
16831
|
-
treatment: {
|
|
16832
|
-
kind: "wave-edge",
|
|
16833
|
-
height: "compact",
|
|
16834
|
-
amplitude: "subtle",
|
|
16835
|
-
rhythm: "single",
|
|
16836
|
-
symmetry: "symmetrical"
|
|
16837
|
-
}
|
|
16838
|
-
};
|
|
16839
|
-
const boldWaveBoundaryOption = {
|
|
16840
|
-
id: asBoundaryOptionId("break:wave-bold"),
|
|
16841
|
-
label: "Bold wave",
|
|
16842
|
-
transitionAfter: "wave-edge-bold",
|
|
16843
|
-
treatment: {
|
|
16844
|
-
kind: "wave-edge",
|
|
16845
|
-
height: "large",
|
|
16846
|
-
amplitude: "bold",
|
|
16847
|
-
rhythm: "double",
|
|
16848
|
-
symmetry: "symmetrical"
|
|
16849
|
-
}
|
|
16850
|
-
};
|
|
16851
|
-
const driftWaveBoundaryOption = {
|
|
16852
|
-
id: asBoundaryOptionId("break:wave-drift"),
|
|
16853
|
-
label: "Drift wave",
|
|
16854
|
-
transitionAfter: "wave-edge-drift",
|
|
16855
|
-
treatment: {
|
|
16856
|
-
kind: "wave-edge",
|
|
16857
|
-
height: "medium",
|
|
16858
|
-
amplitude: "balanced",
|
|
16859
|
-
rhythm: "double",
|
|
16860
|
-
symmetry: "drift"
|
|
16861
|
-
}
|
|
16862
|
-
};
|
|
16863
|
-
const subtleAngleBoundaryOption = {
|
|
16864
|
-
id: asBoundaryOptionId("break:angle-subtle"),
|
|
16865
|
-
label: "Subtle angle",
|
|
16866
|
-
transitionAfter: "angle-edge-subtle",
|
|
16867
|
-
treatment: {
|
|
16868
|
-
kind: "angle-edge",
|
|
16869
|
-
height: "compact",
|
|
16870
|
-
slope: "subtle",
|
|
16871
|
-
direction: "forward"
|
|
16872
|
-
}
|
|
16873
|
-
};
|
|
16874
|
-
const balancedAngleBoundaryOption = {
|
|
16875
|
-
id: asBoundaryOptionId("break:angle-balanced"),
|
|
16876
|
-
label: "Balanced angle",
|
|
16877
|
-
transitionAfter: "angle-edge",
|
|
16878
|
-
treatment: {
|
|
16879
|
-
kind: "angle-edge",
|
|
16880
|
-
height: "medium",
|
|
16881
|
-
slope: "balanced",
|
|
16882
|
-
direction: "forward"
|
|
16883
|
-
}
|
|
16884
|
-
};
|
|
16885
|
-
const steepAngleBoundaryOption = {
|
|
16886
|
-
id: asBoundaryOptionId("break:angle-steep"),
|
|
16887
|
-
label: "Steep angle",
|
|
16888
|
-
transitionAfter: "angle-edge-steep",
|
|
16889
|
-
treatment: {
|
|
16890
|
-
kind: "angle-edge",
|
|
16891
|
-
height: "large",
|
|
16892
|
-
slope: "steep",
|
|
16893
|
-
direction: "forward"
|
|
16894
|
-
}
|
|
16895
|
-
};
|
|
16979
|
+
const boundaryOptionByIntent = new Map(transitionCatalogueEntries.map((entry) => [entry.intent, {
|
|
16980
|
+
id: entry.optionId,
|
|
16981
|
+
label: entry.label,
|
|
16982
|
+
transitionAfter: entry.intent,
|
|
16983
|
+
treatment: entry.treatment
|
|
16984
|
+
}]));
|
|
16985
|
+
function boundaryOptionForTransitionIntent(intent) {
|
|
16986
|
+
return requireCatalogueValue(boundaryOptionByIntent, intent);
|
|
16987
|
+
}
|
|
16988
|
+
const softBoundaryOption = boundaryOptionForTransitionIntent("soft-fade-short");
|
|
16989
|
+
const spaciousBoundaryOption = boundaryOptionForTransitionIntent("soft-fade-long");
|
|
16990
|
+
const expansiveBoundaryOption = boundaryOptionForTransitionIntent("soft-fade-expansive");
|
|
16991
|
+
const waveBoundaryOption = boundaryOptionForTransitionIntent("wave-edge");
|
|
16992
|
+
const balancedWaveBoundaryOption = boundaryOptionForTransitionIntent("wave-edge-balanced");
|
|
16993
|
+
const gentleWaveBoundaryOption = boundaryOptionForTransitionIntent("wave-edge-gentle");
|
|
16994
|
+
const boldWaveBoundaryOption = boundaryOptionForTransitionIntent("wave-edge-bold");
|
|
16995
|
+
const driftWaveBoundaryOption = boundaryOptionForTransitionIntent("wave-edge-drift");
|
|
16996
|
+
const subtleAngleBoundaryOption = boundaryOptionForTransitionIntent("angle-edge-subtle");
|
|
16997
|
+
const balancedAngleBoundaryOption = boundaryOptionForTransitionIntent("angle-edge");
|
|
16998
|
+
const steepAngleBoundaryOption = boundaryOptionForTransitionIntent("angle-edge-steep");
|
|
16999
|
+
/**
|
|
17000
|
+
* Must remain non-empty; downstream code indexes `[0]` as the documented default.
|
|
17001
|
+
*/
|
|
17002
|
+
const boundaryOptions = [noneBoundaryOption, ...transitionCatalogueEntries.map((entry) => boundaryOptionForTransitionIntent(entry.intent))];
|
|
16896
17003
|
const noneTransitionVariant = {
|
|
16897
17004
|
familyId: "none",
|
|
16898
17005
|
variantId: "none",
|
|
16899
17006
|
label: "None",
|
|
16900
17007
|
boundaryOption: noneBoundaryOption
|
|
16901
17008
|
};
|
|
16902
|
-
|
|
16903
|
-
|
|
16904
|
-
|
|
16905
|
-
|
|
16906
|
-
|
|
16907
|
-
|
|
16908
|
-
|
|
16909
|
-
|
|
16910
|
-
|
|
16911
|
-
|
|
16912
|
-
|
|
16913
|
-
|
|
16914
|
-
|
|
16915
|
-
|
|
16916
|
-
|
|
16917
|
-
|
|
16918
|
-
|
|
16919
|
-
|
|
16920
|
-
const
|
|
16921
|
-
|
|
16922
|
-
|
|
16923
|
-
label: "Balanced",
|
|
16924
|
-
boundaryOption: balancedWaveBoundaryOption
|
|
16925
|
-
};
|
|
16926
|
-
const classicWaveTransitionVariant = {
|
|
16927
|
-
familyId: "wave",
|
|
16928
|
-
variantId: "classic",
|
|
16929
|
-
label: "Classic",
|
|
16930
|
-
boundaryOption: waveBoundaryOption
|
|
16931
|
-
};
|
|
16932
|
-
const gentleWaveTransitionVariant = {
|
|
16933
|
-
familyId: "wave",
|
|
16934
|
-
variantId: "gentle",
|
|
16935
|
-
label: "Gentle",
|
|
16936
|
-
boundaryOption: gentleWaveBoundaryOption
|
|
16937
|
-
};
|
|
16938
|
-
const boldWaveTransitionVariant = {
|
|
16939
|
-
familyId: "wave",
|
|
16940
|
-
variantId: "bold",
|
|
16941
|
-
label: "Bold",
|
|
16942
|
-
boundaryOption: boldWaveBoundaryOption
|
|
16943
|
-
};
|
|
16944
|
-
const driftWaveTransitionVariant = {
|
|
16945
|
-
familyId: "wave",
|
|
16946
|
-
variantId: "drift",
|
|
16947
|
-
label: "Drift",
|
|
16948
|
-
boundaryOption: driftWaveBoundaryOption
|
|
16949
|
-
};
|
|
16950
|
-
const subtleAngleTransitionVariant = {
|
|
16951
|
-
familyId: "angle",
|
|
16952
|
-
variantId: "subtle",
|
|
16953
|
-
label: "Subtle",
|
|
16954
|
-
boundaryOption: subtleAngleBoundaryOption
|
|
16955
|
-
};
|
|
16956
|
-
const balancedAngleTransitionVariant = {
|
|
16957
|
-
familyId: "angle",
|
|
16958
|
-
variantId: "balanced",
|
|
16959
|
-
label: "Balanced",
|
|
16960
|
-
boundaryOption: balancedAngleBoundaryOption
|
|
16961
|
-
};
|
|
16962
|
-
const steepAngleTransitionVariant = {
|
|
16963
|
-
familyId: "angle",
|
|
16964
|
-
variantId: "steep",
|
|
16965
|
-
label: "Steep",
|
|
16966
|
-
boundaryOption: steepAngleBoundaryOption
|
|
16967
|
-
};
|
|
16968
|
-
const sectionTransitionFamilies = [
|
|
16969
|
-
{
|
|
16970
|
-
id: "none",
|
|
16971
|
-
label: "None",
|
|
16972
|
-
variants: [noneTransitionVariant]
|
|
16973
|
-
},
|
|
16974
|
-
{
|
|
16975
|
-
id: "gradient",
|
|
16976
|
-
label: "Gradient",
|
|
16977
|
-
variants: [
|
|
16978
|
-
softGradientTransitionVariant,
|
|
16979
|
-
spaciousGradientTransitionVariant,
|
|
16980
|
-
expansiveGradientTransitionVariant
|
|
16981
|
-
]
|
|
16982
|
-
},
|
|
16983
|
-
{
|
|
16984
|
-
id: "wave",
|
|
16985
|
-
label: "Wave",
|
|
16986
|
-
variants: [
|
|
16987
|
-
balancedWaveTransitionVariant,
|
|
16988
|
-
classicWaveTransitionVariant,
|
|
16989
|
-
gentleWaveTransitionVariant,
|
|
16990
|
-
boldWaveTransitionVariant,
|
|
16991
|
-
driftWaveTransitionVariant
|
|
16992
|
-
]
|
|
16993
|
-
},
|
|
16994
|
-
{
|
|
16995
|
-
id: "angle",
|
|
16996
|
-
label: "Angle",
|
|
16997
|
-
variants: [
|
|
16998
|
-
subtleAngleTransitionVariant,
|
|
16999
|
-
balancedAngleTransitionVariant,
|
|
17000
|
-
steepAngleTransitionVariant
|
|
17001
|
-
]
|
|
17002
|
-
}
|
|
17003
|
-
];
|
|
17004
|
-
/**
|
|
17005
|
-
* Must remain non-empty; downstream code indexes `[0]` as the documented default.
|
|
17006
|
-
*/
|
|
17007
|
-
const boundaryOptions = [
|
|
17008
|
-
noneBoundaryOption,
|
|
17009
|
-
softBoundaryOption,
|
|
17010
|
-
spaciousBoundaryOption,
|
|
17011
|
-
expansiveBoundaryOption,
|
|
17012
|
-
balancedWaveBoundaryOption,
|
|
17013
|
-
waveBoundaryOption,
|
|
17014
|
-
gentleWaveBoundaryOption,
|
|
17015
|
-
boldWaveBoundaryOption,
|
|
17016
|
-
driftWaveBoundaryOption,
|
|
17017
|
-
subtleAngleBoundaryOption,
|
|
17018
|
-
balancedAngleBoundaryOption,
|
|
17019
|
-
steepAngleBoundaryOption
|
|
17020
|
-
];
|
|
17009
|
+
function transitionVariantForEntry(entry) {
|
|
17010
|
+
return {
|
|
17011
|
+
familyId: entry.family,
|
|
17012
|
+
variantId: entry.variantId,
|
|
17013
|
+
label: entry.variantLabel,
|
|
17014
|
+
boundaryOption: boundaryOptionForTransitionIntent(entry.intent)
|
|
17015
|
+
};
|
|
17016
|
+
}
|
|
17017
|
+
const sectionTransitionFamilies = [{
|
|
17018
|
+
id: "none",
|
|
17019
|
+
label: "None",
|
|
17020
|
+
variants: [noneTransitionVariant]
|
|
17021
|
+
}, ...transitionCatalogueFamilies.map((family) => ({
|
|
17022
|
+
id: family.id,
|
|
17023
|
+
label: family.label,
|
|
17024
|
+
variants: requireNonEmptyReadonlyArray(transitionCatalogueEntries.filter((entry) => entry.family === family.id).map(transitionVariantForEntry), `Transition family ${family.id} has no catalogue entries.`)
|
|
17025
|
+
}))];
|
|
17026
|
+
const boundaryOptionById = new Map(boundaryOptions.map((option) => [option.id, option]));
|
|
17027
|
+
const boundaryOptionByTreatmentKey = new Map(boundaryOptions.map((option) => [stableTreatmentKey(option.treatment), option]));
|
|
17028
|
+
const transitionVariantByBoundaryOptionId = new Map(sectionTransitionFamilies.flatMap((family) => family.variants.map((variant) => [variant.boundaryOption.id, variant])));
|
|
17029
|
+
const transitionFamilyById = new Map(sectionTransitionFamilies.map((family) => [family.id, family]));
|
|
17021
17030
|
function sectionTransitionVariantForBoundaryOptionId(boundaryOptionId) {
|
|
17022
17031
|
if (!boundaryOptionId) return null;
|
|
17023
|
-
|
|
17024
|
-
const variant = family.variants.find((candidate$1) => candidate$1.boundaryOption.id === boundaryOptionId);
|
|
17025
|
-
if (variant) return variant;
|
|
17026
|
-
}
|
|
17027
|
-
return null;
|
|
17032
|
+
return transitionVariantByBoundaryOptionId.get(boundaryOptionId) ?? null;
|
|
17028
17033
|
}
|
|
17029
17034
|
function boundaryTreatmentForBoundaryOptionId(boundaryOptionId) {
|
|
17030
|
-
return
|
|
17035
|
+
return boundaryOptionById.get(boundaryOptionId)?.treatment ?? {
|
|
17031
17036
|
kind: "legacy-unsupported",
|
|
17032
17037
|
boundaryOptionId
|
|
17033
17038
|
};
|
|
@@ -17036,11 +17041,19 @@ function boundaryOptionForTreatment(treatment) {
|
|
|
17036
17041
|
if (treatment.kind === "legacy-unsupported") {
|
|
17037
17042
|
return null;
|
|
17038
17043
|
}
|
|
17039
|
-
return
|
|
17044
|
+
return boundaryOptionByTreatmentKey.get(stableTreatmentKey(treatment)) ?? null;
|
|
17040
17045
|
}
|
|
17041
17046
|
function boundaryOptionIdForTreatment(treatment) {
|
|
17042
17047
|
return boundaryOptionForTreatment(treatment)?.id ?? (treatment.kind === "legacy-unsupported" ? treatment.boundaryOptionId : null);
|
|
17043
17048
|
}
|
|
17049
|
+
/**
|
|
17050
|
+
* Supported decorative intent for a structured treatment, or null for `none`,
|
|
17051
|
+
* legacy-unsupported pins and structured treatments the catalogue lacks.
|
|
17052
|
+
*/
|
|
17053
|
+
function transitionIntentForTreatment(treatment) {
|
|
17054
|
+
const transition = boundaryOptionForTreatment(treatment)?.transitionAfter;
|
|
17055
|
+
return transition && isDecorativeTransitionIntent(transition) ? transition : null;
|
|
17056
|
+
}
|
|
17044
17057
|
function sectionBoundaryTreatmentsEqual(left, right) {
|
|
17045
17058
|
return stableTreatmentKey(left) === stableTreatmentKey(right);
|
|
17046
17059
|
}
|
|
@@ -17067,10 +17080,10 @@ function stableTreatmentKey(treatment) {
|
|
|
17067
17080
|
function sectionTransitionFamilyForBoundaryOptionId(boundaryOptionId) {
|
|
17068
17081
|
const variant = sectionTransitionVariantForBoundaryOptionId(boundaryOptionId);
|
|
17069
17082
|
if (!variant) return null;
|
|
17070
|
-
return
|
|
17083
|
+
return transitionFamilyById.get(variant.familyId) ?? null;
|
|
17071
17084
|
}
|
|
17072
17085
|
function defaultSectionTransitionVariantForFamily(familyId) {
|
|
17073
|
-
const family =
|
|
17086
|
+
const family = transitionFamilyById.get(familyId);
|
|
17074
17087
|
if (!family) {
|
|
17075
17088
|
throw new Error(`Unknown section transition family: ${familyId}`);
|
|
17076
17089
|
}
|
|
@@ -17078,389 +17091,787 @@ function defaultSectionTransitionVariantForFamily(familyId) {
|
|
|
17078
17091
|
}
|
|
17079
17092
|
|
|
17080
17093
|
//#endregion
|
|
17081
|
-
//#region ../theme-core/src/site-styles/
|
|
17082
|
-
const
|
|
17083
|
-
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
*
|
|
17087
|
-
*
|
|
17088
|
-
|
|
17089
|
-
|
|
17090
|
-
|
|
17091
|
-
|
|
17092
|
-
|
|
17094
|
+
//#region ../theme-core/src/site-styles/sectionBoundaryComposition.ts
|
|
17095
|
+
const backgroundToken = requireThemeColorToken$1("background");
|
|
17096
|
+
/**
|
|
17097
|
+
* Classifies a section from its final render content. `_sectionStyles`
|
|
17098
|
+
* already holds the effective background (Look default, page-design override
|
|
17099
|
+
* and block-authored media merged by `resolveSectionBackground`), so this only
|
|
17100
|
+
* reads it and never re-decides precedence. A missing or unparseable
|
|
17101
|
+
* background is the page background, as it is for the renderer.
|
|
17102
|
+
*/
|
|
17103
|
+
function boundaryEndpointForSectionContent(content) {
|
|
17104
|
+
const background = parseCanonicalRuntimeBackground(content);
|
|
17105
|
+
if (background.kind === "none") {
|
|
17106
|
+
return {
|
|
17107
|
+
kind: "paint",
|
|
17108
|
+
token: backgroundToken
|
|
17109
|
+
};
|
|
17110
|
+
}
|
|
17111
|
+
const effective = background.background;
|
|
17112
|
+
switch (effective.type) {
|
|
17113
|
+
case "color": {
|
|
17114
|
+
if (effective.color === null || effective.color === undefined) {
|
|
17115
|
+
return {
|
|
17116
|
+
kind: "paint",
|
|
17117
|
+
token: backgroundToken
|
|
17118
|
+
};
|
|
17119
|
+
}
|
|
17120
|
+
const token = parseThemeColorToken(effective.color);
|
|
17121
|
+
return token ? {
|
|
17122
|
+
kind: "paint",
|
|
17123
|
+
token
|
|
17124
|
+
} : {
|
|
17125
|
+
kind: "unpainted",
|
|
17126
|
+
reason: "literal-color"
|
|
17127
|
+
};
|
|
17128
|
+
}
|
|
17129
|
+
case "gradient": return {
|
|
17130
|
+
kind: "unpainted",
|
|
17131
|
+
reason: "gradient"
|
|
17132
|
+
};
|
|
17133
|
+
case "image":
|
|
17134
|
+
case "video": return {
|
|
17135
|
+
kind: "unpainted",
|
|
17136
|
+
reason: "media"
|
|
17137
|
+
};
|
|
17138
|
+
default: return assertNever$1(effective, "Unhandled section background type");
|
|
17139
|
+
}
|
|
17140
|
+
}
|
|
17141
|
+
/**
|
|
17142
|
+
* Reads both facts from final render content in one place. `_frameStyles` is
|
|
17143
|
+
* the compiled frame; content without one (no page design, an SDK block)
|
|
17144
|
+
* draws a plain frame.
|
|
17145
|
+
*/
|
|
17146
|
+
function sectionFactsForContent(content) {
|
|
17147
|
+
return {
|
|
17148
|
+
endpoint: boundaryEndpointForSectionContent(content),
|
|
17149
|
+
frame: frameKindForContent(content)
|
|
17093
17150
|
};
|
|
17094
17151
|
}
|
|
17095
|
-
|
|
17096
|
-
|
|
17097
|
-
|
|
17098
|
-
|
|
17099
|
-
|
|
17100
|
-
kind: z.literal("user-pinned"),
|
|
17101
|
-
value: z.string().min(1).transform(asBoundaryOptionId)
|
|
17102
|
-
}).strict();
|
|
17103
|
-
const pageDesignBoundaryTreatmentSchema = z.discriminatedUnion("kind", [
|
|
17104
|
-
z.object({ kind: z.literal("none") }).strict(),
|
|
17105
|
-
z.object({
|
|
17106
|
-
kind: z.literal("soft-fade"),
|
|
17107
|
-
height: z.enum([
|
|
17108
|
-
"compact",
|
|
17109
|
-
"medium",
|
|
17110
|
-
"large",
|
|
17111
|
-
"expansive"
|
|
17112
|
-
]),
|
|
17113
|
-
curve: z.enum([
|
|
17114
|
-
"soft",
|
|
17115
|
-
"spacious",
|
|
17116
|
-
"expansive"
|
|
17117
|
-
])
|
|
17118
|
-
}).strict(),
|
|
17119
|
-
z.object({
|
|
17120
|
-
kind: z.literal("wave-edge"),
|
|
17121
|
-
height: z.enum([
|
|
17122
|
-
"compact",
|
|
17123
|
-
"medium",
|
|
17124
|
-
"large"
|
|
17125
|
-
]),
|
|
17126
|
-
amplitude: z.enum([
|
|
17127
|
-
"subtle",
|
|
17128
|
-
"balanced",
|
|
17129
|
-
"bold"
|
|
17130
|
-
]),
|
|
17131
|
-
rhythm: z.enum(["single", "double"]),
|
|
17132
|
-
symmetry: z.enum([
|
|
17133
|
-
"symmetrical",
|
|
17134
|
-
"asymmetrical",
|
|
17135
|
-
"drift"
|
|
17136
|
-
])
|
|
17137
|
-
}).strict(),
|
|
17138
|
-
z.object({
|
|
17139
|
-
kind: z.literal("angle-edge"),
|
|
17140
|
-
height: z.enum([
|
|
17141
|
-
"compact",
|
|
17142
|
-
"medium",
|
|
17143
|
-
"large"
|
|
17144
|
-
]),
|
|
17145
|
-
slope: z.enum([
|
|
17146
|
-
"subtle",
|
|
17147
|
-
"balanced",
|
|
17148
|
-
"steep"
|
|
17149
|
-
]),
|
|
17150
|
-
direction: z.enum(["forward", "reverse"])
|
|
17151
|
-
}).strict(),
|
|
17152
|
-
z.object({
|
|
17153
|
-
kind: z.literal("legacy-unsupported"),
|
|
17154
|
-
boundaryOptionId: z.string().min(1).transform(asBoundaryOptionId)
|
|
17155
|
-
}).strict()
|
|
17156
|
-
]);
|
|
17157
|
-
const pageDesignUserPinnedBoundaryTreatmentChoiceSchema = z.object({
|
|
17158
|
-
kind: z.literal("user-pinned"),
|
|
17159
|
-
value: pageDesignBoundaryTreatmentSchema
|
|
17160
|
-
}).strict();
|
|
17161
|
-
const pageDesignBlockLookPinSchema = z.object({
|
|
17162
|
-
blockId: z.string().min(1).transform(asDesignBlockId),
|
|
17163
|
-
blockKind: z.string().min(1),
|
|
17164
|
-
choice: pageDesignUserPinnedAppearanceChoiceSchema
|
|
17165
|
-
}).strict();
|
|
17166
|
-
const pageDesignBoundaryPinSchema = z.object({
|
|
17167
|
-
boundaryId: z.string().min(1).transform(asDesignBoundaryId),
|
|
17168
|
-
previousBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17169
|
-
nextBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17170
|
-
choice: pageDesignUserPinnedBoundaryTreatmentChoiceSchema
|
|
17171
|
-
}).strict().superRefine(validateBoundaryPinIdMatchesBlocks);
|
|
17172
|
-
const legacyPageDesignBoundaryPinSchema = z.object({
|
|
17173
|
-
boundaryId: z.string().min(1).transform(asDesignBoundaryId),
|
|
17174
|
-
previousBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17175
|
-
nextBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17176
|
-
choice: pageDesignUserPinnedBoundaryChoiceSchema
|
|
17177
|
-
}).strict().superRefine(validateBoundaryPinIdMatchesBlocks);
|
|
17152
|
+
function frameKindForContent(content) {
|
|
17153
|
+
const frameStyles = content._frameStyles;
|
|
17154
|
+
const kind = typeof frameStyles === "object" && frameStyles !== null && "kind" in frameStyles ? frameStyles.kind : null;
|
|
17155
|
+
return kind === "panel" || kind === "flush-panel" ? kind : "plain";
|
|
17156
|
+
}
|
|
17178
17157
|
/**
|
|
17179
|
-
*
|
|
17180
|
-
*
|
|
17181
|
-
*
|
|
17158
|
+
* The frame rule: a flush panel owns the edge it runs to, so no break is
|
|
17159
|
+
* drawn next to one. The single home for this rule; the generated
|
|
17160
|
+
* pipeline's budget and the site-style lab ask it with their plan frames.
|
|
17182
17161
|
*/
|
|
17183
|
-
|
|
17184
|
-
|
|
17185
|
-
|
|
17186
|
-
|
|
17187
|
-
|
|
17188
|
-
|
|
17189
|
-
|
|
17190
|
-
|
|
17191
|
-
|
|
17192
|
-
|
|
17193
|
-
|
|
17194
|
-
|
|
17195
|
-
|
|
17196
|
-
}
|
|
17197
|
-
function parsePageDesignIntent(value, options = {}) {
|
|
17198
|
-
if (isLegacyPageDesignIntentCandidate(value)) {
|
|
17199
|
-
const legacyParsed = parseSchemaVersionedJson({
|
|
17200
|
-
value,
|
|
17201
|
-
schema: pageDesignIntentV1Schema,
|
|
17202
|
-
expectedSchemaVersion: legacyPageDesignIntentSchemaVersion,
|
|
17203
|
-
unsupportedSchemaVersionMessage: options.unsupportedSchemaVersionMessage ?? "Unsupported Theme V2 page design intent schemaVersion.",
|
|
17204
|
-
invalidShapeMessage: options.invalidShapeMessage ?? "Invalid Theme V2 page design intent shape."
|
|
17205
|
-
});
|
|
17206
|
-
switch (legacyParsed.kind) {
|
|
17207
|
-
case "absent": return legacyParsed;
|
|
17208
|
-
case "parsed": return {
|
|
17209
|
-
kind: "parsed",
|
|
17210
|
-
intent: normalizeLegacyPageDesignIntent(legacyParsed.value)
|
|
17211
|
-
};
|
|
17212
|
-
case "invalid": return legacyParsed;
|
|
17213
|
-
default: return assertNever$1(legacyParsed, "Unhandled legacy page design intent JSON parse result");
|
|
17214
|
-
}
|
|
17162
|
+
function frameNotShownReason(previous, next) {
|
|
17163
|
+
return previous === "flush-panel" || next === "flush-panel" ? "flush-panel" : null;
|
|
17164
|
+
}
|
|
17165
|
+
/**
|
|
17166
|
+
* Decides whether and how a join draws. The frame rule wins before paint is
|
|
17167
|
+
* considered; two unpainted sides show nothing.
|
|
17168
|
+
*/
|
|
17169
|
+
function composeBoundary(previous, next) {
|
|
17170
|
+
const frameReason = frameNotShownReason(previous.frame, next.frame);
|
|
17171
|
+
if (frameReason) {
|
|
17172
|
+
return {
|
|
17173
|
+
kind: "not-shown",
|
|
17174
|
+
reason: frameReason
|
|
17175
|
+
};
|
|
17215
17176
|
}
|
|
17216
|
-
const
|
|
17217
|
-
|
|
17218
|
-
|
|
17219
|
-
|
|
17220
|
-
|
|
17221
|
-
|
|
17222
|
-
|
|
17223
|
-
|
|
17224
|
-
|
|
17225
|
-
|
|
17226
|
-
|
|
17227
|
-
|
|
17177
|
+
const from = previous.endpoint;
|
|
17178
|
+
const to = next.endpoint;
|
|
17179
|
+
if (from.kind === "paint") {
|
|
17180
|
+
return {
|
|
17181
|
+
kind: "shown",
|
|
17182
|
+
composition: to.kind === "paint" ? {
|
|
17183
|
+
kind: "paint-to-paint",
|
|
17184
|
+
from: from.token,
|
|
17185
|
+
to: to.token
|
|
17186
|
+
} : {
|
|
17187
|
+
kind: "paint-to-unpainted",
|
|
17188
|
+
from: from.token
|
|
17189
|
+
}
|
|
17228
17190
|
};
|
|
17229
|
-
case "invalid": return parsed;
|
|
17230
|
-
default: return assertNever$1(parsed, "Unhandled page design intent JSON parse result");
|
|
17231
17191
|
}
|
|
17232
|
-
|
|
17233
|
-
|
|
17234
|
-
|
|
17235
|
-
|
|
17236
|
-
|
|
17237
|
-
|
|
17238
|
-
|
|
17239
|
-
|
|
17240
|
-
|
|
17241
|
-
blockLookPins: intent.blockLookPins,
|
|
17242
|
-
boundaryPins: intent.boundaryPins.map((pin) => ({
|
|
17243
|
-
boundaryId: pin.boundaryId,
|
|
17244
|
-
previousBlockId: pin.previousBlockId,
|
|
17245
|
-
nextBlockId: pin.nextBlockId,
|
|
17246
|
-
choice: userPinnedDesignChoice(boundaryTreatmentForBoundaryOptionId(pin.choice.value))
|
|
17247
|
-
}))
|
|
17192
|
+
return to.kind === "paint" ? {
|
|
17193
|
+
kind: "shown",
|
|
17194
|
+
composition: {
|
|
17195
|
+
kind: "unpainted-to-paint",
|
|
17196
|
+
to: to.token
|
|
17197
|
+
}
|
|
17198
|
+
} : {
|
|
17199
|
+
kind: "not-shown",
|
|
17200
|
+
reason: "both-unpainted"
|
|
17248
17201
|
};
|
|
17249
17202
|
}
|
|
17250
|
-
|
|
17251
|
-
|
|
17203
|
+
/**
|
|
17204
|
+
* Placement, reserves and paint for a shown boundary, derived from the
|
|
17205
|
+
* composition and the catalogue's metrics for the treatment.
|
|
17206
|
+
*/
|
|
17207
|
+
function boundaryLayout(intent, composition) {
|
|
17208
|
+
const metrics = boundaryRuntimeMetricsForDecorativeTransition(intent);
|
|
17209
|
+
switch (composition.kind) {
|
|
17210
|
+
case "paint-to-paint": return {
|
|
17211
|
+
placement: "centred",
|
|
17212
|
+
reserves: {
|
|
17213
|
+
before: metrics.reserveCss,
|
|
17214
|
+
after: metrics.reserveCss
|
|
17215
|
+
},
|
|
17216
|
+
paint: {
|
|
17217
|
+
band: composition.from,
|
|
17218
|
+
shape: composition.to
|
|
17219
|
+
}
|
|
17220
|
+
};
|
|
17221
|
+
case "unpainted-to-paint": return {
|
|
17222
|
+
placement: "previous",
|
|
17223
|
+
reserves: {
|
|
17224
|
+
before: metrics.heightCss,
|
|
17225
|
+
after: null
|
|
17226
|
+
},
|
|
17227
|
+
paint: {
|
|
17228
|
+
band: null,
|
|
17229
|
+
shape: composition.to
|
|
17230
|
+
}
|
|
17231
|
+
};
|
|
17232
|
+
case "paint-to-unpainted": return {
|
|
17233
|
+
placement: "next",
|
|
17234
|
+
reserves: {
|
|
17235
|
+
before: null,
|
|
17236
|
+
after: metrics.heightCss
|
|
17237
|
+
},
|
|
17238
|
+
paint: {
|
|
17239
|
+
band: null,
|
|
17240
|
+
shape: composition.from
|
|
17241
|
+
}
|
|
17242
|
+
};
|
|
17243
|
+
default: return assertNever$1(composition, "Unhandled boundary composition");
|
|
17244
|
+
}
|
|
17252
17245
|
}
|
|
17253
|
-
function
|
|
17246
|
+
function requireThemeColorToken$1(value) {
|
|
17247
|
+
const token = parseThemeColorToken(value);
|
|
17248
|
+
if (!token) {
|
|
17249
|
+
throw new Error(`Expected a theme color token. Received: ${value}`);
|
|
17250
|
+
}
|
|
17251
|
+
return token;
|
|
17252
|
+
}
|
|
17253
|
+
|
|
17254
|
+
//#endregion
|
|
17255
|
+
//#region ../theme-core/src/site-styles/compositionBudget.ts
|
|
17256
|
+
const repairActionsByRatioIssueKind = {
|
|
17257
|
+
"accent-density-exceeded": ["reduce-accent-density"],
|
|
17258
|
+
"panel-density-exceeded": ["reduce-panel-density"],
|
|
17259
|
+
"transition-mix-exceeded": ["reduce-transition-mix"],
|
|
17260
|
+
"media-density-exceeded": ["reduce-media-density"],
|
|
17261
|
+
"decorative-repetition-exceeded": ["reduce-decorative-repetition"]
|
|
17262
|
+
};
|
|
17263
|
+
function issueMetadata(policy, allowedRepairActions) {
|
|
17254
17264
|
return {
|
|
17255
|
-
|
|
17256
|
-
|
|
17265
|
+
policy,
|
|
17266
|
+
severity: designIssueSeverityForPolicy(policy),
|
|
17267
|
+
allowedRepairActions
|
|
17257
17268
|
};
|
|
17258
17269
|
}
|
|
17259
|
-
|
|
17260
|
-
|
|
17270
|
+
/** Returns the fraction of page blocks selected by a budget check. */
|
|
17271
|
+
function ratio(count, total) {
|
|
17272
|
+
return total === 0 ? 0 : count / total;
|
|
17261
17273
|
}
|
|
17262
|
-
function
|
|
17263
|
-
return
|
|
17274
|
+
function maxCompositionItemsWithinRatio(totalItems, allowedRatio) {
|
|
17275
|
+
return Math.floor((allowedRatio + Number.EPSILON) * totalItems);
|
|
17264
17276
|
}
|
|
17265
|
-
function
|
|
17277
|
+
function isRatioExceeded(actualCount, totalItems, allowedRatio) {
|
|
17278
|
+
return actualCount > maxCompositionItemsWithinRatio(totalItems, allowedRatio);
|
|
17279
|
+
}
|
|
17280
|
+
function issueWhenRatioExceeded(input) {
|
|
17281
|
+
const actualRatio = ratio(input.blockIds.length, input.totalBlocks);
|
|
17282
|
+
if (!isRatioExceeded(input.blockIds.length, input.totalBlocks, input.allowedRatio)) {
|
|
17283
|
+
return null;
|
|
17284
|
+
}
|
|
17266
17285
|
return {
|
|
17267
|
-
|
|
17268
|
-
|
|
17269
|
-
|
|
17270
|
-
|
|
17286
|
+
kind: input.kind,
|
|
17287
|
+
budget: input.budget,
|
|
17288
|
+
actualRatio,
|
|
17289
|
+
allowedRatio: input.allowedRatio,
|
|
17290
|
+
blockIds: input.blockIds,
|
|
17291
|
+
...issueMetadata(input.policy, repairActionsByRatioIssueKind[input.kind])
|
|
17271
17292
|
};
|
|
17272
17293
|
}
|
|
17273
|
-
|
|
17274
|
-
|
|
17275
|
-
|
|
17276
|
-
intent,
|
|
17277
|
-
issues: []
|
|
17278
|
-
};
|
|
17279
|
-
case "block-removed": return removeBlockFromPageDesignIntent(intent, event.blockId);
|
|
17280
|
-
case "blocks-reordered": return pruneBoundaryPinsForOrder(intent, event.orderedBlockIds);
|
|
17281
|
-
case "block-kind-changed": return changeBlockKindInPageDesignIntent(intent, event);
|
|
17282
|
-
case "block-duplicated": return duplicateBlockInPageDesignIntent(intent, event);
|
|
17283
|
-
default: return assertNever$1(event, "Unhandled page design structure event");
|
|
17284
|
-
}
|
|
17294
|
+
/** Checks whether block framing or a card surface contributes panel mass. */
|
|
17295
|
+
function hasPanelFrameOrCardSurface(block) {
|
|
17296
|
+
return block.appliedContentFrame.kind !== "plain" || block.appliedCardRole != null && block.appliedCardRole !== "none";
|
|
17285
17297
|
}
|
|
17286
|
-
|
|
17287
|
-
|
|
17288
|
-
|
|
17289
|
-
...intent,
|
|
17290
|
-
pageFlowPresetId: action.pageFlowPresetId
|
|
17291
|
-
};
|
|
17292
|
-
case "set-block-look": return setBlockLookChoice(intent, action.block, action.choice);
|
|
17293
|
-
case "set-boundary": return setBoundaryChoice(intent, action.previousBlockId, action.nextBlockId, action.choice);
|
|
17294
|
-
default: return assertNever$1(action, "Unhandled page design user action");
|
|
17295
|
-
}
|
|
17298
|
+
/** Checks explicit decorative annotations; transitions are budgeted separately. */
|
|
17299
|
+
function hasDecorativeAnnotation(context) {
|
|
17300
|
+
return context?.decorativeIntent === "supporting" || context?.decorativeIntent === "feature";
|
|
17296
17301
|
}
|
|
17297
|
-
|
|
17298
|
-
|
|
17299
|
-
|
|
17300
|
-
|
|
17301
|
-
|
|
17302
|
-
const
|
|
17303
|
-
const
|
|
17304
|
-
const
|
|
17305
|
-
|
|
17306
|
-
|
|
17307
|
-
|
|
17308
|
-
|
|
17309
|
-
|
|
17310
|
-
|
|
17302
|
+
/** Checks whether a block annotation says media contributes visual weight. */
|
|
17303
|
+
function hasMediaAnnotation(context) {
|
|
17304
|
+
return context?.mediaIntent === "supporting" || context?.mediaIntent === "dominant";
|
|
17305
|
+
}
|
|
17306
|
+
function validateCompositionBudget(input) {
|
|
17307
|
+
const { budget, policy, resolved } = input;
|
|
17308
|
+
const totalBlocks = resolved.blocks.length;
|
|
17309
|
+
const knownBlockIds = new Set(resolved.blocks.map((block) => block.blockId));
|
|
17310
|
+
const blockContexts = input.blockContexts ?? [];
|
|
17311
|
+
const unknownContextBlockIds = blockContexts.filter((context) => !knownBlockIds.has(context.blockId)).map((context) => context.blockId);
|
|
17312
|
+
const knownBlockContexts = blockContexts.filter((context) => knownBlockIds.has(context.blockId));
|
|
17313
|
+
const contextsByBlockId = new Map(knownBlockContexts.map((context) => [context.blockId, context]));
|
|
17314
|
+
const issues = [];
|
|
17315
|
+
if (unknownContextBlockIds.length > 0) {
|
|
17316
|
+
issues.push({
|
|
17317
|
+
kind: "unknown-composition-context-block",
|
|
17318
|
+
blockIds: unknownContextBlockIds,
|
|
17319
|
+
...issueMetadata(policy, [])
|
|
17320
|
+
});
|
|
17321
|
+
}
|
|
17322
|
+
const accentBlockIds = resolved.blocks.filter((block) => block.appliedSectionSurface === "accent-band" || block.appliedSectionSurface === "brand-depth-band").map((block) => block.blockId);
|
|
17323
|
+
const accentIssue = issueWhenRatioExceeded({
|
|
17324
|
+
kind: "accent-density-exceeded",
|
|
17325
|
+
policy,
|
|
17326
|
+
budget: budget.accentDensity,
|
|
17327
|
+
blockIds: accentBlockIds,
|
|
17328
|
+
totalBlocks,
|
|
17329
|
+
allowedRatio: compositionDensityRatioLimits[budget.accentDensity]
|
|
17311
17330
|
});
|
|
17312
|
-
|
|
17313
|
-
|
|
17314
|
-
|
|
17315
|
-
|
|
17316
|
-
|
|
17317
|
-
|
|
17318
|
-
|
|
17319
|
-
|
|
17320
|
-
|
|
17321
|
-
|
|
17331
|
+
if (accentIssue) {
|
|
17332
|
+
issues.push(accentIssue);
|
|
17333
|
+
}
|
|
17334
|
+
const panelBlockIds = resolved.blocks.filter(hasPanelFrameOrCardSurface).map((block) => block.blockId);
|
|
17335
|
+
const panelIssue = issueWhenRatioExceeded({
|
|
17336
|
+
kind: "panel-density-exceeded",
|
|
17337
|
+
policy,
|
|
17338
|
+
budget: budget.panelDensity,
|
|
17339
|
+
blockIds: panelBlockIds,
|
|
17340
|
+
totalBlocks,
|
|
17341
|
+
allowedRatio: compositionDensityRatioLimits[budget.panelDensity]
|
|
17342
|
+
});
|
|
17343
|
+
if (panelIssue) {
|
|
17344
|
+
issues.push(panelIssue);
|
|
17345
|
+
}
|
|
17346
|
+
const frameByBlockId = new Map(input.resolved.blocks.map((block) => [block.blockId, block.appliedContentFrame.kind]));
|
|
17347
|
+
const transitionBlockIds = input.joins.filter((join) => {
|
|
17348
|
+
const previous = frameByBlockId.get(join.previousBlockId);
|
|
17349
|
+
const next = frameByBlockId.get(join.nextBlockId);
|
|
17350
|
+
return previous !== undefined && next !== undefined && frameNotShownReason(previous, next) === null;
|
|
17351
|
+
}).map((join) => join.previousBlockId);
|
|
17352
|
+
const transitionIssue = issueWhenRatioExceeded({
|
|
17353
|
+
kind: "transition-mix-exceeded",
|
|
17354
|
+
policy,
|
|
17355
|
+
budget: budget.transitionMix,
|
|
17356
|
+
blockIds: transitionBlockIds,
|
|
17357
|
+
totalBlocks,
|
|
17358
|
+
allowedRatio: compositionTransitionMixRatioLimits[budget.transitionMix]
|
|
17359
|
+
});
|
|
17360
|
+
if (transitionIssue) {
|
|
17361
|
+
issues.push(transitionIssue);
|
|
17362
|
+
}
|
|
17363
|
+
const ctaContexts = knownBlockContexts.filter((context) => (context.primaryCtaCount ?? 0) > 0);
|
|
17364
|
+
const actualPrimaryCtaCount = ctaContexts.reduce((sum, context) => sum + (context.primaryCtaCount ?? 0), 0);
|
|
17365
|
+
if (actualPrimaryCtaCount > budget.primaryCtaLimit) {
|
|
17366
|
+
issues.push({
|
|
17367
|
+
kind: "primary-cta-limit-exceeded",
|
|
17368
|
+
actualCount: actualPrimaryCtaCount,
|
|
17369
|
+
allowedCount: budget.primaryCtaLimit,
|
|
17370
|
+
blockIds: ctaContexts.map((context) => context.blockId),
|
|
17371
|
+
...issueMetadata(policy, ["reduce-primary-ctas"])
|
|
17372
|
+
});
|
|
17373
|
+
}
|
|
17374
|
+
const mediaBlockIds = resolved.blocks.filter((block) => hasMediaAnnotation(contextsByBlockId.get(block.blockId))).map((block) => block.blockId);
|
|
17375
|
+
const mediaIssue = issueWhenRatioExceeded({
|
|
17376
|
+
kind: "media-density-exceeded",
|
|
17377
|
+
policy,
|
|
17378
|
+
budget: budget.mediaDensity,
|
|
17379
|
+
blockIds: mediaBlockIds,
|
|
17380
|
+
totalBlocks,
|
|
17381
|
+
allowedRatio: compositionDensityRatioLimits[budget.mediaDensity]
|
|
17382
|
+
});
|
|
17383
|
+
if (mediaIssue) {
|
|
17384
|
+
issues.push(mediaIssue);
|
|
17385
|
+
}
|
|
17386
|
+
const decorativeBlockIds = resolved.blocks.filter((block) => hasDecorativeAnnotation(contextsByBlockId.get(block.blockId))).map((block) => block.blockId);
|
|
17387
|
+
const decorativeIssue = issueWhenRatioExceeded({
|
|
17388
|
+
kind: "decorative-repetition-exceeded",
|
|
17389
|
+
policy,
|
|
17390
|
+
budget: budget.decorativeRepetition,
|
|
17391
|
+
blockIds: decorativeBlockIds,
|
|
17392
|
+
totalBlocks,
|
|
17393
|
+
allowedRatio: compositionDensityRatioLimits[budget.decorativeRepetition]
|
|
17322
17394
|
});
|
|
17395
|
+
if (decorativeIssue) {
|
|
17396
|
+
issues.push(decorativeIssue);
|
|
17397
|
+
}
|
|
17398
|
+
return issues;
|
|
17399
|
+
}
|
|
17400
|
+
|
|
17401
|
+
//#endregion
|
|
17402
|
+
//#region ../theme-core/src/site-styles/compilationPlan.ts
|
|
17403
|
+
const defaultHeaderBrandPreferences = {
|
|
17404
|
+
brandDisplay: "auto",
|
|
17405
|
+
logoSize: "auto"
|
|
17406
|
+
};
|
|
17407
|
+
function headerBrandPreferencesFromTheme(theme) {
|
|
17323
17408
|
return {
|
|
17324
|
-
|
|
17325
|
-
|
|
17326
|
-
|
|
17327
|
-
|
|
17409
|
+
brandDisplay: theme?.header.logo?.brandDisplay ?? defaultHeaderBrandPreferences.brandDisplay,
|
|
17410
|
+
logoSize: theme?.header.logo?.size ?? defaultHeaderBrandPreferences.logoSize
|
|
17411
|
+
};
|
|
17412
|
+
}
|
|
17413
|
+
function replaceSiteStyleCompilationPlan(input) {
|
|
17414
|
+
return {
|
|
17415
|
+
kind: "replace-site-style",
|
|
17416
|
+
buttons: {
|
|
17417
|
+
kind: "recompile",
|
|
17418
|
+
selection: input.buttonStyleSelection ?? null,
|
|
17419
|
+
reason: "site-style-replacement"
|
|
17328
17420
|
},
|
|
17329
|
-
|
|
17421
|
+
header: {
|
|
17422
|
+
kind: "recompile",
|
|
17423
|
+
selection: input.headerSelection,
|
|
17424
|
+
brandPresentation: input.headerLogo === undefined ? { kind: "use-compiled-defaults" } : {
|
|
17425
|
+
kind: "apply-logo-context",
|
|
17426
|
+
logo: input.headerLogo
|
|
17427
|
+
}
|
|
17428
|
+
},
|
|
17429
|
+
footerLookId: input.footerLookId ?? null
|
|
17330
17430
|
};
|
|
17331
17431
|
}
|
|
17332
|
-
|
|
17333
|
-
|
|
17334
|
-
|
|
17335
|
-
|
|
17336
|
-
|
|
17337
|
-
|
|
17338
|
-
|
|
17432
|
+
/**
|
|
17433
|
+
* Writes the brand display / logo size preference onto the header's logo style.
|
|
17434
|
+
*
|
|
17435
|
+
* Moved here from preview-next in #1318 Phase 4a so the header preference
|
|
17436
|
+
* pipeline can be composed once, in theme-core, rather than half in the client.
|
|
17437
|
+
*/
|
|
17438
|
+
function withHeaderBrandThemePreferences(theme, preferences) {
|
|
17439
|
+
const currentLogo = theme.header.logo;
|
|
17440
|
+
if (!currentLogo && preferences.brandDisplay === defaultHeaderBrandPreferences.brandDisplay && preferences.logoSize === defaultHeaderBrandPreferences.logoSize) {
|
|
17441
|
+
return theme;
|
|
17339
17442
|
}
|
|
17340
17443
|
return {
|
|
17341
|
-
...
|
|
17342
|
-
|
|
17343
|
-
|
|
17344
|
-
|
|
17345
|
-
|
|
17346
|
-
|
|
17444
|
+
...theme,
|
|
17445
|
+
header: {
|
|
17446
|
+
...theme.header,
|
|
17447
|
+
logo: {
|
|
17448
|
+
fontFamily: currentLogo?.fontFamily ?? "heading",
|
|
17449
|
+
letterSpacing: currentLogo?.letterSpacing ?? "normal",
|
|
17450
|
+
gradient: currentLogo?.gradient ?? false,
|
|
17451
|
+
...currentLogo ?? {},
|
|
17452
|
+
brandDisplay: preferences.brandDisplay,
|
|
17453
|
+
size: preferences.logoSize
|
|
17454
|
+
}
|
|
17455
|
+
}
|
|
17347
17456
|
};
|
|
17348
17457
|
}
|
|
17349
|
-
|
|
17350
|
-
|
|
17351
|
-
|
|
17458
|
+
|
|
17459
|
+
//#endregion
|
|
17460
|
+
//#region ../theme-core/src/site-styles/schemaVersionedJson.ts
|
|
17461
|
+
function parseSchemaVersionedJson(input) {
|
|
17462
|
+
if (input.value == null) {
|
|
17463
|
+
return { kind: "absent" };
|
|
17464
|
+
}
|
|
17465
|
+
if (typeof input.value === "object" && input.value !== null && "schemaVersion" in input.value && input.value.schemaVersion !== input.expectedSchemaVersion) {
|
|
17352
17466
|
return {
|
|
17353
|
-
|
|
17354
|
-
|
|
17467
|
+
kind: "invalid",
|
|
17468
|
+
issue: {
|
|
17469
|
+
kind: "unsupported-schema-version",
|
|
17470
|
+
message: input.unsupportedSchemaVersionMessage
|
|
17471
|
+
}
|
|
17472
|
+
};
|
|
17473
|
+
}
|
|
17474
|
+
const parsed = input.schema.safeParse(input.value);
|
|
17475
|
+
if (!parsed.success) {
|
|
17476
|
+
const firstIssue = parsed.error.issues[0];
|
|
17477
|
+
return {
|
|
17478
|
+
kind: "invalid",
|
|
17479
|
+
issue: {
|
|
17480
|
+
kind: "invalid-json-shape",
|
|
17481
|
+
message: firstIssue?.message ?? input.invalidShapeMessage
|
|
17482
|
+
}
|
|
17355
17483
|
};
|
|
17356
17484
|
}
|
|
17357
17485
|
return {
|
|
17486
|
+
kind: "parsed",
|
|
17487
|
+
value: parsed.data
|
|
17488
|
+
};
|
|
17489
|
+
}
|
|
17490
|
+
|
|
17491
|
+
//#endregion
|
|
17492
|
+
//#region ../theme-core/src/site-styles/pageDesignIntent.ts
|
|
17493
|
+
const pageDesignIntentSchemaVersion = 2;
|
|
17494
|
+
const legacyPageDesignIntentSchemaVersion = 1;
|
|
17495
|
+
const unknownBoundaryOptionId = asBoundaryOptionId("break:unknown");
|
|
17496
|
+
/**
|
|
17497
|
+
* Site style is site-owned authority. Page design snapshots retain pins and
|
|
17498
|
+
* flow choices, but must not keep resolving against a superseded site style.
|
|
17499
|
+
*/
|
|
17500
|
+
function rebasePageDesignIntentToSiteStyle(intent, siteStyleId) {
|
|
17501
|
+
return intent.siteStyleId === siteStyleId ? intent : {
|
|
17358
17502
|
...intent,
|
|
17359
|
-
|
|
17503
|
+
siteStyleId
|
|
17360
17504
|
};
|
|
17361
17505
|
}
|
|
17362
|
-
|
|
17363
|
-
|
|
17364
|
-
|
|
17365
|
-
|
|
17366
|
-
|
|
17367
|
-
|
|
17368
|
-
|
|
17369
|
-
|
|
17370
|
-
|
|
17371
|
-
|
|
17372
|
-
|
|
17373
|
-
|
|
17374
|
-
|
|
17375
|
-
|
|
17376
|
-
|
|
17506
|
+
const pageDesignUserPinnedAppearanceChoiceSchema = z.object({
|
|
17507
|
+
kind: z.literal("user-pinned"),
|
|
17508
|
+
value: z.string().min(1).transform(asAppearancePresetId)
|
|
17509
|
+
}).strict();
|
|
17510
|
+
const pageDesignUserPinnedBoundaryChoiceSchema = z.object({
|
|
17511
|
+
kind: z.literal("user-pinned"),
|
|
17512
|
+
value: z.string().min(1).transform(asBoundaryOptionId)
|
|
17513
|
+
}).strict();
|
|
17514
|
+
const pageDesignBoundaryTreatmentSchema = z.discriminatedUnion("kind", [
|
|
17515
|
+
z.object({ kind: z.literal("none") }).strict(),
|
|
17516
|
+
z.object({
|
|
17517
|
+
kind: z.literal("soft-fade"),
|
|
17518
|
+
height: z.enum([
|
|
17519
|
+
"compact",
|
|
17520
|
+
"medium",
|
|
17521
|
+
"large",
|
|
17522
|
+
"expansive"
|
|
17523
|
+
]),
|
|
17524
|
+
curve: z.enum([
|
|
17525
|
+
"soft",
|
|
17526
|
+
"spacious",
|
|
17527
|
+
"expansive"
|
|
17528
|
+
])
|
|
17529
|
+
}).strict(),
|
|
17530
|
+
z.object({
|
|
17531
|
+
kind: z.literal("wave-edge"),
|
|
17532
|
+
height: z.enum([
|
|
17533
|
+
"compact",
|
|
17534
|
+
"medium",
|
|
17535
|
+
"large"
|
|
17536
|
+
]),
|
|
17537
|
+
amplitude: z.enum([
|
|
17538
|
+
"subtle",
|
|
17539
|
+
"balanced",
|
|
17540
|
+
"bold"
|
|
17541
|
+
]),
|
|
17542
|
+
rhythm: z.enum(["single", "double"]),
|
|
17543
|
+
symmetry: z.enum([
|
|
17544
|
+
"symmetrical",
|
|
17545
|
+
"asymmetrical",
|
|
17546
|
+
"drift"
|
|
17547
|
+
])
|
|
17548
|
+
}).strict(),
|
|
17549
|
+
z.object({
|
|
17550
|
+
kind: z.literal("angle-edge"),
|
|
17551
|
+
height: z.enum([
|
|
17552
|
+
"compact",
|
|
17553
|
+
"medium",
|
|
17554
|
+
"large"
|
|
17555
|
+
]),
|
|
17556
|
+
slope: z.enum([
|
|
17557
|
+
"subtle",
|
|
17558
|
+
"balanced",
|
|
17559
|
+
"steep"
|
|
17560
|
+
]),
|
|
17561
|
+
direction: z.enum(["forward", "reverse"])
|
|
17562
|
+
}).strict(),
|
|
17563
|
+
z.object({
|
|
17564
|
+
kind: z.literal("legacy-unsupported"),
|
|
17565
|
+
boundaryOptionId: z.string().min(1).transform(asBoundaryOptionId)
|
|
17566
|
+
}).strict()
|
|
17567
|
+
]);
|
|
17568
|
+
const pageDesignUserPinnedBoundaryTreatmentChoiceSchema = z.object({
|
|
17569
|
+
kind: z.literal("user-pinned"),
|
|
17570
|
+
value: pageDesignBoundaryTreatmentSchema
|
|
17571
|
+
}).strict();
|
|
17572
|
+
const pageDesignBlockLookPinSchema = z.object({
|
|
17573
|
+
blockId: z.string().min(1).transform(asDesignBlockId),
|
|
17574
|
+
blockKind: z.string().min(1),
|
|
17575
|
+
choice: pageDesignUserPinnedAppearanceChoiceSchema
|
|
17576
|
+
}).strict();
|
|
17577
|
+
const pageDesignBoundaryPinSchema = z.object({
|
|
17578
|
+
boundaryId: z.string().min(1).transform(asDesignBoundaryId),
|
|
17579
|
+
previousBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17580
|
+
nextBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17581
|
+
choice: pageDesignUserPinnedBoundaryTreatmentChoiceSchema
|
|
17582
|
+
}).strict().superRefine(validateBoundaryPinIdMatchesBlocks);
|
|
17583
|
+
const legacyPageDesignBoundaryPinSchema = z.object({
|
|
17584
|
+
boundaryId: z.string().min(1).transform(asDesignBoundaryId),
|
|
17585
|
+
previousBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17586
|
+
nextBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17587
|
+
choice: pageDesignUserPinnedBoundaryChoiceSchema
|
|
17588
|
+
}).strict().superRefine(validateBoundaryPinIdMatchesBlocks);
|
|
17589
|
+
/**
|
|
17590
|
+
* Persisted editor intent stores only user-pinned block Looks and boundary choices.
|
|
17591
|
+
* Missing pins mean `auto`; block-kind/preset compatibility is enforced by resolution,
|
|
17592
|
+
* not by this JSON parse boundary.
|
|
17593
|
+
*/
|
|
17594
|
+
const pageDesignIntentV1Schema = z.object({
|
|
17595
|
+
schemaVersion: z.literal(legacyPageDesignIntentSchemaVersion),
|
|
17596
|
+
siteStyleId: z.string().min(1).transform(asSiteStyleId),
|
|
17597
|
+
pageFlowPresetId: z.string().min(1).transform(asPageFlowPresetId),
|
|
17598
|
+
blockLookPins: z.array(pageDesignBlockLookPinSchema),
|
|
17599
|
+
boundaryPins: z.array(legacyPageDesignBoundaryPinSchema)
|
|
17600
|
+
}).strict().superRefine(validateUniquePageDesignPins);
|
|
17601
|
+
const pageDesignIntentV2Schema = z.object({
|
|
17602
|
+
schemaVersion: z.literal(pageDesignIntentSchemaVersion),
|
|
17603
|
+
siteStyleId: z.string().min(1).transform(asSiteStyleId),
|
|
17604
|
+
pageFlowPresetId: z.string().min(1).transform(asPageFlowPresetId),
|
|
17605
|
+
blockLookPins: z.array(pageDesignBlockLookPinSchema),
|
|
17606
|
+
boundaryPins: z.array(pageDesignBoundaryPinSchema)
|
|
17607
|
+
}).strict().superRefine(validateUniquePageDesignPins);
|
|
17608
|
+
function parsePageDesignIntent(value, options = {}) {
|
|
17609
|
+
if (isLegacyPageDesignIntentCandidate(value)) {
|
|
17610
|
+
const legacyParsed = parseSchemaVersionedJson({
|
|
17611
|
+
value,
|
|
17612
|
+
schema: pageDesignIntentV1Schema,
|
|
17613
|
+
expectedSchemaVersion: legacyPageDesignIntentSchemaVersion,
|
|
17614
|
+
unsupportedSchemaVersionMessage: options.unsupportedSchemaVersionMessage ?? "Unsupported Theme V2 page design intent schemaVersion.",
|
|
17615
|
+
invalidShapeMessage: options.invalidShapeMessage ?? "Invalid Theme V2 page design intent shape."
|
|
17616
|
+
});
|
|
17617
|
+
switch (legacyParsed.kind) {
|
|
17618
|
+
case "absent": return legacyParsed;
|
|
17619
|
+
case "parsed": return {
|
|
17620
|
+
kind: "parsed",
|
|
17621
|
+
intent: normalizeLegacyPageDesignIntent(legacyParsed.value)
|
|
17622
|
+
};
|
|
17623
|
+
case "invalid": return legacyParsed;
|
|
17624
|
+
default: return assertNever$1(legacyParsed, "Unhandled legacy page design intent JSON parse result");
|
|
17625
|
+
}
|
|
17626
|
+
}
|
|
17627
|
+
const parsed = parseSchemaVersionedJson({
|
|
17628
|
+
value,
|
|
17629
|
+
schema: pageDesignIntentV2Schema,
|
|
17630
|
+
expectedSchemaVersion: pageDesignIntentSchemaVersion,
|
|
17631
|
+
unsupportedSchemaVersionMessage: options.unsupportedSchemaVersionMessage ?? "Unsupported Theme V2 page design intent schemaVersion.",
|
|
17632
|
+
invalidShapeMessage: options.invalidShapeMessage ?? "Invalid Theme V2 page design intent shape."
|
|
17633
|
+
});
|
|
17634
|
+
switch (parsed.kind) {
|
|
17635
|
+
case "absent": return parsed;
|
|
17636
|
+
case "parsed": return {
|
|
17637
|
+
kind: "parsed",
|
|
17638
|
+
intent: parsed.value
|
|
17639
|
+
};
|
|
17640
|
+
case "invalid": return parsed;
|
|
17641
|
+
default: return assertNever$1(parsed, "Unhandled page design intent JSON parse result");
|
|
17642
|
+
}
|
|
17643
|
+
}
|
|
17644
|
+
function isLegacyPageDesignIntentCandidate(value) {
|
|
17645
|
+
return typeof value === "object" && value !== null && "schemaVersion" in value && value.schemaVersion === legacyPageDesignIntentSchemaVersion;
|
|
17646
|
+
}
|
|
17647
|
+
function normalizeLegacyPageDesignIntent(intent) {
|
|
17377
17648
|
return {
|
|
17378
|
-
|
|
17379
|
-
|
|
17380
|
-
|
|
17381
|
-
|
|
17382
|
-
|
|
17383
|
-
|
|
17649
|
+
schemaVersion: pageDesignIntentSchemaVersion,
|
|
17650
|
+
siteStyleId: intent.siteStyleId,
|
|
17651
|
+
pageFlowPresetId: intent.pageFlowPresetId,
|
|
17652
|
+
blockLookPins: intent.blockLookPins,
|
|
17653
|
+
boundaryPins: intent.boundaryPins.map((pin) => ({
|
|
17654
|
+
boundaryId: pin.boundaryId,
|
|
17655
|
+
previousBlockId: pin.previousBlockId,
|
|
17656
|
+
nextBlockId: pin.nextBlockId,
|
|
17657
|
+
choice: userPinnedDesignChoice(boundaryTreatmentForBoundaryOptionId(pin.choice.value))
|
|
17658
|
+
}))
|
|
17384
17659
|
};
|
|
17385
17660
|
}
|
|
17386
|
-
function
|
|
17387
|
-
|
|
17388
|
-
|
|
17389
|
-
|
|
17390
|
-
boundaryId: pin.boundaryId,
|
|
17391
|
-
previousBlockId: pin.previousBlockId,
|
|
17392
|
-
nextBlockId: pin.nextBlockId,
|
|
17393
|
-
presetId: boundaryIssuePresetId(pin.choice.value),
|
|
17394
|
-
feedback: "debug"
|
|
17395
|
-
}]);
|
|
17661
|
+
function autoDesignChoice() {
|
|
17662
|
+
return { kind: "auto" };
|
|
17663
|
+
}
|
|
17664
|
+
function userPinnedDesignChoice(value) {
|
|
17396
17665
|
return {
|
|
17397
|
-
|
|
17398
|
-
|
|
17399
|
-
boundaryPins: intent.boundaryPins.filter((pin) => adjacentPairs.has(boundaryKey(pin.previousBlockId, pin.nextBlockId)))
|
|
17400
|
-
},
|
|
17401
|
-
issues: removedBoundaryIssues
|
|
17666
|
+
kind: "user-pinned",
|
|
17667
|
+
value
|
|
17402
17668
|
};
|
|
17403
17669
|
}
|
|
17404
|
-
|
|
17405
|
-
|
|
17406
|
-
|
|
17407
|
-
|
|
17408
|
-
|
|
17409
|
-
|
|
17410
|
-
|
|
17411
|
-
...pin,
|
|
17412
|
-
blockKind: event.nextBlockKind
|
|
17413
|
-
} : pin);
|
|
17414
|
-
const changed = intent.blockLookPins.find((pin) => pin.blockId === event.blockId);
|
|
17415
|
-
const incompatiblePinnedLook = changed && !event.compatiblePinnedLookPresetIds.includes(changed.choice.value) ? changed : null;
|
|
17670
|
+
function resolvePageDesignBlockLookChoice(intent, blockId) {
|
|
17671
|
+
return intent.blockLookPins.find((pin) => pin.blockId === blockId)?.choice ?? autoDesignChoice();
|
|
17672
|
+
}
|
|
17673
|
+
function resolvePageDesignBoundaryChoice(intent, previousBlockId, nextBlockId) {
|
|
17674
|
+
return intent.boundaryPins.find((pin) => pin.previousBlockId === previousBlockId && pin.nextBlockId === nextBlockId)?.choice ?? autoDesignChoice();
|
|
17675
|
+
}
|
|
17676
|
+
function buildBoundaryPin(previousBlockId, nextBlockId, choice) {
|
|
17416
17677
|
return {
|
|
17417
|
-
|
|
17418
|
-
|
|
17419
|
-
|
|
17420
|
-
|
|
17421
|
-
issues: incompatiblePinnedLook ? [{
|
|
17422
|
-
kind: "pinned-look-incompatible-with-block-kind",
|
|
17423
|
-
blockId: event.blockId,
|
|
17424
|
-
presetId: incompatiblePinnedLook.choice.value,
|
|
17425
|
-
previousBlockKind: incompatiblePinnedLook.blockKind,
|
|
17426
|
-
nextBlockKind: event.nextBlockKind,
|
|
17427
|
-
feedback: "user-facing"
|
|
17428
|
-
}] : []
|
|
17678
|
+
boundaryId: makeBoundaryId(previousBlockId, nextBlockId),
|
|
17679
|
+
previousBlockId,
|
|
17680
|
+
nextBlockId,
|
|
17681
|
+
choice
|
|
17429
17682
|
};
|
|
17430
17683
|
}
|
|
17431
|
-
function
|
|
17432
|
-
|
|
17433
|
-
|
|
17434
|
-
}
|
|
17435
|
-
/**
|
|
17436
|
-
* Ordinary block duplication does not copy boundary pins. Boundary pins represent
|
|
17437
|
-
* exact adjacent pairs, so duplicated blocks start with automatic surrounding breaks.
|
|
17438
|
-
*/
|
|
17439
|
-
function duplicateBlockInPageDesignIntent(intent, event) {
|
|
17440
|
-
const sourcePin = intent.blockLookPins.find((pin) => pin.blockId === event.sourceBlockId);
|
|
17441
|
-
if (!event.copyPinnedLook) {
|
|
17442
|
-
return {
|
|
17684
|
+
function reducePageDesignIntentForStructureEvent(intent, event) {
|
|
17685
|
+
switch (event.kind) {
|
|
17686
|
+
case "block-added": return {
|
|
17443
17687
|
intent,
|
|
17444
17688
|
issues: []
|
|
17445
17689
|
};
|
|
17690
|
+
case "block-removed": return removeBlockFromPageDesignIntent(intent, event.blockId);
|
|
17691
|
+
case "blocks-reordered": return pruneBoundaryPinsForOrder(intent, event.orderedBlockIds);
|
|
17692
|
+
case "block-kind-changed": return changeBlockKindInPageDesignIntent(intent, event);
|
|
17693
|
+
case "block-duplicated": return duplicateBlockInPageDesignIntent(intent, event);
|
|
17694
|
+
default: return assertNever$1(event, "Unhandled page design structure event");
|
|
17446
17695
|
}
|
|
17447
|
-
|
|
17448
|
-
|
|
17449
|
-
|
|
17450
|
-
|
|
17451
|
-
|
|
17452
|
-
|
|
17453
|
-
duplicatedBlockId: event.block.blockId,
|
|
17454
|
-
feedback: "debug"
|
|
17455
|
-
}]
|
|
17696
|
+
}
|
|
17697
|
+
function reducePageDesignIntentForUserAction(intent, action) {
|
|
17698
|
+
switch (action.kind) {
|
|
17699
|
+
case "set-page-flow": return {
|
|
17700
|
+
...intent,
|
|
17701
|
+
pageFlowPresetId: action.pageFlowPresetId
|
|
17456
17702
|
};
|
|
17703
|
+
case "set-block-look": return setBlockLookChoice(intent, action.block, action.choice);
|
|
17704
|
+
case "set-boundary": return setBoundaryChoice(intent, action.previousBlockId, action.nextBlockId, action.choice);
|
|
17705
|
+
default: return assertNever$1(action, "Unhandled page design user action");
|
|
17457
17706
|
}
|
|
17458
|
-
|
|
17459
|
-
|
|
17460
|
-
|
|
17461
|
-
|
|
17462
|
-
|
|
17463
|
-
|
|
17707
|
+
}
|
|
17708
|
+
function remapPageDesignIntentForDuplicate(intent, input) {
|
|
17709
|
+
const targetBySourceId = new Map(input.blockMappings.map((mapping) => [mapping.sourceBlockId, {
|
|
17710
|
+
blockId: mapping.targetBlockId,
|
|
17711
|
+
blockKind: mapping.targetBlockKind
|
|
17712
|
+
}]));
|
|
17713
|
+
const targetBlockOrder = input.blockMappings.map((mapping) => mapping.targetBlockId);
|
|
17714
|
+
const adjacentTargetPairs = adjacentPairKeySet(targetBlockOrder);
|
|
17715
|
+
const blockLookPins = intent.blockLookPins.flatMap((pin) => {
|
|
17716
|
+
const target = targetBySourceId.get(pin.blockId);
|
|
17717
|
+
return target ? [{
|
|
17718
|
+
blockId: target.blockId,
|
|
17719
|
+
blockKind: target.blockKind,
|
|
17720
|
+
choice: pin.choice
|
|
17721
|
+
}] : [];
|
|
17722
|
+
});
|
|
17723
|
+
const boundaryPins = intent.boundaryPins.flatMap((pin) => {
|
|
17724
|
+
const targetPrevious = targetBySourceId.get(pin.previousBlockId);
|
|
17725
|
+
const targetNext = targetBySourceId.get(pin.nextBlockId);
|
|
17726
|
+
if (!targetPrevious || !targetNext) {
|
|
17727
|
+
return [];
|
|
17728
|
+
}
|
|
17729
|
+
if (!adjacentTargetPairs.has(makeBoundaryId(targetPrevious.blockId, targetNext.blockId))) {
|
|
17730
|
+
return [];
|
|
17731
|
+
}
|
|
17732
|
+
return [buildBoundaryPin(targetPrevious.blockId, targetNext.blockId, pin.choice)];
|
|
17733
|
+
});
|
|
17734
|
+
return {
|
|
17735
|
+
intent: {
|
|
17736
|
+
...intent,
|
|
17737
|
+
blockLookPins,
|
|
17738
|
+
boundaryPins
|
|
17739
|
+
},
|
|
17740
|
+
issues: []
|
|
17741
|
+
};
|
|
17742
|
+
}
|
|
17743
|
+
function setBlockLookChoice(intent, block, choice) {
|
|
17744
|
+
const withoutBlock = intent.blockLookPins.filter((pin) => pin.blockId !== block.blockId);
|
|
17745
|
+
if (choice.kind === "auto") {
|
|
17746
|
+
return {
|
|
17747
|
+
...intent,
|
|
17748
|
+
blockLookPins: withoutBlock
|
|
17749
|
+
};
|
|
17750
|
+
}
|
|
17751
|
+
return {
|
|
17752
|
+
...intent,
|
|
17753
|
+
blockLookPins: [...withoutBlock, {
|
|
17754
|
+
blockId: block.blockId,
|
|
17755
|
+
blockKind: block.blockKind,
|
|
17756
|
+
choice
|
|
17757
|
+
}]
|
|
17758
|
+
};
|
|
17759
|
+
}
|
|
17760
|
+
function setBoundaryChoice(intent, previousBlockId, nextBlockId, choice) {
|
|
17761
|
+
const withoutBoundary = intent.boundaryPins.filter((pin) => pin.previousBlockId !== previousBlockId || pin.nextBlockId !== nextBlockId);
|
|
17762
|
+
if (choice.kind === "auto") {
|
|
17763
|
+
return {
|
|
17764
|
+
...intent,
|
|
17765
|
+
boundaryPins: withoutBoundary
|
|
17766
|
+
};
|
|
17767
|
+
}
|
|
17768
|
+
return {
|
|
17769
|
+
...intent,
|
|
17770
|
+
boundaryPins: [...withoutBoundary, buildBoundaryPin(previousBlockId, nextBlockId, choice)]
|
|
17771
|
+
};
|
|
17772
|
+
}
|
|
17773
|
+
function removeBlockFromPageDesignIntent(intent, blockId) {
|
|
17774
|
+
const removedLookIssues = intent.blockLookPins.flatMap((pin) => pin.blockId === blockId ? [{
|
|
17775
|
+
kind: "removed-look-pin-for-deleted-block",
|
|
17776
|
+
blockId,
|
|
17777
|
+
presetId: pin.choice.value,
|
|
17778
|
+
feedback: "debug"
|
|
17779
|
+
}] : []);
|
|
17780
|
+
const removedBoundaryIssues = intent.boundaryPins.flatMap((pin) => pin.previousBlockId === blockId || pin.nextBlockId === blockId ? [{
|
|
17781
|
+
kind: "removed-boundary-pin-for-broken-adjacency",
|
|
17782
|
+
boundaryId: pin.boundaryId,
|
|
17783
|
+
previousBlockId: pin.previousBlockId,
|
|
17784
|
+
nextBlockId: pin.nextBlockId,
|
|
17785
|
+
presetId: boundaryIssuePresetId(pin.choice.value),
|
|
17786
|
+
feedback: "debug"
|
|
17787
|
+
}] : []);
|
|
17788
|
+
return {
|
|
17789
|
+
intent: {
|
|
17790
|
+
...intent,
|
|
17791
|
+
blockLookPins: intent.blockLookPins.filter((pin) => pin.blockId !== blockId),
|
|
17792
|
+
boundaryPins: intent.boundaryPins.filter((pin) => pin.previousBlockId !== blockId && pin.nextBlockId !== blockId)
|
|
17793
|
+
},
|
|
17794
|
+
issues: [...removedLookIssues, ...removedBoundaryIssues]
|
|
17795
|
+
};
|
|
17796
|
+
}
|
|
17797
|
+
function pruneBoundaryPinsForOrder(intent, orderedBlockIds) {
|
|
17798
|
+
const adjacentPairs = adjacentPairKeySet(orderedBlockIds);
|
|
17799
|
+
const removedBoundaryIssues = intent.boundaryPins.flatMap((pin) => adjacentPairs.has(makeBoundaryId(pin.previousBlockId, pin.nextBlockId)) ? [] : [{
|
|
17800
|
+
kind: "removed-boundary-pin-for-broken-adjacency",
|
|
17801
|
+
boundaryId: pin.boundaryId,
|
|
17802
|
+
previousBlockId: pin.previousBlockId,
|
|
17803
|
+
nextBlockId: pin.nextBlockId,
|
|
17804
|
+
presetId: boundaryIssuePresetId(pin.choice.value),
|
|
17805
|
+
feedback: "debug"
|
|
17806
|
+
}]);
|
|
17807
|
+
return {
|
|
17808
|
+
intent: {
|
|
17809
|
+
...intent,
|
|
17810
|
+
boundaryPins: intent.boundaryPins.filter((pin) => adjacentPairs.has(makeBoundaryId(pin.previousBlockId, pin.nextBlockId)))
|
|
17811
|
+
},
|
|
17812
|
+
issues: removedBoundaryIssues
|
|
17813
|
+
};
|
|
17814
|
+
}
|
|
17815
|
+
/**
|
|
17816
|
+
* A block-kind change updates the pin's current block kind so future resolution sees
|
|
17817
|
+
* the current tree. If the pinned Look is incompatible, the pin remains stored and
|
|
17818
|
+
* the resolver must render a safe auto fallback while the user-facing issue is open.
|
|
17819
|
+
*/
|
|
17820
|
+
function changeBlockKindInPageDesignIntent(intent, event) {
|
|
17821
|
+
const blockLookPins = intent.blockLookPins.map((pin) => pin.blockId === event.blockId ? {
|
|
17822
|
+
...pin,
|
|
17823
|
+
blockKind: event.nextBlockKind
|
|
17824
|
+
} : pin);
|
|
17825
|
+
const changed = intent.blockLookPins.find((pin) => pin.blockId === event.blockId);
|
|
17826
|
+
const incompatiblePinnedLook = changed && !event.compatiblePinnedLookPresetIds.includes(changed.choice.value) ? changed : null;
|
|
17827
|
+
return {
|
|
17828
|
+
intent: {
|
|
17829
|
+
...intent,
|
|
17830
|
+
blockLookPins
|
|
17831
|
+
},
|
|
17832
|
+
issues: incompatiblePinnedLook ? [{
|
|
17833
|
+
kind: "pinned-look-incompatible-with-block-kind",
|
|
17834
|
+
blockId: event.blockId,
|
|
17835
|
+
presetId: incompatiblePinnedLook.choice.value,
|
|
17836
|
+
previousBlockKind: incompatiblePinnedLook.blockKind,
|
|
17837
|
+
nextBlockKind: event.nextBlockKind,
|
|
17838
|
+
feedback: "user-facing"
|
|
17839
|
+
}] : []
|
|
17840
|
+
};
|
|
17841
|
+
}
|
|
17842
|
+
function boundaryIssuePresetId(treatment) {
|
|
17843
|
+
if (typeof treatment === "string") return treatment;
|
|
17844
|
+
return boundaryOptionIdForTreatment(treatment) ?? unknownBoundaryOptionId;
|
|
17845
|
+
}
|
|
17846
|
+
/**
|
|
17847
|
+
* Ordinary block duplication does not copy boundary pins. Boundary pins represent
|
|
17848
|
+
* exact adjacent pairs, so duplicated blocks start with automatic surrounding breaks.
|
|
17849
|
+
*/
|
|
17850
|
+
function duplicateBlockInPageDesignIntent(intent, event) {
|
|
17851
|
+
const sourcePin = intent.blockLookPins.find((pin) => pin.blockId === event.sourceBlockId);
|
|
17852
|
+
if (!event.copyPinnedLook) {
|
|
17853
|
+
return {
|
|
17854
|
+
intent,
|
|
17855
|
+
issues: []
|
|
17856
|
+
};
|
|
17857
|
+
}
|
|
17858
|
+
if (!sourcePin) {
|
|
17859
|
+
return {
|
|
17860
|
+
intent,
|
|
17861
|
+
issues: [{
|
|
17862
|
+
kind: "missing-look-pin-to-copy-on-duplicate",
|
|
17863
|
+
sourceBlockId: event.sourceBlockId,
|
|
17864
|
+
duplicatedBlockId: event.block.blockId,
|
|
17865
|
+
feedback: "debug"
|
|
17866
|
+
}]
|
|
17867
|
+
};
|
|
17868
|
+
}
|
|
17869
|
+
return {
|
|
17870
|
+
intent: {
|
|
17871
|
+
...intent,
|
|
17872
|
+
blockLookPins: [...intent.blockLookPins, {
|
|
17873
|
+
blockId: event.block.blockId,
|
|
17874
|
+
blockKind: event.block.blockKind,
|
|
17464
17875
|
choice: sourcePin.choice
|
|
17465
17876
|
}]
|
|
17466
17877
|
},
|
|
@@ -17475,7 +17886,7 @@ function adjacentPairKeySet(orderedBlockIds) {
|
|
|
17475
17886
|
}
|
|
17476
17887
|
let previousBlockId = first;
|
|
17477
17888
|
for (const nextBlockId of rest) {
|
|
17478
|
-
pairs.add(
|
|
17889
|
+
pairs.add(makeBoundaryId(previousBlockId, nextBlockId));
|
|
17479
17890
|
previousBlockId = nextBlockId;
|
|
17480
17891
|
}
|
|
17481
17892
|
return pairs;
|
|
@@ -17514,14 +17925,11 @@ function validateUniquePageDesignPins(intent, ctx) {
|
|
|
17514
17925
|
label: "block Look pin"
|
|
17515
17926
|
});
|
|
17516
17927
|
addDuplicateStringIssues(ctx, {
|
|
17517
|
-
values: intent.boundaryPins.map((pin) =>
|
|
17928
|
+
values: intent.boundaryPins.map((pin) => makeBoundaryId(pin.previousBlockId, pin.nextBlockId)),
|
|
17518
17929
|
path: ["boundaryPins"],
|
|
17519
17930
|
label: "boundary pin"
|
|
17520
17931
|
});
|
|
17521
17932
|
}
|
|
17522
|
-
function boundaryKey(previousBlockId, nextBlockId) {
|
|
17523
|
-
return makeBoundaryId(previousBlockId, nextBlockId);
|
|
17524
|
-
}
|
|
17525
17933
|
|
|
17526
17934
|
//#endregion
|
|
17527
17935
|
//#region ../theme-core/src/site-styles/contentTemplateDesignIntent.ts
|
|
@@ -20886,7 +21294,7 @@ function underlineNavLinkStyle(colorToken, underlineColorToken, typography = "pl
|
|
|
20886
21294
|
}] }
|
|
20887
21295
|
}, typography);
|
|
20888
21296
|
}
|
|
20889
|
-
function pillNavLinkStyle(colorToken, backgroundToken = "primary", opacity = 10, typography = "plain") {
|
|
21297
|
+
function pillNavLinkStyle(colorToken, backgroundToken$1 = "primary", opacity = 10, typography = "plain") {
|
|
20890
21298
|
return applyNavTypography({
|
|
20891
21299
|
name: "Pill",
|
|
20892
21300
|
typography: "body",
|
|
@@ -20900,14 +21308,14 @@ function pillNavLinkStyle(colorToken, backgroundToken = "primary", opacity = 10,
|
|
|
20900
21308
|
hover: [{
|
|
20901
21309
|
effectId: "background-on-hover-alpha",
|
|
20902
21310
|
options: {
|
|
20903
|
-
colorToken: backgroundToken,
|
|
21311
|
+
colorToken: backgroundToken$1,
|
|
20904
21312
|
opacity
|
|
20905
21313
|
}
|
|
20906
21314
|
}],
|
|
20907
21315
|
active: [{
|
|
20908
21316
|
effectId: "background-on-hover-alpha",
|
|
20909
21317
|
options: {
|
|
20910
|
-
colorToken: backgroundToken,
|
|
21318
|
+
colorToken: backgroundToken$1,
|
|
20911
21319
|
opacity: opacity + 5
|
|
20912
21320
|
}
|
|
20913
21321
|
}]
|
|
@@ -21961,151 +22369,650 @@ function classifyRuntimeStyleFields(input) {
|
|
|
21961
22369
|
fields: []
|
|
21962
22370
|
};
|
|
21963
22371
|
}
|
|
21964
|
-
if (!input.authority) {
|
|
21965
|
-
return {
|
|
21966
|
-
kind: "unsupported-manual-review",
|
|
21967
|
-
fields
|
|
21968
|
-
};
|
|
22372
|
+
if (!input.authority) {
|
|
22373
|
+
return {
|
|
22374
|
+
kind: "unsupported-manual-review",
|
|
22375
|
+
fields
|
|
22376
|
+
};
|
|
22377
|
+
}
|
|
22378
|
+
switch (input.authority.kind) {
|
|
22379
|
+
case "theme-v2": return {
|
|
22380
|
+
kind: "interpretable-override",
|
|
22381
|
+
fields,
|
|
22382
|
+
authority: input.authority
|
|
22383
|
+
};
|
|
22384
|
+
case "advanced-detached": return {
|
|
22385
|
+
kind: "advanced-detached",
|
|
22386
|
+
fields,
|
|
22387
|
+
authority: input.authority
|
|
22388
|
+
};
|
|
22389
|
+
case "legacy-raw": return {
|
|
22390
|
+
kind: "unsupported-manual-review",
|
|
22391
|
+
fields,
|
|
22392
|
+
authority: input.authority
|
|
22393
|
+
};
|
|
22394
|
+
default: return assertNever$1(input.authority);
|
|
22395
|
+
}
|
|
22396
|
+
}
|
|
22397
|
+
function canWriteThemeV2RuntimeFields(authority) {
|
|
22398
|
+
return authority?.kind === "theme-v2";
|
|
22399
|
+
}
|
|
22400
|
+
function blockReasonForAuthority(authority) {
|
|
22401
|
+
if (!authority) {
|
|
22402
|
+
return "missing-theme-v2-authority";
|
|
22403
|
+
}
|
|
22404
|
+
switch (authority?.kind) {
|
|
22405
|
+
case "advanced-detached": return "advanced-detached";
|
|
22406
|
+
case "legacy-raw": return "legacy-raw";
|
|
22407
|
+
default: return assertNever$1(authority);
|
|
22408
|
+
}
|
|
22409
|
+
}
|
|
22410
|
+
/**
|
|
22411
|
+
* Replace every compiler-owned field on a block's content with a fresh compiled
|
|
22412
|
+
* set — the one primitive both writers of compiled output share.
|
|
22413
|
+
*
|
|
22414
|
+
* Replacement rather than merge is the whole point: a field the new
|
|
22415
|
+
* compilation does not produce must *go*, or a recompile onto a Look that asks
|
|
22416
|
+
* for no card leaves the old `_cardStyles` sitting there claiming a surface
|
|
22417
|
+
* nobody asked for. Every writer that discovers compiler ownership for itself
|
|
22418
|
+
* eventually forgets one of these names, so nobody does.
|
|
22419
|
+
*
|
|
22420
|
+
* Pure, and deliberately free of authority checks — those belong to the
|
|
22421
|
+
* persistence wrapper, not to the shape of the content.
|
|
22422
|
+
*/
|
|
22423
|
+
function withCompiledRuntimeStyleFields(input) {
|
|
22424
|
+
const authored = Object.fromEntries(Object.entries(stripStaleTransitionStyleGroup(input.content)).filter(([fieldName]) => !themeV2CompilerOwnedFieldNames.includes(fieldName)));
|
|
22425
|
+
return {
|
|
22426
|
+
...authored,
|
|
22427
|
+
...input.fields
|
|
22428
|
+
};
|
|
22429
|
+
}
|
|
22430
|
+
/**
|
|
22431
|
+
* Persisted Theme V2 output is compile-at-write: once a block has Theme V2
|
|
22432
|
+
* authority, compiler-owned runtime fields are replaced in the same content
|
|
22433
|
+
* version. Preview-only compile-at-read callers should use compileBlockRuntimeFields
|
|
22434
|
+
* and avoid persisting these fields.
|
|
22435
|
+
*/
|
|
22436
|
+
function replaceCompiledRuntimeStyleFields(input) {
|
|
22437
|
+
if (!canWriteThemeV2RuntimeFields(input.authority)) {
|
|
22438
|
+
return {
|
|
22439
|
+
kind: "blocked",
|
|
22440
|
+
reason: blockReasonForAuthority(input.authority),
|
|
22441
|
+
content: input.content
|
|
22442
|
+
};
|
|
22443
|
+
}
|
|
22444
|
+
return {
|
|
22445
|
+
kind: "applied",
|
|
22446
|
+
content: withCompiledRuntimeStyleFields(input)
|
|
22447
|
+
};
|
|
22448
|
+
}
|
|
22449
|
+
function uniqueBlockIds(values) {
|
|
22450
|
+
return [...new Set(values)];
|
|
22451
|
+
}
|
|
22452
|
+
function collectPageStyleAuthorityBuckets(styleAuthorities) {
|
|
22453
|
+
const themeV2BlockIds = [];
|
|
22454
|
+
const legacyRawBlockIds = [];
|
|
22455
|
+
const advancedDetachedBlockIds = [];
|
|
22456
|
+
for (const entry of styleAuthorities) {
|
|
22457
|
+
switch (entry.authority.kind) {
|
|
22458
|
+
case "theme-v2":
|
|
22459
|
+
themeV2BlockIds.push(entry.blockId);
|
|
22460
|
+
break;
|
|
22461
|
+
case "legacy-raw":
|
|
22462
|
+
legacyRawBlockIds.push(entry.blockId);
|
|
22463
|
+
break;
|
|
22464
|
+
case "advanced-detached":
|
|
22465
|
+
advancedDetachedBlockIds.push(entry.blockId);
|
|
22466
|
+
break;
|
|
22467
|
+
default: assertNever$1(entry.authority);
|
|
22468
|
+
}
|
|
22469
|
+
}
|
|
22470
|
+
return {
|
|
22471
|
+
themeV2BlockIds: uniqueBlockIds(themeV2BlockIds),
|
|
22472
|
+
legacyRawBlockIds: uniqueBlockIds(legacyRawBlockIds),
|
|
22473
|
+
advancedDetachedBlockIds: uniqueBlockIds(advancedDetachedBlockIds)
|
|
22474
|
+
};
|
|
22475
|
+
}
|
|
22476
|
+
function summarizePageStyleAuthorities(state) {
|
|
22477
|
+
const { themeV2BlockIds, legacyRawBlockIds, advancedDetachedBlockIds } = collectPageStyleAuthorityBuckets(state.styleAuthorities);
|
|
22478
|
+
if (themeV2BlockIds.length === 0 && legacyRawBlockIds.length === 0 && advancedDetachedBlockIds.length === 0) {
|
|
22479
|
+
return {
|
|
22480
|
+
kind: "no-runtime-authority",
|
|
22481
|
+
themeV2BlockIds: [],
|
|
22482
|
+
legacyRawBlockIds: [],
|
|
22483
|
+
advancedDetachedBlockIds: []
|
|
22484
|
+
};
|
|
22485
|
+
}
|
|
22486
|
+
if (legacyRawBlockIds.length > 0) {
|
|
22487
|
+
return {
|
|
22488
|
+
kind: "manual-review-required",
|
|
22489
|
+
themeV2BlockIds,
|
|
22490
|
+
legacyRawBlockIds,
|
|
22491
|
+
advancedDetachedBlockIds
|
|
22492
|
+
};
|
|
22493
|
+
}
|
|
22494
|
+
if (themeV2BlockIds.length === 0) {
|
|
22495
|
+
return {
|
|
22496
|
+
kind: "advanced-detached-only",
|
|
22497
|
+
themeV2BlockIds: [],
|
|
22498
|
+
legacyRawBlockIds: [],
|
|
22499
|
+
advancedDetachedBlockIds
|
|
22500
|
+
};
|
|
22501
|
+
}
|
|
22502
|
+
if (advancedDetachedBlockIds.length > 0) {
|
|
22503
|
+
return {
|
|
22504
|
+
kind: "mixed-authority",
|
|
22505
|
+
themeV2BlockIds,
|
|
22506
|
+
legacyRawBlockIds: [],
|
|
22507
|
+
advancedDetachedBlockIds
|
|
22508
|
+
};
|
|
22509
|
+
}
|
|
22510
|
+
return {
|
|
22511
|
+
kind: "theme-v2-only",
|
|
22512
|
+
themeV2BlockIds,
|
|
22513
|
+
legacyRawBlockIds: [],
|
|
22514
|
+
advancedDetachedBlockIds: []
|
|
22515
|
+
};
|
|
22516
|
+
}
|
|
22517
|
+
|
|
22518
|
+
//#endregion
|
|
22519
|
+
//#region ../theme-core/src/site-styles/pageFlowPresets.ts
|
|
22520
|
+
/**
|
|
22521
|
+
* Must remain non-empty; downstream code indexes `[0]` as the documented default.
|
|
22522
|
+
*/
|
|
22523
|
+
const pageFlowPresets = [
|
|
22524
|
+
{
|
|
22525
|
+
id: asPageFlowPresetId("flow:quiet"),
|
|
22526
|
+
label: "Quiet",
|
|
22527
|
+
boundaryStrategy: "quiet",
|
|
22528
|
+
defaultBoundaryOptionId: noneBoundaryOption.id
|
|
22529
|
+
},
|
|
22530
|
+
{
|
|
22531
|
+
id: asPageFlowPresetId("flow:balanced"),
|
|
22532
|
+
label: "Balanced",
|
|
22533
|
+
boundaryStrategy: "balanced",
|
|
22534
|
+
defaultBoundaryOptionId: softBoundaryOption.id
|
|
22535
|
+
},
|
|
22536
|
+
{
|
|
22537
|
+
id: asPageFlowPresetId("flow:expressive"),
|
|
22538
|
+
label: "Expressive",
|
|
22539
|
+
boundaryStrategy: "expressive",
|
|
22540
|
+
defaultBoundaryOptionId: spaciousBoundaryOption.id
|
|
22541
|
+
}
|
|
22542
|
+
];
|
|
22543
|
+
/**
|
|
22544
|
+
* The break a join gets when nothing more specific applies. An unknown preset
|
|
22545
|
+
* id (a stale or policy-owned one) falls back to the first boundary option,
|
|
22546
|
+
* and `preset` is null so callers can tell the two apart.
|
|
22547
|
+
*/
|
|
22548
|
+
function pageFlowDefaultBoundary(pageFlowPresetId) {
|
|
22549
|
+
const preset = pageFlowPresets.find((candidate$1) => candidate$1.id === pageFlowPresetId) ?? null;
|
|
22550
|
+
return {
|
|
22551
|
+
preset,
|
|
22552
|
+
boundaryOptionId: preset?.defaultBoundaryOptionId ?? boundaryOptions[0].id
|
|
22553
|
+
};
|
|
22554
|
+
}
|
|
22555
|
+
|
|
22556
|
+
//#endregion
|
|
22557
|
+
//#region ../theme-core/src/site-styles/lookResolution.ts
|
|
22558
|
+
function blockAppearancePresetSupportsBlockKind(preset, blockKind) {
|
|
22559
|
+
return preset.blockKinds.some((candidate$1) => candidate$1 === blockKind);
|
|
22560
|
+
}
|
|
22561
|
+
function preferredAppearanceTargetForBlockKind(blockKind) {
|
|
22562
|
+
switch (blockKind) {
|
|
22563
|
+
case "block.event-calendar":
|
|
22564
|
+
case "block.event-listing": return "events";
|
|
22565
|
+
default: return null;
|
|
22566
|
+
}
|
|
22567
|
+
}
|
|
22568
|
+
function sortCompatibleBlockAppearancePresets(blockKind, options) {
|
|
22569
|
+
const preferredTarget = preferredAppearanceTargetForBlockKind(blockKind);
|
|
22570
|
+
if (!preferredTarget) {
|
|
22571
|
+
return options;
|
|
22572
|
+
}
|
|
22573
|
+
return [...options].sort((left, right) => {
|
|
22574
|
+
const leftPreset = appearancePresets.find((preset) => preset.id === left.id);
|
|
22575
|
+
const rightPreset = appearancePresets.find((preset) => preset.id === right.id);
|
|
22576
|
+
const leftPreferred = leftPreset?.target === preferredTarget;
|
|
22577
|
+
const rightPreferred = rightPreset?.target === preferredTarget;
|
|
22578
|
+
if (leftPreferred === rightPreferred) {
|
|
22579
|
+
return 0;
|
|
22580
|
+
}
|
|
22581
|
+
return leftPreferred ? -1 : 1;
|
|
22582
|
+
});
|
|
22583
|
+
}
|
|
22584
|
+
function blockAppearancePresetSupportsLayoutProfile(preset, profile, input = {}) {
|
|
22585
|
+
const constraints = preset.constraints;
|
|
22586
|
+
if (!constraints || !constraints.layoutFamilies && !constraints.layoutVariantKeys) {
|
|
22587
|
+
return true;
|
|
22588
|
+
}
|
|
22589
|
+
if (!profile) {
|
|
22590
|
+
return input.allowLayoutConstrainedPresetWithoutProfile ?? true;
|
|
22591
|
+
}
|
|
22592
|
+
return layoutProfileSupportsConstraints(profile, constraints);
|
|
22593
|
+
}
|
|
22594
|
+
function resolveBlockAppearancePreset(preset, layoutProfile = null) {
|
|
22595
|
+
return {
|
|
22596
|
+
id: asAppearancePresetId(preset.id),
|
|
22597
|
+
label: preset.label,
|
|
22598
|
+
design: resolveBlockAppearancePresetDesign(preset, layoutProfile)
|
|
22599
|
+
};
|
|
22600
|
+
}
|
|
22601
|
+
function getCompatibleBlockAppearancePresets(input) {
|
|
22602
|
+
const options = appearancePresets.flatMap((preset) => {
|
|
22603
|
+
if (!blockAppearancePresetSupportsBlockKind(preset, input.blockKind) || !blockAppearancePresetSupportsLayoutProfile(preset, input.layoutProfile ?? null, { allowLayoutConstrainedPresetWithoutProfile: input.allowLayoutConstrainedPresetWithoutProfile })) {
|
|
22604
|
+
return [];
|
|
22605
|
+
}
|
|
22606
|
+
return [resolveBlockAppearancePreset(preset, input.layoutProfile ?? null)];
|
|
22607
|
+
});
|
|
22608
|
+
const sortedOptions = sortCompatibleBlockAppearancePresets(input.blockKind, options);
|
|
22609
|
+
const recommendedIds = input.siteStyle?.recommendedAppearancePresetIds ?? [];
|
|
22610
|
+
if (recommendedIds.length === 0) {
|
|
22611
|
+
return sortedOptions;
|
|
22612
|
+
}
|
|
22613
|
+
const recommended = recommendedIds.flatMap((presetId) => sortedOptions.find((option) => option.id === presetId) ?? []);
|
|
22614
|
+
const alreadyIncludedIds = new Set(recommended.map((option) => option.id));
|
|
22615
|
+
return [...recommended, ...sortedOptions.filter((option) => !alreadyIncludedIds.has(option.id))];
|
|
22616
|
+
}
|
|
22617
|
+
|
|
22618
|
+
//#endregion
|
|
22619
|
+
//#region ../theme-core/src/site-styles/siteStyleBlockPolicies.ts
|
|
22620
|
+
const defaultPolicyPageFlowPresetId = asPageFlowPresetId("generated-default");
|
|
22621
|
+
const southWestTwerkSchoolSiteStyleId = asSiteStyleId("site-style:south-west-twerk-school");
|
|
22622
|
+
const heroBrandScrimFixedFrameLookId = asAppearancePresetId("hero-brand-scrim-fixed-frame");
|
|
22623
|
+
const classicHeroLayoutVariantKey = asLayoutVariantKey("classic");
|
|
22624
|
+
const microHeroLayoutVariantKey = asLayoutVariantKey("micro");
|
|
22625
|
+
const waveBoundaryOptionId = asBoundaryOptionId("break:wave");
|
|
22626
|
+
const registeredSiteStyleBlockPolicies = [{
|
|
22627
|
+
siteStyleId: southWestTwerkSchoolSiteStyleId,
|
|
22628
|
+
kind: "locked-look-and-layouts",
|
|
22629
|
+
blockKind: "block.hero",
|
|
22630
|
+
lookId: heroBrandScrimFixedFrameLookId,
|
|
22631
|
+
allowedLayoutVariantKeys: [classicHeroLayoutVariantKey, microHeroLayoutVariantKey],
|
|
22632
|
+
defaultLayoutVariantKey: classicHeroLayoutVariantKey,
|
|
22633
|
+
defaultBoundaryAfter: {
|
|
22634
|
+
optionId: waveBoundaryOptionId,
|
|
22635
|
+
mode: "default-only"
|
|
22636
|
+
},
|
|
22637
|
+
customize: {
|
|
22638
|
+
hideDisallowedLooks: true,
|
|
22639
|
+
hideDisallowedLayouts: true
|
|
22640
|
+
}
|
|
22641
|
+
}];
|
|
22642
|
+
function siteStyleBlockPolicies() {
|
|
22643
|
+
return registeredSiteStyleBlockPolicies;
|
|
22644
|
+
}
|
|
22645
|
+
function buildInitialPolicyPageDesignIntent(siteStyleId) {
|
|
22646
|
+
return {
|
|
22647
|
+
schemaVersion: pageDesignIntentSchemaVersion,
|
|
22648
|
+
siteStyleId,
|
|
22649
|
+
pageFlowPresetId: defaultPolicyPageFlowPresetId,
|
|
22650
|
+
blockLookPins: [],
|
|
22651
|
+
boundaryPins: []
|
|
22652
|
+
};
|
|
22653
|
+
}
|
|
22654
|
+
function deriveSiteStyleBlockPolicy(input) {
|
|
22655
|
+
return registeredSiteStyleBlockPolicies.find((policy) => policy.siteStyleId === input.siteStyleId && policy.blockKind === input.blockKind) ?? { kind: "open" };
|
|
22656
|
+
}
|
|
22657
|
+
function isLayoutVariantAllowedByPolicy(policy, layoutVariantKey) {
|
|
22658
|
+
switch (policy.kind) {
|
|
22659
|
+
case "open": return true;
|
|
22660
|
+
case "locked-look-and-layouts": return policy.allowedLayoutVariantKeys.includes(layoutVariantKey);
|
|
22661
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
21969
22662
|
}
|
|
21970
|
-
|
|
21971
|
-
|
|
21972
|
-
|
|
21973
|
-
|
|
21974
|
-
|
|
21975
|
-
|
|
21976
|
-
case "advanced-detached": return {
|
|
21977
|
-
kind: "advanced-detached",
|
|
21978
|
-
fields,
|
|
21979
|
-
authority: input.authority
|
|
21980
|
-
};
|
|
21981
|
-
case "legacy-raw": return {
|
|
21982
|
-
kind: "unsupported-manual-review",
|
|
21983
|
-
fields,
|
|
21984
|
-
authority: input.authority
|
|
21985
|
-
};
|
|
21986
|
-
default: return assertNever$1(input.authority);
|
|
22663
|
+
}
|
|
22664
|
+
function normalizeLayoutVariantForPolicy(policy, layoutVariantKey) {
|
|
22665
|
+
switch (policy.kind) {
|
|
22666
|
+
case "open": return layoutVariantKey ?? null;
|
|
22667
|
+
case "locked-look-and-layouts": return layoutVariantKey && isLayoutVariantAllowedByPolicy(policy, layoutVariantKey) ? layoutVariantKey : policy.defaultLayoutVariantKey;
|
|
22668
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
21987
22669
|
}
|
|
21988
22670
|
}
|
|
21989
|
-
function
|
|
21990
|
-
|
|
22671
|
+
function filterLayoutProfilesForPolicy(policy, layoutProfiles) {
|
|
22672
|
+
switch (policy.kind) {
|
|
22673
|
+
case "open": return layoutProfiles;
|
|
22674
|
+
case "locked-look-and-layouts": return layoutProfiles.filter((profile) => isLayoutVariantAllowedByPolicy(policy, profile.variantKey));
|
|
22675
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
22676
|
+
}
|
|
21991
22677
|
}
|
|
21992
|
-
function
|
|
21993
|
-
|
|
21994
|
-
|
|
22678
|
+
function isLookAllowedByPolicy(policy, lookId) {
|
|
22679
|
+
switch (policy.kind) {
|
|
22680
|
+
case "open": return true;
|
|
22681
|
+
case "locked-look-and-layouts": return lookId === policy.lookId;
|
|
22682
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
21995
22683
|
}
|
|
21996
|
-
|
|
21997
|
-
|
|
21998
|
-
|
|
21999
|
-
|
|
22684
|
+
}
|
|
22685
|
+
function filterLookIdsForPolicy(policy, looks) {
|
|
22686
|
+
switch (policy.kind) {
|
|
22687
|
+
case "open": return looks;
|
|
22688
|
+
case "locked-look-and-layouts": return looks.filter((look) => look.id === policy.lookId);
|
|
22689
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
22000
22690
|
}
|
|
22001
22691
|
}
|
|
22002
|
-
|
|
22003
|
-
* Replace every compiler-owned field on a block's content with a fresh compiled
|
|
22004
|
-
* set — the one primitive both writers of compiled output share.
|
|
22005
|
-
*
|
|
22006
|
-
* Replacement rather than merge is the whole point: a field the new
|
|
22007
|
-
* compilation does not produce must *go*, or a recompile onto a Look that asks
|
|
22008
|
-
* for no card leaves the old `_cardStyles` sitting there claiming a surface
|
|
22009
|
-
* nobody asked for. Every writer that discovers compiler ownership for itself
|
|
22010
|
-
* eventually forgets one of these names, so nobody does.
|
|
22011
|
-
*
|
|
22012
|
-
* Pure, and deliberately free of authority checks — those belong to the
|
|
22013
|
-
* persistence wrapper, not to the shape of the content.
|
|
22014
|
-
*/
|
|
22015
|
-
function withCompiledRuntimeStyleFields(input) {
|
|
22016
|
-
const authored = Object.fromEntries(Object.entries(input.content).filter(([fieldName]) => !themeV2CompilerOwnedFieldNames.includes(fieldName)));
|
|
22692
|
+
function requiredLookChoice(lookId) {
|
|
22017
22693
|
return {
|
|
22018
|
-
|
|
22019
|
-
|
|
22694
|
+
kind: "user-pinned",
|
|
22695
|
+
value: lookId
|
|
22020
22696
|
};
|
|
22021
22697
|
}
|
|
22022
22698
|
/**
|
|
22023
|
-
*
|
|
22024
|
-
*
|
|
22025
|
-
*
|
|
22026
|
-
*
|
|
22699
|
+
* Writes the look pins a locked-look site style requires.
|
|
22700
|
+
*
|
|
22701
|
+
* Boundary pins are never written: a site style's default break after a block
|
|
22702
|
+
* is resolved at read time by `resolveJoinTreatment`, so it shows as a default
|
|
22703
|
+
* and follows later changes to the style (issue 1422). Pins already stored,
|
|
22704
|
+
* including ones an earlier version wrote on the style's behalf, are left as
|
|
22705
|
+
* they are.
|
|
22027
22706
|
*/
|
|
22028
|
-
function
|
|
22029
|
-
|
|
22030
|
-
|
|
22031
|
-
|
|
22032
|
-
|
|
22033
|
-
|
|
22034
|
-
|
|
22707
|
+
function applySiteStyleBlockPoliciesToPageDesignIntent(intent, blocks) {
|
|
22708
|
+
const policyLookPins = blocks.flatMap((block) => {
|
|
22709
|
+
const policy = deriveSiteStyleBlockPolicy({
|
|
22710
|
+
siteStyleId: intent.siteStyleId,
|
|
22711
|
+
blockKind: block.blockKind
|
|
22712
|
+
});
|
|
22713
|
+
switch (policy.kind) {
|
|
22714
|
+
case "open": return [];
|
|
22715
|
+
case "locked-look-and-layouts": return [{
|
|
22716
|
+
blockId: block.blockId,
|
|
22717
|
+
blockKind: block.blockKind,
|
|
22718
|
+
choice: requiredLookChoice(policy.lookId)
|
|
22719
|
+
}];
|
|
22720
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
22721
|
+
}
|
|
22722
|
+
});
|
|
22723
|
+
if (policyLookPins.length === 0) {
|
|
22724
|
+
return intent;
|
|
22035
22725
|
}
|
|
22726
|
+
const policyPinBlockIds = new Set(policyLookPins.map((pin) => pin.blockId));
|
|
22036
22727
|
return {
|
|
22037
|
-
|
|
22038
|
-
|
|
22728
|
+
...intent,
|
|
22729
|
+
blockLookPins: [...intent.blockLookPins.filter((pin) => !policyPinBlockIds.has(pin.blockId)), ...policyLookPins]
|
|
22039
22730
|
};
|
|
22040
22731
|
}
|
|
22041
|
-
function
|
|
22042
|
-
|
|
22732
|
+
function planBlockContentVariantPolicyUpdate(input) {
|
|
22733
|
+
switch (input.policy.kind) {
|
|
22734
|
+
case "open": return { kind: "unchanged" };
|
|
22735
|
+
case "locked-look-and-layouts": {
|
|
22736
|
+
const currentVariant = typeof input.content.variant === "string" ? asLayoutVariantKey(input.content.variant) : null;
|
|
22737
|
+
return currentVariant && isLayoutVariantAllowedByPolicy(input.policy, currentVariant) ? { kind: "unchanged" } : {
|
|
22738
|
+
kind: "set-variant",
|
|
22739
|
+
variantKey: input.policy.defaultLayoutVariantKey
|
|
22740
|
+
};
|
|
22741
|
+
}
|
|
22742
|
+
default: return assertNever$1(input.policy, "Unhandled site style block policy");
|
|
22743
|
+
}
|
|
22043
22744
|
}
|
|
22044
|
-
function
|
|
22045
|
-
const
|
|
22046
|
-
|
|
22047
|
-
|
|
22048
|
-
|
|
22049
|
-
|
|
22050
|
-
|
|
22051
|
-
|
|
22052
|
-
|
|
22053
|
-
|
|
22054
|
-
|
|
22055
|
-
|
|
22056
|
-
|
|
22057
|
-
|
|
22058
|
-
|
|
22059
|
-
|
|
22745
|
+
function applyBlockContentVariantPolicy(input) {
|
|
22746
|
+
const plan = planBlockContentVariantPolicyUpdate(input);
|
|
22747
|
+
switch (plan.kind) {
|
|
22748
|
+
case "unchanged": return input.content;
|
|
22749
|
+
case "set-variant": return {
|
|
22750
|
+
...input.content,
|
|
22751
|
+
variant: plan.variantKey
|
|
22752
|
+
};
|
|
22753
|
+
default: return assertNever$1(plan, "Unhandled block content variant policy plan");
|
|
22754
|
+
}
|
|
22755
|
+
}
|
|
22756
|
+
function auditPageDesignIntentPolicy(input) {
|
|
22757
|
+
return input.blocks.flatMap((block) => {
|
|
22758
|
+
const policy = deriveSiteStyleBlockPolicy({
|
|
22759
|
+
siteStyleId: input.intent.siteStyleId,
|
|
22760
|
+
blockKind: block.blockKind
|
|
22761
|
+
});
|
|
22762
|
+
switch (policy.kind) {
|
|
22763
|
+
case "open": return [];
|
|
22764
|
+
case "locked-look-and-layouts": {
|
|
22765
|
+
const choice = resolvePageDesignBlockLookChoice(input.intent, block.blockId);
|
|
22766
|
+
const lookIssue = choice.kind === "auto" ? {
|
|
22767
|
+
kind: "missing-required-look-pin",
|
|
22768
|
+
blockId: block.blockId,
|
|
22769
|
+
blockKind: block.blockKind,
|
|
22770
|
+
requiredLookId: policy.lookId
|
|
22771
|
+
} : choice.value === policy.lookId ? null : {
|
|
22772
|
+
kind: "unsupported-look-pin",
|
|
22773
|
+
blockId: block.blockId,
|
|
22774
|
+
blockKind: block.blockKind,
|
|
22775
|
+
actualLookId: choice.value,
|
|
22776
|
+
requiredLookId: policy.lookId
|
|
22777
|
+
};
|
|
22778
|
+
const layoutIssue = block.currentLayoutVariantKey && !isLayoutVariantAllowedByPolicy(policy, block.currentLayoutVariantKey) ? {
|
|
22779
|
+
kind: "unsupported-layout-variant",
|
|
22780
|
+
blockId: block.blockId,
|
|
22781
|
+
blockKind: block.blockKind,
|
|
22782
|
+
actualLayoutVariantKey: block.currentLayoutVariantKey,
|
|
22783
|
+
defaultLayoutVariantKey: policy.defaultLayoutVariantKey
|
|
22784
|
+
} : null;
|
|
22785
|
+
const issues = [];
|
|
22786
|
+
if (lookIssue) {
|
|
22787
|
+
issues.push(lookIssue);
|
|
22788
|
+
}
|
|
22789
|
+
if (layoutIssue) {
|
|
22790
|
+
issues.push(layoutIssue);
|
|
22791
|
+
}
|
|
22792
|
+
return issues;
|
|
22793
|
+
}
|
|
22794
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
22795
|
+
}
|
|
22796
|
+
});
|
|
22797
|
+
}
|
|
22798
|
+
function auditPageDesignAuthorityPolicy(input) {
|
|
22799
|
+
if (input.intent) {
|
|
22800
|
+
return auditPageDesignIntentPolicy({
|
|
22801
|
+
intent: input.intent,
|
|
22802
|
+
blocks: input.blocks
|
|
22803
|
+
});
|
|
22804
|
+
}
|
|
22805
|
+
const policyBlockCount = input.blocks.filter((block) => deriveSiteStyleBlockPolicy({
|
|
22806
|
+
siteStyleId: input.siteStyleId,
|
|
22807
|
+
blockKind: block.blockKind
|
|
22808
|
+
}).kind !== "open").length;
|
|
22809
|
+
return policyBlockCount === 0 ? [] : [{
|
|
22810
|
+
kind: "missing-page-design-authority",
|
|
22811
|
+
siteStyleId: input.siteStyleId,
|
|
22812
|
+
policyBlockCount
|
|
22813
|
+
}];
|
|
22814
|
+
}
|
|
22815
|
+
function assertRegisteredSiteStyleBlockPoliciesAreValid() {
|
|
22816
|
+
registeredSiteStyleBlockPolicies.forEach((policy) => {
|
|
22817
|
+
if (!policy.allowedLayoutVariantKeys.includes(policy.defaultLayoutVariantKey)) {
|
|
22818
|
+
throw new Error(`Site style block policy for ${policy.siteStyleId} ${policy.blockKind} has a default layout outside its allowed layouts.`);
|
|
22819
|
+
}
|
|
22820
|
+
const preset = appearancePresets.find((candidate$1) => candidate$1.id === policy.lookId && blockAppearancePresetSupportsBlockKind(candidate$1, policy.blockKind));
|
|
22821
|
+
if (!preset) {
|
|
22822
|
+
throw new Error(`Site style block policy for ${policy.siteStyleId} ${policy.blockKind} references an unavailable Look ${policy.lookId}.`);
|
|
22060
22823
|
}
|
|
22824
|
+
});
|
|
22825
|
+
}
|
|
22826
|
+
function autoChoiceAllowedByPolicy(policy) {
|
|
22827
|
+
switch (policy.kind) {
|
|
22828
|
+
case "open": return autoDesignChoice();
|
|
22829
|
+
case "locked-look-and-layouts": return requiredLookChoice(policy.lookId);
|
|
22830
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
22061
22831
|
}
|
|
22832
|
+
}
|
|
22833
|
+
|
|
22834
|
+
//#endregion
|
|
22835
|
+
//#region ../theme-core/src/site-styles/joinTreatment.ts
|
|
22836
|
+
/** Narrows any join (a resolved intent included) to its public, intent-only form. */
|
|
22837
|
+
function toPageRuntimeJoin(join) {
|
|
22062
22838
|
return {
|
|
22063
|
-
|
|
22064
|
-
|
|
22065
|
-
|
|
22839
|
+
previousBlockId: join.previousBlockId,
|
|
22840
|
+
nextBlockId: join.nextBlockId,
|
|
22841
|
+
treatment: join.treatment
|
|
22066
22842
|
};
|
|
22067
22843
|
}
|
|
22068
|
-
|
|
22069
|
-
|
|
22070
|
-
|
|
22844
|
+
/**
|
|
22845
|
+
* The single rule set for which treatment a join gets. Candidates arrive in
|
|
22846
|
+
* priority order; the first supported one wins.
|
|
22847
|
+
*
|
|
22848
|
+
* - `none` ends the search and yields no join.
|
|
22849
|
+
* - An unsupported candidate (a legacy option id, or a structured treatment the
|
|
22850
|
+
* catalogue lacks) falls through to the next one. When it was the user's
|
|
22851
|
+
* pin, the pin is reported unsupported and the existing
|
|
22852
|
+
* `pinned-boundary-option-unavailable` issue is raised.
|
|
22853
|
+
*/
|
|
22854
|
+
function resolveJoinTreatment(input) {
|
|
22855
|
+
const boundaryId = makeBoundaryId(input.previousBlockId, input.nextBlockId);
|
|
22856
|
+
const selection = selectCandidate(input.candidates);
|
|
22857
|
+
const selectedOutcome = selection.kind === "selected" ? selection.outcome : { kind: "none" };
|
|
22858
|
+
const pin = pinStatus(input.candidates, selectedOutcome);
|
|
22859
|
+
const issues = pin.kind === "unsupported" ? [{
|
|
22860
|
+
kind: "pinned-boundary-option-unavailable",
|
|
22861
|
+
boundaryId,
|
|
22862
|
+
presetId: pin.optionId,
|
|
22863
|
+
feedback: "user-facing"
|
|
22864
|
+
}] : [];
|
|
22865
|
+
if (selection.kind === "exhausted") {
|
|
22071
22866
|
return {
|
|
22072
|
-
|
|
22073
|
-
|
|
22074
|
-
|
|
22075
|
-
|
|
22867
|
+
join: null,
|
|
22868
|
+
selectedSource: null,
|
|
22869
|
+
pin,
|
|
22870
|
+
issues
|
|
22076
22871
|
};
|
|
22077
22872
|
}
|
|
22078
|
-
if (
|
|
22873
|
+
if (selection.outcome.kind === "none") {
|
|
22079
22874
|
return {
|
|
22080
|
-
|
|
22081
|
-
|
|
22082
|
-
|
|
22083
|
-
|
|
22875
|
+
join: null,
|
|
22876
|
+
selectedSource: selection.candidate.source,
|
|
22877
|
+
pin,
|
|
22878
|
+
issues
|
|
22084
22879
|
};
|
|
22085
22880
|
}
|
|
22086
|
-
|
|
22087
|
-
|
|
22088
|
-
|
|
22089
|
-
|
|
22090
|
-
|
|
22091
|
-
|
|
22092
|
-
|
|
22881
|
+
return {
|
|
22882
|
+
selectedSource: selection.candidate.source,
|
|
22883
|
+
join: {
|
|
22884
|
+
boundaryId,
|
|
22885
|
+
previousBlockId: input.previousBlockId,
|
|
22886
|
+
nextBlockId: input.nextBlockId,
|
|
22887
|
+
treatment: selection.outcome.treatment,
|
|
22888
|
+
source: selection.candidate.source
|
|
22889
|
+
},
|
|
22890
|
+
pin,
|
|
22891
|
+
issues
|
|
22892
|
+
};
|
|
22893
|
+
}
|
|
22894
|
+
function pinStatus(candidates, selectedOutcome) {
|
|
22895
|
+
const pinned = candidates.find((candidate$1) => candidate$1.source.kind === "user-pinned");
|
|
22896
|
+
if (!pinned) return { kind: "none" };
|
|
22897
|
+
const outcome = candidateOutcome(pinned.treatment);
|
|
22898
|
+
return outcome.kind === "unsupported" ? {
|
|
22899
|
+
kind: "unsupported",
|
|
22900
|
+
optionId: outcome.boundaryOptionId ?? fallbackOptionId(selectedOutcome)
|
|
22901
|
+
} : { kind: "supported" };
|
|
22902
|
+
}
|
|
22903
|
+
function selectCandidate(candidates) {
|
|
22904
|
+
for (const candidate$1 of candidates) {
|
|
22905
|
+
const outcome = candidateOutcome(candidate$1.treatment);
|
|
22906
|
+
switch (outcome.kind) {
|
|
22907
|
+
case "decorative":
|
|
22908
|
+
case "none": return {
|
|
22909
|
+
kind: "selected",
|
|
22910
|
+
candidate: candidate$1,
|
|
22911
|
+
outcome
|
|
22912
|
+
};
|
|
22913
|
+
case "unsupported": continue;
|
|
22914
|
+
default: return assertNever$1(outcome, "Unhandled join candidate outcome");
|
|
22915
|
+
}
|
|
22093
22916
|
}
|
|
22094
|
-
|
|
22095
|
-
|
|
22096
|
-
|
|
22097
|
-
|
|
22098
|
-
|
|
22099
|
-
|
|
22100
|
-
|
|
22917
|
+
return { kind: "exhausted" };
|
|
22918
|
+
}
|
|
22919
|
+
function candidateOutcome(treatment) {
|
|
22920
|
+
if (treatment.kind === "none") return { kind: "none" };
|
|
22921
|
+
const intent = transitionIntentForTreatment(treatment);
|
|
22922
|
+
return intent ? {
|
|
22923
|
+
kind: "decorative",
|
|
22924
|
+
treatment: intent
|
|
22925
|
+
} : {
|
|
22926
|
+
kind: "unsupported",
|
|
22927
|
+
boundaryOptionId: boundaryOptionIdForTreatment(treatment)
|
|
22928
|
+
};
|
|
22929
|
+
}
|
|
22930
|
+
/**
|
|
22931
|
+
* Matches the editor's existing issue payload: the pin's own option id when
|
|
22932
|
+
* it has one, otherwise the option the join fell back to.
|
|
22933
|
+
*/
|
|
22934
|
+
function fallbackOptionId(outcome) {
|
|
22935
|
+
switch (outcome.kind) {
|
|
22936
|
+
case "decorative": return boundaryOptionForTransitionIntent(outcome.treatment).id;
|
|
22937
|
+
case "none": return noneBoundaryOption.id;
|
|
22938
|
+
default: return assertNever$1(outcome, "Unhandled join fallback outcome");
|
|
22101
22939
|
}
|
|
22940
|
+
}
|
|
22941
|
+
/**
|
|
22942
|
+
* The page-design defaults for a join, in priority order: the site style's
|
|
22943
|
+
* default break after the previous block, then the page-flow default, which
|
|
22944
|
+
* is always last.
|
|
22945
|
+
*/
|
|
22946
|
+
function pageDesignDefaultJoinCandidates(input) {
|
|
22947
|
+
const policy = deriveSiteStyleBlockPolicy({
|
|
22948
|
+
siteStyleId: input.siteStyleId,
|
|
22949
|
+
blockKind: input.previousBlockKind
|
|
22950
|
+
});
|
|
22951
|
+
const siteStyleDefault = policy.kind === "locked-look-and-layouts" && policy.defaultBoundaryAfter ? [{
|
|
22952
|
+
source: {
|
|
22953
|
+
kind: "site-style-default",
|
|
22954
|
+
siteStyleId: input.siteStyleId
|
|
22955
|
+
},
|
|
22956
|
+
treatment: boundaryTreatmentForBoundaryOptionId(policy.defaultBoundaryAfter.optionId)
|
|
22957
|
+
}] : [];
|
|
22958
|
+
return [...siteStyleDefault, pageFlowDefaultJoinCandidate(input.pageFlowPresetId)];
|
|
22959
|
+
}
|
|
22960
|
+
/** The last-resort page-design default, also the source of a fully unsupported join. */
|
|
22961
|
+
function pageFlowDefaultJoinCandidate(pageFlowPresetId) {
|
|
22962
|
+
const pageFlow = pageFlowDefaultBoundary(pageFlowPresetId);
|
|
22102
22963
|
return {
|
|
22103
|
-
|
|
22104
|
-
|
|
22105
|
-
|
|
22106
|
-
|
|
22964
|
+
source: {
|
|
22965
|
+
kind: "page-flow-default",
|
|
22966
|
+
pageFlowPresetId: pageFlow.preset?.id ?? null
|
|
22967
|
+
},
|
|
22968
|
+
treatment: boundaryTreatmentForBoundaryOptionId(pageFlow.boundaryOptionId)
|
|
22107
22969
|
};
|
|
22108
22970
|
}
|
|
22971
|
+
/**
|
|
22972
|
+
* Page-design source adapter. Priority: the user's pin, then the defaults.
|
|
22973
|
+
* The pin is offered even when unsupported so the rule function can report it.
|
|
22974
|
+
*/
|
|
22975
|
+
function joinCandidatesFromPageDesign(intent, siteStyleId, previous, next) {
|
|
22976
|
+
const choice = resolvePageDesignBoundaryChoice(intent, previous.blockId, next.blockId);
|
|
22977
|
+
return [...choice.kind === "user-pinned" ? [{
|
|
22978
|
+
source: { kind: "user-pinned" },
|
|
22979
|
+
treatment: choice.value
|
|
22980
|
+
}] : [], ...pageDesignDefaultJoinCandidates({
|
|
22981
|
+
siteStyleId,
|
|
22982
|
+
pageFlowPresetId: intent.pageFlowPresetId,
|
|
22983
|
+
previousBlockKind: previous.blockKind
|
|
22984
|
+
})];
|
|
22985
|
+
}
|
|
22986
|
+
/**
|
|
22987
|
+
* Generated-design source adapter. Mirrors today's materialisation: the
|
|
22988
|
+
* boundary intent's explicit choice, then the block design's explicit choice,
|
|
22989
|
+
* then the automatic default of no break.
|
|
22990
|
+
*/
|
|
22991
|
+
function joinCandidatesFromGeneratedIntent(block) {
|
|
22992
|
+
return [
|
|
22993
|
+
...explicitGeneratedCandidate(block.boundaryIntent.transitionAfter, "boundary-intent"),
|
|
22994
|
+
...explicitGeneratedCandidate(block.design.transitionAfter, "block-design"),
|
|
22995
|
+
{
|
|
22996
|
+
source: {
|
|
22997
|
+
kind: "generated",
|
|
22998
|
+
origin: "automatic"
|
|
22999
|
+
},
|
|
23000
|
+
treatment: { kind: "none" }
|
|
23001
|
+
}
|
|
23002
|
+
];
|
|
23003
|
+
}
|
|
23004
|
+
function explicitGeneratedCandidate(choice, origin) {
|
|
23005
|
+
return choice.kind === "explicit" ? [{
|
|
23006
|
+
source: {
|
|
23007
|
+
kind: "generated",
|
|
23008
|
+
origin
|
|
23009
|
+
},
|
|
23010
|
+
treatment: treatmentForTransitionIntent(choice.value)
|
|
23011
|
+
}] : [];
|
|
23012
|
+
}
|
|
23013
|
+
function treatmentForTransitionIntent(transition) {
|
|
23014
|
+
return transition === "none" ? { kind: "none" } : transitionCatalogueEntryForIntent(transition).treatment;
|
|
23015
|
+
}
|
|
22109
23016
|
|
|
22110
23017
|
//#endregion
|
|
22111
23018
|
//#region ../theme-core/src/site-styles/imageSurfaceBackground.ts
|
|
@@ -22219,13 +23126,15 @@ const compiledRuntimeStyleFieldNames = [
|
|
|
22219
23126
|
"_contentCardStyles",
|
|
22220
23127
|
"_heroLayoutStyles",
|
|
22221
23128
|
"_cardStyles",
|
|
22222
|
-
"_transitionStyles",
|
|
22223
23129
|
"blockLook",
|
|
22224
|
-
"blockComposition"
|
|
22225
|
-
"styleGroup"
|
|
23130
|
+
"blockComposition"
|
|
22226
23131
|
];
|
|
23132
|
+
/**
|
|
23133
|
+
* Removes every compiler-owned field, plus a stale transition `styleGroup`.
|
|
23134
|
+
* An authored `styleGroup` is content and survives.
|
|
23135
|
+
*/
|
|
22227
23136
|
function stripCompiledRuntimeStyleFields(content) {
|
|
22228
|
-
return Object.fromEntries(Object.entries(content).filter(([fieldName]) => !compiledRuntimeStyleFieldNames.includes(fieldName)));
|
|
23137
|
+
return Object.fromEntries(Object.entries(stripStaleTransitionStyleGroup(content)).filter(([fieldName]) => !compiledRuntimeStyleFieldNames.includes(fieldName)));
|
|
22229
23138
|
}
|
|
22230
23139
|
function surfaceResolutionContextFromPalette(palette) {
|
|
22231
23140
|
return {
|
|
@@ -22244,7 +23153,7 @@ function defineComponentRuntimeRules(rules) {
|
|
|
22244
23153
|
}
|
|
22245
23154
|
/**
|
|
22246
23155
|
* Default design rules translate semantic page-level choices into the current
|
|
22247
|
-
* runtime's section background
|
|
23156
|
+
* runtime's section background vocabulary.
|
|
22248
23157
|
*/
|
|
22249
23158
|
const defaultDesignRuntimeRules = defineDesignRuntimeRules({
|
|
22250
23159
|
sectionSurfaces: {
|
|
@@ -22279,8 +23188,7 @@ const defaultDesignRuntimeRules = defineDesignRuntimeRules({
|
|
|
22279
23188
|
color: "surface",
|
|
22280
23189
|
opacity: .88
|
|
22281
23190
|
}
|
|
22282
|
-
}
|
|
22283
|
-
transitionClassName: (transition, fromSurface, toSurface) => transition === "none" ? null : `site-style-transition-${transition}-from-${fromSurface}-to-${toSurface}`
|
|
23191
|
+
}
|
|
22284
23192
|
});
|
|
22285
23193
|
/**
|
|
22286
23194
|
* Default component rules translate frame and item-surface semantics into the
|
|
@@ -22506,26 +23414,6 @@ function compileCardStyles(input) {
|
|
|
22506
23414
|
if (!role) return undefined;
|
|
22507
23415
|
return cardStylesOverrideSchema.parse({ role });
|
|
22508
23416
|
}
|
|
22509
|
-
function sectionAdjacencyForBlock(input) {
|
|
22510
|
-
if (input.sectionAdjacency) {
|
|
22511
|
-
return input.sectionAdjacency;
|
|
22512
|
-
}
|
|
22513
|
-
if (input.nextSectionSurface) {
|
|
22514
|
-
return {
|
|
22515
|
-
kind: "next-section",
|
|
22516
|
-
surface: input.nextSectionSurface
|
|
22517
|
-
};
|
|
22518
|
-
}
|
|
22519
|
-
return { kind: "page-end" };
|
|
22520
|
-
}
|
|
22521
|
-
function transitionTargetSurfaceForAdjacency(adjacency) {
|
|
22522
|
-
switch (adjacency.kind) {
|
|
22523
|
-
case "next-section":
|
|
22524
|
-
case "terminal-surface": return adjacency.surface;
|
|
22525
|
-
case "page-end": return null;
|
|
22526
|
-
default: return assertNever$1(adjacency);
|
|
22527
|
-
}
|
|
22528
|
-
}
|
|
22529
23417
|
function resolveEyebrowTreatmentForRuntime(block, rules) {
|
|
22530
23418
|
return block.eyebrowTreatment ?? rules.defaultEyebrowTreatment ?? block.appliedEyebrowTreatment;
|
|
22531
23419
|
}
|
|
@@ -22543,19 +23431,6 @@ function compileBlockRuntimeFields(input) {
|
|
|
22543
23431
|
});
|
|
22544
23432
|
const shouldSuppressContainerFrame = shouldMoveFrameToHeroContentCard(input.block);
|
|
22545
23433
|
const cardStyles = compileCardStyles({ cardRole: input.block.appliedCardRole });
|
|
22546
|
-
const transitionTargetSurface = transitionTargetSurfaceForAdjacency(sectionAdjacencyForBlock(input));
|
|
22547
|
-
const transitionClassName = transitionTargetSurface ? designRules.transitionClassName(input.block.appliedTransitionAfter, visualSectionSurface, transitionTargetSurface) : null;
|
|
22548
|
-
const transitionRuntime = transitionTargetSurface && transitionClassName ? compileTransitionRuntime({
|
|
22549
|
-
treatment: input.block.appliedTransitionAfter,
|
|
22550
|
-
from: {
|
|
22551
|
-
kind: "surface",
|
|
22552
|
-
surface: visualSectionSurface
|
|
22553
|
-
},
|
|
22554
|
-
to: {
|
|
22555
|
-
kind: "surface",
|
|
22556
|
-
surface: transitionTargetSurface
|
|
22557
|
-
}
|
|
22558
|
-
}) : null;
|
|
22559
23434
|
return {
|
|
22560
23435
|
blockId: input.block.blockId,
|
|
22561
23436
|
visualSectionSurface,
|
|
@@ -22580,72 +23455,10 @@ function compileBlockRuntimeFields(input) {
|
|
|
22580
23455
|
...cardStyles ? { _cardStyles: cardStyles } : {},
|
|
22581
23456
|
...heroRuntimeFields,
|
|
22582
23457
|
...input.block.appearancePresetId ? { blockLook: input.block.appearancePresetId } : {},
|
|
22583
|
-
...input.block.appliedComposition ? { blockComposition: input.block.appliedComposition } : {}
|
|
22584
|
-
...transitionRuntime ? { _transitionStyles: transitionRuntime } : {},
|
|
22585
|
-
...transitionClassName ? { styleGroup: transitionClassName } : {}
|
|
22586
|
-
}
|
|
22587
|
-
};
|
|
22588
|
-
}
|
|
22589
|
-
function compileTransitionRuntime(input) {
|
|
22590
|
-
return {
|
|
22591
|
-
treatment: input.treatment,
|
|
22592
|
-
from: input.from,
|
|
22593
|
-
to: input.to,
|
|
22594
|
-
cssVars: {
|
|
22595
|
-
from: input.from.kind === "surface" && input.from.surface === "hero-image" ? "transparent" : transitionEndpointCssValue(input.from),
|
|
22596
|
-
to: transitionEndpointCssValue(input.to)
|
|
22597
|
-
}
|
|
22598
|
-
};
|
|
22599
|
-
}
|
|
22600
|
-
function compileBoundaryRuntime(input) {
|
|
22601
|
-
const rules = input.rules ?? defaultDesignRuntimeRules;
|
|
22602
|
-
const styleGroup = rules.transitionClassName(input.treatment, input.fromSurface, input.toSurface);
|
|
22603
|
-
if (!styleGroup) return null;
|
|
22604
|
-
const metrics = boundaryRuntimeMetricsForTransition(input.treatment);
|
|
22605
|
-
if (!metrics) return null;
|
|
22606
|
-
const transition = compileTransitionRuntime({
|
|
22607
|
-
treatment: input.treatment,
|
|
22608
|
-
from: {
|
|
22609
|
-
kind: "surface",
|
|
22610
|
-
surface: input.fromSurface
|
|
22611
|
-
},
|
|
22612
|
-
to: {
|
|
22613
|
-
kind: "surface",
|
|
22614
|
-
surface: input.toSurface
|
|
23458
|
+
...input.block.appliedComposition ? { blockComposition: input.block.appliedComposition } : {}
|
|
22615
23459
|
}
|
|
22616
|
-
});
|
|
22617
|
-
return {
|
|
22618
|
-
boundaryId: input.boundaryId,
|
|
22619
|
-
previousBlockId: input.previousBlockId,
|
|
22620
|
-
nextBlockId: input.nextBlockId,
|
|
22621
|
-
treatment: transition.treatment,
|
|
22622
|
-
metrics,
|
|
22623
|
-
from: transition.from,
|
|
22624
|
-
to: transition.to,
|
|
22625
|
-
cssVars: transition.cssVars,
|
|
22626
|
-
styleGroup
|
|
22627
23460
|
};
|
|
22628
23461
|
}
|
|
22629
|
-
function transitionEndpointCssValue(endpoint) {
|
|
22630
|
-
switch (endpoint.kind) {
|
|
22631
|
-
case "color-token": return themeColorTokenCssValue(endpoint.token);
|
|
22632
|
-
case "surface": return themeColorTokenCssValue(tokenForTransitionSurface(endpoint.surface));
|
|
22633
|
-
default: return assertNever$1(endpoint);
|
|
22634
|
-
}
|
|
22635
|
-
}
|
|
22636
|
-
function tokenForTransitionSurface(surface$1) {
|
|
22637
|
-
switch (surface$1) {
|
|
22638
|
-
case "base":
|
|
22639
|
-
case "hero-image": return "background";
|
|
22640
|
-
case "muted-band": return "muted";
|
|
22641
|
-
case "accent-band": return "accent";
|
|
22642
|
-
case "brand-depth-band": return "primary-800";
|
|
22643
|
-
default: return assertNever$1(surface$1);
|
|
22644
|
-
}
|
|
22645
|
-
}
|
|
22646
|
-
function themeColorTokenCssValue(token) {
|
|
22647
|
-
return `rgb(var(--tb-${token}))`;
|
|
22648
|
-
}
|
|
22649
23462
|
/**
|
|
22650
23463
|
* Compiles block runtime fields and writes them into content only when Theme V2
|
|
22651
23464
|
* owns that block's runtime-style fields.
|
|
@@ -22658,58 +23471,30 @@ function compileBlockRuntimeFieldsIntoContent(input) {
|
|
|
22658
23471
|
authority: input.authority
|
|
22659
23472
|
});
|
|
22660
23473
|
}
|
|
22661
|
-
/**
|
|
23474
|
+
/**
|
|
23475
|
+
* Compiles a resolved page plan into legacy runtime fields for each resolved
|
|
23476
|
+
* block, plus the public runtime joins between them.
|
|
23477
|
+
*
|
|
23478
|
+
* Joins come from `resolveJoinTreatment`; plans no longer carry a treatment.
|
|
23479
|
+
* Only joins whose two blocks were compiled are kept, and they leave as intent
|
|
23480
|
+
* only: the blocks renderer composes each one from final content after
|
|
23481
|
+
* omission, including whether it draws at all (issue 1422).
|
|
23482
|
+
*/
|
|
22662
23483
|
function compilePageRuntimeFields(input) {
|
|
22663
|
-
const
|
|
22664
|
-
|
|
22665
|
-
|
|
22666
|
-
|
|
22667
|
-
|
|
22668
|
-
|
|
22669
|
-
|
|
22670
|
-
|
|
22671
|
-
|
|
22672
|
-
componentRules: input.componentRules,
|
|
22673
|
-
sectionSpacing: input.sectionSpacing,
|
|
22674
|
-
sectionAdjacency: nextSurface ? {
|
|
22675
|
-
kind: "next-section",
|
|
22676
|
-
surface: nextSurface
|
|
22677
|
-
} : terminalSectionAdjacency
|
|
22678
|
-
});
|
|
22679
|
-
return {
|
|
22680
|
-
...compiled,
|
|
22681
|
-
fields: stripPageLevelTransitionFields(compiled.fields)
|
|
22682
|
-
};
|
|
22683
|
-
});
|
|
22684
|
-
const boundaries = input.resolved.blocks.flatMap((block, index) => {
|
|
22685
|
-
const nextBlock = input.resolved.blocks[index + 1];
|
|
22686
|
-
const fromSurface = visualSurfaces[index];
|
|
22687
|
-
const toSurface = visualSurfaces[index + 1];
|
|
22688
|
-
if (!nextBlock || !fromSurface || !toSurface) {
|
|
22689
|
-
return [];
|
|
22690
|
-
}
|
|
22691
|
-
const boundary = compileBoundaryRuntime({
|
|
22692
|
-
boundaryId: `boundary:${block.blockId}:${nextBlock.blockId}`,
|
|
22693
|
-
previousBlockId: block.blockId,
|
|
22694
|
-
nextBlockId: nextBlock.blockId,
|
|
22695
|
-
treatment: block.appliedTransitionAfter,
|
|
22696
|
-
fromSurface,
|
|
22697
|
-
toSurface,
|
|
22698
|
-
rules: designRules
|
|
22699
|
-
});
|
|
22700
|
-
return boundary ? [boundary] : [];
|
|
22701
|
-
});
|
|
23484
|
+
const blocks = input.resolved.blocks.map((block) => compileBlockRuntimeFields({
|
|
23485
|
+
block,
|
|
23486
|
+
surfaceResolutionContext: input.surfaceResolutionContext,
|
|
23487
|
+
designRules: input.designRules,
|
|
23488
|
+
componentRules: input.componentRules,
|
|
23489
|
+
sectionSpacing: input.sectionSpacing
|
|
23490
|
+
}));
|
|
23491
|
+
const compiledIds = new Set(blocks.map((block) => block.blockId));
|
|
23492
|
+
const joins = input.joins.filter((join) => compiledIds.has(join.previousBlockId) && compiledIds.has(join.nextBlockId)).map(toPageRuntimeJoin);
|
|
22702
23493
|
return {
|
|
22703
23494
|
blocks,
|
|
22704
|
-
|
|
23495
|
+
joins
|
|
22705
23496
|
};
|
|
22706
23497
|
}
|
|
22707
|
-
function stripPageLevelTransitionFields(fields) {
|
|
22708
|
-
const { _transitionStyles, styleGroup, ...rest } = fields;
|
|
22709
|
-
void _transitionStyles;
|
|
22710
|
-
void styleGroup;
|
|
22711
|
-
return rest;
|
|
22712
|
-
}
|
|
22713
23498
|
const paletteByRecipe = {
|
|
22714
23499
|
"brand-led": [
|
|
22715
23500
|
{
|
|
@@ -24769,372 +25554,174 @@ const curatedSiteStylesById = new Map(curatedSiteStyles.map((style) => [style.id
|
|
|
24769
25554
|
* only to the compiler.
|
|
24770
25555
|
*/
|
|
24771
25556
|
function headerStyleRecipeForTheme(theme, styleId) {
|
|
24772
|
-
const siteStyle = theme?.siteStyleId ? getCuratedSiteStyle(theme.siteStyleId) : null;
|
|
24773
|
-
return resolveHeaderStyleRecipe(siteStyle, styleId);
|
|
24774
|
-
}
|
|
24775
|
-
function getCuratedSiteStyle(id) {
|
|
24776
|
-
return curatedSiteStylesById.get(id) ?? null;
|
|
24777
|
-
}
|
|
24778
|
-
function designRuntimeRulesForSiteStyle(siteStyle) {
|
|
24779
|
-
return siteStyle?.designRuntimeRules ?? defaultDesignRuntimeRules;
|
|
24780
|
-
}
|
|
24781
|
-
function designRuntimeRulesForTheme(theme) {
|
|
24782
|
-
const siteStyleId = theme?.siteStyleId;
|
|
24783
|
-
if (!siteStyleId) return defaultDesignRuntimeRules;
|
|
24784
|
-
return designRuntimeRulesForSiteStyle(curatedSiteStylesById.get(asSiteStyleId(siteStyleId)) ?? null);
|
|
24785
|
-
}
|
|
24786
|
-
function componentRuntimeRulesForSiteStyle(siteStyle) {
|
|
24787
|
-
return siteStyle?.componentRuntimeRules ?? defaultComponentRuntimeRules;
|
|
24788
|
-
}
|
|
24789
|
-
function componentRuntimeRulesForTheme(theme) {
|
|
24790
|
-
const siteStyleId = theme?.siteStyleId;
|
|
24791
|
-
if (!siteStyleId) return defaultComponentRuntimeRules;
|
|
24792
|
-
return componentRuntimeRulesForSiteStyle(curatedSiteStylesById.get(asSiteStyleId(siteStyleId)) ?? null);
|
|
24793
|
-
}
|
|
24794
|
-
function defaultBlockVariantForSiteStyle(siteStyle, blockKind) {
|
|
24795
|
-
return siteStyle.defaultBlockVariants?.[blockKind] ?? null;
|
|
24796
|
-
}
|
|
24797
|
-
|
|
24798
|
-
//#endregion
|
|
24799
|
-
//#region ../theme-core/src/site-styles/pageDesignEditorCapabilities.ts
|
|
24800
|
-
function cardRoleCapabilityOf(capability) {
|
|
24801
|
-
return capability?.kind === "designed" ? capability.cardRoles : "unsupported";
|
|
24802
|
-
}
|
|
24803
|
-
function backgroundSupportForCapability(capability) {
|
|
24804
|
-
if (capability === null) {
|
|
24805
|
-
return {
|
|
24806
|
-
kind: "unsupported",
|
|
24807
|
-
reason: "missing-design-capability"
|
|
24808
|
-
};
|
|
24809
|
-
}
|
|
24810
|
-
if (capability.kind === "not-designed") {
|
|
24811
|
-
return {
|
|
24812
|
-
kind: "unsupported",
|
|
24813
|
-
reason: capability.reason
|
|
24814
|
-
};
|
|
24815
|
-
}
|
|
24816
|
-
return capability.sectionSurfaces === "supported" ? {
|
|
24817
|
-
kind: "supported",
|
|
24818
|
-
richBackgrounds: capability.richBackgrounds ?? "unsupported"
|
|
24819
|
-
} : {
|
|
24820
|
-
kind: "unsupported",
|
|
24821
|
-
reason: "section-surfaces-unsupported"
|
|
24822
|
-
};
|
|
24823
|
-
}
|
|
24824
|
-
/**
|
|
24825
|
-
* The capability-derived half of a block's editor read model, in one call so
|
|
24826
|
-
* the read-model builder does not grow a projection per axis.
|
|
24827
|
-
*/
|
|
24828
|
-
function capabilitySupportFor(capability) {
|
|
24829
|
-
return {
|
|
24830
|
-
backgroundSupport: backgroundSupportForCapability(capability),
|
|
24831
|
-
cardRoles: cardRoleCapabilityOf(capability)
|
|
24832
|
-
};
|
|
24833
|
-
}
|
|
24834
|
-
|
|
24835
|
-
//#endregion
|
|
24836
|
-
//#region ../theme-core/src/site-styles/lookResolution.ts
|
|
24837
|
-
function blockAppearancePresetSupportsBlockKind(preset, blockKind) {
|
|
24838
|
-
return preset.blockKinds.some((candidate$1) => candidate$1 === blockKind);
|
|
24839
|
-
}
|
|
24840
|
-
function preferredAppearanceTargetForBlockKind(blockKind) {
|
|
24841
|
-
switch (blockKind) {
|
|
24842
|
-
case "block.event-calendar":
|
|
24843
|
-
case "block.event-listing": return "events";
|
|
24844
|
-
default: return null;
|
|
24845
|
-
}
|
|
24846
|
-
}
|
|
24847
|
-
function sortCompatibleBlockAppearancePresets(blockKind, options) {
|
|
24848
|
-
const preferredTarget = preferredAppearanceTargetForBlockKind(blockKind);
|
|
24849
|
-
if (!preferredTarget) {
|
|
24850
|
-
return options;
|
|
24851
|
-
}
|
|
24852
|
-
return [...options].sort((left, right) => {
|
|
24853
|
-
const leftPreset = appearancePresets.find((preset) => preset.id === left.id);
|
|
24854
|
-
const rightPreset = appearancePresets.find((preset) => preset.id === right.id);
|
|
24855
|
-
const leftPreferred = leftPreset?.target === preferredTarget;
|
|
24856
|
-
const rightPreferred = rightPreset?.target === preferredTarget;
|
|
24857
|
-
if (leftPreferred === rightPreferred) {
|
|
24858
|
-
return 0;
|
|
24859
|
-
}
|
|
24860
|
-
return leftPreferred ? -1 : 1;
|
|
24861
|
-
});
|
|
24862
|
-
}
|
|
24863
|
-
function blockAppearancePresetSupportsLayoutProfile(preset, profile, input = {}) {
|
|
24864
|
-
const constraints = preset.constraints;
|
|
24865
|
-
if (!constraints || !constraints.layoutFamilies && !constraints.layoutVariantKeys) {
|
|
24866
|
-
return true;
|
|
24867
|
-
}
|
|
24868
|
-
if (!profile) {
|
|
24869
|
-
return input.allowLayoutConstrainedPresetWithoutProfile ?? true;
|
|
24870
|
-
}
|
|
24871
|
-
return layoutProfileSupportsConstraints(profile, constraints);
|
|
24872
|
-
}
|
|
24873
|
-
function resolveBlockAppearancePreset(preset, layoutProfile = null) {
|
|
24874
|
-
return {
|
|
24875
|
-
id: asAppearancePresetId(preset.id),
|
|
24876
|
-
label: preset.label,
|
|
24877
|
-
design: resolveBlockAppearancePresetDesign(preset, layoutProfile)
|
|
24878
|
-
};
|
|
24879
|
-
}
|
|
24880
|
-
function getCompatibleBlockAppearancePresets(input) {
|
|
24881
|
-
const options = appearancePresets.flatMap((preset) => {
|
|
24882
|
-
if (!blockAppearancePresetSupportsBlockKind(preset, input.blockKind) || !blockAppearancePresetSupportsLayoutProfile(preset, input.layoutProfile ?? null, { allowLayoutConstrainedPresetWithoutProfile: input.allowLayoutConstrainedPresetWithoutProfile })) {
|
|
24883
|
-
return [];
|
|
24884
|
-
}
|
|
24885
|
-
return [resolveBlockAppearancePreset(preset, input.layoutProfile ?? null)];
|
|
24886
|
-
});
|
|
24887
|
-
const sortedOptions = sortCompatibleBlockAppearancePresets(input.blockKind, options);
|
|
24888
|
-
const recommendedIds = input.siteStyle?.recommendedAppearancePresetIds ?? [];
|
|
24889
|
-
if (recommendedIds.length === 0) {
|
|
24890
|
-
return sortedOptions;
|
|
24891
|
-
}
|
|
24892
|
-
const recommended = recommendedIds.flatMap((presetId) => sortedOptions.find((option) => option.id === presetId) ?? []);
|
|
24893
|
-
const alreadyIncludedIds = new Set(recommended.map((option) => option.id));
|
|
24894
|
-
return [...recommended, ...sortedOptions.filter((option) => !alreadyIncludedIds.has(option.id))];
|
|
25557
|
+
const siteStyle = theme?.siteStyleId ? getCuratedSiteStyle(theme.siteStyleId) : null;
|
|
25558
|
+
return resolveHeaderStyleRecipe(siteStyle, styleId);
|
|
24895
25559
|
}
|
|
24896
|
-
|
|
24897
|
-
|
|
24898
|
-
//#region ../theme-core/src/site-styles/siteStyleBlockPolicies.ts
|
|
24899
|
-
const defaultPolicyPageFlowPresetId = asPageFlowPresetId("generated-default");
|
|
24900
|
-
const southWestTwerkSchoolSiteStyleId = asSiteStyleId("site-style:south-west-twerk-school");
|
|
24901
|
-
const heroBrandScrimFixedFrameLookId = asAppearancePresetId("hero-brand-scrim-fixed-frame");
|
|
24902
|
-
const classicHeroLayoutVariantKey = asLayoutVariantKey("classic");
|
|
24903
|
-
const microHeroLayoutVariantKey = asLayoutVariantKey("micro");
|
|
24904
|
-
const waveBoundaryOptionId = asBoundaryOptionId("break:wave");
|
|
24905
|
-
const registeredSiteStyleBlockPolicies = [{
|
|
24906
|
-
siteStyleId: southWestTwerkSchoolSiteStyleId,
|
|
24907
|
-
kind: "locked-look-and-layouts",
|
|
24908
|
-
blockKind: "block.hero",
|
|
24909
|
-
lookId: heroBrandScrimFixedFrameLookId,
|
|
24910
|
-
allowedLayoutVariantKeys: [classicHeroLayoutVariantKey, microHeroLayoutVariantKey],
|
|
24911
|
-
defaultLayoutVariantKey: classicHeroLayoutVariantKey,
|
|
24912
|
-
defaultBoundaryAfter: {
|
|
24913
|
-
optionId: waveBoundaryOptionId,
|
|
24914
|
-
mode: "default-only"
|
|
24915
|
-
},
|
|
24916
|
-
customize: {
|
|
24917
|
-
hideDisallowedLooks: true,
|
|
24918
|
-
hideDisallowedLayouts: true
|
|
24919
|
-
}
|
|
24920
|
-
}];
|
|
24921
|
-
function siteStyleBlockPolicies() {
|
|
24922
|
-
return registeredSiteStyleBlockPolicies;
|
|
25560
|
+
function getCuratedSiteStyle(id) {
|
|
25561
|
+
return curatedSiteStylesById.get(id) ?? null;
|
|
24923
25562
|
}
|
|
24924
|
-
function
|
|
24925
|
-
return
|
|
24926
|
-
schemaVersion: pageDesignIntentSchemaVersion,
|
|
24927
|
-
siteStyleId,
|
|
24928
|
-
pageFlowPresetId: defaultPolicyPageFlowPresetId,
|
|
24929
|
-
blockLookPins: [],
|
|
24930
|
-
boundaryPins: []
|
|
24931
|
-
};
|
|
25563
|
+
function designRuntimeRulesForSiteStyle(siteStyle) {
|
|
25564
|
+
return siteStyle?.designRuntimeRules ?? defaultDesignRuntimeRules;
|
|
24932
25565
|
}
|
|
24933
|
-
function
|
|
24934
|
-
|
|
24935
|
-
|
|
24936
|
-
|
|
24937
|
-
}).kind !== "open");
|
|
25566
|
+
function designRuntimeRulesForTheme(theme) {
|
|
25567
|
+
const siteStyleId = theme?.siteStyleId;
|
|
25568
|
+
if (!siteStyleId) return defaultDesignRuntimeRules;
|
|
25569
|
+
return designRuntimeRulesForSiteStyle(curatedSiteStylesById.get(asSiteStyleId(siteStyleId)) ?? null);
|
|
24938
25570
|
}
|
|
24939
|
-
function
|
|
24940
|
-
return
|
|
25571
|
+
function componentRuntimeRulesForSiteStyle(siteStyle) {
|
|
25572
|
+
return siteStyle?.componentRuntimeRules ?? defaultComponentRuntimeRules;
|
|
24941
25573
|
}
|
|
24942
|
-
function
|
|
24943
|
-
|
|
24944
|
-
|
|
24945
|
-
|
|
24946
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
24947
|
-
}
|
|
25574
|
+
function componentRuntimeRulesForTheme(theme) {
|
|
25575
|
+
const siteStyleId = theme?.siteStyleId;
|
|
25576
|
+
if (!siteStyleId) return defaultComponentRuntimeRules;
|
|
25577
|
+
return componentRuntimeRulesForSiteStyle(curatedSiteStylesById.get(asSiteStyleId(siteStyleId)) ?? null);
|
|
24948
25578
|
}
|
|
24949
|
-
function
|
|
24950
|
-
|
|
24951
|
-
case "open": return layoutVariantKey ?? null;
|
|
24952
|
-
case "locked-look-and-layouts": return layoutVariantKey && isLayoutVariantAllowedByPolicy(policy, layoutVariantKey) ? layoutVariantKey : policy.defaultLayoutVariantKey;
|
|
24953
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
24954
|
-
}
|
|
25579
|
+
function defaultBlockVariantForSiteStyle(siteStyle, blockKind) {
|
|
25580
|
+
return siteStyle.defaultBlockVariants?.[blockKind] ?? null;
|
|
24955
25581
|
}
|
|
24956
|
-
|
|
24957
|
-
|
|
24958
|
-
|
|
24959
|
-
|
|
24960
|
-
|
|
24961
|
-
}
|
|
25582
|
+
|
|
25583
|
+
//#endregion
|
|
25584
|
+
//#region ../theme-core/src/site-styles/pageDesignEditorCapabilities.ts
|
|
25585
|
+
function cardRoleCapabilityOf(capability) {
|
|
25586
|
+
return capability?.kind === "designed" ? capability.cardRoles : "unsupported";
|
|
24962
25587
|
}
|
|
24963
|
-
function
|
|
24964
|
-
|
|
24965
|
-
|
|
24966
|
-
|
|
24967
|
-
|
|
25588
|
+
function backgroundSupportForCapability(capability) {
|
|
25589
|
+
if (capability === null) {
|
|
25590
|
+
return {
|
|
25591
|
+
kind: "unsupported",
|
|
25592
|
+
reason: "missing-design-capability"
|
|
25593
|
+
};
|
|
24968
25594
|
}
|
|
24969
|
-
|
|
24970
|
-
|
|
24971
|
-
|
|
24972
|
-
|
|
24973
|
-
|
|
24974
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
25595
|
+
if (capability.kind === "not-designed") {
|
|
25596
|
+
return {
|
|
25597
|
+
kind: "unsupported",
|
|
25598
|
+
reason: capability.reason
|
|
25599
|
+
};
|
|
24975
25600
|
}
|
|
24976
|
-
|
|
24977
|
-
|
|
24978
|
-
|
|
24979
|
-
|
|
24980
|
-
|
|
24981
|
-
|
|
24982
|
-
}
|
|
24983
|
-
function requiredBoundaryChoice(optionId) {
|
|
24984
|
-
return {
|
|
24985
|
-
kind: "user-pinned",
|
|
24986
|
-
value: boundaryTreatmentForBoundaryOptionId(optionId)
|
|
25601
|
+
return capability.sectionSurfaces === "supported" ? {
|
|
25602
|
+
kind: "supported",
|
|
25603
|
+
richBackgrounds: capability.richBackgrounds ?? "unsupported"
|
|
25604
|
+
} : {
|
|
25605
|
+
kind: "unsupported",
|
|
25606
|
+
reason: "section-surfaces-unsupported"
|
|
24987
25607
|
};
|
|
24988
25608
|
}
|
|
24989
|
-
|
|
24990
|
-
|
|
24991
|
-
|
|
24992
|
-
|
|
24993
|
-
|
|
24994
|
-
});
|
|
24995
|
-
switch (policy.kind) {
|
|
24996
|
-
case "open": return [];
|
|
24997
|
-
case "locked-look-and-layouts": return [{
|
|
24998
|
-
blockId: block.blockId,
|
|
24999
|
-
blockKind: block.blockKind,
|
|
25000
|
-
choice: requiredLookChoice(policy.lookId)
|
|
25001
|
-
}];
|
|
25002
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
25003
|
-
}
|
|
25004
|
-
});
|
|
25005
|
-
const policyBoundaryPins = blocks.flatMap((block, index) => {
|
|
25006
|
-
const nextBlock = blocks[index + 1];
|
|
25007
|
-
if (!nextBlock) {
|
|
25008
|
-
return [];
|
|
25009
|
-
}
|
|
25010
|
-
const policy = deriveSiteStyleBlockPolicy({
|
|
25011
|
-
siteStyleId: intent.siteStyleId,
|
|
25012
|
-
blockKind: block.blockKind
|
|
25013
|
-
});
|
|
25014
|
-
switch (policy.kind) {
|
|
25015
|
-
case "open": return [];
|
|
25016
|
-
case "locked-look-and-layouts": {
|
|
25017
|
-
const defaultBoundary = policy.defaultBoundaryAfter;
|
|
25018
|
-
if (!defaultBoundary) {
|
|
25019
|
-
return [];
|
|
25020
|
-
}
|
|
25021
|
-
const currentChoice = resolvePageDesignBoundaryChoice(intent, block.blockId, nextBlock.blockId);
|
|
25022
|
-
return currentChoice.kind === "auto" ? [buildBoundaryPin(block.blockId, nextBlock.blockId, requiredBoundaryChoice(defaultBoundary.optionId))] : [];
|
|
25023
|
-
}
|
|
25024
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
25025
|
-
}
|
|
25026
|
-
});
|
|
25027
|
-
if (policyLookPins.length === 0 && policyBoundaryPins.length === 0) {
|
|
25028
|
-
return intent;
|
|
25029
|
-
}
|
|
25030
|
-
const policyPinBlockIds = new Set(policyLookPins.map((pin) => pin.blockId));
|
|
25609
|
+
/**
|
|
25610
|
+
* The capability-derived half of a block's editor read model, in one call so
|
|
25611
|
+
* the read-model builder does not grow a projection per axis.
|
|
25612
|
+
*/
|
|
25613
|
+
function capabilitySupportFor(capability) {
|
|
25031
25614
|
return {
|
|
25032
|
-
|
|
25033
|
-
|
|
25034
|
-
boundaryPins: [...intent.boundaryPins, ...policyBoundaryPins]
|
|
25615
|
+
backgroundSupport: backgroundSupportForCapability(capability),
|
|
25616
|
+
cardRoles: cardRoleCapabilityOf(capability)
|
|
25035
25617
|
};
|
|
25036
25618
|
}
|
|
25037
|
-
|
|
25038
|
-
|
|
25039
|
-
|
|
25040
|
-
|
|
25041
|
-
|
|
25042
|
-
|
|
25043
|
-
|
|
25044
|
-
|
|
25045
|
-
|
|
25046
|
-
|
|
25047
|
-
|
|
25048
|
-
|
|
25049
|
-
}
|
|
25050
|
-
function applyBlockContentVariantPolicy(input) {
|
|
25051
|
-
const plan = planBlockContentVariantPolicyUpdate(input);
|
|
25052
|
-
switch (plan.kind) {
|
|
25053
|
-
case "unchanged": return input.content;
|
|
25054
|
-
case "set-variant": return {
|
|
25055
|
-
...input.content,
|
|
25056
|
-
variant: plan.variantKey
|
|
25057
|
-
};
|
|
25058
|
-
default: return assertNever$1(plan, "Unhandled block content variant policy plan");
|
|
25059
|
-
}
|
|
25060
|
-
}
|
|
25061
|
-
function auditPageDesignIntentPolicy(input) {
|
|
25062
|
-
return input.blocks.flatMap((block) => {
|
|
25063
|
-
const policy = deriveSiteStyleBlockPolicy({
|
|
25064
|
-
siteStyleId: input.intent.siteStyleId,
|
|
25065
|
-
blockKind: block.blockKind
|
|
25066
|
-
});
|
|
25067
|
-
switch (policy.kind) {
|
|
25068
|
-
case "open": return [];
|
|
25069
|
-
case "locked-look-and-layouts": {
|
|
25070
|
-
const choice = resolvePageDesignBlockLookChoice(input.intent, block.blockId);
|
|
25071
|
-
const lookIssue = choice.kind === "auto" ? {
|
|
25072
|
-
kind: "missing-required-look-pin",
|
|
25073
|
-
blockId: block.blockId,
|
|
25074
|
-
blockKind: block.blockKind,
|
|
25075
|
-
requiredLookId: policy.lookId
|
|
25076
|
-
} : choice.value === policy.lookId ? null : {
|
|
25077
|
-
kind: "unsupported-look-pin",
|
|
25078
|
-
blockId: block.blockId,
|
|
25079
|
-
blockKind: block.blockKind,
|
|
25080
|
-
actualLookId: choice.value,
|
|
25081
|
-
requiredLookId: policy.lookId
|
|
25082
|
-
};
|
|
25083
|
-
const layoutIssue = block.currentLayoutVariantKey && !isLayoutVariantAllowedByPolicy(policy, block.currentLayoutVariantKey) ? {
|
|
25084
|
-
kind: "unsupported-layout-variant",
|
|
25085
|
-
blockId: block.blockId,
|
|
25086
|
-
blockKind: block.blockKind,
|
|
25087
|
-
actualLayoutVariantKey: block.currentLayoutVariantKey,
|
|
25088
|
-
defaultLayoutVariantKey: policy.defaultLayoutVariantKey
|
|
25089
|
-
} : null;
|
|
25090
|
-
const issues = [];
|
|
25091
|
-
if (lookIssue) {
|
|
25092
|
-
issues.push(lookIssue);
|
|
25093
|
-
}
|
|
25094
|
-
if (layoutIssue) {
|
|
25095
|
-
issues.push(layoutIssue);
|
|
25096
|
-
}
|
|
25097
|
-
return issues;
|
|
25098
|
-
}
|
|
25099
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
25100
|
-
}
|
|
25619
|
+
|
|
25620
|
+
//#endregion
|
|
25621
|
+
//#region ../theme-core/src/site-styles/pageDesignEditorBoundaries.ts
|
|
25622
|
+
function buildBoundaryReadModels(input) {
|
|
25623
|
+
return input.blocks.flatMap((previousBlock, index) => {
|
|
25624
|
+
const nextBlock = input.blocks[index + 1];
|
|
25625
|
+
return nextBlock ? [buildBoundaryReadModel({
|
|
25626
|
+
siteStyleId: input.siteStyleId,
|
|
25627
|
+
pageFlowPresetId: input.intent.pageFlowPresetId,
|
|
25628
|
+
pin: resolvePageDesignBoundaryChoice(input.intent, previousBlock.blockId, nextBlock.blockId),
|
|
25629
|
+
previousBlock,
|
|
25630
|
+
nextBlock
|
|
25631
|
+
})] : [];
|
|
25101
25632
|
});
|
|
25102
25633
|
}
|
|
25103
|
-
function
|
|
25104
|
-
|
|
25105
|
-
|
|
25106
|
-
|
|
25107
|
-
blocks: input.blocks
|
|
25108
|
-
});
|
|
25109
|
-
}
|
|
25110
|
-
const policyBlockCount = input.blocks.filter((block) => deriveSiteStyleBlockPolicy({
|
|
25111
|
-
siteStyleId: input.siteStyleId,
|
|
25112
|
-
blockKind: block.blockKind
|
|
25113
|
-
}).kind !== "open").length;
|
|
25114
|
-
return policyBlockCount === 0 ? [] : [{
|
|
25115
|
-
kind: "missing-page-design-authority",
|
|
25634
|
+
function buildBoundaryReadModel(input) {
|
|
25635
|
+
const previousBlockId = input.previousBlock.blockId;
|
|
25636
|
+
const nextBlockId = input.nextBlock.blockId;
|
|
25637
|
+
const defaults = pageDesignDefaultJoinCandidates({
|
|
25116
25638
|
siteStyleId: input.siteStyleId,
|
|
25117
|
-
|
|
25118
|
-
|
|
25119
|
-
}
|
|
25120
|
-
function assertRegisteredSiteStyleBlockPoliciesAreValid() {
|
|
25121
|
-
registeredSiteStyleBlockPolicies.forEach((policy) => {
|
|
25122
|
-
if (!policy.allowedLayoutVariantKeys.includes(policy.defaultLayoutVariantKey)) {
|
|
25123
|
-
throw new Error(`Site style block policy for ${policy.siteStyleId} ${policy.blockKind} has a default layout outside its allowed layouts.`);
|
|
25124
|
-
}
|
|
25125
|
-
const preset = appearancePresets.find((candidate$1) => candidate$1.id === policy.lookId && blockAppearancePresetSupportsBlockKind(candidate$1, policy.blockKind));
|
|
25126
|
-
if (!preset) {
|
|
25127
|
-
throw new Error(`Site style block policy for ${policy.siteStyleId} ${policy.blockKind} references an unavailable Look ${policy.lookId}.`);
|
|
25128
|
-
}
|
|
25639
|
+
pageFlowPresetId: input.pageFlowPresetId,
|
|
25640
|
+
previousBlockKind: input.previousBlock.blockKind
|
|
25129
25641
|
});
|
|
25642
|
+
const projection = input.pin.kind === "user-pinned" ? pinnedBreakChoice(resolveJoinTreatment({
|
|
25643
|
+
candidates: [{
|
|
25644
|
+
source: { kind: "user-pinned" },
|
|
25645
|
+
treatment: input.pin.value
|
|
25646
|
+
}, ...defaults],
|
|
25647
|
+
previousBlockId,
|
|
25648
|
+
nextBlockId
|
|
25649
|
+
})) : autoBreakChoice(resolveJoinTreatment({
|
|
25650
|
+
candidates: defaults,
|
|
25651
|
+
previousBlockId,
|
|
25652
|
+
nextBlockId
|
|
25653
|
+
}), input.pageFlowPresetId);
|
|
25654
|
+
return {
|
|
25655
|
+
boundary: {
|
|
25656
|
+
boundaryId: makeBoundaryId(previousBlockId, nextBlockId),
|
|
25657
|
+
previousBlockId,
|
|
25658
|
+
nextBlockId,
|
|
25659
|
+
breakChoice: projection.breakChoice,
|
|
25660
|
+
availableBreaks: boundaryOptions
|
|
25661
|
+
},
|
|
25662
|
+
issues: projection.issues
|
|
25663
|
+
};
|
|
25130
25664
|
}
|
|
25131
|
-
function
|
|
25132
|
-
|
|
25133
|
-
|
|
25134
|
-
|
|
25135
|
-
|
|
25665
|
+
function autoBreakChoice(resolution, pageFlowPresetId) {
|
|
25666
|
+
return {
|
|
25667
|
+
breakChoice: {
|
|
25668
|
+
kind: "auto",
|
|
25669
|
+
source: resolution.selectedSource ?? pageFlowDefaultJoinCandidate(pageFlowPresetId).source,
|
|
25670
|
+
effectiveValue: effectiveBreak(resolution)
|
|
25671
|
+
},
|
|
25672
|
+
issues: resolution.issues
|
|
25673
|
+
};
|
|
25674
|
+
}
|
|
25675
|
+
function pinnedBreakChoice(resolution) {
|
|
25676
|
+
const effectiveValue = effectiveBreak(resolution);
|
|
25677
|
+
switch (resolution.pin.kind) {
|
|
25678
|
+
case "unsupported": return {
|
|
25679
|
+
breakChoice: {
|
|
25680
|
+
kind: "user-pinned",
|
|
25681
|
+
value: resolution.pin.optionId,
|
|
25682
|
+
status: "unsupported",
|
|
25683
|
+
effectiveValue
|
|
25684
|
+
},
|
|
25685
|
+
issues: resolution.issues
|
|
25686
|
+
};
|
|
25687
|
+
case "supported":
|
|
25688
|
+
case "none": return {
|
|
25689
|
+
breakChoice: {
|
|
25690
|
+
kind: "user-pinned",
|
|
25691
|
+
value: effectiveValue ?? noneBoundaryOption.id,
|
|
25692
|
+
status: "supported",
|
|
25693
|
+
effectiveValue
|
|
25694
|
+
},
|
|
25695
|
+
issues: resolution.issues
|
|
25696
|
+
};
|
|
25697
|
+
default: return assertNever$1(resolution.pin, "Unhandled join pin status");
|
|
25136
25698
|
}
|
|
25137
25699
|
}
|
|
25700
|
+
/** The effective break as the option the editor shows; null when nothing was usable. */
|
|
25701
|
+
function effectiveBreak(resolution) {
|
|
25702
|
+
if (resolution.join) {
|
|
25703
|
+
return boundaryOptionForTransitionIntent(resolution.join.treatment).id;
|
|
25704
|
+
}
|
|
25705
|
+
return resolution.selectedSource ? noneBoundaryOption.id : null;
|
|
25706
|
+
}
|
|
25707
|
+
/**
|
|
25708
|
+
* Re-resolves one boundary of an editor model for a changed break choice,
|
|
25709
|
+
* through the same rules the model was built with. The preview uses it for
|
|
25710
|
+
* optimistic updates, so a reset lands on whichever default the rules pick
|
|
25711
|
+
* (site style or Page Flow). Null when either block is not in the model.
|
|
25712
|
+
*/
|
|
25713
|
+
function resolvePageDesignEditorBoundaryForChoice(input) {
|
|
25714
|
+
const previousBlock = input.editorModel.blocks.find((block) => block.blockId === input.previousBlockId);
|
|
25715
|
+
const nextBlock = input.editorModel.blocks.find((block) => block.blockId === input.nextBlockId);
|
|
25716
|
+
if (!previousBlock || !nextBlock) return null;
|
|
25717
|
+
return buildBoundaryReadModel({
|
|
25718
|
+
siteStyleId: input.editorModel.siteStyleId,
|
|
25719
|
+
pageFlowPresetId: input.editorModel.pageFlow.value,
|
|
25720
|
+
pin: input.choice,
|
|
25721
|
+
previousBlock,
|
|
25722
|
+
nextBlock
|
|
25723
|
+
}).boundary;
|
|
25724
|
+
}
|
|
25138
25725
|
|
|
25139
25726
|
//#endregion
|
|
25140
25727
|
//#region ../theme-core/src/site-styles/pageDesignEditorModel.ts
|
|
@@ -25160,29 +25747,6 @@ const backgroundImagePromotedFieldPath = "_sectionStyles.background.image";
|
|
|
25160
25747
|
* Look/Layout semantics support them.
|
|
25161
25748
|
*/
|
|
25162
25749
|
const normalEditorCuratedPromotedFieldPaths = [backgroundImagePromotedFieldPath];
|
|
25163
|
-
/**
|
|
25164
|
-
* Must remain non-empty; downstream code indexes `[0]` as the documented default.
|
|
25165
|
-
*/
|
|
25166
|
-
const pageFlowPresets = [
|
|
25167
|
-
{
|
|
25168
|
-
id: asPageFlowPresetId("flow:quiet"),
|
|
25169
|
-
label: "Quiet",
|
|
25170
|
-
boundaryStrategy: "quiet",
|
|
25171
|
-
defaultBoundaryOptionId: noneBoundaryOption.id
|
|
25172
|
-
},
|
|
25173
|
-
{
|
|
25174
|
-
id: asPageFlowPresetId("flow:balanced"),
|
|
25175
|
-
label: "Balanced",
|
|
25176
|
-
boundaryStrategy: "balanced",
|
|
25177
|
-
defaultBoundaryOptionId: softBoundaryOption.id
|
|
25178
|
-
},
|
|
25179
|
-
{
|
|
25180
|
-
id: asPageFlowPresetId("flow:expressive"),
|
|
25181
|
-
label: "Expressive",
|
|
25182
|
-
boundaryStrategy: "expressive",
|
|
25183
|
-
defaultBoundaryOptionId: spaciousBoundaryOption.id
|
|
25184
|
-
}
|
|
25185
|
-
];
|
|
25186
25750
|
function buildPageDesignEditorReadModel(input) {
|
|
25187
25751
|
const defaultPageFlow = pageFlowPresets[0];
|
|
25188
25752
|
const currentPageFlow = pageFlowPresets.find((preset) => preset.id === input.intent.pageFlowPresetId) ?? null;
|
|
@@ -25270,8 +25834,8 @@ function buildPageDesignEditorReadModel(input) {
|
|
|
25270
25834
|
};
|
|
25271
25835
|
});
|
|
25272
25836
|
const boundaryResults = buildBoundaryReadModels({
|
|
25273
|
-
|
|
25274
|
-
blocks:
|
|
25837
|
+
...input,
|
|
25838
|
+
blocks: blockResults.map((result) => result.block)
|
|
25275
25839
|
});
|
|
25276
25840
|
return {
|
|
25277
25841
|
siteStyleId: input.siteStyleId,
|
|
@@ -25515,62 +26079,6 @@ function editorChoiceForLook(input) {
|
|
|
25515
26079
|
})
|
|
25516
26080
|
});
|
|
25517
26081
|
}
|
|
25518
|
-
function buildBoundaryReadModels(input) {
|
|
25519
|
-
return input.blocks.flatMap((previous, index) => {
|
|
25520
|
-
const next = input.blocks[index + 1];
|
|
25521
|
-
if (!next) {
|
|
25522
|
-
return [];
|
|
25523
|
-
}
|
|
25524
|
-
const boundaryId = makeBoundaryId(previous.blockId, next.blockId);
|
|
25525
|
-
const choice = resolvePageDesignBoundaryChoice(input.intent, previous.blockId, next.blockId);
|
|
25526
|
-
const breakResult = boundaryEditorChoiceFromResolvedChoice({
|
|
25527
|
-
choice,
|
|
25528
|
-
defaultValue: autoBoundaryOptionForIntent(input.intent),
|
|
25529
|
-
unsupportedIssue: (presetId) => ({
|
|
25530
|
-
kind: "pinned-boundary-option-unavailable",
|
|
25531
|
-
boundaryId,
|
|
25532
|
-
presetId,
|
|
25533
|
-
feedback: "user-facing"
|
|
25534
|
-
})
|
|
25535
|
-
});
|
|
25536
|
-
return {
|
|
25537
|
-
boundary: {
|
|
25538
|
-
boundaryId,
|
|
25539
|
-
previousBlockId: previous.blockId,
|
|
25540
|
-
nextBlockId: next.blockId,
|
|
25541
|
-
breakChoice: breakResult.choice,
|
|
25542
|
-
availableBreaks: boundaryOptions
|
|
25543
|
-
},
|
|
25544
|
-
issues: compactIssues([breakResult.issue])
|
|
25545
|
-
};
|
|
25546
|
-
});
|
|
25547
|
-
}
|
|
25548
|
-
function boundaryEditorChoiceFromResolvedChoice(input) {
|
|
25549
|
-
switch (input.choice.kind) {
|
|
25550
|
-
case "auto": return {
|
|
25551
|
-
choice: {
|
|
25552
|
-
kind: "auto",
|
|
25553
|
-
effectiveValue: input.defaultValue
|
|
25554
|
-
},
|
|
25555
|
-
issue: null
|
|
25556
|
-
};
|
|
25557
|
-
case "user-pinned": {
|
|
25558
|
-
const option = boundaryOptionForTreatment(input.choice.value);
|
|
25559
|
-
const fallbackValue = boundaryOptionIdForTreatment(input.choice.value);
|
|
25560
|
-
const issueValue = fallbackValue ?? input.defaultValue ?? noneBoundaryOption.id;
|
|
25561
|
-
return {
|
|
25562
|
-
choice: {
|
|
25563
|
-
kind: "user-pinned",
|
|
25564
|
-
value: issueValue,
|
|
25565
|
-
status: option ? "supported" : "unsupported",
|
|
25566
|
-
effectiveValue: option?.id ?? input.defaultValue
|
|
25567
|
-
},
|
|
25568
|
-
issue: option ? null : input.unsupportedIssue(issueValue)
|
|
25569
|
-
};
|
|
25570
|
-
}
|
|
25571
|
-
default: return assertNever$1(input.choice, "Unhandled boundary design choice");
|
|
25572
|
-
}
|
|
25573
|
-
}
|
|
25574
26082
|
function editorChoiceFromResolvedChoice(input) {
|
|
25575
26083
|
switch (input.choice.kind) {
|
|
25576
26084
|
case "auto": return {
|
|
@@ -25595,10 +26103,6 @@ function editorChoiceFromResolvedChoice(input) {
|
|
|
25595
26103
|
default: return assertNever$1(input.choice, "Unhandled page design choice");
|
|
25596
26104
|
}
|
|
25597
26105
|
}
|
|
25598
|
-
function autoBoundaryOptionForIntent(intent) {
|
|
25599
|
-
const pageFlow = pageFlowPresets.find((preset) => preset.id === intent.pageFlowPresetId);
|
|
25600
|
-
return pageFlow?.defaultBoundaryOptionId ?? boundaryOptions[0].id;
|
|
25601
|
-
}
|
|
25602
26106
|
function compactIssues(issues) {
|
|
25603
26107
|
return issues.filter((issue$1) => issue$1 !== null);
|
|
25604
26108
|
}
|
|
@@ -25649,7 +26153,6 @@ const repairActionsByIssueKind = {
|
|
|
25649
26153
|
"image-surface-treatment-without-image-surface": ["fallback-image-surface-treatment"],
|
|
25650
26154
|
"image-surface-motion-without-image-surface": ["fallback-image-surface-motion"],
|
|
25651
26155
|
"hero-legibility-overridden-by-image-surface-treatment": ["remove-hero-legibility"],
|
|
25652
|
-
"removed-transition-for-flush-frame": ["remove-transition"],
|
|
25653
26156
|
"hero-image-without-legibility": ["fallback-hero-legibility"]
|
|
25654
26157
|
};
|
|
25655
26158
|
function repairActionsForIssue(issueKind) {
|
|
@@ -25737,11 +26240,6 @@ function repairDesignIssue(issue$1) {
|
|
|
25737
26240
|
issue: issue$1,
|
|
25738
26241
|
action: issue$1.allowedRepairActions[0]
|
|
25739
26242
|
};
|
|
25740
|
-
case "removed-transition-for-flush-frame": return {
|
|
25741
|
-
kind: "repaired",
|
|
25742
|
-
issue: issue$1,
|
|
25743
|
-
action: issue$1.allowedRepairActions[0]
|
|
25744
|
-
};
|
|
25745
26243
|
case "hero-image-without-legibility": return {
|
|
25746
26244
|
kind: "fallbackApplied",
|
|
25747
26245
|
issue: issue$1,
|
|
@@ -25784,13 +26282,9 @@ function supportsBlockComposition(capability, composition) {
|
|
|
25784
26282
|
default: return assertNever$1(composition);
|
|
25785
26283
|
}
|
|
25786
26284
|
}
|
|
25787
|
-
function isDecorativeTransition(transition) {
|
|
25788
|
-
return transition !== "none";
|
|
25789
|
-
}
|
|
25790
26285
|
const blockDesignFallback = {
|
|
25791
26286
|
sectionSurface: "base",
|
|
25792
26287
|
contentFrame: plainFrame,
|
|
25793
|
-
transitionAfter: "none",
|
|
25794
26288
|
sectionHeight: "default",
|
|
25795
26289
|
heroLegibility: "none",
|
|
25796
26290
|
imageSurfaceTreatment: { kind: "none" },
|
|
@@ -25806,7 +26300,6 @@ const appliedBlockDesignFallback = {
|
|
|
25806
26300
|
appliedSectionSurface: blockDesignFallback.sectionSurface,
|
|
25807
26301
|
appliedContentFrame: blockDesignFallback.contentFrame,
|
|
25808
26302
|
appliedCardRole: null,
|
|
25809
|
-
appliedTransitionAfter: blockDesignFallback.transitionAfter,
|
|
25810
26303
|
appliedSectionHeight: blockDesignFallback.sectionHeight,
|
|
25811
26304
|
appliedHeroLegibility: blockDesignFallback.heroLegibility,
|
|
25812
26305
|
appliedImageSurfaceTreatment: blockDesignFallback.imageSurfaceTreatment,
|
|
@@ -25832,7 +26325,6 @@ function blockDesignRequest(block) {
|
|
|
25832
26325
|
sectionSurface: block.sectionSurface,
|
|
25833
26326
|
contentFrame: block.contentFrame,
|
|
25834
26327
|
...block.cardRole ? { cardRole: block.cardRole } : {},
|
|
25835
|
-
transitionAfter: block.transitionAfter,
|
|
25836
26328
|
sectionHeight: block.sectionHeight,
|
|
25837
26329
|
heroLegibility: block.heroLegibility,
|
|
25838
26330
|
imageSurfaceTreatment: block.imageSurfaceTreatment,
|
|
@@ -25851,7 +26343,6 @@ function resolveBlockDesignPlan(input) {
|
|
|
25851
26343
|
let appliedSectionSurface = block.sectionSurface;
|
|
25852
26344
|
let appliedContentFrame = block.contentFrame;
|
|
25853
26345
|
const appliedCardRole = appliedCardRoleFor(block, capability);
|
|
25854
|
-
let appliedTransitionAfter = block.transitionAfter;
|
|
25855
26346
|
let appliedSectionHeight = block.sectionHeight ?? "default";
|
|
25856
26347
|
let appliedHeroLegibility = block.heroLegibility ?? "none";
|
|
25857
26348
|
let appliedImageSurfaceTreatment = block.imageSurfaceTreatment ?? { kind: "none" };
|
|
@@ -26116,7 +26607,6 @@ function resolveBlockDesignPlan(input) {
|
|
|
26116
26607
|
appliedSectionSurface,
|
|
26117
26608
|
appliedContentFrame,
|
|
26118
26609
|
appliedCardRole,
|
|
26119
|
-
appliedTransitionAfter,
|
|
26120
26610
|
appliedSectionHeight,
|
|
26121
26611
|
appliedHeroLegibility,
|
|
26122
26612
|
appliedImageSurfaceTreatment,
|
|
@@ -26128,29 +26618,8 @@ function resolveBlockDesignPlan(input) {
|
|
|
26128
26618
|
appliedComposition
|
|
26129
26619
|
};
|
|
26130
26620
|
});
|
|
26131
|
-
const transitionSafeBlocks = blocks.map((block, index) => {
|
|
26132
|
-
const nextBlock = blocks[index + 1];
|
|
26133
|
-
if (!nextBlock || !isDecorativeTransition(block.appliedTransitionAfter) || block.appliedContentFrame.kind !== "flush-panel" && nextBlock.appliedContentFrame.kind !== "flush-panel") {
|
|
26134
|
-
return block;
|
|
26135
|
-
}
|
|
26136
|
-
issues.push({
|
|
26137
|
-
kind: "removed-transition-for-flush-frame",
|
|
26138
|
-
blockId: block.blockId,
|
|
26139
|
-
blockKind: block.blockKind,
|
|
26140
|
-
purpose: block.purpose,
|
|
26141
|
-
requested: block.appliedTransitionAfter,
|
|
26142
|
-
fallback: "none",
|
|
26143
|
-
policy: input.policy,
|
|
26144
|
-
severity: designIssueSeverityForPolicy(input.policy),
|
|
26145
|
-
allowedRepairActions: repairActionsForIssue("removed-transition-for-flush-frame")
|
|
26146
|
-
});
|
|
26147
|
-
return {
|
|
26148
|
-
...block,
|
|
26149
|
-
appliedTransitionAfter: "none"
|
|
26150
|
-
};
|
|
26151
|
-
});
|
|
26152
26621
|
return {
|
|
26153
|
-
blocks
|
|
26622
|
+
blocks,
|
|
26154
26623
|
issues
|
|
26155
26624
|
};
|
|
26156
26625
|
}
|
|
@@ -27037,80 +27506,6 @@ function recompileSiteChromeHeaderFromPersistedIntent(theme, siteStyle, requeste
|
|
|
27037
27506
|
};
|
|
27038
27507
|
}
|
|
27039
27508
|
|
|
27040
|
-
//#endregion
|
|
27041
|
-
//#region ../theme-core/src/site-styles/runtimeBackgroundResolution.ts
|
|
27042
|
-
function parseCanonicalRuntimeBackground(content) {
|
|
27043
|
-
const sectionStyles = readRecord$1(content._sectionStyles);
|
|
27044
|
-
const background = readRecord$1(sectionStyles?.background);
|
|
27045
|
-
if (!background) return { kind: "none" };
|
|
27046
|
-
const parsed = boxBackgroundSchema.safeParse(background);
|
|
27047
|
-
if (!parsed.success) return { kind: "none" };
|
|
27048
|
-
return parsed.data.contentOwner === pageDesignEditorBackgroundOverrideOwner ? {
|
|
27049
|
-
kind: "page-design-override",
|
|
27050
|
-
background: parsed.data
|
|
27051
|
-
} : {
|
|
27052
|
-
kind: "block-authored",
|
|
27053
|
-
background: parsed.data
|
|
27054
|
-
};
|
|
27055
|
-
}
|
|
27056
|
-
function resolveSectionBackground(source, lookDefault) {
|
|
27057
|
-
if (source.kind === "page-design-override") {
|
|
27058
|
-
return {
|
|
27059
|
-
kind: "page-design-override",
|
|
27060
|
-
background: source.background
|
|
27061
|
-
};
|
|
27062
|
-
}
|
|
27063
|
-
if (lookDefault) {
|
|
27064
|
-
if (source.kind === "block-authored" && (source.background.type === "image" || source.background.type === "video")) {
|
|
27065
|
-
return {
|
|
27066
|
-
kind: "block-authored",
|
|
27067
|
-
background: mergeLookForegroundWithAuthoredMedia(lookDefault, source.background)
|
|
27068
|
-
};
|
|
27069
|
-
}
|
|
27070
|
-
return {
|
|
27071
|
-
kind: "look-default",
|
|
27072
|
-
background: lookDefault
|
|
27073
|
-
};
|
|
27074
|
-
}
|
|
27075
|
-
if (source.kind === "block-authored" && (source.background.type === "image" || source.background.type === "video")) {
|
|
27076
|
-
return {
|
|
27077
|
-
kind: "block-authored",
|
|
27078
|
-
background: source.background
|
|
27079
|
-
};
|
|
27080
|
-
}
|
|
27081
|
-
return source.kind === "block-authored" ? {
|
|
27082
|
-
kind: "block-authored",
|
|
27083
|
-
background: source.background
|
|
27084
|
-
} : { kind: "none" };
|
|
27085
|
-
}
|
|
27086
|
-
function resolveSectionForeground(background, palette) {
|
|
27087
|
-
return resolveSurfaceForeground(background.kind === "none" ? null : background.background, palette, {}, { compositeBase: "background" });
|
|
27088
|
-
}
|
|
27089
|
-
/**
|
|
27090
|
-
* Read foreground authority from post-compiler block content. The preview
|
|
27091
|
-
* compiler has already materialized any Look-owned background into
|
|
27092
|
-
* `_sectionStyles`; raw authored content must be composed with its Look through
|
|
27093
|
-
* `resolveSectionBackground` instead.
|
|
27094
|
-
*/
|
|
27095
|
-
function resolveCompiledSectionForegroundFromContent(content, palette) {
|
|
27096
|
-
if (!content) return resolveSurfaceForeground(null, palette);
|
|
27097
|
-
return resolveSectionForeground(resolveSectionBackground(parseCanonicalRuntimeBackground(content), null), palette);
|
|
27098
|
-
}
|
|
27099
|
-
function mergeLookForegroundWithAuthoredMedia(lookDefault, authored) {
|
|
27100
|
-
const merged = boxBackgroundSchema.safeParse({
|
|
27101
|
-
...lookDefault,
|
|
27102
|
-
type: authored.type,
|
|
27103
|
-
image: authored.image,
|
|
27104
|
-
objectFit: authored.objectFit,
|
|
27105
|
-
scale: authored.scale,
|
|
27106
|
-
position: authored.position
|
|
27107
|
-
});
|
|
27108
|
-
return merged.success ? merged.data : authored;
|
|
27109
|
-
}
|
|
27110
|
-
function readRecord$1(value) {
|
|
27111
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
27112
|
-
}
|
|
27113
|
-
|
|
27114
27509
|
//#endregion
|
|
27115
27510
|
//#region ../theme-core/src/site-styles/previewRuntimeCapabilities.ts
|
|
27116
27511
|
function cardRoleCapabilitiesByBlockKind(blocks) {
|
|
@@ -27586,7 +27981,6 @@ function compileEditorModelRuntime(input) {
|
|
|
27586
27981
|
blockKind: block.blockKind,
|
|
27587
27982
|
purpose: previewCustomizePurpose,
|
|
27588
27983
|
...look ? { appearancePresetId: look.id } : {},
|
|
27589
|
-
transitionAfter: "none",
|
|
27590
27984
|
emphasis: "medium",
|
|
27591
27985
|
sectionSurface: "base",
|
|
27592
27986
|
contentFrame: { kind: "plain" },
|
|
@@ -27596,30 +27990,31 @@ function compileEditorModelRuntime(input) {
|
|
|
27596
27990
|
if (blocks.length === 0) {
|
|
27597
27991
|
return {
|
|
27598
27992
|
blocks: [],
|
|
27599
|
-
|
|
27993
|
+
joins: []
|
|
27600
27994
|
};
|
|
27601
27995
|
}
|
|
27602
|
-
|
|
27603
|
-
const compiled = compilePageRuntimeFields({
|
|
27996
|
+
return compilePageRuntimeFields({
|
|
27604
27997
|
resolved: resolveBlockDesignPlan({
|
|
27605
27998
|
policy: "user",
|
|
27606
27999
|
blocks,
|
|
27607
28000
|
capabilities: runtimeCapabilitiesForBlocks(blocks, cardRoleCapabilitiesByBlockKind(input.editorModel.blocks))
|
|
27608
28001
|
}),
|
|
28002
|
+
joins: input.editorModel.boundaries.flatMap(runtimeJoinForEditorBoundary),
|
|
27609
28003
|
surfaceResolutionContext: input.surfaceResolutionContext,
|
|
27610
28004
|
designRules: input.designRules,
|
|
27611
28005
|
componentRules: input.componentRules,
|
|
27612
28006
|
sectionSpacing: input.sectionSpacing
|
|
27613
28007
|
});
|
|
27614
|
-
|
|
27615
|
-
|
|
27616
|
-
|
|
27617
|
-
|
|
27618
|
-
|
|
27619
|
-
|
|
27620
|
-
|
|
27621
|
-
|
|
27622
|
-
|
|
28008
|
+
}
|
|
28009
|
+
/** The editor boundary's effective break as an intent-only join; none for no break. */
|
|
28010
|
+
function runtimeJoinForEditorBoundary(boundary) {
|
|
28011
|
+
const option = boundary.availableBreaks.find((candidate$1) => candidate$1.id === boundary.breakChoice.effectiveValue);
|
|
28012
|
+
const treatment = option?.transitionAfter;
|
|
28013
|
+
return treatment && isDecorativeTransitionIntent(treatment) ? [{
|
|
28014
|
+
previousBlockId: boundary.previousBlockId,
|
|
28015
|
+
nextBlockId: boundary.nextBlockId,
|
|
28016
|
+
treatment
|
|
28017
|
+
}] : [];
|
|
27623
28018
|
}
|
|
27624
28019
|
function buildCompiledRuntimeFieldsByBlockId(compiled) {
|
|
27625
28020
|
return new Map(compiled.blocks.map((block) => [block.blockId, block.fields]));
|
|
@@ -27627,31 +28022,6 @@ function buildCompiledRuntimeFieldsByBlockId(compiled) {
|
|
|
27627
28022
|
function buildEditorModelRuntimeFieldsByBlockId(input) {
|
|
27628
28023
|
return buildCompiledRuntimeFieldsByBlockId(compileEditorModelRuntime(input));
|
|
27629
28024
|
}
|
|
27630
|
-
function buildEditorModelRuntimeBoundaries(input) {
|
|
27631
|
-
return compileEditorModelRuntime(input).boundaries;
|
|
27632
|
-
}
|
|
27633
|
-
function compileEditorBoundaryRuntime(input) {
|
|
27634
|
-
const blockById = new Map(input.blocks.map((block) => [block.blockId, block]));
|
|
27635
|
-
return input.boundaries.flatMap((boundary) => {
|
|
27636
|
-
const previousBlock = blockById.get(boundary.previousBlockId);
|
|
27637
|
-
const nextBlock = blockById.get(boundary.nextBlockId);
|
|
27638
|
-
const transitionAfter = transitionAfterForEditorBoundary(boundary) ?? input.fallbackTransitionAfterByPreviousBlockId.get(boundary.previousBlockId) ?? null;
|
|
27639
|
-
if (!previousBlock || !nextBlock || !transitionAfter) return [];
|
|
27640
|
-
const compiled = compileBoundaryRuntime({
|
|
27641
|
-
boundaryId: boundary.boundaryId,
|
|
27642
|
-
previousBlockId: boundary.previousBlockId,
|
|
27643
|
-
nextBlockId: boundary.nextBlockId,
|
|
27644
|
-
treatment: transitionAfter,
|
|
27645
|
-
fromSurface: previousBlock.visualSectionSurface,
|
|
27646
|
-
toSurface: nextBlock.visualSectionSurface,
|
|
27647
|
-
rules: input.designRules
|
|
27648
|
-
});
|
|
27649
|
-
return compiled ? [compiled] : [];
|
|
27650
|
-
});
|
|
27651
|
-
}
|
|
27652
|
-
function transitionAfterForEditorBoundary(boundary) {
|
|
27653
|
-
return boundary.availableBreaks.find((candidate$1) => candidate$1.id === boundary.breakChoice.effectiveValue)?.transitionAfter ?? null;
|
|
27654
|
-
}
|
|
27655
28025
|
function compileEditorModelRuntimeFieldsForBlock(input) {
|
|
27656
28026
|
return buildEditorModelRuntimeFieldsByBlockId(input).get(input.blockId) ?? null;
|
|
27657
28027
|
}
|
|
@@ -27662,54 +28032,6 @@ function applyCompiledRuntimeFieldsToContent(content, fields) {
|
|
|
27662
28032
|
...runtimeFields
|
|
27663
28033
|
};
|
|
27664
28034
|
}
|
|
27665
|
-
function retargetCompiledRuntimeFieldsForContentAdjacency(fields, adjacency) {
|
|
27666
|
-
if (!fields?._transitionStyles) return fields;
|
|
27667
|
-
const transition = fields._transitionStyles;
|
|
27668
|
-
const fromSurface = contentOwnedBackgroundEndpoint(adjacency.currentContent) ?? transition.from;
|
|
27669
|
-
const toSurface = contentOwnedBackgroundEndpoint(adjacency.nextContent) ?? transition.to;
|
|
27670
|
-
if (fromSurface === transition.from && toSurface === transition.to) {
|
|
27671
|
-
return fields;
|
|
27672
|
-
}
|
|
27673
|
-
return {
|
|
27674
|
-
...fields,
|
|
27675
|
-
_transitionStyles: compileTransitionRuntime({
|
|
27676
|
-
treatment: transition.treatment,
|
|
27677
|
-
from: fromSurface,
|
|
27678
|
-
to: toSurface
|
|
27679
|
-
})
|
|
27680
|
-
};
|
|
27681
|
-
}
|
|
27682
|
-
function retargetCompiledBoundaryRuntimeForContentAdjacency(boundary, adjacency) {
|
|
27683
|
-
const fromSurface = contentOwnedBackgroundEndpoint(adjacency.currentContent) ?? boundary.from;
|
|
27684
|
-
const toSurface = contentOwnedBackgroundEndpoint(adjacency.nextContent) ?? boundary.to;
|
|
27685
|
-
if (fromSurface === boundary.from && toSurface === boundary.to) {
|
|
27686
|
-
return boundary;
|
|
27687
|
-
}
|
|
27688
|
-
const transition = compileTransitionRuntime({
|
|
27689
|
-
treatment: boundary.treatment,
|
|
27690
|
-
from: fromSurface,
|
|
27691
|
-
to: toSurface
|
|
27692
|
-
});
|
|
27693
|
-
return {
|
|
27694
|
-
...boundary,
|
|
27695
|
-
from: transition.from,
|
|
27696
|
-
to: transition.to,
|
|
27697
|
-
cssVars: transition.cssVars
|
|
27698
|
-
};
|
|
27699
|
-
}
|
|
27700
|
-
function contentOwnedBackgroundEndpoint(content) {
|
|
27701
|
-
const sectionStyles = readRecord(content?._sectionStyles);
|
|
27702
|
-
const background = readRecord(sectionStyles?.background);
|
|
27703
|
-
if (background?.contentOwner !== pageDesignEditorBackgroundOverrideOwner || background.type !== "color") {
|
|
27704
|
-
return null;
|
|
27705
|
-
}
|
|
27706
|
-
const token = parseThemeColorToken(background.color);
|
|
27707
|
-
if (!token) return null;
|
|
27708
|
-
return {
|
|
27709
|
-
kind: "color-token",
|
|
27710
|
-
token
|
|
27711
|
-
};
|
|
27712
|
-
}
|
|
27713
28035
|
function preserveContentOwnedBackgroundFields(content, fields) {
|
|
27714
28036
|
const source = parseCanonicalRuntimeBackground(content);
|
|
27715
28037
|
const resolved = resolveSectionBackground(source, fields._sectionStyles?.background);
|
|
@@ -27724,9 +28046,6 @@ function preserveContentOwnedBackgroundFields(content, fields) {
|
|
|
27724
28046
|
}
|
|
27725
28047
|
};
|
|
27726
28048
|
}
|
|
27727
|
-
function readRecord(value) {
|
|
27728
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
27729
|
-
}
|
|
27730
28049
|
function restoreCompiledRuntimeFieldsFromContent(currentContent, previousContent) {
|
|
27731
28050
|
const nextContent = stripCompiledRuntimeStyleFields(currentContent);
|
|
27732
28051
|
for (const fieldName of compiledRuntimeStyleFieldNames) {
|
|
@@ -27773,7 +28092,7 @@ function compileContentTemplateRuntimeFields(input) {
|
|
|
27773
28092
|
}));
|
|
27774
28093
|
return {
|
|
27775
28094
|
blocks,
|
|
27776
|
-
|
|
28095
|
+
joins: compiled.joins,
|
|
27777
28096
|
fieldsByBlockId: new Map(blocks.map((block) => [block.blockId, block.fields])),
|
|
27778
28097
|
issues: editorModel.issues
|
|
27779
28098
|
};
|
|
@@ -28180,9 +28499,6 @@ function defaultContentFrame() {
|
|
|
28180
28499
|
function cardIntentFor(design, lookDefaults) {
|
|
28181
28500
|
return { cardRole: valueOrLookDefault(design.cardRole, lookDefaults?.cardRole, "none") };
|
|
28182
28501
|
}
|
|
28183
|
-
function defaultTransition() {
|
|
28184
|
-
return "none";
|
|
28185
|
-
}
|
|
28186
28502
|
function defaultEmphasis(block) {
|
|
28187
28503
|
return isHeroBlock(block) ? "high" : "medium";
|
|
28188
28504
|
}
|
|
@@ -28207,8 +28523,24 @@ function isDefaultLookSafeForStyle(preset, siteStyle) {
|
|
|
28207
28523
|
}
|
|
28208
28524
|
return preset.design.contentFrame.kind === "plain" && preset.design.cardRole === "none";
|
|
28209
28525
|
}
|
|
28210
|
-
|
|
28211
|
-
|
|
28526
|
+
/**
|
|
28527
|
+
* The generated pipeline's joins: candidates come from the generated intent
|
|
28528
|
+
* and `resolveJoinTreatment` decides. Joins that resolve to no break are
|
|
28529
|
+
* absent; whether one draws is composition's call.
|
|
28530
|
+
*/
|
|
28531
|
+
function resolveGeneratedJoins(input) {
|
|
28532
|
+
const intentByBlockId = new Map(input.intent.blocks.map((block) => [block.blockId, block]));
|
|
28533
|
+
return input.resolved.blocks.flatMap((block, index) => {
|
|
28534
|
+
const next = input.resolved.blocks[index + 1];
|
|
28535
|
+
const blockIntent = intentByBlockId.get(block.blockId);
|
|
28536
|
+
if (!next || !blockIntent) return [];
|
|
28537
|
+
const { join } = resolveJoinTreatment({
|
|
28538
|
+
candidates: joinCandidatesFromGeneratedIntent(blockIntent),
|
|
28539
|
+
previousBlockId: block.blockId,
|
|
28540
|
+
nextBlockId: next.blockId
|
|
28541
|
+
});
|
|
28542
|
+
return join ? [join] : [];
|
|
28543
|
+
});
|
|
28212
28544
|
}
|
|
28213
28545
|
function materializeBlockDesignPlan(block, siteStyle) {
|
|
28214
28546
|
const lookDefaults = defaultAppearanceDesignForBlock({
|
|
@@ -28225,7 +28557,6 @@ function materializeBlockDesignPlan(block, siteStyle) {
|
|
|
28225
28557
|
sectionSurface,
|
|
28226
28558
|
contentFrame: valueOrLookDefault(block.design.contentFrame, lookDefaults?.contentFrame, defaultContentFrame()),
|
|
28227
28559
|
...cardIntentFor(block.design, lookDefaults),
|
|
28228
|
-
transitionAfter: materializeBoundaryTransition(block.design, block.boundaryIntent, defaultTransition()),
|
|
28229
28560
|
emphasis: valueOrDefault(block.design.emphasis, defaultEmphasis(block)),
|
|
28230
28561
|
heroLegibility: valueOrLookDefault(block.mediaIntent.heroLegibility, lookDefaults?.heroLegibility, defaultLegibility),
|
|
28231
28562
|
...lookDefaults?.sectionHeight ? { sectionHeight: lookDefaults.sectionHeight } : {},
|
|
@@ -28281,7 +28612,6 @@ function resolvedBlockToPlan(block) {
|
|
|
28281
28612
|
sectionSurface: block.appliedSectionSurface,
|
|
28282
28613
|
contentFrame: block.appliedContentFrame,
|
|
28283
28614
|
...block.appliedCardRole ? { cardRole: block.appliedCardRole } : {},
|
|
28284
|
-
transitionAfter: block.appliedTransitionAfter,
|
|
28285
28615
|
emphasis: block.emphasis,
|
|
28286
28616
|
sectionHeight: block.appliedSectionHeight,
|
|
28287
28617
|
heroLegibility: block.appliedHeroLegibility,
|
|
@@ -28418,10 +28748,15 @@ function runGeneratedPageDesignPipeline(input) {
|
|
|
28418
28748
|
})
|
|
28419
28749
|
};
|
|
28420
28750
|
}
|
|
28751
|
+
const joins = resolveGeneratedJoins({
|
|
28752
|
+
intent,
|
|
28753
|
+
resolved
|
|
28754
|
+
});
|
|
28421
28755
|
const compositionIssues = validateCompositionBudget({
|
|
28422
28756
|
policy: "generated",
|
|
28423
28757
|
budget: input.siteStyle.template.compositionBudget,
|
|
28424
28758
|
resolved,
|
|
28759
|
+
joins,
|
|
28425
28760
|
blockContexts: intent.blocks.map((block) => ({
|
|
28426
28761
|
blockId: block.blockId,
|
|
28427
28762
|
mediaIntent: block.mediaIntent.media,
|
|
@@ -28445,6 +28780,7 @@ function runGeneratedPageDesignPipeline(input) {
|
|
|
28445
28780
|
}
|
|
28446
28781
|
const compiledRuntime = compilePageRuntimeFields({
|
|
28447
28782
|
resolved,
|
|
28783
|
+
joins,
|
|
28448
28784
|
surfaceResolutionContext: surfaceResolutionContextFromTheme(compileTokenRecipes(input.siteStyle.template.tokenRecipes)),
|
|
28449
28785
|
designRules: designRuntimeRulesForSiteStyle(input.siteStyle),
|
|
28450
28786
|
componentRules: componentRuntimeRulesForSiteStyle(input.siteStyle)
|
|
@@ -28463,6 +28799,7 @@ function runGeneratedPageDesignPipeline(input) {
|
|
|
28463
28799
|
intent,
|
|
28464
28800
|
plan,
|
|
28465
28801
|
resolved,
|
|
28802
|
+
joins,
|
|
28466
28803
|
headerOpeningSectionContext: deriveHeaderOpeningSectionContext({ openingBlock: resolved.blocks[0] ?? null }),
|
|
28467
28804
|
headerOpeningSectionRepairs: headerOpeningSectionPlan.repairs,
|
|
28468
28805
|
repairs,
|
|
@@ -29851,14 +30188,26 @@ const paidOnlineServiceInputSchema = z.object({
|
|
|
29851
30188
|
priceAmount: z.number().int().positive(),
|
|
29852
30189
|
payment: z.object({ mode: z.literal("paid_online_intent") }).strict()
|
|
29853
30190
|
}).strict();
|
|
30191
|
+
/**
|
|
30192
|
+
* A service input with one of the three category placements: none, a
|
|
30193
|
+
* `categoryRef` to a category upserted in the same batch, or the
|
|
30194
|
+
* `categoryIdentifier` of one that already exists (issue 1403).
|
|
30195
|
+
*/
|
|
30196
|
+
function withAppointmentServiceCategoryPlacement(schema) {
|
|
30197
|
+
return z.union([
|
|
30198
|
+
schema.extend(noAppointmentServiceCategoryFields),
|
|
30199
|
+
schema.extend(appointmentServiceCategoryRefFields),
|
|
30200
|
+
schema.extend(appointmentServiceCategoryIdentifierFields)
|
|
30201
|
+
]);
|
|
30202
|
+
}
|
|
29854
30203
|
const upsertAppointmentServiceCommandSchema = z.object({
|
|
29855
30204
|
type: z.literal("upsertAppointmentService"),
|
|
29856
30205
|
ref: appointmentServiceRefSchema,
|
|
29857
|
-
input: z.union([
|
|
29858
|
-
manualRequestServiceInputSchema,
|
|
29859
|
-
freeServiceInputSchema,
|
|
29860
|
-
paidOnlineServiceInputSchema
|
|
29861
|
-
])
|
|
30206
|
+
input: z.unknown().superRefine(rejectBothAppointmentServiceCategoryKeys).pipe(z.union([
|
|
30207
|
+
withAppointmentServiceCategoryPlacement(manualRequestServiceInputSchema),
|
|
30208
|
+
withAppointmentServiceCategoryPlacement(freeServiceInputSchema),
|
|
30209
|
+
withAppointmentServiceCategoryPlacement(paidOnlineServiceInputSchema)
|
|
30210
|
+
]))
|
|
29862
30211
|
}).strict();
|
|
29863
30212
|
const upsertBookableResourceCommandSchema = z.object({
|
|
29864
30213
|
type: z.literal("upsertBookableResource"),
|
|
@@ -29910,6 +30259,31 @@ function validatePortalOrder(input, ctx) {
|
|
|
29910
30259
|
});
|
|
29911
30260
|
}
|
|
29912
30261
|
|
|
30262
|
+
//#endregion
|
|
30263
|
+
//#region ../site-commands/src/bookingCommandSchemaOptions.ts
|
|
30264
|
+
/**
|
|
30265
|
+
* The booking, entitlement and appointment command schemas, in the order the
|
|
30266
|
+
* site command union lists them. `configureBookingSettings` stays with the
|
|
30267
|
+
* site-level commands at the head of the union.
|
|
30268
|
+
*/
|
|
30269
|
+
const bookingCommandSchemaOptions = [
|
|
30270
|
+
upsertBookingPassProductCommandSchema,
|
|
30271
|
+
upsertBookingMembershipProductCommandSchema,
|
|
30272
|
+
seedBookingCustomerCommandSchema,
|
|
30273
|
+
grantCustomerPassCommandSchema,
|
|
30274
|
+
grantCustomerMembershipCommandSchema,
|
|
30275
|
+
seedAppointmentBookingCommandSchema,
|
|
30276
|
+
seedEventSeriesRegistrationCommandSchema,
|
|
30277
|
+
seedEventRegistrationCommandSchema,
|
|
30278
|
+
seedPassRedemptionCommandSchema,
|
|
30279
|
+
seedPortalOrderCommandSchema,
|
|
30280
|
+
upsertAppointmentServiceCategoryCommandSchema,
|
|
30281
|
+
upsertAppointmentServiceCommandSchema,
|
|
30282
|
+
upsertBookableResourceCommandSchema,
|
|
30283
|
+
assignAppointmentServiceResourcesCommandSchema,
|
|
30284
|
+
configureAppointmentAvailabilityCommandSchema
|
|
30285
|
+
];
|
|
30286
|
+
|
|
29913
30287
|
//#endregion
|
|
29914
30288
|
//#region ../site-commands/src/commands.ts
|
|
29915
30289
|
const mediaRefSchema = resourceRefSchema("media");
|
|
@@ -30378,20 +30752,7 @@ const siteCommandSchema = z.discriminatedUnion("type", [
|
|
|
30378
30752
|
deleteEventCategoryCommandSchema,
|
|
30379
30753
|
upsertEventSeriesCommandSchema,
|
|
30380
30754
|
deleteEventSeriesCommandSchema,
|
|
30381
|
-
|
|
30382
|
-
upsertBookingMembershipProductCommandSchema,
|
|
30383
|
-
seedBookingCustomerCommandSchema,
|
|
30384
|
-
grantCustomerPassCommandSchema,
|
|
30385
|
-
grantCustomerMembershipCommandSchema,
|
|
30386
|
-
seedAppointmentBookingCommandSchema,
|
|
30387
|
-
seedEventSeriesRegistrationCommandSchema,
|
|
30388
|
-
seedEventRegistrationCommandSchema,
|
|
30389
|
-
seedPassRedemptionCommandSchema,
|
|
30390
|
-
seedPortalOrderCommandSchema,
|
|
30391
|
-
upsertAppointmentServiceCommandSchema,
|
|
30392
|
-
upsertBookableResourceCommandSchema,
|
|
30393
|
-
assignAppointmentServiceResourcesCommandSchema,
|
|
30394
|
-
configureAppointmentAvailabilityCommandSchema
|
|
30755
|
+
...bookingCommandSchemaOptions
|
|
30395
30756
|
]);
|
|
30396
30757
|
|
|
30397
30758
|
//#endregion
|
|
@@ -30513,6 +30874,7 @@ const commandScopes = [
|
|
|
30513
30874
|
"order",
|
|
30514
30875
|
"booking_settings",
|
|
30515
30876
|
"appointment_service",
|
|
30877
|
+
"appointment_service_category",
|
|
30516
30878
|
"appointment_resource",
|
|
30517
30879
|
"appointment_availability",
|
|
30518
30880
|
"publish"
|
|
@@ -31141,6 +31503,19 @@ const siteCommandMetadata = {
|
|
|
31141
31503
|
capability: "commerce.orders.write",
|
|
31142
31504
|
support: "supported"
|
|
31143
31505
|
},
|
|
31506
|
+
upsertAppointmentServiceCategory: {
|
|
31507
|
+
scope: "appointment_service_category",
|
|
31508
|
+
risk: "medium",
|
|
31509
|
+
writeSemantics: "upsert",
|
|
31510
|
+
lifecycleIntent: "mutation",
|
|
31511
|
+
idempotencyStrategy: "natural_key",
|
|
31512
|
+
conflictPolicy: "update_existing",
|
|
31513
|
+
previewability: "dry_run_only",
|
|
31514
|
+
allowedRuntimes: allRuntimes,
|
|
31515
|
+
intendedExposure: recipeExposure,
|
|
31516
|
+
capability: "bookings.appointment_service_categories.write",
|
|
31517
|
+
support: "supported"
|
|
31518
|
+
},
|
|
31144
31519
|
upsertAppointmentService: {
|
|
31145
31520
|
scope: "appointment_service",
|
|
31146
31521
|
risk: "medium",
|
|
@@ -31320,6 +31695,7 @@ const bookingRefCommandTypeValues = [
|
|
|
31320
31695
|
"seedEventRegistration",
|
|
31321
31696
|
"seedPassRedemption",
|
|
31322
31697
|
"seedPortalOrder",
|
|
31698
|
+
"upsertAppointmentServiceCategory",
|
|
31323
31699
|
"upsertAppointmentService",
|
|
31324
31700
|
"upsertBookableResource",
|
|
31325
31701
|
"assignAppointmentServiceResources",
|
|
@@ -31333,8 +31709,12 @@ function bookingCommandRefContributions(command) {
|
|
|
31333
31709
|
switch (command.type) {
|
|
31334
31710
|
case "upsertBookingMembershipProduct":
|
|
31335
31711
|
case "seedBookingCustomer":
|
|
31336
|
-
case "
|
|
31712
|
+
case "upsertAppointmentServiceCategory":
|
|
31337
31713
|
case "upsertBookableResource": return provided(command.ref);
|
|
31714
|
+
case "upsertAppointmentService": return providedWithRequirements(command.ref, command.input.categoryRef === undefined ? [] : [{
|
|
31715
|
+
ref: command.input.categoryRef,
|
|
31716
|
+
field: "input.categoryRef"
|
|
31717
|
+
}]);
|
|
31338
31718
|
case "upsertBookingPassProduct": return {
|
|
31339
31719
|
...provided(command.ref),
|
|
31340
31720
|
requires: command.input.appointmentScope?.mode === "selected_services" ? command.input.appointmentScope.serviceRefs.map((ref, index) => ({
|
|
@@ -31867,7 +32247,8 @@ function matchSiteCommand(command, match) {
|
|
|
31867
32247
|
case "seedEventRegistration": return match(command);
|
|
31868
32248
|
case "seedPassRedemption": return match(command);
|
|
31869
32249
|
case "seedPortalOrder": return match(command);
|
|
31870
|
-
case "
|
|
32250
|
+
case "upsertAppointmentServiceCategory":
|
|
32251
|
+
case "upsertAppointmentService":
|
|
31871
32252
|
case "upsertBookableResource": return match(command);
|
|
31872
32253
|
case "assignAppointmentServiceResources": return match(command);
|
|
31873
32254
|
case "configureAppointmentAvailability": return match(command);
|
|
@@ -32877,4 +33258,4 @@ function parseSdkEventRunUpsertInput(input, runIndex, options) {
|
|
|
32877
33258
|
}
|
|
32878
33259
|
|
|
32879
33260
|
//#endregion
|
|
32880
|
-
export {
|
|
33261
|
+
export { resolveContextualButtonRole as $, footerModeSchema as $n, getComponentBorderWidthPx as $t, boundaryLayout as A, surfaceToneFromForegroundToken as An, headerVariantValues as At, require_jsx_runtime as B, oklchToHexGamut as Bn, defineBlockDesignCapability as Bt, mergeHeaderNavTypographyPreference as C, borderColorStyle as Cn, BREAKPOINT_SM as Ct, GRADIENT_PRESET_IDS as D, textColorStyle as Dn, MQ_SM_DOWN as Dt, gradientToCss as E, rgbColorValue as En, MQ_MD_DOWN as Et, transitionCatalogueEntries as F, defaultThemeTokens as Fn, pageDesignEditorBackgroundOverrideOwner as Ft, PUBLIC_BUTTON_ROLES as G, generateShadowValue$1 as Gn, featureCardCompositionTreatmentValues as Gt, pickShadeTowardBackground as H, surfaceForegroundDeclarations as Hn, defineNoBlockDesignCapability as Ht, backgroundAppearanceColorTokenNames as I, ORDINARY_TEXT_MIN_CONTRAST_RATIO as In, stripStaleTransitionStyleGroup as It, resolvedButtonColourDeclarations as J, normalizeCardRole as Jn, makeBoundaryId as Jt, generateButtonCss as K, cardRoleSchema as Kn, headingDecorationColorTokenValues as Kt, backgroundAppearanceQuickColorTokenNames as L, contrastRatio as Ln, asAppearancePresetId as Lt, sectionFactsForContent as M, isOnColorBackgroundCandidateToken as Mn, resolveOnColorForThemeToken as Mt, boundaryRuntimeMetricsForDecorativeTransition as N, onColorTokenName as Nn, resolveThemeColorReferenceValue as Nt, getGradientPreset as O, textColorValue as On, MQ_SM_UP as Ot, anglePolygonCss as P, buildThemeTokens as Pn, resolveTokenOrCssColorValue as Pt, deriveButtonSurfaceContext as Q, persistableMediaSchema as Qn, visibleHeadingDecorationFamilyValues as Qt, parseBackgroundAppearanceColorToken as R, featuresFromHex as Rn, asDesignBlockId as Rt, eventBookingOfferIntentSchema as S, backgroundColorStyle as Sn, BREAKPOINT_MD as St, getCuratedSiteStyle as T, mergeStyles as Tn, MQ_LG_UP as Tt, generateCssVars as U, surfaceForegroundStyle as Un, eventListTreatmentValues as Ut, require_react as V, DEFAULT_SURFACE_TEXT_COLOR as Vn, defineFrameCapability as Vt, buttonStyleSelectionSchema as W, surfaceForegroundValue as Wn, eyebrowTreatmentValues as Wt, contextualButtonSurfaceResetStyles as X, mediaSchema as Xn, testimonialsCompositionTreatmentValues as Xt, resolvedButtonFocusDeclarations as Y, mediaIdentifierSchema as Yn, offeringsPreviewCompositionTreatmentValues as Yt, contextualButtonSurfaceStyles as Z, mediaTypeDiscriminants as Zn, tileTreatmentValues as Zt, entryIdentifierForCommand as _, ICON_SIZE_PX as _n, slugPart as _r, generateHeaderScrollTreatmentStyles as _t, classifySdkEventBookingOffer as a, NAV_LINK_PADDING_MAP as an, createBlocksRef as ar, themeButtonExtraClassesWithTrailingIcon as at, pagePathForCommand as b, generateCardCss as bn, renderHeaderPaintTargetRules as bt, stableStringify as c, FONT_WEIGHT_MAP$1 as cn, createEventCategoryRef as cr, parseThemeForPersistence as ct, mapEventCommandContent as d, LABEL_FONT_SIZE_MAP as dn, createFormRef as dr, generateShadowValue as dt, getComponentShadowVar as en, VARIANT_ROLES as er, generateDefaultButtonSystem as et, evaluateSiteCommandBatchExposure as f, ACCORDION_OPEN_ACCENT_THICKNESS as fn, createNavigationRef as fr, expandPalette as ft, blockOrderIdentifiersForCommand as g, ICON_CONFIG as gn, refSlug as gr, boxBackgroundSchema as gt, blockIdentifierForCommand as h, ACCORDION_TRIGGER_LETTER_SPACING as hn, createVenueRef as hr, boxBackgroundOverlaySchema as ht, classifySdkEventSchedule as i, NAV_LINK_LETTER_SPACING_MAP as in, createBlockRef as ir, parseThemeButtonVariantId as it, composeBoundary as j, resolveSurfaceForeground as jn, isCssColorLiteral as jt, parseGradientPresetId as k, selectLogoVariant as kn, MQ_TABLET_ONLY as kt, createDryRunReport as l, INPUT_FONT_SIZE_MAP as ln, createEventSeriesRef as lr, compileButtonColourStates as lt, getSiteCommandMetadata as m, ACCORDION_TRIGGER_FONT_SCALE as mn, createSiteCommandSiteRef as mr, themeSchema as mt, sdkEventOccurrenceInputSchema as n, parseCustomCssRules as nn, unsafeAsOpaqueButtonColourToken as nr, generateBaseInteractiveCSS as nt, venueManagementFields as o, NAV_LINK_PADDING_X_MAP as on, createCommandRef as or, themeButtonSizeClassName as ot, evaluateSiteCommandExposure as p, ACCORDION_SPACING_MAP as pn, createPageRef as pr, getTextColorForBackground as pt, RESOLVED_BUTTON_DISABLED_DECLARATIONS as q, cardVariantRoleValues as qn, introCompositionTreatmentValues as qt, sdkEventUpsertOptionalFieldSchemas as r, NAV_LINK_BORDER_RADIUS_MAP as rn, parseBlockColorToken as rr, generateInteractiveChildInheritanceCSS as rt, sortRecord as s, NAV_LINK_TEXT_SIZE_MAP as sn, createContentEntryRef as sr, themeButtonVariantClassNames as st, classifySdkEventTiming as t, parseBlockCustomCssRules as tn, buttonVariantIdSchema as tr, generateEffectsCSS as tt, parseAndPlanCommandBatchForTypes as u, INPUT_SPACING_MAP as un, createFooterRef as ur, formatButtonColourContractError as ut, pageIdentifierForBlockCommand as v, generateCardCoreCss as vn, __toESM as vr, generateMobileOverlayBackdropFilterFix as vt, readHeaderNavFontSizePreference as w, cssVarValue as wn, BREAKPOINT_XL as wt, hasConfiguredBookingVertical as x, TokenResolver as xn, BREAKPOINT_LG as xt, pageIdentifierForCommand as y, getDefaultCardVariants as yn, getHeaderPaintTargets as yt, defineBlockDesignMetadata as z, hexToRgb as zn, assertNever$1 as zt };
|