From e41fba7a84f327559f24604d3a8a3cf152e70574 Mon Sep 17 00:00:00 2001 From: coltondemetriou Date: Tue, 9 Dec 2025 13:03:12 -0500 Subject: [PATCH 1/3] mem fix wip --- .../src/utils/VisualEditorProvider.tsx | 5 +- .../visual-editor/src/utils/clearPuckCache.ts | 62 ++++++++ packages/visual-editor/src/utils/index.ts | 1 + .../src/utils/resolveComponentData.tsx | 89 ++++++++--- .../src/utils/resolveYextEntityField.ts | 144 ++++++++++++------ .../src/utils/schema/resolveSchema.ts | 125 ++++++++++----- .../src/vite-plugin/templates/directory.tsx | 6 + .../src/vite-plugin/templates/locator.tsx | 6 + .../src/vite-plugin/templates/main.tsx | 6 + 9 files changed, 336 insertions(+), 108 deletions(-) create mode 100644 packages/visual-editor/src/utils/clearPuckCache.ts diff --git a/packages/visual-editor/src/utils/VisualEditorProvider.tsx b/packages/visual-editor/src/utils/VisualEditorProvider.tsx index 65359f785..29c965bc3 100644 --- a/packages/visual-editor/src/utils/VisualEditorProvider.tsx +++ b/packages/visual-editor/src/utils/VisualEditorProvider.tsx @@ -32,7 +32,10 @@ const VisualEditorProvider = >({ tailwindConfig, children, }: VisualEditorProviderProps) => { - const queryClient = new QueryClient(); + // Use useMemo to prevent creating a new QueryClient on every render + // QueryClient maintains internal caches, so creating new instances unnecessarily + // could lead to memory accumulation + const queryClient = React.useMemo(() => new QueryClient(), []); const normalizedTemplateProps = React.useMemo( () => normalizeLocalesInObject(templateProps), [templateProps] diff --git a/packages/visual-editor/src/utils/clearPuckCache.ts b/packages/visual-editor/src/utils/clearPuckCache.ts new file mode 100644 index 000000000..c87852869 --- /dev/null +++ b/packages/visual-editor/src/utils/clearPuckCache.ts @@ -0,0 +1,62 @@ +/** + * Clears Puck's internal cache to prevent memory leaks when processing many pages. + * + * Puck's resolveComponentData maintains a module-level cache that stores resolved + * data per component ID. This cache never gets cleared, causing memory to accumulate + * when processing many unique pages. This function clears that cache. + * + * The cache is exported from @measured/puck's resolve-component-data module. + * We access it via Node.js require.cache to clear it after each page processing. + */ +export function clearPuckCache(): void { + try { + // Access Puck's module from Node.js require cache + // This works because the plugin runs in Node.js during build time + const puckPath = require.resolve("@measured/puck"); + const puckModule = require.cache[puckPath]; + + if (!puckModule) { + return; + } + + // Try to find the cache in the module exports + // The cache is in the resolve-component-data submodule + const exports = puckModule.exports; + + // Check if cache is directly on exports + if (exports?.cache?.lastChange) { + exports.cache.lastChange = {}; + return; + } + + // Try to access via internal module path + // Puck's structure: @measured/puck/lib/resolve-component-data + try { + const resolveComponentDataPath = require.resolve( + "@measured/puck/lib/resolve-component-data" + ); + const resolveModule = require.cache[resolveComponentDataPath]; + if (resolveModule?.exports?.cache?.lastChange) { + resolveModule.exports.cache.lastChange = {}; + return; + } + } catch { + // Module path might be different, continue to next attempt + } + + // Last resort: search through all cached modules for the cache object + if (typeof require.cache === "object") { + for (const [modulePath, module] of Object.entries(require.cache)) { + if (modulePath.includes("puck") && module?.exports?.cache?.lastChange) { + module.exports.cache.lastChange = {}; + return; + } + } + } + } catch (_error) { + // Silently fail - this is a best-effort cleanup + // If we can't clear the cache, it's not a critical error + // The alternative would be to use "force" trigger which bypasses cache + // but that would hurt performance + } +} diff --git a/packages/visual-editor/src/utils/index.ts b/packages/visual-editor/src/utils/index.ts index 88a543bbb..e4a2e940f 100644 --- a/packages/visual-editor/src/utils/index.ts +++ b/packages/visual-editor/src/utils/index.ts @@ -17,6 +17,7 @@ export { } from "./migrate.ts"; export { resolveComponentData } from "./resolveComponentData.tsx"; export { resolveYextEntityField } from "./resolveYextEntityField.ts"; +export { clearPuckCache } from "./clearPuckCache.ts"; export { resolveUrlTemplateOfChild, resolvePageSetUrlTemplate, diff --git a/packages/visual-editor/src/utils/resolveComponentData.tsx b/packages/visual-editor/src/utils/resolveComponentData.tsx index 2c0498f54..3a1598ba8 100644 --- a/packages/visual-editor/src/utils/resolveComponentData.tsx +++ b/packages/visual-editor/src/utils/resolveComponentData.tsx @@ -101,11 +101,26 @@ export function resolveComponentData( /** * Recursively traverses a value and resolves any translatable types * (TranslatableString, TranslatableRichText) to their final form. + * @param value The value to resolve. + * @param locale The locale to use for resolution. + * @param visited WeakSet to track visited objects and prevent circular reference infinite recursion. + * @param depth Current recursion depth to prevent stack overflow from very deep structures. */ const resolveTranslatableType = ( value: any, - locale: string + locale: string, + visited: WeakSet = new WeakSet(), + depth: number = 0 ): any | string | React.ReactElement => { + // Safety limit: prevent stack overflow from extremely deep structures + const MAX_DEPTH = 100; + if (depth > MAX_DEPTH) { + console.warn( + "[@yext/visual-editor] Maximum recursion depth exceeded in resolveTranslatableType. Returning original value." + ); + return value; + } + // If the value is already a React element, return it immediately. if (React.isValidElement(value)) { return value; @@ -115,36 +130,62 @@ const resolveTranslatableType = ( return value; } - // Handle a direct RichText object that is not inside a Translatable object. - if (isRichText(value)) { - return toStringOrElement(value); + // Check for circular references + if (visited.has(value)) { + console.warn( + "[@yext/visual-editor] Circular reference detected in resolveTranslatableType. Returning original value." + ); + return value; } - // Handle TranslatableString - if (value.hasLocalizedValue === "true" && typeof value[locale] === "string") { - return value[locale]; - } + // Mark this object as visited + visited.add(value); - // Handle TranslatableRichText - if (value.hasLocalizedValue === "true" && isRichText(value[locale])) { - return toStringOrElement(value[locale]); - } + try { + // Handle a direct RichText object that is not inside a Translatable object. + if (isRichText(value)) { + return toStringOrElement(value); + } - // Handle missing translation - if (value.hasLocalizedValue === "true" && !value[locale]) { - return ""; - } + // Handle TranslatableString + if ( + value.hasLocalizedValue === "true" && + typeof value[locale] === "string" + ) { + return value[locale]; + } - if (Array.isArray(value)) { - return value.map((item) => resolveTranslatableType(item, locale)); - } + // Handle TranslatableRichText + if (value.hasLocalizedValue === "true" && isRichText(value[locale])) { + return toStringOrElement(value[locale]); + } - // If it's an object, recursively resolve each property. - const newValue: { [key: string]: any } = {}; - for (const key in value) { - newValue[key] = resolveTranslatableType(value[key], locale); + // Handle missing translation + if (value.hasLocalizedValue === "true" && !value[locale]) { + return ""; + } + + if (Array.isArray(value)) { + return value.map((item) => + resolveTranslatableType(item, locale, visited, depth + 1) + ); + } + + // If it's an object, recursively resolve each property. + const newValue: { [key: string]: any } = {}; + for (const key in value) { + newValue[key] = resolveTranslatableType( + value[key], + locale, + visited, + depth + 1 + ); + } + return newValue; + } finally { + // Note: We don't remove from visited here because we want to detect + // circular references even if the same object appears at different depths } - return newValue; }; function isRichText(value: unknown): value is RichText { diff --git a/packages/visual-editor/src/utils/resolveYextEntityField.ts b/packages/visual-editor/src/utils/resolveYextEntityField.ts index 9296525a9..a94a2a016 100644 --- a/packages/visual-editor/src/utils/resolveYextEntityField.ts +++ b/packages/visual-editor/src/utils/resolveYextEntityField.ts @@ -1,6 +1,14 @@ import { YextEntityField } from "../editor/YextEntityFieldSelector.tsx"; -export const embeddedFieldRegex = /\[\[([a-zA-Z0-9._]+)\]\]/g; +// Use a function to create a fresh regex instance each time to avoid any potential +// state retention issues with the global flag, even though String.replace() should be safe +const getEmbeddedFieldRegex = () => /\[\[([a-zA-Z0-9._]+)\]\]/g; + +// Export the regex pattern source for use in other files that need to create their own instances +export const embeddedFieldRegexSource = /\[\[([a-zA-Z0-9._]+)\]\]/g.source; + +// For backward compatibility, export a regex instance (though it should be recreated per use) +export const embeddedFieldRegex = getEmbeddedFieldRegex(); export const resolveYextEntityField = ( streamDocument: any, @@ -47,7 +55,9 @@ export const resolveEmbeddedFieldsInString = ( streamDocument: any, locale?: string ): string => { - return stringToResolve.replace(embeddedFieldRegex, (match, fieldName) => { + // Create a fresh regex instance to avoid any potential state retention + const regex = getEmbeddedFieldRegex(); + return stringToResolve.replace(regex, (match, fieldName) => { const trimmedFieldName = fieldName.trim(); if (!trimmedFieldName) { return ""; @@ -85,13 +95,28 @@ export const resolveEmbeddedFieldsInString = ( * and resolves any embedded entity fields within them. * @param data The data to traverse (object, array, or primitive). * @param streamDocument The entity document to use for resolving fields. + * @param locale The locale to use for resolution. + * @param visited WeakSet to track visited objects and prevent circular reference infinite recursion. + * @param depth Current recursion depth to prevent stack overflow from very deep structures. * @returns The data with embedded fields resolved. */ export const resolveEmbeddedFieldsRecursively = ( data: any, streamDocument: any, - locale?: string + locale?: string, + visited: WeakSet = new WeakSet(), + depth: number = 0 ): any => { + // Safety limit: prevent stack overflow from extremely deep structures + // This is a defensive measure - normal data shouldn't exceed this depth + const MAX_DEPTH = 100; + if (depth > MAX_DEPTH) { + console.warn( + "[@yext/visual-editor] Maximum recursion depth exceeded in resolveEmbeddedFieldsRecursively. Returning original data." + ); + return data; + } + // If data is a string, resolve any embedded fields within it. if (typeof data === "string") { return resolveEmbeddedFieldsInString(data, streamDocument, locale); @@ -102,59 +127,84 @@ export const resolveEmbeddedFieldsRecursively = ( return data; } - // Handle arrays by recursively calling this function on each item. - if (Array.isArray(data)) { - return data.map((item) => - resolveEmbeddedFieldsRecursively(item, streamDocument, locale) + // Check for circular references - if we've seen this object before, return it as-is + // to prevent infinite recursion + if (visited.has(data)) { + console.warn( + "[@yext/visual-editor] Circular reference detected in resolveEmbeddedFieldsRecursively. Returning original data." ); + return data; } - // First, check if the object itself is a translatable shape that needs resolution. - if (data.hasLocalizedValue === "true") { - if (locale && data[locale]) { - // Handle TranslatableString - if (typeof data[locale] === "string") { - const resolvedString = resolveEmbeddedFieldsInString( - data[locale], - streamDocument, - locale - ); - return { ...data, [locale]: resolvedString }; - } + // Mark this object as visited + visited.add(data); - // Handle TranslatableRichText - if ( - typeof data[locale] === "object" && - data[locale] !== null && - typeof data[locale].html === "string" - ) { - const resolvedHtml = resolveEmbeddedFieldsInString( - data[locale].html, + try { + // Handle arrays by recursively calling this function on each item. + if (Array.isArray(data)) { + return data.map((item) => + resolveEmbeddedFieldsRecursively( + item, streamDocument, - locale - ); - return { - ...data, - [locale]: { ...data[locale], html: resolvedHtml }, - }; + locale, + visited, + depth + 1 + ) + ); + } + + // First, check if the object itself is a translatable shape that needs resolution. + if (data.hasLocalizedValue === "true") { + if (locale && data[locale]) { + // Handle TranslatableString + if (typeof data[locale] === "string") { + const resolvedString = resolveEmbeddedFieldsInString( + data[locale], + streamDocument, + locale + ); + return { ...data, [locale]: resolvedString }; + } + + // Handle TranslatableRichText + if ( + typeof data[locale] === "object" && + data[locale] !== null && + typeof data[locale].html === "string" + ) { + const resolvedHtml = resolveEmbeddedFieldsInString( + data[locale].html, + streamDocument, + locale + ); + return { + ...data, + [locale]: { ...data[locale], html: resolvedHtml }, + }; + } + } else { + // If it's a translatable string but missing the locale, + // we return an empty string. + return ""; } - } else { - // If it's a translatable string but missing the locale, - // we return an empty string. - return ""; } - } - // If it's a generic object, recursively call this function on all its values. - const newData: { [key: string]: any } = {}; - for (const key in data) { - newData[key] = resolveEmbeddedFieldsRecursively( - data[key], - streamDocument, - locale - ); + // If it's a generic object, recursively call this function on all its values. + const newData: { [key: string]: any } = {}; + for (const key in data) { + newData[key] = resolveEmbeddedFieldsRecursively( + data[key], + streamDocument, + locale, + visited, + depth + 1 + ); + } + return newData; + } finally { + // Note: We don't remove from visited here because we want to detect + // circular references even if the same object appears at different depths } - return newData; }; export const findField = ( diff --git a/packages/visual-editor/src/utils/schema/resolveSchema.ts b/packages/visual-editor/src/utils/schema/resolveSchema.ts index 045b28f7d..0a191ea54 100644 --- a/packages/visual-editor/src/utils/schema/resolveSchema.ts +++ b/packages/visual-editor/src/utils/schema/resolveSchema.ts @@ -1,6 +1,6 @@ import { OpeningHoursSchema, PhotoGallerySchema } from "@yext/pages-components"; import { StreamDocument } from "../applyTheme"; -import { embeddedFieldRegex, findField } from "../resolveYextEntityField"; +import { embeddedFieldRegexSource, findField } from "../resolveYextEntityField"; import { removeEmptyValues } from "./helpers"; import { resolvePageSetUrlTemplate, @@ -8,8 +8,8 @@ import { } from "../resolveUrlTemplate"; import { mergeMeta } from "../mergeMeta"; -// Recompile the embedded field regex to support matching -const EMBEDDED_FIELD_REGEX = new RegExp(embeddedFieldRegex.source); +// Create a fresh regex instance for each use to avoid any potential state retention +const getEmbeddedFieldRegex = () => new RegExp(embeddedFieldRegexSource, "g"); const stringifyResolvedField = (fieldValue: any): string => { if (fieldValue === undefined || fieldValue === null) { @@ -41,7 +41,8 @@ export const resolveSchemaString = ( streamDocument: StreamDocument, schema: string ): string => { - return schema.replace(embeddedFieldRegex, (_, fieldName) => { + const regex = getEmbeddedFieldRegex(); + return schema.replace(regex, (_, fieldName) => { const resolvedValue = findField(streamDocument, fieldName); if (resolvedValue === undefined || resolvedValue === null) { @@ -63,7 +64,21 @@ export const resolveSchemaJson = ( return removeEmptyValues(resolvedValues); }; -const resolveNode = (streamDocument: StreamDocument, node: any): any => { +const resolveNode = ( + streamDocument: StreamDocument, + node: any, + visited: WeakSet = new WeakSet(), + depth: number = 0 +): any => { + // Safety limit: prevent stack overflow from extremely deep structures + const MAX_DEPTH = 100; + if (depth > MAX_DEPTH) { + console.warn( + "[@yext/visual-editor] Maximum recursion depth exceeded in resolveNode. Returning original node." + ); + return node; + } + // Case 1: Handle primitives other than objects/arrays if (node === null || typeof node !== "object") { // Return numbers, booleans, undefined, and null directly. @@ -74,29 +89,63 @@ const resolveNode = (streamDocument: StreamDocument, node: any): any => { return node; } - // Case 2: Handle Arrays - if (Array.isArray(node)) { - // Recursively resolve each item in the array - return node.map((child) => resolveNode(streamDocument, child)); + // Check for circular references + if (visited.has(node)) { + console.warn( + "[@yext/visual-editor] Circular reference detected in resolveNode. Returning original node." + ); + return node; } - // Case 3: Handle Objects - const newSchema: Record = {}; - for (const key in node) { - if (Object.prototype.hasOwnProperty.call(node, key)) { - if (node[key] === "[[dm_directoryChildren]]") { - // handle directory children - newSchema[key] = resolveDirectoryChildren(streamDocument, node[key]); - } else if (specialCases.includes(key)) { - // Handle keys with special formatting - newSchema[key] = resolveSpecialCases(streamDocument, key, node[key]); - } else { - // Otherwise, recursively resolve each property in the object - newSchema[key] = resolveNode(streamDocument, node[key]); + // Mark this object as visited + visited.add(node); + + try { + // Case 2: Handle Arrays + if (Array.isArray(node)) { + // Recursively resolve each item in the array + return node.map((child) => + resolveNode(streamDocument, child, visited, depth + 1) + ); + } + + // Case 3: Handle Objects + const newSchema: Record = {}; + for (const key in node) { + if (Object.prototype.hasOwnProperty.call(node, key)) { + if (node[key] === "[[dm_directoryChildren]]") { + // handle directory children + newSchema[key] = resolveDirectoryChildren( + streamDocument, + node[key], + visited, + depth + 1 + ); + } else if (specialCases.includes(key)) { + // Handle keys with special formatting + newSchema[key] = resolveSpecialCases( + streamDocument, + key, + node[key], + visited, + depth + 1 + ); + } else { + // Otherwise, recursively resolve each property in the object + newSchema[key] = resolveNode( + streamDocument, + node[key], + visited, + depth + 1 + ); + } } } + return newSchema; + } finally { + // Note: We don't remove from visited here because we want to detect + // circular references even if the same object appears at different depths } - return newSchema; }; const specialCases = ["openingHours", "image", "hasOfferCatalog"]; @@ -104,15 +153,17 @@ const specialCases = ["openingHours", "image", "hasOfferCatalog"]; const resolveSpecialCases = ( streamDocument: StreamDocument, key: string, - value: any + value: any, + visited: WeakSet = new WeakSet(), + depth: number = 0 ): any => { if (typeof value !== "string") { - return resolveNode(streamDocument, value); + return resolveNode(streamDocument, value, visited, depth); } - const fieldName = value.match(EMBEDDED_FIELD_REGEX)?.[1]; + const fieldName = value.match(getEmbeddedFieldRegex())?.[1]; if (!fieldName) { - return resolveNode(streamDocument, value); + return resolveNode(streamDocument, value, visited, depth); } const resolvedValue = findField(streamDocument, fieldName) as any; @@ -122,7 +173,7 @@ const resolveSpecialCases = ( const hoursSchema = OpeningHoursSchema(resolvedValue); if (Object.keys(hoursSchema).length === 0) { - return resolveNode(streamDocument, value); + return resolveNode(streamDocument, value, visited, depth); } return hoursSchema.openingHours; @@ -131,14 +182,14 @@ const resolveSpecialCases = ( const gallerySchema = PhotoGallerySchema(resolvedValue); if (!gallerySchema?.image?.length) { - return resolveNode(streamDocument, value); + return resolveNode(streamDocument, value, visited, depth); } return gallerySchema.image; } case "hasOfferCatalog": { if (!Array.isArray(resolvedValue) || resolvedValue.length === 0) { - return resolveNode(streamDocument, value); + return resolveNode(streamDocument, value, visited, depth); } return { @@ -153,27 +204,29 @@ const resolveSpecialCases = ( }; } default: { - return resolveNode(streamDocument, value); + return resolveNode(streamDocument, value, visited, depth); } } }; const resolveDirectoryChildren = ( streamDocument: StreamDocument, - value: any + value: any, + visited: WeakSet = new WeakSet(), + depth: number = 0 ): any => { if (typeof value !== "string") { - return resolveNode(streamDocument, value); + return resolveNode(streamDocument, value, visited, depth); } - const fieldName = value.match(EMBEDDED_FIELD_REGEX)?.[1]; + const fieldName = value.match(getEmbeddedFieldRegex())?.[1]; if (!fieldName) { - return resolveNode(streamDocument, value); + return resolveNode(streamDocument, value, visited, depth); } const resolvedValue = findField(streamDocument, fieldName) as any; if (!Array.isArray(resolvedValue) || resolvedValue.length === 0) { - return resolveNode(streamDocument, value); + return resolveNode(streamDocument, value, visited, depth); } return resolvedValue.map((child: any, index: number) => { diff --git a/packages/visual-editor/src/vite-plugin/templates/directory.tsx b/packages/visual-editor/src/vite-plugin/templates/directory.tsx index 5ec204c9d..3f8b9f5a9 100644 --- a/packages/visual-editor/src/vite-plugin/templates/directory.tsx +++ b/packages/visual-editor/src/vite-plugin/templates/directory.tsx @@ -25,6 +25,7 @@ import { directoryConfig, getSchema, getCanonicalUrl, + clearPuckCache, } from "@yext/visual-editor"; import { AnalyticsProvider, SchemaWrapper } from "@yext/pages-components"; @@ -115,6 +116,11 @@ export const transformProps: TransformProps = async (props) => { streamDocument: document, }); + // Clear Puck's internal cache after resolving data to prevent memory leaks + // when processing many pages. The cache stores resolved data per component ID + // and never gets cleared, causing memory to accumulate across page invocations. + clearPuckCache(); + return { ...props, data: updatedData }; }; diff --git a/packages/visual-editor/src/vite-plugin/templates/locator.tsx b/packages/visual-editor/src/vite-plugin/templates/locator.tsx index 481093d81..5751b53d1 100644 --- a/packages/visual-editor/src/vite-plugin/templates/locator.tsx +++ b/packages/visual-editor/src/vite-plugin/templates/locator.tsx @@ -25,6 +25,7 @@ import { getCanonicalUrl, migrate, migrationRegistry, + clearPuckCache, } from "@yext/visual-editor"; import { AnalyticsProvider, SchemaWrapper } from "@yext/pages-components"; import mapboxPackageJson from "mapbox-gl/package.json"; @@ -116,6 +117,11 @@ export const transformProps: TransformProps = async (props) => { streamDocument: document, }); + // Clear Puck's internal cache after resolving data to prevent memory leaks + // when processing many pages. The cache stores resolved data per component ID + // and never gets cleared, causing memory to accumulate across page invocations. + clearPuckCache(); + return { ...props, data: updatedData }; }; diff --git a/packages/visual-editor/src/vite-plugin/templates/main.tsx b/packages/visual-editor/src/vite-plugin/templates/main.tsx index e474d9ae0..1bb754dbc 100644 --- a/packages/visual-editor/src/vite-plugin/templates/main.tsx +++ b/packages/visual-editor/src/vite-plugin/templates/main.tsx @@ -26,6 +26,7 @@ import { mainConfig, getSchema, getCanonicalUrl, + clearPuckCache, } from "@yext/visual-editor"; import { AnalyticsProvider, SchemaWrapper } from "@yext/pages-components"; @@ -112,6 +113,11 @@ export const transformProps: TransformProps = async (props) => { streamDocument: document, }); + // Clear Puck's internal cache after resolving data to prevent memory leaks + // when processing many pages. The cache stores resolved data per component ID + // and never gets cleared, causing memory to accumulate across page invocations. + clearPuckCache(); + return { ...props, data: updatedData }; }; From 3b13dd99805339d441435c70f2ac9bbef6ca5ab5 Mon Sep 17 00:00:00 2001 From: coltondemetriou Date: Tue, 9 Dec 2025 13:20:40 -0500 Subject: [PATCH 2/3] only clear cache --- .../src/utils/resolveComponentData.tsx | 89 +++-------- .../src/utils/resolveYextEntityField.ts | 144 ++++++------------ .../src/utils/schema/resolveSchema.ts | 125 +++++---------- 3 files changed, 107 insertions(+), 251 deletions(-) diff --git a/packages/visual-editor/src/utils/resolveComponentData.tsx b/packages/visual-editor/src/utils/resolveComponentData.tsx index 3a1598ba8..2c0498f54 100644 --- a/packages/visual-editor/src/utils/resolveComponentData.tsx +++ b/packages/visual-editor/src/utils/resolveComponentData.tsx @@ -101,26 +101,11 @@ export function resolveComponentData( /** * Recursively traverses a value and resolves any translatable types * (TranslatableString, TranslatableRichText) to their final form. - * @param value The value to resolve. - * @param locale The locale to use for resolution. - * @param visited WeakSet to track visited objects and prevent circular reference infinite recursion. - * @param depth Current recursion depth to prevent stack overflow from very deep structures. */ const resolveTranslatableType = ( value: any, - locale: string, - visited: WeakSet = new WeakSet(), - depth: number = 0 + locale: string ): any | string | React.ReactElement => { - // Safety limit: prevent stack overflow from extremely deep structures - const MAX_DEPTH = 100; - if (depth > MAX_DEPTH) { - console.warn( - "[@yext/visual-editor] Maximum recursion depth exceeded in resolveTranslatableType. Returning original value." - ); - return value; - } - // If the value is already a React element, return it immediately. if (React.isValidElement(value)) { return value; @@ -130,62 +115,36 @@ const resolveTranslatableType = ( return value; } - // Check for circular references - if (visited.has(value)) { - console.warn( - "[@yext/visual-editor] Circular reference detected in resolveTranslatableType. Returning original value." - ); - return value; + // Handle a direct RichText object that is not inside a Translatable object. + if (isRichText(value)) { + return toStringOrElement(value); } - // Mark this object as visited - visited.add(value); - - try { - // Handle a direct RichText object that is not inside a Translatable object. - if (isRichText(value)) { - return toStringOrElement(value); - } - - // Handle TranslatableString - if ( - value.hasLocalizedValue === "true" && - typeof value[locale] === "string" - ) { - return value[locale]; - } + // Handle TranslatableString + if (value.hasLocalizedValue === "true" && typeof value[locale] === "string") { + return value[locale]; + } - // Handle TranslatableRichText - if (value.hasLocalizedValue === "true" && isRichText(value[locale])) { - return toStringOrElement(value[locale]); - } + // Handle TranslatableRichText + if (value.hasLocalizedValue === "true" && isRichText(value[locale])) { + return toStringOrElement(value[locale]); + } - // Handle missing translation - if (value.hasLocalizedValue === "true" && !value[locale]) { - return ""; - } + // Handle missing translation + if (value.hasLocalizedValue === "true" && !value[locale]) { + return ""; + } - if (Array.isArray(value)) { - return value.map((item) => - resolveTranslatableType(item, locale, visited, depth + 1) - ); - } + if (Array.isArray(value)) { + return value.map((item) => resolveTranslatableType(item, locale)); + } - // If it's an object, recursively resolve each property. - const newValue: { [key: string]: any } = {}; - for (const key in value) { - newValue[key] = resolveTranslatableType( - value[key], - locale, - visited, - depth + 1 - ); - } - return newValue; - } finally { - // Note: We don't remove from visited here because we want to detect - // circular references even if the same object appears at different depths + // If it's an object, recursively resolve each property. + const newValue: { [key: string]: any } = {}; + for (const key in value) { + newValue[key] = resolveTranslatableType(value[key], locale); } + return newValue; }; function isRichText(value: unknown): value is RichText { diff --git a/packages/visual-editor/src/utils/resolveYextEntityField.ts b/packages/visual-editor/src/utils/resolveYextEntityField.ts index a94a2a016..9296525a9 100644 --- a/packages/visual-editor/src/utils/resolveYextEntityField.ts +++ b/packages/visual-editor/src/utils/resolveYextEntityField.ts @@ -1,14 +1,6 @@ import { YextEntityField } from "../editor/YextEntityFieldSelector.tsx"; -// Use a function to create a fresh regex instance each time to avoid any potential -// state retention issues with the global flag, even though String.replace() should be safe -const getEmbeddedFieldRegex = () => /\[\[([a-zA-Z0-9._]+)\]\]/g; - -// Export the regex pattern source for use in other files that need to create their own instances -export const embeddedFieldRegexSource = /\[\[([a-zA-Z0-9._]+)\]\]/g.source; - -// For backward compatibility, export a regex instance (though it should be recreated per use) -export const embeddedFieldRegex = getEmbeddedFieldRegex(); +export const embeddedFieldRegex = /\[\[([a-zA-Z0-9._]+)\]\]/g; export const resolveYextEntityField = ( streamDocument: any, @@ -55,9 +47,7 @@ export const resolveEmbeddedFieldsInString = ( streamDocument: any, locale?: string ): string => { - // Create a fresh regex instance to avoid any potential state retention - const regex = getEmbeddedFieldRegex(); - return stringToResolve.replace(regex, (match, fieldName) => { + return stringToResolve.replace(embeddedFieldRegex, (match, fieldName) => { const trimmedFieldName = fieldName.trim(); if (!trimmedFieldName) { return ""; @@ -95,28 +85,13 @@ export const resolveEmbeddedFieldsInString = ( * and resolves any embedded entity fields within them. * @param data The data to traverse (object, array, or primitive). * @param streamDocument The entity document to use for resolving fields. - * @param locale The locale to use for resolution. - * @param visited WeakSet to track visited objects and prevent circular reference infinite recursion. - * @param depth Current recursion depth to prevent stack overflow from very deep structures. * @returns The data with embedded fields resolved. */ export const resolveEmbeddedFieldsRecursively = ( data: any, streamDocument: any, - locale?: string, - visited: WeakSet = new WeakSet(), - depth: number = 0 + locale?: string ): any => { - // Safety limit: prevent stack overflow from extremely deep structures - // This is a defensive measure - normal data shouldn't exceed this depth - const MAX_DEPTH = 100; - if (depth > MAX_DEPTH) { - console.warn( - "[@yext/visual-editor] Maximum recursion depth exceeded in resolveEmbeddedFieldsRecursively. Returning original data." - ); - return data; - } - // If data is a string, resolve any embedded fields within it. if (typeof data === "string") { return resolveEmbeddedFieldsInString(data, streamDocument, locale); @@ -127,84 +102,59 @@ export const resolveEmbeddedFieldsRecursively = ( return data; } - // Check for circular references - if we've seen this object before, return it as-is - // to prevent infinite recursion - if (visited.has(data)) { - console.warn( - "[@yext/visual-editor] Circular reference detected in resolveEmbeddedFieldsRecursively. Returning original data." + // Handle arrays by recursively calling this function on each item. + if (Array.isArray(data)) { + return data.map((item) => + resolveEmbeddedFieldsRecursively(item, streamDocument, locale) ); - return data; } - // Mark this object as visited - visited.add(data); - - try { - // Handle arrays by recursively calling this function on each item. - if (Array.isArray(data)) { - return data.map((item) => - resolveEmbeddedFieldsRecursively( - item, + // First, check if the object itself is a translatable shape that needs resolution. + if (data.hasLocalizedValue === "true") { + if (locale && data[locale]) { + // Handle TranslatableString + if (typeof data[locale] === "string") { + const resolvedString = resolveEmbeddedFieldsInString( + data[locale], streamDocument, - locale, - visited, - depth + 1 - ) - ); - } + locale + ); + return { ...data, [locale]: resolvedString }; + } - // First, check if the object itself is a translatable shape that needs resolution. - if (data.hasLocalizedValue === "true") { - if (locale && data[locale]) { - // Handle TranslatableString - if (typeof data[locale] === "string") { - const resolvedString = resolveEmbeddedFieldsInString( - data[locale], - streamDocument, - locale - ); - return { ...data, [locale]: resolvedString }; - } - - // Handle TranslatableRichText - if ( - typeof data[locale] === "object" && - data[locale] !== null && - typeof data[locale].html === "string" - ) { - const resolvedHtml = resolveEmbeddedFieldsInString( - data[locale].html, - streamDocument, - locale - ); - return { - ...data, - [locale]: { ...data[locale], html: resolvedHtml }, - }; - } - } else { - // If it's a translatable string but missing the locale, - // we return an empty string. - return ""; + // Handle TranslatableRichText + if ( + typeof data[locale] === "object" && + data[locale] !== null && + typeof data[locale].html === "string" + ) { + const resolvedHtml = resolveEmbeddedFieldsInString( + data[locale].html, + streamDocument, + locale + ); + return { + ...data, + [locale]: { ...data[locale], html: resolvedHtml }, + }; } + } else { + // If it's a translatable string but missing the locale, + // we return an empty string. + return ""; } + } - // If it's a generic object, recursively call this function on all its values. - const newData: { [key: string]: any } = {}; - for (const key in data) { - newData[key] = resolveEmbeddedFieldsRecursively( - data[key], - streamDocument, - locale, - visited, - depth + 1 - ); - } - return newData; - } finally { - // Note: We don't remove from visited here because we want to detect - // circular references even if the same object appears at different depths + // If it's a generic object, recursively call this function on all its values. + const newData: { [key: string]: any } = {}; + for (const key in data) { + newData[key] = resolveEmbeddedFieldsRecursively( + data[key], + streamDocument, + locale + ); } + return newData; }; export const findField = ( diff --git a/packages/visual-editor/src/utils/schema/resolveSchema.ts b/packages/visual-editor/src/utils/schema/resolveSchema.ts index 0a191ea54..045b28f7d 100644 --- a/packages/visual-editor/src/utils/schema/resolveSchema.ts +++ b/packages/visual-editor/src/utils/schema/resolveSchema.ts @@ -1,6 +1,6 @@ import { OpeningHoursSchema, PhotoGallerySchema } from "@yext/pages-components"; import { StreamDocument } from "../applyTheme"; -import { embeddedFieldRegexSource, findField } from "../resolveYextEntityField"; +import { embeddedFieldRegex, findField } from "../resolveYextEntityField"; import { removeEmptyValues } from "./helpers"; import { resolvePageSetUrlTemplate, @@ -8,8 +8,8 @@ import { } from "../resolveUrlTemplate"; import { mergeMeta } from "../mergeMeta"; -// Create a fresh regex instance for each use to avoid any potential state retention -const getEmbeddedFieldRegex = () => new RegExp(embeddedFieldRegexSource, "g"); +// Recompile the embedded field regex to support matching +const EMBEDDED_FIELD_REGEX = new RegExp(embeddedFieldRegex.source); const stringifyResolvedField = (fieldValue: any): string => { if (fieldValue === undefined || fieldValue === null) { @@ -41,8 +41,7 @@ export const resolveSchemaString = ( streamDocument: StreamDocument, schema: string ): string => { - const regex = getEmbeddedFieldRegex(); - return schema.replace(regex, (_, fieldName) => { + return schema.replace(embeddedFieldRegex, (_, fieldName) => { const resolvedValue = findField(streamDocument, fieldName); if (resolvedValue === undefined || resolvedValue === null) { @@ -64,21 +63,7 @@ export const resolveSchemaJson = ( return removeEmptyValues(resolvedValues); }; -const resolveNode = ( - streamDocument: StreamDocument, - node: any, - visited: WeakSet = new WeakSet(), - depth: number = 0 -): any => { - // Safety limit: prevent stack overflow from extremely deep structures - const MAX_DEPTH = 100; - if (depth > MAX_DEPTH) { - console.warn( - "[@yext/visual-editor] Maximum recursion depth exceeded in resolveNode. Returning original node." - ); - return node; - } - +const resolveNode = (streamDocument: StreamDocument, node: any): any => { // Case 1: Handle primitives other than objects/arrays if (node === null || typeof node !== "object") { // Return numbers, booleans, undefined, and null directly. @@ -89,63 +74,29 @@ const resolveNode = ( return node; } - // Check for circular references - if (visited.has(node)) { - console.warn( - "[@yext/visual-editor] Circular reference detected in resolveNode. Returning original node." - ); - return node; + // Case 2: Handle Arrays + if (Array.isArray(node)) { + // Recursively resolve each item in the array + return node.map((child) => resolveNode(streamDocument, child)); } - // Mark this object as visited - visited.add(node); - - try { - // Case 2: Handle Arrays - if (Array.isArray(node)) { - // Recursively resolve each item in the array - return node.map((child) => - resolveNode(streamDocument, child, visited, depth + 1) - ); - } - - // Case 3: Handle Objects - const newSchema: Record = {}; - for (const key in node) { - if (Object.prototype.hasOwnProperty.call(node, key)) { - if (node[key] === "[[dm_directoryChildren]]") { - // handle directory children - newSchema[key] = resolveDirectoryChildren( - streamDocument, - node[key], - visited, - depth + 1 - ); - } else if (specialCases.includes(key)) { - // Handle keys with special formatting - newSchema[key] = resolveSpecialCases( - streamDocument, - key, - node[key], - visited, - depth + 1 - ); - } else { - // Otherwise, recursively resolve each property in the object - newSchema[key] = resolveNode( - streamDocument, - node[key], - visited, - depth + 1 - ); - } + // Case 3: Handle Objects + const newSchema: Record = {}; + for (const key in node) { + if (Object.prototype.hasOwnProperty.call(node, key)) { + if (node[key] === "[[dm_directoryChildren]]") { + // handle directory children + newSchema[key] = resolveDirectoryChildren(streamDocument, node[key]); + } else if (specialCases.includes(key)) { + // Handle keys with special formatting + newSchema[key] = resolveSpecialCases(streamDocument, key, node[key]); + } else { + // Otherwise, recursively resolve each property in the object + newSchema[key] = resolveNode(streamDocument, node[key]); } } - return newSchema; - } finally { - // Note: We don't remove from visited here because we want to detect - // circular references even if the same object appears at different depths } + return newSchema; }; const specialCases = ["openingHours", "image", "hasOfferCatalog"]; @@ -153,17 +104,15 @@ const specialCases = ["openingHours", "image", "hasOfferCatalog"]; const resolveSpecialCases = ( streamDocument: StreamDocument, key: string, - value: any, - visited: WeakSet = new WeakSet(), - depth: number = 0 + value: any ): any => { if (typeof value !== "string") { - return resolveNode(streamDocument, value, visited, depth); + return resolveNode(streamDocument, value); } - const fieldName = value.match(getEmbeddedFieldRegex())?.[1]; + const fieldName = value.match(EMBEDDED_FIELD_REGEX)?.[1]; if (!fieldName) { - return resolveNode(streamDocument, value, visited, depth); + return resolveNode(streamDocument, value); } const resolvedValue = findField(streamDocument, fieldName) as any; @@ -173,7 +122,7 @@ const resolveSpecialCases = ( const hoursSchema = OpeningHoursSchema(resolvedValue); if (Object.keys(hoursSchema).length === 0) { - return resolveNode(streamDocument, value, visited, depth); + return resolveNode(streamDocument, value); } return hoursSchema.openingHours; @@ -182,14 +131,14 @@ const resolveSpecialCases = ( const gallerySchema = PhotoGallerySchema(resolvedValue); if (!gallerySchema?.image?.length) { - return resolveNode(streamDocument, value, visited, depth); + return resolveNode(streamDocument, value); } return gallerySchema.image; } case "hasOfferCatalog": { if (!Array.isArray(resolvedValue) || resolvedValue.length === 0) { - return resolveNode(streamDocument, value, visited, depth); + return resolveNode(streamDocument, value); } return { @@ -204,29 +153,27 @@ const resolveSpecialCases = ( }; } default: { - return resolveNode(streamDocument, value, visited, depth); + return resolveNode(streamDocument, value); } } }; const resolveDirectoryChildren = ( streamDocument: StreamDocument, - value: any, - visited: WeakSet = new WeakSet(), - depth: number = 0 + value: any ): any => { if (typeof value !== "string") { - return resolveNode(streamDocument, value, visited, depth); + return resolveNode(streamDocument, value); } - const fieldName = value.match(getEmbeddedFieldRegex())?.[1]; + const fieldName = value.match(EMBEDDED_FIELD_REGEX)?.[1]; if (!fieldName) { - return resolveNode(streamDocument, value, visited, depth); + return resolveNode(streamDocument, value); } const resolvedValue = findField(streamDocument, fieldName) as any; if (!Array.isArray(resolvedValue) || resolvedValue.length === 0) { - return resolveNode(streamDocument, value, visited, depth); + return resolveNode(streamDocument, value); } return resolvedValue.map((child: any, index: number) => { From 6c6b4400bde7e1f5df159eeaa49eed5cc79c5a81 Mon Sep 17 00:00:00 2001 From: coltondemetriou Date: Mon, 15 Dec 2025 02:12:48 -0500 Subject: [PATCH 3/3] random stuff --- packages/visual-editor/package.json | 2 +- .../puck/constant-value-fields/TextList.tsx | 2 - .../visual-editor/src/utils/clearPuckCache.ts | 135 ++- packages/visual-editor/src/utils/index.ts | 3 +- .../src/vite-plugin/templates/directory.tsx | 22 +- .../src/vite-plugin/templates/locator.tsx | 22 +- pnpm-lock.yaml | 755 +++++++++++++++- starter/ensure-builds.sh | 35 + starter/large-template-layout.json | 457 ++++++++++ starter/package.json | 4 +- starter/test-renderer.mjs | 807 ++++++++++++++++++ 11 files changed, 2191 insertions(+), 53 deletions(-) create mode 100755 starter/ensure-builds.sh create mode 100644 starter/large-template-layout.json create mode 100644 starter/test-renderer.mjs diff --git a/packages/visual-editor/package.json b/packages/visual-editor/package.json index f44dbb5d2..8820cb047 100644 --- a/packages/visual-editor/package.json +++ b/packages/visual-editor/package.json @@ -61,7 +61,7 @@ "i18n:check-empty": "pnpm exec tsx scripts/checkEmptyTranslations.ts" }, "dependencies": { - "@measured/puck": "0.20.2", + "@measured/puck": "file:../../../puck/packages/core", "@microsoft/api-documenter": "^7.26.29", "@microsoft/api-extractor": "^7.52.8", "@microsoft/api-extractor-model": "^7.30.6", diff --git a/packages/visual-editor/src/internal/puck/constant-value-fields/TextList.tsx b/packages/visual-editor/src/internal/puck/constant-value-fields/TextList.tsx index 2dfd97c33..e29a4bb3f 100644 --- a/packages/visual-editor/src/internal/puck/constant-value-fields/TextList.tsx +++ b/packages/visual-editor/src/internal/puck/constant-value-fields/TextList.tsx @@ -75,7 +75,6 @@ export const TEXT_LIST_CONSTANT_CONFIG: CustomField = { removeItem(index)} - variant="secondary" title={pt("deleteItem", "Delete Item")} type="button" > @@ -181,7 +180,6 @@ export const TRANSLATABLE_TEXT_LIST_CONSTANT_CONFIG: CustomField<
removeItem(index)} - variant="secondary" title={pt("deleteItem", "Delete Item")} type="button" > diff --git a/packages/visual-editor/src/utils/clearPuckCache.ts b/packages/visual-editor/src/utils/clearPuckCache.ts index c87852869..0929829c2 100644 --- a/packages/visual-editor/src/utils/clearPuckCache.ts +++ b/packages/visual-editor/src/utils/clearPuckCache.ts @@ -8,55 +8,152 @@ * The cache is exported from @measured/puck's resolve-component-data module. * We access it via Node.js require.cache to clear it after each page processing. */ -export function clearPuckCache(): void { +/** + * Gets the current size of Puck's cache for logging purposes + */ +export function getPuckCacheSize(): number { try { - // Access Puck's module from Node.js require cache - // This works because the plugin runs in Node.js during build time const puckPath = require.resolve("@measured/puck"); const puckModule = require.cache[puckPath]; if (!puckModule) { - return; + return -1; } - // Try to find the cache in the module exports - // The cache is in the resolve-component-data submodule const exports = puckModule.exports; - // Check if cache is directly on exports if (exports?.cache?.lastChange) { - exports.cache.lastChange = {}; - return; + return Object.keys(exports.cache.lastChange).length; } - // Try to access via internal module path - // Puck's structure: @measured/puck/lib/resolve-component-data try { const resolveComponentDataPath = require.resolve( "@measured/puck/lib/resolve-component-data" ); const resolveModule = require.cache[resolveComponentDataPath]; if (resolveModule?.exports?.cache?.lastChange) { - resolveModule.exports.cache.lastChange = {}; - return; + return Object.keys(resolveModule.exports.cache.lastChange).length; } } catch { // Module path might be different, continue to next attempt } - // Last resort: search through all cached modules for the cache object if (typeof require.cache === "object") { for (const [modulePath, module] of Object.entries(require.cache)) { if (modulePath.includes("puck") && module?.exports?.cache?.lastChange) { - module.exports.cache.lastChange = {}; + return Object.keys(module.exports.cache.lastChange).length; + } + } + } + } catch { + // Silently fail + } + return -1; +} + +// Direct import for Deno/ESM compatibility +// This will work in both Node.js and Deno +// Note: We can't import this at build time as it's not exported, so we'll access it via require.cache at runtime +let puckCacheModule: { cache?: { lastChange?: Record } } | null = + null; + +export function clearPuckCache(): void { + const cacheSizeBefore = getPuckCacheSize(); + + try { + // Try direct module reference first (works if module was already loaded) + if (puckCacheModule?.cache?.lastChange) { + const sizeBefore = Object.keys(puckCacheModule.cache.lastChange).length; + puckCacheModule.cache.lastChange = {}; + console.log( + `[Puck Cache] clearPuckCache: Cleared ${sizeBefore} entries via direct module (was ${sizeBefore}, now 0)` + ); + return; + } + + // Node.js approach - Access Puck's module from require cache + // This works in Node.js but not in Deno + if ( + typeof require !== "undefined" && + typeof require.cache !== "undefined" + ) { + try { + const puckPath = require.resolve("@measured/puck"); + const puckModule = require.cache[puckPath]; + + if (!puckModule) { + if (cacheSizeBefore >= 0) { + console.log( + `[Puck Cache] clearPuckCache: Puck module not found in require cache` + ); + } + return; + } + + // Try to find the cache in the module exports + const exports = puckModule.exports; + + // Check if cache is directly on exports + if (exports?.cache?.lastChange) { + const sizeBefore = Object.keys(exports.cache.lastChange).length; + exports.cache.lastChange = {}; + console.log( + `[Puck Cache] clearPuckCache: Cleared ${sizeBefore} entries (was ${sizeBefore}, now 0)` + ); return; } + + // Try to access via internal module path + try { + const resolveComponentDataPath = require.resolve( + "@measured/puck/lib/resolve-component-data" + ); + const resolveModule = require.cache[resolveComponentDataPath]; + if (resolveModule?.exports?.cache?.lastChange) { + const sizeBefore = Object.keys( + resolveModule.exports.cache.lastChange + ).length; + resolveModule.exports.cache.lastChange = {}; + console.log( + `[Puck Cache] clearPuckCache: Cleared ${sizeBefore} entries (was ${sizeBefore}, now 0)` + ); + return; + } + } catch { + // Module path might be different, continue to next attempt + } + + // Last resort: search through all cached modules for the cache object + for (const [modulePath, module] of Object.entries(require.cache)) { + if ( + modulePath.includes("puck") && + module?.exports?.cache?.lastChange + ) { + const sizeBefore = Object.keys( + module.exports.cache.lastChange + ).length; + module.exports.cache.lastChange = {}; + console.log( + `[Puck Cache] clearPuckCache: Cleared ${sizeBefore} entries via search (was ${sizeBefore}, now 0)` + ); + return; + } + } + } catch { + // require not available or failed } } + + if (cacheSizeBefore >= 0) { + console.log( + `[Puck Cache] clearPuckCache: Cache not found (size was ${cacheSizeBefore})` + ); + } } catch (_error) { - // Silently fail - this is a best-effort cleanup - // If we can't clear the cache, it's not a critical error - // The alternative would be to use "force" trigger which bypasses cache - // but that would hurt performance + // Log error for debugging + console.error( + `[Puck Cache] clearPuckCache: Error clearing cache (size before: ${cacheSizeBefore}):`, + _error + ); } } diff --git a/packages/visual-editor/src/utils/index.ts b/packages/visual-editor/src/utils/index.ts index e4a2e940f..67f6d6744 100644 --- a/packages/visual-editor/src/utils/index.ts +++ b/packages/visual-editor/src/utils/index.ts @@ -17,7 +17,8 @@ export { } from "./migrate.ts"; export { resolveComponentData } from "./resolveComponentData.tsx"; export { resolveYextEntityField } from "./resolveYextEntityField.ts"; -export { clearPuckCache } from "./clearPuckCache.ts"; +// export { clearPuckCache, getPuckCacheSize } from "./clearPuckCache.ts"; +// export { clearPuckCacheAsync } from "./clearPuckCacheAsync.ts"; export { resolveUrlTemplateOfChild, resolvePageSetUrlTemplate, diff --git a/packages/visual-editor/src/vite-plugin/templates/directory.tsx b/packages/visual-editor/src/vite-plugin/templates/directory.tsx index 3f8b9f5a9..e3eb4c751 100644 --- a/packages/visual-editor/src/vite-plugin/templates/directory.tsx +++ b/packages/visual-editor/src/vite-plugin/templates/directory.tsx @@ -25,7 +25,9 @@ import { directoryConfig, getSchema, getCanonicalUrl, - clearPuckCache, + // clearPuckCache, + // getPuckCacheSize, + // clearPuckCacheAsync, } from "@yext/visual-editor"; import { AnalyticsProvider, SchemaWrapper } from "@yext/pages-components"; @@ -112,14 +114,30 @@ export const transformProps: TransformProps = async (props) => { directoryConfig, document ); + + // Log cache size before resolveAllData + // const cacheSizeBefore = getPuckCacheSize(); + // console.log( + // `[VE transformProps] Before resolveAllData for document ${document.id}: cache size = ${cacheSizeBefore}` + // ); + const updatedData = await resolveAllData(migratedData, directoryConfig, { streamDocument: document, }); + // Log cache size after resolveAllData but before clearing + // const cacheSizeAfterResolve = getPuckCacheSize(); + // console.log( + // `[VE transformProps] After resolveAllData for document ${document.id}: cache size = ${cacheSizeAfterResolve} (was ${cacheSizeBefore})` + // ); + // Clear Puck's internal cache after resolving data to prevent memory leaks // when processing many pages. The cache stores resolved data per component ID // and never gets cleared, causing memory to accumulate across page invocations. - clearPuckCache(); + // The cache also stores parentData with references to document objects, which + // prevents garbage collection and causes exponential memory growth. + // Use async version for Deno compatibility + // await clearPuckCacheAsync(); return { ...props, data: updatedData }; }; diff --git a/packages/visual-editor/src/vite-plugin/templates/locator.tsx b/packages/visual-editor/src/vite-plugin/templates/locator.tsx index 5751b53d1..b6e3da29e 100644 --- a/packages/visual-editor/src/vite-plugin/templates/locator.tsx +++ b/packages/visual-editor/src/vite-plugin/templates/locator.tsx @@ -25,7 +25,9 @@ import { getCanonicalUrl, migrate, migrationRegistry, - clearPuckCache, + // clearPuckCache, + // getPuckCacheSize, + // clearPuckCacheAsync, } from "@yext/visual-editor"; import { AnalyticsProvider, SchemaWrapper } from "@yext/pages-components"; import mapboxPackageJson from "mapbox-gl/package.json"; @@ -113,14 +115,30 @@ export const transformProps: TransformProps = async (props) => { locatorConfig, document ); + + // Log cache size before resolveAllData + // const cacheSizeBefore = getPuckCacheSize(); + // console.log( + // `[VE transformProps] Before resolveAllData for document ${document.id}: cache size = ${cacheSizeBefore}` + // ); + const updatedData = await resolveAllData(migratedData, locatorConfig, { streamDocument: document, }); + // Log cache size after resolveAllData but before clearing + // const cacheSizeAfterResolve = getPuckCacheSize(); + // console.log( + // `[VE transformProps] After resolveAllData for document ${document.id}: cache size = ${cacheSizeAfterResolve} (was ${cacheSizeBefore})` + // ); + // Clear Puck's internal cache after resolving data to prevent memory leaks // when processing many pages. The cache stores resolved data per component ID // and never gets cleared, causing memory to accumulate across page invocations. - clearPuckCache(); + // The cache also stores parentData with references to document objects, which + // prevents garbage collection and causes exponential memory growth. + // Use async version for Deno compatibility + // await clearPuckCacheAsync(); return { ...props, data: updatedData }; }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f47b2310..75f096080 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,8 +83,8 @@ importers: packages/visual-editor: dependencies: "@measured/puck": - specifier: 0.20.2 - version: 0.20.2(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) + specifier: file:../../../puck/packages/core + version: file:../puck/packages/core(@floating-ui/dom@1.7.4)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) "@microsoft/api-documenter": specifier: ^7.26.29 version: 7.26.32(@types/node@20.19.11) @@ -352,7 +352,7 @@ importers: version: 1.6.4(@algolia/client-search@5.35.0)(@types/node@20.19.11)(@types/react@18.3.24)(postcss@8.5.6)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2) vitest: specifier: ^3.2.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.11)(@vitest/browser@3.2.4)(jsdom@24.1.3) + version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.11)(@vitest/browser@3.2.4)(happy-dom@20.0.11)(jsdom@24.1.3) zod: specifier: ^3.23.8 version: 3.25.76 @@ -372,8 +372,8 @@ importers: specifier: ^7.10.1 version: 7.17.8(react@18.3.1) "@measured/puck": - specifier: 0.20.2 - version: 0.20.2(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) + specifier: file:../../puck/packages/core + version: file:../puck/packages/core(@floating-ui/dom@1.7.4)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) "@radix-ui/react-accordion": specifier: ^1.2.0 version: 1.2.12(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -466,8 +466,8 @@ importers: specifier: ^4.2.1 version: 4.7.0(vite@5.4.19(@types/node@20.19.11)) "@yext/pages": - specifier: 1.2.5 - version: 1.2.5(@algolia/client-search@5.35.0)(@types/node@20.19.11)(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)(vite@5.4.19(@types/node@20.19.11)) + specifier: file:../../pages/packages/pages + version: file:../pages/packages/pages(@algolia/client-search@5.35.0)(@types/node@20.19.11)(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)(vite@5.4.19(@types/node@20.19.11)) "@yext/pages-components": specifier: 1.1.16 version: 1.1.16(@lexical/clipboard@0.12.6(lexical@0.12.6))(@lexical/selection@0.12.6(lexical@0.12.6))(@lexical/utils@0.12.6(lexical@0.12.6))(@types/react@18.3.24)(encoding@0.1.13)(mapbox-gl@2.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(yjs@13.6.27) @@ -2157,11 +2157,8 @@ packages: } engines: { node: ">=6.0.0" } - "@measured/puck@0.20.2": - resolution: - { - integrity: sha512-/GuzlsGs1T2S3lY9so4GyHpDBlWnC1h/4rkYuelrLNHvacnXBZyn50hvgRhWAqlLn/xOuJvJeuY740Zemxdt3Q==, - } + "@measured/puck@file:../puck/packages/core": + resolution: { directory: ../puck/packages/core, type: directory } peerDependencies: react: ^18.0.0 || ^19.0.0 @@ -4030,6 +4027,12 @@ packages: react-redux: optional: true + "@remirror/core-constants@3.0.0": + resolution: + { + integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==, + } + "@restart/hooks@0.5.1": resolution: { @@ -4508,6 +4511,194 @@ packages: peerDependencies: "@testing-library/dom": ">=7.21.4" + "@tiptap/core@3.13.0": + resolution: + { + integrity: sha512-iUelgiTMgPVMpY5ZqASUpk8mC8HuR9FWKaDzK27w9oWip9tuB54Z8mePTxNcQaSPb6ErzEaC8x8egrRt7OsdGQ==, + } + peerDependencies: + "@tiptap/pm": ^3.13.0 + + "@tiptap/extension-blockquote@3.13.0": + resolution: + { + integrity: sha512-K1z/PAIIwEmiWbzrP//4cC7iG1TZknDlF1yb42G7qkx2S2X4P0NiqX7sKOej3yqrPjKjGwPujLMSuDnCF87QkQ==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/extension-bold@3.13.0": + resolution: + { + integrity: sha512-VYiDN9EEwR6ShaDLclG8mphkb/wlIzqfk7hxaKboq1G+NSDj8PcaSI9hldKKtTCLeaSNu6UR5nkdu/YHdzYWTw==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/extension-bubble-menu@3.13.0": + resolution: + { + integrity: sha512-qZ3j2DBsqP9DjG2UlExQ+tHMRhAnWlCKNreKddKocb/nAFrPdBCtvkqIEu+68zPlbLD4ukpoyjUklRJg+NipFg==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + "@tiptap/pm": ^3.13.0 + + "@tiptap/extension-code-block@3.13.0": + resolution: + { + integrity: sha512-kIwfQ4iqootsWg9e74iYJK54/YMIj6ahUxEltjZRML5z/h4gTDcQt2eTpnEC8yjDjHeUVOR94zH9auCySyk9CQ==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + "@tiptap/pm": ^3.13.0 + + "@tiptap/extension-code@3.13.0": + resolution: + { + integrity: sha512-sF5raBni6iSVpXWvwJCAcOXw5/kZ+djDHx1YSGWhopm4+fsj0xW7GvVO+VTwiFjZGKSw+K5NeAxzcQTJZd3Vhw==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/extension-document@3.13.0": + resolution: + { + integrity: sha512-RjU7hTJwjKXIdY57o/Pc+Yr8swLkrwT7PBQ/m+LCX5oO/V2wYoWCjoBYnK5KSHrWlNy/aLzC33BvLeqZZ9nzlQ==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/extension-floating-menu@3.13.0": + resolution: + { + integrity: sha512-OsezV2cMofZM4c13gvgi93IEYBUzZgnu8BXTYZQiQYekz4bX4uulBmLa1KOA9EN71FzS+SoLkXHU0YzlbLjlxA==, + } + peerDependencies: + "@floating-ui/dom": ^1.0.0 + "@tiptap/core": ^3.13.0 + "@tiptap/pm": ^3.13.0 + + "@tiptap/extension-hard-break@3.13.0": + resolution: + { + integrity: sha512-nH1OBaO+/pakhu+P1jF208mPgB70IKlrR/9d46RMYoYbqJTNf4KVLx5lHAOHytIhjcNg+MjyTfJWfkK+dyCCyg==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/extension-heading@3.13.0": + resolution: + { + integrity: sha512-8VKWX8waYPtUWN97J89em9fOtxNteh6pvUEd0htcOAtoxjt2uZjbW5N4lKyWhNKifZBrVhH2Cc2NUPuftCVgxw==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/extension-horizontal-rule@3.13.0": + resolution: + { + integrity: sha512-ZUFyORtjj22ib8ykbxRhWFQOTZjNKqOsMQjaAGof30cuD2DN5J5pMz7Haj2fFRtLpugWYH+f0Mi+WumQXC3hCw==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + "@tiptap/pm": ^3.13.0 + + "@tiptap/extension-italic@3.13.0": + resolution: + { + integrity: sha512-XbVTgmzk1kgUMTirA6AGdLTcKHUvEJoh3R4qMdPtwwygEOe7sBuvKuLtF6AwUtpnOM+Y3tfWUTNEDWv9AcEdww==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/extension-link@3.13.0": + resolution: + { + integrity: sha512-LuFPJ5GoL12GHW4A+USsj60O90pLcwUPdvEUSWewl9USyG6gnLnY/j5ZOXPYH7LiwYW8+lhq7ABwrDF2PKyBbA==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + "@tiptap/pm": ^3.13.0 + + "@tiptap/extension-list@3.13.0": + resolution: + { + integrity: sha512-MMFH0jQ4LeCPkJJFyZ77kt6eM/vcKujvTbMzW1xSHCIEA6s4lEcx9QdZMPpfmnOvTzeoVKR4nsu2t2qT9ZXzAw==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + "@tiptap/pm": ^3.13.0 + + "@tiptap/extension-paragraph@3.13.0": + resolution: + { + integrity: sha512-9csQde1i0yeZI5oQQ9e1GYNtGL2JcC2d8Fwtw9FsGC8yz2W0h+Fmk+3bc2kobbtO5LGqupSc1fKM8fAg5rSRDg==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/extension-strike@3.13.0": + resolution: + { + integrity: sha512-VHhWNqTAMOfrC48m2FcPIZB0nhl6XHQviAV16SBc+EFznKNv9tQUsqQrnuQ2y6ZVfqq5UxvZ3hKF/JlN/Ff7xw==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/extension-text-align@3.13.0": + resolution: + { + integrity: sha512-hebIus9tdXWb+AmhO+LTeUxZLdb0tqwdeaL/0wYxJQR5DeCTlJe6huXacMD/BkmnlEpRhxzQH0FrmXAd0d4Wgg==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/extension-text@3.13.0": + resolution: + { + integrity: sha512-VcZIna93rixw7hRkHGCxDbL3kvJWi80vIT25a2pXg0WP1e7Pi3nBYvZIL4SQtkbBCji9EHrbZx3p8nNPzfazYw==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/extension-underline@3.13.0": + resolution: + { + integrity: sha512-VDQi+UYw0tFnfghpthJTFmtJ3yx90kXeDwFvhmT8G+O+si5VmP05xYDBYBmYCix5jqKigJxEASiBL0gYOgMDEg==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + + "@tiptap/html@3.13.0": + resolution: + { + integrity: sha512-WAwb2FiXkvnCsa7CjLSK3cOihL+M6vu3cP1D+Bfcgy0c4DP78tDRny2z6crDUj6b5CvOejyxj2iqhV48gxiDMA==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + "@tiptap/pm": ^3.13.0 + happy-dom: ^20.0.2 + + "@tiptap/pm@3.13.0": + resolution: + { + integrity: sha512-WKR4ucALq+lwx0WJZW17CspeTpXorbIOpvKv5mulZica6QxqfMhn8n1IXCkDws/mCoLRx4Drk5d377tIjFNsvQ==, + } + + "@tiptap/react@3.13.0": + resolution: + { + integrity: sha512-VqpqNZ9qtPr3pWK4NsZYxXgLSEiAnzl6oS7tEGmkkvJbcGSC+F7R13Xc9twv/zT5QCLxaHdEbmxHbuAIkrMgJQ==, + } + peerDependencies: + "@tiptap/core": ^3.13.0 + "@tiptap/pm": ^3.13.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + "@types/react-dom": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + "@ts-morph/common@0.23.0": resolution: { @@ -4828,6 +5019,12 @@ packages: integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==, } + "@types/use-sync-external-store@0.0.6": + resolution: + { + integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==, + } + "@types/uuid@10.0.0": resolution: { @@ -4852,6 +5049,12 @@ packages: integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==, } + "@types/whatwg-mimetype@3.0.2": + resolution: + { + integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==, + } + "@types/yargs-parser@21.0.3": resolution: { @@ -5178,11 +5381,8 @@ packages: react: ^17.0.2 || ^18.2.0 react-dom: ^17.0.2 || ^18.2.0 - "@yext/pages@1.2.5": - resolution: - { - integrity: sha512-h7mMPqzSeM55hH8fxM0jFv2KoA0krZu/V4Lt6L9CiCvLVr/Wf/vx8xCGP4HFtRINgiAjEbTw9az285UTa8C4eQ==, - } + "@yext/pages@file:../pages/packages/pages": + resolution: { directory: ../pages/packages/pages, type: directory } engines: { node: ^18 || ^20.2.0 || ^22 } hasBin: true peerDependencies: @@ -6245,6 +6445,12 @@ packages: integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, } + crelt@1.0.6: + resolution: + { + integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==, + } + cross-fetch@3.2.0: resolution: { @@ -6888,6 +7094,20 @@ packages: integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, } + fast-equals@5.2.2: + resolution: + { + integrity: sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==, + } + engines: { node: ">=6.0.0" } + + fast-equals@5.3.3: + resolution: + { + integrity: sha512-/boTcHZeIAQ2r/tL11voclBHDeP9WPxLt+tyAbVSyyXuUFyh0Tne7gJZTqGbxnvj79TjLdCXLOY7UIPhyG5MTw==, + } + engines: { node: ">=6.0.0" } + fast-fifo@1.3.2: resolution: { @@ -7226,6 +7446,13 @@ packages: engines: { node: ">=0.4.7" } hasBin: true + happy-dom@20.0.11: + resolution: + { + integrity: sha512-QsCdAUHAmiDeKeaNojb1OHOPF7NjcWPBR7obdu3NwH2a/oyQaLg5d0aaCy/9My6CdPChYF07dvz5chaXBGaD4g==, + } + engines: { node: ">=20.0.0" } + has-flag@4.0.0: resolution: { @@ -8172,6 +8399,18 @@ packages: integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, } + linkify-it@5.0.0: + resolution: + { + integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==, + } + + linkifyjs@4.3.2: + resolution: + { + integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==, + } + lint-staged@15.5.2: resolution: { @@ -8350,6 +8589,13 @@ packages: integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==, } + markdown-it@14.1.0: + resolution: + { + integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==, + } + hasBin: true + markdown-table@2.0.0: resolution: { @@ -8477,6 +8723,12 @@ packages: integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==, } + mdurl@2.0.0: + resolution: + { + integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==, + } + media-typer@0.3.0: resolution: { @@ -9216,6 +9468,12 @@ packages: } engines: { node: ">=18" } + orderedmap@2.1.1: + resolution: + { + integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==, + } + os-browserify@0.3.0: resolution: { @@ -9808,6 +10066,118 @@ packages: integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==, } + prosemirror-changeset@2.3.1: + resolution: + { + integrity: sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==, + } + + prosemirror-collab@1.3.1: + resolution: + { + integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==, + } + + prosemirror-commands@1.7.1: + resolution: + { + integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==, + } + + prosemirror-dropcursor@1.8.2: + resolution: + { + integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==, + } + + prosemirror-gapcursor@1.4.0: + resolution: + { + integrity: sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==, + } + + prosemirror-history@1.5.0: + resolution: + { + integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==, + } + + prosemirror-inputrules@1.5.1: + resolution: + { + integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==, + } + + prosemirror-keymap@1.2.3: + resolution: + { + integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==, + } + + prosemirror-markdown@1.13.2: + resolution: + { + integrity: sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==, + } + + prosemirror-menu@1.2.5: + resolution: + { + integrity: sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==, + } + + prosemirror-model@1.25.4: + resolution: + { + integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==, + } + + prosemirror-schema-basic@1.2.4: + resolution: + { + integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==, + } + + prosemirror-schema-list@1.5.1: + resolution: + { + integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==, + } + + prosemirror-state@1.4.4: + resolution: + { + integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==, + } + + prosemirror-tables@1.8.3: + resolution: + { + integrity: sha512-wbqCR/RlRPRe41a4LFtmhKElzBEfBTdtAYWNIGHM6X2e24NN/MTNUKyXjjphfAfdQce37Kh/5yf765mLPYDe7Q==, + } + + prosemirror-trailing-node@3.0.0: + resolution: + { + integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==, + } + peerDependencies: + prosemirror-model: ^1.22.1 + prosemirror-state: ^1.4.2 + prosemirror-view: ^1.33.8 + + prosemirror-transform@1.10.5: + resolution: + { + integrity: sha512-RPDQCxIDhIBb1o36xxwsaeAvivO8VLJcgBtzmOwQ64bMtsVFh5SSuJ6dWSxO1UsHTiTXPCgQm3PDJt7p6IOLbw==, + } + + prosemirror-view@1.41.4: + resolution: + { + integrity: sha512-WkKgnyjNncri03Gjaz3IFWvCAE94XoiEgvtr0/r2Xw7R8/IjK3sKLSiDoCHWcsXSAinVaKlGRZDvMCsF1kbzjA==, + } + proto-list@1.2.4: resolution: { @@ -9839,6 +10209,13 @@ packages: integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==, } + punycode.js@2.3.1: + resolution: + { + integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==, + } + engines: { node: ">=6" } + punycode@1.4.1: resolution: { @@ -10468,6 +10845,12 @@ packages: engines: { node: ">=18.0.0", npm: ">=8.0.0" } hasBin: true + rope-sequence@1.3.4: + resolution: + { + integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==, + } + rrweb-cssom@0.7.1: resolution: { @@ -11438,6 +11821,12 @@ packages: engines: { node: ">=14.17" } hasBin: true + uc.micro@2.1.0: + resolution: + { + integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==, + } + ufo@1.6.1: resolution: { @@ -12067,6 +12456,12 @@ packages: typescript: optional: true + w3c-keyname@2.2.8: + resolution: + { + integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==, + } + w3c-xmlserializer@5.0.0: resolution: { @@ -12124,6 +12519,13 @@ packages: } engines: { node: ">=18" } + whatwg-mimetype@3.0.0: + resolution: + { + integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==, + } + engines: { node: ">=12" } + whatwg-mimetype@4.0.0: resolution: { @@ -13325,13 +13727,35 @@ snapshots: "@mapbox/whoots-js@3.1.0": {} - "@measured/puck@0.20.2(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1))": + "@measured/puck@file:../puck/packages/core(@floating-ui/dom@1.7.4)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1))": dependencies: "@dnd-kit/helpers": 0.1.18 "@dnd-kit/react": 0.1.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + "@radix-ui/react-popover": 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + "@tiptap/extension-blockquote": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/extension-bold": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/extension-code": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/extension-code-block": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0) + "@tiptap/extension-document": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/extension-hard-break": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/extension-heading": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/extension-horizontal-rule": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0) + "@tiptap/extension-italic": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/extension-link": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0) + "@tiptap/extension-list": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0) + "@tiptap/extension-paragraph": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/extension-strike": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/extension-text": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/extension-text-align": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/extension-underline": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0)) + "@tiptap/html": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)(happy-dom@20.0.11) + "@tiptap/pm": 3.13.0 + "@tiptap/react": 3.13.0(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) deep-diff: 1.0.2 - fast-deep-equal: 3.1.3 + fast-equals: 5.2.2 flat: 5.0.2 + happy-dom: 20.0.11 object-hash: 3.0.0 react: 18.3.1 react-hotkeys-hook: 4.6.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13339,7 +13763,9 @@ snapshots: uuid: 9.0.1 zustand: 5.0.8(@types/react@18.3.24)(immer@9.0.21)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) transitivePeerDependencies: + - "@floating-ui/dom" - "@types/react" + - "@types/react-dom" - immer - react-dom - use-sync-external-store @@ -15152,6 +15578,8 @@ snapshots: optionalDependencies: react: 18.3.1 + "@remirror/core-constants@3.0.0": {} + "@restart/hooks@0.5.1(react@18.3.1)": dependencies: dequal: 2.0.3 @@ -15458,6 +15886,137 @@ snapshots: dependencies: "@testing-library/dom": 10.4.1 + "@tiptap/core@3.13.0(@tiptap/pm@3.13.0)": + dependencies: + "@tiptap/pm": 3.13.0 + + "@tiptap/extension-blockquote@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/extension-bold@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/extension-bubble-menu@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)": + dependencies: + "@floating-ui/dom": 1.7.4 + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + "@tiptap/pm": 3.13.0 + optional: true + + "@tiptap/extension-code-block@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + "@tiptap/pm": 3.13.0 + + "@tiptap/extension-code@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/extension-document@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/extension-floating-menu@3.13.0(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)": + dependencies: + "@floating-ui/dom": 1.7.4 + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + "@tiptap/pm": 3.13.0 + optional: true + + "@tiptap/extension-hard-break@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/extension-heading@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/extension-horizontal-rule@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + "@tiptap/pm": 3.13.0 + + "@tiptap/extension-italic@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/extension-link@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + "@tiptap/pm": 3.13.0 + linkifyjs: 4.3.2 + + "@tiptap/extension-list@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + "@tiptap/pm": 3.13.0 + + "@tiptap/extension-paragraph@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/extension-strike@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/extension-text-align@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/extension-text@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/extension-underline@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + + "@tiptap/html@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)(happy-dom@20.0.11)": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + "@tiptap/pm": 3.13.0 + happy-dom: 20.0.11 + + "@tiptap/pm@3.13.0": + dependencies: + prosemirror-changeset: 2.3.1 + prosemirror-collab: 1.3.1 + prosemirror-commands: 1.7.1 + prosemirror-dropcursor: 1.8.2 + prosemirror-gapcursor: 1.4.0 + prosemirror-history: 1.5.0 + prosemirror-inputrules: 1.5.1 + prosemirror-keymap: 1.2.3 + prosemirror-markdown: 1.13.2 + prosemirror-menu: 1.2.5 + prosemirror-model: 1.25.4 + prosemirror-schema-basic: 1.2.4 + prosemirror-schema-list: 1.5.1 + prosemirror-state: 1.4.4 + prosemirror-tables: 1.8.3 + prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4) + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.4 + + "@tiptap/react@3.13.0(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)": + dependencies: + "@tiptap/core": 3.13.0(@tiptap/pm@3.13.0) + "@tiptap/pm": 3.13.0 + "@types/react": 18.3.24 + "@types/react-dom": 18.3.7(@types/react@18.3.24) + "@types/use-sync-external-store": 0.0.6 + fast-equals: 5.3.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + use-sync-external-store: 1.5.0(react@18.3.1) + optionalDependencies: + "@tiptap/extension-bubble-menu": 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0) + "@tiptap/extension-floating-menu": 3.13.0(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0) + transitivePeerDependencies: + - "@floating-ui/dom" + "@ts-morph/common@0.23.0": dependencies: fast-glob: 3.3.3 @@ -15639,6 +16198,8 @@ snapshots: "@types/unist@3.0.3": {} + "@types/use-sync-external-store@0.0.6": {} + "@types/uuid@10.0.0": {} "@types/warning@3.0.3": {} @@ -15647,6 +16208,8 @@ snapshots: "@types/web-bluetooth@0.0.21": {} + "@types/whatwg-mimetype@3.0.2": {} + "@types/yargs-parser@21.0.3": {} "@types/yargs@17.0.33": @@ -15681,7 +16244,7 @@ snapshots: magic-string: 0.30.18 sirv: 3.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.11)(@vitest/browser@3.2.4)(jsdom@24.1.3) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.11)(@vitest/browser@3.2.4)(happy-dom@20.0.11)(jsdom@24.1.3) ws: 8.18.3 optionalDependencies: playwright: 1.55.1 @@ -15913,11 +16476,10 @@ snapshots: - supports-color - yjs - "@yext/pages@1.2.5(@algolia/client-search@5.35.0)(@types/node@20.19.11)(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)(vite@5.4.19(@types/node@20.19.11))": + "@yext/pages@file:../pages/packages/pages(@algolia/client-search@5.35.0)(@types/node@20.19.11)(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)(vite@5.4.19(@types/node@20.19.11))": dependencies: ansi-to-html: 0.7.2 browser-or-node: 2.1.1 - chalk: 5.6.0 commander: 12.1.0 escape-html: 1.0.3 express: 4.21.2 @@ -16623,7 +17185,7 @@ snapshots: dependencies: cipher-base: 1.0.6 inherits: 2.0.4 - ripemd160: 2.0.1 + ripemd160: 2.0.2 sha.js: 2.4.12 create-hash@1.2.0: @@ -16645,6 +17207,8 @@ snapshots: create-require@1.1.1: {} + crelt@1.0.6: {} + cross-fetch@3.2.0(encoding@0.1.13): dependencies: node-fetch: 2.7.0(encoding@0.1.13) @@ -17065,6 +17629,10 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-equals@5.2.2: {} + + fast-equals@5.3.3: {} + fast-fifo@1.3.2: {} fast-glob@3.3.3: @@ -17283,6 +17851,12 @@ snapshots: optionalDependencies: uglify-js: 3.19.3 + happy-dom@20.0.11: + dependencies: + "@types/node": 20.19.11 + "@types/whatwg-mimetype": 3.0.2 + whatwg-mimetype: 3.0.0 + has-flag@4.0.0: {} has-property-descriptors@1.0.2: @@ -17825,6 +18399,12 @@ snapshots: lines-and-columns@1.2.4: {} + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + linkifyjs@4.3.2: {} + lint-staged@15.5.2: dependencies: chalk: 5.6.0 @@ -17962,6 +18542,15 @@ snapshots: mark.js@8.11.1: {} + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + markdown-table@2.0.0: dependencies: repeat-string: 1.6.1 @@ -18101,6 +18690,8 @@ snapshots: mdurl@1.0.1: {} + mdurl@2.0.0: {} + media-typer@0.3.0: {} merge-descriptors@1.0.3: {} @@ -18627,6 +19218,8 @@ snapshots: string-width: 7.2.0 strip-ansi: 7.1.0 + orderedmap@2.1.1: {} + os-browserify@0.3.0: {} oxlint@1.2.0: @@ -18962,6 +19555,109 @@ snapshots: property-information@7.1.0: {} + prosemirror-changeset@2.3.1: + dependencies: + prosemirror-transform: 1.10.5 + + prosemirror-collab@1.3.1: + dependencies: + prosemirror-state: 1.4.4 + + prosemirror-commands@1.7.1: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + + prosemirror-dropcursor@1.8.2: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.4 + + prosemirror-gapcursor@1.4.0: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-view: 1.41.4 + + prosemirror-history@1.5.0: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.4 + rope-sequence: 1.3.4 + + prosemirror-inputrules@1.5.1: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + + prosemirror-keymap@1.2.3: + dependencies: + prosemirror-state: 1.4.4 + w3c-keyname: 2.2.8 + + prosemirror-markdown@1.13.2: + dependencies: + "@types/markdown-it": 14.1.2 + markdown-it: 14.1.0 + prosemirror-model: 1.25.4 + + prosemirror-menu@1.2.5: + dependencies: + crelt: 1.0.6 + prosemirror-commands: 1.7.1 + prosemirror-history: 1.5.0 + prosemirror-state: 1.4.4 + + prosemirror-model@1.25.4: + dependencies: + orderedmap: 2.1.1 + + prosemirror-schema-basic@1.2.4: + dependencies: + prosemirror-model: 1.25.4 + + prosemirror-schema-list@1.5.1: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + + prosemirror-state@1.4.4: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.4 + + prosemirror-tables@1.8.3: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.4 + + prosemirror-trailing-node@3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4): + dependencies: + "@remirror/core-constants": 3.0.0 + escape-string-regexp: 4.0.0 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-view: 1.41.4 + + prosemirror-transform@1.10.5: + dependencies: + prosemirror-model: 1.25.4 + + prosemirror-view@1.41.4: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + proto-list@1.2.4: {} protocol-buffers-schema@3.6.0: {} @@ -18984,6 +19680,8 @@ snapshots: randombytes: 2.1.0 safe-buffer: 5.2.1 + punycode.js@2.3.1: {} + punycode@1.4.1: {} punycode@2.3.1: {} @@ -19516,6 +20214,8 @@ snapshots: "@rollup/rollup-win32-x64-msvc": 4.47.1 fsevents: 2.3.3 + rope-sequence@1.3.4: {} + rrweb-cssom@0.7.1: {} rrweb-cssom@0.8.0: {} @@ -20136,6 +20836,8 @@ snapshots: typescript@5.9.2: {} + uc.micro@2.1.0: {} + ufo@1.6.1: {} uglify-js@3.19.3: @@ -20582,7 +21284,7 @@ snapshots: - typescript - universal-cookie - vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.11)(@vitest/browser@3.2.4)(jsdom@24.1.3): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.11)(@vitest/browser@3.2.4)(happy-dom@20.0.11)(jsdom@24.1.3): dependencies: "@types/chai": 5.2.2 "@vitest/expect": 3.2.4 @@ -20611,6 +21313,7 @@ snapshots: "@types/debug": 4.1.12 "@types/node": 20.19.11 "@vitest/browser": 3.2.4(playwright@1.55.1)(vite@5.4.19(@types/node@20.19.11))(vitest@3.2.4) + happy-dom: 20.0.11 jsdom: 24.1.3 transitivePeerDependencies: - less @@ -20647,6 +21350,8 @@ snapshots: optionalDependencies: typescript: 5.9.2 + w3c-keyname@2.2.8: {} + w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 @@ -20673,6 +21378,8 @@ snapshots: dependencies: iconv-lite: 0.6.3 + whatwg-mimetype@3.0.0: {} + whatwg-mimetype@4.0.0: {} whatwg-url@14.2.0: diff --git a/starter/ensure-builds.sh b/starter/ensure-builds.sh new file mode 100755 index 000000000..c0a25e0d0 --- /dev/null +++ b/starter/ensure-builds.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Ensure all packages are built before testing + +set -e + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +ROOT_DIR="$( cd "$SCRIPT_DIR/../.." && pwd )" + +echo "🔨 Building all packages..." +echo "Script dir: $SCRIPT_DIR" +echo "Root dir: $ROOT_DIR" + +# Build puck +echo "Building @measured/puck..." +cd "$ROOT_DIR/puck/packages/core" +yarn build +cd "$SCRIPT_DIR" + +# Build pages +echo "Building @yext/pages..." +cd "$ROOT_DIR/pages/packages/pages" +pnpm build +cd "$SCRIPT_DIR" + +# Build visual-editor +echo "Building @yext/visual-editor..." +cd "$ROOT_DIR/visual-editor/packages/visual-editor" +pnpm build +cd "$SCRIPT_DIR" + +# Build starter +echo "Building starter..." +pnpm install && pnpm build + +echo "✅ All packages built successfully!" diff --git a/starter/large-template-layout.json b/starter/large-template-layout.json new file mode 100644 index 000000000..2be29f223 --- /dev/null +++ b/starter/large-template-layout.json @@ -0,0 +1,457 @@ +{ + "feature": "location-pages", + "site": { + "branchId": "132038", + "businessId": "2183737", + "businessName": "Inspire Brands", + "commitHash": "a35b3ce97b3ec1db516226dc15610c099e2e648d", + "commitMessage": "Initial commit", + "deployId": "2dub25ppd3", + "platformUrl": "https://www.yext.com/s/2183737/yextsites/161673/branch/132038/deploy/2dub25ppd3/details", + "previewDomain": "https://2dub25ppd3-161673-d.preview.pagescdn.com", + "productionDomain": "keenly-chocolate-leopard.pgsdemo.com", + "repoBranchName": "132038", + "repoBranchUrl": "https://github.com/yext-pages/2183737-visual-editor-starter-e25z6702cf/tree/132038", + "repoUrl": "https://github.com/yext-pages/2183737-visual-editor-starter-e25z6702cf", + "siteId": "161673", + "siteName": "Jimmy John's pages", + "stagingDomain": "132038-keenly--chocolate--leopard-pgsdemo-com.preview.pagescdn.com", + "yextUniverse": "production" + }, + "streamOutput": { + "__": { + "codeTemplate": "main", + "entityPageSet": {}, + "layout": "{\"root\": {\"type\": \"root\", \"props\": {\"title\": {\"field\": \"name\", \"constantValue\": {\"en\": \"Sandwich Shop & Gourmet Subs in [[address.city]] | Jimmy John's \", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}, \"version\": 44, \"description\": {\"field\": \"description\", \"constantValue\": {\"en\": \"Sandwich Shop & Gourmet Subs in [[address.city]] | Jimmy John's \", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}}, \"zones\": {}, \"content\": [{\"type\": \"ExpandedHeader\", \"props\": {\"id\": \"ExpandedHeader-84f1ec29-3de0-4d31-a119-7edce3f2e3c9\", \"slots\": {\"PrimaryHeaderSlot\": [{\"type\": \"PrimaryHeaderSlot\", \"props\": {\"id\": \"ExpandedHeader-84f1ec29-3de0-4d31-a119-7edce3f2e3c9-PrimaryHeaderSlot\", \"slots\": {\"LogoSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ImageSlot-aef02ad9-8576-40e2-84a5-02a7d9dcbdd3\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://a.mktgcdn.com/p/4AsPFV2ZrHyJHS4j5d9IezOR4DP3cbIgrCCxctF9IWs/1024x1024.png\", \"width\": 1024, \"height\": 1024, \"assetImage\": {\"id\": \"22251941\", \"name\": \"Jimmy John's logo\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/4AsPFV2ZrHyJHS4j5d9IezOR4DP3cbIgrCCxctF9IWs/1024x1024.png\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/4AsPFV2ZrHyJHS4j5d9IezOR4DP3cbIgrCCxctF9IWs/1024x1024.png\", \"dimension\": {\"width\": 1024, \"height\": 1024}}, {\"url\": \"//a.mktgcdn.com/p/4AsPFV2ZrHyJHS4j5d9IezOR4DP3cbIgrCCxctF9IWs/619x619.png\", \"dimension\": {\"width\": 619, \"height\": 619}}, {\"url\": \"//a.mktgcdn.com/p/4AsPFV2ZrHyJHS4j5d9IezOR4DP3cbIgrCCxctF9IWs/450x450.png\", \"dimension\": {\"width\": 450, \"height\": 450}}, {\"url\": \"//a.mktgcdn.com/p/4AsPFV2ZrHyJHS4j5d9IezOR4DP3cbIgrCCxctF9IWs/196x196.png\", \"dimension\": {\"width\": 196, \"height\": 196}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/4AsPFV2ZrHyJHS4j5d9IezOR4DP3cbIgrCCxctF9IWs/1024x1024.png\", \"dimension\": {\"width\": 1024, \"height\": 1024}}}, \"alternateText\": \"\"}, \"constantValueEnabled\": true}}, \"styles\": {\"width\": 90, \"aspectRatio\": 1}}}], \"LinksSlot\": [{\"type\": \"HeaderLinks\", \"props\": {\"id\": \"HeaderLinks-e07098e5-d391-4511-9bea-c8f85834112c\", \"data\": {\"links\": [{\"link\": \"https://www.jimmyjohns.com/menu\", \"label\": {\"en\": \"MENU\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/catering\", \"label\": {\"en\": \"CATERING\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/locations\", \"label\": {\"en\": \"LOCATIONS\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/rewards\", \"label\": {\"en\": \"REWARDS\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}}}], \"PrimaryCTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"CTASlot-979b21ed-6363-4f6c-86c4-36ef034c9d3f\", \"data\": {\"show\": true, \"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"https://www.jimmyjohns.com/my-account/sign-in\", \"label\": {\"en\": \"SIGN IN\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"secondary\", \"presetImage\": \"app-store\"}, \"eventName\": \"primaryCta\"}}], \"SecondaryCTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"CTASlot-5c113634-75b7-4d21-a66d-f48a727ded09\", \"data\": {\"show\": true, \"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"https://www.jimmyjohns.com/locations\", \"label\": {\"en\": \"START AN ORDER\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"secondaryCta\"}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-secondary\", \"textColor\": \"text-palette-secondary-contrast\"}}, \"parentValues\": {\"maxWidth\": \"theme\", \"SecondaryHeaderSlot\": [{\"type\": \"SecondaryHeaderSlot\", \"props\": {\"id\": \"ExpandedHeader-84f1ec29-3de0-4d31-a119-7edce3f2e3c9-SecondaryHeaderSlot\", \"data\": {\"show\": false, \"showLanguageDropdown\": false}, \"slots\": {\"LinksSlot\": [{\"type\": \"HeaderLinks\", \"props\": {\"id\": \"ExpandedHeader-84f1ec29-3de0-4d31-a119-7edce3f2e3c9-SecondaryHeaderLinksSlot\", \"data\": {\"links\": [{\"link\": \"#\", \"label\": {\"en\": \"Secondary Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Secondary Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Secondary Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Secondary Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Secondary Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}, \"parentData\": {\"type\": \"Secondary\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-primary-light\", \"textColor\": \"text-black\"}}, \"parentStyles\": {\"maxWidth\": \"theme\"}}}]}, \"conditionalRender\": {\"CTAs\": true, \"navContent\": true}}}], \"SecondaryHeaderSlot\": [{\"type\": \"SecondaryHeaderSlot\", \"props\": {\"id\": \"ExpandedHeader-84f1ec29-3de0-4d31-a119-7edce3f2e3c9-SecondaryHeaderSlot\", \"data\": {\"show\": false, \"showLanguageDropdown\": false}, \"slots\": {\"LinksSlot\": [{\"type\": \"HeaderLinks\", \"props\": {\"id\": \"ExpandedHeader-84f1ec29-3de0-4d31-a119-7edce3f2e3c9-SecondaryHeaderLinksSlot\", \"data\": {\"links\": [{\"link\": \"#\", \"label\": {\"en\": \"Secondary Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Secondary Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Secondary Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Secondary Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Secondary Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}, \"parentData\": {\"type\": \"Secondary\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-primary-light\", \"textColor\": \"text-black\"}}, \"parentStyles\": {\"maxWidth\": \"theme\"}}}]}, \"styles\": {\"maxWidth\": \"theme\", \"headerPosition\": \"fixed\"}, \"ignoreLocaleWarning\": [\"slots.SecondaryHeaderSlot\"]}}, {\"type\": \"BreadcrumbsSection\", \"props\": {\"id\": \"BreadcrumbsSection-16e56d01-021b-4882-9f40-d3861490d278\", \"data\": {\"directoryRoot\": {\"en\": \"Home\", \"hasLocalizedValue\": \"true\"}}, \"analytics\": {\"scope\": \"breadcrumbs\"}, \"liveVisibility\": true}}, {\"type\": \"HeroSection\", \"props\": {\"id\": \"HeroSection-c18d2d63-a529-4168-bd13-d38124210eaf\", \"data\": {\"backgroundImage\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/908x618.jpg\", \"width\": 908, \"height\": 618, \"assetImage\": {\"id\": \"22251958\", \"name\": \"JJ's Locations\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/908x618.jpg\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/908x618.jpg\", \"dimension\": {\"width\": 908, \"height\": 618}}, {\"url\": \"//a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/619x421.jpg\", \"dimension\": {\"width\": 619, \"height\": 421}}, {\"url\": \"//a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/600x408.jpg\", \"dimension\": {\"width\": 600, \"height\": 408}}, {\"url\": \"//a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/196x133.jpg\", \"dimension\": {\"width\": 196, \"height\": 133}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/908x618.jpg\", \"dimension\": {\"width\": 908, \"height\": 618}}}, \"alternateText\": {\"en\": \"Jimmy John's\", \"hasLocalizedValue\": \"true\"}}, \"constantValueEnabled\": true}}, \"slots\": {\"ImageSlot\": [{\"type\": \"HeroImageSlot\", \"props\": {\"id\": \"HeroSection-c18d2d63-a529-4168-bd13-d38124210eaf-ImageSlot\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/908x618.jpg\", \"width\": 908, \"height\": 618, \"assetImage\": {\"id\": \"22251958\", \"name\": \"JJ's Locations\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/908x618.jpg\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/908x618.jpg\", \"dimension\": {\"width\": 908, \"height\": 618}}, {\"url\": \"//a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/619x421.jpg\", \"dimension\": {\"width\": 619, \"height\": 421}}, {\"url\": \"//a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/600x408.jpg\", \"dimension\": {\"width\": 600, \"height\": 408}}, {\"url\": \"//a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/196x133.jpg\", \"dimension\": {\"width\": 196, \"height\": 133}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/B-Uz7WhqEn-nEC0XS-7N1ewxYJmpDOKy3BQOKDJGsJ4/908x618.jpg\", \"dimension\": {\"width\": 908, \"height\": 618}}}, \"alternateText\": {\"en\": \"Jimmy John's\", \"hasLocalizedValue\": \"true\"}}, \"constantValueEnabled\": true}}, \"styles\": {\"height\": 300, \"aspectRatio\": 1.78}, \"variant\": \"compact\", \"className\": \"w-full sm:w-fit h-full ml-auto\"}}], \"PrimaryCTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"HeroSection-c18d2d63-a529-4168-bd13-d38124210eaf-PrimaryCTASlot\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"https://www.jimmyjohns.com/menu/\", \"label\": {\"en\": \"Order Now\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"selectedTypes\": [\"type.cta\"], \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\"}, \"eventName\": \"primaryCta\", \"parentStyles\": {}}}], \"GeomodifierSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeroSection-c18d2d63-a529-4168-bd13-d38124210eaf-GeomodifierSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"[[address.line1]], [[address.city]], [[address.region]] - [[address.postalCode]]\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"level\": 3}}}], \"HoursStatusSlot\": [{\"type\": \"HoursStatusSlot\", \"props\": {\"id\": \"HeroSection-c18d2d63-a529-4168-bd13-d38124210eaf-HoursStatusSlot\", \"data\": {\"hours\": {\"field\": \"hours\", \"constantValue\": {}}}, \"styles\": {}}}], \"BusinessNameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeroSection-c18d2d63-a529-4168-bd13-d38124210eaf-BusinessNameSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Store ID : [[c_storeCode]]\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 5, \"semanticLevelOverride\": 4}}}], \"SecondaryCTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"HeroSection-c18d2d63-a529-4168-bd13-d38124210eaf-SecondaryCTASlot\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Get Directions\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"getDirections\", \"linkType\": \"URL\"}, \"selectedTypes\": [\"type.coordinate\"], \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\"}, \"eventName\": \"secondaryCta\", \"parentStyles\": {}}}]}, \"styles\": {\"variant\": \"compact\", \"showImage\": true, \"imageHeight\": 300, \"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}, \"showAverageReview\": true, \"mobileImagePosition\": \"bottom\", \"desktopImagePosition\": \"right\", \"mobileContentAlignment\": \"left\", \"desktopContainerPosition\": \"left\"}, \"analytics\": {\"scope\": \"heroSection\"}, \"liveVisibility\": true, \"conditionalRender\": {\"hours\": true}}}, {\"type\": \"Grid\", \"props\": {\"id\": \"Grid-b6d6faf6-b6a3-4dfd-a651-8adc874a9b38\", \"align\": \"left\", \"slots\": [{\"Column\": [{\"type\": \"HeadingText\", \"props\": {\"id\": \"HeadingText-695c8b02-d292-4f41-a7c6-0451cde001de\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"HOURS\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}, {\"type\": \"HoursTable\", \"props\": {\"id\": \"HoursTable-69310456-6fa8-44ed-83b2-80193272f910\", \"data\": {\"hours\": {\"field\": \"hours\", \"constantValue\": {}}}, \"styles\": {\"alignment\": \"items-start\", \"startOfWeek\": \"today\", \"collapseDays\": false, \"showAdditionalHoursText\": true}}}]}, {\"Column\": [{\"type\": \"HeadingText\", \"props\": {\"id\": \"HeadingText-143ccc2f-02a5-49a8-94aa-b2e4422b70e5\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"DELIVERY HOURS\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}, {\"type\": \"HoursTable\", \"props\": {\"id\": \"HoursTable-70055bc1-677b-45aa-96f3-48a9ee8e46c3\", \"data\": {\"hours\": {\"field\": \"deliveryHours\", \"constantValue\": {}}}, \"styles\": {\"alignment\": \"items-start\", \"startOfWeek\": \"today\", \"collapseDays\": false, \"showAdditionalHoursText\": true}}}, {\"type\": \"TextList\", \"props\": {\"id\": \"TextList-f87da748-0fb9-4131-9bba-b74c07fb32db\", \"list\": {\"field\": \"\", \"constantValue\": []}, \"commaSeparated\": false}}, {\"type\": \"TextList\", \"props\": {\"id\": \"TextList-648dc10a-5db1-4e44-b2a5-105003d32200\", \"list\": {\"field\": \"\", \"constantValue\": []}, \"commaSeparated\": false}}, {\"type\": \"TextList\", \"props\": {\"id\": \"TextList-20488a91-2e2e-4068-bb84-9f086376bee1\", \"list\": {\"field\": \"\", \"constantValue\": []}, \"commaSeparated\": false}}]}, {\"Column\": [{\"type\": \"HeadingText\", \"props\": {\"id\": \"HeadingText-9418df19-8e4f-49e1-b02b-210fe602064d\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"SERVICES\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}, {\"type\": \"CTAGroup\", \"props\": {\"id\": \"CTAGroup-de2cdaf8-891b-43c1-974e-9829b0b7dfbf\", \"buttons\": [{\"variant\": \"primary\", \"entityField\": {\"field\": \"c_rewardsCta\", \"constantValue\": {\"link\": \"#\", \"label\": \"Button\", \"ctaType\": \"textAndLink\"}, \"constantValueEnabled\": false}, \"presetImage\": \"app-store\"}, {\"variant\": \"primary\", \"entityField\": {\"field\": \"c_CATERINGCTA\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"[[c_cATERINGURL]]\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\"}, \"constantValueEnabled\": false}, \"presetImage\": \"app-store\"}, {\"variant\": \"primary\", \"entityField\": {\"field\": \"C_deliveryCTA\", \"constantValue\": {\"link\": \"#\", \"label\": \"Button\", \"ctaType\": \"textAndLink\"}, \"constantValueEnabled\": false}, \"presetImage\": \"app-store\"}]}}]}], \"columns\": 3, \"analytics\": {\"scope\": \"gridSection\"}, \"liveVisibility\": true, \"backgroundColor\": {\"bgColor\": \"bg-palette-tertiary-light\", \"textColor\": \"text-black\"}}}, {\"type\": \"Grid\", \"props\": {\"id\": \"Grid-e08303a2-eb07-4178-b161-578c58bc4371\", \"align\": \"left\", \"slots\": [{\"Column\": [{\"type\": \"HeadingText\", \"props\": {\"id\": \"HeadingText-c9dec0e1-6052-432c-9406-45b92c624510\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"ABOUT\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}, {\"type\": \"HeadingText\", \"props\": {\"id\": \"HeadingText-9ab3a4b5-0a90-480a-9601-df2a8fe1eea8\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Sandwich Delivery in [[address.city]] for Lunch or Dinner\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 4}}}, {\"type\": \"TextList\", \"props\": {\"id\": \"TextList-fd52bc9b-78cc-43b7-b07d-60ca3d68105b\", \"list\": {\"field\": \"\", \"constantValue\": []}, \"commaSeparated\": false}}, {\"type\": \"TextList\", \"props\": {\"id\": \"TextList-2ced04e9-25a5-4bfe-9395-2b5cd05ee120\", \"list\": {\"field\": \"\", \"constantValue\": []}, \"commaSeparated\": false}}, {\"type\": \"BodyText\", \"props\": {\"id\": \"BodyText-0f5345a5-0148-4c17-8d4c-9012d62d4a6b\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Jimmy John’s has sandwiches near you in [[address.city]]! Order online or with the Jimmy John’s app for quick and easy ordering. Always made with fresh-baked bread, hand-sliced meats and fresh veggies, we bring fresh sandwiches right to you, plus your favorite sides and drinks! Order online now from your local Jimmy John’s at [[address.line1]] for sandwich pickup or delivery* today! *Delivery subject to availability; fees may apply.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Jimmy John’s has sandwiches near you in \\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1},{\\\"text\\\":\\\"address.city\\\",\\\"rawText\\\":\\\"address.city\\\",\\\"format\\\":0,\\\"style\\\":\\\"\\\",\\\"mode\\\":\\\"token\\\",\\\"detail\\\":0,\\\"type\\\":\\\"embedkey\\\",\\\"version\\\":1},{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"! Order online or with the Jimmy John’s app for quick and easy ordering. Always made with fresh-baked bread, hand-sliced meats and fresh veggies, we bring fresh sandwiches right to you, plus your favorite sides and drinks! Order online now from your local Jimmy John’s at \\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1},{\\\"text\\\":\\\"address.line1\\\",\\\"rawText\\\":\\\"address.line1\\\",\\\"format\\\":0,\\\"style\\\":\\\"\\\",\\\"mode\\\":\\\"token\\\",\\\"detail\\\":0,\\\"type\\\":\\\"embedkey\\\",\\\"version\\\":1},{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\" for sandwich pickup or delivery* today! *Delivery subject to availability; fees may apply.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}, {\"type\": \"TextList\", \"props\": {\"id\": \"TextList-e2aa5324-966f-4b30-a00a-a4e006675a3e\", \"list\": {\"field\": \"\", \"constantValue\": []}, \"commaSeparated\": false}}, {\"type\": \"TextList\", \"props\": {\"id\": \"TextList-6fdc4a80-03ba-4a6f-8d73-1974641c31e2\", \"list\": {\"field\": \"\", \"constantValue\": []}, \"commaSeparated\": false}}, {\"type\": \"TextList\", \"props\": {\"id\": \"TextList-8a4b1507-c3ab-4756-aa15-e5a92d7cf467\", \"list\": {\"field\": \"\", \"constantValue\": []}, \"commaSeparated\": false}}]}, {\"Column\": []}, {\"Column\": []}], \"columns\": 1, \"analytics\": {\"scope\": \"gridSection\"}, \"liveVisibility\": true, \"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}}, {\"type\": \"FAQSection\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751\", \"slots\": {\"HeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-HeadingSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"JIMMY JOHN'S FAQ\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}], \"FAQsWrapperSlot\": [{\"type\": \"FAQsWrapperSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-FAQsWrapperSlot\", \"data\": {\"field\": \"\", \"constantValue\": [{\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-0\"}, {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-1\"}, {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-2\"}, {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-3\"}, {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-4\"}, {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-5\"}, {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-6\"}, {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-7\"}], \"constantValueEnabled\": true}, \"slots\": {\"CardSlot\": [{\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-0\", \"index\": 0, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-0-AnswerSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Visit your local Jimmy John’s at [[address.line1]].

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Visit your local Jimmy John’s at [[address.line1]].\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-0-QuestionSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Where is a Jimmy John’s location near me?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":1,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Where is a Jimmy John’s location near me?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-1\", \"index\": 1, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-1-AnswerSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Yes, Jimmy John’s offers contactless delivery options to those within our delivery areas.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Yes, Jimmy John’s offers contactless delivery options to those within our delivery areas.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-1-QuestionSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Does [[address.line1]] Jimmy John’s offer delivery options?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":1,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Does [[address.line1]] Jimmy John’s offer delivery options? \\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-2\", \"index\": 2, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-2-AnswerSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Members of the Jimmy John’s Rewards™ loyalty program earn points for purchasing and can convert those points into the reward of their choosing. Sign up for Jimmy John’s Rewards™ now to earn a free sandwich after your first order!

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Members of the Jimmy John’s Rewards™ loyalty program earn points for purchasing and can convert those points into the reward of their choosing. \\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1},{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Sign up for Jimmy John’s Rewards™\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"link\\\",\\\"version\\\":1,\\\"rel\\\":null,\\\"target\\\":\\\"_blank\\\",\\\"url\\\":\\\"https://www.jimmyjohns.com/rewards\\\"},{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\" now to earn a free sandwich after your first order!\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-2-QuestionSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

What rewards are available at Jimmy John’s?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":1,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"What rewards are available at Jimmy John’s?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-3\", \"index\": 3, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-3-AnswerSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Place an order via the Jimmy John’s app or the Jimmy John’s website to order for delivery or pick up from your local Jimmy John’s.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Place an order via the Jimmy John’s app or the Jimmy John’s website to order for delivery or pick up from your local Jimmy John’s.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-3-QuestionSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

How does Jimmy John’s Order Ahead option work?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":1,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"How does Jimmy John’s Order Ahead option work?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-4\", \"index\": 4, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-4-AnswerSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Earn a free sandwich after your first order with Jimmy John’s Rewards™.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Earn a free sandwich after your first order with \\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1},{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Jimmy John’s Rewards™\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"link\\\",\\\"version\\\":1,\\\"rel\\\":\\\"noopener\\\",\\\"target\\\":null,\\\"url\\\":\\\"https://www.jimmyjohns.com/rewards\\\"},{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\".\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-4-QuestionSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

How do I get a free sandwich from Jimmy John’s?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":1,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"How do I get a free sandwich from Jimmy John’s?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-5\", \"index\": 5, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-5-AnswerSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Jimmy John’s Plain Slims® and Little Johns® are perfect sandwich options for kids.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Jimmy John’s \\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1},{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Plain Slims®\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"link\\\",\\\"version\\\":1,\\\"rel\\\":null,\\\"target\\\":\\\"_blank\\\",\\\"url\\\":\\\"https://www.jimmyjohns.com/menu/slims/\\\"},{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\" and \\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1},{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Little Johns®\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"link\\\",\\\"version\\\":1,\\\"rel\\\":null,\\\"target\\\":\\\"_blank\\\",\\\"url\\\":\\\"https://www.jimmyjohns.com/menu/littlejohns/\\\"},{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\" are perfect sandwich options for kids.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-5-QuestionSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Does Jimmy John’s have a kid’s menu?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":1,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Does Jimmy John’s have a kid’s menu?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-6\", \"index\": 6, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-6-AnswerSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Order your favorite sandwich as an Unwich® and we’ll replace the bread with a tasty lettuce wrap.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Order your favorite sandwich as an Unwich® and we’ll replace the bread with a tasty lettuce wrap.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-6-QuestionSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

What is Jimmy John's Unwich?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":1,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"What is Jimmy John's Unwich?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-7\", \"index\": 7, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-7-AnswerSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Yes, your local Jimmy John’s does have an indoor seating area.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Yes, your local Jimmy John’s does have an indoor seating area.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSection-dadbc552-4769-4f23-a2d1-0d8906b25751-Card-7-QuestionSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Does Jimmy John's at [[address.line1]] in Columbus have an indoor seating area?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":1,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Does Jimmy John's at [[address.line1]] in Columbus have an indoor seating area?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}]}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-tertiary-light\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"faqsSection\"}, \"liveVisibility\": true}}, {\"type\": \"Grid\", \"props\": {\"id\": \"Grid-df8a9f06-60a5-43c5-b88b-611eb377d610\", \"align\": \"center\", \"slots\": [{\"Column\": [{\"type\": \"HeadingText\", \"props\": {\"id\": \"HeadingText-b926fd36-dd92-4c7f-a87e-14433c0cf95f\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"FEATURED PRODUCTS\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}, {\"type\": \"TextList\", \"props\": {\"id\": \"TextList-d034270f-e2c7-48b2-a0b6-35f58da58c6f\", \"list\": {\"field\": \"\", \"constantValue\": [{\"en\": \"These are some of our classic fan favorites!\", \"hasLocalizedValue\": \"true\"}], \"constantValueEnabled\": true}, \"commaSeparated\": true}}, {\"type\": \"CTAWrapper\", \"props\": {\"id\": \"CTAWrapper-9096f339-cba9-4098-a4d5-dd765eb7411a\", \"data\": {\"entityField\": {\"field\": \"\", \"selectedType\": \"textAndLink\", \"constantValue\": {\"link\": \"https://www.jimmyjohns.com/menu\", \"label\": {\"en\": \"View full menu\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}}}]}, {\"Column\": []}, {\"Column\": []}], \"columns\": 1, \"analytics\": {\"scope\": \"gridSection\"}, \"liveVisibility\": true, \"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}}, {\"type\": \"Grid\", \"props\": {\"id\": \"Grid-e2154cc8-c357-42ca-8df7-b95f6c1b8ef9\", \"align\": \"left\", \"slots\": [{\"Column\": [{\"type\": \"ImageWrapper\", \"props\": {\"id\": \"ImageWrapper-58747fd4-d447-456f-aead-238d357dc70f\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://a.mktgcdn.com/p/bQ2KhMeuQiCHTfYO1jJowvYu21R_fQ2jzLdXfYsD8ko/811x456.png\", \"width\": 811, \"height\": 456, \"assetImage\": {\"id\": \"22251974\", \"name\": \"9 italian night club\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/bQ2KhMeuQiCHTfYO1jJowvYu21R_fQ2jzLdXfYsD8ko/811x456.png\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/bQ2KhMeuQiCHTfYO1jJowvYu21R_fQ2jzLdXfYsD8ko/811x456.png\", \"dimension\": {\"width\": 811, \"height\": 456}}, {\"url\": \"//a.mktgcdn.com/p/bQ2KhMeuQiCHTfYO1jJowvYu21R_fQ2jzLdXfYsD8ko/619x348.png\", \"dimension\": {\"width\": 619, \"height\": 348}}, {\"url\": \"//a.mktgcdn.com/p/bQ2KhMeuQiCHTfYO1jJowvYu21R_fQ2jzLdXfYsD8ko/600x337.png\", \"dimension\": {\"width\": 600, \"height\": 337}}, {\"url\": \"//a.mktgcdn.com/p/bQ2KhMeuQiCHTfYO1jJowvYu21R_fQ2jzLdXfYsD8ko/196x110.png\", \"dimension\": {\"width\": 196, \"height\": 110}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/bQ2KhMeuQiCHTfYO1jJowvYu21R_fQ2jzLdXfYsD8ko/811x456.png\", \"dimension\": {\"width\": 811, \"height\": 456}}}, \"alternateText\": {\"en\": \"9 italian club\", \"hasLocalizedValue\": \"true\"}}, \"constantValueEnabled\": true}}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"allowWidthProp\": true}}, {\"type\": \"CTAWrapper\", \"props\": {\"id\": \"CTAWrapper-ae3a81f1-9bd1-4674-8229-b5c5cb73a5cd\", \"data\": {\"entityField\": {\"field\": \"\", \"selectedType\": \"textAndLink\", \"constantValue\": {\"link\": \"https://www.jimmyjohns.com/menu/favorites-sandwiches/italian-night-club\", \"label\": {\"en\": \"#9 Italian Night club\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"link\", \"presetImage\": \"app-store\"}}}, {\"type\": \"ImageWrapper\", \"props\": {\"id\": \"ImageWrapper-42407c51-31b0-4155-8dab-763a924f6ef9\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://a.mktgcdn.com/p/q5kvBZldmEih5Gqan4qwhcM6Hd8-aZ938QNAZ3PMSEE/790x444.png\", \"width\": 790, \"height\": 444, \"assetImage\": {\"id\": \"22251969\", \"name\": \"4 TURKEY TOM\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/q5kvBZldmEih5Gqan4qwhcM6Hd8-aZ938QNAZ3PMSEE/790x444.png\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/q5kvBZldmEih5Gqan4qwhcM6Hd8-aZ938QNAZ3PMSEE/790x444.png\", \"dimension\": {\"width\": 790, \"height\": 444}}, {\"url\": \"//a.mktgcdn.com/p/q5kvBZldmEih5Gqan4qwhcM6Hd8-aZ938QNAZ3PMSEE/619x348.png\", \"dimension\": {\"width\": 619, \"height\": 348}}, {\"url\": \"//a.mktgcdn.com/p/q5kvBZldmEih5Gqan4qwhcM6Hd8-aZ938QNAZ3PMSEE/600x337.png\", \"dimension\": {\"width\": 600, \"height\": 337}}, {\"url\": \"//a.mktgcdn.com/p/q5kvBZldmEih5Gqan4qwhcM6Hd8-aZ938QNAZ3PMSEE/196x110.png\", \"dimension\": {\"width\": 196, \"height\": 110}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/q5kvBZldmEih5Gqan4qwhcM6Hd8-aZ938QNAZ3PMSEE/790x444.png\", \"dimension\": {\"width\": 790, \"height\": 444}}}, \"alternateText\": {\"en\": \"Turkey Tom\", \"hasLocalizedValue\": \"true\"}}, \"constantValueEnabled\": true}}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"allowWidthProp\": true}}, {\"type\": \"CTAWrapper\", \"props\": {\"id\": \"CTAWrapper-2c40b1a5-6c71-4b35-ad43-9bf8157e51b4\", \"data\": {\"entityField\": {\"field\": \"\", \"selectedType\": \"textAndLink\", \"constantValue\": {\"link\": \"https://www.jimmyjohns.com/menu/originals/turkey-tom\", \"label\": {\"en\": \"#4 Turkey Tom\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"link\", \"presetImage\": \"app-store\"}}}]}, {\"Column\": [{\"type\": \"ImageWrapper\", \"props\": {\"id\": \"ImageWrapper-a7b59c5e-2d15-4609-ba52-9d83ce9515c3\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://a.mktgcdn.com/p/1zU-4zEFiX9F_IK8lqegy6GhtynejvrR2uxRKMjpwO0/844x475.png\", \"width\": 844, \"height\": 475, \"assetImage\": {\"id\": \"22251971\", \"name\": \"12 beach club\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/1zU-4zEFiX9F_IK8lqegy6GhtynejvrR2uxRKMjpwO0/844x475.png\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/1zU-4zEFiX9F_IK8lqegy6GhtynejvrR2uxRKMjpwO0/844x475.png\", \"dimension\": {\"width\": 844, \"height\": 475}}, {\"url\": \"//a.mktgcdn.com/p/1zU-4zEFiX9F_IK8lqegy6GhtynejvrR2uxRKMjpwO0/619x348.png\", \"dimension\": {\"width\": 619, \"height\": 348}}, {\"url\": \"//a.mktgcdn.com/p/1zU-4zEFiX9F_IK8lqegy6GhtynejvrR2uxRKMjpwO0/600x338.png\", \"dimension\": {\"width\": 600, \"height\": 338}}, {\"url\": \"//a.mktgcdn.com/p/1zU-4zEFiX9F_IK8lqegy6GhtynejvrR2uxRKMjpwO0/196x110.png\", \"dimension\": {\"width\": 196, \"height\": 110}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/1zU-4zEFiX9F_IK8lqegy6GhtynejvrR2uxRKMjpwO0/844x475.png\", \"dimension\": {\"width\": 844, \"height\": 475}}}, \"alternateText\": {\"en\": \"12 beach club\", \"hasLocalizedValue\": \"true\"}}, \"constantValueEnabled\": true}}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"allowWidthProp\": true}}, {\"type\": \"CTAWrapper\", \"props\": {\"id\": \"CTAWrapper-b8d33aaa-89a2-477e-8083-0c246d7dcea0\", \"data\": {\"entityField\": {\"field\": \"\", \"selectedType\": \"textAndLink\", \"constantValue\": {\"link\": \"https://www.jimmyjohns.com/menu/favorites/beach-club\", \"label\": {\"en\": \"#12 Beach Club\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"link\", \"presetImage\": \"app-store\"}}}, {\"type\": \"ImageWrapper\", \"props\": {\"id\": \"ImageWrapper-db3a6e0c-658a-408f-beed-833ca0d65c25\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://a.mktgcdn.com/p/-JdztcQDFJhzugsCyeDBICYwQ4P3eK-YtuqzMgwEo04/802x451.png\", \"width\": 802, \"height\": 451, \"assetImage\": {\"id\": \"22251973\", \"name\": \"16 club lulu\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/-JdztcQDFJhzugsCyeDBICYwQ4P3eK-YtuqzMgwEo04/802x451.png\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/-JdztcQDFJhzugsCyeDBICYwQ4P3eK-YtuqzMgwEo04/802x451.png\", \"dimension\": {\"width\": 802, \"height\": 451}}, {\"url\": \"//a.mktgcdn.com/p/-JdztcQDFJhzugsCyeDBICYwQ4P3eK-YtuqzMgwEo04/619x348.png\", \"dimension\": {\"width\": 619, \"height\": 348}}, {\"url\": \"//a.mktgcdn.com/p/-JdztcQDFJhzugsCyeDBICYwQ4P3eK-YtuqzMgwEo04/600x337.png\", \"dimension\": {\"width\": 600, \"height\": 337}}, {\"url\": \"//a.mktgcdn.com/p/-JdztcQDFJhzugsCyeDBICYwQ4P3eK-YtuqzMgwEo04/196x110.png\", \"dimension\": {\"width\": 196, \"height\": 110}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/-JdztcQDFJhzugsCyeDBICYwQ4P3eK-YtuqzMgwEo04/802x451.png\", \"dimension\": {\"width\": 802, \"height\": 451}}}, \"alternateText\": {\"en\": \"16 club lulu\", \"hasLocalizedValue\": \"true\"}}, \"constantValueEnabled\": true}}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"allowWidthProp\": true}}, {\"type\": \"CTAWrapper\", \"props\": {\"id\": \"CTAWrapper-1c943f0d-c385-4f52-ace1-6a1e089bc8aa\", \"data\": {\"entityField\": {\"field\": \"\", \"selectedType\": \"textAndLink\", \"constantValue\": {\"link\": \"https://www.jimmyjohns.com/menu/favorites-sandwiches/club-lulu\", \"label\": {\"en\": \"#16 Club Lulu\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"link\", \"presetImage\": \"app-store\"}}}]}, {\"Column\": [{\"type\": \"ImageWrapper\", \"props\": {\"id\": \"ImageWrapper-0ab0dd1b-3133-4072-a69e-b821988d3eff\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://a.mktgcdn.com/p/xvWg4H6A2MguRgeF__dhRgC3klJC_g19_cxP-CY7lwU/780x439.png\", \"width\": 780, \"height\": 439, \"assetImage\": {\"id\": \"22251972\", \"name\": \"11 country club\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/xvWg4H6A2MguRgeF__dhRgC3klJC_g19_cxP-CY7lwU/780x439.png\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/xvWg4H6A2MguRgeF__dhRgC3klJC_g19_cxP-CY7lwU/780x439.png\", \"dimension\": {\"width\": 780, \"height\": 439}}, {\"url\": \"//a.mktgcdn.com/p/xvWg4H6A2MguRgeF__dhRgC3klJC_g19_cxP-CY7lwU/619x348.png\", \"dimension\": {\"width\": 619, \"height\": 348}}, {\"url\": \"//a.mktgcdn.com/p/xvWg4H6A2MguRgeF__dhRgC3klJC_g19_cxP-CY7lwU/600x338.png\", \"dimension\": {\"width\": 600, \"height\": 338}}, {\"url\": \"//a.mktgcdn.com/p/xvWg4H6A2MguRgeF__dhRgC3klJC_g19_cxP-CY7lwU/196x110.png\", \"dimension\": {\"width\": 196, \"height\": 110}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/xvWg4H6A2MguRgeF__dhRgC3klJC_g19_cxP-CY7lwU/780x439.png\", \"dimension\": {\"width\": 780, \"height\": 439}}}, \"alternateText\": {\"en\": \"11 country club\", \"hasLocalizedValue\": \"true\"}}, \"constantValueEnabled\": true}}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"allowWidthProp\": true}}, {\"type\": \"CTAWrapper\", \"props\": {\"id\": \"CTAWrapper-1e76bb2c-3dbb-4a3a-88f1-737c1ddc83fa\", \"data\": {\"entityField\": {\"field\": \"\", \"selectedType\": \"textAndLink\", \"constantValue\": {\"link\": \"https://www.jimmyjohns.com/menu/favorites-sandwiches/country-club\", \"label\": {\"en\": \"#11 Country Club\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"link\", \"presetImage\": \"app-store\"}}}, {\"type\": \"ImageWrapper\", \"props\": {\"id\": \"ImageWrapper-5d140b8b-1106-48df-bb55-10dd01fbb77d\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://a.mktgcdn.com/p/Q8UEmC-OEMueFQ6JOUmYP7zQiWlwYAYYEwH9I4W7-rM/789x444.png\", \"width\": 789, \"height\": 444, \"assetImage\": {\"id\": \"22251970\", \"name\": \"5 vito\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/Q8UEmC-OEMueFQ6JOUmYP7zQiWlwYAYYEwH9I4W7-rM/789x444.png\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/Q8UEmC-OEMueFQ6JOUmYP7zQiWlwYAYYEwH9I4W7-rM/789x444.png\", \"dimension\": {\"width\": 789, \"height\": 444}}, {\"url\": \"//a.mktgcdn.com/p/Q8UEmC-OEMueFQ6JOUmYP7zQiWlwYAYYEwH9I4W7-rM/619x348.png\", \"dimension\": {\"width\": 619, \"height\": 348}}, {\"url\": \"//a.mktgcdn.com/p/Q8UEmC-OEMueFQ6JOUmYP7zQiWlwYAYYEwH9I4W7-rM/600x338.png\", \"dimension\": {\"width\": 600, \"height\": 338}}, {\"url\": \"//a.mktgcdn.com/p/Q8UEmC-OEMueFQ6JOUmYP7zQiWlwYAYYEwH9I4W7-rM/196x110.png\", \"dimension\": {\"width\": 196, \"height\": 110}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/Q8UEmC-OEMueFQ6JOUmYP7zQiWlwYAYYEwH9I4W7-rM/789x444.png\", \"dimension\": {\"width\": 789, \"height\": 444}}}, \"alternateText\": {\"en\": \"5vito\", \"hasLocalizedValue\": \"true\"}}, \"constantValueEnabled\": true}}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"allowWidthProp\": true}}, {\"type\": \"CTAWrapper\", \"props\": {\"id\": \"CTAWrapper-54c3ad97-fbef-47e2-ba6b-c0e0c659373c\", \"data\": {\"entityField\": {\"field\": \"\", \"selectedType\": \"textAndLink\", \"constantValue\": {\"link\": \"https://www.jimmyjohns.com/menu/originals-sandwiches/vito\", \"label\": {\"en\": \"#5 Vito\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"link\", \"presetImage\": \"app-store\"}}}]}], \"columns\": 3, \"analytics\": {\"scope\": \"gridSection\"}, \"liveVisibility\": true, \"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}}, {\"type\": \"PromoSection\", \"props\": {\"id\": \"PromoSection-62505170-7417-4250-80b2-ace68e188a56\", \"data\": {\"promo\": {\"field\": \"\", \"constantValue\": {}, \"constantValueEnabled\": true}}, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"PromoSection-62505170-7417-4250-80b2-ace68e188a56-CTASlot\", \"data\": {\"entityField\": {\"field\": \"\", \"selectedType\": \"type.cta\", \"constantValue\": {\"link\": \"https://careers.jimmyjohns.com/us/en?utm_source=Location%20Pages&utm_medium=Owned&utm_campaign=Evergreen\", \"label\": {\"en\": \"APPLY NOW\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\"}, \"eventName\": \"cta\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"PromoSection-62505170-7417-4250-80b2-ace68e188a56-ImageSlot\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://a.mktgcdn.com/p/rC0QIYsFP_prCw-4I0FyXbJXG8clmLK740jwotVVy5I/1288x801.jpg\", \"width\": 1288, \"height\": 801, \"assetImage\": {\"id\": \"22251966\", \"name\": \"JJ's Hiring\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/rC0QIYsFP_prCw-4I0FyXbJXG8clmLK740jwotVVy5I/1288x801.jpg\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/rC0QIYsFP_prCw-4I0FyXbJXG8clmLK740jwotVVy5I/1288x801.jpg\", \"dimension\": {\"width\": 1288, \"height\": 801}}, {\"url\": \"//a.mktgcdn.com/p/rC0QIYsFP_prCw-4I0FyXbJXG8clmLK740jwotVVy5I/619x385.jpg\", \"dimension\": {\"width\": 619, \"height\": 385}}, {\"url\": \"//a.mktgcdn.com/p/rC0QIYsFP_prCw-4I0FyXbJXG8clmLK740jwotVVy5I/600x373.jpg\", \"dimension\": {\"width\": 600, \"height\": 373}}, {\"url\": \"//a.mktgcdn.com/p/rC0QIYsFP_prCw-4I0FyXbJXG8clmLK740jwotVVy5I/196x122.jpg\", \"dimension\": {\"width\": 196, \"height\": 122}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/rC0QIYsFP_prCw-4I0FyXbJXG8clmLK740jwotVVy5I/1288x801.jpg\", \"dimension\": {\"width\": 1288, \"height\": 801}}}, \"alternateText\": {\"en\": \"Jimmy John's Hiring\", \"hasLocalizedValue\": \"true\"}}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"width\", \"md\": \"min(width, 450px)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"className\": \"max-w-full sm:max-w-initial md:max-w-[450px] lg:max-w-none rounded-image-borderRadius w-full\"}}], \"VideoSlot\": [{\"type\": \"VideoSlot\", \"props\": {\"id\": \"PromoSection-62505170-7417-4250-80b2-ace68e188a56-VideoSlot\", \"data\": {\"assetVideo\": {}}}}], \"HeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"PromoSection-62505170-7417-4250-80b2-ace68e188a56-HeadingSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"WE'RE HIRING!\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"PromoSection-62505170-7417-4250-80b2-ace68e188a56-DescriptionSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Join our team and become a sandwich master! Now hiring for bike delivery, sandwich makers and managers. Competitive pay and flexible hours available. Visit your Jimmy John's in [[address.city]] or click the link to apply today.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Join our team and become a sandwich master! Now hiring for bike delivery, sandwich makers and managers. Competitive pay and flexible hours available. Visit your Jimmy John's in \\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1},{\\\"text\\\":\\\"address.city\\\",\\\"rawText\\\":\\\"address.city\\\",\\\"format\\\":0,\\\"style\\\":\\\"\\\",\\\"mode\\\":\\\"token\\\",\\\"detail\\\":0,\\\"type\\\":\\\"embedkey\\\",\\\"version\\\":1},{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\" or click the link to apply today.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}, \"styles\": {\"image\": {\"aspectRatio\": 1.78}, \"orientation\": \"left\", \"backgroundColor\": {\"bgColor\": \"bg-palette-tertiary-light\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"promoSection\"}, \"liveVisibility\": true}, \"readOnly\": {\"data.media\": false}}, {\"type\": \"NearbyLocationsSection\", \"props\": {\"id\": \"NearbyLocationsSection-e7a2620d-750a-4ad4-b818-919eb5f232dc\", \"slots\": {\"CardsWrapperSlot\": [{\"type\": \"NearbyLocationCardsWrapper\", \"props\": {\"id\": \"NearbyLocationsSection-e7a2620d-750a-4ad4-b818-919eb5f232dc-CardsWrapperSlot\", \"data\": {\"limit\": 3, \"radius\": 10, \"coordinate\": {\"field\": \"yextDisplayCoordinate\", \"constantValue\": {\"latitude\": 0, \"longitude\": 0}}}, \"styles\": {\"hours\": {\"timeFormat\": \"12h\", \"showDayNames\": true, \"dayOfWeekFormat\": \"long\", \"showCurrentStatus\": true}, \"phone\": {\"phoneNumberLink\": true, \"phoneNumberFormat\": \"domestic\"}, \"headingLevel\": 3, \"backgroundColor\": {\"bgColor\": \"bg-palette-tertiary-light\", \"textColor\": \"text-black\"}}, \"sectionHeadingLevel\": 3}}], \"SectionHeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"NearbyLocationsSection-e7a2620d-750a-4ad4-b818-919eb5f232dc-SectionHeadingSlot\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"OTHER LOCATIONS\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"nearbyLocationsSection\"}, \"liveVisibility\": true}}, {\"type\": \"ExpandedFooter\", \"props\": {\"id\": \"ExpandedFooter-edbfdaa2-b232-437f-87ef-6ce8a2563b25\", \"data\": {\"primaryFooter\": {\"expandedFooter\": true}, \"secondaryFooter\": {\"show\": true, \"copyrightMessage\": {\"en\": \"TM & © 2025 Jimmy John's Franchisor SPV, LLC All Rights Reserved.\", \"hasLocalizedValue\": \"true\"}, \"secondaryFooterLinks\": [{\"link\": \"https://www.jimmyjohns.com/terms-and-conditions\", \"label\": {\"en\": \"Terms & Conditions\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/ad-cookie-policy\", \"label\": {\"en\": \"Ad & Cookie Policy\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/privacy-policy\", \"label\": {\"en\": \"Privacy Policy\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://bigidprivacy.cloud/consumer/#/EnSBtJyXmT/Form-NJkZtUEqYjcmwwr\", \"label\": {\"en\": \"Your Privacy Choices\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/accessibility\", \"label\": {\"en\": \"Accessibility Statement\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/california-transparency-in-supply-chain-act\", \"label\": {\"en\": \"CA Supply Chains Act\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://locations.jimmyjohns.com/\", \"label\": {\"en\": \"All JJ's Locations\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/consumer-health-data\", \"label\": {\"en\": \"Consumer Health Data\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/sitemap\", \"label\": {\"en\": \"Sitemap\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}}, \"slots\": {\"LogoSlot\": [{\"type\": \"FooterLogoSlot\", \"props\": {\"id\": \"ExpandedFooter-edbfdaa2-b232-437f-87ef-6ce8a2563b25-FooterLogoSlot\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://a.mktgcdn.com/p/Zc2wyXeP8N88ZSfgJqFHE2UAgD94JwmbKpKl_Juz1Vc/472x473.jpg\", \"width\": 472, \"height\": 473, \"assetImage\": {\"id\": \"22251942\", \"name\": \"Jimmy John's white logo\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/Zc2wyXeP8N88ZSfgJqFHE2UAgD94JwmbKpKl_Juz1Vc/472x473.jpg\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/Zc2wyXeP8N88ZSfgJqFHE2UAgD94JwmbKpKl_Juz1Vc/472x473.jpg\", \"dimension\": {\"width\": 472, \"height\": 473}}, {\"url\": \"//a.mktgcdn.com/p/Zc2wyXeP8N88ZSfgJqFHE2UAgD94JwmbKpKl_Juz1Vc/449x450.jpg\", \"dimension\": {\"width\": 449, \"height\": 450}}, {\"url\": \"//a.mktgcdn.com/p/Zc2wyXeP8N88ZSfgJqFHE2UAgD94JwmbKpKl_Juz1Vc/196x196.jpg\", \"dimension\": {\"width\": 196, \"height\": 196}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/Zc2wyXeP8N88ZSfgJqFHE2UAgD94JwmbKpKl_Juz1Vc/472x473.jpg\", \"dimension\": {\"width\": 472, \"height\": 473}}}, \"alternateText\": {\"en\": \"Jimmy John's sandwiches\", \"hasLocalizedValue\": \"true\"}}, \"constantValueEnabled\": true}}, \"styles\": {\"width\": 150, \"aspectRatio\": 1}}}], \"SocialLinksSlot\": [{\"type\": \"FooterSocialLinksSlot\", \"props\": {\"id\": \"ExpandedFooter-edbfdaa2-b232-437f-87ef-6ce8a2563b25-FooterSocialLinksSlot\", \"data\": {\"xLink\": \"https://twitter.com/jimmyjohns\", \"tiktokLink\": \"\", \"youtubeLink\": \"https://www.youtube.com/user/jimmyjohns\", \"facebookLink\": \"https://www.facebook.com/jimmyjohns/\", \"linkedInLink\": \"\", \"instagramLink\": \"https://www.instagram.com/jimmyjohns/\", \"pinterestLink\": \"\"}}}], \"UtilityImagesSlot\": [{\"type\": \"FooterUtilityImagesSlot\", \"props\": {\"id\": \"ExpandedFooter-edbfdaa2-b232-437f-87ef-6ce8a2563b25-FooterUtilityImagesSlot\", \"data\": {\"utilityImages\": [{\"image\": {\"url\": \"https://a.mktgcdn.com/p/pQ2yCUWnfqw2_52yrLtUuf1sNMvmdVM-4IJ2ieVIhIc/390x129.png\", \"width\": 390, \"height\": 129, \"assetImage\": {\"id\": \"22251943\", \"name\": \"App Store\", \"altText\": \"\", \"sourceUrl\": \"https://a.mktgcdn.com/p/pQ2yCUWnfqw2_52yrLtUuf1sNMvmdVM-4IJ2ieVIhIc/390x129.png\", \"childImages\": [{\"url\": \"//a.mktgcdn.com/p/pQ2yCUWnfqw2_52yrLtUuf1sNMvmdVM-4IJ2ieVIhIc/390x129.png\", \"dimension\": {\"width\": 390, \"height\": 129}}, {\"url\": \"//a.mktgcdn.com/p/pQ2yCUWnfqw2_52yrLtUuf1sNMvmdVM-4IJ2ieVIhIc/196x65.png\", \"dimension\": {\"width\": 196, \"height\": 65}}], \"originalImage\": null, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/pQ2yCUWnfqw2_52yrLtUuf1sNMvmdVM-4IJ2ieVIhIc/390x129.png\", \"dimension\": {\"width\": 390, \"height\": 129}}}, \"alternateText\": {\"en\": \"Download From app Store\", \"hasLocalizedValue\": \"true\"}}, \"linkTarget\": \"https://apps.apple.com/us/app/jimmy-johns-in-app-ordering/id409366411\"}, {\"image\": {\"url\": \"https://a.mktgcdn.com/p/8WlnXc3NgPqYYJOXQ4cciv_7m48_cxgevDwv1NojZl0/420x125.png\", \"width\": 420, \"height\": 125, \"assetImage\": {\"id\": \"22251944\", \"name\": \"play store\", \"sourceUrl\": \"\", \"childImages\": [{\"url\": \"https://a.mktgcdn.com/p/8WlnXc3NgPqYYJOXQ4cciv_7m48_cxgevDwv1NojZl0/420x125.png\", \"dimension\": {\"width\": 420, \"height\": 125}}], \"originalImage\": {\"url\": \"https://a.mktgcdn.com/p/QWDVaRhi4Uv2v4JNDlHzKpr846zp5bVOAK1kOw6ShAQ/420x125.png\", \"dimension\": {\"width\": 420, \"height\": 125}, \"exifMetadata\": {\"rotate\": 0}}, \"transformations\": {}, \"transformedImage\": {\"url\": \"https://a.mktgcdn.com/p/8WlnXc3NgPqYYJOXQ4cciv_7m48_cxgevDwv1NojZl0/420x125.png\", \"dimension\": {\"width\": 420, \"height\": 125}}}, \"alternateText\": {\"en\": \"Get it on Google Play\", \"hasLocalizedValue\": \"true\"}}, \"linkTarget\": \"https://play.google.com/store/apps/details?id=com.jimmyjohns\"}]}, \"styles\": {\"width\": 100, \"aspectRatio\": 4}}}], \"SecondaryFooterSlot\": [{\"type\": \"SecondaryFooterSlot\", \"props\": {\"id\": \"ExpandedFooter-edbfdaa2-b232-437f-87ef-6ce8a2563b25-SecondaryFooterSlot\", \"data\": {\"show\": true}, \"slots\": {\"CopyrightSlot\": [{\"type\": \"CopyrightMessageSlot\", \"props\": {\"id\": \"ExpandedFooter-edbfdaa2-b232-437f-87ef-6ce8a2563b25-CopyrightSlot\", \"data\": {\"text\": {\"en\": \"TM & © 2025 Jimmy John's Franchisor SPV, LLC All Rights Reserved.\", \"hasLocalizedValue\": \"true\"}}, \"alignment\": \"left\"}}], \"SecondaryLinksWrapperSlot\": [{\"type\": \"FooterLinksSlot\", \"props\": {\"id\": \"ExpandedFooter-edbfdaa2-b232-437f-87ef-6ce8a2563b25-FooterSecondaryLinksSlot\", \"data\": {\"links\": [{\"link\": \"https://www.jimmyjohns.com/terms-and-conditions\", \"label\": {\"en\": \"Terms & Conditions\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/ad-cookie-policy\", \"label\": {\"en\": \"Ad & Cookie Policy\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/privacy-policy\", \"label\": {\"en\": \"Privacy Policy\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://bigidprivacy.cloud/consumer/#/EnSBtJyXmT/Form-NJkZtUEqYjcmwwr\", \"label\": {\"en\": \"Your Privacy Choices\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/accessibility\", \"label\": {\"en\": \"Accessibility Statement\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/california-transparency-in-supply-chain-act\", \"label\": {\"en\": \"CA Supply Chains Act\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://locations.jimmyjohns.com/\", \"label\": {\"en\": \"All JJ's Locations\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/consumer-health-data\", \"label\": {\"en\": \"Consumer Health Data\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://locations.jimmyjohns.com/sitemap.xml\", \"label\": {\"en\": \"Sitemap\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}, \"variant\": \"secondary\", \"alignment\": \"left\", \"eventNamePrefix\": \"secondary\"}}]}, \"styles\": {\"linksAlignment\": \"left\", \"backgroundColor\": {\"bgColor\": \"bg-palette-tertiary\", \"textColor\": \"text-palette-tertiary-contrast\"}}, \"maxWidth\": \"theme\", \"ignoreLocaleWarning\": []}}], \"PrimaryLinksWrapperSlot\": [{\"type\": \"FooterLinksSlot\", \"props\": {\"id\": \"ExpandedFooter-edbfdaa2-b232-437f-87ef-6ce8a2563b25-FooterPrimaryLinksSlot\", \"data\": {\"links\": [{\"link\": \"#\", \"label\": {\"en\": \"Footer Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Footer Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Footer Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Footer Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Footer Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}, \"variant\": \"primary\", \"eventNamePrefix\": \"primary\"}}], \"ExpandedLinksWrapperSlot\": [{\"type\": \"FooterExpandedLinksWrapper\", \"props\": {\"id\": \"ExpandedFooter-edbfdaa2-b232-437f-87ef-6ce8a2563b25-FooterExpandedLinksWrapper\", \"data\": {\"sections\": [{\"label\": {\"en\": \"OUR MENU\", \"hasLocalizedValue\": \"true\"}, \"links\": [{\"link\": \"https://www.jimmyjohns.com/documents/print-menu\", \"label\": {\"en\": \"Print Menu (PDF)\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/documents/print-catering-menu\", \"label\": {\"en\": \"Print Catering Menu (PDF)\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/documents/allergen-info\", \"label\": {\"en\": \"Allergen Info (PDF)\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/documents/nutrition-info\", \"label\": {\"en\": \"Nutrition Guide (PDF)\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}, {\"label\": {\"en\": \"ABOUT US\", \"hasLocalizedValue\": \"true\"}, \"links\": [{\"link\": \"https://www.jimmyjohns.com/our-food\", \"label\": {\"en\": \"Our Food\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/company-history\", \"label\": {\"en\": \"History\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/faq\", \"label\": {\"en\": \"FAQs\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohnsfranchising.com/\", \"label\": {\"en\": \"Franchising\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://careers.jimmyjohns.com/\", \"label\": {\"en\": \"Careers\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/jimmyjohnsfoundation\", \"label\": {\"en\": \"Foundation\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/contact-us/feedback\", \"label\": {\"en\": \"Feedback\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}, {\"label\": {\"en\": \"MORE JJ'S\", \"hasLocalizedValue\": \"true\"}, \"links\": [{\"link\": \"https://www.jimmyjohns.com/promos\", \"label\": {\"en\": \"Promos\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://www.jimmyjohns.com/gift-cards\", \"label\": {\"en\": \"Gift Cards\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"https://store.jimmyjohns.com/\", \"label\": {\"en\": \"JJ Swag\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}]}}}]}, \"styles\": {\"maxWidth\": \"theme\", \"primaryFooter\": {\"logo\": {\"width\": 150, \"aspectRatio\": 1}, \"utilityImages\": {\"width\": 100, \"aspectRatio\": 4}, \"linksAlignment\": \"right\", \"backgroundColor\": {\"bgColor\": \"bg-palette-secondary\", \"textColor\": \"text-palette-secondary-contrast\"}}, \"secondaryFooter\": {\"linksAlignment\": \"left\", \"backgroundColor\": {\"bgColor\": \"bg-palette-tertiary\", \"textColor\": \"text-palette-tertiary-contrast\"}}}, \"analytics\": {\"scope\": \"expandedFooter\"}, \"ignoreLocaleWarning\": [\"slots.PrimaryLinksWrapperSlot\"]}}]}", + "name": "location-pages", + "theme": "{\"--display-link-caret\": \"none\", \"--fontSize-h1-fontSize\": \"32px\", \"--fontSize-h2-fontSize\": \"40px\", \"--fontSize-h3-fontSize\": \"32px\", \"--fontSize-h4-fontSize\": \"24px\", \"--fontSize-h5-fontSize\": \"20px\", \"--fontSize-h6-fontSize\": \"18px\", \"--colors-palette-primary\": \"#e4002b\", \"--fontSize-body-fontSize\": \"18px\", \"--fontSize-link-fontSize\": \"16px\", \"--colors-palette-tertiary\": \"#000000\", \"--colors-palette-secondary\": \"#000000\", \"--fontFamily-h1-fontFamily\": \"'Good Stuff', sans-serif\", \"--fontFamily-h2-fontFamily\": \"'Good Stuff', sans-serif\", \"--fontFamily-h3-fontFamily\": \"'Good Stuff', sans-serif\", \"--fontFamily-h4-fontFamily\": \"'Good Stuff', sans-serif\", \"--fontFamily-h5-fontFamily\": \"'Good Stuff', sans-serif\", \"--fontFamily-h6-fontFamily\": \"'Good Stuff', sans-serif\", \"--fontSize-button-fontSize\": \"20px\", \"--fontWeight-h1-fontWeight\": \"700\", \"--fontWeight-h2-fontWeight\": \"700\", \"--fontWeight-h3-fontWeight\": \"700\", \"--fontWeight-h4-fontWeight\": \"700\", \"--fontWeight-h5-fontWeight\": \"700\", \"--fontWeight-h6-fontWeight\": \"700\", \"--colors-palette-quaternary\": \"#e4002b\", \"--fontFamily-body-fontFamily\": \"'Good Stuff', sans-serif\", \"--fontFamily-link-fontFamily\": \"'Good Stuff', sans-serif\", \"--fontWeight-body-fontWeight\": \"400\", \"--fontWeight-link-fontWeight\": \"700\", \"--fontFamily-button-fontFamily\": \"'Good Stuff', sans-serif\", \"--fontWeight-button-fontWeight\": \"700\", \"--borderRadius-image-borderRadius\": \"2px\", \"--colors-palette-primary-contrast\": \"#FFFFFF\", \"--borderRadius-button-borderRadius\": \"0px\", \"--colors-palette-tertiary-contrast\": \"#FFFFFF\", \"--letterSpacing-link-letterSpacing\": \"0em\", \"--textTransform-link-textTransform\": \"none\", \"--colors-palette-secondary-contrast\": \"#FFFFFF\", \"--maxWidth-pageSection-contentWidth\": \"1280px\", \"--colors-palette-quaternary-contrast\": \"#FFFFFF\", \"--letterSpacing-button-letterSpacing\": \"0em\", \"--textTransform-button-textTransform\": \"uppercase\", \"--padding-pageSection-verticalPadding\": \"32px\"}", + "visualEditorConfig": "{}" + }, + "__certified_facts": { + "@context": [ + "https://www.w3.org/ns/credentials/v2", + "https://schema.org", + "https://w3id.org/security/data-integrity/v2", + { + "CertifiedFact": "https://yext.com/.well-known/certified-fact/" + } + ], + "credentialSchema": { + "id": "https://yext.com/.well-known/certified-fact/core-snapshot/1/schema.json", + "type": "JsonSchema" + }, + "credentialSubject": { + "address": { + "@type": "PostalAddress", + "addressCountry": "US", + "addressLocality": "Brooklyn", + "addressRegion": "NY", + "postalCode": "11201", + "streetAddress": "32 COURT ST" + }, + "asOf": "2025-12-12T23:09:08Z", + "geo": { + "@type": "GeoCoordinates", + "latitude": 40.692950911219576, + "longitude": -73.99105563703733 + }, + "name": "Jimmy John's", + "openingHoursSpecification": [ + { + "@type": "OpeningHoursSpecification", + "closes": "22:00", + "dayOfWeek": "https://schema.org/Monday", + "opens": "10:00" + }, + { + "@type": "OpeningHoursSpecification", + "closes": "22:00", + "dayOfWeek": "https://schema.org/Tuesday", + "opens": "10:00" + }, + { + "@type": "OpeningHoursSpecification", + "closes": "22:00", + "dayOfWeek": "https://schema.org/Wednesday", + "opens": "10:00" + }, + { + "@type": "OpeningHoursSpecification", + "closes": "22:00", + "dayOfWeek": "https://schema.org/Thursday", + "opens": "10:00" + }, + { + "@type": "OpeningHoursSpecification", + "closes": "22:00", + "dayOfWeek": "https://schema.org/Friday", + "opens": "10:00" + }, + { + "@type": "OpeningHoursSpecification", + "closes": "22:00", + "dayOfWeek": "https://schema.org/Saturday", + "opens": "10:00" + }, + { + "@type": "OpeningHoursSpecification", + "closes": "22:00", + "dayOfWeek": "https://schema.org/Sunday", + "opens": "10:00" + } + ], + "telephone": "+15185548556", + "url": "https://online.jimmyjohns.com/menu/jj4775/" + }, + "issuer": "did:web:yext.com", + "proof": { + "created": "2025-12-12T23:09:08Z", + "cryptosuite": "eddsa-jcs-2022", + "proofPurpose": "assertionMethod", + "proofValue": "zeU7SW1CTP5nGHy1E89BMdboz4p431xD28MoEeyL2VzGzHXCbMgE57cMprwG7BDMMhm4Tww9UuJgy91H5bfQN8ci", + "type": "DataIntegrityProof", + "verificationMethod": "did:web:yext.com#key-2025" + }, + "termsOfUse": [ + { + "purpose": "Attests facts as-of validFrom", + "type": "CertifiedFact:SnapshotTerms" + } + ], + "type": ["VerifiableCredential", "CertifiedFact:CoreSnapshot"], + "validFrom": "2025-12-12T23:09:08Z" + }, + "_additionalLayoutCategories": ["coreInformation"], + "_additionalLayoutComponents": ["CustomCodeSection"], + "_env": { + "YEXT_PUBLIC_VISUAL_EDITOR_APP_API_KEY": "fd33c34dd9f36d6b7f5f04bb5e4ba6e7", + "YEXT_VISUAL_EDITOR_REVIEWS_APP_API_KEY": "750f63fac8823ad63459e678c1657299" + }, + "_favicon": "https://a.mktgcdn.com/p/1Rceh-AVNp-91DLjqBPIx3BR7xpRdtWOX77r7EbJ-i8/96x96.png", + "_pageset": "{\"name\":\"accounts/2183737/sites/161673/branches/132038/pagesets/location-pages\",\"uid\":\"019aeb1f-4ed8-74d5-a023-c15f5f23845c\",\"codeTemplate\":\"main\",\"assignments\":[\"global\"],\"createTime\":\"2025-12-04T20:48:09Z\",\"updateTime\":\"2025-12-04T20:48:11Z\",\"scope\":{\"locales\":[\"en\"],\"savedFilters\":[\"1475492710\"],\"entityTypes\":[\"restaurant\"]},\"defaultLayout\":\"accounts/2183737/sites/161673/branches/132038/layouts/location-pages-default-layout\",\"displayName\":\"Location Pages\",\"writebackUrlField\":\"pgs_jimmyJohnSPages_locationPages_betpc_Url\",\"type\":\"ENTITY\",\"typeConfig\":{\"entityConfig\":{\"rootDirectory\":\"accounts/2183737/sites/161673/branches/132038/pagesets/location-pages-directory-root\",\"directoryManagerId\":\"1663\"}},\"config\":{\"contentEndpointId\":\"161673-132038-location-pages-Content\",\"urlTemplate\":{\"primary\":\"[[address.region]]/[[address.city]]/sandwiches-[[c_storeCode]]\"}}}", + "_schema": { + "@graph": [ + { + "@context": "https://schema.org", + "@type": "LocalBusiness", + "address": { + "@type": "PostalAddress", + "addressCountry": "US", + "addressLocality": "Brooklyn", + "addressRegion": "NY", + "postalCode": "11201", + "streetAddress": "32 COURT ST" + }, + "hasOfferCatalog": { + "@type": "OfferCatalog", + "itemListElement": [ + { + "@type": "Offer", + "itemOffered": { + "@type": "Service", + "name": "Delivery" + } + }, + { + "@type": "Offer", + "itemOffered": { + "@type": "Service", + "name": "Freaky Fast Rewards®" + } + }, + { + "@type": "Offer", + "itemOffered": { + "@type": "Service", + "name": "Catering" + } + } + ], + "name": "Services" + }, + "name": "Jimmy John's", + "openingHours": ["Mo-Su 10:00-22:00"], + "paymentAccepted": [ + "American Express", + "Discover", + "MasterCard", + "Visa" + ], + "telephone": "+15185548556" + }, + { + "@context": "https://schema.org", + "@type": "BreadcrumbList", + "itemListElement": [ + { + "@type": "ListItem", + "item": { + "@id": "/index.html", + "@type": "Thing" + }, + "name": "Location Pages Directory", + "position": 1 + }, + { + "@type": "ListItem", + "item": { + "@id": "/us", + "@type": "Thing" + }, + "name": "US", + "position": 2 + }, + { + "@type": "ListItem", + "item": { + "@id": "/us/ny", + "@type": "Thing" + }, + "name": "NY", + "position": 3 + }, + { + "@type": "ListItem", + "item": { + "@id": "/us/ny/brooklyn", + "@type": "Thing" + }, + "name": "Brooklyn", + "position": 4 + } + ] + } + ] + }, + "_yext": { + "contentDeliveryAPIDomain": "https://cdn.yextapis.com", + "managementAPIDomain": "https://api.yext.com", + "platformDomain": "https://www.yext.com" + }, + "address": { + "city": "Brooklyn", + "countryCode": "US", + "line1": "32 COURT ST", + "localizedCountryName": "United States", + "localizedRegionName": "New York", + "postalCode": "11201", + "region": "NY" + }, + "appleCompanyId": "1467556518795347456", + "businessId": 2183737, + "c_baseURL": "https://locations.jimmyjohns.com/ny/brooklyn/sandwiches-4775.html", + "c_catering": false, + "c_delivery": false, + "c_liveOnPFMPages": true, + "c_rewardsCta": { + "label": "REWARDS", + "link": "https://www.jimmyjohns.com/rewards", + "linkType": "URL" + }, + "c_storeCode": "4775", + "cityCoordinate": { + "latitude": 40.675234, + "longitude": -73.971043 + }, + "closed": false, + "dm_directoryParents_161673_132038_location_pages": [ + { + "id": "161673-132038-location-pages", + "name": "Location Pages Directory", + "slug": "index.html" + }, + { + "dm_addressCountryDisplayName": "United States", + "id": "161673-132038-location-pages_us", + "name": "US", + "slug": "us" + }, + { + "dm_addressCountryDisplayName": "United States", + "dm_addressRegionDisplayName": "New York", + "id": "161673-132038-location-pages_us_ny", + "name": "NY", + "slug": "us/ny" + }, + { + "dm_addressCountryDisplayName": "United States", + "dm_addressRegionDisplayName": "New York", + "id": "161673-132038-location-pages_us_ny_brooklyn", + "name": "Brooklyn", + "slug": "us/ny/brooklyn" + } + ], + "geocodedCoordinate": { + "latitude": 40.6929538, + "longitude": -73.9910393 + }, + "hours": { + "friday": { + "openIntervals": [ + { + "end": "22:00", + "start": "10:00" + } + ] + }, + "monday": { + "openIntervals": [ + { + "end": "22:00", + "start": "10:00" + } + ] + }, + "saturday": { + "openIntervals": [ + { + "end": "22:00", + "start": "10:00" + } + ] + }, + "sunday": { + "openIntervals": [ + { + "end": "22:00", + "start": "10:00" + } + ] + }, + "thursday": { + "openIntervals": [ + { + "end": "22:00", + "start": "10:00" + } + ] + }, + "tuesday": { + "openIntervals": [ + { + "end": "22:00", + "start": "10:00" + } + ] + }, + "wednesday": { + "openIntervals": [ + { + "end": "22:00", + "start": "10:00" + } + ] + } + }, + "id": "4775_JJ", + "isoRegionCode": "NY", + "locale": "en", + "logo": { + "clickthroughUrl": "https://www.jimmyjohns.com/", + "image": { + "alternateText": "Jimmy Johns", + "height": 1054, + "url": "https://a.mktgcdn.com/p/qxnGVjiLfwpooGtcT_X6garPzQyzljNuv0GBjnVBcXs/1054x1054.jpg", + "width": 1054 + } + }, + "mainPhone": "+15185548556", + "meta": { + "entityType": { + "id": "restaurant", + "uid": 5 + }, + "locale": "en" + }, + "name": "Jimmy John's", + "olo_advanceOrderingOnly": "false", + "olo_brand": "jimmyjohns", + "olo_curbsidePickup": "No", + "olo_daysToOrderInAdvance": "30", + "olo_deliveryArea": "TBD", + "olo_deliveryFee": "0.0", + "olo_deliveryServices": "true", + "olo_isAvailable": "false", + "olo_maximumPayInstoreOrder": "0.0", + "olo_minimumDeliveryPrice": "3.0", + "olo_minimumPickupOrder": "0.0", + "olo_mobileURL": "https://online.jimmyjohns.com/menu/jj4775/", + "olo_supportsCoupons": "true", + "olo_supportsDinein": "false", + "olo_supportsDispatch": "false", + "olo_supportsDrivethru": "false", + "olo_supportsFeedback": "true", + "olo_supportsGuestOrdering": "true", + "olo_supportsLoyalty": "true", + "olo_supportsOnlineOrdering": "Yes", + "olo_supportsSpecialInstructions": "false", + "olo_supportsSplitPayments": "true", + "olo_supportsTip": "true", + "paymentOptions": ["American Express", "Discover", "MasterCard", "Visa"], + "pickupHours": { + "friday": { + "isClosed": true + }, + "monday": { + "isClosed": true + }, + "saturday": { + "isClosed": true + }, + "sunday": { + "isClosed": true + }, + "thursday": { + "isClosed": true + }, + "tuesday": { + "isClosed": true + }, + "wednesday": { + "isClosed": true + } + }, + "ref_listings": [], + "ref_reviewsAgg": [], + "services": ["Delivery", "Freaky Fast Rewards®", "Catering"], + "siteDomain": "", + "siteId": 161673, + "siteInternalHostName": "", + "takeoutHours": { + "friday": { + "isClosed": true + }, + "monday": { + "isClosed": true + }, + "saturday": { + "isClosed": true + }, + "sunday": { + "isClosed": true + }, + "thursday": { + "isClosed": true + }, + "tuesday": { + "isClosed": true + }, + "wednesday": { + "isClosed": true + } + }, + "timezone": "America/New_York", + "uid": 2034734812, + "websiteUrl": { + "url": "https://online.jimmyjohns.com/menu/jj4775/" + }, + "yextDisplayCoordinate": { + "latitude": 40.692950911219576, + "longitude": -73.99105563703733 + }, + "yextRoutableCoordinate": { + "latitude": 40.6928748, + "longitude": -73.9908072 + } + } +} diff --git a/starter/package.json b/starter/package.json index 04bb106f9..7ab3011b9 100644 --- a/starter/package.json +++ b/starter/package.json @@ -20,7 +20,7 @@ "@heroicons/react": "^2.1.5", "@mantine/core": "^7.10.1", "@mantine/hooks": "^7.10.1", - "@measured/puck": "0.20.2", + "@measured/puck": "file:../../puck/packages/core", "@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.1.15", @@ -53,7 +53,7 @@ "@types/react": "^18.2.77", "@types/react-dom": "^18.2.25", "@vitejs/plugin-react": "^4.2.1", - "@yext/pages": "1.2.5", + "@yext/pages": "file:../../pages/packages/pages", "@yext/pages-components": "1.1.16", "@yext/visual-editor": "workspace:*", "autoprefixer": "^10.4.8", diff --git a/starter/test-renderer.mjs b/starter/test-renderer.mjs new file mode 100644 index 000000000..f3e2cd828 --- /dev/null +++ b/starter/test-renderer.mjs @@ -0,0 +1,807 @@ +#!/usr/bin/env node +/** + * Test script to invoke the renderer and see the loop logs + Puck cache growth + * + * This simulates how PagesGenerator plugin calls the renderer. + * + * Usage: node test-renderer.mjs + */ + +// Use node: prefix for Deno compatibility +import { readFileSync, existsSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import { dirname, resolve } from "node:path"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +async function testRenderer() { + try { + console.log("=".repeat(70)); + console.log("Testing Renderer Loop + Puck Cache Growth"); + console.log("=".repeat(70)); + console.log(""); + + // Check if dist folder exists + const distPath = resolve(__dirname, "dist"); + if (!existsSync(distPath)) { + console.error("❌ dist folder not found!"); + console.error(" Please build the project first: pnpm build"); + (typeof Deno !== "undefined" ? Deno.exit : process.exit)(1); + } + + // Load manifest + const manifestPath = resolve(distPath, "plugin/manifest.json"); + if (!existsSync(manifestPath)) { + console.error("❌ Manifest not found!"); + console.error(" Please build the project first: pnpm build"); + (typeof Deno !== "undefined" ? Deno.exit : process.exit)(1); + } + + const manifest = JSON.parse(readFileSync(manifestPath, "utf-8")); + console.log("✓ Manifest loaded"); + console.log( + ` Templates: ${Object.keys(manifest.serverPaths || {}).join(", ") || "none"}`, + ); + console.log(""); + + // Check renderer exists and has loop code + const rendererPath = resolve( + distPath, + "assets/renderer/templateRenderer.js", + ); + if (!existsSync(rendererPath)) { + console.error("❌ Renderer not found!"); + console.error(" Please build the project first: pnpm build"); + (typeof Deno !== "undefined" ? Deno.exit : process.exit)(1); + } + + const rendererSource = readFileSync(rendererPath, "utf-8"); + const hasLoopCode = rendererSource.includes("Iteration"); + + if (!hasLoopCode) { + console.warn("⚠ WARNING: Bundled renderer does not contain loop code!"); + console.warn( + " The loop code is in: pages/packages/pages/src/vite-plugin/build/buildStart/rendering/renderer.ts", + ); + console.warn(" Rebuild pages and this project to include it."); + console.warn(""); + } else { + console.log("✓ Renderer contains loop code - loop will execute!"); + } + console.log(""); + + // Load test data + const testDataPath = resolve( + __dirname, + "localData/dev-location-stream__en__cbafb9cd1c3e63d9814e236ba9181377.json", + ); + if (!existsSync(testDataPath)) { + console.error("❌ Test data not found!"); + (typeof Deno !== "undefined" ? Deno.exit : process.exit)(1); + } + + const testData = JSON.parse(readFileSync(testDataPath, "utf-8")); + + // Add mock product data to document to demonstrate parentData with document references + // This simulates real document data that will be referenced in parentData + // ProductCardsWrapper.resolveData expects resolveYextEntityField to return { products: [...] } + // So we need to structure the data so that c_productSection.linkedProducts returns an object with products + // IMPORTANT: The document ID is used in the PRODUCT DATA (not component IDs) + // The renderer modifies document.id per iteration (e.g., "1101-wilson-blvd-iteration-1") + // We need product data that includes the document ID so logs show which document each product comes from + const baseDocumentId = testData.id || "test-document"; + + // Create a function to generate products with consistent IDs per layout + // Product IDs are CONSISTENT, but product data (name, description) will vary per document + // This demonstrates that even with consistent IDs, different document objects are referenced in parentData + const createProductsForDocument = (docId) => [ + { + id: "product-1", // CONSISTENT ID per layout (not per document) + name: `Test Product 1 from document ${docId}`, // Data varies per document + c_productPromo: "Special Offer", + c_description: `This product data comes from document ${docId} and will be referenced in parentData`, // Data varies per document + c_coverPhoto: { + url: "https://example.com/product1.jpg", + alternateText: "Product 1", + }, + c_productCTA: { + label: "Buy Now", + link: "https://example.com/buy", + linkType: "URL", + }, + }, + { + id: "product-2", // CONSISTENT ID per layout (not per document) + name: `Test Product 2 from document ${docId}`, // Data varies per document + c_productPromo: "New Arrival", + c_description: `This product data comes from document ${docId} and will be referenced in parentData`, // Data varies per document + c_coverPhoto: { + url: "https://example.com/product2.jpg", + alternateText: "Product 2", + }, + c_productCTA: { + label: "Learn More", + link: "https://example.com/learn", + linkType: "URL", + }, + }, + ]; + + // Initialize product data with base document ID + // The renderer will modify document.id per iteration, but we need to update product data too + // Store the function so we can update product data when document ID changes + if (!testData.c_productSection) { + const products = createProductsForDocument(baseDocumentId); + + // Store as object with products property so resolveYextEntityField returns { products: [...] } + // When field is 'c_productSection.linkedProducts', findField will return this object + testData.c_productSection = { + sectionTitle: "Featured Products", + linkedProducts: { + products: products, // Wrap in object with products property + }, + }; + + console.log( + `✓ Added mock product data to document (${products.length} products)`, + ); + console.log(` Base Document ID: ${baseDocumentId}`); + console.log( + ` Note: Renderer modifies document.id per iteration (e.g., ${baseDocumentId}-iteration-1)`, + ); + console.log(` Field path: c_productSection.linkedProducts`); + console.log(` Structure: { products: [...] }`); + console.log( + ` Products: ${products.map((p) => `${p.name} (id: ${p.id})`).join(", ")}`, + ); + console.log( + ` ⚠️ Product IDs are CONSISTENT per layout (product-1, product-2)`, + ); + console.log( + ` ⚠️ Product DATA (name, description) varies per document - this is what gets referenced in parentData`, + ); + console.log( + ` ⚠️ Component IDs are CONSISTENT, Product IDs are CONSISTENT, but product DATA objects are DIFFERENT per page`, + ); + } else { + // If product data already exists, update it with current document ID + // This ensures product data reflects the document ID that will be used + const products = createProductsForDocument(baseDocumentId); + testData.c_productSection.linkedProducts.products = products; + console.log( + `✓ Updated existing product data with document ID: ${baseDocumentId}`, + ); + } + + // Use CONSISTENT component IDs across pages to demonstrate cache overwrite issue + // Even though component IDs are the same, each page has different document + // The parentData will contain references to different document objects + // This proves that cache overwriting doesn't prevent memory leaks + const componentId = "component-1"; // CONSISTENT ID - same across all pages + const productSectionId = "productSection-1"; // CONSISTENT ID + const productCardsWrapperId = "productCardsWrapper-1"; // CONSISTENT ID + + console.log( + `Using CONSISTENT component IDs to demonstrate cache overwrite:`, + ); + console.log( + ` Component IDs: ${componentId}, ${productSectionId}, ${productCardsWrapperId}`, + ); + console.log( + ` Document ID: ${baseDocumentId} (will be DIFFERENT per page iteration)`, + ); + console.log( + ` This proves cache overwriting doesn't prevent memory leaks when parentData holds document references`, + ); + + // Add mock layout data for testing cache growth + // This simulates a visual editor page with components + // Component IDs are CONSISTENT but document IDs are DIFFERENT + if (!testData.__) { + testData.__ = {}; + } + if (!testData.__.layout) { + // Use the large production template layout from the comment example + // This is the actual payload size (~124KB) that causes the memory leak + // The layout JSON is extracted from the example template JSON in the comment above + const largeTemplateLayoutPath = resolve( + __dirname, + "large-template-layout.json", + ); + if (existsSync(largeTemplateLayoutPath)) { + const largeTemplateLayoutStr = readFileSync( + largeTemplateLayoutPath, + "utf-8", + ); + testData.__.layout = largeTemplateLayoutStr; + console.log( + `✓ Loaded large template layout from file (${(largeTemplateLayoutStr.length / 1024).toFixed(2)} KB)`, + ); + console.log( + ` This matches the production payload size that causes the memory leak`, + ); + } else { + // Fallback to simple layout if file doesn't exist + console.log( + `⚠ Large template layout file not found, using simple layout`, + ); + testData.__.layout = JSON.stringify({ + root: { + props: { + id: "root", // CONSISTENT ID + version: 50, // High version to skip all migrations + }, + }, + content: [ + { + type: "Heading", + props: { + id: componentId, // CONSISTENT ID - same across all pages + text: "Test Heading", + }, + }, + { + type: "ProductSection", + props: { + id: productSectionId, // CONSISTENT ID - same across all pages + styles: { + backgroundColor: "background2", + }, + slots: { + SectionHeadingSlot: [ + { + type: "HeadingTextSlot", + props: { + id: "headingSlot-1", // CONSISTENT ID + data: { + text: { + field: "", + constantValue: { + en: "Featured Products", + hasLocalizedValue: "true", + }, + constantValueEnabled: true, + }, + }, + styles: { + level: 2, + align: "left", + }, + }, + }, + ], + CardsWrapperSlot: [ + { + type: "ProductCardsWrapper", + props: { + id: productCardsWrapperId, // CONSISTENT ID - same across all pages + // Use document field to trigger resolveData and create parentData + // This will call resolveYextEntityField which returns REFERENCES to document objects + // Even though component ID is consistent, parentData.product will reference DIFFERENT document objects + data: { + field: "c_productSection.linkedProducts", + constantValueEnabled: false, // Use document field, not constant value + constantValue: [], + }, + slots: { + CardSlot: [ + // Pre-populate with ProductCard components that have CONSISTENT IDs + // This prevents ProductCardsWrapper.resolveData from generating random UUIDs + // The resolveData function will use existing cards if CardSlot.length >= requiredLength + { + type: "ProductCard", + props: { + id: "ProductCard-1", // CONSISTENT ID - same across all pages + index: 0, + styles: { + backgroundColor: "background1", + }, + slots: { + ImageSlot: [ + { + type: "ImageSlot", + props: { + id: "ProductCard-1-image", + data: { + image: { + field: "", + constantValue: {}, + constantValueEnabled: true, + }, + }, + styles: { + aspectRatio: 1.78, + width: 640, + }, + }, + }, + ], + TitleSlot: [ + { + type: "HeadingTextSlot", + props: { + id: "ProductCard-1-title", + data: { + text: { + field: "", + constantValue: {}, + constantValueEnabled: true, + }, + }, + styles: { level: 3, align: "left" }, + }, + }, + ], + CategorySlot: [ + { + type: "BodyTextSlot", + props: { + id: "ProductCard-1-category", + data: { + text: { + field: "", + constantValue: {}, + constantValueEnabled: true, + }, + }, + styles: { variant: "base" }, + }, + }, + ], + DescriptionSlot: [ + { + type: "BodyTextSlot", + props: { + id: "ProductCard-1-description", + data: { + text: { + field: "", + constantValue: {}, + constantValueEnabled: true, + }, + }, + styles: { variant: "base" }, + }, + }, + ], + CTASlot: [ + { + type: "CTASlot", + props: { + id: "ProductCard-1-cta", + data: { + entityField: { + field: "", + constantValue: {}, + constantValueEnabled: true, + }, + }, + styles: { + variant: "primary", + presetImage: "app-store", + }, + }, + }, + ], + }, + }, + }, + { + type: "ProductCard", + props: { + id: "ProductCard-2", // CONSISTENT ID - same across all pages + index: 1, + styles: { + backgroundColor: "background1", + }, + slots: { + ImageSlot: [ + { + type: "ImageSlot", + props: { + id: "ProductCard-2-image", + data: { + image: { + field: "", + constantValue: {}, + constantValueEnabled: true, + }, + }, + styles: { + aspectRatio: 1.78, + width: 640, + }, + }, + }, + ], + TitleSlot: [ + { + type: "HeadingTextSlot", + props: { + id: "ProductCard-2-title", + data: { + text: { + field: "", + constantValue: {}, + constantValueEnabled: true, + }, + }, + styles: { level: 3, align: "left" }, + }, + }, + ], + CategorySlot: [ + { + type: "BodyTextSlot", + props: { + id: "ProductCard-2-category", + data: { + text: { + field: "", + constantValue: {}, + constantValueEnabled: true, + }, + }, + styles: { variant: "base" }, + }, + }, + ], + DescriptionSlot: [ + { + type: "BodyTextSlot", + props: { + id: "ProductCard-2-description", + data: { + text: { + field: "", + constantValue: {}, + constantValueEnabled: true, + }, + }, + styles: { variant: "base" }, + }, + }, + ], + CTASlot: [ + { + type: "CTASlot", + props: { + id: "ProductCard-2-cta", + data: { + entityField: { + field: "", + constantValue: {}, + constantValueEnabled: true, + }, + }, + styles: { + variant: "primary", + presetImage: "app-store", + }, + }, + }, + ], + }, + }, + }, + ], + }, + }, + }, + ], + }, + analytics: { + scope: "productsSection", + }, + liveVisibility: true, + }, + }, + { + type: "Text", + props: { + id: componentId, // CONSISTENT ID - same across all pages (reused to show cache overwrite) + text: "Test content", + }, + }, + ], + }); + console.log( + `✓ Added mock layout data with ProductSection (uses document field: c_productSection.linkedProducts)`, + ); + console.log( + ` This will create parentData with document references to demonstrate memory leak`, + ); + console.log( + ` Component IDs are CONSISTENT (component-1, productSection-1, etc.)`, + ); + } + } else { + // If layout already exists, update all IDs to be unique for this test run + const layout = JSON.parse(testData.__.layout); + + // Update root ID + if (layout.root?.props) { + layout.root.props.id = `root-${randomId}`; + } + + // Update all content component IDs + if (Array.isArray(layout.content)) { + layout.content = layout.content.map((comp, idx) => ({ + ...comp, + props: { + ...comp.props, + id: `${comp.type?.toLowerCase() || "component"}-${randomId}-${idx}`, + }, + })); + } + + testData.__.layout = JSON.stringify(layout); + console.log(`✓ Updated layout with unique IDs (random: ${randomId})`); + } + + console.log("✓ Test data loaded"); + console.log(` Document: ${testData.name || testData.id || "unknown"}`); + console.log(` Has layout: ${!!testData.__?.layout}`); + console.log(""); + + // Import renderer + console.log("Importing renderer..."); + const rendererUrl = `file://${rendererPath}`; + console.log(`Renderer URL: ${rendererUrl}`); + const rendererModule = await import(rendererUrl); + const renderer = rendererModule.default; + console.log("✓ Renderer imported"); + console.log(""); + + // Prepare props (matching PagesGenerator format) + // IMPORTANT: The renderer modifies document.id per iteration (e.g., "1101-wilson-blvd-iteration-1") + // The renderer will also update product data to match the document ID per iteration + // This demonstrates that even with consistent component IDs, different document data creates different parentData references + const props = { + document: testData, + __meta: { + mode: "production", + }, + }; + + console.log("=".repeat(70)); + console.log("Executing renderer - watch for:"); + console.log(" - [Renderer] Iteration X/5 logs (from renderer.ts loop)"); + console.log(" - [Puck Cache] logs (from puck cache growth)"); + console.log(" - [VE transformProps] logs (from visual-editor)"); + console.log(" - [Memory Tracking] logs (tracking object references)"); + console.log("=".repeat(70)); + console.log(""); + + // Track updatedData objects across iterations to see where they're held + const updatedDataTracker = new Map(); // Track by iteration number + const objectReferenceTracker = new WeakMap(); // Track object references + + // Override console.log temporarily to capture updatedData references + const originalLog = console.log; + let iterationCount = 0; + + // Intercept logs to track updatedData objects + console.log = function (...args) { + const message = args[0]; + if ( + typeof message === "string" && + message.includes("[VE transformProps] PROOF - Document references") + ) { + // Extract updatedData reference from the log context + // We'll need to modify the template to expose this + } + originalLog.apply(console, args); + }; + + // Call renderer - THIS IS WHERE THE LOOP WILL EXECUTE + const result = await renderer(props, manifest); + + // Restore original console.log + console.log = originalLog; + + // Memory Tracking Analysis + console.log(""); + console.log("=".repeat(70)); + console.log("[Memory Tracking] Analysis:"); + console.log(""); + console.log(" ✅ CONFIRMED from logs:"); + console.log( + " - Cache overwrites correctly (same component IDs, new values)", + ); + console.log(" - Returned objects share SAME reference as cached objects"); + console.log( + " - parentData references survive mapFields (not deep cloned)", + ); + console.log( + " - Document references are shared between cache and returned data", + ); + console.log(""); + console.log(" ❓ THE KEY QUESTION:"); + console.log( + " If cache overwrites correctly, where are old updatedData objects being held?", + ); + console.log(""); + console.log(" 🔍 HYPOTHESIS - Old updatedData objects are retained by:"); + console.log( + " 1. React SSR: pluginRenderTemplates.server.render() may hold component trees", + ); + console.log( + " 2. Closures: Functions in rendering pipeline capturing props/updatedData", + ); + console.log( + " 3. Async/Promises: Promise chains holding references during async rendering", + ); + console.log( + " 4. Module state: Hidden caches in rendering code we haven't found", + ); + console.log(""); + console.log(" 🧪 TO VALIDATE, we could:"); + console.log( + " - Use Node.js memory profiler (--inspect) to see object retention", + ); + console.log(" - Add WeakMap tracking in rendering pipeline"); + console.log(" - Check React SSR internals for component tree retention"); + console.log(" - Inspect closures in generateTemplateResponses/renderHtml"); + console.log(" - Look for module-level variables in rendering code"); + console.log(""); + console.log(" 💡 CURRENT EVIDENCE:"); + console.log(" - Memory grows exponentially (100MB over 5 min)"); + console.log(" - Cache overwrites correctly (not the problem)"); + console.log(" - Objects share references (proven by === checks)"); + console.log( + " - Therefore: Something ELSE is holding old updatedData objects", + ); + console.log("=".repeat(70)); + + console.log(""); + console.log("=".repeat(70)); + console.log("✅ Renderer execution completed!"); + console.log("=".repeat(70)); + console.log(""); + console.log("Results:"); + console.log(` Path: ${result.path}`); + console.log( + ` Content: ${result.content ? `${(result.content.length / 1024).toFixed(2)} KB` : "none"}`, + ); + console.log(` Redirects: ${result.redirects?.length || 0}`); + console.log(""); + Deno.exit(1); + } catch (error) { + console.error(""); + console.error("❌ Error executing renderer:"); + console.error(error.message); + console.error(""); + if (error.stack) { + console.error("Stack trace:"); + console.error(error.stack); + console.error(""); + } + console.error("Troubleshooting:"); + console.error("1. Ensure project is built: pnpm build"); + console.error( + "2. Ensure pages package is built: cd ../../pages/packages/pages && pnpm build", + ); + console.error( + "3. Ensure puck package is built: cd ../../../puck/packages/core && pnpm build", + ); + process.exit(1); + } +} + +testRenderer(); + +/** + * Sample Template json: + * { + "feature": "colto-test-pg", + "site": { + "branchId": "6057", + "businessId": "11727428", + "businessName": "Joe Ballschneider's Demo Account", + "commitHash": "90d39190a612ff4a56cf5df5954fde063378b480", + "commitMessage": "Initial commit", + "deployId": "vev52ebehb", + "platformUrl": "https://dev.yext.com/s/11727428/yextsites/66377/branch/6057/deploy/vev52ebehb/details", + "previewDomain": "https://vev52ebehb-66377-d.dev.preview.pagescdn.com", + "productionDomain": "skilfully-medieval-sunbird.dev.pgsdemo.com", + "repoBranchName": "main", + "repoBranchUrl": "https://github.com/adept-rug-hens/11727428-visual-editor-starter-7b6za5du0u2/tree/main", + "repoUrl": "https://github.com/adept-rug-hens/11727428-visual-editor-starter-7b6za5du0u2", + "siteId": "66377", + "siteName": "colto-test", + "stagingDomain": "main-skilfully--medieval--sunbird-dev-pgsdemo-com.dev.preview.pagescdn.com", + "yextUniverse": "development" + }, + "streamOutput": { + "__": { + "codeTemplate": "main", + "entityPageSet": {}, + "layout": "{\"root\": {\"type\": \"root\", \"props\": {\"title\": {\"field\": \"name\", \"constantValue\": \"\", \"constantValueEnabled\": false}, \"version\": 44, \"description\": {\"field\": \"description\", \"constantValue\": \"\", \"constantValueEnabled\": false}}}, \"zones\": {}, \"content\": [{\"type\": \"ExpandedHeader\", \"props\": {\"id\": \"ExpandedHeader-92679ccf-a7de-4b5b-90d3-fea0f03449d0\", \"slots\": {\"PrimaryHeaderSlot\": [{\"type\": \"PrimaryHeaderSlot\", \"props\": {\"id\": \"PrimaryHeaderSlot-0d3864b1-add7-4268-9a02-f0526eb35c9b\", \"slots\": {\"LogoSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ImageSlot-dbf6589a-4cff-4ef8-ada0-1a53bf5af37a\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://placehold.co/100\", \"width\": 100, \"height\": 100}, \"constantValueEnabled\": true}}, \"styles\": {\"width\": 100, \"aspectRatio\": 2}}}], \"LinksSlot\": [{\"type\": \"HeaderLinks\", \"props\": {\"id\": \"HeaderLinks-48f4506c-6421-4f54-95c2-0a44f6d89c29\", \"data\": {\"links\": [{\"link\": \"#\", \"label\": {\"en\": \"Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}, \"parentData\": {\"type\": \"Primary\"}}}], \"PrimaryCTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"CTASlot-6ff4af13-e9a4-4ec2-8884-8e0cd165f900\", \"data\": {\"show\": true, \"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Call to Action\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}}}], \"SecondaryCTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"CTASlot-203ce7a4-6207-42b5-bd8d-500051893a78\", \"data\": {\"show\": true, \"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Call to Action\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"secondary\", \"presetImage\": \"app-store\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"parentValues\": {\"maxWidth\": \"theme\", \"SecondaryHeaderSlot\": [{\"type\": \"SecondaryHeaderSlot\", \"props\": {\"id\": \"SecondaryHeaderSlot-27cae493-886a-4c73-a9fa-376d28a0baf3\", \"data\": {\"show\": true, \"showLanguageDropdown\": false}, \"slots\": {\"LinksSlot\": [{\"type\": \"HeaderLinks\", \"props\": {\"id\": \"HeaderLinks-76826121-e9bc-452a-8b99-c663a5803dc3\", \"data\": {\"links\": [{\"link\": \"#\", \"label\": {\"en\": \"Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}, \"parentData\": {\"type\": \"Secondary\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-primary-light\", \"textColor\": \"text-black\"}}, \"parentStyles\": {\"maxWidth\": \"theme\"}}}]}, \"conditionalRender\": {\"CTAs\": true, \"navContent\": true}}}], \"SecondaryHeaderSlot\": [{\"type\": \"SecondaryHeaderSlot\", \"props\": {\"id\": \"SecondaryHeaderSlot-27cae493-886a-4c73-a9fa-376d28a0baf3\", \"data\": {\"show\": true, \"showLanguageDropdown\": false}, \"slots\": {\"LinksSlot\": [{\"type\": \"HeaderLinks\", \"props\": {\"id\": \"HeaderLinks-76826121-e9bc-452a-8b99-c663a5803dc3\", \"data\": {\"links\": [{\"link\": \"#\", \"label\": {\"en\": \"Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}, {\"link\": \"#\", \"label\": {\"en\": \"Header Link\", \"hasLocalizedValue\": \"true\"}, \"linkType\": \"URL\"}]}, \"parentData\": {\"type\": \"Secondary\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-primary-light\", \"textColor\": \"text-black\"}}, \"parentStyles\": {\"maxWidth\": \"theme\"}}}]}, \"styles\": {\"maxWidth\": \"theme\", \"headerPosition\": \"scrollsWithPage\"}, \"analytics\": {\"scope\": \"expandedHeader\"}, \"ignoreLocaleWarning\": []}}, {\"type\": \"BannerSection\", \"props\": {\"id\": \"BannerSection-85b90f9c-f8a3-4796-9dc4-18160b9972b6\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Banner Text\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"textAlignment\": \"center\", \"backgroundColor\": {\"bgColor\": \"bg-palette-primary-dark\", \"textColor\": \"text-white\"}}, \"liveVisibility\": true, \"ignoreLocaleWarning\": [\"data.text\"]}}, {\"type\": \"BreadcrumbsSection\", \"props\": {\"id\": \"BreadcrumbsSection-23f3c339-618a-4e10-9ce1-68117745e3b6\", \"data\": {\"directoryRoot\": {\"en\": \"Directory Root\", \"hasLocalizedValue\": \"true\"}}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"breadcrumbs\"}, \"liveVisibility\": true}}, {\"type\": \"HeroSection\", \"props\": {\"id\": \"HeroSection-6171b068-a44d-406e-9094-95f1ca7a53c5\", \"data\": {\"backgroundImage\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1755745360285-0633c972b0fd?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"slots\": {\"ImageSlot\": [{\"type\": \"HeroImageSlot\", \"props\": {\"id\": \"HeroImageSlot-7d8be313-bcd4-4fcf-ba4d-41effa837db2\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1755745360285-0633c972b0fd?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"styles\": {\"width\": 490, \"aspectRatio\": 1.78}, \"variant\": \"classic\", \"className\": \"mx-auto max-w-full md:max-w-[350px] lg:max-w-[calc(min(calc(100vw-1.5rem),var(--maxWidth-pageSection-contentWidth))-350px)] rounded-image-borderRadius\"}}], \"PrimaryCTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"CTASlot-46811f58-2779-4c49-a871-26cf27454544\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Call To Action\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"primaryCta\", \"parentStyles\": {}}}], \"GeomodifierSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-8905a32e-da1c-42a6-b1b4-98630e328236\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Geomodifier\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 1}}}], \"HoursStatusSlot\": [{\"type\": \"HoursStatusSlot\", \"props\": {\"id\": \"HoursStatusSlot-4b970196-2462-4b19-b166-79e7554f7513\", \"data\": {\"hours\": {\"field\": \"hours\", \"constantValue\": {}}}, \"styles\": {\"showDayNames\": true, \"dayOfWeekFormat\": \"long\", \"showCurrentStatus\": true}}}], \"BusinessNameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-bb2ccf6e-ab98-4fb4-9e9b-fdcd5c6834e6\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Business Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 2}}}], \"SecondaryCTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"CTASlot-633345f6-c438-400b-bdf7-92dce47746bc\", \"data\": {\"entityField\": {\"field\": \"\", \"selectedType\": \"textAndLink\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Learn More\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}}}, \"styles\": {\"variant\": \"secondary\", \"presetImage\": \"app-store\"}, \"eventName\": \"secondaryCta\", \"parentStyles\": {}}}]}, \"styles\": {\"variant\": \"classic\", \"showImage\": true, \"imageHeight\": 500, \"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}, \"showAverageReview\": true, \"mobileImagePosition\": \"bottom\", \"desktopImagePosition\": \"right\", \"mobileContentAlignment\": \"left\", \"desktopContainerPosition\": \"left\"}, \"analytics\": {\"scope\": \"heroSection\"}, \"liveVisibility\": true, \"conditionalRender\": {\"hours\": false}}}, {\"type\": \"CoreInfoSection\", \"props\": {\"id\": \"CoreInfoSection-660d4d53-8a6f-4f01-ac84-e9c23d485554\", \"slots\": {\"TextListSlot\": [{\"type\": \"TextListSlot\", \"props\": {\"id\": \"ServicesListSlot-2ab9809e-7c31-4a55-934d-2dd7d2f3b105\", \"list\": {\"field\": \"services\", \"constantValue\": []}, \"commaSeparated\": false}}], \"HoursTableSlot\": [{\"type\": \"HoursTableSlot\", \"props\": {\"id\": \"HoursTableSlot-f2625bcc-e225-44d9-a4ae-e6861b100b19\", \"data\": {\"hours\": {\"field\": \"hours\", \"constantValue\": {}}}, \"styles\": {\"alignment\": \"items-start\", \"startOfWeek\": \"today\", \"collapseDays\": false, \"showAdditionalHoursText\": true}}}], \"HoursHeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-05556e7b-c4ef-4251-8d94-1f57cbebb8be\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Hours\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}], \"CoreInfoEmailsSlot\": [{\"type\": \"EmailsSlot\", \"props\": {\"id\": \"EmailsSlot-15e44360-bc22-43e3-b6c2-c86d26dba9f1\", \"data\": {\"list\": {\"field\": \"emails\", \"constantValue\": []}}, \"styles\": {\"listLength\": 1}}}], \"CoreInfoAddressSlot\": [{\"type\": \"AddressSlot\", \"props\": {\"id\": \"AddressSlot-1ec6157c-ef5e-43ce-a05d-259202245b0c\", \"data\": {\"address\": {\"field\": \"address\", \"constantValue\": {\"city\": \"\", \"line1\": \"\", \"postalCode\": \"\", \"countryCode\": \"\"}}}, \"styles\": {\"ctaVariant\": \"link\", \"showGetDirectionsLink\": true}}}], \"CoreInfoHeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-53d6582f-3f69-4224-b172-31f7ecac6824\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Information\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}], \"ServicesHeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-febfb175-cce0-4d5c-8d79-f58784bf0277\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Services\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}], \"CoreInfoPhoneNumbersSlot\": [{\"type\": \"PhoneNumbersSlot\", \"props\": {\"id\": \"PhoneNumbersSlot-ed14a9b1-7a46-465a-9726-fc6c308054a3\", \"data\": {\"phoneNumbers\": [{\"label\": {\"en\": \"Phone\", \"hasLocalizedValue\": \"true\"}, \"number\": {\"field\": \"mainPhone\", \"constantValue\": \"\"}}]}, \"styles\": {\"phoneFormat\": \"domestic\", \"includePhoneHyperlink\": true}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"coreInfoSection\"}, \"liveVisibility\": true, \"conditionalRender\": {\"hoursCol\": false, \"coreInfoCol\": true, \"servicesCol\": false}}}, {\"type\": \"PromoSection\", \"props\": {\"id\": \"PromoSection-f4ad4730-016a-46cf-8ae2-e307c23c3c47\", \"data\": {\"media\": \"image\", \"promo\": {\"field\": \"\", \"constantValue\": {}, \"constantValueEnabled\": true}}, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"CTASlot-e8531a98-b8ff-4ce1-a299-11fc085eb6c3\", \"data\": {\"entityField\": {\"field\": \"\", \"selectedType\": \"textAndLink\", \"constantValue\": {\"link\": \"#\", \"label\": \"Learn More\", \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ImageSlot-4263a6eb-10fb-43d6-a352-39d3794e9816\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1502252430442-aac78f397426?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"width\", \"md\": \"min(width, 450px)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"className\": \"max-w-full sm:max-w-initial md:max-w-[450px] lg:max-w-none rounded-image-borderRadius w-full\"}}], \"VideoSlot\": [{\"type\": \"VideoSlot\", \"props\": {\"id\": \"VideoSlot-87e838a4-28eb-4b6e-900d-9a1718170e89\", \"data\": {}}}], \"HeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-2124ebb9-01d5-49c5-8f9c-80461e3e09f2\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Featured Promotion\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 2}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"BodyTextSlot-977b436f-82c1-4b44-8667-908e771d6b6f\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. 100 characters

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. 100 characters\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}, \"styles\": {\"orientation\": \"left\", \"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"promoSection\"}, \"liveVisibility\": true}, \"readOnly\": {\"data.media\": false}}, {\"type\": \"ProductSection\", \"props\": {\"id\": \"ProductSection-985d98bc-d5cf-4f69-aea5-597183c27cea\", \"slots\": {\"CardsWrapperSlot\": [{\"type\": \"ProductCardsWrapper\", \"props\": {\"id\": \"ProductCardsWrapper-31103b0f-5bfb-4dfe-a4e5-9f18cfd7cfcf\", \"data\": {\"field\": \"\", \"constantValue\": [{\"id\": \"ProductCard-4ddddc07-d36d-4ed3-90e8-1ca3ca2e8447\"}, {\"id\": \"ProductCard-996096bf-bc44-4827-ab79-21e9106abf53\"}, {\"id\": \"ProductCard-a7549442-809c-489f-9f73-4cd5c6038f51\"}, {\"id\": \"ProductCard-967dd579-2678-47f4-92ca-5e2454e6a523\"}, {\"id\": \"ProductCard-8e164405-f166-49da-881f-cd591ea1a3b1\"}, {\"id\": \"ProductCard-73a51294-29fc-4023-a84e-0bc863275268\"}], \"constantValueEnabled\": true}, \"slots\": {\"CardSlot\": [{\"type\": \"ProductCard\", \"props\": {\"id\": \"ProductCard-4ddddc07-d36d-4ed3-90e8-1ca3ca2e8447\", \"index\": 0, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"ProductCard-4ddddc07-d36d-4ed3-90e8-1ca3ca2e8447-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": \"Learn More\", \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta0\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ProductCard-4ddddc07-d36d-4ed3-90e8-1ca3ca2e8447-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1504548840739-580b10ae7715?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc((maxWidth - 32px) / 3)\", \"md\": \"calc((maxWidth - 32px) / 2)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"ProductCard-4ddddc07-d36d-4ed3-90e8-1ca3ca2e8447-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Product Title\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"CategorySlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-4ddddc07-d36d-4ed3-90e8-1ca3ca2e8447-category\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Category, Pricing, etc

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Category, Pricing, etc\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-4ddddc07-d36d-4ed3-90e8-1ca3ca2e8447-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"category\": true}}}, {\"type\": \"ProductCard\", \"props\": {\"id\": \"ProductCard-996096bf-bc44-4827-ab79-21e9106abf53\", \"index\": 1, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"ProductCard-996096bf-bc44-4827-ab79-21e9106abf53-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": \"Learn More\", \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta1\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ProductCard-996096bf-bc44-4827-ab79-21e9106abf53-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1502252430442-aac78f397426?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc((maxWidth - 32px) / 3)\", \"md\": \"calc((maxWidth - 32px) / 2)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"ProductCard-996096bf-bc44-4827-ab79-21e9106abf53-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Product Title\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"CategorySlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-996096bf-bc44-4827-ab79-21e9106abf53-category\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Category, Pricing, etc

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Category, Pricing, etc\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-996096bf-bc44-4827-ab79-21e9106abf53-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"category\": true}}}, {\"type\": \"ProductCard\", \"props\": {\"id\": \"ProductCard-a7549442-809c-489f-9f73-4cd5c6038f51\", \"index\": 2, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"ProductCard-a7549442-809c-489f-9f73-4cd5c6038f51-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": \"Learn More\", \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta2\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ProductCard-a7549442-809c-489f-9f73-4cd5c6038f51-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1755745360285-0633c972b0fd?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc((maxWidth - 32px) / 3)\", \"md\": \"calc((maxWidth - 32px) / 2)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"ProductCard-a7549442-809c-489f-9f73-4cd5c6038f51-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Product Title\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"CategorySlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-a7549442-809c-489f-9f73-4cd5c6038f51-category\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Category, Pricing, etc

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Category, Pricing, etc\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-a7549442-809c-489f-9f73-4cd5c6038f51-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"category\": true}}}, {\"type\": \"ProductCard\", \"props\": {\"id\": \"ProductCard-967dd579-2678-47f4-92ca-5e2454e6a523\", \"index\": 3, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"ProductCard-967dd579-2678-47f4-92ca-5e2454e6a523-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Learn More\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta3\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ProductCard-967dd579-2678-47f4-92ca-5e2454e6a523-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1755745360285-0633c972b0fd?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb&height=360&width=640&fit=max\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc((maxWidth - 32px) / 3)\", \"md\": \"calc((maxWidth - 32px) / 2)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"ProductCard-967dd579-2678-47f4-92ca-5e2454e6a523-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Product Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"CategorySlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-967dd579-2678-47f4-92ca-5e2454e6a523-category\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Category, Pricing, etc

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Category, Pricing, etc\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-967dd579-2678-47f4-92ca-5e2454e6a523-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"category\": true}}}, {\"type\": \"ProductCard\", \"props\": {\"id\": \"ProductCard-8e164405-f166-49da-881f-cd591ea1a3b1\", \"index\": 4, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"ProductCard-8e164405-f166-49da-881f-cd591ea1a3b1-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Learn More\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta4\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ProductCard-8e164405-f166-49da-881f-cd591ea1a3b1-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1502252430442-aac78f397426?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb&height=360&width=640&fit=max\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc((maxWidth - 32px) / 3)\", \"md\": \"calc((maxWidth - 32px) / 2)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"ProductCard-8e164405-f166-49da-881f-cd591ea1a3b1-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Product Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"CategorySlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-8e164405-f166-49da-881f-cd591ea1a3b1-category\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Category, Pricing, etc

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Category, Pricing, etc\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-8e164405-f166-49da-881f-cd591ea1a3b1-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"category\": true}}}, {\"type\": \"ProductCard\", \"props\": {\"id\": \"ProductCard-73a51294-29fc-4023-a84e-0bc863275268\", \"index\": 5, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"ProductCard-73a51294-29fc-4023-a84e-0bc863275268-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Learn More\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta5\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ProductCard-73a51294-29fc-4023-a84e-0bc863275268-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1502252430442-aac78f397426?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb&height=360&width=640&fit=max\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc((maxWidth - 32px) / 3)\", \"md\": \"calc((maxWidth - 32px) / 2)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"ProductCard-73a51294-29fc-4023-a84e-0bc863275268-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Product Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"CategorySlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-73a51294-29fc-4023-a84e-0bc863275268-category\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Category, Pricing, etc

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Category, Pricing, etc\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"ProductCard-73a51294-29fc-4023-a84e-0bc863275268-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"category\": true}}}]}}}], \"SectionHeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-ca4fe590-4d36-4477-b34f-fba39583384f\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Featured Products\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 2}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-primary-light\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"productsSection\"}, \"liveVisibility\": true}}, {\"type\": \"TestimonialSection\", \"props\": {\"id\": \"TestimonialSection-21edd977-c45d-4a7b-ab17-e6273774b815\", \"slots\": {\"CardsWrapperSlot\": [{\"type\": \"TestimonialCardsWrapper\", \"props\": {\"id\": \"TestimonialCardsWrapper-e3c3bbf7-1130-4558-9557-e0eb8a5fb7f1\", \"data\": {\"field\": \"\", \"constantValue\": [{\"id\": \"TestimonialCard-6661d40d-1001-4ace-9c98-30c71f933742\"}, {\"id\": \"TestimonialCard-e4f61016-5051-4b0f-8e13-521392f2c204\"}, {\"id\": \"TestimonialCard-1898bde5-72bb-4eef-97dc-c6c6aea0ecd5\"}, {\"id\": \"TestimonialCard-09d44d36-d3cb-4d66-8b8b-6462a7e8d073\"}, {\"id\": \"TestimonialCard-cbb7eb88-0869-436e-8ba5-a168707bb977\"}, {\"id\": \"TestimonialCard-93b120df-1c71-429b-8f43-908e87d45be7\"}], \"constantValueEnabled\": true}, \"slots\": {\"CardSlot\": [{\"type\": \"TestimonialCard\", \"props\": {\"id\": \"TestimonialCard-6661d40d-1001-4ace-9c98-30c71f933742\", \"index\": 0, \"slots\": {\"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"BodyTextSlot-4171d3d9-4fd2-48c9-9e77-3d32d9914eb1\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"ContributorNameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-435197f7-7dcc-495c-8181-9c66c494da99\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"ContributionDateSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"Timestamp-71930a6f-035d-4ae3-9426-b9dfab6039be\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-08-02T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": false, \"includeRange\": false}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"description\": true, \"contributorName\": true, \"contributionDate\": true}}}, {\"type\": \"TestimonialCard\", \"props\": {\"id\": \"TestimonialCard-e4f61016-5051-4b0f-8e13-521392f2c204\", \"index\": 1, \"slots\": {\"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"BodyTextSlot-03715ec2-8ea8-4032-9561-d93c145a65d9\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"ContributorNameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-746e8537-2e7b-46ca-b0a6-0a20673d6504\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"ContributionDateSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"Timestamp-66dd3a52-aafa-40ee-9e58-61a5b5aa1d94\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-08-02T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": false, \"includeRange\": false}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"description\": true, \"contributorName\": true, \"contributionDate\": true}}}, {\"type\": \"TestimonialCard\", \"props\": {\"id\": \"TestimonialCard-1898bde5-72bb-4eef-97dc-c6c6aea0ecd5\", \"index\": 2, \"slots\": {\"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"BodyTextSlot-f515ea6a-f7bd-4120-9600-1f1aa65779e8\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"ContributorNameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-4f2d770d-67b6-4ebc-9ade-95d47a6957e6\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"ContributionDateSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"Timestamp-ca272118-f2a5-4e73-8389-35980eca89a2\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-08-02T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": false, \"includeRange\": false}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"description\": true, \"contributorName\": true, \"contributionDate\": true}}}, {\"type\": \"TestimonialCard\", \"props\": {\"id\": \"TestimonialCard-09d44d36-d3cb-4d66-8b8b-6462a7e8d073\", \"index\": 3, \"slots\": {\"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"TestimonialCard-09d44d36-d3cb-4d66-8b8b-6462a7e8d073-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"ContributorNameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"TestimonialCard-09d44d36-d3cb-4d66-8b8b-6462a7e8d073-contributorName\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"ContributionDateSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"TestimonialCard-09d44d36-d3cb-4d66-8b8b-6462a7e8d073-contributionDate\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-08-02T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": false, \"includeRange\": false}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"description\": true, \"contributorName\": true, \"contributionDate\": true}}}, {\"type\": \"TestimonialCard\", \"props\": {\"id\": \"TestimonialCard-cbb7eb88-0869-436e-8ba5-a168707bb977\", \"index\": 4, \"slots\": {\"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"TestimonialCard-cbb7eb88-0869-436e-8ba5-a168707bb977-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"ContributorNameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"TestimonialCard-cbb7eb88-0869-436e-8ba5-a168707bb977-contributorName\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"ContributionDateSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"TestimonialCard-cbb7eb88-0869-436e-8ba5-a168707bb977-contributionDate\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-08-02T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": false, \"includeRange\": false}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"description\": true, \"contributorName\": true, \"contributionDate\": true}}}, {\"type\": \"TestimonialCard\", \"props\": {\"id\": \"TestimonialCard-93b120df-1c71-429b-8f43-908e87d45be7\", \"index\": 5, \"slots\": {\"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"TestimonialCard-93b120df-1c71-429b-8f43-908e87d45be7-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"ContributorNameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"TestimonialCard-93b120df-1c71-429b-8f43-908e87d45be7-contributorName\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"ContributionDateSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"TestimonialCard-93b120df-1c71-429b-8f43-908e87d45be7-contributionDate\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-08-02T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": false, \"includeRange\": false}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"description\": true, \"contributorName\": true, \"contributionDate\": true}}}]}}}], \"SectionHeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-b4d5c262-ef79-450e-ab4b-17982eea39b2\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Featured Testimonials\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 2}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-primary-light\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"testimonialSection\"}, \"liveVisibility\": true}}, {\"type\": \"FAQSection\", \"props\": {\"id\": \"FAQSection-bbfde40e-2d68-4f33-afc2-836aa183d7b0\", \"slots\": {\"HeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-c85952bc-d30c-44a8-a17c-0eff090cc35e\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Frequently Asked Questions\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 2}}}], \"FAQsWrapperSlot\": [{\"type\": \"FAQsWrapperSlot\", \"props\": {\"id\": \"FAQsWrapperSlot-3393daed-5f2f-4d49-b780-fdfa0470a7fa\", \"data\": {\"field\": \"\", \"constantValue\": [{\"id\": \"FAQSlot-25f8cd22-4390-41ec-9cd7-6b6cbdb32a02\"}, {\"id\": \"FAQSlot-b4fb610a-a797-4596-ab28-8a27ea4056f9\"}, {\"id\": \"FAQSlot-f7f73734-c0c6-415c-903e-218d18e71929\"}, {\"id\": \"FAQSlot-40130593-ac3f-4c9d-a48e-1d3326fff2db\"}, {\"id\": \"FAQSlot-8690fcd8-c3db-4eb3-ae15-e448e3b2a8d4\"}, {\"id\": \"FAQSlot-4ef05090-abc9-4234-a661-3ffa5e1e151c\"}, {\"id\": \"FAQSlot-043e849e-0d02-49e0-9070-a5b5308bb60e\"}, {\"id\": \"FAQSlot-8fc88feb-438b-4671-9f2f-1e86925db751\"}, {\"id\": \"FAQSlot-1891f75f-3112-46b4-aaf3-17b67323a67c\"}, {\"id\": \"FAQSlot-9b9e7834-391a-4e25-a5a4-d5faffe1b64d\"}], \"constantValueEnabled\": true}, \"slots\": {\"CardSlot\": [{\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSlot-25f8cd22-4390-41ec-9cd7-6b6cbdb32a02\", \"index\": 0, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-25f8cd22-4390-41ec-9cd7-6b6cbdb32a02-answer\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-25f8cd22-4390-41ec-9cd7-6b6cbdb32a02-question\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Question Lorem ipsum dolor sit amet?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Question Lorem ipsum dolor sit amet?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSlot-b4fb610a-a797-4596-ab28-8a27ea4056f9\", \"index\": 1, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-b4fb610a-a797-4596-ab28-8a27ea4056f9-answer\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-b4fb610a-a797-4596-ab28-8a27ea4056f9-question\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Question Lorem ipsum dolor sit amet?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Question Lorem ipsum dolor sit amet?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSlot-f7f73734-c0c6-415c-903e-218d18e71929\", \"index\": 2, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-f7f73734-c0c6-415c-903e-218d18e71929-answer\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-f7f73734-c0c6-415c-903e-218d18e71929-question\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Question Lorem ipsum dolor sit amet?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Question Lorem ipsum dolor sit amet?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSlot-40130593-ac3f-4c9d-a48e-1d3326fff2db\", \"index\": 3, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-40130593-ac3f-4c9d-a48e-1d3326fff2db-answer\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-40130593-ac3f-4c9d-a48e-1d3326fff2db-question\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Question Lorem ipsum dolor sit amet?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Question Lorem ipsum dolor sit amet?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSlot-8690fcd8-c3db-4eb3-ae15-e448e3b2a8d4\", \"index\": 4, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-8690fcd8-c3db-4eb3-ae15-e448e3b2a8d4-answer\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-8690fcd8-c3db-4eb3-ae15-e448e3b2a8d4-question\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Question Lorem ipsum dolor sit amet?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Question Lorem ipsum dolor sit amet?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSlot-4ef05090-abc9-4234-a661-3ffa5e1e151c\", \"index\": 5, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-4ef05090-abc9-4234-a661-3ffa5e1e151c-answer\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-4ef05090-abc9-4234-a661-3ffa5e1e151c-question\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Question Lorem ipsum dolor sit amet?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Question Lorem ipsum dolor sit amet?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSlot-043e849e-0d02-49e0-9070-a5b5308bb60e\", \"index\": 6, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-043e849e-0d02-49e0-9070-a5b5308bb60e-answer\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-043e849e-0d02-49e0-9070-a5b5308bb60e-question\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Question Lorem ipsum dolor sit amet?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Question Lorem ipsum dolor sit amet?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSlot-8fc88feb-438b-4671-9f2f-1e86925db751\", \"index\": 7, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-8fc88feb-438b-4671-9f2f-1e86925db751-answer\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-8fc88feb-438b-4671-9f2f-1e86925db751-question\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Question Lorem ipsum dolor sit amet?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Question Lorem ipsum dolor sit amet?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSlot-1891f75f-3112-46b4-aaf3-17b67323a67c\", \"index\": 8, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-1891f75f-3112-46b4-aaf3-17b67323a67c-answer\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-1891f75f-3112-46b4-aaf3-17b67323a67c-question\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Question Lorem ipsum dolor sit amet?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Question Lorem ipsum dolor sit amet?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}, {\"type\": \"FAQSlot\", \"props\": {\"id\": \"FAQSlot-9b9e7834-391a-4e25-a5a4-d5faffe1b64d\", \"index\": 9, \"slots\": {\"AnswerSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-9b9e7834-391a-4e25-a5a4-d5faffe1b64d-answer\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"QuestionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"FAQSlot-9b9e7834-391a-4e25-a5a4-d5faffe1b64d-question\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Question Lorem ipsum dolor sit amet?

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Question Lorem ipsum dolor sit amet?\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}]}}}]}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-primary-light\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"faqsSection\"}, \"liveVisibility\": true}}, {\"type\": \"TeamSection\", \"props\": {\"id\": \"TeamSection-c3e1d6c3-7105-4a52-b6c7-16f47d4d112e\", \"slots\": {\"CardsWrapperSlot\": [{\"type\": \"TeamCardsWrapper\", \"props\": {\"id\": \"TeamCardsWrapper-55fffe71-8671-40fd-b539-4cea67efa107\", \"data\": {\"field\": \"\", \"constantValue\": [{\"id\": \"TeamCard-78b6012c-8ee0-40b9-a5dc-9bff50ee6a98\"}, {\"id\": \"TeamCard-b33b9272-18a6-4075-8b0d-bd567d190ee3\"}, {\"id\": \"TeamCard-1486b519-8c1a-4e71-9622-eda626ba72ad\"}, {\"id\": \"TeamCard-274bc8ae-b605-4fcd-9329-8dd52b6ef84e\"}, {\"id\": \"TeamCard-c370b442-edca-4473-b94c-a71dc1a951f4\"}, {\"id\": \"TeamCard-9fa08698-4ce0-4482-896e-291ea987ec93\"}], \"constantValueEnabled\": true}, \"slots\": {\"CardSlot\": [{\"type\": \"TeamCard\", \"props\": {\"id\": \"TeamCard-78b6012c-8ee0-40b9-a5dc-9bff50ee6a98\", \"index\": 0, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"CTASlot-84f00400-c27d-4cd7-aa28-a1632694b359\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Visit Profile\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"card0-cta\"}}], \"NameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-058b94a5-2ef5-4e1c-8d69-a1a823a384c6\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"First Last\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}], \"EmailSlot\": [{\"type\": \"EmailsSlot\", \"props\": {\"id\": \"EmailsSlot-430cd79d-84fc-440e-b51b-22ede4a9651b\", \"data\": {\"list\": {\"field\": \"\", \"constantValue\": [\"jkelley@[company].com\"], \"constantValueEnabled\": true}}, \"styles\": {\"listLength\": 1}, \"eventName\": \"card0-email\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ImageSlot-1933f28f-2a14-419a-9e67-521009d2c1f2\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1755745360285-0633c972b0fd?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 80, \"height\": 80}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.33)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 200, \"aspectRatio\": 1}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"PhoneSlot\": [{\"type\": \"PhoneNumbersSlot\", \"props\": {\"id\": \"PhoneNumbersSlot-635c91da-e2f9-4e8f-8dd7-5beef9b7b814\", \"data\": {\"phoneNumbers\": [{\"label\": {\"en\": \"\", \"hasLocalizedValue\": \"true\"}, \"number\": {\"field\": \"\", \"constantValue\": \"+12027706619\", \"constantValueEnabled\": true}}]}, \"styles\": {\"phoneFormat\": \"domestic\", \"includePhoneHyperlink\": true}, \"eventName\": \"card0-phone\"}}], \"TitleSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"BodyTextSlot-7bc54a04-147d-4c12-9664-087c2477a60a\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Associate Agent\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\", \"semanticLevelOverride\": 3}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"cta\": true, \"name\": true, \"email\": true, \"image\": true, \"phone\": true, \"title\": true}}}, {\"type\": \"TeamCard\", \"props\": {\"id\": \"TeamCard-b33b9272-18a6-4075-8b0d-bd567d190ee3\", \"index\": 1, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"CTASlot-2f5fcbf5-5f6f-4f18-814d-30b6de491d0a\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Visit Profile\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"card1-cta\"}}], \"NameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-32894127-a9c2-442d-96eb-928cb3d79d91\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"First Last\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}], \"EmailSlot\": [{\"type\": \"EmailsSlot\", \"props\": {\"id\": \"EmailsSlot-39d65030-4fb1-4286-a73e-db994a195e33\", \"data\": {\"list\": {\"field\": \"\", \"constantValue\": [\"jkelley@[company].com\"], \"constantValueEnabled\": true}}, \"styles\": {\"listLength\": 1}, \"eventName\": \"card1-email\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ImageSlot-429dbd15-ae0a-41c6-94b3-39f332d9d199\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1755745360285-0633c972b0fd?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 80, \"height\": 80}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.33)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 200, \"aspectRatio\": 1}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"PhoneSlot\": [{\"type\": \"PhoneNumbersSlot\", \"props\": {\"id\": \"PhoneNumbersSlot-88afb804-14ba-43ea-b63f-3026dd2d1428\", \"data\": {\"phoneNumbers\": [{\"label\": {\"en\": \"\", \"hasLocalizedValue\": \"true\"}, \"number\": {\"field\": \"\", \"constantValue\": \"+12027706619\", \"constantValueEnabled\": true}}]}, \"styles\": {\"phoneFormat\": \"domestic\", \"includePhoneHyperlink\": true}, \"eventName\": \"card1-phone\"}}], \"TitleSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"BodyTextSlot-e84b6fc0-d859-48af-aaf3-c6eff7054c79\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Associate Agent\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\", \"semanticLevelOverride\": 3}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"cta\": true, \"name\": true, \"email\": true, \"image\": true, \"phone\": true, \"title\": true}}}, {\"type\": \"TeamCard\", \"props\": {\"id\": \"TeamCard-1486b519-8c1a-4e71-9622-eda626ba72ad\", \"index\": 2, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"CTASlot-569564d0-a69a-44f6-b528-d0aacdc875e5\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Visit Profile\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"card2-cta\"}}], \"NameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-a83bf243-6048-453f-99fc-f9716d59fcbc\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"First Last\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}], \"EmailSlot\": [{\"type\": \"EmailsSlot\", \"props\": {\"id\": \"EmailsSlot-410578ce-c60e-4409-9290-d3ff60d37c2d\", \"data\": {\"list\": {\"field\": \"\", \"constantValue\": [\"jkelley@[company].com\"], \"constantValueEnabled\": true}}, \"styles\": {\"listLength\": 1}, \"eventName\": \"card2-email\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"ImageSlot-f415ddf9-d370-44f8-a51e-200870b1b24f\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1502252430442-aac78f397426?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 80, \"height\": 80}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.33)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 200, \"aspectRatio\": 1}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"PhoneSlot\": [{\"type\": \"PhoneNumbersSlot\", \"props\": {\"id\": \"PhoneNumbersSlot-a44b07ad-b6ea-4a79-a33c-2fb379fe8589\", \"data\": {\"phoneNumbers\": [{\"label\": {\"en\": \"\", \"hasLocalizedValue\": \"true\"}, \"number\": {\"field\": \"\", \"constantValue\": \"+12027706619\", \"constantValueEnabled\": true}}]}, \"styles\": {\"phoneFormat\": \"domestic\", \"includePhoneHyperlink\": true}, \"eventName\": \"card2-phone\"}}], \"TitleSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"BodyTextSlot-b466a56b-0e41-4dac-876d-c1cb0418f6cf\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Associate Agent\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\", \"semanticLevelOverride\": 3}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"cta\": true, \"name\": true, \"email\": true, \"image\": true, \"phone\": true, \"title\": true}}}, {\"type\": \"TeamCard\", \"props\": {\"id\": \"TeamCard-274bc8ae-b605-4fcd-9329-8dd52b6ef84e\", \"index\": 3, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"TeamCard-274bc8ae-b605-4fcd-9329-8dd52b6ef84e-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Visit Profile\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"card3-cta\"}}], \"NameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"TeamCard-274bc8ae-b605-4fcd-9329-8dd52b6ef84e-name\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"First Last\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}], \"EmailSlot\": [{\"type\": \"EmailsSlot\", \"props\": {\"id\": \"TeamCard-274bc8ae-b605-4fcd-9329-8dd52b6ef84e-email\", \"data\": {\"list\": {\"field\": \"\", \"constantValue\": [\"jkelley@[company].com\"], \"constantValueEnabled\": true}}, \"styles\": {\"listLength\": 1}, \"eventName\": \"card3-email\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"TeamCard-274bc8ae-b605-4fcd-9329-8dd52b6ef84e-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://placehold.co/80x80\", \"width\": 80, \"height\": 80}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.33)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 200, \"aspectRatio\": 1}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"PhoneSlot\": [{\"type\": \"PhoneNumbersSlot\", \"props\": {\"id\": \"TeamCard-274bc8ae-b605-4fcd-9329-8dd52b6ef84e-phone\", \"data\": {\"phoneNumbers\": [{\"label\": {\"en\": \"\", \"hasLocalizedValue\": \"true\"}, \"number\": {\"field\": \"\", \"constantValue\": \"+12027706619\", \"constantValueEnabled\": true}}]}, \"styles\": {\"phoneFormat\": \"domestic\", \"includePhoneHyperlink\": true}, \"eventName\": \"card3-phone\"}}], \"TitleSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"TeamCard-274bc8ae-b605-4fcd-9329-8dd52b6ef84e-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Associate Agent

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Associate Agent\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\", \"semanticLevelOverride\": 3}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"cta\": true, \"name\": true, \"email\": true, \"image\": true, \"phone\": true, \"title\": true}}}, {\"type\": \"TeamCard\", \"props\": {\"id\": \"TeamCard-c370b442-edca-4473-b94c-a71dc1a951f4\", \"index\": 4, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"TeamCard-c370b442-edca-4473-b94c-a71dc1a951f4-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Visit Profile\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"card4-cta\"}}], \"NameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"TeamCard-c370b442-edca-4473-b94c-a71dc1a951f4-name\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"First Last\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}], \"EmailSlot\": [{\"type\": \"EmailsSlot\", \"props\": {\"id\": \"TeamCard-c370b442-edca-4473-b94c-a71dc1a951f4-email\", \"data\": {\"list\": {\"field\": \"\", \"constantValue\": [\"jkelley@[company].com\"], \"constantValueEnabled\": true}}, \"styles\": {\"listLength\": 1}, \"eventName\": \"card4-email\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"TeamCard-c370b442-edca-4473-b94c-a71dc1a951f4-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://placehold.co/80x80\", \"width\": 80, \"height\": 80}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.33)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 200, \"aspectRatio\": 1}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"PhoneSlot\": [{\"type\": \"PhoneNumbersSlot\", \"props\": {\"id\": \"TeamCard-c370b442-edca-4473-b94c-a71dc1a951f4-phone\", \"data\": {\"phoneNumbers\": [{\"label\": {\"en\": \"\", \"hasLocalizedValue\": \"true\"}, \"number\": {\"field\": \"\", \"constantValue\": \"+12027706619\", \"constantValueEnabled\": true}}]}, \"styles\": {\"phoneFormat\": \"domestic\", \"includePhoneHyperlink\": true}, \"eventName\": \"card4-phone\"}}], \"TitleSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"TeamCard-c370b442-edca-4473-b94c-a71dc1a951f4-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Associate Agent

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Associate Agent\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\", \"semanticLevelOverride\": 3}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"cta\": true, \"name\": true, \"email\": true, \"image\": true, \"phone\": true, \"title\": true}}}, {\"type\": \"TeamCard\", \"props\": {\"id\": \"TeamCard-9fa08698-4ce0-4482-896e-291ea987ec93\", \"index\": 5, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"TeamCard-9fa08698-4ce0-4482-896e-291ea987ec93-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Visit Profile\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"card5-cta\"}}], \"NameSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"TeamCard-9fa08698-4ce0-4482-896e-291ea987ec93-name\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"First Last\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}], \"EmailSlot\": [{\"type\": \"EmailsSlot\", \"props\": {\"id\": \"TeamCard-9fa08698-4ce0-4482-896e-291ea987ec93-email\", \"data\": {\"list\": {\"field\": \"\", \"constantValue\": [\"jkelley@[company].com\"], \"constantValueEnabled\": true}}, \"styles\": {\"listLength\": 1}, \"eventName\": \"card5-email\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"TeamCard-9fa08698-4ce0-4482-896e-291ea987ec93-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://placehold.co/80x80\", \"width\": 80, \"height\": 80}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.33)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 200, \"aspectRatio\": 1}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"PhoneSlot\": [{\"type\": \"PhoneNumbersSlot\", \"props\": {\"id\": \"TeamCard-9fa08698-4ce0-4482-896e-291ea987ec93-phone\", \"data\": {\"phoneNumbers\": [{\"label\": {\"en\": \"\", \"hasLocalizedValue\": \"true\"}, \"number\": {\"field\": \"\", \"constantValue\": \"+12027706619\", \"constantValueEnabled\": true}}]}, \"styles\": {\"phoneFormat\": \"domestic\", \"includePhoneHyperlink\": true}, \"eventName\": \"card5-phone\"}}], \"TitleSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"TeamCard-9fa08698-4ce0-4482-896e-291ea987ec93-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Associate Agent

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Associate Agent\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\", \"semanticLevelOverride\": 3}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"cta\": true, \"name\": true, \"email\": true, \"image\": true, \"phone\": true, \"title\": true}}}]}}}], \"SectionHeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-a976e584-6a55-40c4-9ce7-6193135a059d\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Meet Our Team\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 2}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-secondary-light\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"teamSection\"}, \"liveVisibility\": true}}, {\"type\": \"InsightSection\", \"props\": {\"id\": \"InsightSection-bdb34130-f7d5-49b0-8efa-385f7f81790d\", \"slots\": {\"CardsWrapperSlot\": [{\"type\": \"InsightCardsWrapper\", \"props\": {\"id\": \"InsightCardsWrapper-2282eee3-ff09-4572-b68a-931b226cf1fb\", \"data\": {\"field\": \"\", \"constantValue\": [{\"id\": \"InsightCard-1\"}, {\"id\": \"InsightCard-2\"}, {\"id\": \"InsightCard-3\"}], \"constantValueEnabled\": true}, \"slots\": {\"CardSlot\": [{\"type\": \"InsightCard\", \"props\": {\"id\": \"InsightCard-1\", \"index\": 0, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"InsightCard-1-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Read More\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta0\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"InsightCard-1-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1755745360285-0633c972b0fd?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc((maxWidth - 32px) / 3)\", \"md\": \"calc((maxWidth - 32px) / 2)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-3b5823a9-2c36-48b7-920e-36583edc9aa4\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Article Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 4, \"semanticLevelOverride\": 4}}}], \"CategorySlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"InsightCard-1-category\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Category

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Category\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"InsightCard-1-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo.Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. 300 characters

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo.Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. 300 characters\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"PublishTimeSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"InsightCard-1-timestamp\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-08-02T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": false, \"includeRange\": false}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"hasCategory\": true, \"hasPublishTime\": true}}}, {\"type\": \"InsightCard\", \"props\": {\"id\": \"InsightCard-2\", \"index\": 1, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"InsightCard-2-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Read More\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta1\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"InsightCard-2-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1502252430442-aac78f397426?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc((maxWidth - 32px) / 3)\", \"md\": \"calc((maxWidth - 32px) / 2)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-aad5d2b2-0109-4dca-94f1-217dbbaf0681\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Article Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 4, \"semanticLevelOverride\": 4}}}], \"CategorySlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"InsightCard-2-category\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Category

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Category\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"InsightCard-2-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo.Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. 300 characters

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo.Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. 300 characters\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"PublishTimeSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"InsightCard-2-timestamp\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-08-02T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": false, \"includeRange\": false}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"hasCategory\": true, \"hasPublishTime\": true}}}, {\"type\": \"InsightCard\", \"props\": {\"id\": \"InsightCard-3\", \"index\": 2, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"InsightCard-3-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Read More\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta2\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"InsightCard-3-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1504548840739-580b10ae7715?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc((maxWidth - 32px) / 3)\", \"md\": \"calc((maxWidth - 32px) / 2)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-208f4aae-eeea-440e-ab2a-119085c3a354\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Article Name\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 4, \"semanticLevelOverride\": 4}}}], \"CategorySlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"InsightCard-3-category\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Category

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Category\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"InsightCard-3-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo.Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. 300 characters

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo.Lorem ipsum dolor sit amet, consectetur adipiscing. Maecenas finibus placerat justo. 300 characters\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}}}], \"PublishTimeSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"InsightCard-3-timestamp\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-08-02T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": false, \"includeRange\": false}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"conditionalRender\": {\"hasCategory\": true, \"hasPublishTime\": true}}}]}}}], \"SectionHeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-7ca92f71-86ef-4686-b164-42ad74859298\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Insights\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-primary-light\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"insightsSection\"}, \"liveVisibility\": true}}, {\"type\": \"PhotoGallerySection\", \"props\": {\"id\": \"PhotoGallerySection-9526fe23-bbc4-46b7-b4f3-339f17a303c8\", \"slots\": {\"HeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-ddc30c55-8671-4509-ae10-e4cb198a95a6\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Gallery\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 2}}}], \"PhotoGalleryWrapper\": [{\"type\": \"PhotoGalleryWrapper\", \"props\": {\"id\": \"PhotoGalleryWrapper-68527f41-e591-46ad-9e2f-21657028f48e\", \"data\": {\"images\": {\"field\": \"\", \"constantValue\": [{\"assetImage\": {\"url\": \"https://images.unsplash.com/photo-1755745360285-0633c972b0fd?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360, \"assetImage\": {\"name\": \"Placeholder\"}}}, {\"assetImage\": {\"url\": \"https://images.unsplash.com/photo-1502252430442-aac78f397426?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360, \"assetImage\": {\"name\": \"Placeholder\"}}}, {\"assetImage\": {\"url\": \"https://images.unsplash.com/photo-1504548840739-580b10ae7715?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360, \"assetImage\": {\"name\": \"Placeholder\"}}}], \"constantValueEnabled\": true}}, \"styles\": {\"image\": {\"aspectRatio\": 1.78}}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"liveVisibility\": true}}, {\"type\": \"EventSection\", \"props\": {\"id\": \"EventSection-6015ba31-ab1b-4cb3-8942-4adf3bcea430\", \"slots\": {\"CardsWrapperSlot\": [{\"type\": \"EventCardsWrapper\", \"props\": {\"id\": \"EventCardsWrapper-4274079a-3925-4469-b899-4699cacd3c6d\", \"data\": {\"field\": \"\", \"constantValue\": [{\"id\": \"EventCard-92abd8ca-550c-4aee-92d9-4140b4ef53ad\"}, {\"id\": \"EventCard-b1fd4377-76db-433e-9803-ea5ae0d9f996\"}, {\"id\": \"EventCard-90968d53-5878-4459-b3dc-0b9b75e028ea\"}, {\"id\": \"EventCard-1a97ec3c-313e-4f70-88ab-c529803ff25f\"}, {\"id\": \"EventCard-021d9b3c-e667-4842-b0a7-d55ac2910418\"}, {\"id\": \"EventCard-38a61b45-3091-459b-b358-3e6cf4a1ce54\"}], \"constantValueEnabled\": true}, \"slots\": {\"CardSlot\": [{\"type\": \"EventCard\", \"props\": {\"id\": \"EventCard-92abd8ca-550c-4aee-92d9-4140b4ef53ad\", \"index\": 0, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"EventCard-92abd8ca-550c-4aee-92d9-4140b4ef53ad-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": \"Learn More\", \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta0\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"EventCard-92abd8ca-550c-4aee-92d9-4140b4ef53ad-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1504548840739-580b10ae7715?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.45)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"EventCard-92abd8ca-550c-4aee-92d9-4140b4ef53ad-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Event Title\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"DateTimeSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"EventCard-92abd8ca-550c-4aee-92d9-4140b4ef53ad-timestamp\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-12-12T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"2022-12-12T15:00:00\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": true, \"includeRange\": false}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"EventCard-92abd8ca-550c-4aee-92d9-4140b4ef53ad-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}, \"parentStyles\": {\"className\": \"md:line-clamp-2\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}, \"truncateDescription\": true}, \"conditionalRender\": {\"cta\": true, \"image\": true, \"title\": true, \"dateTime\": true, \"description\": true}}}, {\"type\": \"EventCard\", \"props\": {\"id\": \"EventCard-b1fd4377-76db-433e-9803-ea5ae0d9f996\", \"index\": 1, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"EventCard-b1fd4377-76db-433e-9803-ea5ae0d9f996-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": \"Learn More\", \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta1\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"EventCard-b1fd4377-76db-433e-9803-ea5ae0d9f996-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1502252430442-aac78f397426?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.45)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"EventCard-b1fd4377-76db-433e-9803-ea5ae0d9f996-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Event Title\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"DateTimeSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"EventCard-b1fd4377-76db-433e-9803-ea5ae0d9f996-timestamp\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-12-12T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"2022-12-12T15:00:00\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": true, \"includeRange\": false}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"EventCard-b1fd4377-76db-433e-9803-ea5ae0d9f996-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}, \"parentStyles\": {\"className\": \"md:line-clamp-2\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}, \"truncateDescription\": true}, \"conditionalRender\": {\"cta\": true, \"image\": true, \"title\": true, \"dateTime\": true, \"description\": true}}}, {\"type\": \"EventCard\", \"props\": {\"id\": \"EventCard-90968d53-5878-4459-b3dc-0b9b75e028ea\", \"index\": 2, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"EventCard-90968d53-5878-4459-b3dc-0b9b75e028ea-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": \"Learn More\", \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta2\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"EventCard-90968d53-5878-4459-b3dc-0b9b75e028ea-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1755745360285-0633c972b0fd?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.45)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"EventCard-90968d53-5878-4459-b3dc-0b9b75e028ea-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Event Title\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"DateTimeSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"EventCard-90968d53-5878-4459-b3dc-0b9b75e028ea-timestamp\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-12-12T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"2022-12-12T15:00:00\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": true, \"includeRange\": false}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"EventCard-90968d53-5878-4459-b3dc-0b9b75e028ea-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}, \"parentStyles\": {\"className\": \"md:line-clamp-2\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}, \"truncateDescription\": true}, \"conditionalRender\": {\"cta\": true, \"image\": true, \"title\": true, \"dateTime\": true, \"description\": true}}}, {\"type\": \"EventCard\", \"props\": {\"id\": \"EventCard-1a97ec3c-313e-4f70-88ab-c529803ff25f\", \"index\": 3, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"EventCard-1a97ec3c-313e-4f70-88ab-c529803ff25f-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Learn More\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta3\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"EventCard-1a97ec3c-313e-4f70-88ab-c529803ff25f-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1502252430442-aac78f397426?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb&height=360&width=640&fit=max\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.45)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"EventCard-1a97ec3c-313e-4f70-88ab-c529803ff25f-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Event Title\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"DateTimeSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"EventCard-1a97ec3c-313e-4f70-88ab-c529803ff25f-timestamp\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-12-12T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": true, \"includeRange\": false}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"EventCard-1a97ec3c-313e-4f70-88ab-c529803ff25f-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}, \"parentStyles\": {\"className\": \"md:line-clamp-2\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}, \"truncateDescription\": true}, \"conditionalRender\": {\"cta\": true, \"image\": true, \"title\": true, \"dateTime\": true, \"description\": true}}}, {\"type\": \"EventCard\", \"props\": {\"id\": \"EventCard-021d9b3c-e667-4842-b0a7-d55ac2910418\", \"index\": 4, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"EventCard-021d9b3c-e667-4842-b0a7-d55ac2910418-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Learn More\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta4\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"EventCard-021d9b3c-e667-4842-b0a7-d55ac2910418-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1504548840739-580b10ae7715?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb&height=360&width=640&fit=max\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.45)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"EventCard-021d9b3c-e667-4842-b0a7-d55ac2910418-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Event Title\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"DateTimeSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"EventCard-021d9b3c-e667-4842-b0a7-d55ac2910418-timestamp\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-12-12T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": true, \"includeRange\": false}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"EventCard-021d9b3c-e667-4842-b0a7-d55ac2910418-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}, \"parentStyles\": {\"className\": \"md:line-clamp-2\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}, \"truncateDescription\": true}, \"conditionalRender\": {\"cta\": true, \"image\": true, \"title\": true, \"dateTime\": true, \"description\": true}}}, {\"type\": \"EventCard\", \"props\": {\"id\": \"EventCard-38a61b45-3091-459b-b358-3e6cf4a1ce54\", \"index\": 5, \"slots\": {\"CTASlot\": [{\"type\": \"CTASlot\", \"props\": {\"id\": \"EventCard-38a61b45-3091-459b-b358-3e6cf4a1ce54-cta\", \"data\": {\"entityField\": {\"field\": \"\", \"constantValue\": {\"link\": \"#\", \"label\": {\"en\": \"Learn More\", \"hasLocalizedValue\": \"true\"}, \"ctaType\": \"textAndLink\", \"linkType\": \"URL\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"primary\", \"presetImage\": \"app-store\"}, \"eventName\": \"cta5\"}}], \"ImageSlot\": [{\"type\": \"ImageSlot\", \"props\": {\"id\": \"EventCard-38a61b45-3091-459b-b358-3e6cf4a1ce54-image\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"https://images.unsplash.com/photo-1504548840739-580b10ae7715?ixlib=rb-4.1.0&q=85&fm=jpg&crop=entropy&cs=srgb&height=360&width=640&fit=max\", \"width\": 640, \"height\": 360}, \"constantValueEnabled\": true}}, \"sizes\": {\"lg\": \"calc(maxWidth * 0.45)\", \"base\": \"calc(100vw - 32px)\"}, \"styles\": {\"width\": 640, \"aspectRatio\": 1.78}, \"className\": \"max-w-full h-full object-cover\", \"hideWidthProp\": true}}], \"TitleSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"EventCard-38a61b45-3091-459b-b358-3e6cf4a1ce54-title\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Event Title\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 3, \"semanticLevelOverride\": 3}}}], \"DateTimeSlot\": [{\"type\": \"Timestamp\", \"props\": {\"id\": \"EventCard-38a61b45-3091-459b-b358-3e6cf4a1ce54-timestamp\", \"data\": {\"date\": {\"field\": \"\", \"constantValue\": \"2022-12-12T14:00:00\", \"constantValueEnabled\": true}, \"endDate\": {\"field\": \"\", \"constantValue\": \"\", \"constantValueEnabled\": true}}, \"styles\": {\"includeTime\": true, \"includeRange\": false}}}], \"DescriptionSlot\": [{\"type\": \"BodyTextSlot\", \"props\": {\"id\": \"EventCard-38a61b45-3091-459b-b358-3e6cf4a1ce54-description\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": {\"html\": \"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.

\", \"json\": \"{\\\"root\\\":{\\\"children\\\":[{\\\"children\\\":[{\\\"detail\\\":0,\\\"format\\\":0,\\\"mode\\\":\\\"normal\\\",\\\"style\\\":\\\"\\\",\\\"text\\\":\\\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.\\\",\\\"type\\\":\\\"text\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"paragraph\\\",\\\"version\\\":1}],\\\"direction\\\":\\\"ltr\\\",\\\"format\\\":\\\"\\\",\\\"indent\\\":0,\\\"type\\\":\\\"root\\\",\\\"version\\\":1}}\"}, \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"variant\": \"base\"}, \"parentStyles\": {\"className\": \"md:line-clamp-2\"}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}, \"truncateDescription\": true}, \"conditionalRender\": {\"cta\": true, \"image\": true, \"title\": true, \"dateTime\": true, \"description\": true}}}]}}}], \"SectionHeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-31ae80c9-1679-427b-bb96-6d77526bac3e\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Upcoming Events\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 2}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-palette-secondary-light\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"eventsSection\"}, \"liveVisibility\": true}}, {\"type\": \"NearbyLocationsSection\", \"props\": {\"id\": \"NearbyLocationsSection-f6e05922-2989-4125-9234-2db1a0c46279\", \"slots\": {\"CardsWrapperSlot\": [{\"type\": \"NearbyLocationCardsWrapper\", \"props\": {\"id\": \"NearbyLocationCardsWrapper-7d43eba1-9a72-49eb-876d-3b77d672198b\", \"data\": {\"limit\": 3, \"radius\": 10, \"coordinate\": {\"field\": \"yextDisplayCoordinate\", \"constantValue\": {\"latitude\": 0, \"longitude\": 0}}}, \"styles\": {\"hours\": {\"timeFormat\": \"12h\", \"showDayNames\": true, \"dayOfWeekFormat\": \"long\", \"showCurrentStatus\": true}, \"phone\": {\"phoneNumberLink\": true, \"phoneNumberFormat\": \"domestic\"}, \"headingLevel\": 3, \"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"sectionHeadingLevel\": 2}}], \"SectionHeadingSlot\": [{\"type\": \"HeadingTextSlot\", \"props\": {\"id\": \"HeadingTextSlot-bb13cea8-227b-46ea-9da6-cb0845e62fb6\", \"data\": {\"text\": {\"field\": \"\", \"constantValue\": {\"en\": \"Nearby Locations\", \"hasLocalizedValue\": \"true\"}, \"constantValueEnabled\": true}}, \"styles\": {\"align\": \"left\", \"level\": 2}}}]}, \"styles\": {\"backgroundColor\": {\"bgColor\": \"bg-white\", \"textColor\": \"text-black\"}}, \"analytics\": {\"scope\": \"nearbyLocationsSection\"}, \"liveVisibility\": true}}, {\"type\": \"ExpandedFooter\", \"props\": {\"id\": \"ExpandedFooter-2c5d3c6c-615b-4d94-9b0b-16220bd840a0\", \"data\": {\"primaryFooter\": {\"expandedFooter\": false}}, \"slots\": {\"LogoSlot\": [{\"type\": \"FooterLogoSlot\", \"props\": {\"id\": \"ExpandedFooter-2c5d3c6c-615b-4d94-9b0b-16220bd840a0-FooterLogoSlot\", \"data\": {\"image\": {\"field\": \"\", \"constantValue\": {\"url\": \"\", \"width\": 100, \"height\": 100, \"alternateText\": {\"en\": \"Logo\", \"hasLocalizedValue\": \"true\"}}, \"constantValueEnabled\": true}}, \"styles\": {\"width\": 100, \"aspectRatio\": 1.78}}}], \"SocialLinksSlot\": [{\"type\": \"FooterSocialLinksSlot\", \"props\": {\"id\": \"ExpandedFooter-2c5d3c6c-615b-4d94-9b0b-16220bd840a0-FooterSocialLinksSlot\", \"data\": {\"xLink\": \"\", \"tiktokLink\": \"\", \"youtubeLink\": \"\", \"facebookLink\": \"\", \"linkedInLink\": \"\", \"instagramLink\": \"\", \"pinterestLink\": \"\"}}}], \"UtilityImagesSlot\": [{\"type\": \"FooterUtilityImagesSlot\", \"props\": {\"id\": \"ExpandedFooter-2c5d3c6c-615b-4d94-9b0b-16220bd840a0-FooterUtilityImagesSlot\", \"data\": {\"utilityImages\": []}, \"styles\": {\"width\": 60, \"aspectRatio\": 1}}}], \"SecondaryFooterSlot\": [{\"type\": \"SecondaryFooterSlot\", \"props\": {\"id\": \"ExpandedFooter-2c5d3c6c-615b-4d94-9b0b-16220bd840a0-SecondaryFooterSlot\", \"data\": {\"show\": true}, \"slots\": {\"CopyrightSlot\": [{\"type\": \"CopyrightMessageSlot\", \"props\": {\"id\": \"ExpandedFooter-2c5d3c6c-615b-4d94-9b0b-16220bd840a0-CopyrightSlot\", \"data\": {\"text\": {\"en\": \"\", \"hasLocalizedValue\": \"true\"}}, \"alignment\": \"left\"}}], \"SecondaryLinksWrapperSlot\": [{\"type\": \"FooterLinksSlot\", \"props\": {\"id\": \"ExpandedFooter-2c5d3c6c-615b-4d94-9b0b-16220bd840a0-FooterSecondaryLinksSlot\", \"data\": {\"links\": []}, \"variant\": \"secondary\", \"alignment\": \"left\", \"eventNamePrefix\": \"secondary\"}}]}, \"styles\": {\"linksAlignment\": \"left\"}, \"maxWidth\": \"theme\", \"ignoreLocaleWarning\": []}}], \"PrimaryLinksWrapperSlot\": [{\"type\": \"FooterLinksSlot\", \"props\": {\"id\": \"ExpandedFooter-2c5d3c6c-615b-4d94-9b0b-16220bd840a0-FooterPrimaryLinksSlot\", \"data\": {\"links\": []}, \"variant\": \"primary\", \"eventNamePrefix\": \"primary\"}}], \"ExpandedLinksWrapperSlot\": [{\"type\": \"FooterExpandedLinksWrapper\", \"props\": {\"id\": \"ExpandedFooter-2c5d3c6c-615b-4d94-9b0b-16220bd840a0-FooterExpandedLinksWrapper\", \"data\": {\"sections\": []}}}]}, \"styles\": {\"maxWidth\": \"theme\", \"primaryFooter\": {\"linksAlignment\": \"right\", \"backgroundColor\": {\"bgColor\": \"bg-palette-primary-dark\", \"textColor\": \"text-white\"}}}, \"analytics\": {\"scope\": \"expandedFooter\"}, \"ignoreLocaleWarning\": [\"slots.ExpandedLinksWrapperSlot\"]}}]}", + "name": "colto-test-pg", + "theme": "{}", + "visualEditorConfig": "{}" + }, + "_additionalLayoutComponents": [ + "CustomCodeSection" + ], + "_env": { + "YEXT_CLOUD_CHOICE": "GLOBAL-MULTI", + "YEXT_CLOUD_REGION": "US", + "YEXT_EDIT_LAYOUT_MODE_MAPBOX_API_KEY": "pk.eyJ1IjoieWV4dCIsImEiOiJjbWIxNmZ4ODcwNGhlMmpva3VpM2NvaGFjIn0.NRPU0XHQXTrb6Ix80JgJrg", + "YEXT_ENVIRONMENT": "DEV", + "YEXT_MAPBOX_API_KEY": "pk.eyJ1IjoieWV4dCIsImEiOiJjbWl5dHZhZ3IwaWxjM2ZvY3l2NjF2bTh6In0.HKvTsV6Zoeu7eTqdnQS9fg", + "YEXT_PUBLIC_VISUAL_EDITOR_APP_API_KEY": "2732254e8080baad4e51c4e86cb055cc", + "YEXT_SEARCH_API_KEY": "351640477c443b00f1537d4f93c97700" + }, + "_pageset": "{\"name\":\"accounts/11727428/sites/66377/branches/6057/pagesets/colto-test-pg\",\"uid\":\"019b040f-d865-7426-a0d9-f53af59badca\",\"codeTemplate\":\"main\",\"assignments\":[\"global\"],\"createTime\":\"2025-12-09T17:01:46Z\",\"updateTime\":\"2025-12-09T19:26:56Z\",\"scope\":{\"locales\":[\"en\"],\"entityTypes\":[\"location\"]},\"defaultLayout\":\"accounts/11727428/sites/66377/branches/6057/layouts/colto-test-pg-default-layout\",\"displayName\":\"colto-test-pg\",\"writebackUrlField\":\"pgs_coltoTest_coltoTestPg_gyrsk_Url\",\"type\":\"ENTITY\",\"typeConfig\":{\"entityConfig\":{\"locator\":\"accounts/11727428/sites/66377/branches/6057/pagesets/colto-test-pg-locator\"}},\"config\":{\"contentEndpointId\":\"66377-6057-colto-test-pg-Content\",\"urlTemplate\":{\"primary\":\"[[address.region]]/[[address.city]]/[[address.line1]]\"}}}", + "_schema": { + "@graph": [ + { + "@context": "https://schema.org", + "@type": "LocalBusiness", + "address": { + "@type": "PostalAddress", + "addressCountry": "US", + "addressLocality": "Kayliehaven", + "addressRegion": "AR", + "postalCode": "55498", + "streetAddress": "9872156 Leonardo Path" + }, + "description": "Everything is the same! Yes!", + "name": "Harber-Harber", + "telephone": "+19299599796" + } + ] + }, + "_yext": { + "contentDeliveryAPIDomain": "https://streams-dev.yext.com", + "managementAPIDomain": "https://dev.yext.com", + "platformDomain": "https://dev.yext.com" + }, + "address": { + "city": "Kayliehaven", + "countryCode": "US", + "line1": "9872156 Leonardo Path", + "line2": "Suite 231", + "localizedCountryName": "United States", + "localizedRegionName": "Arkansas", + "postalCode": "55498", + "region": "AR" + }, + "businessId": 11727428, + "description": "Everything is the same! Yes!", + "featuredMessage": { + "description": "Organized disintermediate matrix" + }, + "id": "2664307198831195313", + "isoRegionCode": "AR", + "locale": "en", + "mainPhone": "+19299599796", + "meta": { + "entityType": { + "id": "location", + "uid": 0 + }, + "locale": "en" + }, + "name": "Harber-Harber", + "ref_listings": [], + "ref_reviewsAgg": [], + "siteDomain": "", + "siteId": 66377, + "siteInternalHostName": "", + "timezone": "America/Chicago", + "uid": 5142224, + "yextDisplayCoordinate": { + "latitude": 39.5035514831543, + "longitude": -99.01830291748047 + }, + "yextRoutableCoordinate": { + "latitude": 33.956597, + "longitude": -116.517755 + } + } +} + */