meno-core 1.0.37 → 1.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../lib/server/jsonLoader.ts", "../../lib/shared/jsonRepair.ts", "../../lib/server/services/CachedConfigLoader.ts", "../../lib/server/services/ColorService.ts", "../../lib/server/services/VariableService.ts", "../../lib/server/services/cmsService.ts", "../../lib/shared/fontLoader.ts", "../../lib/server/ssr/attributeBuilder.ts", "../../lib/shared/slugTranslator.ts", "../../lib/server/ssr/metaTagGenerator.ts", "../../lib/server/ssr/cssCollector.ts", "../../lib/server/ssr/jsCollector.ts", "../../lib/server/ssr/cmsSSRProcessor.ts", "../../lib/server/ssr/imageMetadata.ts", "../../lib/server/ssr/ssrRenderer.ts", "../../lib/server/validateStyleCoverage.ts", "../../lib/server/ssr/clientDataInjector.ts", "../../lib/shared/libraryLoader.ts", "../../lib/server/cssGenerator.ts", "../../lib/client/scripts/formHandler.ts", "../../lib/client/meno-filter/script.generated.ts", "../../lib/server/ssr/htmlGenerator.ts", "../../lib/server/providers/fileSystemCMSProvider.ts", "../../lib/server/migrateTemplates.ts"],
4
- "sourcesContent": ["/**\n * JSON Loader\n * Utilities for loading and parsing JSON files\n */\n\nimport { existsSync, readdirSync } from 'fs';\nimport type { z } from 'zod';\nimport type { ComponentDefinition } from '../shared/types';\nimport type { BreakpointConfig, BreakpointConfigInput, BreakpointEntry } from '../shared/breakpoints';\nimport { readTextFile, fileExists } from './runtime';\nimport { DEFAULT_BREAKPOINTS, normalizeBreakpointConfig } from '../shared/breakpoints';\nimport type { ResponsiveScales, BreakpointScales } from '../shared/responsiveScaling';\nimport { DEFAULT_RESPONSIVE_SCALES } from '../shared/responsiveScaling';\nimport type { I18nConfig } from '../shared/types/components';\nimport { DEFAULT_I18N_CONFIG, migrateI18nConfig } from '../shared/i18n';\nimport type { PrefetchConfig } from '../shared/types/prefetch';\nimport { DEFAULT_PREFETCH_CONFIG } from '../shared/types/prefetch';\nimport { validateComponentDefinition } from '../shared/validation/validators';\nimport { attemptJsonRepair } from '../shared/jsonRepair';\nimport { projectPaths } from './projectContext';\n\n/**\n * Load JSON file from a file path\n */\nexport async function loadJSONFile(filePath: string): Promise<string | null> {\n try {\n if (await fileExists(filePath)) {\n return await readTextFile(filePath);\n }\n return null;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Parse JSON content\n */\nexport function parseJSON<T = unknown>(content: string): T {\n return JSON.parse(content);\n}\n\n/**\n * Parse and validate JSON content against a zod schema\n * Returns null on validation failure (for backward compatibility)\n */\nexport function parseAndValidateJSON<T>(\n content: string,\n schema: z.ZodType<T>\n): T | null {\n try {\n const parsed = JSON.parse(content);\n const result = schema.safeParse(parsed);\n if (result.success) {\n return result.data;\n }\n // Return parsed value anyway for backward compatibility\n return parsed as T;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Load and parse JSON file\n */\nexport async function loadAndParseJSON<T = any>(filePath: string): Promise<T | null> {\n const content = await loadJSONFile(filePath);\n if (!content) return null;\n \n try {\n return parseJSON<T>(content);\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Load all JSON files from a directory\n */\nexport async function loadJSONDirectory(\n dirPath: string\n): Promise<Map<string, string>> {\n const files = new Map<string, string>();\n \n if (!existsSync(dirPath)) {\n return files;\n }\n \n const fileList = readdirSync(dirPath);\n \n const jsonFiles = fileList.filter(f => f.endsWith('.json'));\n const results = await Promise.all(\n jsonFiles.map(async file => {\n const name = file.replace('.json', '');\n const content = await loadJSONFile(`${dirPath}/${file}`);\n return content ? { name, content } : null;\n })\n );\n for (const r of results) {\n if (r) files.set(r.name, r.content);\n }\n \n return files;\n}\n\n/**\n * Load file content as text (for .js, .css, etc.)\n */\nasync function loadFileAsText(filePath: string): Promise<string | null> {\n try {\n if (await fileExists(filePath)) {\n return await readTextFile(filePath);\n }\n return null;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Component with category metadata from folder structure\n */\nexport interface ComponentWithCategory extends ComponentDefinition {\n _category?: string;\n _relativePath?: string;\n}\n\nexport interface ComponentLoadDiagnostic {\n componentName: string;\n description: string;\n line: number;\n column: number;\n}\n\nexport interface ComponentLoadResult {\n component: ComponentWithCategory | null;\n warning?: ComponentLoadDiagnostic;\n error?: ComponentLoadDiagnostic;\n}\n\nexport interface ComponentDirectoryResult {\n components: Map<string, ComponentWithCategory>;\n warnings: ComponentLoadDiagnostic[];\n errors: ComponentLoadDiagnostic[];\n}\n\n/**\n * Load a single component from a file path\n * @internal\n */\nasync function loadSingleComponent(\n filePath: string,\n componentName: string,\n category?: string\n): Promise<ComponentLoadResult> {\n const content = await loadJSONFile(filePath);\n if (!content) return { component: null };\n\n const fileName = `${componentName}.json`;\n const repairResult = attemptJsonRepair(content);\n\n if (!repairResult.success) {\n return {\n component: null,\n error: {\n componentName,\n description: repairResult.error!.message,\n line: repairResult.error!.line,\n column: repairResult.error!.column,\n },\n };\n }\n\n const warning: ComponentLoadDiagnostic | undefined = repairResult.repaired\n ? {\n componentName,\n description: repairResult.repairDescription!,\n line: repairResult.repairLine ?? 1,\n column: repairResult.repairColumn ?? 1,\n }\n : undefined;\n\n try {\n const parsed = repairResult.data as ComponentDefinition;\n\n // Validate component definition (logs warnings but doesn't fail - graceful degradation)\n const validationResult = validateComponentDefinition(parsed);\n if (!validationResult.valid) {\n console.warn(`[jsonLoader] Component validation failed for ${componentName}:`,\n validationResult.errors.map(e => `${e.path}: ${e.message}`).join('; '));\n }\n const componentDef: ComponentWithCategory = validationResult.valid ? validationResult.data : parsed;\n\n // Determine the directory where the component file is located\n const dirPath = filePath.substring(0, filePath.lastIndexOf('/'));\n\n // Load .js and .css files in parallel\n const jsFilePath = `${dirPath}/${componentName}.js`;\n const cssFilePath = `${dirPath}/${componentName}.css`;\n const [jsContent, cssContent] = await Promise.all([\n loadFileAsText(jsFilePath),\n loadFileAsText(cssFilePath),\n ]);\n\n if (!componentDef.component) {\n componentDef.component = {};\n }\n\n // If .js file exists, use its content for javascript field\n // This takes precedence over any javascript field in the JSON\n if (jsContent) {\n componentDef.component.javascript = jsContent;\n\n // Auto-enable defineVars when .js file exists (unless explicitly set to false)\n if (componentDef.component.defineVars === undefined) {\n componentDef.component.defineVars = true;\n }\n }\n\n // If .css file exists, use its content for css field\n // This takes precedence over any css field in the JSON\n if (cssContent) {\n componentDef.component.css = cssContent;\n }\n\n // Add category metadata from folder structure\n if (category) {\n componentDef._category = category;\n componentDef._relativePath = `${category}/${componentName}`;\n }\n\n return { component: componentDef, warning };\n } catch (error) {\n return { component: null };\n }\n}\n\n/**\n * Load all component definitions from components directory (recursive)\n * Scans subdirectories as category folders. Component names must be unique across all folders.\n *\n * Folder structure:\n * - /components/Button.json \u2192 name: \"Button\", category: undefined\n * - /components/ui/Card.json \u2192 name: \"Card\", category: \"ui\"\n *\n * @param dirPath - Root components directory path\n * @returns Map of component names to ComponentDefinition with category metadata\n */\nexport async function loadComponentDirectory(\n dirPath: string = './components'\n): Promise<ComponentDirectoryResult> {\n const components = new Map<string, ComponentWithCategory>();\n const warnings: string[] = [];\n const errors: string[] = [];\n\n if (!existsSync(dirPath)) {\n return { components, warnings, errors };\n }\n\n const entries = readdirSync(dirPath, { withFileTypes: true });\n\n // Collect all component entries to load in parallel\n const loadEntries: { filePath: string; componentName: string; category?: string }[] = [];\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const category = entry.name;\n const categoryPath = `${dirPath}/${category}`;\n const categoryFiles = readdirSync(categoryPath);\n\n for (const file of categoryFiles) {\n if (file.endsWith('.json')) {\n loadEntries.push({\n filePath: `${categoryPath}/${file}`,\n componentName: file.replace('.json', ''),\n category,\n });\n }\n }\n } else if (entry.name.endsWith('.json')) {\n loadEntries.push({\n filePath: `${dirPath}/${entry.name}`,\n componentName: entry.name.replace('.json', ''),\n });\n }\n }\n\n // Load all components in parallel\n const results = await Promise.all(\n loadEntries.map(async e => ({\n ...e,\n result: await loadSingleComponent(e.filePath, e.componentName, e.category),\n }))\n );\n\n // Insert into map preserving listing order, with duplicate detection\n for (const { componentName, category, result } of results) {\n if (result.warning) warnings.push(result.warning);\n if (result.error) errors.push(result.error);\n if (!result.component) continue;\n if (components.has(componentName)) {\n const location = category ? `category \"${category}\"` : 'root level';\n console.warn(`[jsonLoader] Duplicate component name \"${componentName}\" found at ${location}. Skipping.`);\n continue;\n }\n components.set(componentName, result.component);\n }\n\n return { components, warnings, errors };\n}\n\n/**\n * Map page filename to route path\n */\nexport function mapPageNameToPath(pageName: string): string {\n return pageName === 'index' ? '/' : `/${pageName}`;\n}\n\n/**\n * Map route path to page filename\n */\nexport function mapPathToPageName(path: string): string {\n return path === '/' ? 'index' : path.substring(1);\n}\n\n// Breakpoint types are now imported from shared/breakpoints\n\n/**\n * Load and validate breakpoint configuration from project.config.json\n */\nexport async function loadBreakpointConfig(): Promise<BreakpointConfig> {\n try {\n const configContent = await loadJSONFile(projectPaths.config());\n if (configContent) {\n const config = parseJSON<{ breakpoints?: BreakpointConfigInput }>(configContent);\n\n if (config.breakpoints && typeof config.breakpoints === 'object') {\n // Preserve all breakpoints from config, filtering out invalid values\n const validInput: BreakpointConfigInput = {};\n for (const [key, value] of Object.entries(config.breakpoints)) {\n if (typeof value === 'number' && value > 0) {\n // Legacy format: number\n validInput[key] = value;\n } else if (typeof value === 'object' && value !== null) {\n // New format: object with breakpoint and optional previewPoint\n const entry = value as BreakpointEntry;\n if (typeof entry.breakpoint === 'number' && entry.breakpoint > 0) {\n validInput[key] = {\n breakpoint: entry.breakpoint,\n previewPoint: typeof entry.previewPoint === 'number' && entry.previewPoint > 0\n ? entry.previewPoint\n : entry.breakpoint,\n };\n }\n }\n }\n\n // If we have valid breakpoints, return them normalized; otherwise fall back to defaults\n if (Object.keys(validInput).length > 0) {\n return normalizeBreakpointConfig(validInput);\n }\n }\n }\n } catch (error) {\n }\n\n return { ...DEFAULT_BREAKPOINTS };\n}\n\n/**\n * Get breakpoint config synchronously (for cases where async is not available)\n * Uses cached value if available, otherwise defaults\n */\nlet cachedBreakpoints: BreakpointConfig | null = null;\n\nexport function getBreakpointConfig(): BreakpointConfig {\n if (cachedBreakpoints) {\n return cachedBreakpoints;\n }\n return DEFAULT_BREAKPOINTS;\n}\n\nexport function setBreakpointConfig(config: BreakpointConfig): void {\n cachedBreakpoints = config;\n}\n\n/**\n * Deep merge scale categories, preserving user-defined breakpoints\n * while filling in missing values from defaults\n */\nfunction mergeScaleCategory(\n userScales: BreakpointScales | undefined,\n defaultScales: BreakpointScales | undefined\n): BreakpointScales | undefined {\n if (!userScales && !defaultScales) return undefined;\n if (!userScales) return defaultScales ? { ...defaultScales } : undefined;\n if (!defaultScales) return { ...userScales };\n\n // User scales take precedence, but include defaults for breakpoints not specified\n return {\n ...defaultScales,\n ...userScales,\n };\n}\n\n/**\n * Load and validate responsive scales configuration from project.config.json\n * Supports dynamic breakpoints - scales are keyed by breakpoint name\n */\nexport async function loadResponsiveScalesConfig(): Promise<ResponsiveScales> {\n try {\n const configContent = await loadJSONFile(projectPaths.config());\n if (configContent) {\n const config = parseJSON<{ responsiveScales?: Partial<ResponsiveScales> }>(configContent);\n\n if (config.responsiveScales && typeof config.responsiveScales === 'object') {\n // Deep merge scale categories to preserve user breakpoint definitions\n // while filling in missing values from defaults\n const scales: ResponsiveScales = {\n enabled: config.responsiveScales.enabled ?? DEFAULT_RESPONSIVE_SCALES.enabled,\n baseReference: config.responsiveScales.baseReference ?? DEFAULT_RESPONSIVE_SCALES.baseReference,\n fontSize: mergeScaleCategory(\n config.responsiveScales.fontSize as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.fontSize\n ),\n padding: mergeScaleCategory(\n config.responsiveScales.padding as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.padding\n ),\n margin: mergeScaleCategory(\n config.responsiveScales.margin as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.margin\n ),\n gap: mergeScaleCategory(\n config.responsiveScales.gap as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.gap\n ),\n };\n\n return scales;\n }\n }\n } catch (error) {\n }\n\n return { ...DEFAULT_RESPONSIVE_SCALES };\n}\n\n/**\n * Get responsive scales config synchronously (for cases where async is not available)\n * Uses cached value if available, otherwise defaults\n */\nlet cachedResponsiveScales: ResponsiveScales | null = null;\n\nexport function getResponsiveScalesConfig(): ResponsiveScales {\n if (cachedResponsiveScales) {\n return cachedResponsiveScales;\n }\n return { ...DEFAULT_RESPONSIVE_SCALES };\n}\n\nexport function setResponsiveScalesConfig(config: ResponsiveScales): void {\n cachedResponsiveScales = config;\n}\n\n/**\n * Load and validate i18n configuration from project.config.json\n * Automatically migrates old string[] format to new LocaleConfig[] format\n */\nexport async function loadI18nConfig(): Promise<I18nConfig> {\n try {\n const configContent = await loadJSONFile(projectPaths.config());\n if (configContent) {\n const config = parseJSON<{ i18n?: unknown }>(configContent);\n return migrateI18nConfig(config.i18n);\n }\n } catch (error) {\n // Fall through to default\n }\n\n return { ...DEFAULT_I18N_CONFIG };\n}\n\n/**\n * Get i18n config synchronously (for cases where async is not available)\n * Uses cached value if available, otherwise defaults\n */\nlet cachedI18nConfig: I18nConfig | null = null;\n\nexport function getI18nConfig(): I18nConfig {\n if (cachedI18nConfig) {\n return cachedI18nConfig;\n }\n return { ...DEFAULT_I18N_CONFIG };\n}\n\nexport function setI18nConfig(config: I18nConfig): void {\n cachedI18nConfig = config;\n}\n\n/**\n * Icons configuration from project.config.json\n */\nexport interface IconsConfig {\n favicon?: string;\n appleTouchIcon?: string;\n}\n\n/**\n * Load icons configuration from project.config.json\n */\nexport async function loadIconsConfig(): Promise<IconsConfig> {\n try {\n const configContent = await loadJSONFile(projectPaths.config());\n if (configContent) {\n const config = parseJSON<{ icons?: IconsConfig }>(configContent);\n if (config.icons && typeof config.icons === 'object') {\n return config.icons;\n }\n }\n } catch (error) {\n // Fall through to default\n }\n\n return {};\n}\n\n/**\n * Load prefetch configuration from project.config.json\n * Used for production SSR sites to enable link prefetching\n */\nexport async function loadPrefetchConfig(): Promise<PrefetchConfig> {\n try {\n const configContent = await loadJSONFile(projectPaths.config());\n if (configContent) {\n const config = parseJSON<{ prefetch?: Partial<PrefetchConfig> }>(configContent);\n if (config.prefetch && typeof config.prefetch === 'object') {\n // Merge with defaults to ensure all required fields are present\n return {\n ...DEFAULT_PREFETCH_CONFIG,\n ...config.prefetch,\n };\n }\n }\n } catch (error) {\n // Fall through to default\n }\n\n return { ...DEFAULT_PREFETCH_CONFIG };\n}\n\n", "/**\n * JSON Repair Utility\n * Attempts to fix common JSON syntax errors (trailing commas, missing commas)\n */\n\nexport interface JsonParseErrorInfo {\n message: string;\n line: number;\n column: number;\n}\n\nexport interface JsonRepairResult {\n success: boolean;\n data?: unknown;\n repaired: boolean;\n repairDescription?: string;\n repairLine?: number;\n repairColumn?: number;\n error?: JsonParseErrorInfo;\n}\n\n/**\n * Extract line/column from a JSON SyntaxError\n */\nexport function parseJsonError(error: unknown, content: string): JsonParseErrorInfo {\n if (!(error instanceof SyntaxError)) {\n return { message: String(error), line: 1, column: 1 };\n }\n\n const msg = error.message;\n\n // Bun/V8: \"JSON Parse error: Expected '}'\" or \"Unexpected token } in JSON at position 42\"\n // Try to extract position from message\n const posMatch = msg.match(/at position (\\d+)/i);\n if (posMatch) {\n const pos = parseInt(posMatch[1], 10);\n const { line, column } = offsetToLineColumn(content, pos);\n return { message: msg, line, column };\n }\n\n // Bun format: \"JSON Parse error: ...\"\n // Try line number extraction\n const lineMatch = msg.match(/line (\\d+)/i);\n const colMatch = msg.match(/column (\\d+)/i);\n if (lineMatch) {\n return {\n message: msg,\n line: parseInt(lineMatch[1], 10),\n column: colMatch ? parseInt(colMatch[1], 10) : 1,\n };\n }\n\n return { message: msg, line: 1, column: 1 };\n}\n\nfunction offsetToLineColumn(content: string, offset: number): { line: number; column: number } {\n let line = 1;\n let lastNewline = -1;\n for (let i = 0; i < offset && i < content.length; i++) {\n if (content[i] === '\\n') {\n line++;\n lastNewline = i;\n }\n }\n return { line, column: offset - lastNewline };\n}\n\n/**\n * Attempt to repair common JSON errors\n */\nexport function attemptJsonRepair(content: string): JsonRepairResult {\n // Try parsing as-is first\n try {\n const data = JSON.parse(content);\n return { success: true, repaired: false, data };\n } catch (firstError) {\n // Continue to repair attempts\n }\n\n // Attempt: remove trailing commas (e.g., {a: 1,} or [1,])\n {\n const fixed = content.replace(/,\\s*([\\]}])/g, '$1');\n try {\n const data = JSON.parse(fixed);\n // Find where we removed a comma for the description\n const trailingCommaMatch = content.match(/,\\s*([\\]}])/);\n const pos = trailingCommaMatch ? content.indexOf(trailingCommaMatch[0]) : 0;\n const { line, column } = offsetToLineColumn(content, pos);\n return {\n success: true,\n repaired: true,\n data,\n repairDescription: `removed trailing comma at line ${line}`,\n repairLine: line,\n repairColumn: column,\n };\n } catch {\n // Continue\n }\n }\n\n // Attempt: insert missing commas between properties/elements\n // Pattern: value on one line, key/value on next line without comma\n // e.g., \"foo\": \"bar\"\\n \"baz\": ... or \"value\"\\n \"next\"\n {\n const lines = content.split('\\n');\n let fixed = '';\n let repairLine = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trimEnd();\n const nextLine = i + 1 < lines.length ? lines[i + 1] : null;\n\n if (nextLine !== null) {\n const nextTrimmed = nextLine.trimStart();\n // Check if current line ends with a value (not comma, not opening bracket, not colon)\n // and next line starts with a key or value\n const needsComma =\n /[\"\\d\\w\\]}\\-]$/.test(trimmed) &&\n !trimmed.endsWith(',') &&\n !trimmed.endsWith('{') &&\n !trimmed.endsWith('[') &&\n !trimmed.endsWith(':') &&\n (nextTrimmed.startsWith('\"') || nextTrimmed.startsWith('{') || nextTrimmed.startsWith('[') || /^\\d/.test(nextTrimmed) || nextTrimmed === 'true' || nextTrimmed === 'false' || nextTrimmed === 'null');\n\n if (needsComma) {\n fixed += trimmed + ',\\n';\n if (repairLine === 0) repairLine = i + 1;\n } else {\n fixed += line + '\\n';\n }\n } else {\n fixed += line;\n }\n }\n\n try {\n const data = JSON.parse(fixed);\n return {\n success: true,\n repaired: true,\n data,\n repairDescription: `auto-fixed missing comma at line ${repairLine}`,\n repairLine,\n repairColumn: 1,\n };\n } catch {\n // Continue\n }\n }\n\n // All repairs failed - return structured error\n let errorInfo: JsonParseErrorInfo;\n try {\n JSON.parse(content);\n errorInfo = { message: 'Unknown error', line: 1, column: 1 };\n } catch (e) {\n errorInfo = parseJsonError(e, content);\n }\n\n return { success: false, repaired: false, error: errorInfo };\n}\n\n/**\n * Format a user-friendly error message for JSON parse failures\n */\nexport function formatJsonErrorMessage(fileName: string, error: JsonParseErrorInfo): string {\n return `${fileName}: JSON syntax error at line ${error.line}, column ${error.column} \u2014 ${error.message}`;\n}\n\n/**\n * Format a message describing a successful JSON repair\n */\nexport function formatJsonRepairMessage(fileName: string, description: string): string {\n return `${fileName}: ${description}. Save to apply fix.`;\n}\n", "/**\n * Base class for services that lazy-load, cache, and deduplicate config file access.\n *\n * Subclasses implement `performLoad()` and optionally `getDefaultConfig()`.\n */\nexport abstract class CachedConfigLoader<T> {\n private config: T | null = null;\n private loadingPromise: Promise<T> | null = null;\n\n /**\n * Load config, returning cached value if available.\n * Concurrent calls share the same loading promise.\n */\n async load(): Promise<T> {\n if (this.config) {\n return this.config;\n }\n\n if (this.loadingPromise) {\n return this.loadingPromise;\n }\n\n this.loadingPromise = this.performLoad();\n this.config = await this.loadingPromise;\n this.loadingPromise = null;\n\n return this.config;\n }\n\n /**\n * Override in subclass to load config from disk.\n */\n protected abstract performLoad(): Promise<T>;\n\n /**\n * Reset cached value so the next `load()` re-reads from disk.\n */\n clearCache(): void {\n this.config = null;\n }\n\n /**\n * Update the cached value directly (used after saving to disk).\n */\n protected setCache(config: T): void {\n this.config = config;\n }\n\n /**\n * Peek at the current cached value (null if not loaded).\n */\n protected getCache(): T | null {\n return this.config;\n }\n}\n", "/**\n * Color Service\n * Manages loading and caching of color variables and themes from colors.json\n */\n\nimport { loadJSONFile, parseJSON } from '../jsonLoader';\nimport { projectPaths } from '../projectContext';\nimport type { ColorVariables, ColorVariableEntry, ThemeConfig, ThemeEntry } from '../../shared/types';\nimport { resolvePaletteColor } from '../../shared/types';\nimport { CachedConfigLoader } from './CachedConfigLoader';\nimport { writeFile } from '../runtime';\n\nexport class ColorService extends CachedConfigLoader<ThemeConfig> {\n /**\n * Load theme configuration from colors.json\n */\n async loadThemeConfig(): Promise<ThemeConfig> {\n return this.load();\n }\n\n /**\n * Perform the actual loading from file\n */\n protected async performLoad(): Promise<ThemeConfig> {\n try {\n const content = await loadJSONFile(projectPaths.colors());\n if (content) {\n const data = parseJSON(content);\n if (data && typeof data === 'object' && 'themes' in data && 'default' in data) {\n return data as ThemeConfig;\n }\n }\n } catch (error) {\n console.warn('Failed to load colors.json:', error);\n }\n\n // Return default theme config if file not found or invalid\n return this.getDefaultThemeConfig();\n }\n\n /**\n * Get default theme configuration\n */\n private getDefaultThemeConfig(): ThemeConfig {\n return {\n default: 'dark',\n themes: {\n dark: {\n label: 'Dark',\n colors: {\n 'primary': '#007acc',\n 'primary-light': '#0099ff',\n 'primary-dark': '#005a99',\n 'secondary': '#6c757d',\n 'success': '#28a745',\n 'warning': '#ffc107',\n 'danger': '#dc3545',\n 'error': '#d32f2f',\n 'info': '#17a2b8',\n 'light': '#f8f9fa',\n 'dark': '#343a40',\n 'text': '#cccccc',\n 'text-dark': '#1e1e1e',\n 'background': '#1e1e1e',\n 'background-light': '#252526',\n 'border': '#444444',\n 'border-light': '#d0d0d0',\n },\n },\n light: {\n label: 'Light',\n colors: {\n 'primary': '#0066ff',\n 'primary-light': '#3385ff',\n 'primary-dark': '#0052cc',\n 'secondary': '#888888',\n 'success': '#22c55e',\n 'warning': '#f59e0b',\n 'danger': '#ef4444',\n 'error': '#dc2626',\n 'info': '#06b6d4',\n 'light': '#f8f9fa',\n 'dark': '#1f2937',\n 'text': '#1f2937',\n 'text-dark': '#ffffff',\n 'background': '#ffffff',\n 'background-light': '#f3f4f6',\n 'border': '#d1d5db',\n 'border-light': '#e5e7eb',\n },\n },\n },\n };\n }\n\n /**\n * Get minimal theme configuration (for new file creation)\n */\n private getMinimalConfig(): ThemeConfig {\n return {\n default: 'default',\n themes: {\n default: {\n label: 'Default',\n colors: {\n 'background': '#1e1e1e',\n 'text': '#cccccc',\n },\n },\n },\n };\n }\n\n /**\n * Get config with status info (for editor UI)\n * Distinguishes between missing file, invalid JSON, and valid config\n */\n async getConfigWithStatus(): Promise<{\n status: 'valid' | 'missing' | 'invalid';\n config: ThemeConfig;\n error?: string;\n filePath: string;\n }> {\n const filePath = projectPaths.colors();\n try {\n const content = await loadJSONFile(filePath);\n if (!content) {\n return { status: 'missing', config: this.getMinimalConfig(), filePath };\n }\n const data = parseJSON(content);\n if (data && typeof data === 'object' && 'themes' in data && 'default' in data) {\n return { status: 'valid', config: data as ThemeConfig, filePath };\n }\n return { status: 'invalid', config: this.getMinimalConfig(), error: 'Invalid structure: missing \"themes\" or \"default\" property', filePath };\n } catch (error) {\n return {\n status: 'invalid',\n config: this.getMinimalConfig(),\n error: error instanceof Error ? error.message : 'Parse error',\n filePath,\n };\n }\n }\n\n /**\n * Get colors for a specific theme (or default if not found)\n */\n async getThemeColors(themeName?: string): Promise<ColorVariables> {\n const config = await this.loadThemeConfig();\n const theme = themeName && config.themes[themeName] ? config.themes[themeName] : config.themes[config.default];\n const resolvedColors: Record<string, string> = {};\n for (const [name, value] of Object.entries(theme.colors)) {\n resolvedColors[name] = resolvePaletteColor(value, config.palette);\n }\n return { colors: resolvedColors };\n }\n\n /**\n * Load color variables from colors.json (for backward compatibility)\n */\n async loadColors(): Promise<ColorVariables> {\n return this.getThemeColors();\n }\n\n /**\n * Get all available themes\n */\n async getAvailableThemes(): Promise<ThemeEntry[]> {\n const config = await this.loadThemeConfig();\n return Object.entries(config.themes).map(([name, theme]) => ({\n name,\n label: theme.label,\n }));\n }\n\n /**\n * Get default theme name\n */\n async getDefaultTheme(): Promise<string> {\n const config = await this.loadThemeConfig();\n return config.default;\n }\n\n /**\n * Get all color variables as entries for a theme\n */\n async getColorEntries(themeName?: string): Promise<ColorVariableEntry[]> {\n const colors = await this.getThemeColors(themeName);\n return Object.entries(colors.colors).map(([name, value]) => ({\n name,\n value,\n }));\n }\n\n /**\n * Get a specific color by name from a theme\n */\n async getColor(name: string, themeName?: string): Promise<string | null> {\n const colors = await this.getThemeColors(themeName);\n return colors.colors[name] || null;\n }\n\n /**\n * Get the full theme configuration (for editor)\n */\n async getFullConfig(): Promise<ThemeConfig> {\n return this.loadThemeConfig();\n }\n\n /**\n * Save theme configuration to colors.json\n */\n async saveThemeConfig(config: ThemeConfig): Promise<void> {\n const colorsPath = projectPaths.colors();\n const content = JSON.stringify(config, null, 2);\n await writeFile(colorsPath, content);\n\n // Update cache with new config\n this.setCache(config);\n }\n}\n\n// Export singleton instance\nexport const colorService = new ColorService();\n", "/**\n * Variable Service\n * Manages loading and caching of CSS variables from variables.json\n */\n\nimport { loadJSONFile, parseJSON } from '../jsonLoader';\nimport { projectPaths } from '../projectContext';\nimport type { VariablesConfig } from '../../shared/types';\nimport { CachedConfigLoader } from './CachedConfigLoader';\nimport { writeFile } from '../runtime';\n\nexport class VariableService extends CachedConfigLoader<VariablesConfig> {\n /**\n * Load variables configuration from variables.json\n */\n async loadConfig(): Promise<VariablesConfig> {\n return this.load();\n }\n\n protected async performLoad(): Promise<VariablesConfig> {\n try {\n const content = await loadJSONFile(projectPaths.variables());\n if (content) {\n const data = parseJSON(content);\n if (data && typeof data === 'object' && 'variables' in data && Array.isArray(data.variables)) {\n return this.migrateConfig(data as VariablesConfig);\n }\n }\n } catch (error) {\n console.warn('Failed to load variables.json:', error);\n }\n\n return this.getDefaultConfig();\n }\n\n private getDefaultConfig(): VariablesConfig {\n return { variables: [] };\n }\n\n /**\n * Migrate legacy config values (e.g. \"spacing\" group -> margin/padding/gap)\n */\n private migrateConfig(config: VariablesConfig): VariablesConfig {\n for (const variable of config.variables) {\n if ((variable.group as string) === 'spacing') {\n const lower = (variable.cssVar + ' ' + variable.name).toLowerCase();\n if (lower.includes('margin')) {\n variable.group = 'margin';\n } else if (lower.includes('gap')) {\n variable.group = 'gap';\n } else {\n variable.group = 'padding';\n }\n }\n }\n return config;\n }\n\n /**\n * Get config with status info (for editor UI)\n */\n async getConfigWithStatus(): Promise<{\n status: 'valid' | 'missing' | 'invalid';\n config: VariablesConfig;\n error?: string;\n filePath: string;\n }> {\n const filePath = projectPaths.variables();\n try {\n const content = await loadJSONFile(filePath);\n if (!content) {\n return { status: 'missing', config: this.getDefaultConfig(), filePath };\n }\n const data = parseJSON(content);\n if (data && typeof data === 'object' && 'variables' in data && Array.isArray(data.variables)) {\n return { status: 'valid', config: this.migrateConfig(data as VariablesConfig), filePath };\n }\n return { status: 'invalid', config: this.getDefaultConfig(), error: 'Invalid structure: missing \"variables\" array', filePath };\n } catch (error) {\n return {\n status: 'invalid',\n config: this.getDefaultConfig(),\n error: error instanceof Error ? error.message : 'Parse error',\n filePath,\n };\n }\n }\n\n /**\n * Save variables configuration to variables.json\n */\n async saveConfig(config: VariablesConfig): Promise<void> {\n const variablesPath = projectPaths.variables();\n const content = JSON.stringify(config, null, 2);\n await writeFile(variablesPath, content);\n this.setCache(config);\n }\n}\n\n// Export singleton instance\nexport const variableService = new VariableService();\n", "/**\n * CMS Service\n * Handles CMS schema extraction, route matching, and content querying\n */\n\nimport type { CMSProvider, CMSSchemaInfo } from '../../shared/interfaces/contentProvider';\nimport type {\n CMSSchema,\n CMSItem,\n CMSRouteMatch,\n CMSListQuery,\n CMSFilterCondition,\n CMSSortConfig,\n ReferenceLocation,\n} from '../../shared/types';\nimport { isItemDraftForLocale } from '../../shared/types';\nimport { isI18nValue } from '../../shared/i18n';\nimport { tiptapToHtml } from '../../shared/richtext/tiptapToHtml';\nimport { isTiptapDocument } from '../../shared/richtext/types';\n\ninterface RoutePattern {\n regex: RegExp;\n collection: string;\n slugGroup: number;\n pagePath: string;\n}\n\ninterface CachedItems {\n items: CMSItem[];\n timestamp: number;\n}\n\n/**\n * CMS Service\n * Manages CMS schemas, route matching, and content querying\n */\nexport class CMSService {\n private schemaCache = new Map<string, CMSSchemaInfo>();\n private routePatterns: RoutePattern[] = [];\n private provider?: CMSProvider;\n\n /** Item cache with TTL-based expiration */\n private itemsCache = new Map<string, CachedItems>();\n /** Cache TTL in milliseconds (5 seconds) */\n private readonly ITEMS_CACHE_TTL = 5000;\n\n /**\n * Creates a new CMSService instance\n * @param provider - Optional CMSProvider for loading data (enables DI for testing)\n */\n constructor(provider?: CMSProvider) {\n this.provider = provider;\n }\n\n /**\n * Set the CMS provider\n * Allows setting provider after construction for backward compatibility\n * @param provider - CMSProvider implementation\n */\n setProvider(provider: CMSProvider): void {\n this.provider = provider;\n }\n\n /**\n * Get items with caching\n * Returns cached items if available and not expired, otherwise fetches fresh data\n * Rich-text fields are automatically preprocessed to HTML for template interpolation\n * @param collection - Collection ID to fetch items for\n * @returns Array of CMSItems with rich-text fields converted to HTML markers\n */\n private async getCachedItems(collection: string): Promise<CMSItem[]> {\n const cached = this.itemsCache.get(collection);\n const now = Date.now();\n\n // Return cached items if still valid\n if (cached && now - cached.timestamp < this.ITEMS_CACHE_TTL) {\n return cached.items;\n }\n\n // Fetch fresh items\n const rawItems = await this.provider!.getItems(collection);\n\n // Preprocess rich-text fields for template interpolation\n const items = this.preprocessRichTextFields(collection, rawItems);\n\n // Update cache\n this.itemsCache.set(collection, { items, timestamp: now });\n\n return items;\n }\n\n /**\n * Preprocess rich-text fields in CMS items.\n * Converts TipTap JSON to HTML and wraps in __richtext__ marker for template interpolation.\n * @param collection - Collection ID (to get schema)\n * @param items - Raw CMS items\n * @returns Items with rich-text fields converted\n */\n private preprocessRichTextFields(collection: string, items: CMSItem[]): CMSItem[] {\n const schemaInfo = this.schemaCache.get(collection);\n if (!schemaInfo) return items;\n\n // Find rich-text fields in schema\n const richTextFields = Object.entries(schemaInfo.schema.fields)\n .filter(([, def]) => def.type === 'rich-text')\n .map(([name]) => name);\n\n if (richTextFields.length === 0) return items;\n\n // Process each item\n return items.map(item => {\n const processed = { ...item };\n\n for (const fieldName of richTextFields) {\n const value = item[fieldName];\n\n // Skip if no value or already processed\n if (!value) continue;\n if (typeof value === 'object' && '__richtext__' in value) continue;\n\n // Convert TipTap document to HTML\n if (isTiptapDocument(value)) {\n const html = tiptapToHtml(value);\n processed[fieldName] = { __richtext__: true, html };\n }\n // Already HTML string - wrap it\n else if (typeof value === 'string') {\n processed[fieldName] = { __richtext__: true, html: value };\n }\n }\n\n return processed;\n });\n }\n\n /**\n * Clear items cache for a specific collection or all collections\n * @param collection - Optional collection ID, clears all if not provided\n */\n clearItemsCache(collection?: string): void {\n if (collection) {\n this.itemsCache.delete(collection);\n } else {\n this.itemsCache.clear();\n }\n }\n\n /**\n * Initialize service - extract schemas from pages and build route patterns\n * Builds state in local variables then swaps atomically so concurrent\n * matchRoute() calls see either old OR new state, never empty.\n */\n async initialize(): Promise<void> {\n if (!this.provider) {\n return;\n }\n\n const schemas = await this.provider.getAllSchemas();\n\n // Build new state in locals before swapping\n const newSchemaCache = new Map<string, CMSSchemaInfo>();\n const newRoutePatterns: RoutePattern[] = [];\n\n for (const [id, schemaInfo] of schemas) {\n newSchemaCache.set(id, schemaInfo);\n newRoutePatterns.push({\n regex: this.patternToRegex(schemaInfo.schema.urlPattern),\n collection: id,\n slugGroup: 1,\n pagePath: schemaInfo.pagePath,\n });\n }\n\n // Atomic swap - concurrent matchRoute sees old OR new, never empty\n this.schemaCache = newSchemaCache;\n this.routePatterns = newRoutePatterns;\n }\n\n /**\n * Convert URL pattern to regex\n * e.g., \"/blog/{{slug}}\" -> /^\\/blog\\/([^\\/]+)$/\n */\n private patternToRegex(pattern: string): RegExp {\n // Escape special regex characters except our placeholder\n const escaped = pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n // Replace the escaped placeholder with a capture group\n const withCapture = escaped.replace(/\\\\\\{\\\\\\{slug\\\\\\}\\\\\\}/g, '([^/]+)');\n return new RegExp(`^${withCapture}$`);\n }\n\n /**\n * Match URL against CMS route patterns\n * Supports i18n slugs - matches locale-specific slug values\n * @param path - URL path to match\n * @param locale - Optional locale for i18n slug matching\n * @returns CMSRouteMatch if matched, null otherwise\n */\n async matchRoute(path: string, locale?: string): Promise<CMSRouteMatch | null> {\n if (!this.provider) {\n return null;\n }\n\n for (const route of this.routePatterns) {\n const match = path.match(route.regex);\n if (match) {\n const urlSlug = match[route.slugGroup];\n\n // Try to find item by matching its slug field value\n const item = await this.findItemBySlug(route.collection, urlSlug, locale);\n\n if (item) {\n return {\n collection: route.collection,\n slug: urlSlug,\n item,\n pagePath: route.pagePath,\n };\n }\n }\n }\n return null;\n }\n\n /**\n * Find item by simple string slug match\n * @param items - Items to search through\n * @param urlSlug - Slug value from URL\n * @param slugField - Field name containing the slug\n * @returns CMSItem if found, null otherwise\n */\n private findBySimpleSlug(\n items: CMSItem[],\n urlSlug: string,\n slugField: string\n ): CMSItem | null {\n for (const item of items) {\n const slugValue = item[slugField];\n\n if (typeof slugValue === 'string' && slugValue === urlSlug) {\n return item;\n }\n // Also check _filename for backward compatibility\n if (item._filename === urlSlug) {\n return item;\n }\n }\n return null;\n }\n\n /**\n * Find item by i18n slug match\n * @param items - Items to search through\n * @param urlSlug - Slug value from URL\n * @param slugField - Field name containing the slug\n * @param locale - Optional locale for preferential matching\n * @returns CMSItem if found, null otherwise\n */\n private findByI18nSlug(\n items: CMSItem[],\n urlSlug: string,\n slugField: string,\n locale?: string\n ): CMSItem | null {\n for (const item of items) {\n const slugValue = item[slugField];\n\n if (!isI18nValue(slugValue)) continue;\n\n // If locale provided, try to match that locale's slug first\n if (locale && slugValue[locale] === urlSlug) {\n return item;\n }\n\n // Try to match any locale's slug value\n for (const key of Object.keys(slugValue)) {\n if (key !== '_i18n' && slugValue[key] === urlSlug) {\n return item;\n }\n }\n }\n return null;\n }\n\n /**\n * Find item by slug value (supports i18n slugs)\n * @param collection - Collection ID\n * @param urlSlug - Slug value from URL\n * @param locale - Optional locale for i18n slug matching\n * @returns CMSItem if found, null otherwise\n */\n private async findItemBySlug(\n collection: string,\n urlSlug: string,\n locale?: string\n ): Promise<CMSItem | null> {\n if (!this.provider) {\n return null;\n }\n\n const schemaInfo = this.schemaCache.get(collection);\n if (!schemaInfo) return null;\n\n const slugField = schemaInfo.schema.slugField;\n const items = await this.getCachedItems(collection);\n\n // Try simple string slug match first\n const simpleMatch = this.findBySimpleSlug(items, urlSlug, slugField);\n if (simpleMatch) return simpleMatch;\n\n // Try i18n slug match\n const i18nMatch = this.findByI18nSlug(items, urlSlug, slugField, locale);\n if (i18nMatch) return i18nMatch;\n\n // Fallback: try direct filename lookup for backward compatibility\n return await this.provider.getItemByFilename(collection, urlSlug);\n }\n\n /**\n * Get all URLs for a collection (for static generation)\n * Supports i18n slugs - generates URLs for all locales when slug is i18n\n * @param collection - Collection ID\n * @param locales - Optional array of locale codes for i18n URL generation\n * @param defaultLocale - Optional default locale (URLs without prefix)\n * @returns Array of URLs\n */\n async getCollectionURLs(\n collection: string,\n locales?: string[],\n defaultLocale?: string,\n options?: { excludeDrafts?: boolean }\n ): Promise<string[]> {\n if (!this.provider) {\n return [];\n }\n\n const schemaInfo = this.schemaCache.get(collection);\n if (!schemaInfo) return [];\n\n const items = await this.getCachedItems(collection);\n const urls: string[] = [];\n\n for (const item of items) {\n const slugValue = item[schemaInfo.schema.slugField];\n\n // Case 1: Simple string slug - one URL\n if (typeof slugValue === 'string') {\n // Skip if item is draft for the default locale (non-i18n case)\n if (options?.excludeDrafts && defaultLocale && isItemDraftForLocale(item, defaultLocale)) continue;\n urls.push(\n schemaInfo.schema.urlPattern.replace('{{slug}}', slugValue)\n );\n }\n // Case 2: i18n slug - one URL per locale\n else if (isI18nValue(slugValue) && locales) {\n for (const locale of locales) {\n if (options?.excludeDrafts && isItemDraftForLocale(item, locale)) continue;\n const localizedSlug = slugValue[locale] as string;\n if (localizedSlug) {\n const path = schemaInfo.schema.urlPattern.replace('{{slug}}', localizedSlug);\n // For default locale, no prefix; for others, add locale prefix\n if (locale === defaultLocale) {\n urls.push(path);\n } else {\n urls.push(`/${locale}${path}`);\n }\n }\n }\n }\n // Case 3: i18n slug but no locales provided - use first available slug\n else if (isI18nValue(slugValue)) {\n for (const key of Object.keys(slugValue)) {\n if (key !== '_i18n' && typeof slugValue[key] === 'string') {\n urls.push(\n schemaInfo.schema.urlPattern.replace('{{slug}}', slugValue[key] as string)\n );\n break; // Only use first available\n }\n }\n }\n }\n\n return urls;\n }\n\n /**\n * Get schema for collection\n * @param collection - Collection ID\n * @returns CMSSchema or undefined\n */\n getSchema(collection: string): CMSSchema | undefined {\n return this.schemaCache.get(collection)?.schema;\n }\n\n /**\n * Get all schemas\n * @returns Map of collection ID to CMSSchemaInfo\n */\n getAllSchemas(): Map<string, CMSSchemaInfo> {\n return this.schemaCache;\n }\n\n /**\n * Refresh schemas from provider\n * Call this after adding/removing collections to update the cache.\n * Only clears items cache and provider cache before re-initializing.\n * Schema/route caches are swapped atomically inside initialize().\n */\n async refreshSchemas(): Promise<void> {\n if (!this.provider) {\n return;\n }\n\n // Clear items cache so stale content isn't served\n this.itemsCache.clear();\n\n // Clear provider cache if available\n if ('clearSchemaCache' in this.provider && typeof this.provider.clearSchemaCache === 'function') {\n this.provider.clearSchemaCache();\n }\n\n // Re-initialize - atomically swaps schemaCache and routePatterns\n await this.initialize();\n }\n\n /**\n * Query items with filter/sort/limit\n * @param query - CMSListQuery with collection, filter, sort, limit, offset\n * @returns Filtered and sorted array of CMSItems\n */\n async queryItems(query: CMSListQuery): Promise<CMSItem[]> {\n if (!this.provider) {\n return [];\n }\n\n let items = await this.getCachedItems(query.collection);\n\n // Exclude draft items for the specified locale\n if (query.excludeDraftLocale) {\n items = items.filter(item => !isItemDraftForLocale(item, query.excludeDraftLocale!));\n }\n\n // Apply filters\n if (query.filter) {\n items = this.applyFilters(items, query.filter);\n }\n\n // Apply sorting\n if (query.sort) {\n items = this.applySorting(items, query.sort);\n }\n\n // Apply offset\n if (query.offset !== undefined && query.offset > 0) {\n items = items.slice(query.offset);\n }\n\n // Apply limit\n if (query.limit !== undefined && query.limit > 0) {\n items = items.slice(0, query.limit);\n }\n\n return items;\n }\n\n /**\n * Apply filters to items\n */\n private applyFilters(\n items: CMSItem[],\n filter: CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown>\n ): CMSItem[] {\n // Handle simple object filter: { featured: true }\n if (!Array.isArray(filter) && !this.isFilterCondition(filter)) {\n return items.filter(item =>\n Object.entries(filter).every(([key, value]) => item[key] === value)\n );\n }\n\n // Handle array of conditions or single condition\n const conditions = Array.isArray(filter) ? filter : [filter as CMSFilterCondition];\n return items.filter(item =>\n conditions.every(cond => this.matchCondition(item, cond))\n );\n }\n\n /**\n * Check if object is a CMSFilterCondition\n */\n private isFilterCondition(obj: unknown): obj is CMSFilterCondition {\n return typeof obj === 'object' && obj !== null && 'field' in obj;\n }\n\n /**\n * Match a single filter condition against an item\n */\n private matchCondition(item: CMSItem, condition: CMSFilterCondition): boolean {\n const value = item[condition.field];\n const op = condition.operator || 'eq';\n\n switch (op) {\n case 'eq':\n return value === condition.value;\n case 'neq':\n return value !== condition.value;\n case 'gt':\n return (value as number) > (condition.value as number);\n case 'gte':\n return (value as number) >= (condition.value as number);\n case 'lt':\n return (value as number) < (condition.value as number);\n case 'lte':\n return (value as number) <= (condition.value as number);\n case 'contains':\n return String(value).includes(String(condition.value));\n case 'in':\n return Array.isArray(condition.value) && condition.value.includes(value);\n default:\n return false;\n }\n }\n\n /**\n * Get items by their IDs from a collection.\n * Used for resolving reference fields in CMS List templates.\n * Missing IDs are silently skipped. Order is preserved based on input ids array.\n *\n * @param collection - Collection ID to fetch from\n * @param ids - Array of item IDs or filenames to fetch\n * @returns Array of CMSItems matching the IDs\n */\n async getItemsByIds(collection: string, ids: string[]): Promise<CMSItem[]> {\n if (!this.provider) {\n return [];\n }\n\n const allItems = await this.getCachedItems(collection);\n\n // Build lookup maps for both _id and _filename\n const itemMap = new Map(allItems.map(item => [item._id, item]));\n const filenameMap = new Map(\n allItems\n .filter(item => item._filename)\n .map(item => [item._filename!, item])\n );\n\n // Filter to matching items, preserving input order\n return ids\n .filter(Boolean)\n .map(id => itemMap.get(id) || filenameMap.get(id))\n .filter((item): item is CMSItem => item !== undefined);\n }\n\n /**\n * Apply sorting to items\n */\n private applySorting(items: CMSItem[], sort: CMSSortConfig | CMSSortConfig[]): CMSItem[] {\n const sorts = Array.isArray(sort) ? sort : [sort];\n\n return [...items].sort((a, b) => {\n for (const s of sorts) {\n const aVal = a[s.field];\n const bVal = b[s.field];\n const isDesc = s.order === 'desc';\n\n // Handle boolean comparison\n if (typeof aVal === 'boolean' && typeof bVal === 'boolean') {\n if (aVal === bVal) continue;\n // For desc: true first (true > false), for asc: false first\n if (isDesc) {\n return aVal ? -1 : 1;\n } else {\n return aVal ? 1 : -1;\n }\n }\n\n // Standard comparison (compare as primitives)\n let result = 0;\n if ((aVal as string | number) < (bVal as string | number)) result = -1;\n else if ((aVal as string | number) > (bVal as string | number)) result = 1;\n\n if (result !== 0) {\n return isDesc ? -result : result;\n }\n }\n return 0;\n });\n }\n\n /**\n * Find all references to a specific item across all collections.\n * Used to warn users before deleting an item that is referenced elsewhere.\n *\n * @param targetCollection - Collection ID of the item being referenced\n * @param targetId - ID or filename of the target item\n * @returns Array of ReferenceLocation objects describing where the item is referenced\n */\n async findReferencesTo(\n targetCollection: string,\n targetId: string\n ): Promise<ReferenceLocation[]> {\n if (!this.provider) {\n return [];\n }\n\n const references: ReferenceLocation[] = [];\n const allSchemas = this.getAllSchemas();\n\n for (const [collectionId, schemaInfo] of allSchemas) {\n const { schema } = schemaInfo;\n\n // Find reference fields pointing to targetCollection\n const refFields = Object.entries(schema.fields)\n .filter(([_, def]) => def.type === 'reference' && def.collection === targetCollection);\n\n if (refFields.length === 0) continue;\n\n // Check all items in this collection\n const items = await this.getCachedItems(collectionId);\n for (const item of items) {\n for (const [fieldName] of refFields) {\n const value = item[fieldName];\n if (!value) continue;\n\n const ids = Array.isArray(value) ? value : [value];\n if (ids.includes(targetId)) {\n references.push({\n collection: collectionId,\n itemId: item._id,\n itemSlug: item._slug,\n itemFilename: item._filename,\n fieldName,\n });\n }\n }\n }\n }\n\n return references;\n }\n\n /**\n * Remove all references to a target item.\n * For single-reference fields: sets to null\n * For multi-reference fields: filters out the target ID\n * @returns Number of items updated\n */\n async removeReferencesTo(\n targetCollection: string,\n targetId: string\n ): Promise<number> {\n if (!this.provider) {\n return 0;\n }\n\n const references = await this.findReferencesTo(targetCollection, targetId);\n let removedCount = 0;\n\n for (const ref of references) {\n if (!ref.itemFilename) continue;\n\n const item = await this.provider.getItemByFilename(ref.collection, ref.itemFilename);\n if (!item) continue;\n\n const schemaInfo = this.getAllSchemas().get(ref.collection);\n const fieldDef = schemaInfo?.schema.fields[ref.fieldName];\n const currentValue = item[ref.fieldName];\n\n let newValue: string | string[] | null;\n if (fieldDef?.multiple && Array.isArray(currentValue)) {\n // Multi-reference: filter out target\n newValue = currentValue.filter(id => id !== targetId);\n if (newValue.length === 0) newValue = null;\n } else {\n // Single reference: clear it\n newValue = null;\n }\n\n // Update the item\n await this.provider.saveItem(ref.collection, {\n ...item,\n [ref.fieldName]: newValue,\n });\n removedCount++;\n }\n\n return removedCount;\n }\n}\n\n// Re-export ReferenceLocation from shared types for backward compatibility\nexport type { ReferenceLocation } from '../../shared/types';\n", "import { projectPaths } from '../server/projectContext';\nimport { readJsonFile, fileExists } from '../server/runtime';\n\nexport interface FontConfig {\n path: string;\n family?: string;\n weight?: number;\n weightMax?: number; // If set, font is variable with weight range [weight, weightMax]\n style?: 'normal' | 'italic';\n fontDisplay?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional';\n unicodeRange?: string;\n}\n\ninterface ProjectConfig {\n fonts?: FontConfig[];\n siteUrl?: string;\n [key: string]: unknown;\n}\n\nlet cachedConfig: ProjectConfig | null = null;\n\nexport function resetFontConfig(): void {\n cachedConfig = null;\n}\n\nexport async function loadProjectConfig(): Promise<ProjectConfig> {\n if (cachedConfig) return cachedConfig;\n if (await fileExists(projectPaths.config())) {\n cachedConfig = await readJsonFile<ProjectConfig>(projectPaths.config());\n } else {\n cachedConfig = { fonts: [] };\n }\n return cachedConfig!;\n}\n\n// For synchronous access after config is loaded\nexport function getProjectConfig(): ProjectConfig {\n return cachedConfig || { fonts: [] };\n}\n\n/**\n * Detect font format from file extension\n */\nfunction getFontFormat(path: string): string {\n if (path.endsWith('.woff2')) return 'woff2';\n if (path.endsWith('.woff')) return 'woff';\n if (path.endsWith('.ttf')) return 'truetype';\n if (path.endsWith('.otf')) return 'opentype';\n return 'truetype';\n}\n\n/**\n * Extract font family name from path if not provided\n * Example: \"/fonts/geomanist-regular.ttf\" -> \"Geomanist\"\n */\nfunction extractFamilyName(path: string): string {\n const filename = path.split('/').pop() || 'Font';\n const name = filename.replace(/\\.(ttf|woff2?|otf)$/i, '');\n // Capitalize and replace hyphens with spaces\n return name\n .split('-')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n}\n\nexport function generateFontCSS(): string {\n const config = getProjectConfig();\n const fonts = config.fonts || [];\n\n return fonts\n .filter((font: any) => font.path || font.src)\n .map((font: any) => {\n // Support both \"path\" (standard) and \"src\" (legacy from website import)\n const fontPath: string = font.path || font.src;\n const format = getFontFormat(fontPath);\n const family = font.family || extractFamilyName(fontPath);\n const weight = font.weight ?? 400;\n const weightMax = font.weightMax;\n const style = font.style ?? 'normal';\n const fontDisplay = font.fontDisplay;\n\n // Variable fonts use weight range syntax: \"100 900\"\n const fontWeight = weightMax != null ? `${weight} ${weightMax}` : weight;\n\n const unicodeRange = font.unicodeRange;\n\n return `@font-face {\n font-family: '${family}';\n src: url('${fontPath}') format('${format}');\n font-weight: ${fontWeight};\n font-style: ${style};${fontDisplay ? `\\n font-display: ${fontDisplay};` : ''}${unicodeRange ? `\\n unicode-range: ${unicodeRange};` : ''}\n}`;\n })\n .join('\\n\\n');\n}\n\n/**\n * Get font MIME type for preload \"type\" attribute\n */\nfunction getFontMimeType(path: string): string {\n if (path.endsWith('.woff2')) return 'font/woff2';\n if (path.endsWith('.woff')) return 'font/woff';\n if (path.endsWith('.ttf')) return 'font/ttf';\n if (path.endsWith('.otf')) return 'font/otf';\n return 'font/ttf';\n}\n\n/**\n * Generate font preload link tags for early font loading\n * This prevents font swap flash on SPA navigation by ensuring fonts are\n * loaded and cached before they're needed.\n */\nexport function generateFontPreloadTags(): string {\n const config = getProjectConfig();\n const fonts = config.fonts || [];\n\n if (fonts.length === 0) return '';\n\n return fonts\n .filter((font: any) => font.path || font.src)\n .map((font: any) => {\n const fontPath: string = font.path || font.src;\n const mimeType = getFontMimeType(fontPath);\n // crossorigin is required for fonts to be cached properly\n return `<link rel=\"preload\" href=\"${fontPath}\" as=\"font\" type=\"${mimeType}\" crossorigin>`;\n })\n .join('\\n ');\n}\n\nexport function getFontFamilies(): Record<string, number[]> {\n const config = getProjectConfig();\n const fonts = config.fonts || [];\n const familiesMap: Record<string, number[]> = {};\n\n fonts.forEach((font: any) => {\n const fontPath: string = font.path || font.src;\n if (!fontPath) return;\n const family = font.family || extractFamilyName(fontPath);\n const weight = font.weight ?? 400;\n const weightMax = font.weightMax;\n\n if (!familiesMap[family]) {\n familiesMap[family] = [];\n }\n\n // Variable fonts: include all weights in range (100, 200, ..., weightMax)\n if (weightMax != null) {\n for (let w = weight; w <= weightMax; w += 100) {\n if (!familiesMap[family].includes(w)) {\n familiesMap[family].push(w);\n }\n }\n } else {\n if (!familiesMap[family].includes(weight)) {\n familiesMap[family].push(weight);\n }\n }\n });\n\n return familiesMap;\n}\n", "/**\n * HTML attribute building utilities for SSR\n * Pure functions with no external dependencies\n */\n\n/**\n * Escape HTML special characters to prevent XSS\n */\nexport function escapeHtml(unsafe: string): string {\n // Handle non-string values defensively\n if (typeof unsafe !== 'string') {\n if (unsafe === null || unsafe === undefined) {\n return '';\n }\n // Convert arrays/objects/numbers to string\n unsafe = String(unsafe);\n }\n return unsafe\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n}\n\n/** HTML attributes that must NOT be kebab-cased (single-word or special casing) */\nconst NO_KEBAB_ATTRS = new Set([\n 'autoplay', 'playsinline', 'crossorigin', 'novalidate', 'readonly',\n 'nomodule', 'formnovalidate', 'ismap', 'usemap', 'srcset', 'inputmode',\n 'enterkeyhint', 'autocomplete', 'autofocus', 'contenteditable',\n]);\n\n/**\n * Build HTML attributes string from props (excluding style and other special props)\n */\nexport function buildAttributes(props: Record<string, unknown>, exclude: string[] = []): string {\n const attrs: string[] = [];\n // Internal props that should never be rendered as HTML attributes\n // Note: image-specific props (src, alt, loading, width, height, sizes, srcset, fetchpriority)\n // are NOT excluded here - they're only excluded for <img> tags via the exclude parameter\n const internalProps = ['tag', 'component', 'props', 'children'];\n const defaultExclude = [...internalProps, ...exclude];\n\n // Regex to detect unresolved template strings like {{link.target}}\n // But NOT item templates like {{item.field}} or {{post.field}} - those should be preserved for client-side rendering\n const unresolvedTemplatePattern = /^\\{\\{(?!item\\.|[a-z]+Index|[a-z]+First|[a-z]+Last).+\\}\\}$/;\n\n for (const [key, value] of Object.entries(props)) {\n if (defaultExclude.includes(key)) continue;\n if (value === null || value === undefined) continue;\n if (typeof value === 'function') continue; // Skip event handlers in SSR\n if (typeof value === 'object') continue; // Skip objects (prevents [object Object] in attributes)\n // Skip unresolved template strings (e.g., {{link.target}} when link.target is undefined)\n // BUT keep item templates like {{item.field}} for client-side dynamic rendering\n if (typeof value === 'string' && unresolvedTemplatePattern.test(value)) continue;\n\n // Convert camelCase to kebab-case for HTML attributes,\n // but preserve non-kebab HTML attributes (autoplay, playsinline, etc.)\n const attrName = NO_KEBAB_ATTRS.has(key.toLowerCase())\n ? key.toLowerCase()\n : key.replace(/([A-Z])/g, '-$1').toLowerCase();\n const attrValue = typeof value === 'boolean'\n ? (value ? '' : undefined)\n : escapeHtml(String(value));\n\n if (attrValue !== undefined) {\n if (typeof value === 'boolean' && value) {\n attrs.push(attrName);\n } else {\n attrs.push(`${attrName}=\"${attrValue}\"`);\n }\n }\n }\n\n return attrs.length > 0 ? ' ' + attrs.join(' ') : '';\n}\n\n/**\n * Convert a style object to inline CSS string\n * Handles CSS variables (--is-0: value) and regular properties\n */\nexport function styleToString(style: Record<string, string | number> | undefined): string {\n if (!style || Object.keys(style).length === 0) return '';\n\n const declarations: string[] = [];\n for (const [key, value] of Object.entries(style)) {\n if (value === null || value === undefined) continue;\n\n // Handle CSS variables (already in kebab-case with -- prefix)\n if (key.startsWith('--')) {\n declarations.push(`${key}: ${escapeHtml(String(value))}`);\n } else {\n // Convert camelCase to kebab-case for regular CSS properties\n const cssProperty = key.replace(/([A-Z])/g, '-$1').toLowerCase();\n declarations.push(`${cssProperty}: ${escapeHtml(String(value))}`);\n }\n }\n\n return declarations.length > 0 ? declarations.join('; ') : '';\n}\n", "/**\n * Slug Translation Service\n * Handles translation of URL slugs between locales\n */\n\nimport type { I18nConfig } from './types';\n\n/**\n * Slug mapping for a single page\n */\nexport interface SlugMap {\n pageId: string;\n slugs: Record<string, string>;\n}\n\n/**\n * Index entry for reverse lookup (slug+locale \u2192 pageId)\n */\ninterface SlugIndexEntry {\n pageId: string;\n slugs: Record<string, string>;\n}\n\n/**\n * Build reverse lookup index: \"locale:slug\" \u2192 SlugIndexEntry\n * This allows quick lookup of pageId from any locale's slug\n */\nexport function buildSlugIndex(mappings: SlugMap[]): Map<string, SlugIndexEntry> {\n const index = new Map<string, SlugIndexEntry>();\n\n for (const mapping of mappings) {\n for (const [locale, slug] of Object.entries(mapping.slugs)) {\n // Key format: \"locale:slug\" (e.g., \"pl:o-nas\" or \"en:about\")\n const key = `${locale}:${slug}`;\n index.set(key, {\n pageId: mapping.pageId,\n slugs: mapping.slugs,\n });\n }\n }\n\n return index;\n}\n\n/**\n * Find page by slug and locale\n * @returns The SlugIndexEntry if found, undefined otherwise\n */\nexport function findPageBySlug(\n slug: string,\n locale: string,\n index: Map<string, SlugIndexEntry>\n): SlugIndexEntry | undefined {\n const key = `${locale}:${slug}`;\n return index.get(key);\n}\n\n/**\n * Translate a path to another locale\n *\n * @param currentPath - Current URL path (e.g., \"/pl/o-nas\" or \"/about\")\n * @param targetLocale - Target locale (e.g., \"en\")\n * @param currentLocale - Current locale (e.g., \"pl\")\n * @param defaultLocale - Default locale that doesn't use prefix (e.g., \"en\")\n * @param index - Slug index from buildSlugIndex()\n * @returns Translated path (e.g., \"/about\" for en default, \"/de/uber\" for de)\n */\nexport function translatePath(\n currentPath: string,\n targetLocale: string,\n currentLocale: string,\n defaultLocale: string,\n index: Map<string, SlugIndexEntry>\n): string {\n // Extract slug from current path (remove locale prefix if present)\n let slug = currentPath;\n\n // Remove leading slash\n if (slug.startsWith('/')) {\n slug = slug.substring(1);\n }\n\n // Remove locale prefix if present (e.g., \"pl/o-nas\" \u2192 \"o-nas\")\n // Also handle case where slug IS the locale (e.g., \"pl\" for Polish homepage)\n if (currentLocale !== defaultLocale) {\n if (slug.startsWith(`${currentLocale}/`)) {\n slug = slug.substring(currentLocale.length + 1);\n } else if (slug === currentLocale) {\n // Path is just the locale prefix (e.g., \"/pl\" \u2192 index page)\n slug = '';\n }\n }\n\n // Handle root path\n if (slug === '' || slug === '/') {\n slug = '';\n }\n\n // Look up page by current slug and locale\n let entry = findPageBySlug(slug, currentLocale, index);\n\n // If not found for current locale, try default locale\n // This handles cases like /de/about where German uses the English slug\n if (!entry && currentLocale !== defaultLocale) {\n entry = findPageBySlug(slug, defaultLocale, index);\n }\n\n if (!entry) {\n // No translation found - return path with just locale prefix change\n if (targetLocale === defaultLocale) {\n return slug === '' ? '/' : `/${slug}`;\n }\n return slug === '' ? `/${targetLocale}` : `/${targetLocale}/${slug}`;\n }\n\n // Get translated slug for target locale\n const targetSlug = entry.slugs[targetLocale] ?? entry.slugs[defaultLocale] ?? slug;\n\n // Build target path\n if (targetLocale === defaultLocale) {\n return targetSlug === '' ? '/' : `/${targetSlug}`;\n }\n return targetSlug === '' ? `/${targetLocale}` : `/${targetLocale}/${targetSlug}`;\n}\n\n/**\n * Locale link information for locale switcher\n */\nexport interface LocaleLink {\n locale: string; // Locale code (e.g., \"pl\")\n langTag: string; // BCP 47 language tag (e.g., \"pl-PL\")\n name: string; // English name (e.g., \"Polish\")\n nativeName: string; // Display name in native language (e.g., \"Polski\")\n path: string; // Translated path for this locale\n isCurrent: boolean; // Whether this is the current locale\n}\n\n/**\n * Get all available locales with their translated paths for the current page\n * Useful for rendering locale switcher\n *\n * @param currentPath - Current URL path\n * @param currentLocale - Current locale\n * @param i18nConfig - i18n configuration with locales\n * @param index - Slug index\n * @returns Array of LocaleLink objects\n */\nexport function getLocaleLinks(\n currentPath: string,\n currentLocale: string,\n i18nConfig: I18nConfig,\n index: Map<string, SlugIndexEntry>\n): LocaleLink[] {\n return i18nConfig.locales.map(localeConfig => ({\n locale: localeConfig.code,\n langTag: localeConfig.langTag,\n name: localeConfig.name,\n nativeName: localeConfig.nativeName,\n path: translatePath(currentPath, localeConfig.code, currentLocale, i18nConfig.defaultLocale, index),\n isCurrent: localeConfig.code === currentLocale,\n }));\n}\n\n/**\n * Resolve a slug to its pageId (for server-side page loading)\n *\n * @param slug - URL slug (e.g., \"o-nas\")\n * @param locale - Current locale (e.g., \"pl\")\n * @param index - Slug index\n * @returns pageId if found (e.g., \"about\"), undefined otherwise\n */\nexport function resolveSlugToPageId(\n slug: string,\n locale: string,\n index: Map<string, SlugIndexEntry>\n): string | undefined {\n const entry = findPageBySlug(slug, locale, index);\n return entry?.pageId;\n}\n", "/**\n * Meta tag generation for SSR\n * Handles SEO meta information extraction and HTML generation\n */\n\nimport type { JSONPage } from '../../shared/types';\nimport type { I18nConfig } from '../../shared/types/components';\nimport { DEFAULT_I18N_CONFIG, resolveI18nValue } from '../../shared/i18n';\nimport { escapeHtml } from './attributeBuilder';\nimport { buildSlugIndex, getLocaleLinks, type SlugMap } from '../../shared/slugTranslator';\n\n/**\n * Page meta information for SEO\n * Values can be strings or i18n objects - resolved in generateMetaTags\n */\nexport interface PageMeta {\n title?: unknown;\n description?: unknown;\n keywords?: unknown;\n ogTitle?: unknown;\n ogDescription?: unknown;\n ogImage?: unknown;\n ogType?: unknown;\n}\n\nexport function extractPageMeta(pageData: JSONPage): PageMeta {\n const meta: PageMeta = {};\n\n if (pageData?.meta) {\n meta.title = pageData.meta.title;\n meta.description = pageData.meta.description;\n meta.keywords = pageData.meta.keywords;\n meta.ogTitle = pageData.meta.ogTitle || pageData.meta.title;\n meta.ogDescription = pageData.meta.ogDescription || pageData.meta.description;\n meta.ogImage = pageData.meta.ogImage;\n meta.ogType = pageData.meta.ogType || 'website';\n }\n\n return meta;\n}\n\n/**\n * Options for hreflang tag generation\n */\nexport interface HreflangOptions {\n slugMappings?: SlugMap[];\n pagePath?: string;\n baseUrl?: string;\n}\n\n/**\n * Generate HTML meta tags string\n * Resolves i18n values using the provided locale and config\n * Optionally generates hreflang tags for multilingual pages\n */\nexport function generateMetaTags(\n meta: PageMeta,\n url: string = '',\n locale: string = 'en',\n config: I18nConfig = DEFAULT_I18N_CONFIG,\n hreflangOptions?: HreflangOptions\n): string {\n const tags: string[] = [];\n\n // Helper to resolve i18n values and ensure string type\n const resolve = (value: unknown): string => {\n const resolved = resolveI18nValue(value, locale, config);\n return typeof resolved === 'string' ? resolved : '';\n };\n\n const title = resolve(meta.title);\n const description = resolve(meta.description);\n const keywords = resolve(meta.keywords);\n const ogTitle = resolve(meta.ogTitle) || title;\n const ogDescription = resolve(meta.ogDescription) || description;\n const ogImage = resolve(meta.ogImage);\n const ogType = resolve(meta.ogType);\n\n if (title) {\n tags.push(`<title>${escapeHtml(title)}</title>`);\n }\n\n if (description) {\n tags.push(`<meta name=\"description\" content=\"${escapeHtml(description)}\" />`);\n }\n\n if (keywords) {\n tags.push(`<meta name=\"keywords\" content=\"${escapeHtml(keywords)}\" />`);\n }\n\n // Open Graph tags\n if (ogTitle) {\n tags.push(`<meta property=\"og:title\" content=\"${escapeHtml(ogTitle)}\" />`);\n }\n\n if (ogDescription) {\n tags.push(`<meta property=\"og:description\" content=\"${escapeHtml(ogDescription)}\" />`);\n }\n\n if (ogImage) {\n tags.push(`<meta property=\"og:image\" content=\"${escapeHtml(ogImage)}\" />`);\n }\n\n if (ogType) {\n tags.push(`<meta property=\"og:type\" content=\"${escapeHtml(ogType)}\" />`);\n }\n\n if (url) {\n tags.push(`<meta property=\"og:url\" content=\"${escapeHtml(url)}\" />`);\n }\n\n // Canonical URL\n if (url) {\n tags.push(`<link rel=\"canonical\" href=\"${escapeHtml(url)}\" />`);\n }\n\n // Hreflang tags for multilingual pages\n if (hreflangOptions?.slugMappings && hreflangOptions.slugMappings.length > 0 && config.locales.length > 1) {\n const { slugMappings, pagePath = '/', baseUrl = '' } = hreflangOptions;\n const slugIndex = buildSlugIndex(slugMappings);\n const localeLinks = getLocaleLinks(pagePath, locale, config, slugIndex);\n\n for (const link of localeLinks) {\n const hrefUrl = baseUrl ? `${baseUrl}${link.path}` : link.path;\n tags.push(`<link rel=\"alternate\" hreflang=\"${escapeHtml(link.langTag)}\" href=\"${escapeHtml(hrefUrl)}\" />`);\n }\n\n // Add x-default pointing to default locale version\n const defaultLink = localeLinks.find(l => l.locale === config.defaultLocale);\n if (defaultLink) {\n const xDefaultUrl = baseUrl ? `${baseUrl}${defaultLink.path}` : defaultLink.path;\n tags.push(`<link rel=\"alternate\" hreflang=\"x-default\" href=\"${escapeHtml(xDefaultUrl)}\" />`);\n }\n }\n\n return tags.join('\\n ');\n}\n", "/**\n * CSS collection utilities for SSR\n * Collects CSS from component definitions\n */\n\nimport type { ComponentDefinition } from '../../shared/types';\n\n/**\n * Collect CSS code from all components (global and page-specific)\n */\nexport function collectComponentCSS(\n globalComponents: Record<string, ComponentDefinition> = {},\n pageComponents: Record<string, ComponentDefinition> = {}\n): string {\n const cssBlocks: string[] = [];\n\n // Collect CSS from global components\n for (const [name, component] of Object.entries(globalComponents)) {\n if (component?.component?.css) {\n cssBlocks.push(`/* Component: ${name} */\\n${component.component.css}`);\n }\n }\n\n // Collect CSS from page-specific components\n for (const [name, component] of Object.entries(pageComponents)) {\n // Skip if already collected from global components\n if (!globalComponents[name] && component?.component?.css) {\n cssBlocks.push(`/* Component: ${name} */\\n${component.component.css}`);\n }\n }\n\n return cssBlocks.join('\\n\\n');\n}\n", "/**\n * JavaScript collection utilities for SSR\n * Collects and wraps component JavaScript with defineVars support\n */\n\nimport type { ComponentDefinition } from '../../shared/types';\nimport { validateJS as runtimeValidateJS } from '../runtime';\n\n/**\n * Validate JavaScript syntax using runtime bundler\n * Returns error message if invalid, null if valid\n */\nasync function validateJS(code: string): Promise<string | null> {\n return runtimeValidateJS(code);\n}\n\n/**\n * Runtime helper for defineVars - initializes components with their props\n * Injected once when any component uses defineVars\n */\nconst DEFINE_VARS_RUNTIME = `(function() {\n var __meno = window.__meno || (window.__meno = {});\n __meno.initComponent = function(name, fn) {\n var elements = document.querySelectorAll('[data-component~=\"' + name + '\"]');\n elements.forEach(function(el) {\n var propsStr = el.getAttribute('data-props');\n var allProps = propsStr ? JSON.parse(propsStr) : {};\n var props = allProps[name] || {};\n fn(el, props);\n });\n };\n})();`;\n\n/**\n * Generate destructure statement for defineVars\n */\nfunction generateDestructure(\n defineVars: true | string[],\n interfaceDef?: Record<string, unknown>\n): string {\n const vars = defineVars === true\n ? Object.keys(interfaceDef || {})\n : defineVars;\n if (vars.length === 0) return '';\n return `var {${vars.join(', ')}} = props;`;\n}\n\n/**\n * Callback for component JS validation errors\n */\nexport type JSErrorCallback = (componentName: string, error: string) => void;\n\n/**\n * Cache for validated component JS\n * Maps component name -> validation result (null=valid, string=error)\n * This prevents re-validating the same component for every page\n */\nconst validationCache = new Map<string, string | null>();\n\n/**\n * Collected JS validation errors (componentName -> error message)\n */\nconst collectedErrors = new Map<string, string>();\n\n/**\n * Clear the validation cache and collected errors (call at start of build)\n */\nexport function clearJSValidationCache(): void {\n validationCache.clear();\n collectedErrors.clear();\n}\n\n/**\n * Get all collected JS validation errors\n * Returns array of { component, error } objects\n */\nexport function getJSValidationErrors(): Array<{ component: string; error: string }> {\n return Array.from(collectedErrors.entries()).map(([component, error]) => ({\n component,\n error,\n }));\n}\n\n/**\n * Collect JavaScript code from all components (global and page-specific)\n * Wraps defineVars components with initComponent pattern\n * Validates each component's JS individually and reports errors via callback\n */\nexport async function collectComponentJavaScript(\n globalComponents: Record<string, ComponentDefinition> = {},\n pageComponents: Record<string, ComponentDefinition> = {},\n onError?: JSErrorCallback\n): Promise<string> {\n const jsCodeBlocks: string[] = [];\n let hasDefineVars = false;\n\n // Helper to process a component's JavaScript\n const processComponent = async (name: string, component: ComponentDefinition) => {\n if (!component?.component?.javascript) return;\n\n const js = component.component.javascript;\n const defineVars = component.component.defineVars;\n\n // Check cache first to avoid re-validating\n let error: string | null;\n if (validationCache.has(name)) {\n error = validationCache.get(name)!;\n } else {\n error = await validateJS(js);\n validationCache.set(name, error);\n }\n\n if (error) {\n // Collect error internally (for build-static.ts to retrieve)\n if (!collectedErrors.has(name)) {\n collectedErrors.set(name, error);\n }\n onError?.(name, error);\n return; // Skip this component's JS\n }\n\n if (defineVars) {\n hasDefineVars = true;\n const destructure = generateDestructure(defineVars, component.component.interface);\n jsCodeBlocks.push(`// Component: ${name}\n__meno.initComponent(\"${name}\", function(el, props) {\n ${destructure}\n ${js}\n});`);\n } else {\n // No defineVars - emit as-is (backward compatible)\n jsCodeBlocks.push(`// Component: ${name}\\n${js}`);\n }\n };\n\n // Collect JS from global components\n for (const [name, component] of Object.entries(globalComponents)) {\n await processComponent(name, component);\n }\n\n // Collect JS from page-specific components\n for (const [name, component] of Object.entries(pageComponents)) {\n // Skip if already collected from global components\n if (!globalComponents[name]) {\n await processComponent(name, component);\n }\n }\n\n // Prepend runtime helper if any component uses defineVars\n if (hasDefineVars && jsCodeBlocks.length > 0) {\n jsCodeBlocks.unshift(DEFINE_VARS_RUNTIME);\n }\n\n return jsCodeBlocks.join('\\n\\n');\n}\n", "/**\n * CMS template processing for SSR\n * Handles {{cms.field}} interpolation and CMS context management\n */\n\nimport type { I18nConfig } from '../../shared/types/components';\nimport type { TemplateContext } from '../../shared/types';\nimport { DEFAULT_I18N_CONFIG, resolveI18nValue, isI18nValue } from '../../shared/i18n';\nimport type { ValueResolver } from '../../shared/itemTemplateUtils';\nimport { tiptapToHtml } from '../../shared/richtext/tiptapToHtml';\nimport { isTiptapDocument } from '../../shared/richtext/types';\nimport { RAW_HTML_PREFIX } from '../../shared/constants';\n\n// Re-export for backward compatibility\nexport { RAW_HTML_PREFIX };\n\n/**\n * CMS context for template interpolation\n */\nexport interface CMSContext {\n cms?: Record<string, unknown>;\n}\n\n/**\n * Get i18n resolver function for value resolution\n */\nexport function createI18nResolver(\n locale?: string,\n i18nConfig?: I18nConfig\n): ValueResolver | undefined {\n if (!locale || !i18nConfig) return undefined;\n return (value: unknown) => resolveI18nValue(value, locale, i18nConfig);\n}\n\n/**\n * Process CMS template strings like {{cms.title}} or {{cms.author}}\n * Replaces template expressions with values from CMS item\n * Supports i18n values - resolves to locale-specific strings\n */\nexport function processCMSTemplate(\n template: string,\n cmsItem: Record<string, unknown>,\n locale?: string,\n i18nConfig?: I18nConfig\n): string {\n const config = i18nConfig || DEFAULT_I18N_CONFIG;\n const effectiveLocale = locale || config.defaultLocale;\n\n return template.replace(/\\{\\{cms\\.([^}]+)\\}\\}/g, (match, fieldPath) => {\n // Support nested paths like cms.author.name\n const parts = fieldPath.trim().split('.');\n let value: unknown = cmsItem;\n\n for (const part of parts) {\n if (value && typeof value === 'object' && part in value) {\n value = (value as Record<string, unknown>)[part];\n } else {\n // Field not found, return empty string\n return '';\n }\n }\n\n // Return string representation\n if (value === null || value === undefined) {\n return '';\n }\n // Handle i18n values - resolve to locale-specific value, then continue\n // through rich-text detection (don't early-return, as resolved value may be Tiptap JSON)\n if (isI18nValue(value)) {\n value = resolveI18nValue(value, effectiveLocale, config);\n }\n // Handle rich-text markers - extract HTML content for interpolation\n // Mark with RAW_HTML_PREFIX so renderer knows not to escape\n if (typeof value === 'object' && value !== null && '__richtext__' in value) {\n const richText = value as Record<string, unknown>;\n if (typeof richText.html === 'string') {\n return RAW_HTML_PREFIX + richText.html;\n }\n }\n // Handle raw TipTap documents (fallback if not preprocessed)\n // Mark with RAW_HTML_PREFIX so renderer knows not to escape\n if (isTiptapDocument(value)) {\n return RAW_HTML_PREFIX + tiptapToHtml(value);\n }\n return String(value);\n });\n}\n\n/**\n * Process CMS templates in props object\n * Recursively processes all string values in props\n */\nexport function processCMSPropsTemplate(\n props: Record<string, unknown>,\n cmsItem: Record<string, unknown>,\n locale?: string,\n i18nConfig?: I18nConfig\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(props)) {\n if (typeof value === 'string' && value.includes('{{cms.')) {\n result[key] = processCMSTemplate(value, cmsItem, locale, i18nConfig);\n } else if (value && typeof value === 'object' && !Array.isArray(value)) {\n // Recursively process nested objects (but not arrays or null)\n result[key] = processCMSPropsTemplate(value as Record<string, unknown>, cmsItem, locale, i18nConfig);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n", "/**\n * Image metadata handling for SSR\n * Loads image manifest and builds metadata map for responsive images\n */\n\nimport { projectPaths } from '../projectContext';\nimport * as path from 'path';\nimport { escapeHtml } from './attributeBuilder';\nimport { readTextFile, fileExists } from '../runtime';\n\n/**\n * Image metadata for SSR rendering\n */\nexport interface ImageMetadata {\n /** WebP srcset string */\n srcset: string;\n /** AVIF srcset string (if available) */\n avifSrcset?: string;\n /** Original image width */\n width?: number;\n /** Original image height */\n height?: number;\n /** Base64 blur placeholder data URL */\n blurHash?: string;\n}\n\n/**\n * Image metadata map - maps image URLs to their metadata\n */\nexport type ImageMetadataMap = Map<string, ImageMetadata>;\n\n/**\n * Responsive image widths for variant detection (optimized for mobile 2x/3x DPR and desktop)\n */\nexport const RESPONSIVE_WIDTHS = [500, 800, 1080, 1600, 2400] as const;\n\n/**\n * Default sizes attribute for responsive images\n */\nexport const DEFAULT_SIZES = '100vw';\n\n/**\n * Build image metadata map from manifest\n * Returns a map of image URL -> metadata (srcset, avifSrcset, dimensions, blurHash)\n */\nexport async function buildImageMetadataMap(): Promise<ImageMetadataMap> {\n const metadataMap = new Map<string, ImageMetadata>();\n\n try {\n const imagesDir = projectPaths.images();\n const manifestPath = path.join(imagesDir, 'manifest.json');\n\n // Try to load manifest\n if (!(await fileExists(manifestPath))) {\n return metadataMap;\n }\n\n const manifestContent = await readTextFile(manifestPath);\n const manifest = JSON.parse(manifestContent) as {\n version: number;\n images: Record<string, {\n filename: string;\n width: number;\n height: number;\n blurHash: string;\n formats: { avif: boolean; webp: boolean };\n variants: { width: number; webpFilename: string; avifFilename: string }[];\n }>;\n };\n\n // Build metadata for each image\n for (const [filename, entry] of Object.entries(manifest.images)) {\n const baseName = path.basename(filename, path.extname(filename));\n\n // Build WebP srcset\n const webpSrcsetParts: string[] = [];\n const avifSrcsetParts: string[] = [];\n\n // Add variants\n for (const variant of entry.variants) {\n webpSrcsetParts.push(\n `/images/${encodeURIComponent(variant.webpFilename)} ${variant.width}w`\n );\n if (variant.avifFilename) {\n avifSrcsetParts.push(\n `/images/${encodeURIComponent(variant.avifFilename)} ${variant.width}w`\n );\n }\n }\n\n // Add main image as largest option (use original width or 2400 as fallback)\n const mainWidth = entry.width || 2400;\n if (entry.formats.webp) {\n webpSrcsetParts.push(`/images/${encodeURIComponent(`${baseName}.webp`)} ${mainWidth}w`);\n } else {\n webpSrcsetParts.push(`/images/${encodeURIComponent(filename)} ${mainWidth}w`);\n }\n if (entry.formats.avif) {\n avifSrcsetParts.push(`/images/${encodeURIComponent(`${baseName}.avif`)} ${mainWidth}w`);\n }\n\n const metadata: ImageMetadata = {\n srcset: webpSrcsetParts.join(', '),\n width: entry.width,\n height: entry.height,\n blurHash: entry.blurHash,\n };\n\n if (avifSrcsetParts.length > 0) {\n metadata.avifSrcset = avifSrcsetParts.join(', ');\n }\n\n // Map both /images/filename and /images/encoded-filename\n metadataMap.set(`/images/${filename}`, metadata);\n metadataMap.set(`/images/${encodeURIComponent(filename)}`, metadata);\n }\n } catch (error) {\n console.error('Failed to build image metadata map:', error);\n }\n\n return metadataMap;\n}\n\n/**\n * Extract the src attribute value from an <img> tag string.\n * Handles both src=\"...\" and src='...' quoting.\n */\nexport function extractImgSrc(imgTag: string): string | null {\n const match = imgTag.match(/src=[\"']([^\"']+)[\"']/i);\n return match ? match[1] : null;\n}\n\n/**\n * Rewrite <img> tags in rich-text HTML to <picture> elements with responsive variants.\n * Only rewrites images that exist in the metadata map (project images with generated variants).\n * External/unrecognized images are left unchanged.\n */\nexport function rewriteRichTextImages(html: string, metadataMap: ImageMetadataMap): string {\n return html.replace(/<img\\b([^>]*)\\/?>/gi, (fullMatch, innerAttrs: string) => {\n const src = extractImgSrc(fullMatch);\n if (!src) return fullMatch;\n\n const metadata = metadataMap.get(src);\n if (!metadata) return fullMatch;\n\n // Check if width/height already present in original tag\n const hasWidth = /width=/i.test(innerAttrs);\n const hasHeight = /height=/i.test(innerAttrs);\n\n // Inject width/height if missing and available from metadata\n let enhancedTag = fullMatch;\n if (!hasWidth && metadata.width) {\n enhancedTag = enhancedTag.replace(/<img\\b/i, `<img width=\"${escapeHtml(String(metadata.width))}\"`);\n }\n if (!hasHeight && metadata.height) {\n enhancedTag = enhancedTag.replace(/<img\\b/i, `<img height=\"${escapeHtml(String(metadata.height))}\"`);\n }\n\n const sizes = DEFAULT_SIZES;\n\n // Render as <picture> with AVIF + WebP sources when AVIF is available\n if (metadata.avifSrcset) {\n return `<picture>` +\n `<source type=\"image/avif\" srcset=\"${escapeHtml(metadata.avifSrcset)}\" sizes=\"${escapeHtml(sizes)}\" />` +\n `<source type=\"image/webp\" srcset=\"${escapeHtml(metadata.srcset)}\" sizes=\"${escapeHtml(sizes)}\" />` +\n enhancedTag +\n `</picture>`;\n }\n\n // WebP only: add srcset and sizes to existing <img>\n if (metadata.srcset) {\n enhancedTag = enhancedTag.replace(/<img\\b/i,\n `<img srcset=\"${escapeHtml(metadata.srcset)}\" sizes=\"${escapeHtml(sizes)}\"`\n );\n }\n\n return enhancedTag;\n });\n}\n", "/**\n * Server-Side Rendering (SSR) Core Module\n * Converts JSON component structures to HTML strings for SEO-friendly initial page loads\n */\n\nimport type { ComponentNode, ComponentDefinition, JSONPage, CMSItem, EmbedNode, LinkNode, LocaleListNode, CMSFilterCondition } from '../../shared/types';\nimport type { TemplateContext, NestedCMSListConfig } from '../../shared/types/cms';\nimport { processItemTemplate, processItemPropsTemplate, hasItemTemplates, buildTemplateContext, resolveItemsTemplate, resolveTemplateRawValue, addItemUrl, getNestedValue, type ValueResolver } from '../../shared/itemTemplateUtils';\nimport { singularize, isItemDraftForLocale } from '../../shared/types/cms';\nimport type { ResponsiveStyleObject, StyleObject } from '../../shared/types';\nimport type { BreakpointConfig } from '../../shared/breakpoints';\nimport { evaluateTemplate, processStructure, isResponsiveStyle, isHtmlMapping, resolveHtmlMapping } from '../../client/templateEngine';\nimport { resolvePropsFromDefinition, isRichTextMarker, richTextMarkerToHtml } from '../../shared/propResolver';\nimport { loadBreakpointConfig, loadI18nConfig } from '../jsonLoader';\nimport type { I18nConfig } from '../../shared/types/components';\nimport { extractLocaleFromPath, DEFAULT_I18N_CONFIG, resolveI18nValue, buildLocalizedPath, isI18nValue } from '../../shared/i18n';\nimport { NODE_TYPE } from '../../shared/constants';\nimport { isComponentNode, isHtmlNode, isLinkNode, isEmbedNode, isLocaleListNode, isListNode, markAsSlotContent, isBooleanMapping } from '../../shared/nodeUtils';\nimport type { ListNode } from '../../shared/registry/nodeTypes/ListNodeType';\nimport type { CMSService } from '../services/cmsService';\nimport { extractAttributesFromNode, skipEmptyTemplateAttributes } from '../../shared/attributeNodeUtils';\nimport { SSRRegistry } from '../../shared/registry/SSRRegistry';\nimport { mergeResponsiveStyles } from '../../shared/responsiveStyleUtils';\n// Lazy-loaded: jsdom (used by isomorphic-dompurify on the server) can't be bundled by esbuild\n// because it reads CSS files relative to __dirname at init time. When the module is unavailable\n// (packaged Electron app), embed HTML is returned unsanitized \u2014 acceptable since content is local.\nlet _DOMPurify: any = null;\nlet _DOMPurifyLoaded = false;\nfunction getDOMPurify() {\n if (!_DOMPurifyLoaded) {\n _DOMPurifyLoaded = true;\n try {\n _DOMPurify = require('isomorphic-dompurify');\n if (_DOMPurify.default) _DOMPurify = _DOMPurify.default;\n } catch {\n // Not available in bundled environment\n }\n }\n return _DOMPurify;\n}\nimport { responsiveStylesToClasses } from '../../shared/utilityClassMapper';\nimport { validateStyleCoverage } from '../validateStyleCoverage';\nimport { generateElementClassName, type ElementClassContext } from '../../shared/elementClassName';\nimport type { InteractiveStyles } from '../../shared/types/styles';\nimport { extractInteractiveStyleMappings, resolveExtractedMappings, hasInteractiveStyleMappings } from '../../shared/interactiveStyleMappings';\nimport { isCurrentLink } from '../../shared/linkUtils';\nimport type { SlugMap } from '../../shared/slugTranslator';\nimport { buildSlugIndex, getLocaleLinks, translatePath } from '../../shared/slugTranslator';\n\n// Import from modularized files\nimport { escapeHtml, buildAttributes, styleToString } from './attributeBuilder';\nimport { extractPageMeta, generateMetaTags } from './metaTagGenerator';\nimport { collectComponentCSS } from './cssCollector';\nimport { collectComponentJavaScript } from './jsCollector';\nimport { CMSContext, processCMSTemplate, processCMSPropsTemplate, createI18nResolver, RAW_HTML_PREFIX } from './cmsSSRProcessor';\nimport { ImageMetadataMap, DEFAULT_SIZES, buildImageMetadataMap, rewriteRichTextImages } from './imageMetadata';\n\n/**\n * Image preload info for generating <link rel=\"preload\"> tags in head\n */\nexport interface PreloadImage {\n /** Best available srcset (AVIF preferred, then WebP) */\n srcset: string;\n /** Image type (image/avif or image/webp) */\n type: 'image/avif' | 'image/webp';\n /** Sizes attribute */\n sizes: string;\n}\n\n// Re-export types for external consumers\nexport type { CMSContext } from './cmsSSRProcessor';\nexport type { PageMeta } from './metaTagGenerator';\nexport { extractPageMeta, generateMetaTags } from './metaTagGenerator';\n\n/**\n * SSR rendering context - passed through the render chain\n */\ninterface SSRContext {\n locale?: string;\n i18nConfig?: I18nConfig;\n slugMappings?: SlugMap[];\n pagePath?: string;\n breakpoints?: BreakpointConfig;\n viewportWidth?: number;\n cmsContext?: CMSContext;\n imageMetadataMap?: ImageMetadataMap;\n cmsService?: CMSService;\n /** Template context for CMSList iteration with named contexts */\n templateContext?: TemplateContext;\n /** Element path for tracking position in tree (for element class generation) */\n elementPath?: number[];\n /** Map to collect interactive styles during render */\n interactiveStylesMap?: Map<string, InteractiveStyles>;\n /** Component context for tracking when inside a component definition */\n componentContext?: string;\n /** Resolved component props for interactive style mapping resolution */\n componentResolvedProps?: Record<string, unknown>;\n /** Array to collect high-priority images for preloading */\n preloadImages?: PreloadImage[];\n /**\n * Template mode: preserve {{item.field}} placeholders instead of processing them.\n * Used when emitting item templates for client-side dynamic rendering.\n */\n templateMode?: boolean;\n /**\n * When true, nested cms-list nodes should be emitted as placeholders\n * for client-side hydration rather than fully rendered.\n * Set when parent cms-list has emitTemplate: true.\n */\n nestedCMSListMode?: boolean;\n /**\n * Set of collection IDs that need client-side data injection.\n * Populated during rendering when nested cms-list placeholders are emitted.\n * Used by build process to prepare and inject collection data scripts.\n */\n neededCollections?: Set<string>;\n /** When true, draft items are filtered out from CMS lists */\n isProductionBuild?: boolean;\n}\n\n/**\n * Get template context from SSRContext (for use with shared itemTemplateUtils)\n * Returns the full TemplateContext which includes named contexts\n */\nfunction getTemplateContext(ctx: SSRContext): TemplateContext | null {\n return ctx.templateContext || null;\n}\n\n/**\n * Create a value resolver for i18n resolution (for use with item templates)\n */\nfunction getI18nResolver(ctx: SSRContext): ValueResolver | undefined {\n return createI18nResolver(ctx.locale, ctx.i18nConfig);\n}\n\n/**\n * Localize an internal href to the current locale.\n * Reusable helper extracted from LinkNode rendering.\n */\nfunction localizeHref(href: string, ctx: SSRContext): string {\n if (ctx.templateMode) return href;\n if (!href.startsWith('/') || href.startsWith('//')) return href;\n const { locale, i18nConfig, slugMappings } = ctx;\n if (!locale || !i18nConfig) return href;\n if (slugMappings) {\n const slugIndex = buildSlugIndex(slugMappings);\n return translatePath(href, locale, i18nConfig.defaultLocale, i18nConfig.defaultLocale, slugIndex);\n } else if (locale !== i18nConfig.defaultLocale) {\n return buildLocalizedPath(href, locale);\n }\n return href;\n}\n\n/**\n * Localize <a href=\"...\"> links within rich-text HTML output.\n * Similar pattern to rewriteRichTextImages.\n */\nfunction localizeRichTextLinks(html: string, ctx: SSRContext): string {\n if (ctx.templateMode || !ctx.locale || !ctx.i18nConfig) return html;\n return html.replace(\n /<a\\b([^>]*?)href=([\"'])([^\"']*?)\\2([^>]*?)>/gi,\n (match, before, quote, href, after) => {\n if (!href.startsWith('/') || href.startsWith('//')) return match;\n const localized = localizeHref(href, ctx);\n return localized === href ? match : `<a${before}href=${quote}${localized}${quote}${after}>`;\n }\n );\n}\n\n/**\n * Process style templates and convert to utility classes.\n * Handles {{item.field}} patterns within list contexts.\n */\nfunction processStyleToClasses(\n style: StyleObject | ResponsiveStyleObject | undefined,\n ctx: SSRContext\n): string[] {\n if (!style) return [];\n\n let processedStyle = style;\n const templateCtx = getTemplateContext(ctx);\n if (templateCtx && !ctx.templateMode) {\n processedStyle = processItemPropsTemplate(\n style as Record<string, unknown>,\n templateCtx,\n getI18nResolver(ctx)\n ) as StyleObject | ResponsiveStyleObject;\n }\n return responsiveStylesToClasses(processedStyle as ResponsiveStyleObject);\n}\n\n/**\n * Evaluate the if condition on a node with full SSR context.\n * Handles boolean, mapping, and string template values.\n * Returns true if node should be rendered, false if it should be skipped.\n */\nfunction evaluateIfCondition(node: ComponentNode, ctx: SSRContext): boolean {\n const ifValue = (node as any).if;\n\n // No if property = render (default true)\n if (ifValue === undefined) {\n return true;\n }\n\n // Boolean value\n if (typeof ifValue === 'boolean') {\n return ifValue;\n }\n\n // Mapping value - resolve using component props\n if (isBooleanMapping(ifValue)) {\n const props = ctx.componentResolvedProps || {};\n const propValue = props[ifValue.prop];\n const mappedValue = ifValue.values[String(propValue)];\n // If no mapping found for this prop value, default to true\n return mappedValue !== undefined ? Boolean(mappedValue) : true;\n }\n\n // String template - resolve using CMS or item context\n if (typeof ifValue === 'string') {\n let resolved: string = ifValue;\n\n // Process item templates first (for CMSList context)\n const templateCtx = getTemplateContext(ctx);\n if (templateCtx && hasItemTemplates(resolved)) {\n resolved = processItemTemplate(resolved, templateCtx, getI18nResolver(ctx));\n }\n\n // Process CMS template strings like {{cms.field}}\n if (ctx.cmsContext?.cms && resolved.includes('{{cms.')) {\n resolved = processCMSTemplate(resolved, ctx.cmsContext.cms, ctx.locale, ctx.i18nConfig);\n }\n\n // Evaluate truthiness - false, 0, empty string are falsy\n return Boolean(resolved) && resolved !== 'false' && resolved !== '0' && resolved !== '';\n }\n\n // Unknown type, default to true\n return true;\n}\n\n/**\n * Resolve a template value like \"{{category.slug}}\" from template context.\n * Returns the original value if not a template or can't be resolved.\n */\nfunction resolveFilterValue(value: unknown, templateContext: TemplateContext | undefined): unknown {\n if (!templateContext || typeof value !== 'string' || !value.startsWith('{{') || !value.endsWith('}}')) {\n return value;\n }\n const path = value.slice(2, -2).trim();\n const resolved = getNestedValue(templateContext as Record<string, unknown>, path);\n return resolved !== undefined ? resolved : value;\n}\n\n/**\n * Resolve template values in CMS filter for nested cms-list support.\n * Handles filter values like \"{{category.slug}}\" from parent template context.\n */\nfunction resolveFilterTemplates(\n filter: CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined,\n templateContext: TemplateContext | undefined\n): CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined {\n if (!filter || !templateContext) return filter;\n\n // Handle array of conditions\n if (Array.isArray(filter)) {\n return filter.map(cond => ({\n ...cond,\n value: resolveFilterValue(cond.value, templateContext)\n }));\n }\n\n // Handle single condition object with field/value\n if ('field' in filter && 'value' in filter) {\n return {\n ...(filter as CMSFilterCondition),\n value: resolveFilterValue((filter as CMSFilterCondition).value, templateContext)\n };\n }\n\n // Handle simple object filter: { category: \"{{category.slug}}\" }\n const resolved: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(filter)) {\n resolved[key] = resolveFilterValue(value, templateContext);\n }\n return resolved;\n}\n\n/**\n * Expand Meno component markers in rich text HTML output.\n * Scans for <div data-meno-component=\"Name\" data-meno-props='{\"key\":\"val\"}'></div>\n * and replaces them with rendered component HTML using the existing SSR component renderer.\n */\nasync function expandRichTextComponents(html: string, ctx: SSRContext): Promise<string> {\n // Quick check - if no component markers, return as-is\n if (!html.includes('data-meno-component')) return html;\n\n // Match component markers\n const markerRegex = /<div\\s+data-meno-component=\"([^\"]+)\"\\s+data-meno-props=\"([^\"]*)\"[^>]*><\\/div>/g;\n const parts: (string | Promise<string>)[] = [];\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = markerRegex.exec(html)) !== null) {\n // Add text before this match\n if (match.index > lastIndex) {\n parts.push(html.slice(lastIndex, match.index));\n }\n\n const componentName = match[1];\n let props: Record<string, unknown> = {};\n try {\n // Unescape HTML entities in the JSON\n const propsStr = match[2]\n .replace(/&quot;/g, '\"')\n .replace(/&#039;/g, \"'\")\n .replace(/&amp;/g, '&');\n props = JSON.parse(propsStr);\n } catch {\n // ignore parse errors\n }\n\n // Render the component using SSR registry\n if (ssrComponentRegistry.has(componentName)) {\n parts.push(\n renderComponent(componentName, props, [], {}, ctx)\n );\n } else {\n // Keep marker for unknown components\n parts.push(match[0]);\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add remaining text\n if (lastIndex < html.length) {\n parts.push(html.slice(lastIndex));\n }\n\n // Resolve all promises\n const resolved = await Promise.all(parts);\n return resolved.join('');\n}\n\n/**\n * Component registry for SSR (shared between requests)\n * Uses the shared SSRRegistry for consistency\n */\nconst ssrComponentRegistry = new SSRRegistry();\n\n/**\n * Build HTML string from component node (server-side)\n * Exported for component preview rendering\n */\nexport async function buildComponentHTML(\n node: ComponentNode | ComponentNode[] | string | number | null | undefined,\n globalComponents: Record<string, ComponentDefinition> = {},\n pageComponents: Record<string, ComponentDefinition> = {},\n locale?: string,\n i18nConfig?: I18nConfig,\n slugMappings?: SlugMap[],\n pagePath?: string,\n cmsContext?: CMSContext,\n cmsService?: CMSService,\n isProductionBuild?: boolean\n): Promise<{ html: string; interactiveStylesMap: Map<string, InteractiveStyles>; preloadImages: PreloadImage[]; neededCollections: Set<string> }> {\n // Create map to collect interactive styles during render\n const interactiveStylesMap = new Map<string, InteractiveStyles>();\n // Create array to collect high-priority images for preloading\n const preloadImages: PreloadImage[] = [];\n // Create set to track collections that need client-side data injection\n const neededCollections = new Set<string>();\n\n if (!node) return { html: '', interactiveStylesMap, preloadImages, neededCollections };\n\n // Register components for this render\n ssrComponentRegistry.merge(globalComponents);\n ssrComponentRegistry.merge(pageComponents);\n\n // Load breakpoint config for responsive style resolution\n const breakpoints = await loadBreakpointConfig();\n\n // Build image metadata map for responsive images (from manifest)\n const imageMetadataMap = await buildImageMetadataMap();\n\n // Render using desktop viewport (1920px) - same as editor system\n const SSR_VIEWPORT_WIDTH = 1920;\n\n // Build SSR context\n const ctx: SSRContext = {\n locale,\n i18nConfig,\n slugMappings,\n pagePath,\n breakpoints,\n viewportWidth: SSR_VIEWPORT_WIDTH,\n cmsContext,\n imageMetadataMap,\n cmsService,\n elementPath: [0], // Initialize path tracking for interactive styles\n interactiveStylesMap, // Collect interactive styles during render\n preloadImages, // Collect high-priority images for preloading\n neededCollections, // Track collections that need client-side data\n isProductionBuild,\n };\n\n const html = await renderNode(node, ctx);\n\n return { html, interactiveStylesMap, preloadImages, neededCollections };\n}\n\n/**\n * Render a nested list (collection mode) as a placeholder for client-side hydration.\n * Used when parent list has emitTemplate: true.\n * The placeholder contains the configuration and template for MenoFilter to hydrate.\n */\nasync function renderNestedListPlaceholder(\n node: ListNode,\n ctx: SSRContext\n): Promise<string> {\n // Get source - handle both string and pre-resolved array sources\n const sourceValue = node.source || (node as any).collection;\n const sourceStr = typeof sourceValue === 'string' ? sourceValue : '';\n\n // Track this collection for client-side data injection\n if (ctx.neededCollections && sourceStr) {\n ctx.neededCollections.add(sourceStr);\n }\n\n // Build configuration for client-side hydration\n const config: NestedCMSListConfig = {\n collection: sourceStr,\n itemAs: node.itemAs,\n items: node.items,\n filter: node.filter as CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined,\n sort: node.sort,\n limit: node.limit,\n offset: node.offset,\n excludeCurrentItem: node.excludeCurrentItem,\n };\n\n // Render children template (preserving {{item.field}} placeholders)\n const childTemplateCtx: SSRContext = {\n ...ctx,\n templateMode: true,\n templateContext: undefined, // Clear context for inner item templates\n nestedCMSListMode: false, // Reset for deeper nesting levels\n };\n const templateContent = node.children\n ? await renderChildrenAsync(node.children, childTemplateCtx)\n : '';\n\n // Escape config for attribute\n const configJson = escapeHtml(JSON.stringify(config));\n\n // Emit placeholder with embedded config and template\n return `<div data-cms-list-nested=\"true\" data-collection=\"${escapeHtml(sourceStr)}\" data-cms-config=\"${configJson}\">` +\n `<template data-nested-template>${templateContent}</template>` +\n `</div>`;\n}\n\n/**\n * Unified List node processor - renders children for each item\n * Supports both source types:\n * - 'prop': Reads from component props or template context\n * - 'collection': Queries from CMS collections\n */\nasync function processList(node: ListNode, ctx: SSRContext): Promise<string> {\n // Determine source type (default to 'prop', but handle legacy 'cms-list' type)\n const nodeType = (node as any).type;\n const isLegacyCMSList = nodeType === 'cms-list';\n const sourceType = isLegacyCMSList ? 'collection' : (node.sourceType || 'prop');\n\n // For collection mode, check CMS service availability\n if (sourceType === 'collection' && !ctx.cmsService) {\n console.warn('List with sourceType \"collection\" requires CMS service');\n return '';\n }\n\n // When in templateMode with nestedCMSListMode, emit placeholder for client-side hydration\n // This allows nested lists inside emitTemplate to work with MenoFilter\n if (sourceType === 'collection' && ctx.templateMode && ctx.nestedCMSListMode) {\n return renderNestedListPlaceholder(node, ctx);\n }\n\n // Get source - handle both new 'source' and legacy 'collection' property\n // Source can be a string (prop name) or array (pre-resolved by processStructure)\n const rawSource = node.source || (node as any).collection;\n const source = typeof rawSource === 'string' ? rawSource : '';\n const sourceIsResolved = Array.isArray(rawSource);\n\n // Determine variable name for this list's items\n let variableName: string;\n if (node.itemAs) {\n variableName = node.itemAs;\n } else if (sourceType === 'collection') {\n variableName = singularize(source);\n } else {\n variableName = 'item';\n }\n\n // Get items based on sourceType\n let items: unknown[];\n\n if (sourceType === 'collection') {\n // Collection mode: Query from CMS service\n items = await getCollectionItems(node, source, ctx);\n } else {\n // Prop mode: Read from component props or template context\n // If source was already resolved to an array by processStructure (e.g., from {{features}}),\n // use it directly instead of looking up by prop name\n if (sourceIsResolved) {\n // Source was resolved to array by processStructure\n items = rawSource as unknown[];\n } else if (source) {\n // Source is a prop name or template expression - resolve it\n items = getPropItems(source, ctx);\n } else {\n items = [];\n }\n }\n\n // Apply shared options: offset and limit\n if (node.offset && sourceType === 'prop') {\n items = items.slice(node.offset);\n }\n if (node.limit && sourceType === 'prop') {\n items = items.slice(0, node.limit);\n }\n\n if (items.length === 0) {\n return '';\n }\n\n // Get schema for URL computation (collection mode only)\n const schema = sourceType === 'collection' && ctx.cmsService\n ? ctx.cmsService.getSchema(source)\n : undefined;\n\n // Render children for each item\n const renderedItems: string[] = [];\n\n for (let i = 0; i < items.length; i++) {\n const rawItem = items[i] as Record<string, unknown>;\n const item = schema\n ? addItemUrl(rawItem as CMSItem, schema, ctx.locale, ctx.i18nConfig)\n : rawItem;\n\n const templateContext = buildTemplateContext(\n variableName,\n item as CMSItem,\n i,\n items.length,\n ctx.templateContext\n );\n\n const itemCtx: SSRContext = {\n ...ctx,\n templateContext,\n };\n\n const childrenHtml = await renderChildrenAsync(node.children || [], itemCtx);\n renderedItems.push(childrenHtml);\n }\n\n const childrenHTML = renderedItems.join('');\n\n // Emit item template when emitTemplate is enabled (collection mode)\n // This allows MenoFilter to dynamically render items from JSON data\n let templateHtml = '';\n if (sourceType === 'collection' && node.emitTemplate && node.children && node.children.length > 0) {\n const templateCtx: SSRContext = {\n ...ctx,\n templateMode: true,\n templateContext: ctx.templateContext,\n nestedCMSListMode: true,\n };\n const templateContent = await renderChildrenAsync(node.children, templateCtx);\n templateHtml = `<template data-meno-item>${templateContent}</template>`;\n }\n\n // List is a pure repeater - no container element, just children + optional template\n return childrenHTML + templateHtml;\n}\n\n/**\n * Get items from CMS collection (for sourceType: 'collection')\n */\nasync function getCollectionItems(node: ListNode, source: string, ctx: SSRContext): Promise<CMSItem[]> {\n if (!ctx.cmsService) return [];\n\n let items: CMSItem[];\n\n // Check if items are specified directly (for nested reference lists)\n if (node.items) {\n // If items is a template expression, resolve it from current context\n if (typeof node.items === 'string' && node.items.startsWith('{{')) {\n let resolvedIds: string | string[] | undefined;\n\n // Check if this is a CMS template ({{cms.field}}) - resolve from cmsContext\n if (node.items.startsWith('{{cms.') && ctx.cmsContext?.cms) {\n const fieldPath = node.items.slice(6, -2); // Extract \"field\" from \"{{cms.field}}\"\n let value: unknown = ctx.cmsContext.cms;\n for (const part of fieldPath.split('.')) {\n if (value && typeof value === 'object' && part in value) {\n value = (value as Record<string, unknown>)[part];\n } else {\n value = undefined;\n break;\n }\n }\n if (value !== null && value !== undefined) {\n resolvedIds = Array.isArray(value) ? value.map(v => String(v)) : String(value);\n }\n } else {\n // Otherwise resolve from template context (for nested lists)\n const parentContext = ctx.templateContext || { _type: 'template' as const };\n resolvedIds = resolveItemsTemplate(node.items, parentContext);\n }\n\n if (!resolvedIds) {\n return [];\n }\n const ids = Array.isArray(resolvedIds) ? resolvedIds : [resolvedIds];\n items = await ctx.cmsService.getItemsByIds(source, ids);\n } else {\n // Direct IDs (string or array)\n const ids = Array.isArray(node.items) ? node.items : [node.items];\n items = await ctx.cmsService.getItemsByIds(source, ids);\n }\n // Filter draft items from ID-based queries\n if (ctx.locale) {\n items = items.filter(item => !isItemDraftForLocale(item, ctx.locale!));\n }\n } else {\n // Build query from node props (resolve filter templates for nested list support)\n const query = {\n collection: source,\n filter: resolveFilterTemplates(node.filter as CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined, ctx.templateContext),\n sort: node.sort,\n limit: node.limit,\n offset: node.offset,\n excludeDraftLocale: ctx.locale,\n };\n items = await ctx.cmsService.queryItems(query);\n }\n\n // Exclude current item if option is set and we have a current CMS context\n if (node.excludeCurrentItem && ctx.cmsContext?.cms?._id) {\n const currentId = ctx.cmsContext.cms._id as string;\n items = items.filter(item => item._id !== currentId);\n }\n\n return items;\n}\n\n/**\n * Get items from component props or template context (for sourceType: 'prop')\n */\nfunction getPropItems(source: string, ctx: SSRContext): unknown[] {\n // Resolve the source - can be a direct prop name or a template expression\n if (source.startsWith('{{') && source.endsWith('}}')) {\n // Template expression - resolve from template context (for nested lists)\n // e.g., {{category.items}} where category is from parent list\n const templateCtx = ctx.templateContext;\n if (templateCtx) {\n const path = source.slice(2, -2).trim(); // Extract \"category.items\"\n const resolved = getNestedValue(templateCtx as Record<string, unknown>, path);\n if (Array.isArray(resolved)) {\n return resolved;\n } else if (resolved !== undefined) {\n // Warn if resolved to non-array value (likely a bug in template)\n console.warn(`List source \"${source}\" resolved to non-array value (type: ${typeof resolved})`);\n }\n }\n return [];\n } else {\n // Direct prop name - resolve from component props\n const propValue = ctx.componentResolvedProps?.[source];\n if (Array.isArray(propValue)) {\n return propValue;\n }\n\n // Also try template context for prop mode (for cms context values)\n if (ctx.cmsContext?.cms) {\n const cmsValue = ctx.cmsContext.cms[source];\n if (Array.isArray(cmsValue)) {\n return cmsValue;\n }\n }\n }\n return [];\n}\n\n/**\n * Render children array asynchronously\n */\nasync function renderChildrenAsync(children: unknown[], ctx: SSRContext): Promise<string> {\n const rendered: string[] = [];\n for (let index = 0; index < children.length; index++) {\n const child = children[index];\n const childPath = ctx.elementPath ? [...ctx.elementPath, index] : [index];\n rendered.push(await renderNode(child as ComponentNode | string | number, { ...ctx, elementPath: childPath }));\n }\n return rendered.join('');\n}\n\n/**\n * Build element class name for a node based on its SSR context.\n * Used by embed, link, locale-list, and regular HTML nodes.\n */\nfunction buildNodeElementClass(\n ctx: SSRContext,\n label: string | undefined,\n isSlotContent?: boolean\n): string {\n const { pagePath } = ctx;\n // Slot content uses page context (defined in page, not component)\n const useComponentContext = !isSlotContent && Boolean(ctx.componentContext);\n const effectiveFileType = useComponentContext ? 'component' : 'page';\n const effectiveFileName = useComponentContext ? ctx.componentContext : (pagePath\n ? pagePath.replace(/^\\//, '').replace(/\\//g, '_') || 'index'\n : 'page');\n\n const elementClassCtx: ElementClassContext = {\n fileType: effectiveFileType,\n fileName: effectiveFileName || 'page',\n label,\n path: ctx.elementPath || [],\n };\n return generateElementClassName(elementClassCtx);\n}\n\n/**\n * Register interactive styles for CSS generation with mapping support.\n * Returns CSS variable overrides (if any) from resolved prop mappings.\n */\nfunction registerInteractiveStyles(\n ctx: SSRContext,\n elementClass: string,\n interactiveStyles: InteractiveStyles\n): Record<string, string> {\n if (!ctx.interactiveStylesMap) return {};\n\n if (ctx.componentResolvedProps && hasInteractiveStyleMappings(interactiveStyles)) {\n const { resolvedStyles, mappings } = extractInteractiveStyleMappings(interactiveStyles);\n const cssVariables = resolveExtractedMappings(mappings, ctx.componentResolvedProps);\n ctx.interactiveStylesMap.set(elementClass, resolvedStyles);\n return cssVariables;\n }\n\n ctx.interactiveStylesMap.set(elementClass, interactiveStyles);\n return {};\n}\n\n/**\n * Build inline style attribute string from CSS variable overrides.\n */\nfunction buildCssVariableStyleAttr(cssVariables: Record<string, string>): string {\n if (Object.keys(cssVariables).length === 0) return '';\n const styleString = Object.entries(cssVariables)\n .map(([k, v]) => `${k}: ${v}`)\n .join('; ');\n return ` style=\"${escapeHtml(styleString)}\"`;\n}\n\n/**\n * Render a node (or array of nodes) to HTML string\n */\nasync function renderNode(\n node: ComponentNode | ComponentNode[] | string | number | null | undefined,\n ctx: SSRContext\n): Promise<string> {\n const { breakpoints, viewportWidth, locale, i18nConfig, slugMappings, pagePath } = ctx;\n\n if (node === null || node === undefined) return '';\n\n if (typeof node === 'string' || typeof node === 'number') {\n let text = String(node);\n\n // In template mode, preserve {{item.field}} placeholders for client-side rendering\n if (ctx.templateMode) {\n // Only process CMS template strings ({{cms.field}}) - preserve item templates\n if (ctx.cmsContext?.cms && text.includes('{{cms.')) {\n text = processCMSTemplate(text, ctx.cmsContext.cms, locale, i18nConfig);\n }\n // Check for raw HTML marker (from rich-text fields) - don't escape\n if (text.startsWith(RAW_HTML_PREFIX)) {\n let rawHtml = text.slice(RAW_HTML_PREFIX.length);\n if (ctx.imageMetadataMap) rawHtml = rewriteRichTextImages(rawHtml, ctx.imageMetadataMap);\n rawHtml = await expandRichTextComponents(rawHtml, ctx);\n rawHtml = localizeRichTextLinks(rawHtml, ctx);\n return rawHtml;\n }\n return escapeHtml(text);\n }\n\n // Normal mode: Process item template strings first (for CMSList context)\n const templateCtx = getTemplateContext(ctx);\n if (templateCtx && hasItemTemplates(text)) {\n text = processItemTemplate(text, templateCtx, getI18nResolver(ctx));\n }\n // Process CMS template strings like {{cms.title}}\n if (ctx.cmsContext?.cms && text.includes('{{cms.')) {\n text = processCMSTemplate(text, ctx.cmsContext.cms, locale, i18nConfig);\n }\n // Check for raw HTML marker (from rich-text fields) - don't escape\n if (text.startsWith(RAW_HTML_PREFIX)) {\n let rawHtml = text.slice(RAW_HTML_PREFIX.length);\n if (ctx.imageMetadataMap) rawHtml = rewriteRichTextImages(rawHtml, ctx.imageMetadataMap);\n rawHtml = await expandRichTextComponents(rawHtml, ctx);\n rawHtml = localizeRichTextLinks(rawHtml, ctx);\n return rawHtml;\n }\n return escapeHtml(text);\n }\n\n if (Array.isArray(node)) {\n return (await Promise.all(node.map((child, index) => {\n const childPath = ctx.elementPath ? [...ctx.elementPath.slice(0, -1), index] : [index];\n return renderNode(child, { ...ctx, elementPath: childPath });\n }))).join('');\n }\n\n if (typeof node !== 'object') return '';\n\n // Check if condition - skip rendering if false\n if (!evaluateIfCondition(node as ComponentNode, ctx)) {\n return '';\n }\n\n // Handle List nodes (async operation - handles both prop and collection source types)\n // isListNode() also matches legacy 'cms-list' type for migration\n if (isListNode(node)) {\n return await processList(node, ctx);\n }\n\n const nodeType = 'type' in node ? node.type : undefined;\n const nodeStyle = ('style' in node) ? node.style as StyleObject | ResponsiveStyleObject | undefined : undefined;\n const children = ('children' in node) ? (node.children || []) : [];\n\n // Handle embed nodes - render custom HTML content\n if (isEmbedNode(node)) {\n // Resolve HTML mapping if present\n let htmlContent: string;\n if (isHtmlMapping(node.html)) {\n const resolved = resolveHtmlMapping(node.html, ctx.componentResolvedProps);\n htmlContent = resolved ?? '';\n } else if (typeof node.html === 'string') {\n htmlContent = node.html;\n } else {\n // Fallback: non-string, non-mapping value \u2014 default to empty\n htmlContent = '';\n }\n\n // In template mode, preserve {{item.field}} placeholders for client-side rendering\n if (ctx.templateMode) {\n // Only process CMS template strings ({{cms.field}}) - preserve item templates\n if (ctx.cmsContext?.cms && htmlContent.includes('{{cms.')) {\n htmlContent = processCMSTemplate(htmlContent, ctx.cmsContext.cms, locale, i18nConfig);\n }\n } else {\n // Normal mode: Process item template strings first (for CMSList context)\n const templateCtx = getTemplateContext(ctx);\n if (templateCtx && hasItemTemplates(htmlContent)) {\n htmlContent = processItemTemplate(htmlContent, templateCtx, getI18nResolver(ctx));\n }\n // Process CMS template strings like {{cms.title}}\n if (ctx.cmsContext?.cms && htmlContent.includes('{{cms.')) {\n htmlContent = processCMSTemplate(htmlContent, ctx.cmsContext.cms, locale, i18nConfig);\n }\n }\n\n // Sanitize HTML with allowlist for SVG, rich-text formatting, and common elements (same as client)\n const purify = getDOMPurify();\n const sanitizedHtml = purify ? purify.sanitize(htmlContent, {\n ALLOWED_TAGS: ['svg', 'path', 'circle', 'rect', 'line', 'polyline', 'polygon', 'g', 'text', 'tspan', 'image', 'defs', 'use', 'linearGradient', 'radialGradient', 'stop', 'clipPath', 'mask', 'pattern', 'marker', 'symbol', 'a', 'div', 'span', 'p', 'br', 'button', 'img', 'iframe', 'video', 'audio', 'source', 'canvas', 'b', 'i', 'u', 'strong', 'em', 'sub', 'sup', 'mark', 's', 'small', 'del', 'ins', 'q', 'abbr', 'code', 'pre', 'blockquote', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],\n ALLOWED_ATTR: ['class', 'id', 'style', 'width', 'height', 'viewBox', 'xmlns', 'fill', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin', 'stroke-dasharray', 'stroke-dashoffset', 'd', 'cx', 'cy', 'r', 'x', 'y', 'x1', 'y1', 'x2', 'y2', 'points', 'href', 'src', 'alt', 'target', 'rel', 'data-*', 'aria-*', 'transform', 'opacity', 'fill-opacity', 'stroke-opacity', 'font-size', 'font-family', 'text-anchor', 'dominant-baseline', 'offset', 'stop-color', 'stop-opacity', 'frameborder', 'allowfullscreen', 'allow', 'title'],\n KEEP_CONTENT: true\n }) : htmlContent;\n const optimizedHtml = ctx.imageMetadataMap\n ? rewriteRichTextImages(sanitizedHtml, ctx.imageMetadataMap)\n : sanitizedHtml;\n\n // Extract attributes from node\n const nodeAttributes = extractAttributesFromNode(node);\n\n // Build className array\n const classNames: string[] = ['oem'];\n\n // Convert styles to utility classes (process templates in style values)\n if (nodeStyle) {\n const utilityClasses = processStyleToClasses(nodeStyle, ctx);\n classNames.push(...utilityClasses);\n }\n\n // Handle interactive styles for embed nodes\n const embedInteractiveStyles = node.interactiveStyles as InteractiveStyles | undefined;\n const embedGenerateElementClass = node.generateElementClass;\n\n if ((embedInteractiveStyles && embedInteractiveStyles.length > 0) || embedGenerateElementClass) {\n const elementClass = buildNodeElementClass(ctx, node.label);\n classNames.unshift(elementClass);\n\n let embedCssVariables: Record<string, string> = {};\n if (embedInteractiveStyles && embedInteractiveStyles.length > 0) {\n embedCssVariables = registerInteractiveStyles(ctx, elementClass, embedInteractiveStyles);\n }\n\n let embedStyleAttr = buildCssVariableStyleAttr(embedCssVariables);\n\n // Add attribute className if present\n const attrClassName = (nodeAttributes.className || nodeAttributes.class || '') as string;\n if (attrClassName) {\n classNames.push(attrClassName);\n }\n delete nodeAttributes.className;\n delete nodeAttributes.class;\n\n const attrs = buildAttributes(nodeAttributes);\n const classAttr = classNames.length > 0 ? ` class=\"${escapeHtml(classNames.filter(Boolean).join(' '))}\"` : '';\n\n // Always use span for embeds - valid inside <p> and other phrasing content\n return `<span${classAttr}${embedStyleAttr}${attrs}>${optimizedHtml}</span>`;\n }\n\n // Add attribute className if present (fallback when no interactive styles)\n const attrClassName = (nodeAttributes.className || nodeAttributes.class || '') as string;\n if (attrClassName) {\n classNames.push(attrClassName);\n }\n delete nodeAttributes.className;\n delete nodeAttributes.class;\n\n const attrs = buildAttributes(nodeAttributes);\n const classAttr = classNames.length > 0 ? ` class=\"${escapeHtml(classNames.filter(Boolean).join(' '))}\"` : '';\n\n // Always use span for embeds - valid inside <p> and other phrasing content\n return `<span${classAttr}${attrs}>${optimizedHtml}</span>`;\n }\n\n // Handle link nodes (render as <a> tag in SSR)\n if (isLinkNode(node)) {\n let href: string = typeof node.href === 'string' ? node.href : '#';\n let targetFromLink: string | undefined;\n\n // Process item templates in href (for CMSList context)\n // Skip when in templateMode to preserve {{item.field}} placeholders\n const templateCtx = getTemplateContext(ctx);\n if (!ctx.templateMode && templateCtx && hasItemTemplates(href)) {\n // Get raw value first to check if it's a link object (like { href: \"/path\", target: \"_blank\" })\n const rawValue = resolveTemplateRawValue(href, templateCtx);\n if (rawValue && typeof rawValue === 'object' && 'href' in rawValue) {\n // Link object - extract href and target\n // Unwrap nested link objects (e.g., {href: {href: \"/path\"}} from double-wrapped list item templates)\n let linkObj = rawValue as { href: unknown; target?: string };\n while (typeof linkObj.href === 'object' && linkObj.href !== null && 'href' in (linkObj.href as Record<string, unknown>)) {\n const nested = linkObj.href as { href: unknown; target?: string };\n if (!linkObj.target && nested.target) linkObj = { ...linkObj, target: nested.target };\n linkObj = { ...linkObj, href: nested.href };\n }\n href = String(linkObj.href);\n targetFromLink = linkObj.target;\n } else {\n // Regular value - use string processing\n href = processItemTemplate(href, templateCtx, getI18nResolver(ctx));\n }\n }\n\n // Process CMS templates in href (e.g., {{cms.ctaLink}})\n if (ctx.cmsContext?.cms && href.includes('{{cms.')) {\n href = processCMSTemplate(href, ctx.cmsContext.cms, locale, i18nConfig);\n }\n\n // Localize internal page links to current locale\n href = localizeHref(href, ctx);\n\n // Extract attributes from node\n const nodeAttributes = extractAttributesFromNode(node);\n\n // Build className array - start with olink base class\n const classNames: string[] = ['olink'];\n\n // Convert styles to utility classes (process templates in style values)\n if (nodeStyle) {\n const utilityClasses = processStyleToClasses(nodeStyle, ctx);\n classNames.push(...utilityClasses);\n }\n\n // Handle interactive styles for link nodes\n const olinkInteractiveStyles = node.interactiveStyles as InteractiveStyles | undefined;\n const olinkGenerateElementClass = node.generateElementClass;\n let olinkCssVariables: Record<string, string> = {};\n let olinkStyleAttr = '';\n\n if ((olinkInteractiveStyles && olinkInteractiveStyles.length > 0) || olinkGenerateElementClass) {\n const elementClass = buildNodeElementClass(ctx, node.label);\n classNames.splice(1, 0, elementClass);\n\n if (olinkInteractiveStyles && olinkInteractiveStyles.length > 0) {\n olinkCssVariables = registerInteractiveStyles(ctx, elementClass, olinkInteractiveStyles);\n }\n olinkStyleAttr = buildCssVariableStyleAttr(olinkCssVariables);\n }\n\n // Add attribute className if present\n const attrClassName = (nodeAttributes.className || nodeAttributes.class || '') as string;\n if (attrClassName) {\n classNames.push(attrClassName);\n }\n delete nodeAttributes.className;\n delete nodeAttributes.class;\n\n // Add is-current class when link href matches current page path\n if (pagePath && !ctx.templateMode && isCurrentLink(href, pagePath)) {\n classNames.push('is-current');\n }\n\n // Add target from link object if present (and not already set in attributes)\n if (targetFromLink && !nodeAttributes.target) {\n nodeAttributes.target = targetFromLink;\n }\n\n const attrs = buildAttributes(nodeAttributes, ['href']);\n const classAttr = ` class=\"${escapeHtml(classNames.filter(Boolean).join(' '))}\"`;\n\n const childrenHTML = Array.isArray(children)\n ? (await Promise.all(children.map((child, index) => {\n const childPath = ctx.elementPath ? [...ctx.elementPath, index] : [index];\n return renderNode(child, { ...ctx, elementPath: childPath });\n }))).join('')\n : await renderNode(children as ComponentNode | string | number | null | undefined, { ...ctx, elementPath: ctx.elementPath ? [...ctx.elementPath, 0] : [0] });\n\n return `<a href=\"${escapeHtml(String(href))}\"${classAttr}${olinkStyleAttr}${attrs}>${childrenHTML}</a>`;\n }\n\n // Handle locale-list node type (render locale switcher links)\n if (isLocaleListNode(node)) {\n return renderLocaleList(node, ctx);\n }\n\n // Extract tag or component name based on node type\n let tag = isHtmlNode(node) ? node.tag : undefined;\n const componentName = isComponentNode(node) ? node.component : undefined;\n let nodeProps = isComponentNode(node) ? (node.props || {}) : {};\n\n // Process CMS templates in props\n if (ctx.cmsContext?.cms && Object.keys(nodeProps).length > 0) {\n nodeProps = processCMSPropsTemplate(nodeProps, ctx.cmsContext.cms, locale, i18nConfig);\n }\n\n // Process item templates in props (for CMSList context)\n // Skip when in templateMode to preserve {{item.field}} placeholders\n const templateCtx = getTemplateContext(ctx);\n const i18nResolver = getI18nResolver(ctx);\n if (!ctx.templateMode && templateCtx && Object.keys(nodeProps).length > 0) {\n nodeProps = processItemPropsTemplate(nodeProps, templateCtx, i18nResolver);\n }\n\n // Extract attributes from node\n let nodeAttributes = extractAttributesFromNode(node);\n const originalAttributes = { ...nodeAttributes };\n\n // Process CMS templates in attributes (e.g., href=\"{{cms.link}}\")\n if (ctx.cmsContext?.cms && Object.keys(nodeAttributes).length > 0) {\n nodeAttributes = processCMSPropsTemplate(nodeAttributes as Record<string, unknown>, ctx.cmsContext.cms, locale, i18nConfig) as Record<string, string | number | boolean>;\n }\n\n // Process item templates in attributes (for CMSList context)\n // Skip when in templateMode to preserve {{item.field}} placeholders\n if (!ctx.templateMode && templateCtx && Object.keys(nodeAttributes).length > 0) {\n nodeAttributes = processItemPropsTemplate(nodeAttributes, templateCtx, i18nResolver) as Record<string, string | number | boolean>;\n }\n\n // Auto-skip attributes that were entirely template expressions and resolved to \"\"\n if (Object.keys(nodeAttributes).length > 0) {\n nodeAttributes = skipEmptyTemplateAttributes(originalAttributes, nodeAttributes) as Record<string, string | number | boolean>;\n }\n\n if (!tag && !componentName) return '';\n\n // Convert styles to utility classes instead of inline styles\n let utilityClasses: string[] = [];\n let resolvedStyle: StyleObject = {};\n\n if (nodeStyle) {\n // Validate that all styles can generate utility classes (build-time warnings)\n validateStyleCoverage(nodeStyle, `Node: ${nodeType || 'unknown'}`);\n\n // Convert style object to utility class names (process templates in style values)\n utilityClasses = processStyleToClasses(nodeStyle, ctx);\n } else if (nodeProps.style) {\n // If no node.style but props have style, keep it for backward compatibility\n if (isResponsiveStyle(nodeProps.style) && breakpoints && viewportWidth) {\n resolvedStyle = mergeResponsiveStyles(nodeProps.style as ResponsiveStyleObject, 'viewport', viewportWidth, breakpoints);\n } else {\n resolvedStyle = nodeProps.style as StyleObject;\n }\n }\n\n // Generate element-specific class if node has interactive styles or generateElementClass flag\n const nodeInteractiveStyles = (node as any).interactiveStyles as InteractiveStyles | undefined;\n const nodeGenerateElementClass = (node as any).generateElementClass as boolean | undefined;\n const nodeLabel = (node as any).label as string | undefined;\n let elementClass = '';\n\n if ((nodeInteractiveStyles && nodeInteractiveStyles.length > 0) || nodeGenerateElementClass) {\n const isSlotContent = (node as any)._isSlotContent === true;\n elementClass = buildNodeElementClass(ctx, nodeLabel, isSlotContent);\n\n if (nodeInteractiveStyles && nodeInteractiveStyles.length > 0) {\n const cssVariables = registerInteractiveStyles(ctx, elementClass, nodeInteractiveStyles);\n // Add CSS variables to resolved style for inline output\n if (Object.keys(cssVariables).length > 0) {\n for (const [varName, value] of Object.entries(cssVariables)) {\n (resolvedStyle as Record<string, string | number>)[varName] = value;\n }\n }\n }\n }\n\n // Merge resolved style into props.style, and merge attributes\n // Handle class/className specially - merge with utility classes instead of replacing\n const attrClassName = (nodeAttributes.className || nodeAttributes.class || '') as string;\n const nodeAttributesWithoutClass = { ...nodeAttributes };\n delete nodeAttributesWithoutClass.className;\n delete nodeAttributesWithoutClass.class;\n\n // Merge classNames: element class (first for specificity) + attribute classes + utility classes\n const allClassNames = [elementClass, attrClassName, ...utilityClasses].filter(Boolean);\n const mergedClassName = allClassNames.length > 0 ? allClassNames.join(' ') : '';\n\n const propsWithStyleAndAttrs = {\n ...nodeProps,\n ...nodeAttributesWithoutClass,\n ...(mergedClassName ? { className: mergedClassName } : {}),\n ...(Object.keys(resolvedStyle).length > 0 ? { style: resolvedStyle } : {})\n };\n\n // Check if this is a custom component\n if (nodeType === NODE_TYPE.COMPONENT && componentName && ssrComponentRegistry.has(componentName)) {\n return renderComponent(componentName, propsWithStyleAndAttrs, children, nodeAttributes, ctx);\n }\n\n // Component not found in registry - warn and return empty\n if (nodeType === NODE_TYPE.COMPONENT && componentName) {\n console.warn(`[Meno SSR] Component \"${componentName}\" not found in registry.`);\n return '';\n }\n\n // Handle Link component for navigation (only for HTML nodes)\n if (tag === 'Link') {\n return renderLinkNode(propsWithStyleAndAttrs, children, ctx);\n }\n\n // Regular HTML element (must have tag)\n if (!tag) {\n console.error('Missing tag for HTML element in SSR');\n return '';\n }\n\n return renderHtmlElement(tag, propsWithStyleAndAttrs, children, ctx);\n}\n\n/**\n * Render a custom component\n */\nasync function renderComponent(\n componentName: string,\n propsWithStyleAndAttrs: Record<string, unknown>,\n children: unknown,\n nodeAttributes: Record<string, unknown>,\n ctx: SSRContext\n): Promise<string> {\n const { locale, i18nConfig, pagePath } = ctx;\n const componentDef = ssrComponentRegistry.get(componentName);\n if (!componentDef) return '';\n\n try {\n const structuredComponentDef = componentDef.component;\n if (!structuredComponentDef) return '';\n\n // Resolve props with defaults from interface definition (with i18n support)\n const resolvedProps = resolvePropsFromDefinition(\n structuredComponentDef,\n propsWithStyleAndAttrs,\n children as Array<ComponentNode | string> | string | ComponentNode | null | undefined,\n locale,\n i18nConfig\n );\n\n // Process the structure with resolved props\n // Pass instance children to replace { type: \"children\" } markers\n // Use preserveResponsiveStyles: true to keep responsive styles intact for SSR rendering\n // Mark children as slot content so they use page context for element class generation\n // Pass parent template context (itemContext) for nested cms-list template resolution\n const markedChildren = children ? markAsSlotContent(children as ComponentNode | ComponentNode[] | string | number | null | undefined) : undefined;\n\n const processedStructure = processStructure(\n structuredComponentDef.structure,\n { props: resolvedProps, componentDef: structuredComponentDef, itemContext: ctx.templateContext },\n undefined,\n markedChildren,\n true\n );\n\n if (!processedStructure) return '';\n\n // Type guard: ensure processedStructure is a ComponentNode\n if (typeof processedStructure === 'string' || typeof processedStructure === 'number' || Array.isArray(processedStructure)) {\n return await renderNode(processedStructure as string | number | ComponentNode[], ctx);\n }\n\n // Merge instance style overrides, className, and attributes\n // processedStructure is typically an HTML node (the component's root element)\n // Handle both component nodes and HTML nodes\n const rootNode = processedStructure as ComponentNode & { props?: Record<string, unknown> };\n if (isComponentNode(rootNode) || isHtmlNode(rootNode)) {\n if (!rootNode.props) {\n rootNode.props = {};\n }\n\n if (rootNode.props.style && typeof rootNode.props.style === 'object') {\n rootNode.props.style = {\n ...(rootNode.props.style as Record<string, unknown>),\n ...(propsWithStyleAndAttrs.style as Record<string, unknown> || {})\n };\n } else if (propsWithStyleAndAttrs.style) {\n rootNode.props.style = propsWithStyleAndAttrs.style;\n }\n\n // Merge className from component instance (includes responsive utility classes)\n if (propsWithStyleAndAttrs.className) {\n const existingClassName = rootNode.props.className || '';\n rootNode.props.className = existingClassName\n ? `${existingClassName} ${propsWithStyleAndAttrs.className}`\n : propsWithStyleAndAttrs.className;\n }\n\n // Merge attributes into props\n Object.assign(rootNode.props, nodeAttributes);\n\n // Forward nodeAttributes to rootNode.attributes for HTML root nodes\n // so attributes from outer components (e.g. data-component) reach the final HTML element\n if (isHtmlNode(rootNode) && Object.keys(nodeAttributes).length > 0) {\n if (!rootNode.attributes) {\n rootNode.attributes = {};\n }\n for (const [key, value] of Object.entries(nodeAttributes)) {\n if (key !== 'class' && key !== 'className') {\n rootNode.attributes[key] = value as string | number | boolean;\n }\n }\n }\n\n // Add defineVars data attributes for JS prop injection\n const defineVars = structuredComponentDef.defineVars;\n if (defineVars && componentName) {\n const varsToExpose = defineVars === true\n ? Object.keys(structuredComponentDef.interface || {})\n : defineVars;\n\n const propsForJS: Record<string, unknown> = {};\n for (const varName of varsToExpose) {\n if (resolvedProps[varName] !== undefined) {\n propsForJS[varName] = resolvedProps[varName];\n }\n }\n\n // Accumulate data-component (space-separated) and data-props (keyed by name)\n const processedRoot = processedStructure as import('../../shared/types').HtmlNode;\n if (!processedRoot.attributes) {\n processedRoot.attributes = {};\n }\n const existingComponent = (processedRoot.attributes?.['data-component'] as string)\n || (processedRoot.props?.['data-component'] as string)\n || '';\n processedRoot.attributes['data-component'] = existingComponent\n ? `${existingComponent} ${componentName}`\n : componentName;\n\n let existingPropsMap: Record<string, unknown> = {};\n const existingPropsStr = (processedRoot.attributes?.['data-props'] as string)\n || (processedRoot.props?.['data-props'] as string);\n if (existingPropsStr) {\n try { existingPropsMap = JSON.parse(existingPropsStr); } catch {}\n }\n existingPropsMap[componentName] = propsForJS;\n processedRoot.attributes['data-props'] = JSON.stringify(existingPropsMap);\n }\n }\n\n // Render the processed component structure with component context\n // Reset element path to component-relative for stable class names\n // Pass resolved props for interactive style mapping resolution\n return await renderNode(processedStructure, {\n ...ctx,\n componentContext: componentName,\n elementPath: [0],\n componentResolvedProps: resolvedProps,\n });\n\n } catch (error) {\n console.error(`\u274C SSR Error rendering component ${componentName}:`, error);\n return '';\n }\n}\n\n/**\n * Render a Link component as anchor tag\n */\nasync function renderLinkNode(\n propsWithStyleAndAttrs: Record<string, unknown>,\n children: unknown,\n ctx: SSRContext\n): Promise<string> {\n const to = 'to' in propsWithStyleAndAttrs ? propsWithStyleAndAttrs.to : undefined;\n const restProps: Record<string, unknown> = { ...propsWithStyleAndAttrs };\n delete restProps.to;\n const rawHref = (typeof to === 'string' ? to : undefined) || '#';\n const href = localizeHref(rawHref, ctx);\n\n // Build class attribute from utility classes\n const linkClassAttr = restProps.className\n ? ` class=\"${escapeHtml(String(restProps.className))}\"`\n : '';\n\n const attrs = buildAttributes(restProps, ['style', 'className', 'to']);\n const childrenHTML = Array.isArray(children)\n ? (await Promise.all((children as any[]).map((child, index) => {\n const childPath = ctx.elementPath ? [...ctx.elementPath, index] : [index];\n return renderNode(child, { ...ctx, elementPath: childPath });\n }))).join('')\n : await renderNode(children as ComponentNode, { ...ctx, elementPath: ctx.elementPath ? [...ctx.elementPath, 0] : [0] });\n\n return `<a href=\"${escapeHtml(String(href))}\"${linkClassAttr}${attrs}>${childrenHTML}</a>`;\n}\n\n/**\n * Render a regular HTML element\n */\nasync function renderHtmlElement(\n tag: string,\n propsWithStyleAndAttrs: Record<string, unknown>,\n children: unknown,\n ctx: SSRContext\n): Promise<string> {\n // Build class attribute from utility classes\n let classValue = propsWithStyleAndAttrs.className ? String(propsWithStyleAndAttrs.className) : '';\n\n // Localize and check <a> tag hrefs\n if (tag === 'a' && !ctx.templateMode) {\n const href = propsWithStyleAndAttrs.href as string | undefined;\n if (href && typeof href === 'string') {\n const localizedHref = localizeHref(href, ctx);\n if (localizedHref !== href) {\n propsWithStyleAndAttrs = { ...propsWithStyleAndAttrs, href: localizedHref };\n }\n if (ctx.pagePath && isCurrentLink(localizedHref, ctx.pagePath)) {\n classValue = classValue ? `${classValue} is-current` : 'is-current';\n }\n }\n }\n\n const classAttr = classValue ? ` class=\"${escapeHtml(classValue)}\"` : '';\n\n // Build style attribute (for CSS variables and remaining inline styles)\n const styleString = styleToString(propsWithStyleAndAttrs.style as Record<string, string | number> | undefined);\n const styleAttr = styleString ? ` style=\"${styleString}\"` : '';\n\n // For img tags, exclude image-specific props (handled specially in renderImageElement)\n const imageProps = ['src', 'alt', 'loading', 'width', 'height', 'sizes', 'srcset', 'fetchpriority'];\n const excludeProps = tag.toLowerCase() === 'img'\n ? ['style', 'className', ...imageProps]\n : ['style', 'className'];\n const attrs = buildAttributes(propsWithStyleAndAttrs, excludeProps);\n const childrenHTML = Array.isArray(children)\n ? (await Promise.all((children as any[]).map((child, index) => {\n const childPath = ctx.elementPath ? [...ctx.elementPath, index] : [index];\n return renderNode(child, { ...ctx, elementPath: childPath });\n }))).join('')\n : await renderNode(children as ComponentNode, { ...ctx, elementPath: ctx.elementPath ? [...ctx.elementPath, 0] : [0] });\n\n // Self-closing tags\n const voidElements = ['img', 'input', 'br', 'hr', 'meta', 'link', 'area', 'base', 'col', 'embed', 'source', 'track', 'wbr'];\n if (voidElements.includes(tag.toLowerCase())) {\n // Special handling for img tags - inject srcset and render as <picture> when AVIF available\n if (tag.toLowerCase() === 'img') {\n return renderImageElement(propsWithStyleAndAttrs, classAttr, attrs, ctx);\n }\n\n return `<${tag}${classAttr}${styleAttr}${attrs} />`;\n }\n\n return `<${tag}${classAttr}${styleAttr}${attrs}>${childrenHTML}</${tag}>`;\n}\n\n/**\n * Render an image element with responsive image support\n */\nfunction renderImageElement(\n propsWithStyleAndAttrs: Record<string, unknown>,\n classAttr: string,\n attrs: string,\n ctx: SSRContext\n): string {\n const imgProps = propsWithStyleAndAttrs;\n const src = imgProps.src as string | undefined;\n const alt = imgProps.alt as string | undefined;\n const loading = imgProps.loading as string | undefined;\n const sizes = imgProps.sizes as string | undefined;\n const fetchpriority = imgProps.fetchpriority as string | undefined;\n let width = imgProps.width as string | number | undefined;\n let height = imgProps.height as string | number | undefined;\n\n // Get image metadata from manifest\n const metadata = src ? ctx.imageMetadataMap?.get(src) : undefined;\n\n // Use dimensions from manifest if not explicitly set\n if (metadata) {\n if (width === undefined && metadata.width) width = metadata.width;\n if (height === undefined && metadata.height) height = metadata.height;\n }\n\n // Determine sizes attribute (prop > default)\n const sizesAttr = sizes || DEFAULT_SIZES;\n\n // Collect high-priority images for preloading in head\n if (fetchpriority === 'high' && metadata && ctx.preloadImages) {\n // Prefer AVIF, fallback to WebP\n if (metadata.avifSrcset) {\n ctx.preloadImages.push({\n srcset: metadata.avifSrcset,\n type: 'image/avif',\n sizes: sizesAttr,\n });\n } else if (metadata.srcset) {\n ctx.preloadImages.push({\n srcset: metadata.srcset,\n type: 'image/webp',\n sizes: sizesAttr,\n });\n }\n }\n\n // Build img attributes\n let imgAttrs = '';\n if (src) imgAttrs += ` src=\"${escapeHtml(String(src))}\"`;\n if (alt !== undefined) imgAttrs += ` alt=\"${escapeHtml(String(alt))}\"`;\n if (fetchpriority) imgAttrs += ` fetchpriority=\"${escapeHtml(String(fetchpriority))}\"`;\n if (loading) imgAttrs += ` loading=\"${escapeHtml(String(loading))}\"`;\n\n if (width !== undefined) imgAttrs += ` width=\"${escapeHtml(String(width))}\"`;\n if (height !== undefined) imgAttrs += ` height=\"${escapeHtml(String(height))}\"`;\n\n // Add blur placeholder as background if available\n let blurStyle = '';\n if (metadata?.blurHash) {\n blurStyle = ` style=\"background-image: url(${escapeHtml(metadata.blurHash)}); background-size: cover;\" onload=\"this.style.backgroundImage=''\"`;\n }\n\n // Render as <picture> element if AVIF is available\n // Split classes: layout/sizing on <picture>, image-specific on <img>\n if (metadata?.avifSrcset) {\n // Image-specific class prefixes that should stay on <img>\n const imgClassPrefixes = [\n 'objf-', 'objp-', 'flt-', 'tm-', 'bs-',\n 'br-', 'bt-', 'bb-', 'bl-', 'border-r-', 'bc-', 'b-'\n ];\n // Opacity classes (o-NUMBER) go on img, but overflow (o-h, o-a, o-s, o-v) stays on picture\n const opacityPattern = /^o-\\d/;\n\n // Parse classes from classAttr\n const classMatch = classAttr.match(/class=\"([^\"]*)\"/);\n const allClasses = classMatch ? classMatch[1].split(/\\s+/).filter(Boolean) : [];\n\n // Split classes between picture and img\n const imgClasses: string[] = [];\n const pictureClasses: string[] = [];\n\n for (const cls of allClasses) {\n if (imgClassPrefixes.some(prefix => cls.startsWith(prefix)) || opacityPattern.test(cls)) {\n imgClasses.push(cls);\n } else {\n pictureClasses.push(cls);\n }\n }\n\n const pictureClassAttr = pictureClasses.length > 0\n ? ` class=\"${escapeHtml(pictureClasses.join(' '))}\"`\n : '';\n const imgClassAttr = imgClasses.length > 0\n ? ` class=\"${escapeHtml(imgClasses.join(' '))}\"`\n : '';\n\n return `<picture${pictureClassAttr}>` +\n `<source type=\"image/avif\" srcset=\"${escapeHtml(metadata.avifSrcset)}\" sizes=\"${escapeHtml(sizesAttr)}\" />` +\n `<source type=\"image/webp\" srcset=\"${escapeHtml(metadata.srcset)}\" sizes=\"${escapeHtml(sizesAttr)}\" />` +\n `<img${imgClassAttr}${imgAttrs}${blurStyle}${attrs} />` +\n `</picture>`;\n }\n\n // Fallback: regular img with WebP srcset\n if (metadata?.srcset) {\n imgAttrs += ` srcset=\"${escapeHtml(metadata.srcset)}\"`;\n imgAttrs += ` sizes=\"${escapeHtml(sizesAttr)}\"`;\n }\n\n return `<img${classAttr}${imgAttrs}${blurStyle}${attrs} />`;\n}\n\n/**\n * Render a locale list node (language switcher)\n */\nfunction renderLocaleList(node: import('../../shared/types').LocaleListNode, ctx: SSRContext): string {\n const { slugMappings, pagePath, i18nConfig, locale } = ctx;\n\n if (slugMappings && pagePath && i18nConfig && locale) {\n const slugIndex = buildSlugIndex(slugMappings);\n const localeLinks = getLocaleLinks(pagePath, locale, i18nConfig, slugIndex);\n const showCurrent = node.showCurrent !== false;\n const showSeparator = node.showSeparator !== false;\n const showFlag = node.showFlag !== false;\n const displayType = node.displayType || 'nativeName';\n const nodeStyle = node.style;\n\n // Build a map of locale code to icon for quick lookup\n const localeIconMap = new Map<string, string>();\n for (const localeConfig of i18nConfig.locales) {\n if (localeConfig.icon) {\n localeIconMap.set(localeConfig.code, localeConfig.icon);\n }\n }\n\n // Convert container styles to utility classes\n let containerClasses: string[] = [];\n if (nodeStyle) {\n containerClasses = responsiveStylesToClasses(nodeStyle as ResponsiveStyleObject);\n }\n\n // Handle interactive styles for locale-list wrapper\n const localeListInteractiveStyles = node.interactiveStyles as InteractiveStyles | undefined;\n const localeListGenerateElementClass = node.generateElementClass;\n let localeListCssVariables: Record<string, string> = {};\n let localeListStyleAttr = '';\n\n if ((localeListInteractiveStyles && localeListInteractiveStyles.length > 0) || localeListGenerateElementClass) {\n const elementClass = buildNodeElementClass(ctx, node.label);\n containerClasses.unshift(elementClass);\n\n if (localeListInteractiveStyles && localeListInteractiveStyles.length > 0) {\n localeListCssVariables = registerInteractiveStyles(ctx, elementClass, localeListInteractiveStyles);\n }\n localeListStyleAttr = buildCssVariableStyleAttr(localeListCssVariables);\n }\n\n const containerClassAttr = containerClasses.length > 0\n ? ` class=\"${escapeHtml(containerClasses.join(' '))}\"`\n : '';\n\n // Convert item styles to utility classes\n let itemClasses: string[] = [];\n if (node.itemStyle) {\n itemClasses = responsiveStylesToClasses(node.itemStyle as ResponsiveStyleObject);\n }\n const itemClassAttr = itemClasses.length > 0\n ? ` class=\"${escapeHtml(itemClasses.join(' '))}\"`\n : '';\n\n // Convert active item styles to utility classes\n let activeItemClasses: string[] = [];\n if (node.activeItemStyle) {\n activeItemClasses = responsiveStylesToClasses(node.activeItemStyle as ResponsiveStyleObject);\n }\n\n // Convert separator styles to utility classes\n let separatorClasses: string[] = [];\n if (node.separatorStyle) {\n separatorClasses = responsiveStylesToClasses(node.separatorStyle as ResponsiveStyleObject);\n }\n const separatorClassAttr = separatorClasses.length > 0\n ? ` class=\"${escapeHtml(separatorClasses.join(' '))}\"`\n : '';\n\n // Convert flag styles to utility classes\n let flagClasses: string[] = [];\n if (node.flagStyle) {\n flagClasses = responsiveStylesToClasses(node.flagStyle as ResponsiveStyleObject);\n }\n const flagClassAttr = flagClasses.length > 0\n ? ` class=\"${escapeHtml(flagClasses.join(' '))}\"`\n : '';\n\n // Current item gets both itemStyle + activeItemStyle (additive/override)\n const currentItemClasses = [...itemClasses, ...activeItemClasses];\n const currentItemClassAttr = currentItemClasses.length > 0\n ? ` class=\"${escapeHtml(currentItemClasses.join(' '))}\"`\n : '';\n\n // Build links HTML\n const links: string[] = [];\n for (const link of localeLinks) {\n if (!showCurrent && link.isCurrent) continue;\n const currentAttr = link.isCurrent ? ' data-current=\"true\"' : ' data-current=\"false\"';\n const classAttrForLink = link.isCurrent ? currentItemClassAttr : itemClassAttr;\n const hreflangAttr = ` hreflang=\"${escapeHtml(link.langTag)}\"`;\n\n // Build link content with optional flag icon + text in div\n let linkContent = '';\n const localeIcon = localeIconMap.get(link.locale);\n if (showFlag && localeIcon) {\n linkContent += `<img src=\"${escapeHtml(localeIcon)}\" alt=\"${escapeHtml(link.nativeName)} flag\"${flagClassAttr}>`;\n }\n\n // Get display text based on displayType\n let displayText: string;\n switch (displayType) {\n case 'code':\n displayText = link.locale.toUpperCase();\n break;\n case 'name':\n displayText = link.name;\n break;\n case 'nativeName':\n default:\n displayText = link.nativeName;\n break;\n }\n linkContent += `<div>${escapeHtml(displayText)}</div>`;\n\n links.push(`<a href=\"${escapeHtml(link.path)}\"${hreflangAttr}${currentAttr} data-locale=\"${escapeHtml(link.locale)}\"${classAttrForLink}>${linkContent}</a>`);\n }\n\n // Join links with separator (empty span styled via separatorStyle) or concatenate directly\n const linksHTML = showSeparator\n ? links.join(`<span${separatorClassAttr}></span>`)\n : links.join('');\n\n // Extract attributes from node\n const nodeAttributes = extractAttributesFromNode(node as any);\n const attrsStr = buildAttributes(nodeAttributes);\n\n return `<div data-locale-list=\"true\"${containerClassAttr}${localeListStyleAttr}${attrsStr}>${linksHTML}</div>`;\n }\n // If context is missing, return empty div\n return '<div data-locale-list=\"true\"></div>';\n}\n\n/**\n * Main SSR render function - generates complete HTML with pre-rendered content\n */\nexport async function renderPageSSR(\n pageData: JSONPage,\n globalComponents: Record<string, ComponentDefinition> = {},\n pagePath: string = '/',\n baseUrl: string = '',\n locale?: string,\n i18nConfig?: I18nConfig,\n slugMappings?: SlugMap[],\n cmsContext?: CMSContext,\n cmsService?: CMSService,\n isProductionBuild?: boolean\n): Promise<{ html: string; meta: string; title: string; javascript: string; componentCSS?: string; locale: string; interactiveStylesMap: Map<string, InteractiveStyles>; preloadImages: PreloadImage[]; neededCollections: Set<string> }> {\n // Extract page content\n const rootNode = pageData?.root || undefined;\n if (!rootNode) {\n throw new Error('Page data must have a root node');\n }\n\n // Load i18n config if not provided\n const config = i18nConfig || await loadI18nConfig();\n\n // Extract locale from path if not explicitly provided\n const { locale: pathLocale, pathWithoutLocale } = extractLocaleFromPath(pagePath, config);\n const effectiveLocale = locale || pathLocale || config.defaultLocale;\n\n // Extract meta information and process CMS templates in meta\n let meta = extractPageMeta(pageData);\n if (cmsContext?.cms) {\n // Process CMS templates in meta fields (with i18n support)\n if (typeof meta.title === 'string') {\n meta = { ...meta, title: processCMSTemplate(meta.title, cmsContext.cms, effectiveLocale, config) };\n }\n if (typeof meta.description === 'string') {\n meta = { ...meta, description: processCMSTemplate(meta.description, cmsContext.cms, effectiveLocale, config) };\n }\n if (typeof meta.ogTitle === 'string') {\n meta = { ...meta, ogTitle: processCMSTemplate(meta.ogTitle, cmsContext.cms, effectiveLocale, config) };\n }\n if (typeof meta.ogDescription === 'string') {\n meta = { ...meta, ogDescription: processCMSTemplate(meta.ogDescription, cmsContext.cms, effectiveLocale, config) };\n }\n }\n\n const pageComponents = pageData?.components || {};\n\n // Render the component tree to HTML with i18n and CMS support\n // Also collect interactive styles, preload images, and needed collections during render\n const { html: contentHTML, interactiveStylesMap, preloadImages, neededCollections } = rootNode\n ? await buildComponentHTML(rootNode, globalComponents, pageComponents, effectiveLocale, config, slugMappings, pagePath, cmsContext, cmsService, isProductionBuild)\n : { html: '', interactiveStylesMap: new Map<string, InteractiveStyles>(), preloadImages: [], neededCollections: new Set<string>() };\n\n // Collect JavaScript and CSS from all components\n const javascript = await collectComponentJavaScript(globalComponents, pageComponents);\n const componentCSS = collectComponentCSS(globalComponents, pageComponents);\n\n // Build full URL for meta tags\n const fullUrl = baseUrl ? `${baseUrl}${pagePath}` : pagePath;\n\n // Generate meta tags with i18n resolution and hreflang tags\n const metaTags = generateMetaTags(meta, fullUrl, effectiveLocale, config, {\n slugMappings,\n pagePath,\n baseUrl,\n });\n\n // Resolve title for use in HTML template\n const resolvedTitle = resolveI18nValue(meta.title, effectiveLocale, config);\n\n // Return pre-rendered HTML (will be injected into template)\n return {\n html: contentHTML,\n meta: metaTags,\n title: typeof resolvedTitle === 'string' ? resolvedTitle : 'UPLO',\n javascript,\n // Component CSS is still included in the final HTML document\n componentCSS,\n locale: effectiveLocale,\n interactiveStylesMap,\n preloadImages,\n neededCollections,\n };\n}\n", "/**\n * Build-time validation tool\n * Scans all rendered HTML and warns about styles that don't generate utility classes\n */\n\nimport { propertyMap } from '../shared/utilityClassConfig';\nimport type { StyleObject, ResponsiveStyleObject } from '../shared/types';\n\ninterface MissingStyleReport {\n property: string;\n value: string;\n locations: string[];\n count: number;\n}\n\n// Track missing styles\nconst missingStylesMap = new Map<string, MissingStyleReport>();\n\n/**\n * Check if a style property and value can be converted to a utility class\n *\n * All CSS properties now generate utility classes:\n * - Known properties (in propertyMap) use standard prefixes\n * - Unknown properties generate dynamic classes with auto-prefixes\n */\nfunction canGenerateClass(property: string, value: unknown): boolean {\n // Skip internal component properties that shouldn't be styles\n const internalProps = new Set([\n 'type', 'tag', 'props', 'component', 'children', 'id', 'key',\n 'ref', 'className', 'style', 'node'\n ]);\n\n if (internalProps.has(property)) {\n return true; // Skip reporting these - they're not CSS styles\n }\n\n // Skip if value is null, undefined, or empty - these don't need utility classes\n if (value === null || value === undefined || value === '') {\n return true; // Skip reporting - nothing to convert\n }\n\n // Try to convert to string and check\n const strValue = String(value).trim();\n if (!strValue) {\n return false;\n }\n\n // Object values cannot be converted to utility classes\n if (typeof value === 'object') {\n return false;\n }\n\n // All CSS properties (including unknown ones) now generate utility classes:\n // - Known properties use standard prefixes from propertyMap\n // - Unknown properties generate dynamic classes registered in the dynamic registry\n // - CSS var() calls, space-separated values, and functions are all handled\n return true;\n}\n\n/**\n * Validate a style object and report missing utility class coverage\n */\nexport function validateStyleCoverage(\n styles: StyleObject | ResponsiveStyleObject | undefined,\n location: string\n): void {\n if (!styles || typeof styles !== 'object') {\n return;\n }\n\n // Check if it's a responsive style object\n if ('base' in styles || 'tablet' in styles || 'mobile' in styles) {\n // Process each breakpoint\n const responsive = styles as ResponsiveStyleObject;\n for (const [breakpoint, breakpointStyles] of Object.entries(responsive)) {\n if (typeof breakpointStyles === 'object' && breakpointStyles !== null) {\n validateStyleCoverage(breakpointStyles, `${location} (${breakpoint})`);\n }\n }\n return;\n }\n\n // Process regular style object\n const styleObj = styles as StyleObject;\n for (const [property, value] of Object.entries(styleObj)) {\n if (!canGenerateClass(property, value)) {\n const key = `${property}:${String(value)}`;\n const existing = missingStylesMap.get(key);\n\n if (existing) {\n existing.count++;\n existing.locations.push(location);\n } else {\n missingStylesMap.set(key, {\n property,\n value: String(value),\n locations: [location],\n count: 1,\n });\n }\n }\n }\n}\n\n/**\n * Print warnings for all missing utility class mappings found during build\n */\nexport function printMissingStyleWarnings(verbose = false): void {\n if (missingStylesMap.size === 0) {\n return;\n }\n\n const warnings: string[] = [];\n warnings.push(\n '\\n\u26A0\uFE0F WARNING: Found styles that cannot be converted to utility classes\\n'\n );\n warnings.push(\n 'These styles use object values which cannot be serialized to class names:\\n'\n );\n\n // Sort by frequency\n const sorted = Array.from(missingStylesMap.values()).sort(\n (a, b) => b.count - a.count\n );\n\n for (const report of sorted) {\n warnings.push(\n ` \u2022 ${report.property}: \"${report.value}\" (used ${report.count} time${report.count > 1 ? 's' : ''})`\n );\n\n if (verbose && report.locations.length > 0) {\n for (const location of report.locations.slice(0, 3)) {\n warnings.push(` \u2514\u2500 ${location}`);\n }\n if (report.locations.length > 3) {\n warnings.push(\n ` \u2514\u2500 ... and ${report.locations.length - 3} more locations`\n );\n }\n }\n }\n\n warnings.push('\\n\uD83D\uDCA1 Note:');\n warnings.push(' \u2022 All string/number values are now converted to utility classes');\n warnings.push(' \u2022 Object values (non-primitive) cannot be converted and will remain as-is');\n warnings.push(' \u2022 This warning only appears for object-type style values\\n');\n\n console.warn(warnings.join('\\n'));\n}\n\n/**\n * Reset the validation state (useful for testing)\n */\nexport function resetValidation(): void {\n missingStylesMap.clear();\n}\n\n/**\n * Get all missing styles found during validation\n */\nexport function getMissingStyles(): MissingStyleReport[] {\n return Array.from(missingStylesMap.values());\n}\n", "/**\n * Client Data Injector\n *\n * Utilities for injecting CMS collection data into HTML for client-side filtering.\n * Generates inline JSON script tags that MenoFilter can read.\n */\n\nimport type { CMSItem, CMSClientDataConfig } from '../../shared/types/cms';\n\n/** System fields that are always included in client data */\nconst SYSTEM_FIELDS = ['_id', '_url', '_filename', '_slug'];\n\n/**\n * Filter CMS items to only include specified fields.\n * System fields (_id, _url, _filename, _slug) are always included.\n *\n * @param items CMS items to filter\n * @param fields Fields to include (undefined or empty = all fields)\n * @returns Filtered items with only specified fields\n */\nexport function filterItemFields(\n items: CMSItem[],\n fields: string[] | undefined\n): CMSItem[] {\n // If no field restriction, return all items as-is\n if (!fields || fields.length === 0) {\n return items;\n }\n\n // Build set of allowed fields (user fields + system fields)\n const allowedFields = new Set([...SYSTEM_FIELDS, ...fields]);\n\n // Filter each item to only include allowed fields\n return items.map(item => {\n const filtered: CMSItem = { _id: item._id };\n\n for (const [key, value] of Object.entries(item)) {\n if (allowedFields.has(key)) {\n filtered[key] = value;\n }\n }\n\n return filtered;\n });\n}\n\n/**\n * Generate inline JSON script tag for collection data.\n * Uses type=\"application/json\" so it doesn't execute, just stores data.\n *\n * @param collection Collection ID\n * @param items Items to embed\n * @returns HTML script tag string\n */\nexport function generateInlineDataScript(\n collection: string,\n items: CMSItem[]\n): string {\n // Escape HTML entities in JSON to prevent XSS\n const jsonString = JSON.stringify(items)\n .replace(/</g, '\\\\u003c')\n .replace(/>/g, '\\\\u003e')\n .replace(/&/g, '\\\\u0026');\n\n return `<script type=\"application/json\" id=\"meno-cms-${escapeAttr(collection)}\">${jsonString}</script>`;\n}\n\n/**\n * Escape attribute value for safe HTML insertion\n */\nfunction escapeAttr(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n}\n\n/**\n * Determine the effective strategy for a collection based on config and item count.\n *\n * @param config Client data config\n * @param itemCount Number of items in collection\n * @returns Effective strategy ('inline' or 'static')\n */\nexport function determineStrategy(\n config: CMSClientDataConfig,\n itemCount: number\n): 'inline' | 'static' {\n if (config.strategy === 'inline') return 'inline';\n if (config.strategy === 'static') return 'static';\n\n // Auto strategy: use threshold to decide\n const threshold = config.threshold ?? 500;\n return itemCount <= threshold ? 'inline' : 'static';\n}\n\n/**\n * Collection data prepared for client-side injection\n */\nexport interface ClientDataCollection {\n /** Collection ID */\n collection: string;\n /** Filtered items for client */\n items: CMSItem[];\n /** Client data config */\n config: CMSClientDataConfig;\n /** Determined strategy */\n strategy: 'inline' | 'static';\n}\n\n/**\n * Prepare collection data for client-side injection.\n * Filters fields and determines strategy.\n *\n * @param collection Collection ID\n * @param items All items in collection\n * @param config Client data config from schema\n * @returns Prepared collection data, or null if not enabled\n */\nexport function prepareClientData(\n collection: string,\n items: CMSItem[],\n config: CMSClientDataConfig | undefined\n): ClientDataCollection | null {\n // Skip if not enabled\n if (!config?.enabled) {\n return null;\n }\n\n const strategy = determineStrategy(config, items.length);\n const filteredItems = filterItemFields(items, config.fields);\n\n return {\n collection,\n items: filteredItems,\n config,\n strategy,\n };\n}\n\n/**\n * Generate all inline data scripts for collections using inline strategy.\n *\n * @param collections Map of collection ID to prepared client data\n * @returns Combined HTML string with all data scripts\n */\nexport function generateAllInlineDataScripts(\n collections: Map<string, ClientDataCollection>\n): string {\n const scripts: string[] = [];\n\n for (const [collectionId, data] of collections) {\n if (data.strategy === 'inline') {\n scripts.push(generateInlineDataScript(collectionId, data.items));\n }\n }\n\n return scripts.join('\\n ');\n}\n", "/**\n * Library Loader\n * Generates HTML tags for external JS/CSS libraries\n */\n\nimport type {\n JSLibraryConfig,\n CSSLibraryConfig,\n LibrariesConfig,\n PageLibrariesConfig,\n} from './types/libraries';\nimport type { ComponentDefinition } from './types/components';\n\n/**\n * Escape HTML special characters in attribute values\n */\nfunction escapeAttr(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/\"/g, '&quot;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n}\n\n/**\n * Merge global and page-level library configurations\n * @param global Global libraries from project.config.json\n * @param page Page-level libraries from page meta\n * @returns Merged library configuration\n */\nexport function mergeLibraries(\n global: LibrariesConfig,\n page?: PageLibrariesConfig\n): LibrariesConfig {\n if (!page) {\n return global;\n }\n\n if (page.mode === 'replace') {\n return {\n js: page.js || [],\n css: page.css || [],\n };\n }\n\n // Default: extend\n return {\n js: [...(global.js || []), ...(page.js || [])],\n css: [...(global.css || []), ...(page.css || [])],\n };\n}\n\n/**\n * Generate <script> tag for a JS library\n * @param lib JavaScript library configuration\n * @returns HTML script tag string\n */\nexport function generateScriptTag(lib: JSLibraryConfig): string {\n const attrs: string[] = [`src=\"${escapeAttr(lib.url)}\"`];\n\n if (lib.type === 'module') {\n attrs.push('type=\"module\"');\n } else {\n // Default to defer for better performance\n const mode = lib.mode || 'defer';\n attrs.push(mode);\n }\n\n return `<script ${attrs.join(' ')}></script>`;\n}\n\n/**\n * Generate inline <style> tag with CSS content\n * @param content CSS content to embed\n * @param media Optional media query attribute\n * @returns HTML style tag string\n */\nexport function generateInlineStyleTag(content: string, media?: string): string {\n const attrs = media ? ` media=\"${escapeAttr(media)}\"` : '';\n return `<style${attrs}>${content}</style>`;\n}\n\n/**\n * Generate <link> tag for a CSS library\n * @param lib CSS library configuration\n * @returns HTML link tag string\n */\nexport function generateStylesheetTag(lib: CSSLibraryConfig): string {\n const attrs: string[] = [\n 'rel=\"stylesheet\"',\n `href=\"${escapeAttr(lib.url)}\"`,\n ];\n\n if (lib.media) {\n attrs.push(`media=\"${escapeAttr(lib.media)}\"`);\n }\n\n return `<link ${attrs.join(' ')}>`;\n}\n\n/**\n * Generated library tags grouped by position\n */\nexport interface LibraryTags {\n /** CSS tags for <head> */\n headCSS: string;\n /** JS tags for <head> */\n headJS: string;\n /** JS tags for before </body> */\n bodyEndJS: string;\n}\n\n/**\n * Generate all library tags grouped by position\n * @param libs Library configuration\n * @param inlineContents Optional map of URL \u2192 CSS content for inline embedding\n * @returns Object with tags grouped by position\n */\nexport function generateLibraryTags(libs: LibrariesConfig, inlineContents?: Map<string, string>): LibraryTags {\n const headCSS: string[] = [];\n const headJS: string[] = [];\n const bodyEndJS: string[] = [];\n\n // CSS always goes in head\n for (const css of libs.css || []) {\n const inlineContent = inlineContents?.get(css.url);\n if (inlineContent !== undefined) {\n headCSS.push(generateInlineStyleTag(inlineContent, css.media));\n } else {\n headCSS.push(generateStylesheetTag(css));\n }\n }\n\n // JS can go in head or body-end\n for (const js of libs.js || []) {\n const tag = generateScriptTag(js);\n if (js.position === 'head') {\n headJS.push(tag);\n } else {\n // Default to body-end\n bodyEndJS.push(tag);\n }\n }\n\n return {\n headCSS: headCSS.join('\\n '),\n headJS: headJS.join('\\n '),\n bodyEndJS: bodyEndJS.join('\\n '),\n };\n}\n\n/**\n * Collect library configurations from all component definitions, deduplicated by URL\n * @param globalComponents Global component definitions\n * @param pageComponents Page-specific component definitions\n * @returns Combined library configuration from all components\n */\nexport function collectComponentLibraries(\n globalComponents: Record<string, ComponentDefinition> = {},\n pageComponents: Record<string, ComponentDefinition> = {}\n): LibrariesConfig {\n const seenJS = new Set<string>();\n const seenCSS = new Set<string>();\n const jsLibs: JSLibraryConfig[] = [];\n const cssLibs: CSSLibraryConfig[] = [];\n\n const collect = (components: Record<string, ComponentDefinition>) => {\n for (const component of Object.values(components)) {\n const libs = component?.component?.libraries;\n if (!libs) continue;\n\n for (const js of libs.js || []) {\n if (!seenJS.has(js.url)) {\n seenJS.add(js.url);\n jsLibs.push(js);\n }\n }\n for (const css of libs.css || []) {\n if (!seenCSS.has(css.url)) {\n seenCSS.add(css.url);\n cssLibs.push(css);\n }\n }\n }\n };\n\n collect(globalComponents);\n collect(pageComponents);\n\n return { js: jsLibs, css: cssLibs };\n}\n\n/**\n * Origins extracted from library URLs, grouped by resource type\n */\nexport interface LibraryOrigins {\n /** Origins for script-src (from JS library URLs) */\n scriptOrigins: Set<string>;\n /** Origins for style-src (from CSS library URLs) */\n styleOrigins: Set<string>;\n}\n\n/**\n * Extract unique origin domains from library URLs for CSP headers.\n * Skips relative URLs (/, ./, ../) since they're covered by 'self'.\n * Silently skips malformed URLs.\n */\nexport function extractLibraryOrigins(libs: LibrariesConfig): LibraryOrigins {\n const scriptOrigins = new Set<string>();\n const styleOrigins = new Set<string>();\n\n for (const js of libs.js || []) {\n const origin = safeOrigin(js.url);\n if (origin) scriptOrigins.add(origin);\n }\n\n for (const css of libs.css || []) {\n const origin = safeOrigin(css.url);\n if (origin) styleOrigins.add(origin);\n }\n\n return { scriptOrigins, styleOrigins };\n}\n\n/**\n * Filter libraries based on context (editor, build, or preview).\n * Removes CSS libraries that have the corresponding disable flag set.\n * JS libraries pass through unchanged.\n * Preview context (dev server on port 8080) returns all libraries unfiltered.\n */\nexport function filterLibrariesByContext(\n libs: LibrariesConfig,\n context: 'editor' | 'build' | 'preview'\n): LibrariesConfig {\n if (context === 'preview') return libs;\n const key = context === 'editor' ? 'disableEditor' : 'disableBuild';\n return {\n js: libs.js,\n css: (libs.css || []).filter(css => !css[key]),\n };\n}\n\nfunction safeOrigin(url: string): string | null {\n if (!url || url.startsWith('/') || url.startsWith('./') || url.startsWith('../')) {\n return null;\n }\n try {\n return new URL(url).origin;\n } catch {\n return null;\n }\n}\n", "/**\n * CSS Variables Generator\n * Generates CSS color variable declarations for themes\n * and CSS custom property declarations from variables.json\n */\n\nimport type { ColorVariables, ThemeConfig } from '../shared/types/colors';\nimport { resolvePaletteColor } from '../shared/types/colors';\nimport type { VariablesConfig, CSSVariable } from '../shared/types/variables';\nimport type { BreakpointConfig } from '../shared/breakpoints';\nimport type { ResponsiveScales, BreakpointScales } from '../shared/responsiveScaling';\nimport { scalePropertyValue } from '../shared/responsiveScaling';\n\n/**\n * Generate CSS color variable declarations from color variables\n * Creates :root { --variable-name: value; } CSS\n */\nexport function generateColorVariablesCSS(colors: ColorVariables): string {\n const cssVars: string[] = [];\n\n for (const [name, value] of Object.entries(colors.colors)) {\n cssVars.push(` --${name}: ${value};`);\n }\n\n if (cssVars.length === 0) {\n return '';\n }\n\n return `:root {\\n${cssVars.join('\\n')}\\n}`;\n}\n\n/**\n * Generate CSS color variable declarations for multiple themes\n * Creates [theme=\"dark\"] { --variable-name: value; } selectors for each theme\n */\nexport function generateThemeColorVariablesCSS(themeConfig: ThemeConfig): string {\n const cssBlocks: string[] = [];\n const palette = themeConfig.palette;\n\n for (const [themeName, theme] of Object.entries(themeConfig.themes)) {\n const cssVars: string[] = [];\n\n for (const [name, value] of Object.entries(theme.colors)) {\n const resolved = resolvePaletteColor(value, palette);\n cssVars.push(` --${name}: ${resolved};`);\n }\n\n if (cssVars.length > 0) {\n cssBlocks.push(`[theme=\"${themeName}\"] {\\n${cssVars.join('\\n')}\\n}`);\n }\n }\n\n // Also include :root with default theme colors\n const defaultTheme = themeConfig.themes[themeConfig.default];\n if (defaultTheme) {\n const cssVars: string[] = [];\n for (const [name, value] of Object.entries(defaultTheme.colors)) {\n const resolved = resolvePaletteColor(value, palette);\n cssVars.push(` --${name}: ${resolved};`);\n }\n if (cssVars.length > 0) {\n cssBlocks.unshift(`:root {\\n${cssVars.join('\\n')}\\n}`);\n }\n }\n\n return cssBlocks.join('\\n\\n');\n}\n\n/**\n * Generate CSS custom property declarations from variables.json config\n * Produces :root block for base values and @media blocks for responsive scaling\n */\nexport function generateVariablesCSS(\n config: VariablesConfig,\n breakpoints?: BreakpointConfig,\n responsiveScales?: ResponsiveScales\n): string {\n if (!config.variables || config.variables.length === 0) {\n return '';\n }\n\n const cssBlocks: string[] = [];\n\n // Base :root block with all variables\n const baseVars = config.variables.map(v => ` ${v.cssVar}: ${v.value};`);\n cssBlocks.push(`:root {\\n${baseVars.join('\\n')}\\n}`);\n\n // Generate @media blocks for responsive scaling\n if (breakpoints && responsiveScales?.enabled) {\n const baseRef = responsiveScales.baseReference || 16;\n\n // Sort breakpoints by value descending (largest first)\n const sortedBreakpoints = Object.entries(breakpoints)\n .sort((a, b) => b[1].breakpoint - a[1].breakpoint);\n\n for (const [bpName, bpEntry] of sortedBreakpoints) {\n const scaledVars: string[] = [];\n\n for (const variable of config.variables) {\n // Per-variable override takes priority \u2014 stored string is the CSS value\n if (variable.scales && variable.scales[bpName]) {\n const overrideValue = variable.scales[bpName];\n if (overrideValue !== variable.value) {\n scaledVars.push(` ${variable.cssVar}: ${overrideValue};`);\n }\n continue;\n }\n\n // Global category scale (existing logic)\n if (variable.type === 'none') continue;\n const categoryScales = responsiveScales[variable.type] as BreakpointScales | undefined;\n const scale = categoryScales?.[bpName] ?? null;\n if (scale === null) continue;\n\n const scaled = scalePropertyValue(variable.value, baseRef, scale);\n if (scaled !== null && scaled !== variable.value) {\n scaledVars.push(` ${variable.cssVar}: ${scaled};`);\n }\n }\n\n if (scaledVars.length > 0) {\n cssBlocks.push(\n `@media (max-width: ${bpEntry.breakpoint}px) {\\n :root {\\n${scaledVars.join('\\n')}\\n }\\n}`\n );\n }\n }\n }\n\n return cssBlocks.join('\\n');\n}\n\n", "/**\n * Client-side Form Handler\n * Handles form submissions via fetch for forms with data-submit-handler=\"fetch\"\n *\n * This script is designed to be included inline in SSR output.\n * It's a self-executing module that attaches to forms automatically.\n */\n\nexport const formHandlerScript = `\n(function() {\n // Find all forms with fetch handler\n const forms = document.querySelectorAll('form[data-submit-handler=\"fetch\"]');\n\n forms.forEach(function(form) {\n form.addEventListener('submit', async function(e) {\n e.preventDefault();\n\n const action = form.getAttribute('action');\n const method = form.getAttribute('method') || 'POST';\n const successMessage = form.getAttribute('data-success-message') || 'Form submitted successfully!';\n const errorMessage = form.getAttribute('data-error-message') || 'Something went wrong. Please try again.';\n\n // Find or create message element\n let messageEl = form.querySelector('[data-form-message]');\n if (!messageEl) {\n messageEl = document.createElement('div');\n messageEl.setAttribute('data-form-message', 'true');\n form.appendChild(messageEl);\n }\n\n // Find submit button and disable it\n const submitBtn = form.querySelector('button[type=\"submit\"], input[type=\"submit\"]');\n const originalBtnText = submitBtn ? submitBtn.textContent || submitBtn.value : '';\n\n if (submitBtn) {\n submitBtn.disabled = true;\n if (submitBtn.tagName === 'BUTTON') {\n submitBtn.textContent = 'Sending...';\n } else {\n submitBtn.value = 'Sending...';\n }\n }\n\n // Hide any previous message\n messageEl.style.display = 'none';\n\n try {\n const formData = new FormData(form);\n\n const response = await fetch(action, {\n method: method.toUpperCase(),\n body: formData,\n });\n\n const data = await response.json();\n\n if (response.ok && data.success) {\n // Success\n messageEl.textContent = data.message || successMessage;\n messageEl.style.display = 'block';\n messageEl.style.backgroundColor = '#d4edda';\n messageEl.style.color = '#155724';\n messageEl.style.border = '1px solid #c3e6cb';\n\n // Optionally reset form\n form.reset();\n } else {\n // Error from server\n messageEl.textContent = data.error || errorMessage;\n messageEl.style.display = 'block';\n messageEl.style.backgroundColor = '#f8d7da';\n messageEl.style.color = '#721c24';\n messageEl.style.border = '1px solid #f5c6cb';\n }\n } catch (error) {\n // Network or other error\n messageEl.textContent = errorMessage;\n messageEl.style.display = 'block';\n messageEl.style.backgroundColor = '#f8d7da';\n messageEl.style.color = '#721c24';\n messageEl.style.border = '1px solid #f5c6cb';\n } finally {\n // Re-enable submit button\n if (submitBtn) {\n submitBtn.disabled = false;\n if (submitBtn.tagName === 'BUTTON') {\n submitBtn.textContent = originalBtnText;\n } else {\n submitBtn.value = originalBtnText;\n }\n }\n }\n });\n });\n})();\n`;\n\n/**\n * Check if page HTML contains forms that need the fetch handler\n */\nexport function needsFormHandler(html: string): boolean {\n return html.includes('data-submit-handler=\"fetch\"');\n}\n", "// AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY\n// Generated from: lib/client/meno-filter/MenoFilter.ts + init.ts\n// Regenerate with: bun scripts/build-meno-filter.ts\n//\n// This file is the production inline script injected into SSR HTML.\n// Edit the source TypeScript files, then run the build script.\n\n/**\n * MenoFilter Inline Script\n *\n * Self-contained script for client-side CMS filtering.\n * Injected into pages that use cms-list or MenoFilter.\n *\n * Features:\n * - Filter by field values with operators ($gt, $lt, $in, etc.)\n * - Search with debounce\n * - Sort ascending/descending\n * - Pagination\n * - Data attribute auto-binding\n * - Facet counts\n * - Lifecycle events\n */\n\nexport const menoFilterScript = `\"use strict\";var MenoFilterBundle=(()=>{var b=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var Z=Object.prototype.hasOwnProperty;var K=(r,e,t)=>e in r?b(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var X=(r,e)=>{for(var t in e)b(r,t,{get:e[t],enumerable:!0})},V=(r,e,t,n)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let i of Y(e))!Z.call(r,i)&&i!==t&&b(r,i,{get:()=>e[i],enumerable:!(n=J(e,i))||n.enumerable});return r};var ee=r=>V(b({},\"__esModule\",{value:!0}),r);var g=(r,e,t)=>K(r,typeof e!=\"symbol\"?e+\"\":e,t);var we={};X(we,{autoInit:()=>$,default:()=>Pe,destroyAllMenoFilters:()=>Q,destroyMenoFilter:()=>k,getMenoFilterInstance:()=>Re,initMenoFilter:()=>C});var S=class S{constructor(e){g(this,\"collection\");g(this,\"items\",[]);g(this,\"filteredItems\",[]);g(this,\"initialized\",!1);g(this,\"criteria\",{});g(this,\"orCriteria\",[]);g(this,\"searchQuery\",\"\");g(this,\"searchFields\",[]);g(this,\"sortConfig\",null);g(this,\"perPage\");g(this,\"currentPage\",1);g(this,\"visibleCount\",0);g(this,\"filterMatch\");g(this,\"fieldTypes\",{});g(this,\"urlSync\",!1);g(this,\"urlMode\",\"replace\");g(this,\"popstateHandler\",()=>this.syncFromUrl());g(this,\"fuzzySearchEnabled\",!1);g(this,\"fuzzyThreshold\",.3);g(this,\"eventListeners\",new Map);g(this,\"watchers\",new Set);this.collection=e.collection,this.perPage=e.perPage??0,this.filterMatch=e.filterMatch??\"and\",this.fieldTypes=e.fieldTypes??{},this.fuzzySearchEnabled=e.fuzzySearch??!1,this.fuzzyThreshold=e.fuzzyThreshold??.3,S.instances.set(this.collection,this),e.urlSync&&this.enableUrlSync({mode:e.urlMode})}static get(e){return S.instances.get(e)}static getAll(){return new Map(S.instances)}static has(e){return S.instances.has(e)}static destroy(e){let t=S.instances.get(e);t&&(t.destroy(),S.instances.delete(e))}static destroyAll(){for(let e of S.instances.values())e.destroy();S.instances.clear()}async init(){if(this.initialized)return;let e=document.getElementById(\\`meno-cms-\\${this.collection}\\`);if(e?.textContent)try{this.items=JSON.parse(e.textContent),this.filteredItems=[...this.items],this.initialized=!0,this.emit(\"init\",this.items),this.notifyWatchers();return}catch(t){console.error(\\`MenoFilter: Failed to parse inline data for \"\\${this.collection}\"\\`,t)}try{let t=await fetch(\\`/data/\\${this.collection}/index.json\\`);if(t.ok){this.items=await t.json(),this.filteredItems=[...this.items],this.initialized=!0,this.emit(\"init\",this.items),this.notifyWatchers();return}}catch(t){console.error(\\`MenoFilter: Failed to fetch static data for \"\\${this.collection}\"\\`,t)}console.warn(\\`MenoFilter: No data found for collection \"\\${this.collection}\"\\`),this.items=[],this.filteredItems=[],this.initialized=!0,this.emit(\"init\",[]),this.notifyWatchers()}isInitialized(){return this.initialized}destroy(){this.eventListeners.clear(),this.watchers.clear(),this.items=[],this.filteredItems=[],this.criteria={},this.orCriteria=[],this.initialized=!1}filter(e){return this.emit(\"beforeFilter\",e),this.criteria=e,this.orCriteria=[],this.currentPage=1,this.applyAllFilters(),this.emit(\"afterFilter\",this.filteredItems),this.getPageItems()}filterOr(e){return this.emit(\"beforeFilter\",e),this.criteria={},this.orCriteria=e,this.currentPage=1,this.applyAllFilters(),this.emit(\"afterFilter\",this.filteredItems),this.getPageItems()}addFilter(e,t){return this.criteria[e]=t,this.currentPage=1,this.applyAllFilters(),this.emit(\"afterFilter\",this.filteredItems),this.getPageItems()}removeFilter(e){return delete this.criteria[e],this.currentPage=1,this.applyAllFilters(),this.emit(\"afterFilter\",this.filteredItems),this.getPageItems()}clearFilters(){return this.criteria={},this.orCriteria=[],this.currentPage=1,this.applyAllFilters(),this.emit(\"afterFilter\",this.filteredItems),this.getPageItems()}getFilters(){return{...this.criteria}}search(e,t){return this.emit(\"beforeSearch\",{query:e,fields:t}),this.searchQuery=e,this.searchFields=t??[],this.currentPage=1,this.applyAllFilters(),this.emit(\"afterSearch\",this.filteredItems),this.getPageItems()}clearSearch(){return this.searchQuery=\"\",this.searchFields=[],this.applyAllFilters(),this.getPageItems()}getSearch(){return{query:this.searchQuery,fields:[...this.searchFields]}}sort(e,t=\"asc\"){return this.emit(\"beforeSort\",{field:e,order:t}),this.sortConfig={field:e,order:t},this.currentPage=1,this.applyAllFilters(),this.emit(\"afterSort\",this.filteredItems),this.getPageItems()}clearSort(){return this.sortConfig=null,this.applyAllFilters(),this.getPageItems()}getSort(){return this.sortConfig?{...this.sortConfig}:null}setPage(e){let t=this.getTotalPages(),n=Math.max(1,Math.min(e,t||1));return n!==this.currentPage&&(this.currentPage=n,this.emit(\"pageChange\",this.getPageInfo()),this.notifyWatchers()),this.getPageItems()}nextPage(){return this.setPage(this.currentPage+1)}prevPage(){return this.setPage(this.currentPage-1)}setPerPage(e){return this.perPage=e,this.currentPage=1,this.emit(\"pageChange\",this.getPageInfo()),this.notifyWatchers(),this.getPageItems()}getPageInfo(){let e=this.getTotalPages();return{current:this.currentPage,total:e,hasNext:this.currentPage<e,hasPrev:this.currentPage>1,totalItems:this.filteredItems.length,perPage:this.perPage||this.filteredItems.length}}getTotalPages(){return this.perPage===0?1:Math.ceil(this.filteredItems.length/this.perPage)}getPageItems(){if(this.perPage===0)return this.filteredItems;let e=(this.currentPage-1)*this.perPage,t=e+this.perPage;return this.filteredItems.slice(e,t)}loadMore(e){let t=e??(this.perPage||10),n=Math.min(this.visibleCount+t,this.filteredItems.length);return n!==this.visibleCount&&(this.visibleCount=n,this.emit(\"loadMore\",this.getLoadMoreInfo()),this.notifyWatchers()),this.getVisibleItems()}getVisibleItems(){return this.visibleCount===0?this.getPageItems():this.filteredItems.slice(0,this.visibleCount)}getLoadMoreInfo(){let e=this.visibleCount||this.filteredItems.length;return{visible:e,total:this.filteredItems.length,remaining:Math.max(0,this.filteredItems.length-e),hasMore:e<this.filteredItems.length}}resetVisibleCount(){this.visibleCount=this.perPage||0}initLoadMore(e){this.visibleCount=e??(this.perPage||10),this.notifyWatchers()}getAll(){return this.items}getFiltered(){return this.filteredItems}getItems(){return this.getPageItems()}getById(e){return this.items.find(t=>t._id===e||t._filename===e)}getUniqueValues(e){let t=new Set;for(let n of this.items){let i=n[e];i!=null&&(Array.isArray(i)?i.forEach(s=>t.add(s)):t.add(i))}return Array.from(t)}countFacets(e,t){let n={};for(let i of e){let s=i[t];if(s!=null)if(Array.isArray(s))s.forEach(o=>{let a=String(o);n[a]=(n[a]||0)+1});else{let o=String(s);n[o]=(n[o]||0)+1}}return n}getFacets(e){return this.countFacets(this.filteredItems,e)}getAllFacets(e){return this.countFacets(this.items,e)}reset(){return this.criteria={},this.orCriteria=[],this.searchQuery=\"\",this.searchFields=[],this.sortConfig=null,this.currentPage=1,this.filteredItems=[...this.items],this.emit(\"reset\",null),this.notifyWatchers(),this.getPageItems()}setFieldType(e,t){this.fieldTypes[e]=t}setFieldTypes(e){this.fieldTypes={...this.fieldTypes,...e}}getFieldTypes(){return{...this.fieldTypes}}coerceValue(e,t){let n=this.fieldTypes[e];if(!n||n===\"string\"||t===null||t===void 0)return t;switch(n){case\"number\":{if(typeof t==\"number\")return t;let i=parseFloat(String(t));return isNaN(i)?t:i}case\"date\":{if(t instanceof Date)return t.getTime();let i=new Date(String(t)).getTime();return isNaN(i)?t:i}case\"boolean\":return t===!0||t===\"true\"||t===\"1\";default:return t}}filterRange(e,t){let n={};return t.min!==void 0&&t.min!==\"\"&&(n.$gte=t.min),t.max!==void 0&&t.max!==\"\"&&(n.$lte=t.max),Object.keys(n).length===0?this.removeFilter(e):this.addFilter(e,n)}clearRangeFilter(e){return this.removeFilter(e)}enableUrlSync(e){typeof window>\"u\"||(this.urlSync=!0,this.urlMode=e?.mode??\"replace\",window.addEventListener(\"popstate\",this.popstateHandler),this.syncFromUrl())}disableUrlSync(){typeof window>\"u\"||(this.urlSync=!1,window.removeEventListener(\"popstate\",this.popstateHandler))}syncToUrl(){if(typeof window>\"u\")return;let e=new URLSearchParams;for(let[i,s]of Object.entries(this.criteria))if(!(s==null||s===\"\"))if(typeof s==\"object\"&&s!==null&&!Array.isArray(s))for(let[o,a]of Object.entries(s))a!=null&&a!==\"\"&&e.set(\\`filter.\\${i}.\\${o}\\`,String(a));else Array.isArray(s)?e.set(\\`filter.\\${i}\\`,s.join(\",\")):e.set(\\`filter.\\${i}\\`,String(s));this.sortConfig&&e.set(\"sort\",\\`\\${this.sortConfig.field}:\\${this.sortConfig.order}\\`),this.searchQuery&&(e.set(\"search\",this.searchQuery),this.searchFields.length>0&&e.set(\"search.fields\",this.searchFields.join(\",\"))),this.currentPage>1&&e.set(\"page\",String(this.currentPage)),this.perPage>0&&e.set(\"perPage\",String(this.perPage));let t=e.toString(),n=t?\\`\\${window.location.pathname}?\\${t}\\`:window.location.pathname;this.urlMode===\"push\"?history.pushState(null,\"\",n):history.replaceState(null,\"\",n)}syncFromUrl(){if(typeof window>\"u\")return;let e=new URLSearchParams(window.location.search);if(e.size===0)return;let t={};for(let[a,l]of e.entries()){if(!a.startsWith(\"filter.\"))continue;let u=a.split(\".\"),c=u[1],d=u[2];d?((!t[c]||typeof t[c]!=\"object\")&&(t[c]={}),t[c][d]=l):l.includes(\",\")?t[c]=l.split(\",\"):t[c]=l}let n=e.get(\"sort\");if(n){let[a,l=\"asc\"]=n.split(\":\");this.sortConfig={field:a,order:l}}let i=e.get(\"search\");if(i){this.searchQuery=i;let a=e.get(\"search.fields\");a&&(this.searchFields=a.split(\",\"))}let s=e.get(\"page\");if(s){let a=parseInt(s,10);!isNaN(a)&&a>0&&(this.currentPage=a)}let o=e.get(\"perPage\");if(o){let a=parseInt(o,10);!isNaN(a)&&a>0&&(this.perPage=a)}Object.keys(t).length>0&&(this.criteria=t),this.applyAllFilters()}setFuzzySearch(e,t){this.fuzzySearchEnabled=e,t!==void 0&&(this.fuzzyThreshold=Math.max(0,Math.min(1,t)))}isFuzzySearchEnabled(){return this.fuzzySearchEnabled}getTrigrams(e){let t=[],n=\\` \\${e} \\`;for(let i=0;i<n.length-2;i++)t.push(n.slice(i,i+3));return t}fuzzyMatch(e,t){if(t.length<3)return e.toLowerCase().includes(t.toLowerCase());let n=e.toLowerCase(),i=t.toLowerCase();if(n.includes(i))return!0;let s=this.getTrigrams(n),o=this.getTrigrams(i),a=new Set(o),l=new Set(s),u=0;for(let h of a)l.has(h)&&u++;let c=a.size+l.size-u;return c===0?!1:u/c>=this.fuzzyThreshold}on(e,t){return this.eventListeners.has(e)||this.eventListeners.set(e,new Set),this.eventListeners.get(e).add(t),()=>this.off(e,t)}off(e,t){this.eventListeners.get(e)?.delete(t)}emit(e,t){let n=this.eventListeners.get(e);if(n)for(let i of n)try{i(t)}catch(s){console.error(\\`MenoFilter: Error in \\${e} listener\\`,s)}}watch(e){return this.watchers.add(e),e(this.getState()),()=>this.watchers.delete(e)}subscribe(e){let t=n=>e(n.pageItems);return this.watchers.add(t),e(this.getPageItems()),()=>this.watchers.delete(t)}getState(){return{items:this.items,filteredItems:this.filteredItems,pageItems:this.getPageItems(),filters:{...this.criteria},sort:this.sortConfig?{...this.sortConfig}:null,search:{query:this.searchQuery,fields:[...this.searchFields]},page:this.getPageInfo()}}notifyWatchers(){let e=this.getState();for(let t of this.watchers)try{t(e)}catch(n){console.error(\"MenoFilter: Error in watcher\",n)}this.urlSync&&this.syncToUrl()}applyAllFilters(){let e=[...this.items];if(Object.keys(this.criteria).length>0&&(e=e.filter(t=>this.matchesCriteria(t,this.criteria))),this.orCriteria.length>0&&(e=e.filter(t=>this.orCriteria.some(n=>this.matchesCriteria(t,n)))),this.searchQuery){let t=this.searchQuery;e=e.filter(n=>(this.searchFields.length>0?this.searchFields:Object.keys(n)).some(s=>{let o=n[s];return typeof o!=\"string\"?!1:this.fuzzySearchEnabled?this.fuzzyMatch(o,t):o.toLowerCase().includes(t.toLowerCase())}))}if(this.sortConfig){let{field:t,order:n}=this.sortConfig;e.sort((i,s)=>{let o=i[t],a=s[t];if(o==null)return n===\"asc\"?1:-1;if(a==null)return n===\"asc\"?-1:1;let l=0;return typeof o==\"string\"&&typeof a==\"string\"?l=o.localeCompare(a):typeof o==\"number\"&&typeof a==\"number\"?l=o-a:l=String(o).localeCompare(String(a)),n===\"desc\"?-l:l})}this.filteredItems=e,this.visibleCount>0&&(this.visibleCount=Math.min(this.perPage||10,e.length)),this.notifyWatchers()}matchesCriteria(e,t){let n=Object.entries(t);return this.filterMatch===\"or\"?n.some(([i,s])=>this.matchesFieldValue(e,i,s)):n.every(([i,s])=>this.matchesFieldValue(e,i,s))}matchesFieldValue(e,t,n){if(n==null||n===\"\"||n===\"*\")return!0;let i=e[t];if(this.isOperatorObject(n))return this.matchesOperators(i,n,t);if(Array.isArray(i))return i.includes(n);if(Array.isArray(n))return n.includes(i);let s=this.coerceValue(t,i),o=this.coerceValue(t,n);return s===o}isOperatorObject(e){return typeof e!=\"object\"||e===null||Array.isArray(e)?!1:Object.keys(e).some(n=>n.startsWith(\"$\"))}matchesOperators(e,t,n){for(let[i,s]of Object.entries(t))if(!this.matchesOperator(e,i,s,n))return!1;return!0}matchesOperator(e,t,n,i){let s=i?this.coerceValue(i,e):e,o=i?this.coerceValue(i,n):n;switch(t){case\"$eq\":return s===o;case\"$neq\":return s!==o;case\"$gt\":return typeof s==\"number\"&&typeof o==\"number\"?s>o:String(s)>String(o);case\"$gte\":return typeof s==\"number\"&&typeof o==\"number\"?s>=o:String(s)>=String(o);case\"$lt\":return typeof s==\"number\"&&typeof o==\"number\"?s<o:String(s)<String(o);case\"$lte\":return typeof s==\"number\"&&typeof o==\"number\"?s<=o:String(s)<=String(o);case\"$contains\":return Array.isArray(e)?e.includes(n):typeof e==\"string\"&&typeof n==\"string\"?e.toLowerCase().includes(n.toLowerCase()):!1;case\"$notContains\":return Array.isArray(e)?!e.includes(n):typeof e==\"string\"&&typeof n==\"string\"?!e.toLowerCase().includes(n.toLowerCase()):!0;case\"$startsWith\":return typeof e==\"string\"&&typeof n==\"string\"?e.toLowerCase().startsWith(n.toLowerCase()):!1;case\"$endsWith\":return typeof e==\"string\"&&typeof n==\"string\"?e.toLowerCase().endsWith(n.toLowerCase()):!1;case\"$in\":return Array.isArray(n)?n.includes(e):!1;case\"$nin\":return Array.isArray(n)?!n.includes(e):!0;case\"$empty\":let a=e==null||e===\"\"||Array.isArray(e)&&e.length===0;return n?a:!a;default:return console.warn(\\`MenoFilter: Unknown operator \"\\${t}\"\\`),!0}}};g(S,\"instances\",new Map);var F=S;var f={FILTER:\"data-meno-filter\",LIST:\"data-meno-list\",ITEM:\"data-meno-item\",FILTER_FIELD:\"data-meno-filter-field\",FILTER_VALUE:\"data-meno-filter-value\",FILTER_MODE:\"data-meno-filter-mode\",SEARCH:\"data-meno-search\",SEARCH_FIELDS:\"data-meno-search-fields\",SEARCH_FUZZY:\"data-meno-search-fuzzy\",SEARCH_THRESHOLD:\"data-meno-search-threshold\",SORT:\"data-meno-sort\",SORT_ORDER:\"data-meno-sort-order\",CLEAR:\"data-meno-clear\",RESET:\"data-meno-reset\",PER_PAGE:\"data-meno-per-page\",FILTER_MATCH:\"data-meno-filter-match\",DEBOUNCE:\"data-meno-debounce\",PAGE:\"data-meno-page\",PAGE_CURRENT:\"data-meno-page-current\",PAGE_TOTAL:\"data-meno-page-total\",PAGE_BUTTONS:\"data-meno-page-buttons\",PER_PAGE_SELECT:\"data-meno-per-page-select\",LOAD_MORE:\"data-meno-load-more\",REMAINING:\"data-meno-remaining\",COUNT:\"data-meno-count\",FACET:\"data-meno-facet\",EMPTY:\"data-meno-empty\",ACTIVE_FILTERS:\"data-meno-active-filters\",ACTIVE_FILTER_TEMPLATE:\"data-meno-active-filter-template\",FILTER_REMOVE:\"data-meno-filter-remove\",ACTIVE_CLASS:\"data-meno-active-class\",TYPES:\"data-meno-types\",RANGE:\"data-meno-range\",RANGE_BOUND:\"data-meno-range-bound\",URL_SYNC:\"data-meno-url-sync\",URL_MODE:\"data-meno-url-mode\"};function te(r,e){let t;return(...n)=>{clearTimeout(t),t=setTimeout(()=>r(...n),e)}}function x(r){let e=r.closest(\\`[\\${f.FILTER_MODE}]\\`);if(!e)return null;let t=e.getAttribute(f.FILTER_MODE);return t===\"single\"||t===\"multi\"?t:null}function ne(r,e,t,n){let i=[];n!==void 0&&(typeof n==\"object\"&&n!==null&&\"$in\"in n?i=[...n.$in||[]]:typeof n==\"string\"&&(i=[n]));let s=i.indexOf(t);s===-1?i.push(t):i.splice(s,1),i.length===0?r.removeFilter(e):i.length===1?r.addFilter(e,i[0]):r.addFilter(e,{$in:i})}function O(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.FILTER_FIELD}][\\${f.FILTER_VALUE}]\\`);for(let l of i){if(l.tagName===\"INPUT\")continue;let u=l.getAttribute(f.FILTER_FIELD),c=l.getAttribute(f.FILTER_VALUE),d=()=>{let h=x(l),p=t.getFilters()[u];h===\"multi\"?ne(t,u,c,p):h===\"single\"?p!==c&&t.addFilter(u,c):p===c?t.removeFilter(u):t.addFilter(u,c)};l.addEventListener(\"click\",d),n.push(()=>l.removeEventListener(\"click\",d))}let s=e.querySelectorAll(\\`input[type=\"checkbox\"][\\${f.FILTER_FIELD}]\\`);for(let l of s){let u=l.getAttribute(f.FILTER_FIELD),c=()=>{if(x(l)===\"single\"&&l.checked){let h=e.querySelectorAll(\\`input[type=\"checkbox\"][\\${f.FILTER_FIELD}=\"\\${u}\"]\\`);for(let m of h)m!==l&&(m.checked=!1)}re(e,t,u)};l.addEventListener(\"change\",c),n.push(()=>l.removeEventListener(\"change\",c))}let o=e.querySelectorAll(\\`select[\\${f.FILTER_FIELD}]\\`);for(let l of o){let u=l.getAttribute(f.FILTER_FIELD),c=()=>{let d=l.value;d===\"\"||d===\"all\"||d===\"*\"?t.removeFilter(u):t.addFilter(u,d)};l.addEventListener(\"change\",c),n.push(()=>l.removeEventListener(\"change\",c))}let a=e.querySelectorAll(\\`input[type=\"radio\"][\\${f.FILTER_FIELD}]\\`);for(let l of a){let u=l.getAttribute(f.FILTER_FIELD),c=l.getAttribute(f.FILTER_VALUE)||l.value,d=()=>{l.checked&&(c===\"\"||c===\"all\"||c===\"*\"?t.removeFilter(u):t.addFilter(u,c))};l.addEventListener(\"change\",d),n.push(()=>l.removeEventListener(\"change\",d))}}function re(r,e,t){let n=r.querySelectorAll(\\`input[type=\"checkbox\"][\\${f.FILTER_FIELD}=\"\\${t}\"]:checked\\`),i=Array.from(n).map(s=>s.getAttribute(f.FILTER_VALUE)||s.value);i.length===0?e.removeFilter(t):i.length===1?e.addFilter(t,i[0]):e.addFilter(t,{$in:i})}function N(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.SEARCH}]\\`);for(let s of i){let o=s.getAttribute(f.SEARCH_FIELDS),a=o?o.split(\",\").map(d=>d.trim()):void 0,l,u=parseInt(e.getAttribute(f.DEBOUNCE)||\"300\",10),c=()=>{clearTimeout(l),l=setTimeout(()=>{t.search(s.value,a)},u)};s.addEventListener(\"input\",c),n.push(()=>{s.removeEventListener(\"input\",c),clearTimeout(l)})}}function _(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.SORT}]\\`);for(let o of i){if(o.tagName===\"SELECT\")continue;let a=o.getAttribute(f.SORT),l=o.getAttribute(f.SORT_ORDER)||\"asc\",u=()=>{let c=t.getSort();c?.field===a?c.order===l?t.sort(a,l===\"asc\"?\"desc\":\"asc\"):t.clearSort():t.sort(a,l)};o.addEventListener(\"click\",u),n.push(()=>o.removeEventListener(\"click\",u))}let s=e.querySelectorAll(\\`select[\\${f.SORT}]\\`);for(let o of s){let a=()=>{let l=o.value;if(!l){t.clearSort();return}let[u,c=\"asc\"]=l.split(\":\");t.sort(u,c)};o.addEventListener(\"change\",a),n.push(()=>o.removeEventListener(\"change\",a))}}function q(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.CLEAR}]\\`);for(let o of i){let a=()=>{t.clearFilters()};o.addEventListener(\"click\",a),n.push(()=>o.removeEventListener(\"click\",a))}let s=e.querySelectorAll(\\`[\\${f.RESET}]\\`);for(let o of s){let a=()=>{t.reset(),ie(e)};o.addEventListener(\"click\",a),n.push(()=>o.removeEventListener(\"click\",a))}}function ie(r){let e=r.querySelectorAll(\\`input[type=\"checkbox\"][\\${f.FILTER_FIELD}]\\`);for(let s of e)s.checked=!1;let t=r.querySelectorAll(\\`select[\\${f.FILTER_FIELD}]\\`);for(let s of t)s.selectedIndex=0;let n=r.querySelectorAll(\\`[\\${f.SEARCH}]\\`);for(let s of n)s.value=\"\";let i=r.querySelectorAll(\\`select[\\${f.SORT}]\\`);for(let s of i)s.selectedIndex=0}function D(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.PAGE}]\\`);for(let o of i){let a=o.getAttribute(f.PAGE),l=()=>{switch(a){case\"prev\":t.prevPage();break;case\"next\":t.nextPage();break;case\"first\":t.setPage(1);break;case\"last\":t.setPage(t.getPageInfo().total);break;default:let u=parseInt(a||\"1\",10);isNaN(u)||t.setPage(u)}};o.addEventListener(\"click\",l),n.push(()=>o.removeEventListener(\"click\",l))}let s=e.querySelectorAll(\\`[\\${f.PER_PAGE_SELECT}]\\`);for(let o of s){let a=()=>{let l=parseInt(o.value,10);!isNaN(l)&&l>0&&t.setPerPage(l)};o.addEventListener(\"change\",a),n.push(()=>o.removeEventListener(\"change\",a))}}function z(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelector(\\`[\\${f.LOAD_MORE}]\\`);if(!i)return;r.loadMoreMode=!0,t.initLoadMore();let s=()=>{let o=i.getAttribute(f.LOAD_MORE),a=o&&o!==\"\"?parseInt(o,10):void 0;t.loadMore(a)};i.addEventListener(\"click\",s),n.push(()=>i.removeEventListener(\"click\",s))}function H(r){if(r.value)return r.type===\"date\"?r.valueAsNumber||(r.value?new Date(r.value).getTime():void 0):r.valueAsNumber||(r.value?parseFloat(r.value):void 0)}function U(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.RANGE}]\\`);if(i.length===0)return;let s=parseInt(e.getAttribute(f.DEBOUNCE)||\"300\",10),o=new Map;for(let a of i){let l=a.getAttribute(f.RANGE);if(!l)continue;let u=a.getAttribute(f.RANGE_BOUND);!u||u!==\"min\"&&u!==\"max\"||(o.has(l)||o.set(l,{}),o.get(l)[u]=a)}for(let[a,l]of o){let u=te(()=>{let c=l.min?H(l.min):void 0,d=l.max?H(l.max):void 0;t.filterRange(a,{min:c,max:d})},s);if(l.min){let c=()=>u();l.min.addEventListener(\"input\",c),n.push(()=>l.min.removeEventListener(\"input\",c))}if(l.max){let c=()=>u();l.max.addEventListener(\"input\",c),n.push(()=>l.max.removeEventListener(\"input\",c))}}}function I(r){return r.replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\").replace(/'/g,\"&#x27;\")}function j(r){return r.endsWith(\"ies\")?r.slice(0,-3)+\"y\":r.endsWith(\"es\")?r.slice(0,-2):r.endsWith(\"s\")?r.slice(0,-1):r}function R(r,e){return e.split(\".\").reduce((t,n)=>t&&typeof t==\"object\"?t[n]:void 0,r)}function G(r,e,t,n,i){let s=r;s=s.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}\\\\\\\\.(\\\\\\\\w+)\\\\\\\\}\\\\\\\\}\\`,\"g\"),(l,u)=>{let c=e[u];return I(c!=null?String(c):\"\")}),s=s.replace(/\\\\{\\\\{item\\\\.(\\\\w+)\\\\}\\\\}/g,(l,u)=>{let c=e[u];return I(c!=null?String(c):\"\")}),s=s.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}Index\\\\\\\\}\\\\\\\\}\\`,\"g\"),String(n)),s=s.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}First\\\\\\\\}\\\\\\\\}\\`,\"g\"),n===0?\"true\":\"false\"),s=s.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}Last\\\\\\\\}\\\\\\\\}\\`,\"g\"),n===i-1?\"true\":\"false\"),s=s.replace(/\\\\{\\\\{itemIndex\\\\}\\\\}/g,String(n)),s=s.replace(/\\\\{\\\\{itemFirst\\\\}\\\\}/g,n===0?\"true\":\"false\"),s=s.replace(/\\\\{\\\\{itemLast\\\\}\\\\}/g,n===i-1?\"true\":\"false\");let o=document.createElement(\"div\");o.innerHTML=s;let a=o.firstElementChild;return W(a,e,t),a}function se(r,e,t,n,i,s,o){let a=r;o!==t&&(a=a.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${o}\\\\\\\\.(\\\\\\\\w+)\\\\\\\\}\\\\\\\\}\\`,\"g\"),(c,d)=>{let h=s[d];return I(h!=null?String(h):\"\")})),a=a.replace(/\\\\{\\\\{parentItem\\\\.(\\\\w+)\\\\}\\\\}/g,(c,d)=>{let h=s[d];return I(h!=null?String(h):\"\")}),o===\"item\"&&(a=a.replace(/\\\\{\\\\{item\\\\.(\\\\w+)\\\\}\\\\}/g,(c,d)=>{let h=s[d];return I(h!=null?String(h):\"\")})),a=a.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}\\\\\\\\.(\\\\\\\\w+)\\\\\\\\}\\\\\\\\}\\`,\"g\"),(c,d)=>{let h=e[d];return I(h!=null?String(h):\"\")}),t!==\"item\"&&o!==\"item\"&&(a=a.replace(/\\\\{\\\\{item\\\\.(\\\\w+)\\\\}\\\\}/g,(c,d)=>{let h=e[d];return I(h!=null?String(h):\"\")})),a=a.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}Index\\\\\\\\}\\\\\\\\}\\`,\"g\"),String(n)),a=a.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}First\\\\\\\\}\\\\\\\\}\\`,\"g\"),n===0?\"true\":\"false\"),a=a.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}Last\\\\\\\\}\\\\\\\\}\\`,\"g\"),n===i-1?\"true\":\"false\"),a=a.replace(/\\\\{\\\\{itemIndex\\\\}\\\\}/g,String(n)),a=a.replace(/\\\\{\\\\{itemFirst\\\\}\\\\}/g,n===0?\"true\":\"false\"),a=a.replace(/\\\\{\\\\{itemLast\\\\}\\\\}/g,n===i-1?\"true\":\"false\");let l=document.createElement(\"div\");l.innerHTML=a;let u=l.firstElementChild;return W(u,e,t),u}function W(r,e,t){let n=r.querySelectorAll('[data-cms-list-nested=\"true\"]');for(let i of n)oe(i,e,t)}function oe(r,e,t){let n=r.getAttribute(\"data-cms-config\");if(!n)return;let i;try{i=JSON.parse(n)}catch{return}let s=i.collection,o=r.querySelector(\"template[data-nested-template]\");if(!o)return;let a=o.innerHTML.trim(),l=i.itemAs||j(s),u=ae(s);if(!u){console.warn(\\`MenoFilter: No data for nested collection \"\\${s}\". Ensure clientData.enabled is true in schema.\\`);return}let c;i.items?c=le(i.items,e,t).map(p=>u.find(E=>E._id===p||E._filename===p)).filter(p=>p!==void 0):c=ce(u,i.filter,e,t),i.sort&&(c=de(c,i.sort)),i.offset&&(c=c.slice(i.offset)),i.limit&&(c=c.slice(0,i.limit));let d=[];for(let m=0;m<c.length;m++){let p=se(a,c[m],l,m,c.length,e,t);d.push(p)}Array.from(r.children).filter(m=>m.tagName!==\"TEMPLATE\").forEach(m=>m.remove());for(let m of d)r.appendChild(m);r.setAttribute(\"data-cms-list-hydrated\",\"true\")}function ae(r){let e=document.getElementById(\\`meno-cms-\\${r}\\`);if(!e?.textContent)return null;try{return JSON.parse(e.textContent)}catch{return null}}function le(r,e,t){if(Array.isArray(r))return r;if(typeof r!=\"string\"||!r.startsWith(\"{{\"))return[r];let n=r.match(/^\\\\{\\\\{(\\\\w+)\\\\.([^}]+)\\\\}\\\\}$/);if(!n)return[];let[,i,s]=n;if(i!==t&&i!==\"item\")return[];let o=R(e,s);return o==null?[]:Array.isArray(o)?o.map(String):[String(o)]}function ce(r,e,t,n){if(!e)return r;let i=ue(e,t,n);return r.filter(s=>fe(s,i))}function ue(r,e,t){if(Array.isArray(r))return r.map(n=>({...n,value:P(n.value,e,t)}));if(r&&typeof r==\"object\"){if(\"field\"in r&&\"value\"in r)return{...r,value:P(r.value,e,t)};let n={};for(let[i,s]of Object.entries(r))n[i]=P(s,e,t);return n}return r}function P(r,e,t){if(typeof r!=\"string\"||!r.startsWith(\"{{\"))return r;let n=r.match(/^\\\\{\\\\{(\\\\w+)\\\\.([^}]+)\\\\}\\\\}$/);if(!n)return r;let[,i,s]=n;return i!==t&&i!==\"item\"?r:R(e,s)}function fe(r,e){if(!e||typeof e!=\"object\")return!0;if(Array.isArray(e))return e.every(t=>B(r,t));if(\"field\"in e&&\"value\"in e)return B(r,e);for(let[t,n]of Object.entries(e))if(r[t]!==n)return!1;return!0}function B(r,e){let t=r[e.field],n=e.value;return Array.isArray(t)?t.includes(n):t===n}function de(r,e){if(!e)return r;let t=Array.isArray(e)?e[0]:e;if(!t||typeof t!=\"object\")return r;let{field:n,order:i=\"asc\"}=t;return[...r].sort((s,o)=>{let a=s[n],l=o[n],u=0;return typeof a==\"string\"&&typeof l==\"string\"?u=a.localeCompare(l):a!=null&&l!=null&&(u=String(a).localeCompare(String(l))),i===\"desc\"?-u:u})}function w(r){let{wrapper:e,filter:t}=r,n=t.getState();he(r),Ee(e,n),Te(e,t),Se(e,t,r),Le(e,n),ve(e,n),Fe(e,t),Me(e,t),be(e,t)}function he(r){let{wrapper:e,filter:t,itemTemplate:n}=r,i=e.querySelector(\\`[\\${f.LIST}]\\`);if(!i)return;if(t.getAll().length>0&&n){me(r,i);return}ge(r,i)}function me(r,e){let{filter:t,itemTemplate:n,ssrItems:i,itemAs:s,loadMoreMode:o}=r,a=o?t.getVisibleItems():t.getItems(),l=[],u=new Set;if(o)for(let c of Array.from(e.children)){if(c.tagName===\"TEMPLATE\")continue;let d=c.getAttribute(\"data-id\")||c.getAttribute(\"data-_id\");d&&u.add(d)}if(!o)for(let c of Array.from(e.children))c.tagName!==\"TEMPLATE\"&&(c.hasAttribute(\"data-meno-dynamic\")?c.remove():c.style.display=\"none\");for(let c=0;c<a.length;c++){let d=a[c],h=d._id;if(o&&u.has(h))continue;let m=i.get(h);if(m)m.style.display=\"\",e.appendChild(m),l.push(m);else if(n){let p=G(n,d,s,c,a.length);p.setAttribute(\"data-meno-dynamic\",\"true\"),p.setAttribute(\"data-id\",h),e.appendChild(p),l.push(p)}}}function ge(r,e){let{filter:t}=r,n=Array.from(e.children);if(n.length===0)return;let i=t.getFilters(),s=t.getSearch().query.toLowerCase(),o=t.getSearch().fields,a=t.getSort(),l=t.getPageInfo().perPage,u=t.getPageInfo().current,c=n.filter(E=>{for(let[v,y]of Object.entries(i)){let T=A(E,v);if(!ye(T,y))return!1}return!(s&&!pe(E,o).toLowerCase().includes(s))});a&&c.sort((E,v)=>{let y=A(E,a.field),T=A(v,a.field),L=0;return typeof y==\"string\"&&typeof T==\"string\"?L=y.localeCompare(T):y!=null&&T!=null?L=String(y).localeCompare(String(T)):y==null?L=1:L=-1,a.order===\"desc\"?-L:L});let d=c.length,h=l>0?(u-1)*l:0,m=l>0?h+l:d,p=c.slice(h,m);for(let E of n){let v=p.includes(E);E.style.display=v?\"\":\"none\"}if(a)for(let E of c)e.appendChild(E)}function A(r,e){let t=r.getAttribute(\\`data-\\${e}\\`);if(t!==null)return t;let n=r.querySelector(\\`[data-field=\"\\${e}\"]\\`);if(n)return n.textContent?.trim()||null;let i=r.querySelector(\\`[data-\\${e}]\\`);return i?i.getAttribute(\\`data-\\${e}\\`):null}function pe(r,e){return e.length>0?e.map(t=>A(r,t)||\"\").join(\" \"):r.textContent||\"\"}function ye(r,e){if(e==null||e===\"\")return!0;if(r===null)return!1;if(typeof e==\"object\"&&e!==null&&!Array.isArray(e)){let t=e;for(let[n,i]of Object.entries(t))switch(n){case\"$eq\":if(r!==i)return!1;break;case\"$neq\":if(r===i)return!1;break;case\"$contains\":if(!r.toLowerCase().includes(String(i).toLowerCase()))return!1;break;case\"$in\":if(!Array.isArray(i)||!i.includes(r))return!1;break;case\"$nin\":if(Array.isArray(i)&&i.includes(r))return!1;break}return!0}return r===String(e)}function Ee(r,e){let t=r.querySelectorAll(\\`[\\${f.COUNT}]\\`);for(let n of t){let i=n.getAttribute(f.COUNT),s;switch(i){case\"results\":s=e.page.totalItems;break;case\"total\":s=e.items.length;break;case\"visible\":s=e.pageItems.length;break;default:continue}n.textContent=String(s)}}function Te(r,e){let t=r.querySelectorAll(\\`[\\${f.FACET}]\\`);for(let n of t){let i=n.getAttribute(f.FACET);if(!i)continue;let[s,o]=i.split(\":\");if(!s||!o)continue;let l=e.getAllFacets(s)[o]||0;n.textContent=String(l)}}function Se(r,e,t){let n=r.querySelector(\\`[\\${f.ACTIVE_FILTERS}]\\`);if(!n)return;let i=r.querySelector(\\`template[\\${f.ACTIVE_FILTER_TEMPLATE}]\\`),s=e.getFilters(),o=Object.entries(s);if(n.innerHTML=\"\",o.length===0){n.style.display=\"none\";return}n.style.display=\"\";for(let[a,l]of o){let u=typeof l==\"object\"?\"[filter]\":String(l);if(i){let c=i.content.cloneNode(!0),d=c.querySelector(\"[data-meno-filter-label]\"),h=c.querySelector(\"[data-meno-filter-value]\"),m=c.querySelector(\\`[\\${f.FILTER_REMOVE}]\\`);if(d&&(d.textContent=a),h&&(h.textContent=u),m){let p=()=>{e.removeFilter(a)};m.addEventListener(\"click\",p),t.cleanup.push(()=>m.removeEventListener(\"click\",p))}n.appendChild(c)}else{let c=document.createElement(\"span\");c.className=\"meno-filter-tag\",c.innerHTML=\\`\\${a}: \\${u} <button type=\"button\">&times;</button>\\`;let d=c.querySelector(\"button\"),h=()=>{e.removeFilter(a)};d.addEventListener(\"click\",h),t.cleanup.push(()=>d.removeEventListener(\"click\",h)),n.appendChild(c)}}}function Le(r,e){let t=r.querySelector(\\`[\\${f.EMPTY}]\\`);t&&(e.pageItems.length===0?t.style.display=\"\":t.style.display=\"none\")}function ve(r,e){let{page:t}=e,n=r.querySelectorAll(\\`[\\${f.PAGE_CURRENT}]\\`);for(let l of n)l.textContent=String(t.current);let i=r.querySelectorAll(\\`[\\${f.PAGE_TOTAL}]\\`);for(let l of i)l.textContent=String(t.total);let s=r.querySelectorAll(\\`[\\${f.PAGE}=\"prev\"]\\`);for(let l of s)l.disabled=!t.hasPrev,l.style.opacity=t.hasPrev?\"\":\"0.5\";let o=r.querySelectorAll(\\`[\\${f.PAGE}=\"next\"]\\`);for(let l of o)l.disabled=!t.hasNext,l.style.opacity=t.hasNext?\"\":\"0.5\";let a=r.querySelector(\\`[\\${f.PAGE_BUTTONS}]\\`);a&&Ie(a,t,l=>{F.get(r.getAttribute(f.FILTER))?.setPage(l)})}function Ie(r,e,t){if(r.innerHTML=\"\",e.total<=1)return;let n=7,i=[];if(e.total<=n)i=Array.from({length:e.total},(s,o)=>o+1);else{let s=e.current;i=[1],s>3&&i.push(\"...\");for(let o=Math.max(2,s-1);o<=Math.min(e.total-1,s+1);o++)i.includes(o)||i.push(o);s<e.total-2&&i.push(\"...\"),i.includes(e.total)||i.push(e.total)}for(let s of i)if(s===\"...\"){let o=document.createElement(\"span\");o.textContent=\"...\",o.className=\"meno-page-dots\",r.appendChild(o)}else{let o=document.createElement(\"button\");o.type=\"button\",o.textContent=String(s),o.className=s===e.current?\"meno-page-btn active\":\"meno-page-btn\",o.addEventListener(\"click\",()=>t(s)),r.appendChild(o)}}function Fe(r,e){let t=e.getLoadMoreInfo(),n=r.querySelectorAll(\\`[\\${f.REMAINING}]\\`);for(let s of n)s.textContent=String(t.remaining);let i=r.querySelector(\\`[\\${f.LOAD_MORE}]\\`);i&&(i.style.display=t.hasMore?\"\":\"none\")}function Me(r,e){let t=e.getFilters(),n=r.getAttribute(f.ACTIVE_CLASS)||\"active\",i=r.querySelectorAll(\\`[\\${f.FILTER_FIELD}][\\${f.FILTER_VALUE}]\\`);for(let u of i){if(u.tagName===\"INPUT\")continue;let c=u.getAttribute(f.FILTER_FIELD),d=u.getAttribute(f.FILTER_VALUE);if(!c||!d)continue;let h=t[c],m=h!==void 0&&(h===d||Array.isArray(h)&&h.includes(d)||typeof h==\"object\"&&h!==null&&\"$in\"in h&&Array.isArray(h.$in)&&h.$in.includes(d));u.classList.toggle(n,m)}let s=r.querySelectorAll(\\`[\\${f.CLEAR}]\\`),o=Object.keys(t).length>0;for(let u of s)u.classList.toggle(n,!o);let a=e.getSort(),l=r.querySelectorAll(\\`[\\${f.SORT}]\\`);for(let u of l){if(u.tagName===\"SELECT\"){let h=u;a?h.value=\\`\\${a.field}:\\${a.order}\\`:h.value=\"\";continue}let c=u.getAttribute(f.SORT),d=a?.field===c;u.classList.toggle(n,d),d&&a?u.setAttribute(\"data-meno-sort-active\",a.order):u.removeAttribute(\"data-meno-sort-active\")}}function be(r,e){let t=e.getFilters(),n=r.querySelectorAll(\\`[\\${f.RANGE}]\\`);for(let i of n){let s=i.getAttribute(f.RANGE);if(!s)continue;let o=i.getAttribute(f.RANGE_BOUND);if(!o||o!==\"min\"&&o!==\"max\")continue;let a=t[s];if(!a||typeof a!=\"object\"||a===null)continue;let l=a,u=o===\"min\"?l.$gte:l.$lte;if(u!=null)if(i.type===\"date\"){let c=new Date(u);isNaN(c.getTime())||(i.value=c.toISOString().split(\"T\")[0])}else i.value=String(u)}}var M=new Map;async function C(){let r=document.querySelectorAll(\\`[\\${f.FILTER}]\\`);for(let e of r){let t=e.getAttribute(f.FILTER);t&&(M.has(t)||await Ae(e,t))}}async function Ae(r,e){let t=parseInt(r.getAttribute(f.PER_PAGE)||\"0\",10),n=r.getAttribute(f.FILTER_MATCH)||\"and\",i=parseInt(r.getAttribute(f.DEBOUNCE)||\"0\",10),s=r.getAttribute(f.URL_SYNC)===\"true\",o=r.getAttribute(f.URL_MODE)||\"replace\",a,l=r.getAttribute(f.TYPES);if(l)try{a=JSON.parse(l)}catch(T){console.warn(\"MenoFilter: Invalid data-meno-types JSON\",T)}let u=!1,c=.3,d=r.querySelector(\\`[\\${f.SEARCH}]\\`);if(d){u=d.getAttribute(f.SEARCH_FUZZY)===\"true\";let T=d.getAttribute(f.SEARCH_THRESHOLD);if(T){let L=parseFloat(T);isNaN(L)||(c=L)}}let h=new F({collection:e,perPage:t,filterMatch:n,debounce:i,urlSync:s,urlMode:o,fieldTypes:a,fuzzySearch:u,fuzzyThreshold:c}),m=[],{itemTemplate:p,ssrItems:E,itemAs:v}=Ce(r),y={wrapper:r,collection:e,filter:h,cleanup:m,itemTemplate:p,ssrItems:E,itemAs:v,loadMoreMode:!1};M.set(e,y),O(y),N(y),_(y),q(y),D(y),z(y),U(y),await h.init(),w(y),m.push(h.watch(()=>{w(y)}))}function Ce(r){let e=r.querySelector(\\`[\\${f.LIST}]\\`),t=new Map,n=\"item\";if(!e)return{itemTemplate:void 0,ssrItems:t,itemAs:n};let i=e.querySelector(\\`template[\\${f.ITEM}]\\`);if(i){let o=i.innerHTML.trim(),a=o.match(/\\\\{\\\\{(\\\\w+)\\\\./);a&&(n=a[1]);for(let l of Array.from(e.children)){if(l.tagName===\"TEMPLATE\")continue;let u=l.getAttribute(\"data-id\")||l.getAttribute(\"data-_id\");u&&t.set(u,l)}return{itemTemplate:o,ssrItems:t,itemAs:n}}let s=r.querySelector(\\`template[\\${f.ITEM}]\\`);if(s){let o=s.innerHTML.trim(),a=o.match(/\\\\{\\\\{(\\\\w+)\\\\./);return a&&(n=a[1]),{itemTemplate:o,ssrItems:t,itemAs:n}}for(let o=0;o<e.children.length;o++){let a=e.children[o];t.set(\\`__ssr_index_\\${o}\\`,a)}return{itemTemplate:void 0,ssrItems:t,itemAs:n}}function k(r){let e=M.get(r);if(e){for(let t of e.cleanup)t();e.filter.destroy(),M.delete(r),F.destroy(r)}}function Q(){for(let r of M.keys())k(r)}function Re(r){return M.get(r)}function $(){typeof document>\"u\"||(document.readyState===\"loading\"?document.addEventListener(\"DOMContentLoaded\",()=>C()):C())}$();var Pe={initMenoFilter:C,destroyMenoFilter:k,destroyAllMenoFilters:Q,autoInit:$};return ee(we);})();\nwindow.MenoFilter = MenoFilterBundle.MenoFilter;\n`;\n\n/**\n * Check if HTML contains elements that need MenoFilter\n */\nexport function needsMenoFilter(html: string): boolean {\n // Check for inline CMS data scripts\n if (/id=\"meno-cms-[^\"]+\"/i.test(html)) {\n return true;\n }\n // Check for cms-list nodes (static strategy)\n if (/data-cms-list=\"true\"/i.test(html)) {\n return true;\n }\n // Check for data-meno-filter wrappers\n if (/data-meno-filter=\"/i.test(html)) {\n return true;\n }\n return false;\n}\n\n/**\n * Check if any schemas have clientData enabled\n */\nexport function schemasNeedMenoFilter(\n schemas: Array<{ clientData?: { enabled: boolean } }>\n): boolean {\n return schemas.some((schema) => schema.clientData?.enabled === true);\n}\n\nexport default menoFilterScript;\n", "/**\n * HTML document generation for SSR\n * Generates complete HTML documents with SSR content\n * Supports CSP-compliant external scripts for static builds\n */\n\nimport type { ComponentDefinition, JSONPage, PageLibrariesConfig } from '../../shared/types';\nimport type { SlugMap } from '../../shared/slugTranslator';\nimport type { CMSService } from '../services/cmsService';\nimport { configService } from '../services/configService';\nimport { loadBreakpointConfig, loadResponsiveScalesConfig, loadIconsConfig, loadPrefetchConfig } from '../jsonLoader';\nimport { generateFontCSS, generateFontPreloadTags, loadProjectConfig } from '../../shared/fontLoader';\nimport { colorService } from '../services/ColorService';\nimport { generateThemeColorVariablesCSS, generateVariablesCSS } from '../cssGenerator';\nimport { variableService } from '../services/VariableService';\nimport { generateUtilityCSS, extractUtilityClassesFromHTML, generateAllInteractiveCSS } from '../../shared/cssGeneration';\nimport { printMissingStyleWarnings } from '../validateStyleCoverage';\nimport { formHandlerScript, needsFormHandler } from '../../client/scripts/formHandler';\nimport { menoFilterScript, needsMenoFilter } from '../../client/meno-filter/script.generated';\nimport { generateAllInlineDataScripts, prepareClientData, type ClientDataCollection } from './clientDataInjector';\nimport { mergeLibraries, generateLibraryTags, collectComponentLibraries, filterLibrariesByContext } from '../../shared/libraryLoader';\nimport { escapeHtml } from './attributeBuilder';\nimport { renderPageSSR, type PreloadImage } from './ssrRenderer';\nimport type { CMSContext } from './cmsSSRProcessor';\nimport { resolveProjectPath } from '../projectContext';\nimport { readTextFile } from '../runtime/fs';\n\n/**\n * Generate image preload link tags for high-priority images\n * Uses imagesrcset and imagesizes for responsive image preloading\n */\nfunction generateImagePreloadTags(preloadImages: PreloadImage[]): string {\n if (preloadImages.length === 0) return '';\n\n return preloadImages\n .map(img => `<link rel=\"preload\" as=\"image\" type=\"${img.type}\" imagesrcset=\"${escapeHtml(img.srcset)}\" imagesizes=\"${escapeHtml(img.sizes)}\" fetchpriority=\"high\">`)\n .join('\\n ');\n}\n\n/**\n * Minify CSS code using regex-based minification\n * Removes comments, unnecessary whitespace, and optimizes values\n */\nfunction minifyCSS(code: string): string {\n if (!code.trim()) return code;\n\n return code\n // Remove CSS comments\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n // Remove whitespace around special characters\n .replace(/\\s*([{};:,>~+])\\s*/g, '$1')\n // Collapse multiple spaces/newlines into single space\n .replace(/\\s+/g, ' ')\n // Remove space after opening brace\n .replace(/\\{\\s+/g, '{')\n // Remove space before closing brace\n .replace(/\\s+\\}/g, '}')\n // Remove trailing semicolons before closing braces\n .replace(/;}/g, '}')\n // Remove leading/trailing whitespace\n .trim();\n}\n\n/**\n * Result of SSR HTML generation with separate JS for CSP compliance\n */\nexport interface SSRHTMLResult {\n /** Complete HTML document */\n html: string;\n /** JavaScript code to be written to external file (for CSP compliance) */\n javascript: string | null;\n}\n\n/**\n * Options for SSR HTML generation\n */\nexport interface GenerateSSRHTMLOptions {\n /** Page data to render */\n pageData: JSONPage;\n /** Global component definitions */\n globalComponents?: Record<string, ComponentDefinition>;\n /** URL path for the page */\n pagePath?: string;\n /** Base URL for assets */\n baseUrl?: string;\n /** Use built bundle (production) vs dev server */\n useBuiltBundle?: boolean;\n /** Locale for i18n */\n locale?: string;\n /** Slug mappings for locale switching */\n slugMappings?: SlugMap[];\n /** CMS context for template rendering */\n cmsContext?: CMSContext;\n /** CMS service for CMSList queries */\n cmsService?: CMSService;\n /** When true, draft items are filtered out from CMS lists */\n isProductionBuild?: boolean;\n /**\n * Path to external scripts file (for CSP compliance).\n * When provided, JS is NOT inlined but referenced via this path.\n * Example: \"/_scripts/abc123.js\"\n */\n externalScriptPath?: string;\n /**\n * CMS template path for client-side hydration (dev mode only).\n * When provided, serializes CMS context to window.__MENO_CMS__ so the\n * client Router can load the template instead of the CMS URL.\n * Example: \"/templates/posts\"\n */\n cmsTemplatePath?: string;\n /**\n * Page-level library configuration (merged with global libraries)\n */\n pageLibraries?: PageLibrariesConfig;\n /**\n * Client-side CMS data for collections with clientData enabled.\n * Used for injecting inline JSON data for MenoFilter.\n */\n clientDataCollections?: Map<string, ClientDataCollection>;\n /**\n * Inject live reload script for on-demand SSR preview mode.\n * When true, adds a WebSocket client that reloads the page on HMR messages.\n */\n injectLiveReload?: boolean;\n /** Whether this is the visual editor (studio). Affects library filtering. */\n isEditor?: boolean;\n /** Actual bound server port for live reload WS (connects directly to SSR server) */\n serverPort?: number;\n}\n\n/**\n * Generate complete HTML document with SSR content (legacy positional args)\n */\nexport async function generateSSRHTML(\n pageData: JSONPage,\n globalComponents?: Record<string, ComponentDefinition>,\n pagePath?: string,\n baseUrl?: string,\n useBuiltBundle?: boolean,\n locale?: string,\n slugMappings?: SlugMap[],\n cmsContext?: CMSContext,\n cmsService?: CMSService,\n externalScriptPath?: string\n): Promise<string>;\n\n/**\n * Generate complete HTML document with SSR content (options object, returns separate JS for CSP)\n */\nexport async function generateSSRHTML(\n options: GenerateSSRHTMLOptions & { returnSeparateJS: true }\n): Promise<SSRHTMLResult>;\n\n/**\n * Generate complete HTML document with SSR content (options object)\n */\nexport async function generateSSRHTML(\n options: GenerateSSRHTMLOptions & { returnSeparateJS?: false }\n): Promise<string>;\n\n/**\n * Generate complete HTML document with SSR content\n */\nexport async function generateSSRHTML(\n pageDataOrOptions: JSONPage | (GenerateSSRHTMLOptions & { returnSeparateJS?: boolean }),\n globalComponents: Record<string, ComponentDefinition> = {},\n pagePath: string = '/',\n baseUrl: string = '',\n useBuiltBundle: boolean = false,\n locale?: string,\n slugMappings?: SlugMap[],\n cmsContext?: CMSContext,\n cmsService?: CMSService,\n externalScriptPath?: string\n): Promise<string | SSRHTMLResult> {\n // Handle options object vs legacy positional args\n let options: GenerateSSRHTMLOptions & { returnSeparateJS?: boolean };\n\n if ('pageData' in pageDataOrOptions) {\n options = pageDataOrOptions;\n } else {\n options = {\n pageData: pageDataOrOptions,\n globalComponents,\n pagePath,\n baseUrl,\n useBuiltBundle,\n locale,\n slugMappings,\n cmsContext,\n cmsService,\n externalScriptPath,\n };\n }\n\n const {\n pageData,\n globalComponents: components = {},\n pagePath: path = '/',\n baseUrl: base = '',\n useBuiltBundle: useBundled = false,\n locale: loc,\n slugMappings: slugs,\n cmsContext: cms,\n cmsService: cmsServ,\n externalScriptPath: extScriptPath,\n cmsTemplatePath,\n returnSeparateJS = false,\n pageLibraries,\n clientDataCollections,\n injectLiveReload = false,\n isEditor = false,\n isProductionBuild = false,\n serverPort,\n } = options;\n const rendered = await renderPageSSR(pageData, components, path, base, loc, undefined, slugs, cms, cmsServ, isProductionBuild);\n\n // Auto-inject data for nested collections (detected during SSR)\n // This enables client-side hydration for nested cms-list placeholders\n let finalClientDataCollections = clientDataCollections;\n if (rendered.neededCollections.size > 0 && cmsServ) {\n // Create a mutable copy if we need to add collections\n finalClientDataCollections = clientDataCollections\n ? new Map(clientDataCollections)\n : new Map();\n\n for (const collectionId of rendered.neededCollections) {\n // Skip if already provided\n if (finalClientDataCollections.has(collectionId)) continue;\n\n // Get schema to check if clientData is enabled\n const schema = cmsServ.getSchema(collectionId);\n if (!schema?.clientData?.enabled) {\n console.warn(\n `[SSR] Nested collection \"${collectionId}\" needs clientData.enabled for client-side hydration`\n );\n continue;\n }\n\n // Get items and prepare client data (force inline for nested collections)\n const items = await cmsServ.queryItems({\n collection: collectionId,\n excludeDraftLocale: loc,\n });\n const clientData = prepareClientData(collectionId, items, {\n ...schema.clientData,\n strategy: 'inline', // Force inline for nested collections\n });\n\n if (clientData) {\n finalClientDataCollections.set(collectionId, clientData);\n }\n }\n }\n\n // Load and merge external library configuration\n // Merge order: global \u2192 component \u2192 page (page can \"replace\" global+component, or \"extend\" all)\n await configService.load();\n const globalLibraries = configService.getLibraries() || { js: [], css: [] };\n const componentLibraries = collectComponentLibraries(components, pageData.components || {});\n // Merge global + component first (component libraries always extend)\n const globalPlusComponent = mergeLibraries(globalLibraries, componentLibraries) || { js: [], css: [] };\n // Then merge with page libraries (page can replace or extend)\n const mergedRaw = mergeLibraries(globalPlusComponent, pageLibraries) || { js: [], css: [] };\n // Deduplicate by URL so the same library isn't loaded twice\n const seenJS = new Set<string>();\n const seenCSS = new Set<string>();\n const mergedLibraries = {\n js: (mergedRaw.js || []).filter(lib => {\n if (seenJS.has(lib.url)) return false;\n seenJS.add(lib.url);\n return true;\n }),\n css: (mergedRaw.css || []).filter(lib => {\n if (seenCSS.has(lib.url)) return false;\n seenCSS.add(lib.url);\n return true;\n }),\n };\n const libraryContext = isEditor ? 'editor' : (useBundled && !injectLiveReload ? 'build' : 'preview');\n const filteredLibraries = filterLibrariesByContext(mergedLibraries, libraryContext);\n\n // Cache-bust local library URLs in dev/preview to avoid stale browser cache\n const devMode = !useBundled || injectLiveReload;\n const bustCache = devMode ? `?v=${Date.now()}` : '';\n const finalLibraries = bustCache ? {\n js: (filteredLibraries.js || []).map(lib =>\n lib.url.startsWith('/') ? { ...lib, url: lib.url + bustCache } : lib\n ),\n css: (filteredLibraries.css || []).map(lib =>\n lib.url.startsWith('/') ? { ...lib, url: lib.url + bustCache } : lib\n ),\n } : filteredLibraries;\n\n // Read local CSS files for inline embedding\n const inlineContents = new Map<string, string>();\n for (const css of finalLibraries.css || []) {\n // Inline by default for local files, unless explicitly set to false\n const shouldInline = css.inline !== false && css.url.startsWith('/');\n if (shouldInline) {\n try {\n const cleanUrl = css.url.split('?')[0]; // Strip cache-bust query param\n const filePath = resolveProjectPath(cleanUrl.slice(1));\n const content = await readTextFile(filePath);\n inlineContents.set(css.url, content);\n } catch {\n // File not found \u2014 fall back to <link> tag\n }\n }\n }\n\n const libraryTags = generateLibraryTags(finalLibraries, inlineContents);\n\n // Use built bundle in production, dev server in development\n const clientScript = useBundled\n ? '' // No client router in static build (true static HTML)\n : '<script type=\"module\" src=\"/client-router.tsx\"></script>'; // Dev server (development)\n\n // Collect all JavaScript (component JS + form handler + meno filter if needed)\n const needsForm = needsFormHandler(rendered.html);\n // Include MenoFilter if: inline clientData exists OR page has cms-list nodes (for static strategy)\n const needsFilter = (finalClientDataCollections && finalClientDataCollections.size > 0) || needsMenoFilter(rendered.html);\n const allJavaScript = [\n rendered.javascript || '',\n needsForm ? formHandlerScript : '',\n needsFilter ? menoFilterScript : ''\n ].filter(Boolean).join('\\n\\n');\n\n // Determine script output based on mode\n let componentScript = '';\n let externalJavaScript: string | null = null;\n\n if (allJavaScript) {\n if (extScriptPath) {\n // CSP-compliant: reference external script file (defer to avoid render-blocking)\n componentScript = `\\n <script src=\"${extScriptPath}\" defer></script>`;\n externalJavaScript = allJavaScript;\n } else if (returnSeparateJS) {\n // Return JS separately (for build-static to write to file)\n externalJavaScript = allJavaScript;\n } else {\n // Legacy inline mode (dev server)\n // Escape </script> sequences to prevent premature script tag closure\n const escapedJavaScript = allJavaScript.replace(/<\\/script>/gi, '<\\\\/script>');\n componentScript = `\\n <script>\\n${escapedJavaScript}\\n </script>`;\n }\n }\n\n // Ensure project config is loaded (reloads from disk if cache was cleared)\n await loadProjectConfig();\n const fontCSS = generateFontCSS();\n const fontPreloadTags = generateFontPreloadTags();\n\n // Load icons config for favicon and apple touch icon\n const iconsConfig = await loadIconsConfig();\n\n // Load and generate theme color variables CSS\n const themeConfig = await colorService.loadThemeConfig();\n const themeColorVariablesCSS = generateThemeColorVariablesCSS(themeConfig);\n\n // Include component CSS (no longer generating inline style classes)\n const componentCSS = rendered.componentCSS || '';\n\n // Extract and generate utility CSS from rendered HTML\n const usedUtilityClasses = extractUtilityClassesFromHTML(rendered.html);\n const breakpointConfig = await loadBreakpointConfig();\n const responsiveScalesConfig = await loadResponsiveScalesConfig();\n\n // Load and generate CSS custom properties from variables.json\n const variablesConfig = await variableService.loadConfig();\n const variablesCSS = generateVariablesCSS(variablesConfig, breakpointConfig, responsiveScalesConfig);\n const utilityCSS = generateUtilityCSS(usedUtilityClasses, breakpointConfig, responsiveScalesConfig);\n\n // Generate interactive styles CSS from map collected during render\n const interactiveCSS = rendered.interactiveStylesMap.size > 0\n ? generateAllInteractiveCSS(rendered.interactiveStylesMap, breakpointConfig)\n : '';\n\n // Print warnings for any unmapped styles found during build\n printMissingStyleWarnings(false);\n\n // Build base CSS (reset styles)\n const baseCSS = `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;\n}\nbutton {\n background: none;\n border: none;\n padding: 0;\n font: inherit;\n cursor: pointer;\n outline: inherit;\n}\nimg {\n display: block;\n width: 100%;\n height: 100%;\n}\n.olink {\n text-decoration: none;\n display: block;\n}\n.oem {\n display: inline-block;\n}`;\n\n // Combine all CSS\n const combinedCSS = [\n fontCSS,\n themeColorVariablesCSS,\n variablesCSS,\n baseCSS,\n componentCSS,\n utilityCSS,\n interactiveCSS\n ].filter(Boolean).join('\\n');\n\n // Minify CSS in production mode\n const finalCSS = useBundled ? minifyCSS(combinedCSS) : combinedCSS;\n\n // Load prefetch config for client-side prefetching\n const prefetchConfig = await loadPrefetchConfig();\n // Only include non-default values to minimize payload\n const menoConfig = prefetchConfig.enabled ? { prefetch: prefetchConfig } : {};\n // Config script - inline for dev, include in external JS for static build\n const hasConfig = Object.keys(menoConfig).length > 0;\n const configInlineScript = hasConfig && !extScriptPath && !returnSeparateJS\n ? `<script>window.__MENO_CONFIG__=${JSON.stringify(menoConfig)}</script>\\n `\n : '';\n // Add config to external JS if using external scripts\n if (hasConfig && externalJavaScript !== null) {\n externalJavaScript = `window.__MENO_CONFIG__=${JSON.stringify(menoConfig)};\\n\\n` + externalJavaScript;\n }\n\n // CMS context script - needed when a client-side Router is present (dev mode or studio preview)\n // Production builds are pure HTML with no client routing, so excluded\n const cmsInlineScript = cmsTemplatePath && cms && (!useBundled || injectLiveReload)\n ? `<script>window.__MENO_CMS__=${JSON.stringify({ item: cms.cms, templatePath: cmsTemplatePath })}</script>\\n `\n : '';\n\n // Client data scripts - inline JSON for MenoFilter (production builds only)\n const clientDataScripts = finalClientDataCollections && finalClientDataCollections.size > 0\n ? generateAllInlineDataScripts(finalClientDataCollections) + '\\n '\n : '';\n\n // Generate favicon and apple touch icon link tags\n const faviconTag = iconsConfig.favicon\n ? `<link rel=\"icon\" href=\"${escapeHtml(iconsConfig.favicon)}\" />`\n : '';\n const appleTouchIconTag = iconsConfig.appleTouchIcon\n ? `<link rel=\"apple-touch-icon\" href=\"${escapeHtml(iconsConfig.appleTouchIcon)}\" />`\n : '';\n const iconTags = [faviconTag, appleTouchIconTag].filter(Boolean).join('\\n ');\n\n // Script preload tag - eliminates critical request chain by discovering script early\n const scriptPreloadTag = extScriptPath\n ? `<link rel=\"preload\" href=\"${extScriptPath}\" as=\"script\">`\n : '';\n\n // Image preload tags for high-priority images (LCP optimization)\n const imagePreloadTags = generateImagePreloadTags(rendered.preloadImages);\n\n // Live reload script for on-demand SSR preview mode (in-place DOM update, no white flash)\n const wsUrl = serverPort\n ? `'ws://localhost:${serverPort}/hmr'`\n : `location.origin.replace('http','ws')+'/hmr'`;\n const liveReloadScript = injectLiveReload\n ? `<script>(function(){var ws,timer,gen=0;function connect(){ws=new WebSocket(${wsUrl});ws.onmessage=function(e){var d=JSON.parse(e.data);if(d.type==='hmr:libraries-update'){location.reload()}else if(d.type==='hmr:update'||d.type==='hmr:cms-update'||d.type==='hmr:colors-update'||d.type==='hmr:variables-update')hotReload()};ws.onclose=function(){clearTimeout(timer);timer=setTimeout(connect,1000)}}function hotReload(){var g=++gen;var sx=window.scrollX,sy=window.scrollY;fetch(location.href,{cache:'no-store'}).then(function(r){return r.text()}).then(function(html){if(g!==gen)return;var p=new DOMParser();var d=p.parseFromString(html,'text/html');var or=document.getElementById('root');var nr=d.getElementById('root');if(or&&nr)or.innerHTML=nr.innerHTML;var os=document.getElementById('meno-styles');var ns=d.getElementById('meno-styles');if(os&&ns){os.parentNode.replaceChild(ns.cloneNode(true),os)}var nh=d.documentElement;if(nh){document.documentElement.setAttribute('lang',nh.getAttribute('lang')||'en');document.documentElement.setAttribute('theme',nh.getAttribute('theme')||'light')}document.querySelectorAll('script[id^=\"meno-cms-\"]').forEach(function(s){s.remove()});d.querySelectorAll('script[id^=\"meno-cms-\"]').forEach(function(s){var c=document.createElement('script');c.type=s.type;c.id=s.id;c.textContent=s.textContent;document.head.appendChild(c)});window.__menoHotReload=true;document.querySelectorAll('body > script[src^=\"/libraries/\"]').forEach(function(o){o.remove()});d.querySelectorAll('body > script[src^=\"/libraries/\"]').forEach(function(n){var ls=document.createElement('script');ls.src=n.getAttribute('src')+(n.getAttribute('src').indexOf('?')>-1?'&':'?')+'_r='+Date.now();document.body.appendChild(ls)});var oscr=document.querySelector('script[src^=\"/_scripts/\"]');var nscr=d.querySelector('script[src^=\"/_scripts/\"]');if(nscr){var src=nscr.getAttribute('src');if(oscr)oscr.remove();var s=document.createElement('script');s.src=src+(src.indexOf('?')>-1?'&':'?')+'_r='+Date.now();s.onload=function(){document.dispatchEvent(new Event('DOMContentLoaded'));window.scrollTo(sx,sy)};s.onerror=function(){window.scrollTo(sx,sy)};document.body.appendChild(s)}else{if(oscr)oscr.remove();document.dispatchEvent(new Event('DOMContentLoaded'));window.scrollTo(sx,sy)}}).catch(function(){location.reload()})}connect()})()</script>`\n : '';\n\n // Scroll position handlers for preview mode iframe switching\n const scrollHandlerScript = injectLiveReload\n ? `<script>(function(){window.addEventListener('message',function(e){if(e.data.type==='GET_SCROLL_POSITION'){window.parent.postMessage({type:'SCROLL_POSITION_RESPONSE',scrollX:window.scrollX,scrollY:window.scrollY},'*')}else if(e.data.type==='SET_SCROLL_POSITION'){window.scrollTo(e.data.scrollX,e.data.scrollY)}})})()</script>`\n : '';\n\n // In production, output minified CSS on single line; in dev, preserve formatting\n const styleContent = useBundled\n ? finalCSS\n : `\\n ${combinedCSS.split('\\n').join('\\n ')}\\n `;\n\n const htmlDocument = `<!DOCTYPE html>\n<html lang=\"${rendered.locale}\" theme=\"${themeConfig.default}\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${iconTags ? iconTags + '\\n ' : ''}${scriptPreloadTag ? scriptPreloadTag + '\\n ' : ''}${imagePreloadTags ? imagePreloadTags + '\\n ' : ''}${fontPreloadTags ? fontPreloadTags + '\\n ' : ''}${libraryTags.headCSS ? libraryTags.headCSS + '\\n ' : ''}${libraryTags.headJS ? libraryTags.headJS + '\\n ' : ''}${rendered.meta}\n ${configInlineScript}${cmsInlineScript}${clientDataScripts}<style id=\"meno-styles\">${styleContent}</style>\n</head>\n<body>\n <div id=\"root\">\n ${rendered.html}\n </div>\n ${clientScript}${componentScript}${libraryTags.bodyEndJS ? '\\n ' + libraryTags.bodyEndJS : ''}${liveReloadScript ? '\\n ' + liveReloadScript : ''}${scrollHandlerScript ? '\\n ' + scrollHandlerScript : ''}\n</body>\n</html>`;\n\n // Return based on mode\n if (returnSeparateJS) {\n return {\n html: htmlDocument,\n javascript: externalJavaScript\n };\n }\n\n return htmlDocument;\n}\n", "/**\n * File System CMS Provider\n * Implements CMSProvider for loading CMS data from the file system\n */\n\nimport { existsSync, readdirSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport type { CMSProvider, CMSSchemaInfo } from '../../shared/interfaces/contentProvider';\nimport type { CMSSchema, CMSItem } from '../../shared/types';\nimport { validateCMSItem } from '../../shared/validation/validators';\nimport { isSafePathSegment, isValidIdentifier } from '../../shared/pathSecurity';\nimport { readJsonFile, fileExists } from '../runtime';\n\n/**\n * Load JSON file content from disk\n * Logs a warning if JSON parsing fails (helps debug malformed files)\n */\nasync function loadJSONFile(filePath: string): Promise<unknown | null> {\n try {\n if (await fileExists(filePath)) {\n return await readJsonFile(filePath);\n }\n return null;\n } catch (error) {\n console.warn(`[CMS] Failed to parse JSON at ${filePath}:`, error instanceof Error ? error.message : error);\n return null;\n }\n}\n\n/**\n * Normalize a raw CMS item by adding _slug and _filename fields\n */\nfunction normalizeItem(content: unknown, filename: string): CMSItem {\n return {\n ...content as CMSItem,\n _slug: filename,\n _filename: filename,\n };\n}\n\n/**\n * FileSystemCMSProvider\n * Loads CMS schemas from template files in root templates/ dir and CMS items from cms/<collection>/<slug>.json\n */\nexport class FileSystemCMSProvider implements CMSProvider {\n private schemaCache: Map<string, CMSSchemaInfo> | null = null;\n\n constructor(\n private templatesDir: string, // e.g., './templates' - CMS template pages\n private cmsDir: string // e.g., './cms' - items stored here\n ) {}\n\n /**\n * Validate collection name to prevent path traversal attacks\n * @throws Error if collection name is invalid\n */\n private validateCollection(collection: string): void {\n if (!isValidIdentifier(collection)) {\n throw new Error(`Invalid collection name: \"${collection}\". Collection names must contain only letters, numbers, hyphens, and underscores.`);\n }\n }\n\n /**\n * Validate filename to prevent path traversal attacks\n * @throws Error if filename is invalid\n */\n private validateFilename(filename: string): void {\n if (!isSafePathSegment(filename)) {\n throw new Error(`Invalid filename: \"${filename}\". Filenames cannot contain path separators or traversal sequences.`);\n }\n }\n\n /**\n * Load all CMS schemas from page files with source: 'cms' in templates/\n */\n async getAllSchemas(): Promise<Map<string, CMSSchemaInfo>> {\n // Return cached if available\n if (this.schemaCache) {\n return this.schemaCache;\n }\n\n const schemas = new Map<string, CMSSchemaInfo>();\n\n if (!existsSync(this.templatesDir)) {\n return schemas;\n }\n\n const files = readdirSync(this.templatesDir);\n const jsonFiles = files.filter(f => f.endsWith('.json'));\n\n const results = await Promise.all(\n jsonFiles.map(async file => {\n const filePath = join(this.templatesDir, file);\n const content = await loadJSONFile(filePath);\n return { filePath, content };\n })\n );\n\n for (const { filePath, content } of results) {\n if (\n content &&\n typeof content === 'object' &&\n 'meta' in content &&\n typeof (content as Record<string, unknown>).meta === 'object'\n ) {\n const meta = (content as Record<string, unknown>).meta as Record<string, unknown>;\n\n if (meta.source === 'cms' && meta.cms) {\n const schema = meta.cms as CMSSchema;\n schemas.set(schema.id, {\n schema,\n pagePath: filePath,\n });\n }\n }\n }\n\n this.schemaCache = schemas;\n return schemas;\n }\n\n /**\n * Load all items for a collection\n */\n async getItems(collection: string): Promise<CMSItem[]> {\n this.validateCollection(collection);\n const collectionDir = join(this.cmsDir, collection);\n\n if (!existsSync(collectionDir)) {\n return [];\n }\n\n const files = readdirSync(collectionDir);\n const jsonFiles = files.filter(f => f.endsWith('.json'));\n\n const results = await Promise.all(\n jsonFiles.map(async file => {\n const filePath = join(collectionDir, file);\n const content = await loadJSONFile(filePath);\n return { file, filePath, content };\n })\n );\n\n const items: CMSItem[] = [];\n for (const { file, filePath, content } of results) {\n if (content && typeof content === 'object') {\n const filename = file.replace('.json', '');\n const item = normalizeItem(content, filename);\n\n const validation = validateCMSItem(item);\n if (validation.valid) {\n items.push(validation.data);\n } else {\n console.warn(`Invalid CMS item at ${filePath}:`, validation.errors);\n }\n }\n }\n\n return items;\n }\n\n /**\n * Get single item by slug (backward compat - slug is actually filename)\n * @deprecated Use getItemByFilename instead\n */\n async getItemBySlug(collection: string, slug: string): Promise<CMSItem | null> {\n return this.getItemByFilename(collection, slug);\n }\n\n /**\n * Get single item by filename\n */\n async getItemByFilename(collection: string, filename: string): Promise<CMSItem | null> {\n this.validateCollection(collection);\n this.validateFilename(filename);\n const filePath = join(this.cmsDir, collection, `${filename}.json`);\n const content = await loadJSONFile(filePath);\n\n if (!content || typeof content !== 'object') {\n return null;\n }\n\n const item = normalizeItem(content, filename);\n const validation = validateCMSItem(item);\n\n if (validation.valid) {\n return validation.data;\n }\n\n console.warn(`Invalid CMS item at ${filePath}:`, validation.errors);\n return null;\n }\n\n /**\n * Get single item by ID\n */\n async getItemById(collection: string, id: string): Promise<CMSItem | null> {\n const items = await this.getItems(collection);\n return items.find(item => item._id === id) || null;\n }\n\n /**\n * Save item to file system\n * Uses _filename for file path (stable, doesn't change when slug changes)\n */\n async saveItem(collection: string, item: CMSItem): Promise<void> {\n this.validateCollection(collection);\n const { writeFile } = await import('fs/promises');\n\n // Get schema\n const schemas = await this.getAllSchemas();\n const schemaInfo = schemas.get(collection);\n\n if (!schemaInfo) {\n throw new Error(`Unknown collection: ${collection}`);\n }\n\n // Use _filename for file path (new behavior)\n // Falls back to slugField for backward compatibility with items without _filename\n let filename: string;\n\n if (item._filename) {\n filename = item._filename;\n } else {\n // Legacy fallback: use slug field value (may break for i18n slugs)\n const slugField = schemaInfo.schema.slugField;\n const slugValue = item[slugField];\n filename = typeof slugValue === 'string' ? slugValue : String(slugValue);\n }\n\n if (!filename || filename === '[object Object]') {\n throw new Error('Missing _filename field. Items must have _filename set on creation.');\n }\n\n // Validate filename to prevent path traversal\n this.validateFilename(filename);\n\n // Ensure collection directory exists\n const collectionDir = join(this.cmsDir, collection);\n if (!existsSync(collectionDir)) {\n mkdirSync(collectionDir, { recursive: true });\n }\n\n // Remove internal _slug field before saving (keep _filename in file for persistence)\n const { _slug, ...itemData } = item;\n\n const filePath = join(collectionDir, `${filename}.json`);\n await writeFile(filePath, JSON.stringify(itemData, null, 2), 'utf-8');\n }\n\n /**\n * Delete item by filename (or slug for backward compat)\n */\n async deleteItem(collection: string, filename: string): Promise<void> {\n this.validateCollection(collection);\n this.validateFilename(filename);\n const { unlink } = await import('fs/promises');\n const filePath = join(this.cmsDir, collection, `${filename}.json`);\n\n if (existsSync(filePath)) {\n await unlink(filePath);\n }\n }\n\n /**\n * Clear schema cache (useful when pages are modified)\n */\n clearSchemaCache(): void {\n this.schemaCache = null;\n }\n\n /**\n * Save a new collection schema by creating a page file in templates/\n */\n async saveSchema(collectionId: string, pageData: unknown): Promise<void> {\n if (!isValidIdentifier(collectionId)) {\n throw new Error(`Invalid collection ID: \"${collectionId}\". Collection IDs must contain only letters, numbers, hyphens, and underscores.`);\n }\n const { writeFile, mkdir } = await import('fs/promises');\n\n // Ensure templates directory exists\n if (!existsSync(this.templatesDir)) {\n await mkdir(this.templatesDir, { recursive: true });\n }\n\n // Create page file path in templates/ subdirectory\n const pageFilePath = join(this.templatesDir, `${collectionId}.json`);\n\n // Check if file already exists\n if (existsSync(pageFilePath)) {\n throw new Error(`Page file already exists: templates/${collectionId}.json`);\n }\n\n // Write the page file\n await writeFile(pageFilePath, JSON.stringify(pageData, null, 2), 'utf-8');\n\n // Create the CMS collection directory\n const collectionDir = join(this.cmsDir, collectionId);\n if (!existsSync(collectionDir)) {\n await mkdir(collectionDir, { recursive: true });\n }\n\n // Clear the schema cache so the new collection is detected\n this.clearSchemaCache();\n }\n\n /**\n * Update an existing collection schema\n * Preserves the root component tree, only updates meta.cms\n */\n async updateSchema(collectionId: string, updates: Partial<CMSSchema>): Promise<void> {\n if (!isValidIdentifier(collectionId)) {\n throw new Error(`Invalid collection ID: \"${collectionId}\". Collection IDs must contain only letters, numbers, hyphens, and underscores.`);\n }\n const { readFile, writeFile } = await import('fs/promises');\n\n const pageFilePath = join(this.templatesDir, `${collectionId}.json`);\n\n if (!existsSync(pageFilePath)) {\n throw new Error(`Collection not found: ${collectionId}`);\n }\n\n // Read existing page data\n const content = await readFile(pageFilePath, 'utf-8');\n const pageData = JSON.parse(content) as {\n meta: { cms: CMSSchema; [key: string]: unknown };\n [key: string]: unknown;\n };\n\n // Update only the cms schema in meta, preserving id\n pageData.meta.cms = {\n ...pageData.meta.cms,\n ...updates,\n id: collectionId, // ID cannot be changed\n };\n\n await writeFile(pageFilePath, JSON.stringify(pageData, null, 2), 'utf-8');\n this.clearSchemaCache();\n }\n}\n", "import { existsSync } from 'fs';\nimport { rename } from 'fs/promises';\nimport { join } from 'path';\nimport { projectPaths } from './projectContext';\n\n/**\n * Auto-migrate CMS templates from pages/templates/ to root templates/\n * Only runs if pages/templates/ exists and root templates/ does not\n */\nexport async function migrateTemplatesDirectory(): Promise<void> {\n const oldDir = join(projectPaths.pages(), 'templates');\n const newDir = projectPaths.templates();\n\n // Nothing to migrate\n if (!existsSync(oldDir)) return;\n\n // Don't clobber existing root templates/\n if (existsSync(newDir)) return;\n\n await rename(oldDir, newDir);\n console.log('Migrated CMS templates: pages/templates/ \u2192 templates/');\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * JSON Loader\n * Utilities for loading and parsing JSON files\n */\n\nimport { existsSync, readdirSync } from 'fs';\nimport type { z } from 'zod';\nimport type { ComponentDefinition } from '../shared/types';\nimport type { BreakpointConfig, BreakpointConfigInput, BreakpointEntry } from '../shared/breakpoints';\nimport { readTextFile, fileExists } from './runtime';\nimport { DEFAULT_BREAKPOINTS, normalizeBreakpointConfig } from '../shared/breakpoints';\nimport type { ResponsiveScales, BreakpointScales } from '../shared/responsiveScaling';\nimport { DEFAULT_RESPONSIVE_SCALES } from '../shared/responsiveScaling';\nimport type { I18nConfig } from '../shared/types/components';\nimport { DEFAULT_I18N_CONFIG, migrateI18nConfig } from '../shared/i18n';\nimport type { PrefetchConfig } from '../shared/types/prefetch';\nimport { DEFAULT_PREFETCH_CONFIG } from '../shared/types/prefetch';\nimport { validateComponentDefinition } from '../shared/validation/validators';\nimport { attemptJsonRepair } from '../shared/jsonRepair';\nimport { projectPaths } from './projectContext';\n\n/**\n * Load JSON file from a file path\n */\nexport async function loadJSONFile(filePath: string): Promise<string | null> {\n try {\n if (await fileExists(filePath)) {\n return await readTextFile(filePath);\n }\n return null;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Parse JSON content\n */\nexport function parseJSON<T = unknown>(content: string): T {\n return JSON.parse(content);\n}\n\n/**\n * Parse and validate JSON content against a zod schema\n * Returns null on validation failure (for backward compatibility)\n */\nexport function parseAndValidateJSON<T>(\n content: string,\n schema: z.ZodType<T>\n): T | null {\n try {\n const parsed = JSON.parse(content);\n const result = schema.safeParse(parsed);\n if (result.success) {\n return result.data;\n }\n // Return parsed value anyway for backward compatibility\n return parsed as T;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Load and parse JSON file\n */\nexport async function loadAndParseJSON<T = any>(filePath: string): Promise<T | null> {\n const content = await loadJSONFile(filePath);\n if (!content) return null;\n \n try {\n return parseJSON<T>(content);\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Load all JSON files from a directory\n */\nexport async function loadJSONDirectory(\n dirPath: string\n): Promise<Map<string, string>> {\n const files = new Map<string, string>();\n \n if (!existsSync(dirPath)) {\n return files;\n }\n \n const fileList = readdirSync(dirPath);\n \n const jsonFiles = fileList.filter(f => f.endsWith('.json'));\n const results = await Promise.all(\n jsonFiles.map(async file => {\n const name = file.replace('.json', '');\n const content = await loadJSONFile(`${dirPath}/${file}`);\n return content ? { name, content } : null;\n })\n );\n for (const r of results) {\n if (r) files.set(r.name, r.content);\n }\n \n return files;\n}\n\n/**\n * Load file content as text (for .js, .css, etc.)\n */\nasync function loadFileAsText(filePath: string): Promise<string | null> {\n try {\n if (await fileExists(filePath)) {\n return await readTextFile(filePath);\n }\n return null;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Component with category metadata from folder structure\n */\nexport interface ComponentWithCategory extends ComponentDefinition {\n _category?: string;\n _relativePath?: string;\n}\n\nexport interface ComponentLoadDiagnostic {\n componentName: string;\n description: string;\n line: number;\n column: number;\n}\n\nexport interface ComponentLoadResult {\n component: ComponentWithCategory | null;\n warning?: ComponentLoadDiagnostic;\n error?: ComponentLoadDiagnostic;\n}\n\nexport interface ComponentDirectoryResult {\n components: Map<string, ComponentWithCategory>;\n warnings: ComponentLoadDiagnostic[];\n errors: ComponentLoadDiagnostic[];\n}\n\n/**\n * Load a single component from a file path\n * @internal\n */\nasync function loadSingleComponent(\n filePath: string,\n componentName: string,\n category?: string\n): Promise<ComponentLoadResult> {\n const content = await loadJSONFile(filePath);\n if (!content) return { component: null };\n\n const fileName = `${componentName}.json`;\n const repairResult = attemptJsonRepair(content);\n\n if (!repairResult.success) {\n return {\n component: null,\n error: {\n componentName,\n description: repairResult.error!.message,\n line: repairResult.error!.line,\n column: repairResult.error!.column,\n },\n };\n }\n\n const warning: ComponentLoadDiagnostic | undefined = repairResult.repaired\n ? {\n componentName,\n description: repairResult.repairDescription!,\n line: repairResult.repairLine ?? 1,\n column: repairResult.repairColumn ?? 1,\n }\n : undefined;\n\n try {\n const parsed = repairResult.data as ComponentDefinition;\n\n // Validate component definition (logs warnings but doesn't fail - graceful degradation)\n const validationResult = validateComponentDefinition(parsed);\n if (!validationResult.valid) {\n console.warn(`[jsonLoader] Component validation failed for ${componentName}:`,\n validationResult.errors.map(e => `${e.path}: ${e.message}`).join('; '));\n }\n const componentDef: ComponentWithCategory = validationResult.valid ? validationResult.data : parsed;\n\n // Determine the directory where the component file is located\n const dirPath = filePath.substring(0, filePath.lastIndexOf('/'));\n\n // Load .js and .css files in parallel\n const jsFilePath = `${dirPath}/${componentName}.js`;\n const cssFilePath = `${dirPath}/${componentName}.css`;\n const [jsContent, cssContent] = await Promise.all([\n loadFileAsText(jsFilePath),\n loadFileAsText(cssFilePath),\n ]);\n\n if (!componentDef.component) {\n componentDef.component = {};\n }\n\n // If .js file exists, use its content for javascript field\n // This takes precedence over any javascript field in the JSON\n if (jsContent) {\n componentDef.component.javascript = jsContent;\n\n // Auto-enable defineVars when .js file exists (unless explicitly set to false)\n if (componentDef.component.defineVars === undefined) {\n componentDef.component.defineVars = true;\n }\n }\n\n // If .css file exists, use its content for css field\n // This takes precedence over any css field in the JSON\n if (cssContent) {\n componentDef.component.css = cssContent;\n }\n\n // Add category metadata from folder structure\n if (category) {\n componentDef._category = category;\n componentDef._relativePath = `${category}/${componentName}`;\n }\n\n return { component: componentDef, warning };\n } catch (error) {\n return { component: null };\n }\n}\n\n/**\n * Load all component definitions from components directory (recursive)\n * Scans subdirectories as category folders. Component names must be unique across all folders.\n *\n * Folder structure:\n * - /components/Button.json \u2192 name: \"Button\", category: undefined\n * - /components/ui/Card.json \u2192 name: \"Card\", category: \"ui\"\n *\n * @param dirPath - Root components directory path\n * @returns Map of component names to ComponentDefinition with category metadata\n */\nexport async function loadComponentDirectory(\n dirPath: string = './components'\n): Promise<ComponentDirectoryResult> {\n const components = new Map<string, ComponentWithCategory>();\n const warnings: string[] = [];\n const errors: string[] = [];\n\n if (!existsSync(dirPath)) {\n return { components, warnings, errors };\n }\n\n const entries = readdirSync(dirPath, { withFileTypes: true });\n\n // Collect all component entries to load in parallel\n const loadEntries: { filePath: string; componentName: string; category?: string }[] = [];\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const category = entry.name;\n const categoryPath = `${dirPath}/${category}`;\n const categoryFiles = readdirSync(categoryPath);\n\n for (const file of categoryFiles) {\n if (file.endsWith('.json')) {\n loadEntries.push({\n filePath: `${categoryPath}/${file}`,\n componentName: file.replace('.json', ''),\n category,\n });\n }\n }\n } else if (entry.name.endsWith('.json')) {\n loadEntries.push({\n filePath: `${dirPath}/${entry.name}`,\n componentName: entry.name.replace('.json', ''),\n });\n }\n }\n\n // Load all components in parallel\n const results = await Promise.all(\n loadEntries.map(async e => ({\n ...e,\n result: await loadSingleComponent(e.filePath, e.componentName, e.category),\n }))\n );\n\n // Insert into map preserving listing order, with duplicate detection\n for (const { componentName, category, result } of results) {\n if (result.warning) warnings.push(result.warning);\n if (result.error) errors.push(result.error);\n if (!result.component) continue;\n if (components.has(componentName)) {\n const location = category ? `category \"${category}\"` : 'root level';\n console.warn(`[jsonLoader] Duplicate component name \"${componentName}\" found at ${location}. Skipping.`);\n continue;\n }\n components.set(componentName, result.component);\n }\n\n return { components, warnings, errors };\n}\n\n/**\n * Map page filename to route path\n */\nexport function mapPageNameToPath(pageName: string): string {\n return pageName === 'index' ? '/' : `/${pageName}`;\n}\n\n/**\n * Map route path to page filename\n */\nexport function mapPathToPageName(path: string): string {\n return path === '/' ? 'index' : path.substring(1);\n}\n\n// Breakpoint types are now imported from shared/breakpoints\n\n/**\n * Load and validate breakpoint configuration from project.config.json\n */\nexport async function loadBreakpointConfig(): Promise<BreakpointConfig> {\n try {\n const configContent = await loadJSONFile(projectPaths.config());\n if (configContent) {\n const config = parseJSON<{ breakpoints?: BreakpointConfigInput }>(configContent);\n\n if (config.breakpoints && typeof config.breakpoints === 'object') {\n // Preserve all breakpoints from config, filtering out invalid values\n const validInput: BreakpointConfigInput = {};\n for (const [key, value] of Object.entries(config.breakpoints)) {\n if (typeof value === 'number' && value > 0) {\n // Legacy format: number\n validInput[key] = value;\n } else if (typeof value === 'object' && value !== null) {\n // New format: object with breakpoint and optional previewPoint\n const entry = value as BreakpointEntry;\n if (typeof entry.breakpoint === 'number' && entry.breakpoint > 0) {\n validInput[key] = {\n breakpoint: entry.breakpoint,\n previewPoint: typeof entry.previewPoint === 'number' && entry.previewPoint > 0\n ? entry.previewPoint\n : entry.breakpoint,\n };\n }\n }\n }\n\n // If we have valid breakpoints, return them normalized; otherwise fall back to defaults\n if (Object.keys(validInput).length > 0) {\n return normalizeBreakpointConfig(validInput);\n }\n }\n }\n } catch (error) {\n }\n\n return { ...DEFAULT_BREAKPOINTS };\n}\n\n/**\n * Get breakpoint config synchronously (for cases where async is not available)\n * Uses cached value if available, otherwise defaults\n */\nlet cachedBreakpoints: BreakpointConfig | null = null;\n\nexport function getBreakpointConfig(): BreakpointConfig {\n if (cachedBreakpoints) {\n return cachedBreakpoints;\n }\n return DEFAULT_BREAKPOINTS;\n}\n\nexport function setBreakpointConfig(config: BreakpointConfig): void {\n cachedBreakpoints = config;\n}\n\n/**\n * Deep merge scale categories, preserving user-defined breakpoints\n * while filling in missing values from defaults\n */\nfunction mergeScaleCategory(\n userScales: BreakpointScales | undefined,\n defaultScales: BreakpointScales | undefined\n): BreakpointScales | undefined {\n if (!userScales && !defaultScales) return undefined;\n if (!userScales) return defaultScales ? { ...defaultScales } : undefined;\n if (!defaultScales) return { ...userScales };\n\n // User scales take precedence, but include defaults for breakpoints not specified\n return {\n ...defaultScales,\n ...userScales,\n };\n}\n\n/**\n * Load and validate responsive scales configuration from project.config.json\n * Supports dynamic breakpoints - scales are keyed by breakpoint name\n */\nexport async function loadResponsiveScalesConfig(): Promise<ResponsiveScales> {\n try {\n const configContent = await loadJSONFile(projectPaths.config());\n if (configContent) {\n const config = parseJSON<{ responsiveScales?: Partial<ResponsiveScales> }>(configContent);\n\n if (config.responsiveScales && typeof config.responsiveScales === 'object') {\n // Deep merge scale categories to preserve user breakpoint definitions\n // while filling in missing values from defaults\n const scales: ResponsiveScales = {\n enabled: config.responsiveScales.enabled ?? DEFAULT_RESPONSIVE_SCALES.enabled,\n baseReference: config.responsiveScales.baseReference ?? DEFAULT_RESPONSIVE_SCALES.baseReference,\n fontSize: mergeScaleCategory(\n config.responsiveScales.fontSize as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.fontSize\n ),\n padding: mergeScaleCategory(\n config.responsiveScales.padding as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.padding\n ),\n margin: mergeScaleCategory(\n config.responsiveScales.margin as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.margin\n ),\n gap: mergeScaleCategory(\n config.responsiveScales.gap as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.gap\n ),\n };\n\n return scales;\n }\n }\n } catch (error) {\n }\n\n return { ...DEFAULT_RESPONSIVE_SCALES };\n}\n\n/**\n * Get responsive scales config synchronously (for cases where async is not available)\n * Uses cached value if available, otherwise defaults\n */\nlet cachedResponsiveScales: ResponsiveScales | null = null;\n\nexport function getResponsiveScalesConfig(): ResponsiveScales {\n if (cachedResponsiveScales) {\n return cachedResponsiveScales;\n }\n return { ...DEFAULT_RESPONSIVE_SCALES };\n}\n\nexport function setResponsiveScalesConfig(config: ResponsiveScales): void {\n cachedResponsiveScales = config;\n}\n\n/**\n * Load and validate i18n configuration from project.config.json\n * Automatically migrates old string[] format to new LocaleConfig[] format\n */\nexport async function loadI18nConfig(): Promise<I18nConfig> {\n try {\n const configContent = await loadJSONFile(projectPaths.config());\n if (configContent) {\n const config = parseJSON<{ i18n?: unknown }>(configContent);\n return migrateI18nConfig(config.i18n);\n }\n } catch (error) {\n // Fall through to default\n }\n\n return { ...DEFAULT_I18N_CONFIG };\n}\n\n/**\n * Get i18n config synchronously (for cases where async is not available)\n * Uses cached value if available, otherwise defaults\n */\nlet cachedI18nConfig: I18nConfig | null = null;\n\nexport function getI18nConfig(): I18nConfig {\n if (cachedI18nConfig) {\n return cachedI18nConfig;\n }\n return { ...DEFAULT_I18N_CONFIG };\n}\n\nexport function setI18nConfig(config: I18nConfig): void {\n cachedI18nConfig = config;\n}\n\n/**\n * Icons configuration from project.config.json\n */\nexport interface IconsConfig {\n favicon?: string;\n appleTouchIcon?: string;\n}\n\n/**\n * Load icons configuration from project.config.json\n */\nexport async function loadIconsConfig(): Promise<IconsConfig> {\n try {\n const configContent = await loadJSONFile(projectPaths.config());\n if (configContent) {\n const config = parseJSON<{ icons?: IconsConfig }>(configContent);\n if (config.icons && typeof config.icons === 'object') {\n return config.icons;\n }\n }\n } catch (error) {\n // Fall through to default\n }\n\n return {};\n}\n\n/**\n * Load prefetch configuration from project.config.json\n * Used for production SSR sites to enable link prefetching\n */\nexport async function loadPrefetchConfig(): Promise<PrefetchConfig> {\n try {\n const configContent = await loadJSONFile(projectPaths.config());\n if (configContent) {\n const config = parseJSON<{ prefetch?: Partial<PrefetchConfig> }>(configContent);\n if (config.prefetch && typeof config.prefetch === 'object') {\n // Merge with defaults to ensure all required fields are present\n return {\n ...DEFAULT_PREFETCH_CONFIG,\n ...config.prefetch,\n };\n }\n }\n } catch (error) {\n // Fall through to default\n }\n\n return { ...DEFAULT_PREFETCH_CONFIG };\n}\n\n", "/**\n * JSON Repair Utility\n * Attempts to fix common JSON syntax errors (trailing commas, missing commas)\n */\n\nexport interface JsonParseErrorInfo {\n message: string;\n line: number;\n column: number;\n}\n\nexport interface JsonRepairResult {\n success: boolean;\n data?: unknown;\n repaired: boolean;\n repairDescription?: string;\n repairLine?: number;\n repairColumn?: number;\n error?: JsonParseErrorInfo;\n}\n\n/**\n * Extract line/column from a JSON SyntaxError\n */\nexport function parseJsonError(error: unknown, content: string): JsonParseErrorInfo {\n if (!(error instanceof SyntaxError)) {\n return { message: String(error), line: 1, column: 1 };\n }\n\n const msg = error.message;\n\n // Bun/V8: \"JSON Parse error: Expected '}'\" or \"Unexpected token } in JSON at position 42\"\n // Try to extract position from message\n const posMatch = msg.match(/at position (\\d+)/i);\n if (posMatch) {\n const pos = parseInt(posMatch[1], 10);\n const { line, column } = offsetToLineColumn(content, pos);\n return { message: msg, line, column };\n }\n\n // Bun format: \"JSON Parse error: ...\"\n // Try line number extraction\n const lineMatch = msg.match(/line (\\d+)/i);\n const colMatch = msg.match(/column (\\d+)/i);\n if (lineMatch) {\n return {\n message: msg,\n line: parseInt(lineMatch[1], 10),\n column: colMatch ? parseInt(colMatch[1], 10) : 1,\n };\n }\n\n return { message: msg, line: 1, column: 1 };\n}\n\nfunction offsetToLineColumn(content: string, offset: number): { line: number; column: number } {\n let line = 1;\n let lastNewline = -1;\n for (let i = 0; i < offset && i < content.length; i++) {\n if (content[i] === '\\n') {\n line++;\n lastNewline = i;\n }\n }\n return { line, column: offset - lastNewline };\n}\n\n/**\n * Attempt to repair common JSON errors\n */\nexport function attemptJsonRepair(content: string): JsonRepairResult {\n // Try parsing as-is first\n try {\n const data = JSON.parse(content);\n return { success: true, repaired: false, data };\n } catch (firstError) {\n // Continue to repair attempts\n }\n\n // Attempt: remove trailing commas (e.g., {a: 1,} or [1,])\n {\n const fixed = content.replace(/,\\s*([\\]}])/g, '$1');\n try {\n const data = JSON.parse(fixed);\n // Find where we removed a comma for the description\n const trailingCommaMatch = content.match(/,\\s*([\\]}])/);\n const pos = trailingCommaMatch ? content.indexOf(trailingCommaMatch[0]) : 0;\n const { line, column } = offsetToLineColumn(content, pos);\n return {\n success: true,\n repaired: true,\n data,\n repairDescription: `removed trailing comma at line ${line}`,\n repairLine: line,\n repairColumn: column,\n };\n } catch {\n // Continue\n }\n }\n\n // Attempt: insert missing commas between properties/elements\n // Pattern: value on one line, key/value on next line without comma\n // e.g., \"foo\": \"bar\"\\n \"baz\": ... or \"value\"\\n \"next\"\n {\n const lines = content.split('\\n');\n let fixed = '';\n let repairLine = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trimEnd();\n const nextLine = i + 1 < lines.length ? lines[i + 1] : null;\n\n if (nextLine !== null) {\n const nextTrimmed = nextLine.trimStart();\n // Check if current line ends with a value (not comma, not opening bracket, not colon)\n // and next line starts with a key or value\n const needsComma =\n /[\"\\d\\w\\]}\\-]$/.test(trimmed) &&\n !trimmed.endsWith(',') &&\n !trimmed.endsWith('{') &&\n !trimmed.endsWith('[') &&\n !trimmed.endsWith(':') &&\n (nextTrimmed.startsWith('\"') || nextTrimmed.startsWith('{') || nextTrimmed.startsWith('[') || /^\\d/.test(nextTrimmed) || nextTrimmed === 'true' || nextTrimmed === 'false' || nextTrimmed === 'null');\n\n if (needsComma) {\n fixed += trimmed + ',\\n';\n if (repairLine === 0) repairLine = i + 1;\n } else {\n fixed += line + '\\n';\n }\n } else {\n fixed += line;\n }\n }\n\n try {\n const data = JSON.parse(fixed);\n return {\n success: true,\n repaired: true,\n data,\n repairDescription: `auto-fixed missing comma at line ${repairLine}`,\n repairLine,\n repairColumn: 1,\n };\n } catch {\n // Continue\n }\n }\n\n // All repairs failed - return structured error\n let errorInfo: JsonParseErrorInfo;\n try {\n JSON.parse(content);\n errorInfo = { message: 'Unknown error', line: 1, column: 1 };\n } catch (e) {\n errorInfo = parseJsonError(e, content);\n }\n\n return { success: false, repaired: false, error: errorInfo };\n}\n\n/**\n * Format a user-friendly error message for JSON parse failures\n */\nexport function formatJsonErrorMessage(fileName: string, error: JsonParseErrorInfo): string {\n return `${fileName}: JSON syntax error at line ${error.line}, column ${error.column} \u2014 ${error.message}`;\n}\n\n/**\n * Format a message describing a successful JSON repair\n */\nexport function formatJsonRepairMessage(fileName: string, description: string): string {\n return `${fileName}: ${description}. Save to apply fix.`;\n}\n", "/**\n * Base class for services that lazy-load, cache, and deduplicate config file access.\n *\n * Subclasses implement `performLoad()` and optionally `getDefaultConfig()`.\n */\nexport abstract class CachedConfigLoader<T> {\n private config: T | null = null;\n private loadingPromise: Promise<T> | null = null;\n\n /**\n * Load config, returning cached value if available.\n * Concurrent calls share the same loading promise.\n */\n async load(): Promise<T> {\n if (this.config) {\n return this.config;\n }\n\n if (this.loadingPromise) {\n return this.loadingPromise;\n }\n\n this.loadingPromise = this.performLoad();\n this.config = await this.loadingPromise;\n this.loadingPromise = null;\n\n return this.config;\n }\n\n /**\n * Override in subclass to load config from disk.\n */\n protected abstract performLoad(): Promise<T>;\n\n /**\n * Reset cached value so the next `load()` re-reads from disk.\n */\n clearCache(): void {\n this.config = null;\n }\n\n /**\n * Update the cached value directly (used after saving to disk).\n */\n protected setCache(config: T): void {\n this.config = config;\n }\n\n /**\n * Peek at the current cached value (null if not loaded).\n */\n protected getCache(): T | null {\n return this.config;\n }\n}\n", "/**\n * Color Service\n * Manages loading and caching of color variables and themes from colors.json\n */\n\nimport { loadJSONFile, parseJSON } from '../jsonLoader';\nimport { projectPaths } from '../projectContext';\nimport type { ColorVariables, ColorVariableEntry, ThemeConfig, ThemeEntry } from '../../shared/types';\nimport { resolvePaletteColor } from '../../shared/types';\nimport { CachedConfigLoader } from './CachedConfigLoader';\nimport { writeFile } from '../runtime';\n\nexport class ColorService extends CachedConfigLoader<ThemeConfig> {\n /**\n * Load theme configuration from colors.json\n */\n async loadThemeConfig(): Promise<ThemeConfig> {\n return this.load();\n }\n\n /**\n * Perform the actual loading from file\n */\n protected async performLoad(): Promise<ThemeConfig> {\n try {\n const content = await loadJSONFile(projectPaths.colors());\n if (content) {\n const data = parseJSON(content);\n if (data && typeof data === 'object' && 'themes' in data && 'default' in data) {\n return data as ThemeConfig;\n }\n }\n } catch (error) {\n console.warn('Failed to load colors.json:', error);\n }\n\n // Return default theme config if file not found or invalid\n return this.getDefaultThemeConfig();\n }\n\n /**\n * Get default theme configuration\n */\n private getDefaultThemeConfig(): ThemeConfig {\n return {\n default: 'dark',\n themes: {\n dark: {\n label: 'Dark',\n colors: {\n 'primary': '#007acc',\n 'primary-light': '#0099ff',\n 'primary-dark': '#005a99',\n 'secondary': '#6c757d',\n 'success': '#28a745',\n 'warning': '#ffc107',\n 'danger': '#dc3545',\n 'error': '#d32f2f',\n 'info': '#17a2b8',\n 'light': '#f8f9fa',\n 'dark': '#343a40',\n 'text': '#cccccc',\n 'text-dark': '#1e1e1e',\n 'background': '#1e1e1e',\n 'background-light': '#252526',\n 'border': '#444444',\n 'border-light': '#d0d0d0',\n },\n },\n light: {\n label: 'Light',\n colors: {\n 'primary': '#0066ff',\n 'primary-light': '#3385ff',\n 'primary-dark': '#0052cc',\n 'secondary': '#888888',\n 'success': '#22c55e',\n 'warning': '#f59e0b',\n 'danger': '#ef4444',\n 'error': '#dc2626',\n 'info': '#06b6d4',\n 'light': '#f8f9fa',\n 'dark': '#1f2937',\n 'text': '#1f2937',\n 'text-dark': '#ffffff',\n 'background': '#ffffff',\n 'background-light': '#f3f4f6',\n 'border': '#d1d5db',\n 'border-light': '#e5e7eb',\n },\n },\n },\n };\n }\n\n /**\n * Get minimal theme configuration (for new file creation)\n */\n private getMinimalConfig(): ThemeConfig {\n return {\n default: 'default',\n themes: {\n default: {\n label: 'Default',\n colors: {\n 'background': '#1e1e1e',\n 'text': '#cccccc',\n },\n },\n },\n };\n }\n\n /**\n * Get config with status info (for editor UI)\n * Distinguishes between missing file, invalid JSON, and valid config\n */\n async getConfigWithStatus(): Promise<{\n status: 'valid' | 'missing' | 'invalid';\n config: ThemeConfig;\n error?: string;\n filePath: string;\n }> {\n const filePath = projectPaths.colors();\n try {\n const content = await loadJSONFile(filePath);\n if (!content) {\n return { status: 'missing', config: this.getMinimalConfig(), filePath };\n }\n const data = parseJSON(content);\n if (data && typeof data === 'object' && 'themes' in data && 'default' in data) {\n return { status: 'valid', config: data as ThemeConfig, filePath };\n }\n return { status: 'invalid', config: this.getMinimalConfig(), error: 'Invalid structure: missing \"themes\" or \"default\" property', filePath };\n } catch (error) {\n return {\n status: 'invalid',\n config: this.getMinimalConfig(),\n error: error instanceof Error ? error.message : 'Parse error',\n filePath,\n };\n }\n }\n\n /**\n * Get colors for a specific theme (or default if not found)\n */\n async getThemeColors(themeName?: string): Promise<ColorVariables> {\n const config = await this.loadThemeConfig();\n const theme = themeName && config.themes[themeName] ? config.themes[themeName] : config.themes[config.default];\n const resolvedColors: Record<string, string> = {};\n for (const [name, value] of Object.entries(theme.colors)) {\n resolvedColors[name] = resolvePaletteColor(value, config.palette);\n }\n return { colors: resolvedColors };\n }\n\n /**\n * Load color variables from colors.json (for backward compatibility)\n */\n async loadColors(): Promise<ColorVariables> {\n return this.getThemeColors();\n }\n\n /**\n * Get all available themes\n */\n async getAvailableThemes(): Promise<ThemeEntry[]> {\n const config = await this.loadThemeConfig();\n return Object.entries(config.themes).map(([name, theme]) => ({\n name,\n label: theme.label,\n }));\n }\n\n /**\n * Get default theme name\n */\n async getDefaultTheme(): Promise<string> {\n const config = await this.loadThemeConfig();\n return config.default;\n }\n\n /**\n * Get all color variables as entries for a theme\n */\n async getColorEntries(themeName?: string): Promise<ColorVariableEntry[]> {\n const colors = await this.getThemeColors(themeName);\n return Object.entries(colors.colors).map(([name, value]) => ({\n name,\n value,\n }));\n }\n\n /**\n * Get a specific color by name from a theme\n */\n async getColor(name: string, themeName?: string): Promise<string | null> {\n const colors = await this.getThemeColors(themeName);\n return colors.colors[name] || null;\n }\n\n /**\n * Get the full theme configuration (for editor)\n */\n async getFullConfig(): Promise<ThemeConfig> {\n return this.loadThemeConfig();\n }\n\n /**\n * Save theme configuration to colors.json\n */\n async saveThemeConfig(config: ThemeConfig): Promise<void> {\n const colorsPath = projectPaths.colors();\n const content = JSON.stringify(config, null, 2);\n await writeFile(colorsPath, content);\n\n // Update cache with new config\n this.setCache(config);\n }\n}\n\n// Export singleton instance\nexport const colorService = new ColorService();\n", "/**\n * Variable Service\n * Manages loading and caching of CSS variables from variables.json\n */\n\nimport { loadJSONFile, parseJSON } from '../jsonLoader';\nimport { projectPaths } from '../projectContext';\nimport type { VariablesConfig } from '../../shared/types';\nimport { CachedConfigLoader } from './CachedConfigLoader';\nimport { writeFile } from '../runtime';\n\nexport class VariableService extends CachedConfigLoader<VariablesConfig> {\n /**\n * Load variables configuration from variables.json\n */\n async loadConfig(): Promise<VariablesConfig> {\n return this.load();\n }\n\n protected async performLoad(): Promise<VariablesConfig> {\n try {\n const content = await loadJSONFile(projectPaths.variables());\n if (content) {\n const data = parseJSON(content);\n if (data && typeof data === 'object' && 'variables' in data && Array.isArray(data.variables)) {\n return this.migrateConfig(data as VariablesConfig);\n }\n }\n } catch (error) {\n console.warn('Failed to load variables.json:', error);\n }\n\n return this.getDefaultConfig();\n }\n\n private getDefaultConfig(): VariablesConfig {\n return { variables: [] };\n }\n\n /**\n * Migrate legacy config values (e.g. \"spacing\" group -> margin/padding/gap)\n */\n private migrateConfig(config: VariablesConfig): VariablesConfig {\n for (const variable of config.variables) {\n if ((variable.group as string) === 'spacing') {\n const lower = (variable.cssVar + ' ' + variable.name).toLowerCase();\n if (lower.includes('margin')) {\n variable.group = 'margin';\n } else if (lower.includes('gap')) {\n variable.group = 'gap';\n } else {\n variable.group = 'padding';\n }\n }\n }\n return config;\n }\n\n /**\n * Get config with status info (for editor UI)\n */\n async getConfigWithStatus(): Promise<{\n status: 'valid' | 'missing' | 'invalid';\n config: VariablesConfig;\n error?: string;\n filePath: string;\n }> {\n const filePath = projectPaths.variables();\n try {\n const content = await loadJSONFile(filePath);\n if (!content) {\n return { status: 'missing', config: this.getDefaultConfig(), filePath };\n }\n const data = parseJSON(content);\n if (data && typeof data === 'object' && 'variables' in data && Array.isArray(data.variables)) {\n return { status: 'valid', config: this.migrateConfig(data as VariablesConfig), filePath };\n }\n return { status: 'invalid', config: this.getDefaultConfig(), error: 'Invalid structure: missing \"variables\" array', filePath };\n } catch (error) {\n return {\n status: 'invalid',\n config: this.getDefaultConfig(),\n error: error instanceof Error ? error.message : 'Parse error',\n filePath,\n };\n }\n }\n\n /**\n * Save variables configuration to variables.json\n */\n async saveConfig(config: VariablesConfig): Promise<void> {\n const variablesPath = projectPaths.variables();\n const content = JSON.stringify(config, null, 2);\n await writeFile(variablesPath, content);\n this.setCache(config);\n }\n}\n\n// Export singleton instance\nexport const variableService = new VariableService();\n", "/**\n * CMS Service\n * Handles CMS schema extraction, route matching, and content querying\n */\n\nimport type { CMSProvider, CMSSchemaInfo } from '../../shared/interfaces/contentProvider';\nimport type {\n CMSSchema,\n CMSItem,\n CMSRouteMatch,\n CMSListQuery,\n CMSFilterCondition,\n CMSSortConfig,\n ReferenceLocation,\n} from '../../shared/types';\nimport { isItemDraftForLocale } from '../../shared/types';\nimport { isI18nValue } from '../../shared/i18n';\nimport { tiptapToHtml } from '../../shared/richtext/tiptapToHtml';\nimport { isTiptapDocument } from '../../shared/richtext/types';\n\ninterface RoutePattern {\n regex: RegExp;\n collection: string;\n slugGroup: number;\n pagePath: string;\n}\n\ninterface CachedItems {\n items: CMSItem[];\n timestamp: number;\n}\n\n/**\n * CMS Service\n * Manages CMS schemas, route matching, and content querying\n */\nexport class CMSService {\n private schemaCache = new Map<string, CMSSchemaInfo>();\n private routePatterns: RoutePattern[] = [];\n private provider?: CMSProvider;\n\n /** Item cache with TTL-based expiration */\n private itemsCache = new Map<string, CachedItems>();\n /** Cache TTL in milliseconds (5 seconds) */\n private readonly ITEMS_CACHE_TTL = 5000;\n\n /**\n * Creates a new CMSService instance\n * @param provider - Optional CMSProvider for loading data (enables DI for testing)\n */\n constructor(provider?: CMSProvider) {\n this.provider = provider;\n }\n\n /**\n * Set the CMS provider\n * Allows setting provider after construction for backward compatibility\n * @param provider - CMSProvider implementation\n */\n setProvider(provider: CMSProvider): void {\n this.provider = provider;\n }\n\n /**\n * Get items with caching\n * Returns cached items if available and not expired, otherwise fetches fresh data\n * Rich-text fields are automatically preprocessed to HTML for template interpolation\n * @param collection - Collection ID to fetch items for\n * @returns Array of CMSItems with rich-text fields converted to HTML markers\n */\n private async getCachedItems(collection: string): Promise<CMSItem[]> {\n const cached = this.itemsCache.get(collection);\n const now = Date.now();\n\n // Return cached items if still valid\n if (cached && now - cached.timestamp < this.ITEMS_CACHE_TTL) {\n return cached.items;\n }\n\n // Fetch fresh items\n const rawItems = await this.provider!.getItems(collection);\n\n // Preprocess rich-text fields for template interpolation\n const items = this.preprocessRichTextFields(collection, rawItems);\n\n // Update cache\n this.itemsCache.set(collection, { items, timestamp: now });\n\n return items;\n }\n\n /**\n * Preprocess rich-text fields in CMS items.\n * Converts TipTap JSON to HTML and wraps in __richtext__ marker for template interpolation.\n * @param collection - Collection ID (to get schema)\n * @param items - Raw CMS items\n * @returns Items with rich-text fields converted\n */\n private preprocessRichTextFields(collection: string, items: CMSItem[]): CMSItem[] {\n const schemaInfo = this.schemaCache.get(collection);\n if (!schemaInfo) return items;\n\n // Find rich-text fields in schema\n const richTextFields = Object.entries(schemaInfo.schema.fields)\n .filter(([, def]) => def.type === 'rich-text')\n .map(([name]) => name);\n\n if (richTextFields.length === 0) return items;\n\n // Process each item\n return items.map(item => {\n const processed = { ...item };\n\n for (const fieldName of richTextFields) {\n const value = item[fieldName];\n\n // Skip if no value or already processed\n if (!value) continue;\n if (typeof value === 'object' && '__richtext__' in value) continue;\n\n // Convert TipTap document to HTML\n if (isTiptapDocument(value)) {\n const html = tiptapToHtml(value);\n processed[fieldName] = { __richtext__: true, html };\n }\n // Already HTML string - wrap it\n else if (typeof value === 'string') {\n processed[fieldName] = { __richtext__: true, html: value };\n }\n }\n\n return processed;\n });\n }\n\n /**\n * Clear items cache for a specific collection or all collections\n * @param collection - Optional collection ID, clears all if not provided\n */\n clearItemsCache(collection?: string): void {\n if (collection) {\n this.itemsCache.delete(collection);\n } else {\n this.itemsCache.clear();\n }\n }\n\n /**\n * Initialize service - extract schemas from pages and build route patterns\n * Builds state in local variables then swaps atomically so concurrent\n * matchRoute() calls see either old OR new state, never empty.\n */\n async initialize(): Promise<void> {\n if (!this.provider) {\n return;\n }\n\n const schemas = await this.provider.getAllSchemas();\n\n // Build new state in locals before swapping\n const newSchemaCache = new Map<string, CMSSchemaInfo>();\n const newRoutePatterns: RoutePattern[] = [];\n\n for (const [id, schemaInfo] of schemas) {\n newSchemaCache.set(id, schemaInfo);\n newRoutePatterns.push({\n regex: this.patternToRegex(schemaInfo.schema.urlPattern),\n collection: id,\n slugGroup: 1,\n pagePath: schemaInfo.pagePath,\n });\n }\n\n // Atomic swap - concurrent matchRoute sees old OR new, never empty\n this.schemaCache = newSchemaCache;\n this.routePatterns = newRoutePatterns;\n }\n\n /**\n * Convert URL pattern to regex\n * e.g., \"/blog/{{slug}}\" -> /^\\/blog\\/([^\\/]+)$/\n */\n private patternToRegex(pattern: string): RegExp {\n // Escape special regex characters except our placeholder\n const escaped = pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n // Replace the escaped placeholder with a capture group\n const withCapture = escaped.replace(/\\\\\\{\\\\\\{slug\\\\\\}\\\\\\}/g, '([^/]+)');\n return new RegExp(`^${withCapture}$`);\n }\n\n /**\n * Match URL against CMS route patterns\n * Supports i18n slugs - matches locale-specific slug values\n * @param path - URL path to match\n * @param locale - Optional locale for i18n slug matching\n * @returns CMSRouteMatch if matched, null otherwise\n */\n async matchRoute(path: string, locale?: string): Promise<CMSRouteMatch | null> {\n if (!this.provider) {\n return null;\n }\n\n for (const route of this.routePatterns) {\n const match = path.match(route.regex);\n if (match) {\n const urlSlug = match[route.slugGroup];\n\n // Try to find item by matching its slug field value\n const item = await this.findItemBySlug(route.collection, urlSlug, locale);\n\n if (item) {\n return {\n collection: route.collection,\n slug: urlSlug,\n item,\n pagePath: route.pagePath,\n };\n }\n }\n }\n return null;\n }\n\n /**\n * Find item by simple string slug match\n * @param items - Items to search through\n * @param urlSlug - Slug value from URL\n * @param slugField - Field name containing the slug\n * @returns CMSItem if found, null otherwise\n */\n private findBySimpleSlug(\n items: CMSItem[],\n urlSlug: string,\n slugField: string\n ): CMSItem | null {\n for (const item of items) {\n const slugValue = item[slugField];\n\n if (typeof slugValue === 'string' && slugValue === urlSlug) {\n return item;\n }\n // Also check _filename for backward compatibility\n if (item._filename === urlSlug) {\n return item;\n }\n }\n return null;\n }\n\n /**\n * Find item by i18n slug match\n * @param items - Items to search through\n * @param urlSlug - Slug value from URL\n * @param slugField - Field name containing the slug\n * @param locale - Optional locale for preferential matching\n * @returns CMSItem if found, null otherwise\n */\n private findByI18nSlug(\n items: CMSItem[],\n urlSlug: string,\n slugField: string,\n locale?: string\n ): CMSItem | null {\n for (const item of items) {\n const slugValue = item[slugField];\n\n if (!isI18nValue(slugValue)) continue;\n\n // If locale provided, try to match that locale's slug first\n if (locale && slugValue[locale] === urlSlug) {\n return item;\n }\n\n // Try to match any locale's slug value\n for (const key of Object.keys(slugValue)) {\n if (key !== '_i18n' && slugValue[key] === urlSlug) {\n return item;\n }\n }\n }\n return null;\n }\n\n /**\n * Find item by slug value (supports i18n slugs)\n * @param collection - Collection ID\n * @param urlSlug - Slug value from URL\n * @param locale - Optional locale for i18n slug matching\n * @returns CMSItem if found, null otherwise\n */\n private async findItemBySlug(\n collection: string,\n urlSlug: string,\n locale?: string\n ): Promise<CMSItem | null> {\n if (!this.provider) {\n return null;\n }\n\n const schemaInfo = this.schemaCache.get(collection);\n if (!schemaInfo) return null;\n\n const slugField = schemaInfo.schema.slugField;\n const items = await this.getCachedItems(collection);\n\n // Try simple string slug match first\n const simpleMatch = this.findBySimpleSlug(items, urlSlug, slugField);\n if (simpleMatch) return simpleMatch;\n\n // Try i18n slug match\n const i18nMatch = this.findByI18nSlug(items, urlSlug, slugField, locale);\n if (i18nMatch) return i18nMatch;\n\n // Fallback: try direct filename lookup for backward compatibility\n return await this.provider.getItemByFilename(collection, urlSlug);\n }\n\n /**\n * Get all URLs for a collection (for static generation)\n * Supports i18n slugs - generates URLs for all locales when slug is i18n\n * @param collection - Collection ID\n * @param locales - Optional array of locale codes for i18n URL generation\n * @param defaultLocale - Optional default locale (URLs without prefix)\n * @returns Array of URLs\n */\n async getCollectionURLs(\n collection: string,\n locales?: string[],\n defaultLocale?: string,\n options?: { excludeDrafts?: boolean }\n ): Promise<string[]> {\n if (!this.provider) {\n return [];\n }\n\n const schemaInfo = this.schemaCache.get(collection);\n if (!schemaInfo) return [];\n\n const items = await this.getCachedItems(collection);\n const urls: string[] = [];\n\n for (const item of items) {\n const slugValue = item[schemaInfo.schema.slugField];\n\n // Case 1: Simple string slug - one URL\n if (typeof slugValue === 'string') {\n // Skip if item is draft for the default locale (non-i18n case)\n if (options?.excludeDrafts && defaultLocale && isItemDraftForLocale(item, defaultLocale)) continue;\n urls.push(\n schemaInfo.schema.urlPattern.replace('{{slug}}', slugValue)\n );\n }\n // Case 2: i18n slug - one URL per locale\n else if (isI18nValue(slugValue) && locales) {\n for (const locale of locales) {\n if (options?.excludeDrafts && isItemDraftForLocale(item, locale)) continue;\n const localizedSlug = slugValue[locale] as string;\n if (localizedSlug) {\n const path = schemaInfo.schema.urlPattern.replace('{{slug}}', localizedSlug);\n // For default locale, no prefix; for others, add locale prefix\n if (locale === defaultLocale) {\n urls.push(path);\n } else {\n urls.push(`/${locale}${path}`);\n }\n }\n }\n }\n // Case 3: i18n slug but no locales provided - use first available slug\n else if (isI18nValue(slugValue)) {\n for (const key of Object.keys(slugValue)) {\n if (key !== '_i18n' && typeof slugValue[key] === 'string') {\n urls.push(\n schemaInfo.schema.urlPattern.replace('{{slug}}', slugValue[key] as string)\n );\n break; // Only use first available\n }\n }\n }\n }\n\n return urls;\n }\n\n /**\n * Get schema for collection\n * @param collection - Collection ID\n * @returns CMSSchema or undefined\n */\n getSchema(collection: string): CMSSchema | undefined {\n return this.schemaCache.get(collection)?.schema;\n }\n\n /**\n * Get all schemas\n * @returns Map of collection ID to CMSSchemaInfo\n */\n getAllSchemas(): Map<string, CMSSchemaInfo> {\n return this.schemaCache;\n }\n\n /**\n * Refresh schemas from provider\n * Call this after adding/removing collections to update the cache.\n * Only clears items cache and provider cache before re-initializing.\n * Schema/route caches are swapped atomically inside initialize().\n */\n async refreshSchemas(): Promise<void> {\n if (!this.provider) {\n return;\n }\n\n // Clear items cache so stale content isn't served\n this.itemsCache.clear();\n\n // Clear provider cache if available\n if ('clearSchemaCache' in this.provider && typeof this.provider.clearSchemaCache === 'function') {\n this.provider.clearSchemaCache();\n }\n\n // Re-initialize - atomically swaps schemaCache and routePatterns\n await this.initialize();\n }\n\n /**\n * Query items with filter/sort/limit\n * @param query - CMSListQuery with collection, filter, sort, limit, offset\n * @returns Filtered and sorted array of CMSItems\n */\n async queryItems(query: CMSListQuery): Promise<CMSItem[]> {\n if (!this.provider) {\n return [];\n }\n\n let items = await this.getCachedItems(query.collection);\n\n // Exclude draft items for the specified locale\n if (query.excludeDraftLocale) {\n items = items.filter(item => !isItemDraftForLocale(item, query.excludeDraftLocale!));\n }\n\n // Apply filters\n if (query.filter) {\n items = this.applyFilters(items, query.filter);\n }\n\n // Apply sorting\n if (query.sort) {\n items = this.applySorting(items, query.sort);\n }\n\n // Apply offset\n if (query.offset !== undefined && query.offset > 0) {\n items = items.slice(query.offset);\n }\n\n // Apply limit\n if (query.limit !== undefined && query.limit > 0) {\n items = items.slice(0, query.limit);\n }\n\n return items;\n }\n\n /**\n * Apply filters to items\n */\n private applyFilters(\n items: CMSItem[],\n filter: CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown>\n ): CMSItem[] {\n // Handle simple object filter: { featured: true }\n if (!Array.isArray(filter) && !this.isFilterCondition(filter)) {\n return items.filter(item =>\n Object.entries(filter).every(([key, value]) => item[key] === value)\n );\n }\n\n // Handle array of conditions or single condition\n const conditions = Array.isArray(filter) ? filter : [filter as CMSFilterCondition];\n return items.filter(item =>\n conditions.every(cond => this.matchCondition(item, cond))\n );\n }\n\n /**\n * Check if object is a CMSFilterCondition\n */\n private isFilterCondition(obj: unknown): obj is CMSFilterCondition {\n return typeof obj === 'object' && obj !== null && 'field' in obj;\n }\n\n /**\n * Match a single filter condition against an item\n */\n private matchCondition(item: CMSItem, condition: CMSFilterCondition): boolean {\n const value = item[condition.field];\n const op = condition.operator || 'eq';\n\n switch (op) {\n case 'eq':\n return value === condition.value;\n case 'neq':\n return value !== condition.value;\n case 'gt':\n return (value as number) > (condition.value as number);\n case 'gte':\n return (value as number) >= (condition.value as number);\n case 'lt':\n return (value as number) < (condition.value as number);\n case 'lte':\n return (value as number) <= (condition.value as number);\n case 'contains':\n return String(value).includes(String(condition.value));\n case 'in':\n return Array.isArray(condition.value) && condition.value.includes(value);\n default:\n return false;\n }\n }\n\n /**\n * Get items by their IDs from a collection.\n * Used for resolving reference fields in CMS List templates.\n * Missing IDs are silently skipped. Order is preserved based on input ids array.\n *\n * @param collection - Collection ID to fetch from\n * @param ids - Array of item IDs or filenames to fetch\n * @returns Array of CMSItems matching the IDs\n */\n async getItemsByIds(collection: string, ids: string[]): Promise<CMSItem[]> {\n if (!this.provider) {\n return [];\n }\n\n const allItems = await this.getCachedItems(collection);\n\n // Build lookup maps for both _id and _filename\n const itemMap = new Map(allItems.map(item => [item._id, item]));\n const filenameMap = new Map(\n allItems\n .filter(item => item._filename)\n .map(item => [item._filename!, item])\n );\n\n // Filter to matching items, preserving input order\n return ids\n .filter(Boolean)\n .map(id => itemMap.get(id) || filenameMap.get(id))\n .filter((item): item is CMSItem => item !== undefined);\n }\n\n /**\n * Apply sorting to items\n */\n private applySorting(items: CMSItem[], sort: CMSSortConfig | CMSSortConfig[]): CMSItem[] {\n const sorts = Array.isArray(sort) ? sort : [sort];\n\n return [...items].sort((a, b) => {\n for (const s of sorts) {\n const aVal = a[s.field];\n const bVal = b[s.field];\n const isDesc = s.order === 'desc';\n\n // Handle boolean comparison\n if (typeof aVal === 'boolean' && typeof bVal === 'boolean') {\n if (aVal === bVal) continue;\n // For desc: true first (true > false), for asc: false first\n if (isDesc) {\n return aVal ? -1 : 1;\n } else {\n return aVal ? 1 : -1;\n }\n }\n\n // Standard comparison (compare as primitives)\n let result = 0;\n if ((aVal as string | number) < (bVal as string | number)) result = -1;\n else if ((aVal as string | number) > (bVal as string | number)) result = 1;\n\n if (result !== 0) {\n return isDesc ? -result : result;\n }\n }\n return 0;\n });\n }\n\n /**\n * Find all references to a specific item across all collections.\n * Used to warn users before deleting an item that is referenced elsewhere.\n *\n * @param targetCollection - Collection ID of the item being referenced\n * @param targetId - ID or filename of the target item\n * @returns Array of ReferenceLocation objects describing where the item is referenced\n */\n async findReferencesTo(\n targetCollection: string,\n targetId: string\n ): Promise<ReferenceLocation[]> {\n if (!this.provider) {\n return [];\n }\n\n const references: ReferenceLocation[] = [];\n const allSchemas = this.getAllSchemas();\n\n for (const [collectionId, schemaInfo] of allSchemas) {\n const { schema } = schemaInfo;\n\n // Find reference fields pointing to targetCollection\n const refFields = Object.entries(schema.fields)\n .filter(([_, def]) => def.type === 'reference' && def.collection === targetCollection);\n\n if (refFields.length === 0) continue;\n\n // Check all items in this collection\n const items = await this.getCachedItems(collectionId);\n for (const item of items) {\n for (const [fieldName] of refFields) {\n const value = item[fieldName];\n if (!value) continue;\n\n const ids = Array.isArray(value) ? value : [value];\n if (ids.includes(targetId)) {\n references.push({\n collection: collectionId,\n itemId: item._id,\n itemSlug: item._slug,\n itemFilename: item._filename,\n fieldName,\n });\n }\n }\n }\n }\n\n return references;\n }\n\n /**\n * Remove all references to a target item.\n * For single-reference fields: sets to null\n * For multi-reference fields: filters out the target ID\n * @returns Number of items updated\n */\n async removeReferencesTo(\n targetCollection: string,\n targetId: string\n ): Promise<number> {\n if (!this.provider) {\n return 0;\n }\n\n const references = await this.findReferencesTo(targetCollection, targetId);\n let removedCount = 0;\n\n for (const ref of references) {\n if (!ref.itemFilename) continue;\n\n const item = await this.provider.getItemByFilename(ref.collection, ref.itemFilename);\n if (!item) continue;\n\n const schemaInfo = this.getAllSchemas().get(ref.collection);\n const fieldDef = schemaInfo?.schema.fields[ref.fieldName];\n const currentValue = item[ref.fieldName];\n\n let newValue: string | string[] | null;\n if (fieldDef?.multiple && Array.isArray(currentValue)) {\n // Multi-reference: filter out target\n newValue = currentValue.filter(id => id !== targetId);\n if (newValue.length === 0) newValue = null;\n } else {\n // Single reference: clear it\n newValue = null;\n }\n\n // Update the item\n await this.provider.saveItem(ref.collection, {\n ...item,\n [ref.fieldName]: newValue,\n });\n removedCount++;\n }\n\n return removedCount;\n }\n}\n\n// Re-export ReferenceLocation from shared types for backward compatibility\nexport type { ReferenceLocation } from '../../shared/types';\n", "import { projectPaths } from '../server/projectContext';\nimport { readJsonFile, fileExists } from '../server/runtime';\n\nexport interface FontConfig {\n path: string;\n family?: string;\n weight?: number;\n weightMax?: number; // If set, font is variable with weight range [weight, weightMax]\n style?: 'normal' | 'italic';\n fontDisplay?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional';\n unicodeRange?: string;\n}\n\ninterface ProjectConfig {\n fonts?: FontConfig[];\n siteUrl?: string;\n [key: string]: unknown;\n}\n\nlet cachedConfig: ProjectConfig | null = null;\n\nexport function resetFontConfig(): void {\n cachedConfig = null;\n}\n\nexport async function loadProjectConfig(): Promise<ProjectConfig> {\n if (cachedConfig) return cachedConfig;\n if (await fileExists(projectPaths.config())) {\n cachedConfig = await readJsonFile<ProjectConfig>(projectPaths.config());\n } else {\n cachedConfig = { fonts: [] };\n }\n return cachedConfig!;\n}\n\n// For synchronous access after config is loaded\nexport function getProjectConfig(): ProjectConfig {\n return cachedConfig || { fonts: [] };\n}\n\n/**\n * Detect font format from file extension\n */\nfunction getFontFormat(path: string): string {\n if (path.endsWith('.woff2')) return 'woff2';\n if (path.endsWith('.woff')) return 'woff';\n if (path.endsWith('.ttf')) return 'truetype';\n if (path.endsWith('.otf')) return 'opentype';\n return 'truetype';\n}\n\n/**\n * Extract font family name from path if not provided\n * Example: \"/fonts/geomanist-regular.ttf\" -> \"Geomanist\"\n */\nfunction extractFamilyName(path: string): string {\n const filename = path.split('/').pop() || 'Font';\n const name = filename.replace(/\\.(ttf|woff2?|otf)$/i, '');\n // Capitalize and replace hyphens with spaces\n return name\n .split('-')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n}\n\nexport function generateFontCSS(): string {\n const config = getProjectConfig();\n const fonts = config.fonts || [];\n\n return fonts\n .filter((font: any) => font.path || font.src)\n .map((font: any) => {\n // Support both \"path\" (standard) and \"src\" (legacy from website import)\n const fontPath: string = font.path || font.src;\n const format = getFontFormat(fontPath);\n const family = font.family || extractFamilyName(fontPath);\n const weight = font.weight ?? 400;\n const weightMax = font.weightMax;\n const style = font.style ?? 'normal';\n const fontDisplay = font.fontDisplay;\n\n // Variable fonts use weight range syntax: \"100 900\"\n const fontWeight = weightMax != null ? `${weight} ${weightMax}` : weight;\n\n const unicodeRange = font.unicodeRange;\n\n return `@font-face {\n font-family: '${family}';\n src: url('${fontPath}') format('${format}');\n font-weight: ${fontWeight};\n font-style: ${style};${fontDisplay ? `\\n font-display: ${fontDisplay};` : ''}${unicodeRange ? `\\n unicode-range: ${unicodeRange};` : ''}\n}`;\n })\n .join('\\n\\n');\n}\n\n/**\n * Get font MIME type for preload \"type\" attribute\n */\nfunction getFontMimeType(path: string): string {\n if (path.endsWith('.woff2')) return 'font/woff2';\n if (path.endsWith('.woff')) return 'font/woff';\n if (path.endsWith('.ttf')) return 'font/ttf';\n if (path.endsWith('.otf')) return 'font/otf';\n return 'font/ttf';\n}\n\n/**\n * Generate font preload link tags for early font loading\n * This prevents font swap flash on SPA navigation by ensuring fonts are\n * loaded and cached before they're needed.\n */\nexport function generateFontPreloadTags(): string {\n const config = getProjectConfig();\n const fonts = config.fonts || [];\n\n if (fonts.length === 0) return '';\n\n return fonts\n .filter((font: any) => font.path || font.src)\n .map((font: any) => {\n const fontPath: string = font.path || font.src;\n const mimeType = getFontMimeType(fontPath);\n // crossorigin is required for fonts to be cached properly\n return `<link rel=\"preload\" href=\"${fontPath}\" as=\"font\" type=\"${mimeType}\" crossorigin>`;\n })\n .join('\\n ');\n}\n\nexport function getFontFamilies(): Record<string, number[]> {\n const config = getProjectConfig();\n const fonts = config.fonts || [];\n const familiesMap: Record<string, number[]> = {};\n\n fonts.forEach((font: any) => {\n const fontPath: string = font.path || font.src;\n if (!fontPath) return;\n const family = font.family || extractFamilyName(fontPath);\n const weight = font.weight ?? 400;\n const weightMax = font.weightMax;\n\n if (!familiesMap[family]) {\n familiesMap[family] = [];\n }\n\n // Variable fonts: include all weights in range (100, 200, ..., weightMax)\n if (weightMax != null) {\n for (let w = weight; w <= weightMax; w += 100) {\n if (!familiesMap[family].includes(w)) {\n familiesMap[family].push(w);\n }\n }\n } else {\n if (!familiesMap[family].includes(weight)) {\n familiesMap[family].push(weight);\n }\n }\n });\n\n return familiesMap;\n}\n", "/**\n * HTML attribute building utilities for SSR\n * Pure functions with no external dependencies\n */\n\n/**\n * Escape HTML special characters to prevent XSS\n */\nexport function escapeHtml(unsafe: string): string {\n // Handle non-string values defensively\n if (typeof unsafe !== 'string') {\n if (unsafe === null || unsafe === undefined) {\n return '';\n }\n // Convert arrays/objects/numbers to string\n unsafe = String(unsafe);\n }\n return unsafe\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n}\n\n/** HTML attributes that must NOT be kebab-cased (single-word or special casing) */\nconst NO_KEBAB_ATTRS = new Set([\n 'autoplay', 'playsinline', 'crossorigin', 'novalidate', 'readonly',\n 'nomodule', 'formnovalidate', 'ismap', 'usemap', 'srcset', 'inputmode',\n 'enterkeyhint', 'autocomplete', 'autofocus', 'contenteditable',\n]);\n\n/**\n * Build HTML attributes string from props (excluding style and other special props)\n */\nexport function buildAttributes(props: Record<string, unknown>, exclude: string[] = []): string {\n const attrs: string[] = [];\n // Internal props that should never be rendered as HTML attributes\n // Note: image-specific props (src, alt, loading, width, height, sizes, srcset, fetchpriority)\n // are NOT excluded here - they're only excluded for <img> tags via the exclude parameter\n const internalProps = ['tag', 'component', 'props', 'children'];\n const defaultExclude = [...internalProps, ...exclude];\n\n // Regex to detect unresolved template strings like {{link.target}}\n // But NOT item templates like {{item.field}} or {{post.field}} - those should be preserved for client-side rendering\n const unresolvedTemplatePattern = /^\\{\\{(?!item\\.|[a-z]+Index|[a-z]+First|[a-z]+Last).+\\}\\}$/;\n\n for (const [key, value] of Object.entries(props)) {\n if (defaultExclude.includes(key)) continue;\n if (value === null || value === undefined) continue;\n if (typeof value === 'function') continue; // Skip event handlers in SSR\n if (typeof value === 'object') continue; // Skip objects (prevents [object Object] in attributes)\n // Skip unresolved template strings (e.g., {{link.target}} when link.target is undefined)\n // BUT keep item templates like {{item.field}} for client-side dynamic rendering\n if (typeof value === 'string' && unresolvedTemplatePattern.test(value)) continue;\n\n // Convert camelCase to kebab-case for HTML attributes,\n // but preserve non-kebab HTML attributes (autoplay, playsinline, etc.)\n const attrName = NO_KEBAB_ATTRS.has(key.toLowerCase())\n ? key.toLowerCase()\n : key.replace(/([A-Z])/g, '-$1').toLowerCase();\n const attrValue = typeof value === 'boolean'\n ? (value ? '' : undefined)\n : escapeHtml(String(value));\n\n if (attrValue !== undefined) {\n if (typeof value === 'boolean' && value) {\n attrs.push(attrName);\n } else {\n attrs.push(`${attrName}=\"${attrValue}\"`);\n }\n }\n }\n\n return attrs.length > 0 ? ' ' + attrs.join(' ') : '';\n}\n\n/**\n * Convert a style object to inline CSS string\n * Handles CSS variables (--is-0: value) and regular properties\n */\nexport function styleToString(style: Record<string, string | number> | undefined): string {\n if (!style || Object.keys(style).length === 0) return '';\n\n const declarations: string[] = [];\n for (const [key, value] of Object.entries(style)) {\n if (value === null || value === undefined) continue;\n\n // Handle CSS variables (already in kebab-case with -- prefix)\n if (key.startsWith('--')) {\n declarations.push(`${key}: ${escapeHtml(String(value))}`);\n } else {\n // Convert camelCase to kebab-case for regular CSS properties\n const cssProperty = key.replace(/([A-Z])/g, '-$1').toLowerCase();\n declarations.push(`${cssProperty}: ${escapeHtml(String(value))}`);\n }\n }\n\n return declarations.length > 0 ? declarations.join('; ') : '';\n}\n", "/**\n * Slug Translation Service\n * Handles translation of URL slugs between locales\n */\n\nimport type { I18nConfig } from './types';\n\n/**\n * Slug mapping for a single page\n */\nexport interface SlugMap {\n pageId: string;\n slugs: Record<string, string>;\n}\n\n/**\n * Index entry for reverse lookup (slug+locale \u2192 pageId)\n */\ninterface SlugIndexEntry {\n pageId: string;\n slugs: Record<string, string>;\n}\n\n/**\n * Build reverse lookup index: \"locale:slug\" \u2192 SlugIndexEntry\n * This allows quick lookup of pageId from any locale's slug\n */\nexport function buildSlugIndex(mappings: SlugMap[]): Map<string, SlugIndexEntry> {\n const index = new Map<string, SlugIndexEntry>();\n\n for (const mapping of mappings) {\n for (const [locale, slug] of Object.entries(mapping.slugs)) {\n // Key format: \"locale:slug\" (e.g., \"pl:o-nas\" or \"en:about\")\n const key = `${locale}:${slug}`;\n index.set(key, {\n pageId: mapping.pageId,\n slugs: mapping.slugs,\n });\n }\n }\n\n return index;\n}\n\n/**\n * Find page by slug and locale\n * @returns The SlugIndexEntry if found, undefined otherwise\n */\nexport function findPageBySlug(\n slug: string,\n locale: string,\n index: Map<string, SlugIndexEntry>\n): SlugIndexEntry | undefined {\n const key = `${locale}:${slug}`;\n return index.get(key);\n}\n\n/**\n * Translate a path to another locale\n *\n * @param currentPath - Current URL path (e.g., \"/pl/o-nas\" or \"/about\")\n * @param targetLocale - Target locale (e.g., \"en\")\n * @param currentLocale - Current locale (e.g., \"pl\")\n * @param defaultLocale - Default locale that doesn't use prefix (e.g., \"en\")\n * @param index - Slug index from buildSlugIndex()\n * @returns Translated path (e.g., \"/about\" for en default, \"/de/uber\" for de)\n */\nexport function translatePath(\n currentPath: string,\n targetLocale: string,\n currentLocale: string,\n defaultLocale: string,\n index: Map<string, SlugIndexEntry>\n): string {\n // Extract slug from current path (remove locale prefix if present)\n let slug = currentPath;\n\n // Remove leading slash\n if (slug.startsWith('/')) {\n slug = slug.substring(1);\n }\n\n // Remove locale prefix if present (e.g., \"pl/o-nas\" \u2192 \"o-nas\")\n // Also handle case where slug IS the locale (e.g., \"pl\" for Polish homepage)\n if (currentLocale !== defaultLocale) {\n if (slug.startsWith(`${currentLocale}/`)) {\n slug = slug.substring(currentLocale.length + 1);\n } else if (slug === currentLocale) {\n // Path is just the locale prefix (e.g., \"/pl\" \u2192 index page)\n slug = '';\n }\n }\n\n // Handle root path\n if (slug === '' || slug === '/') {\n slug = '';\n }\n\n // Look up page by current slug and locale\n let entry = findPageBySlug(slug, currentLocale, index);\n\n // If not found for current locale, try default locale\n // This handles cases like /de/about where German uses the English slug\n if (!entry && currentLocale !== defaultLocale) {\n entry = findPageBySlug(slug, defaultLocale, index);\n }\n\n if (!entry) {\n // No translation found - return path with just locale prefix change\n if (targetLocale === defaultLocale) {\n return slug === '' ? '/' : `/${slug}`;\n }\n return slug === '' ? `/${targetLocale}` : `/${targetLocale}/${slug}`;\n }\n\n // Get translated slug for target locale\n const targetSlug = entry.slugs[targetLocale] ?? entry.slugs[defaultLocale] ?? slug;\n\n // Build target path\n if (targetLocale === defaultLocale) {\n return targetSlug === '' ? '/' : `/${targetSlug}`;\n }\n return targetSlug === '' ? `/${targetLocale}` : `/${targetLocale}/${targetSlug}`;\n}\n\n/**\n * Locale link information for locale switcher\n */\nexport interface LocaleLink {\n locale: string; // Locale code (e.g., \"pl\")\n langTag: string; // BCP 47 language tag (e.g., \"pl-PL\")\n name: string; // English name (e.g., \"Polish\")\n nativeName: string; // Display name in native language (e.g., \"Polski\")\n path: string; // Translated path for this locale\n isCurrent: boolean; // Whether this is the current locale\n}\n\n/**\n * Get all available locales with their translated paths for the current page\n * Useful for rendering locale switcher\n *\n * @param currentPath - Current URL path\n * @param currentLocale - Current locale\n * @param i18nConfig - i18n configuration with locales\n * @param index - Slug index\n * @returns Array of LocaleLink objects\n */\nexport function getLocaleLinks(\n currentPath: string,\n currentLocale: string,\n i18nConfig: I18nConfig,\n index: Map<string, SlugIndexEntry>\n): LocaleLink[] {\n return i18nConfig.locales.map(localeConfig => ({\n locale: localeConfig.code,\n langTag: localeConfig.langTag,\n name: localeConfig.name,\n nativeName: localeConfig.nativeName,\n path: translatePath(currentPath, localeConfig.code, currentLocale, i18nConfig.defaultLocale, index),\n isCurrent: localeConfig.code === currentLocale,\n }));\n}\n\n/**\n * Resolve a slug to its pageId (for server-side page loading)\n *\n * @param slug - URL slug (e.g., \"o-nas\")\n * @param locale - Current locale (e.g., \"pl\")\n * @param index - Slug index\n * @returns pageId if found (e.g., \"about\"), undefined otherwise\n */\nexport function resolveSlugToPageId(\n slug: string,\n locale: string,\n index: Map<string, SlugIndexEntry>\n): string | undefined {\n const entry = findPageBySlug(slug, locale, index);\n return entry?.pageId;\n}\n", "/**\n * Meta tag generation for SSR\n * Handles SEO meta information extraction and HTML generation\n */\n\nimport type { JSONPage } from '../../shared/types';\nimport type { I18nConfig } from '../../shared/types/components';\nimport { DEFAULT_I18N_CONFIG, resolveI18nValue } from '../../shared/i18n';\nimport { escapeHtml } from './attributeBuilder';\nimport { buildSlugIndex, getLocaleLinks, type SlugMap } from '../../shared/slugTranslator';\n\n/**\n * Page meta information for SEO\n * Values can be strings or i18n objects - resolved in generateMetaTags\n */\nexport interface PageMeta {\n title?: unknown;\n description?: unknown;\n keywords?: unknown;\n ogTitle?: unknown;\n ogDescription?: unknown;\n ogImage?: unknown;\n ogType?: unknown;\n}\n\nexport function extractPageMeta(pageData: JSONPage): PageMeta {\n const meta: PageMeta = {};\n\n if (pageData?.meta) {\n meta.title = pageData.meta.title;\n meta.description = pageData.meta.description;\n meta.keywords = pageData.meta.keywords;\n meta.ogTitle = pageData.meta.ogTitle || pageData.meta.title;\n meta.ogDescription = pageData.meta.ogDescription || pageData.meta.description;\n meta.ogImage = pageData.meta.ogImage;\n meta.ogType = pageData.meta.ogType || 'website';\n }\n\n return meta;\n}\n\n/**\n * Options for hreflang tag generation\n */\nexport interface HreflangOptions {\n slugMappings?: SlugMap[];\n pagePath?: string;\n baseUrl?: string;\n}\n\n/**\n * Generate HTML meta tags string\n * Resolves i18n values using the provided locale and config\n * Optionally generates hreflang tags for multilingual pages\n */\nexport function generateMetaTags(\n meta: PageMeta,\n url: string = '',\n locale: string = 'en',\n config: I18nConfig = DEFAULT_I18N_CONFIG,\n hreflangOptions?: HreflangOptions\n): string {\n const tags: string[] = [];\n\n // Helper to resolve i18n values and ensure string type\n const resolve = (value: unknown): string => {\n const resolved = resolveI18nValue(value, locale, config);\n return typeof resolved === 'string' ? resolved : '';\n };\n\n const title = resolve(meta.title);\n const description = resolve(meta.description);\n const keywords = resolve(meta.keywords);\n const ogTitle = resolve(meta.ogTitle) || title;\n const ogDescription = resolve(meta.ogDescription) || description;\n const ogImage = resolve(meta.ogImage);\n const ogType = resolve(meta.ogType);\n\n if (title) {\n tags.push(`<title>${escapeHtml(title)}</title>`);\n }\n\n if (description) {\n tags.push(`<meta name=\"description\" content=\"${escapeHtml(description)}\" />`);\n }\n\n if (keywords) {\n tags.push(`<meta name=\"keywords\" content=\"${escapeHtml(keywords)}\" />`);\n }\n\n // Open Graph tags\n if (ogTitle) {\n tags.push(`<meta property=\"og:title\" content=\"${escapeHtml(ogTitle)}\" />`);\n }\n\n if (ogDescription) {\n tags.push(`<meta property=\"og:description\" content=\"${escapeHtml(ogDescription)}\" />`);\n }\n\n if (ogImage) {\n tags.push(`<meta property=\"og:image\" content=\"${escapeHtml(ogImage)}\" />`);\n }\n\n if (ogType) {\n tags.push(`<meta property=\"og:type\" content=\"${escapeHtml(ogType)}\" />`);\n }\n\n if (url) {\n tags.push(`<meta property=\"og:url\" content=\"${escapeHtml(url)}\" />`);\n }\n\n // Canonical URL\n if (url) {\n tags.push(`<link rel=\"canonical\" href=\"${escapeHtml(url)}\" />`);\n }\n\n // Hreflang tags for multilingual pages\n if (hreflangOptions?.slugMappings && hreflangOptions.slugMappings.length > 0 && config.locales.length > 1) {\n const { slugMappings, pagePath = '/', baseUrl = '' } = hreflangOptions;\n const slugIndex = buildSlugIndex(slugMappings);\n const localeLinks = getLocaleLinks(pagePath, locale, config, slugIndex);\n\n for (const link of localeLinks) {\n const hrefUrl = baseUrl ? `${baseUrl}${link.path}` : link.path;\n tags.push(`<link rel=\"alternate\" hreflang=\"${escapeHtml(link.langTag)}\" href=\"${escapeHtml(hrefUrl)}\" />`);\n }\n\n // Add x-default pointing to default locale version\n const defaultLink = localeLinks.find(l => l.locale === config.defaultLocale);\n if (defaultLink) {\n const xDefaultUrl = baseUrl ? `${baseUrl}${defaultLink.path}` : defaultLink.path;\n tags.push(`<link rel=\"alternate\" hreflang=\"x-default\" href=\"${escapeHtml(xDefaultUrl)}\" />`);\n }\n }\n\n return tags.join('\\n ');\n}\n", "/**\n * CSS collection utilities for SSR\n * Collects CSS from component definitions\n */\n\nimport type { ComponentDefinition } from '../../shared/types';\n\n/**\n * Collect CSS code from all components (global and page-specific)\n */\nexport function collectComponentCSS(\n globalComponents: Record<string, ComponentDefinition> = {},\n pageComponents: Record<string, ComponentDefinition> = {}\n): string {\n const cssBlocks: string[] = [];\n\n // Collect CSS from global components\n for (const [name, component] of Object.entries(globalComponents)) {\n if (component?.component?.css) {\n cssBlocks.push(`/* Component: ${name} */\\n${component.component.css}`);\n }\n }\n\n // Collect CSS from page-specific components\n for (const [name, component] of Object.entries(pageComponents)) {\n // Skip if already collected from global components\n if (!globalComponents[name] && component?.component?.css) {\n cssBlocks.push(`/* Component: ${name} */\\n${component.component.css}`);\n }\n }\n\n return cssBlocks.join('\\n\\n');\n}\n", "/**\n * JavaScript collection utilities for SSR\n * Collects and wraps component JavaScript with defineVars support\n */\n\nimport type { ComponentDefinition } from '../../shared/types';\nimport { validateJS as runtimeValidateJS } from '../runtime';\n\n/**\n * Validate JavaScript syntax using runtime bundler\n * Returns error message if invalid, null if valid\n */\nasync function validateJS(code: string): Promise<string | null> {\n return runtimeValidateJS(code);\n}\n\n/**\n * Runtime helper for defineVars - initializes components with their props\n * Injected once when any component uses defineVars\n */\nconst DEFINE_VARS_RUNTIME = `(function() {\n var __meno = window.__meno || (window.__meno = {});\n __meno.initComponent = function(name, fn) {\n var elements = document.querySelectorAll('[data-component~=\"' + name + '\"]');\n elements.forEach(function(el) {\n var propsStr = el.getAttribute('data-props');\n var allProps = propsStr ? JSON.parse(propsStr) : {};\n var props = allProps[name] || {};\n fn(el, props);\n });\n };\n})();`;\n\n/**\n * Generate destructure statement for defineVars\n */\nfunction generateDestructure(\n defineVars: true | string[],\n interfaceDef?: Record<string, unknown>\n): string {\n const vars = defineVars === true\n ? Object.keys(interfaceDef || {})\n : defineVars;\n if (vars.length === 0) return '';\n return `var {${vars.join(', ')}} = props;`;\n}\n\n/**\n * Callback for component JS validation errors\n */\nexport type JSErrorCallback = (componentName: string, error: string) => void;\n\n/**\n * Cache for validated component JS\n * Maps component name -> validation result (null=valid, string=error)\n * This prevents re-validating the same component for every page\n */\nconst validationCache = new Map<string, string | null>();\n\n/**\n * Collected JS validation errors (componentName -> error message)\n */\nconst collectedErrors = new Map<string, string>();\n\n/**\n * Clear the validation cache and collected errors (call at start of build)\n */\nexport function clearJSValidationCache(): void {\n validationCache.clear();\n collectedErrors.clear();\n}\n\n/**\n * Get all collected JS validation errors\n * Returns array of { component, error } objects\n */\nexport function getJSValidationErrors(): Array<{ component: string; error: string }> {\n return Array.from(collectedErrors.entries()).map(([component, error]) => ({\n component,\n error,\n }));\n}\n\n/**\n * Collect JavaScript code from all components (global and page-specific)\n * Wraps defineVars components with initComponent pattern\n * Validates each component's JS individually and reports errors via callback\n */\nexport async function collectComponentJavaScript(\n globalComponents: Record<string, ComponentDefinition> = {},\n pageComponents: Record<string, ComponentDefinition> = {},\n onError?: JSErrorCallback\n): Promise<string> {\n const jsCodeBlocks: string[] = [];\n let hasDefineVars = false;\n\n // Helper to process a component's JavaScript\n const processComponent = async (name: string, component: ComponentDefinition) => {\n if (!component?.component?.javascript) return;\n\n const js = component.component.javascript;\n const defineVars = component.component.defineVars;\n\n // Check cache first to avoid re-validating\n let error: string | null;\n if (validationCache.has(name)) {\n error = validationCache.get(name)!;\n } else {\n error = await validateJS(js);\n validationCache.set(name, error);\n }\n\n if (error) {\n // Collect error internally (for build-static.ts to retrieve)\n if (!collectedErrors.has(name)) {\n collectedErrors.set(name, error);\n }\n onError?.(name, error);\n return; // Skip this component's JS\n }\n\n if (defineVars) {\n hasDefineVars = true;\n const destructure = generateDestructure(defineVars, component.component.interface);\n jsCodeBlocks.push(`// Component: ${name}\n__meno.initComponent(\"${name}\", function(el, props) {\n ${destructure}\n ${js}\n});`);\n } else {\n // No defineVars - emit as-is (backward compatible)\n jsCodeBlocks.push(`// Component: ${name}\\n${js}`);\n }\n };\n\n // Collect JS from global components\n for (const [name, component] of Object.entries(globalComponents)) {\n await processComponent(name, component);\n }\n\n // Collect JS from page-specific components\n for (const [name, component] of Object.entries(pageComponents)) {\n // Skip if already collected from global components\n if (!globalComponents[name]) {\n await processComponent(name, component);\n }\n }\n\n // Prepend runtime helper if any component uses defineVars\n if (hasDefineVars && jsCodeBlocks.length > 0) {\n jsCodeBlocks.unshift(DEFINE_VARS_RUNTIME);\n }\n\n return jsCodeBlocks.join('\\n\\n');\n}\n", "/**\n * CMS template processing for SSR\n * Handles {{cms.field}} interpolation and CMS context management\n */\n\nimport type { I18nConfig } from '../../shared/types/components';\nimport type { TemplateContext } from '../../shared/types';\nimport { DEFAULT_I18N_CONFIG, resolveI18nValue, isI18nValue } from '../../shared/i18n';\nimport type { ValueResolver } from '../../shared/itemTemplateUtils';\nimport { tiptapToHtml } from '../../shared/richtext/tiptapToHtml';\nimport { isTiptapDocument } from '../../shared/richtext/types';\nimport { RAW_HTML_PREFIX } from '../../shared/constants';\n\n// Re-export for backward compatibility\nexport { RAW_HTML_PREFIX };\n\n/**\n * CMS context for template interpolation\n */\nexport interface CMSContext {\n cms?: Record<string, unknown>;\n}\n\n/**\n * Get i18n resolver function for value resolution\n */\nexport function createI18nResolver(\n locale?: string,\n i18nConfig?: I18nConfig\n): ValueResolver | undefined {\n if (!locale || !i18nConfig) return undefined;\n return (value: unknown) => resolveI18nValue(value, locale, i18nConfig);\n}\n\n/**\n * Process CMS template strings like {{cms.title}} or {{cms.author}}\n * Replaces template expressions with values from CMS item\n * Supports i18n values - resolves to locale-specific strings\n */\nexport function processCMSTemplate(\n template: string,\n cmsItem: Record<string, unknown>,\n locale?: string,\n i18nConfig?: I18nConfig\n): string {\n const config = i18nConfig || DEFAULT_I18N_CONFIG;\n const effectiveLocale = locale || config.defaultLocale;\n\n return template.replace(/\\{\\{cms\\.([^}]+)\\}\\}/g, (match, fieldPath) => {\n // Support nested paths like cms.author.name\n const parts = fieldPath.trim().split('.');\n let value: unknown = cmsItem;\n\n for (const part of parts) {\n if (value && typeof value === 'object' && part in value) {\n value = (value as Record<string, unknown>)[part];\n } else {\n // Field not found, return empty string\n return '';\n }\n }\n\n // Return string representation\n if (value === null || value === undefined) {\n return '';\n }\n // Handle i18n values - resolve to locale-specific value, then continue\n // through rich-text detection (don't early-return, as resolved value may be Tiptap JSON)\n if (isI18nValue(value)) {\n value = resolveI18nValue(value, effectiveLocale, config);\n }\n // Handle rich-text markers - extract HTML content for interpolation\n // Mark with RAW_HTML_PREFIX so renderer knows not to escape\n if (typeof value === 'object' && value !== null && '__richtext__' in value) {\n const richText = value as Record<string, unknown>;\n if (typeof richText.html === 'string') {\n return RAW_HTML_PREFIX + richText.html;\n }\n }\n // Handle raw TipTap documents (fallback if not preprocessed)\n // Mark with RAW_HTML_PREFIX so renderer knows not to escape\n if (isTiptapDocument(value)) {\n return RAW_HTML_PREFIX + tiptapToHtml(value);\n }\n return String(value);\n });\n}\n\n/**\n * Process CMS templates in props object\n * Recursively processes all string values in props\n */\nexport function processCMSPropsTemplate(\n props: Record<string, unknown>,\n cmsItem: Record<string, unknown>,\n locale?: string,\n i18nConfig?: I18nConfig\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(props)) {\n if (typeof value === 'string' && value.includes('{{cms.')) {\n result[key] = processCMSTemplate(value, cmsItem, locale, i18nConfig);\n } else if (value && typeof value === 'object' && !Array.isArray(value)) {\n // Recursively process nested objects (but not arrays or null)\n result[key] = processCMSPropsTemplate(value as Record<string, unknown>, cmsItem, locale, i18nConfig);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n", "/**\n * Image metadata handling for SSR\n * Loads image manifest and builds metadata map for responsive images\n */\n\nimport { projectPaths } from '../projectContext';\nimport * as path from 'path';\nimport { escapeHtml } from './attributeBuilder';\nimport { readTextFile, fileExists } from '../runtime';\n\n/**\n * Image metadata for SSR rendering\n */\nexport interface ImageMetadata {\n /** WebP srcset string */\n srcset: string;\n /** AVIF srcset string (if available) */\n avifSrcset?: string;\n /** Original image width */\n width?: number;\n /** Original image height */\n height?: number;\n /** Base64 blur placeholder data URL */\n blurHash?: string;\n}\n\n/**\n * Image metadata map - maps image URLs to their metadata\n */\nexport type ImageMetadataMap = Map<string, ImageMetadata>;\n\n/**\n * Responsive image widths for variant detection (optimized for mobile 2x/3x DPR and desktop)\n */\nexport const RESPONSIVE_WIDTHS = [500, 800, 1080, 1600, 2400] as const;\n\n/**\n * Default sizes attribute for responsive images\n */\nexport const DEFAULT_SIZES = '100vw';\n\n/**\n * Build image metadata map from manifest\n * Returns a map of image URL -> metadata (srcset, avifSrcset, dimensions, blurHash)\n */\nexport async function buildImageMetadataMap(): Promise<ImageMetadataMap> {\n const metadataMap = new Map<string, ImageMetadata>();\n\n try {\n const imagesDir = projectPaths.images();\n const manifestPath = path.join(imagesDir, 'manifest.json');\n\n // Try to load manifest\n if (!(await fileExists(manifestPath))) {\n return metadataMap;\n }\n\n const manifestContent = await readTextFile(manifestPath);\n const manifest = JSON.parse(manifestContent) as {\n version: number;\n images: Record<string, {\n filename: string;\n width: number;\n height: number;\n blurHash: string;\n formats: { avif: boolean; webp: boolean };\n variants: { width: number; webpFilename: string; avifFilename: string }[];\n }>;\n };\n\n // Build metadata for each image\n for (const [filename, entry] of Object.entries(manifest.images)) {\n const baseName = path.basename(filename, path.extname(filename));\n\n // Build WebP srcset\n const webpSrcsetParts: string[] = [];\n const avifSrcsetParts: string[] = [];\n\n // Add variants\n for (const variant of entry.variants) {\n webpSrcsetParts.push(\n `/images/${encodeURIComponent(variant.webpFilename)} ${variant.width}w`\n );\n if (variant.avifFilename) {\n avifSrcsetParts.push(\n `/images/${encodeURIComponent(variant.avifFilename)} ${variant.width}w`\n );\n }\n }\n\n // Add main image as largest option (use original width or 2400 as fallback)\n const mainWidth = entry.width || 2400;\n if (entry.formats.webp) {\n webpSrcsetParts.push(`/images/${encodeURIComponent(`${baseName}.webp`)} ${mainWidth}w`);\n } else {\n webpSrcsetParts.push(`/images/${encodeURIComponent(filename)} ${mainWidth}w`);\n }\n if (entry.formats.avif) {\n avifSrcsetParts.push(`/images/${encodeURIComponent(`${baseName}.avif`)} ${mainWidth}w`);\n }\n\n const metadata: ImageMetadata = {\n srcset: webpSrcsetParts.join(', '),\n width: entry.width,\n height: entry.height,\n blurHash: entry.blurHash,\n };\n\n if (avifSrcsetParts.length > 0) {\n metadata.avifSrcset = avifSrcsetParts.join(', ');\n }\n\n // Map both /images/filename and /images/encoded-filename\n metadataMap.set(`/images/${filename}`, metadata);\n metadataMap.set(`/images/${encodeURIComponent(filename)}`, metadata);\n }\n } catch (error) {\n console.error('Failed to build image metadata map:', error);\n }\n\n return metadataMap;\n}\n\n/**\n * Extract the src attribute value from an <img> tag string.\n * Handles both src=\"...\" and src='...' quoting.\n */\nexport function extractImgSrc(imgTag: string): string | null {\n const match = imgTag.match(/src=[\"']([^\"']+)[\"']/i);\n return match ? match[1] : null;\n}\n\n/**\n * Rewrite <img> tags in rich-text HTML to <picture> elements with responsive variants.\n * Only rewrites images that exist in the metadata map (project images with generated variants).\n * External/unrecognized images are left unchanged.\n */\nexport function rewriteRichTextImages(html: string, metadataMap: ImageMetadataMap): string {\n return html.replace(/<img\\b([^>]*)\\/?>/gi, (fullMatch, innerAttrs: string) => {\n const src = extractImgSrc(fullMatch);\n if (!src) return fullMatch;\n\n const metadata = metadataMap.get(src);\n if (!metadata) return fullMatch;\n\n // Check if width/height already present in original tag\n const hasWidth = /width=/i.test(innerAttrs);\n const hasHeight = /height=/i.test(innerAttrs);\n\n // Inject width/height if missing and available from metadata\n let enhancedTag = fullMatch;\n if (!hasWidth && metadata.width) {\n enhancedTag = enhancedTag.replace(/<img\\b/i, `<img width=\"${escapeHtml(String(metadata.width))}\"`);\n }\n if (!hasHeight && metadata.height) {\n enhancedTag = enhancedTag.replace(/<img\\b/i, `<img height=\"${escapeHtml(String(metadata.height))}\"`);\n }\n\n const sizes = DEFAULT_SIZES;\n\n // Render as <picture> with AVIF + WebP sources when AVIF is available\n if (metadata.avifSrcset) {\n return `<picture>` +\n `<source type=\"image/avif\" srcset=\"${escapeHtml(metadata.avifSrcset)}\" sizes=\"${escapeHtml(sizes)}\" />` +\n `<source type=\"image/webp\" srcset=\"${escapeHtml(metadata.srcset)}\" sizes=\"${escapeHtml(sizes)}\" />` +\n enhancedTag +\n `</picture>`;\n }\n\n // WebP only: add srcset and sizes to existing <img>\n if (metadata.srcset) {\n enhancedTag = enhancedTag.replace(/<img\\b/i,\n `<img srcset=\"${escapeHtml(metadata.srcset)}\" sizes=\"${escapeHtml(sizes)}\"`\n );\n }\n\n return enhancedTag;\n });\n}\n", "/**\n * Server-Side Rendering (SSR) Core Module\n * Converts JSON component structures to HTML strings for SEO-friendly initial page loads\n */\n\nimport type { ComponentNode, ComponentDefinition, JSONPage, CMSItem, EmbedNode, LinkNode, LocaleListNode, CMSFilterCondition } from '../../shared/types';\nimport type { TemplateContext, NestedCMSListConfig } from '../../shared/types/cms';\nimport { processItemTemplate, processItemPropsTemplate, hasItemTemplates, buildTemplateContext, resolveItemsTemplate, resolveTemplateRawValue, addItemUrl, getNestedValue, type ValueResolver } from '../../shared/itemTemplateUtils';\nimport { singularize, isItemDraftForLocale } from '../../shared/types/cms';\nimport type { ResponsiveStyleObject, StyleObject } from '../../shared/types';\nimport type { BreakpointConfig } from '../../shared/breakpoints';\nimport { evaluateTemplate, processStructure, isResponsiveStyle, isHtmlMapping, resolveHtmlMapping } from '../../client/templateEngine';\nimport { resolvePropsFromDefinition, isRichTextMarker, richTextMarkerToHtml } from '../../shared/propResolver';\nimport { loadBreakpointConfig, loadI18nConfig } from '../jsonLoader';\nimport type { I18nConfig } from '../../shared/types/components';\nimport { extractLocaleFromPath, DEFAULT_I18N_CONFIG, resolveI18nValue, buildLocalizedPath, isI18nValue } from '../../shared/i18n';\nimport { NODE_TYPE } from '../../shared/constants';\nimport { isComponentNode, isHtmlNode, isLinkNode, isEmbedNode, isLocaleListNode, isListNode, markAsSlotContent, isBooleanMapping } from '../../shared/nodeUtils';\nimport type { ListNode } from '../../shared/registry/nodeTypes/ListNodeType';\nimport type { CMSService } from '../services/cmsService';\nimport { extractAttributesFromNode, skipEmptyTemplateAttributes } from '../../shared/attributeNodeUtils';\nimport { SSRRegistry } from '../../shared/registry/SSRRegistry';\nimport { mergeResponsiveStyles } from '../../shared/responsiveStyleUtils';\n// Lazy-loaded: jsdom (used by isomorphic-dompurify on the server) can't be bundled by esbuild\n// because it reads CSS files relative to __dirname at init time. When the module is unavailable\n// (packaged Electron app), embed HTML is returned unsanitized \u2014 acceptable since content is local.\nlet _DOMPurify: any = null;\nlet _DOMPurifyLoaded = false;\nfunction getDOMPurify() {\n if (!_DOMPurifyLoaded) {\n _DOMPurifyLoaded = true;\n try {\n _DOMPurify = require('isomorphic-dompurify');\n if (_DOMPurify.default) _DOMPurify = _DOMPurify.default;\n } catch {\n // Not available in bundled environment\n }\n }\n return _DOMPurify;\n}\nimport { responsiveStylesToClasses } from '../../shared/utilityClassMapper';\nimport { validateStyleCoverage } from '../validateStyleCoverage';\nimport { generateElementClassName, type ElementClassContext } from '../../shared/elementClassName';\nimport type { InteractiveStyles } from '../../shared/types/styles';\nimport { extractInteractiveStyleMappings, resolveExtractedMappings, hasInteractiveStyleMappings } from '../../shared/interactiveStyleMappings';\nimport { isCurrentLink } from '../../shared/linkUtils';\nimport type { SlugMap } from '../../shared/slugTranslator';\nimport { buildSlugIndex, getLocaleLinks, translatePath } from '../../shared/slugTranslator';\n\n// Import from modularized files\nimport { escapeHtml, buildAttributes, styleToString } from './attributeBuilder';\nimport { extractPageMeta, generateMetaTags } from './metaTagGenerator';\nimport { collectComponentCSS } from './cssCollector';\nimport { collectComponentJavaScript } from './jsCollector';\nimport { CMSContext, processCMSTemplate, processCMSPropsTemplate, createI18nResolver, RAW_HTML_PREFIX } from './cmsSSRProcessor';\nimport { ImageMetadataMap, DEFAULT_SIZES, buildImageMetadataMap, rewriteRichTextImages } from './imageMetadata';\n\n/**\n * Image preload info for generating <link rel=\"preload\"> tags in head\n */\nexport interface PreloadImage {\n /** Best available srcset (AVIF preferred, then WebP) */\n srcset: string;\n /** Image type (image/avif or image/webp) */\n type: 'image/avif' | 'image/webp';\n /** Sizes attribute */\n sizes: string;\n}\n\n// Re-export types for external consumers\nexport type { CMSContext } from './cmsSSRProcessor';\nexport type { PageMeta } from './metaTagGenerator';\nexport { extractPageMeta, generateMetaTags } from './metaTagGenerator';\n\n/**\n * SSR rendering context - passed through the render chain\n */\ninterface SSRContext {\n locale?: string;\n i18nConfig?: I18nConfig;\n slugMappings?: SlugMap[];\n pagePath?: string;\n breakpoints?: BreakpointConfig;\n viewportWidth?: number;\n cmsContext?: CMSContext;\n imageMetadataMap?: ImageMetadataMap;\n cmsService?: CMSService;\n /** Template context for CMSList iteration with named contexts */\n templateContext?: TemplateContext;\n /** Element path for tracking position in tree (for element class generation) */\n elementPath?: number[];\n /** Map to collect interactive styles during render */\n interactiveStylesMap?: Map<string, InteractiveStyles>;\n /** Component context for tracking when inside a component definition */\n componentContext?: string;\n /** Resolved component props for interactive style mapping resolution */\n componentResolvedProps?: Record<string, unknown>;\n /** Array to collect high-priority images for preloading */\n preloadImages?: PreloadImage[];\n /**\n * Template mode: preserve {{item.field}} placeholders instead of processing them.\n * Used when emitting item templates for client-side dynamic rendering.\n */\n templateMode?: boolean;\n /**\n * When true, nested cms-list nodes should be emitted as placeholders\n * for client-side hydration rather than fully rendered.\n * Set when parent cms-list has emitTemplate: true.\n */\n nestedCMSListMode?: boolean;\n /**\n * Set of collection IDs that need client-side data injection.\n * Populated during rendering when nested cms-list placeholders are emitted.\n * Used by build process to prepare and inject collection data scripts.\n */\n neededCollections?: Set<string>;\n /** When true, draft items are filtered out from CMS lists */\n isProductionBuild?: boolean;\n}\n\n/**\n * Get template context from SSRContext (for use with shared itemTemplateUtils)\n * Returns the full TemplateContext which includes named contexts\n */\nfunction getTemplateContext(ctx: SSRContext): TemplateContext | null {\n return ctx.templateContext || null;\n}\n\n/**\n * Create a value resolver for i18n resolution (for use with item templates)\n */\nfunction getI18nResolver(ctx: SSRContext): ValueResolver | undefined {\n return createI18nResolver(ctx.locale, ctx.i18nConfig);\n}\n\n/**\n * Localize an internal href to the current locale.\n * Reusable helper extracted from LinkNode rendering.\n */\nfunction localizeHref(href: string, ctx: SSRContext): string {\n if (ctx.templateMode) return href;\n if (!href.startsWith('/') || href.startsWith('//')) return href;\n const { locale, i18nConfig, slugMappings } = ctx;\n if (!locale || !i18nConfig) return href;\n if (slugMappings) {\n const slugIndex = buildSlugIndex(slugMappings);\n return translatePath(href, locale, i18nConfig.defaultLocale, i18nConfig.defaultLocale, slugIndex);\n } else if (locale !== i18nConfig.defaultLocale) {\n return buildLocalizedPath(href, locale);\n }\n return href;\n}\n\n/**\n * Localize <a href=\"...\"> links within rich-text HTML output.\n * Similar pattern to rewriteRichTextImages.\n */\nfunction localizeRichTextLinks(html: string, ctx: SSRContext): string {\n if (ctx.templateMode || !ctx.locale || !ctx.i18nConfig) return html;\n return html.replace(\n /<a\\b([^>]*?)href=([\"'])([^\"']*?)\\2([^>]*?)>/gi,\n (match, before, quote, href, after) => {\n if (!href.startsWith('/') || href.startsWith('//')) return match;\n const localized = localizeHref(href, ctx);\n return localized === href ? match : `<a${before}href=${quote}${localized}${quote}${after}>`;\n }\n );\n}\n\n/**\n * Process style templates and convert to utility classes.\n * Handles {{item.field}} patterns within list contexts.\n */\nfunction processStyleToClasses(\n style: StyleObject | ResponsiveStyleObject | undefined,\n ctx: SSRContext\n): string[] {\n if (!style) return [];\n\n let processedStyle = style;\n const templateCtx = getTemplateContext(ctx);\n if (templateCtx && !ctx.templateMode) {\n processedStyle = processItemPropsTemplate(\n style as Record<string, unknown>,\n templateCtx,\n getI18nResolver(ctx)\n ) as StyleObject | ResponsiveStyleObject;\n }\n return responsiveStylesToClasses(processedStyle as ResponsiveStyleObject);\n}\n\n/**\n * Evaluate the if condition on a node with full SSR context.\n * Handles boolean, mapping, and string template values.\n * Returns true if node should be rendered, false if it should be skipped.\n */\nfunction evaluateIfCondition(node: ComponentNode, ctx: SSRContext): boolean {\n const ifValue = (node as any).if;\n\n // No if property = render (default true)\n if (ifValue === undefined) {\n return true;\n }\n\n // Boolean value\n if (typeof ifValue === 'boolean') {\n return ifValue;\n }\n\n // Mapping value - resolve using component props\n if (isBooleanMapping(ifValue)) {\n const props = ctx.componentResolvedProps || {};\n const propValue = props[ifValue.prop];\n const mappedValue = ifValue.values[String(propValue)];\n // If no mapping found for this prop value, default to true\n return mappedValue !== undefined ? Boolean(mappedValue) : true;\n }\n\n // String template - resolve using CMS or item context\n if (typeof ifValue === 'string') {\n let resolved: string = ifValue;\n\n // Process item templates first (for CMSList context)\n const templateCtx = getTemplateContext(ctx);\n if (templateCtx && hasItemTemplates(resolved)) {\n resolved = processItemTemplate(resolved, templateCtx, getI18nResolver(ctx));\n }\n\n // Process CMS template strings like {{cms.field}}\n if (ctx.cmsContext?.cms && resolved.includes('{{cms.')) {\n resolved = processCMSTemplate(resolved, ctx.cmsContext.cms, ctx.locale, ctx.i18nConfig);\n }\n\n // Evaluate truthiness - false, 0, empty string are falsy\n return Boolean(resolved) && resolved !== 'false' && resolved !== '0' && resolved !== '';\n }\n\n // Unknown type, default to true\n return true;\n}\n\n/**\n * Resolve a template value like \"{{category.slug}}\" from template context.\n * Returns the original value if not a template or can't be resolved.\n */\nfunction resolveFilterValue(value: unknown, templateContext: TemplateContext | undefined): unknown {\n if (!templateContext || typeof value !== 'string' || !value.startsWith('{{') || !value.endsWith('}}')) {\n return value;\n }\n const path = value.slice(2, -2).trim();\n const resolved = getNestedValue(templateContext as Record<string, unknown>, path);\n return resolved !== undefined ? resolved : value;\n}\n\n/**\n * Resolve template values in CMS filter for nested cms-list support.\n * Handles filter values like \"{{category.slug}}\" from parent template context.\n */\nfunction resolveFilterTemplates(\n filter: CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined,\n templateContext: TemplateContext | undefined\n): CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined {\n if (!filter || !templateContext) return filter;\n\n // Handle array of conditions\n if (Array.isArray(filter)) {\n return filter.map(cond => ({\n ...cond,\n value: resolveFilterValue(cond.value, templateContext)\n }));\n }\n\n // Handle single condition object with field/value\n if ('field' in filter && 'value' in filter) {\n return {\n ...(filter as CMSFilterCondition),\n value: resolveFilterValue((filter as CMSFilterCondition).value, templateContext)\n };\n }\n\n // Handle simple object filter: { category: \"{{category.slug}}\" }\n const resolved: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(filter)) {\n resolved[key] = resolveFilterValue(value, templateContext);\n }\n return resolved;\n}\n\n/**\n * Expand Meno component markers in rich text HTML output.\n * Scans for <div data-meno-component=\"Name\" data-meno-props='{\"key\":\"val\"}'></div>\n * and replaces them with rendered component HTML using the existing SSR component renderer.\n */\nasync function expandRichTextComponents(html: string, ctx: SSRContext): Promise<string> {\n // Quick check - if no component markers, return as-is\n if (!html.includes('data-meno-component')) return html;\n\n // Match component markers\n const markerRegex = /<div\\s+data-meno-component=\"([^\"]+)\"\\s+data-meno-props=\"([^\"]*)\"[^>]*><\\/div>/g;\n const parts: (string | Promise<string>)[] = [];\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = markerRegex.exec(html)) !== null) {\n // Add text before this match\n if (match.index > lastIndex) {\n parts.push(html.slice(lastIndex, match.index));\n }\n\n const componentName = match[1];\n let props: Record<string, unknown> = {};\n try {\n // Unescape HTML entities in the JSON\n const propsStr = match[2]\n .replace(/&quot;/g, '\"')\n .replace(/&#039;/g, \"'\")\n .replace(/&amp;/g, '&');\n props = JSON.parse(propsStr);\n } catch {\n // ignore parse errors\n }\n\n // Render the component using SSR registry\n if (ssrComponentRegistry.has(componentName)) {\n parts.push(\n renderComponent(componentName, props, [], {}, ctx)\n );\n } else {\n // Keep marker for unknown components\n parts.push(match[0]);\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add remaining text\n if (lastIndex < html.length) {\n parts.push(html.slice(lastIndex));\n }\n\n // Resolve all promises\n const resolved = await Promise.all(parts);\n return resolved.join('');\n}\n\n/**\n * Component registry for SSR (shared between requests)\n * Uses the shared SSRRegistry for consistency\n */\nconst ssrComponentRegistry = new SSRRegistry();\n\n/**\n * Build HTML string from component node (server-side)\n * Exported for component preview rendering\n */\nexport async function buildComponentHTML(\n node: ComponentNode | ComponentNode[] | string | number | null | undefined,\n globalComponents: Record<string, ComponentDefinition> = {},\n pageComponents: Record<string, ComponentDefinition> = {},\n locale?: string,\n i18nConfig?: I18nConfig,\n slugMappings?: SlugMap[],\n pagePath?: string,\n cmsContext?: CMSContext,\n cmsService?: CMSService,\n isProductionBuild?: boolean\n): Promise<{ html: string; interactiveStylesMap: Map<string, InteractiveStyles>; preloadImages: PreloadImage[]; neededCollections: Set<string> }> {\n // Create map to collect interactive styles during render\n const interactiveStylesMap = new Map<string, InteractiveStyles>();\n // Create array to collect high-priority images for preloading\n const preloadImages: PreloadImage[] = [];\n // Create set to track collections that need client-side data injection\n const neededCollections = new Set<string>();\n\n if (!node) return { html: '', interactiveStylesMap, preloadImages, neededCollections };\n\n // Register components for this render\n ssrComponentRegistry.merge(globalComponents);\n ssrComponentRegistry.merge(pageComponents);\n\n // Load breakpoint config for responsive style resolution\n const breakpoints = await loadBreakpointConfig();\n\n // Build image metadata map for responsive images (from manifest)\n const imageMetadataMap = await buildImageMetadataMap();\n\n // Render using desktop viewport (1920px) - same as editor system\n const SSR_VIEWPORT_WIDTH = 1920;\n\n // Build SSR context\n const ctx: SSRContext = {\n locale,\n i18nConfig,\n slugMappings,\n pagePath,\n breakpoints,\n viewportWidth: SSR_VIEWPORT_WIDTH,\n cmsContext,\n imageMetadataMap,\n cmsService,\n elementPath: [0], // Initialize path tracking for interactive styles\n interactiveStylesMap, // Collect interactive styles during render\n preloadImages, // Collect high-priority images for preloading\n neededCollections, // Track collections that need client-side data\n isProductionBuild,\n };\n\n const html = await renderNode(node, ctx);\n\n return { html, interactiveStylesMap, preloadImages, neededCollections };\n}\n\n/**\n * Render a nested list (collection mode) as a placeholder for client-side hydration.\n * Used when parent list has emitTemplate: true.\n * The placeholder contains the configuration and template for MenoFilter to hydrate.\n */\nasync function renderNestedListPlaceholder(\n node: ListNode,\n ctx: SSRContext\n): Promise<string> {\n // Get source - handle both string and pre-resolved array sources\n const sourceValue = node.source || (node as any).collection;\n const sourceStr = typeof sourceValue === 'string' ? sourceValue : '';\n\n // Track this collection for client-side data injection\n if (ctx.neededCollections && sourceStr) {\n ctx.neededCollections.add(sourceStr);\n }\n\n // Build configuration for client-side hydration\n const config: NestedCMSListConfig = {\n collection: sourceStr,\n itemAs: node.itemAs,\n items: node.items,\n filter: node.filter as CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined,\n sort: node.sort,\n limit: node.limit,\n offset: node.offset,\n excludeCurrentItem: node.excludeCurrentItem,\n };\n\n // Render children template (preserving {{item.field}} placeholders)\n const childTemplateCtx: SSRContext = {\n ...ctx,\n templateMode: true,\n templateContext: undefined, // Clear context for inner item templates\n nestedCMSListMode: false, // Reset for deeper nesting levels\n };\n const templateContent = node.children\n ? await renderChildrenAsync(node.children, childTemplateCtx)\n : '';\n\n // Escape config for attribute\n const configJson = escapeHtml(JSON.stringify(config));\n\n // Emit placeholder with embedded config and template\n return `<div data-cms-list-nested=\"true\" data-collection=\"${escapeHtml(sourceStr)}\" data-cms-config=\"${configJson}\">` +\n `<template data-nested-template>${templateContent}</template>` +\n `</div>`;\n}\n\n/**\n * Unified List node processor - renders children for each item\n * Supports both source types:\n * - 'prop': Reads from component props or template context\n * - 'collection': Queries from CMS collections\n */\nasync function processList(node: ListNode, ctx: SSRContext): Promise<string> {\n // Determine source type (default to 'prop', but handle legacy 'cms-list' type)\n const nodeType = (node as any).type;\n const isLegacyCMSList = nodeType === 'cms-list';\n const sourceType = isLegacyCMSList ? 'collection' : (node.sourceType || 'prop');\n\n // For collection mode, check CMS service availability\n if (sourceType === 'collection' && !ctx.cmsService) {\n console.warn('List with sourceType \"collection\" requires CMS service');\n return '';\n }\n\n // When in templateMode with nestedCMSListMode, emit placeholder for client-side hydration\n // This allows nested lists inside emitTemplate to work with MenoFilter\n if (sourceType === 'collection' && ctx.templateMode && ctx.nestedCMSListMode) {\n return renderNestedListPlaceholder(node, ctx);\n }\n\n // Get source - handle both new 'source' and legacy 'collection' property\n // Source can be a string (prop name) or array (pre-resolved by processStructure)\n const rawSource = node.source || (node as any).collection;\n const source = typeof rawSource === 'string' ? rawSource : '';\n const sourceIsResolved = Array.isArray(rawSource);\n\n // Determine variable name for this list's items\n let variableName: string;\n if (node.itemAs) {\n variableName = node.itemAs;\n } else if (sourceType === 'collection') {\n variableName = singularize(source);\n } else {\n variableName = 'item';\n }\n\n // Get items based on sourceType\n let items: unknown[];\n\n if (sourceType === 'collection') {\n // Collection mode: Query from CMS service\n items = await getCollectionItems(node, source, ctx);\n } else {\n // Prop mode: Read from component props or template context\n // If source was already resolved to an array by processStructure (e.g., from {{features}}),\n // use it directly instead of looking up by prop name\n if (sourceIsResolved) {\n // Source was resolved to array by processStructure\n items = rawSource as unknown[];\n } else if (source) {\n // Source is a prop name or template expression - resolve it\n items = getPropItems(source, ctx);\n } else {\n items = [];\n }\n }\n\n // Apply shared options: offset and limit\n if (node.offset && sourceType === 'prop') {\n items = items.slice(node.offset);\n }\n if (node.limit && sourceType === 'prop') {\n items = items.slice(0, node.limit);\n }\n\n if (items.length === 0) {\n return '';\n }\n\n // Get schema for URL computation (collection mode only)\n const schema = sourceType === 'collection' && ctx.cmsService\n ? ctx.cmsService.getSchema(source)\n : undefined;\n\n // Render children for each item\n const renderedItems: string[] = [];\n\n for (let i = 0; i < items.length; i++) {\n const rawItem = items[i] as Record<string, unknown>;\n const item = schema\n ? addItemUrl(rawItem as CMSItem, schema, ctx.locale, ctx.i18nConfig)\n : rawItem;\n\n const templateContext = buildTemplateContext(\n variableName,\n item as CMSItem,\n i,\n items.length,\n ctx.templateContext\n );\n\n const itemCtx: SSRContext = {\n ...ctx,\n templateContext,\n };\n\n const childrenHtml = await renderChildrenAsync(node.children || [], itemCtx);\n renderedItems.push(childrenHtml);\n }\n\n const childrenHTML = renderedItems.join('');\n\n // Emit item template when emitTemplate is enabled (collection mode)\n // This allows MenoFilter to dynamically render items from JSON data\n let templateHtml = '';\n if (sourceType === 'collection' && node.emitTemplate && node.children && node.children.length > 0) {\n const templateCtx: SSRContext = {\n ...ctx,\n templateMode: true,\n templateContext: ctx.templateContext,\n nestedCMSListMode: true,\n };\n const templateContent = await renderChildrenAsync(node.children, templateCtx);\n templateHtml = `<template data-meno-item>${templateContent}</template>`;\n }\n\n // List is a pure repeater - no container element, just children + optional template\n return childrenHTML + templateHtml;\n}\n\n/**\n * Get items from CMS collection (for sourceType: 'collection')\n */\nasync function getCollectionItems(node: ListNode, source: string, ctx: SSRContext): Promise<CMSItem[]> {\n if (!ctx.cmsService) return [];\n\n let items: CMSItem[];\n\n // Check if items are specified directly (for nested reference lists)\n if (node.items) {\n // If items is a template expression, resolve it from current context\n if (typeof node.items === 'string' && node.items.startsWith('{{')) {\n let resolvedIds: string | string[] | undefined;\n\n // Check if this is a CMS template ({{cms.field}}) - resolve from cmsContext\n if (node.items.startsWith('{{cms.') && ctx.cmsContext?.cms) {\n const fieldPath = node.items.slice(6, -2); // Extract \"field\" from \"{{cms.field}}\"\n let value: unknown = ctx.cmsContext.cms;\n for (const part of fieldPath.split('.')) {\n if (value && typeof value === 'object' && part in value) {\n value = (value as Record<string, unknown>)[part];\n } else {\n value = undefined;\n break;\n }\n }\n if (value !== null && value !== undefined) {\n resolvedIds = Array.isArray(value) ? value.map(v => String(v)) : String(value);\n }\n } else {\n // Otherwise resolve from template context (for nested lists)\n const parentContext = ctx.templateContext || { _type: 'template' as const };\n resolvedIds = resolveItemsTemplate(node.items, parentContext);\n }\n\n if (!resolvedIds) {\n return [];\n }\n const ids = Array.isArray(resolvedIds) ? resolvedIds : [resolvedIds];\n items = await ctx.cmsService.getItemsByIds(source, ids);\n } else {\n // Direct IDs (string or array)\n const ids = Array.isArray(node.items) ? node.items : [node.items];\n items = await ctx.cmsService.getItemsByIds(source, ids);\n }\n // Filter draft items from ID-based queries\n if (ctx.locale) {\n items = items.filter(item => !isItemDraftForLocale(item, ctx.locale!));\n }\n } else {\n // Build query from node props (resolve filter templates for nested list support)\n const query = {\n collection: source,\n filter: resolveFilterTemplates(node.filter as CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined, ctx.templateContext),\n sort: node.sort,\n limit: node.limit,\n offset: node.offset,\n excludeDraftLocale: ctx.locale,\n };\n items = await ctx.cmsService.queryItems(query);\n }\n\n // Exclude current item if option is set and we have a current CMS context\n if (node.excludeCurrentItem && ctx.cmsContext?.cms?._id) {\n const currentId = ctx.cmsContext.cms._id as string;\n items = items.filter(item => item._id !== currentId);\n }\n\n return items;\n}\n\n/**\n * Get items from component props or template context (for sourceType: 'prop')\n */\nfunction getPropItems(source: string, ctx: SSRContext): unknown[] {\n // Resolve the source - can be a direct prop name or a template expression\n if (source.startsWith('{{') && source.endsWith('}}')) {\n // Template expression - resolve from template context (for nested lists)\n // e.g., {{category.items}} where category is from parent list\n const templateCtx = ctx.templateContext;\n if (templateCtx) {\n const path = source.slice(2, -2).trim(); // Extract \"category.items\"\n const resolved = getNestedValue(templateCtx as Record<string, unknown>, path);\n if (Array.isArray(resolved)) {\n return resolved;\n } else if (resolved !== undefined) {\n // Warn if resolved to non-array value (likely a bug in template)\n console.warn(`List source \"${source}\" resolved to non-array value (type: ${typeof resolved})`);\n }\n }\n return [];\n } else {\n // Direct prop name - resolve from component props\n const propValue = ctx.componentResolvedProps?.[source];\n if (Array.isArray(propValue)) {\n return propValue;\n }\n\n // Also try template context for prop mode (for cms context values)\n if (ctx.cmsContext?.cms) {\n const cmsValue = ctx.cmsContext.cms[source];\n if (Array.isArray(cmsValue)) {\n return cmsValue;\n }\n }\n }\n return [];\n}\n\n/**\n * Render children array asynchronously\n */\nasync function renderChildrenAsync(children: unknown[], ctx: SSRContext): Promise<string> {\n const rendered: string[] = [];\n for (let index = 0; index < children.length; index++) {\n const child = children[index];\n const childPath = ctx.elementPath ? [...ctx.elementPath, index] : [index];\n rendered.push(await renderNode(child as ComponentNode | string | number, { ...ctx, elementPath: childPath }));\n }\n return rendered.join('');\n}\n\n/**\n * Build element class name for a node based on its SSR context.\n * Used by embed, link, locale-list, and regular HTML nodes.\n */\nfunction buildNodeElementClass(\n ctx: SSRContext,\n label: string | undefined,\n isSlotContent?: boolean\n): string {\n const { pagePath } = ctx;\n // Slot content uses page context (defined in page, not component)\n const useComponentContext = !isSlotContent && Boolean(ctx.componentContext);\n const effectiveFileType = useComponentContext ? 'component' : 'page';\n const effectiveFileName = useComponentContext ? ctx.componentContext : (pagePath\n ? pagePath.replace(/^\\//, '').replace(/\\//g, '_') || 'index'\n : 'page');\n\n const elementClassCtx: ElementClassContext = {\n fileType: effectiveFileType,\n fileName: effectiveFileName || 'page',\n label,\n path: ctx.elementPath || [],\n };\n return generateElementClassName(elementClassCtx);\n}\n\n/**\n * Register interactive styles for CSS generation with mapping support.\n * Returns CSS variable overrides (if any) from resolved prop mappings.\n */\nfunction registerInteractiveStyles(\n ctx: SSRContext,\n elementClass: string,\n interactiveStyles: InteractiveStyles\n): Record<string, string> {\n if (!ctx.interactiveStylesMap) return {};\n\n if (ctx.componentResolvedProps && hasInteractiveStyleMappings(interactiveStyles)) {\n const { resolvedStyles, mappings } = extractInteractiveStyleMappings(interactiveStyles);\n const cssVariables = resolveExtractedMappings(mappings, ctx.componentResolvedProps);\n ctx.interactiveStylesMap.set(elementClass, resolvedStyles);\n return cssVariables;\n }\n\n ctx.interactiveStylesMap.set(elementClass, interactiveStyles);\n return {};\n}\n\n/**\n * Build inline style attribute string from CSS variable overrides.\n */\nfunction buildCssVariableStyleAttr(cssVariables: Record<string, string>): string {\n if (Object.keys(cssVariables).length === 0) return '';\n const styleString = Object.entries(cssVariables)\n .map(([k, v]) => `${k}: ${v}`)\n .join('; ');\n return ` style=\"${escapeHtml(styleString)}\"`;\n}\n\n/**\n * Render a node (or array of nodes) to HTML string\n */\nasync function renderNode(\n node: ComponentNode | ComponentNode[] | string | number | null | undefined,\n ctx: SSRContext\n): Promise<string> {\n const { breakpoints, viewportWidth, locale, i18nConfig, slugMappings, pagePath } = ctx;\n\n if (node === null || node === undefined) return '';\n\n if (typeof node === 'string' || typeof node === 'number') {\n let text = String(node);\n\n // In template mode, preserve {{item.field}} placeholders for client-side rendering\n if (ctx.templateMode) {\n // Only process CMS template strings ({{cms.field}}) - preserve item templates\n if (ctx.cmsContext?.cms && text.includes('{{cms.')) {\n text = processCMSTemplate(text, ctx.cmsContext.cms, locale, i18nConfig);\n }\n // Check for raw HTML marker (from rich-text fields) - don't escape\n if (text.startsWith(RAW_HTML_PREFIX)) {\n let rawHtml = text.slice(RAW_HTML_PREFIX.length);\n if (ctx.imageMetadataMap) rawHtml = rewriteRichTextImages(rawHtml, ctx.imageMetadataMap);\n rawHtml = await expandRichTextComponents(rawHtml, ctx);\n rawHtml = localizeRichTextLinks(rawHtml, ctx);\n return rawHtml;\n }\n return escapeHtml(text);\n }\n\n // Normal mode: Process item template strings first (for CMSList context)\n const templateCtx = getTemplateContext(ctx);\n if (templateCtx && hasItemTemplates(text)) {\n text = processItemTemplate(text, templateCtx, getI18nResolver(ctx));\n }\n // Process CMS template strings like {{cms.title}}\n if (ctx.cmsContext?.cms && text.includes('{{cms.')) {\n text = processCMSTemplate(text, ctx.cmsContext.cms, locale, i18nConfig);\n }\n // Check for raw HTML marker (from rich-text fields) - don't escape\n if (text.startsWith(RAW_HTML_PREFIX)) {\n let rawHtml = text.slice(RAW_HTML_PREFIX.length);\n if (ctx.imageMetadataMap) rawHtml = rewriteRichTextImages(rawHtml, ctx.imageMetadataMap);\n rawHtml = await expandRichTextComponents(rawHtml, ctx);\n rawHtml = localizeRichTextLinks(rawHtml, ctx);\n return rawHtml;\n }\n return escapeHtml(text);\n }\n\n if (Array.isArray(node)) {\n return (await Promise.all(node.map((child, index) => {\n const childPath = ctx.elementPath ? [...ctx.elementPath.slice(0, -1), index] : [index];\n return renderNode(child, { ...ctx, elementPath: childPath });\n }))).join('');\n }\n\n if (typeof node !== 'object') return '';\n\n // Check if condition - skip rendering if false\n if (!evaluateIfCondition(node as ComponentNode, ctx)) {\n return '';\n }\n\n // Handle List nodes (async operation - handles both prop and collection source types)\n // isListNode() also matches legacy 'cms-list' type for migration\n if (isListNode(node)) {\n return await processList(node, ctx);\n }\n\n const nodeType = 'type' in node ? node.type : undefined;\n const nodeStyle = ('style' in node) ? node.style as StyleObject | ResponsiveStyleObject | undefined : undefined;\n const children = ('children' in node) ? (node.children || []) : [];\n\n // Handle embed nodes - render custom HTML content\n if (isEmbedNode(node)) {\n // Resolve HTML mapping if present\n let htmlContent: string;\n if (isHtmlMapping(node.html)) {\n const resolved = resolveHtmlMapping(node.html, ctx.componentResolvedProps);\n htmlContent = resolved ?? '';\n } else if (typeof node.html === 'string') {\n htmlContent = node.html;\n } else {\n // Fallback: non-string, non-mapping value \u2014 default to empty\n htmlContent = '';\n }\n\n // In template mode, preserve {{item.field}} placeholders for client-side rendering\n if (ctx.templateMode) {\n // Only process CMS template strings ({{cms.field}}) - preserve item templates\n if (ctx.cmsContext?.cms && htmlContent.includes('{{cms.')) {\n htmlContent = processCMSTemplate(htmlContent, ctx.cmsContext.cms, locale, i18nConfig);\n }\n } else {\n // Normal mode: Process item template strings first (for CMSList context)\n const templateCtx = getTemplateContext(ctx);\n if (templateCtx && hasItemTemplates(htmlContent)) {\n htmlContent = processItemTemplate(htmlContent, templateCtx, getI18nResolver(ctx));\n }\n // Process CMS template strings like {{cms.title}}\n if (ctx.cmsContext?.cms && htmlContent.includes('{{cms.')) {\n htmlContent = processCMSTemplate(htmlContent, ctx.cmsContext.cms, locale, i18nConfig);\n }\n }\n\n // Sanitize HTML with allowlist for SVG, rich-text formatting, and common elements (same as client)\n const purify = getDOMPurify();\n const sanitizedHtml = purify ? purify.sanitize(htmlContent, {\n ALLOWED_TAGS: ['svg', 'path', 'circle', 'rect', 'line', 'polyline', 'polygon', 'g', 'text', 'tspan', 'image', 'defs', 'use', 'linearGradient', 'radialGradient', 'stop', 'clipPath', 'mask', 'pattern', 'marker', 'symbol', 'a', 'div', 'span', 'p', 'br', 'button', 'img', 'iframe', 'video', 'audio', 'source', 'canvas', 'b', 'i', 'u', 'strong', 'em', 'sub', 'sup', 'mark', 's', 'small', 'del', 'ins', 'q', 'abbr', 'code', 'pre', 'blockquote', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],\n ALLOWED_ATTR: ['class', 'id', 'style', 'width', 'height', 'viewBox', 'xmlns', 'fill', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin', 'stroke-dasharray', 'stroke-dashoffset', 'd', 'cx', 'cy', 'r', 'x', 'y', 'x1', 'y1', 'x2', 'y2', 'points', 'href', 'src', 'alt', 'target', 'rel', 'data-*', 'aria-*', 'transform', 'opacity', 'fill-opacity', 'stroke-opacity', 'font-size', 'font-family', 'text-anchor', 'dominant-baseline', 'offset', 'stop-color', 'stop-opacity', 'frameborder', 'allowfullscreen', 'allow', 'title'],\n KEEP_CONTENT: true\n }) : htmlContent;\n const optimizedHtml = ctx.imageMetadataMap\n ? rewriteRichTextImages(sanitizedHtml, ctx.imageMetadataMap)\n : sanitizedHtml;\n\n // Extract attributes from node\n const nodeAttributes = extractAttributesFromNode(node);\n\n // Build className array\n const classNames: string[] = ['oem'];\n\n // Convert styles to utility classes (process templates in style values)\n if (nodeStyle) {\n const utilityClasses = processStyleToClasses(nodeStyle, ctx);\n classNames.push(...utilityClasses);\n }\n\n // Handle interactive styles for embed nodes\n const embedInteractiveStyles = node.interactiveStyles as InteractiveStyles | undefined;\n const embedGenerateElementClass = node.generateElementClass;\n\n if ((embedInteractiveStyles && embedInteractiveStyles.length > 0) || embedGenerateElementClass) {\n const elementClass = buildNodeElementClass(ctx, node.label);\n classNames.unshift(elementClass);\n\n let embedCssVariables: Record<string, string> = {};\n if (embedInteractiveStyles && embedInteractiveStyles.length > 0) {\n embedCssVariables = registerInteractiveStyles(ctx, elementClass, embedInteractiveStyles);\n }\n\n let embedStyleAttr = buildCssVariableStyleAttr(embedCssVariables);\n\n // Add attribute className if present\n const attrClassName = (nodeAttributes.className || nodeAttributes.class || '') as string;\n if (attrClassName) {\n classNames.push(attrClassName);\n }\n delete nodeAttributes.className;\n delete nodeAttributes.class;\n\n const attrs = buildAttributes(nodeAttributes);\n const classAttr = classNames.length > 0 ? ` class=\"${escapeHtml(classNames.filter(Boolean).join(' '))}\"` : '';\n\n // Always use span for embeds - valid inside <p> and other phrasing content\n return `<span${classAttr}${embedStyleAttr}${attrs}>${optimizedHtml}</span>`;\n }\n\n // Add attribute className if present (fallback when no interactive styles)\n const attrClassName = (nodeAttributes.className || nodeAttributes.class || '') as string;\n if (attrClassName) {\n classNames.push(attrClassName);\n }\n delete nodeAttributes.className;\n delete nodeAttributes.class;\n\n const attrs = buildAttributes(nodeAttributes);\n const classAttr = classNames.length > 0 ? ` class=\"${escapeHtml(classNames.filter(Boolean).join(' '))}\"` : '';\n\n // Always use span for embeds - valid inside <p> and other phrasing content\n return `<span${classAttr}${attrs}>${optimizedHtml}</span>`;\n }\n\n // Handle link nodes (render as <a> tag in SSR)\n if (isLinkNode(node)) {\n let href: string = typeof node.href === 'string' ? node.href : '#';\n let targetFromLink: string | undefined;\n\n // Process item templates in href (for CMSList context)\n // Skip when in templateMode to preserve {{item.field}} placeholders\n const templateCtx = getTemplateContext(ctx);\n if (!ctx.templateMode && templateCtx && hasItemTemplates(href)) {\n // Get raw value first to check if it's a link object (like { href: \"/path\", target: \"_blank\" })\n const rawValue = resolveTemplateRawValue(href, templateCtx);\n if (rawValue && typeof rawValue === 'object' && 'href' in rawValue) {\n // Link object - extract href and target\n // Unwrap nested link objects (e.g., {href: {href: \"/path\"}} from double-wrapped list item templates)\n let linkObj = rawValue as { href: unknown; target?: string };\n while (typeof linkObj.href === 'object' && linkObj.href !== null && 'href' in (linkObj.href as Record<string, unknown>)) {\n const nested = linkObj.href as { href: unknown; target?: string };\n if (!linkObj.target && nested.target) linkObj = { ...linkObj, target: nested.target };\n linkObj = { ...linkObj, href: nested.href };\n }\n href = String(linkObj.href);\n targetFromLink = linkObj.target;\n } else {\n // Regular value - use string processing\n href = processItemTemplate(href, templateCtx, getI18nResolver(ctx));\n }\n }\n\n // Process CMS templates in href (e.g., {{cms.ctaLink}})\n if (ctx.cmsContext?.cms && href.includes('{{cms.')) {\n href = processCMSTemplate(href, ctx.cmsContext.cms, locale, i18nConfig);\n }\n\n // Localize internal page links to current locale\n href = localizeHref(href, ctx);\n\n // Extract attributes from node\n const nodeAttributes = extractAttributesFromNode(node);\n\n // Build className array - start with olink base class\n const classNames: string[] = ['olink'];\n\n // Convert styles to utility classes (process templates in style values)\n if (nodeStyle) {\n const utilityClasses = processStyleToClasses(nodeStyle, ctx);\n classNames.push(...utilityClasses);\n }\n\n // Handle interactive styles for link nodes\n const olinkInteractiveStyles = node.interactiveStyles as InteractiveStyles | undefined;\n const olinkGenerateElementClass = node.generateElementClass;\n let olinkCssVariables: Record<string, string> = {};\n let olinkStyleAttr = '';\n\n if ((olinkInteractiveStyles && olinkInteractiveStyles.length > 0) || olinkGenerateElementClass) {\n const elementClass = buildNodeElementClass(ctx, node.label);\n classNames.splice(1, 0, elementClass);\n\n if (olinkInteractiveStyles && olinkInteractiveStyles.length > 0) {\n olinkCssVariables = registerInteractiveStyles(ctx, elementClass, olinkInteractiveStyles);\n }\n olinkStyleAttr = buildCssVariableStyleAttr(olinkCssVariables);\n }\n\n // Add attribute className if present\n const attrClassName = (nodeAttributes.className || nodeAttributes.class || '') as string;\n if (attrClassName) {\n classNames.push(attrClassName);\n }\n delete nodeAttributes.className;\n delete nodeAttributes.class;\n\n // Add is-current class when link href matches current page path\n if (pagePath && !ctx.templateMode && isCurrentLink(href, pagePath)) {\n classNames.push('is-current');\n }\n\n // Add target from link object if present (and not already set in attributes)\n if (targetFromLink && !nodeAttributes.target) {\n nodeAttributes.target = targetFromLink;\n }\n\n const attrs = buildAttributes(nodeAttributes, ['href']);\n const classAttr = ` class=\"${escapeHtml(classNames.filter(Boolean).join(' '))}\"`;\n\n const childrenHTML = Array.isArray(children)\n ? (await Promise.all(children.map((child, index) => {\n const childPath = ctx.elementPath ? [...ctx.elementPath, index] : [index];\n return renderNode(child, { ...ctx, elementPath: childPath });\n }))).join('')\n : await renderNode(children as ComponentNode | string | number | null | undefined, { ...ctx, elementPath: ctx.elementPath ? [...ctx.elementPath, 0] : [0] });\n\n return `<a href=\"${escapeHtml(String(href))}\"${classAttr}${olinkStyleAttr}${attrs}>${childrenHTML}</a>`;\n }\n\n // Handle locale-list node type (render locale switcher links)\n if (isLocaleListNode(node)) {\n return renderLocaleList(node, ctx);\n }\n\n // Extract tag or component name based on node type\n let tag = isHtmlNode(node) ? node.tag : undefined;\n const componentName = isComponentNode(node) ? node.component : undefined;\n let nodeProps = isComponentNode(node) ? (node.props || {}) : {};\n\n // Process CMS templates in props\n if (ctx.cmsContext?.cms && Object.keys(nodeProps).length > 0) {\n nodeProps = processCMSPropsTemplate(nodeProps, ctx.cmsContext.cms, locale, i18nConfig);\n }\n\n // Process item templates in props (for CMSList context)\n // Skip when in templateMode to preserve {{item.field}} placeholders\n const templateCtx = getTemplateContext(ctx);\n const i18nResolver = getI18nResolver(ctx);\n if (!ctx.templateMode && templateCtx && Object.keys(nodeProps).length > 0) {\n nodeProps = processItemPropsTemplate(nodeProps, templateCtx, i18nResolver);\n }\n\n // Extract attributes from node\n let nodeAttributes = extractAttributesFromNode(node);\n const originalAttributes = { ...nodeAttributes };\n\n // Process CMS templates in attributes (e.g., href=\"{{cms.link}}\")\n if (ctx.cmsContext?.cms && Object.keys(nodeAttributes).length > 0) {\n nodeAttributes = processCMSPropsTemplate(nodeAttributes as Record<string, unknown>, ctx.cmsContext.cms, locale, i18nConfig) as Record<string, string | number | boolean>;\n }\n\n // Process item templates in attributes (for CMSList context)\n // Skip when in templateMode to preserve {{item.field}} placeholders\n if (!ctx.templateMode && templateCtx && Object.keys(nodeAttributes).length > 0) {\n nodeAttributes = processItemPropsTemplate(nodeAttributes, templateCtx, i18nResolver) as Record<string, string | number | boolean>;\n }\n\n // Auto-skip attributes that were entirely template expressions and resolved to \"\"\n if (Object.keys(nodeAttributes).length > 0) {\n nodeAttributes = skipEmptyTemplateAttributes(originalAttributes, nodeAttributes) as Record<string, string | number | boolean>;\n }\n\n if (!tag && !componentName) return '';\n\n // Convert styles to utility classes instead of inline styles\n let utilityClasses: string[] = [];\n let resolvedStyle: StyleObject = {};\n\n if (nodeStyle) {\n // Validate that all styles can generate utility classes (build-time warnings)\n validateStyleCoverage(nodeStyle, `Node: ${nodeType || 'unknown'}`);\n\n // Convert style object to utility class names (process templates in style values)\n utilityClasses = processStyleToClasses(nodeStyle, ctx);\n } else if (nodeProps.style) {\n // If no node.style but props have style, keep it for backward compatibility\n if (isResponsiveStyle(nodeProps.style) && breakpoints && viewportWidth) {\n resolvedStyle = mergeResponsiveStyles(nodeProps.style as ResponsiveStyleObject, 'viewport', viewportWidth, breakpoints);\n } else {\n resolvedStyle = nodeProps.style as StyleObject;\n }\n }\n\n // Generate element-specific class if node has interactive styles or generateElementClass flag\n const nodeInteractiveStyles = (node as any).interactiveStyles as InteractiveStyles | undefined;\n const nodeGenerateElementClass = (node as any).generateElementClass as boolean | undefined;\n const nodeLabel = (node as any).label as string | undefined;\n let elementClass = '';\n\n if ((nodeInteractiveStyles && nodeInteractiveStyles.length > 0) || nodeGenerateElementClass) {\n const isSlotContent = (node as any)._isSlotContent === true;\n elementClass = buildNodeElementClass(ctx, nodeLabel, isSlotContent);\n\n if (nodeInteractiveStyles && nodeInteractiveStyles.length > 0) {\n const cssVariables = registerInteractiveStyles(ctx, elementClass, nodeInteractiveStyles);\n // Add CSS variables to resolved style for inline output\n if (Object.keys(cssVariables).length > 0) {\n for (const [varName, value] of Object.entries(cssVariables)) {\n (resolvedStyle as Record<string, string | number>)[varName] = value;\n }\n }\n }\n }\n\n // Merge resolved style into props.style, and merge attributes\n // Handle class/className specially - merge with utility classes instead of replacing\n const attrClassName = (nodeAttributes.className || nodeAttributes.class || '') as string;\n const nodeAttributesWithoutClass = { ...nodeAttributes };\n delete nodeAttributesWithoutClass.className;\n delete nodeAttributesWithoutClass.class;\n\n // Merge classNames: element class (first for specificity) + attribute classes + utility classes\n const allClassNames = [elementClass, attrClassName, ...utilityClasses].filter(Boolean);\n const mergedClassName = allClassNames.length > 0 ? allClassNames.join(' ') : '';\n\n const propsWithStyleAndAttrs = {\n ...nodeProps,\n ...nodeAttributesWithoutClass,\n ...(mergedClassName ? { className: mergedClassName } : {}),\n ...(Object.keys(resolvedStyle).length > 0 ? { style: resolvedStyle } : {})\n };\n\n // Check if this is a custom component\n if (nodeType === NODE_TYPE.COMPONENT && componentName && ssrComponentRegistry.has(componentName)) {\n return renderComponent(componentName, propsWithStyleAndAttrs, children, nodeAttributes, ctx);\n }\n\n // Component not found in registry - warn and return empty\n if (nodeType === NODE_TYPE.COMPONENT && componentName) {\n console.warn(`[Meno SSR] Component \"${componentName}\" not found in registry.`);\n return '';\n }\n\n // Handle Link component for navigation (only for HTML nodes)\n if (tag === 'Link') {\n return renderLinkNode(propsWithStyleAndAttrs, children, ctx);\n }\n\n // Regular HTML element (must have tag)\n if (!tag) {\n console.error('Missing tag for HTML element in SSR');\n return '';\n }\n\n return renderHtmlElement(tag, propsWithStyleAndAttrs, children, ctx);\n}\n\n/**\n * Render a custom component\n */\nasync function renderComponent(\n componentName: string,\n propsWithStyleAndAttrs: Record<string, unknown>,\n children: unknown,\n nodeAttributes: Record<string, unknown>,\n ctx: SSRContext\n): Promise<string> {\n const { locale, i18nConfig, pagePath } = ctx;\n const componentDef = ssrComponentRegistry.get(componentName);\n if (!componentDef) return '';\n\n try {\n const structuredComponentDef = componentDef.component;\n if (!structuredComponentDef) return '';\n\n // Resolve props with defaults from interface definition (with i18n support)\n const resolvedProps = resolvePropsFromDefinition(\n structuredComponentDef,\n propsWithStyleAndAttrs,\n children as Array<ComponentNode | string> | string | ComponentNode | null | undefined,\n locale,\n i18nConfig\n );\n\n // Process the structure with resolved props\n // Pass instance children to replace { type: \"children\" } markers\n // Use preserveResponsiveStyles: true to keep responsive styles intact for SSR rendering\n // Mark children as slot content so they use page context for element class generation\n // Pass parent template context (itemContext) for nested cms-list template resolution\n const markedChildren = children ? markAsSlotContent(children as ComponentNode | ComponentNode[] | string | number | null | undefined) : undefined;\n\n const processedStructure = processStructure(\n structuredComponentDef.structure,\n { props: resolvedProps, componentDef: structuredComponentDef, itemContext: ctx.templateContext },\n undefined,\n markedChildren,\n true\n );\n\n if (!processedStructure) return '';\n\n // Type guard: ensure processedStructure is a ComponentNode\n if (typeof processedStructure === 'string' || typeof processedStructure === 'number' || Array.isArray(processedStructure)) {\n return await renderNode(processedStructure as string | number | ComponentNode[], ctx);\n }\n\n // Merge instance style overrides, className, and attributes\n // processedStructure is typically an HTML node (the component's root element)\n // Handle both component nodes and HTML nodes\n const rootNode = processedStructure as ComponentNode & { props?: Record<string, unknown> };\n if (isComponentNode(rootNode) || isHtmlNode(rootNode)) {\n if (!rootNode.props) {\n rootNode.props = {};\n }\n\n if (rootNode.props.style && typeof rootNode.props.style === 'object') {\n rootNode.props.style = {\n ...(rootNode.props.style as Record<string, unknown>),\n ...(propsWithStyleAndAttrs.style as Record<string, unknown> || {})\n };\n } else if (propsWithStyleAndAttrs.style) {\n rootNode.props.style = propsWithStyleAndAttrs.style;\n }\n\n // Merge className from component instance (includes responsive utility classes)\n if (propsWithStyleAndAttrs.className) {\n const existingClassName = rootNode.props.className || '';\n rootNode.props.className = existingClassName\n ? `${existingClassName} ${propsWithStyleAndAttrs.className}`\n : propsWithStyleAndAttrs.className;\n }\n\n // Merge attributes into props\n Object.assign(rootNode.props, nodeAttributes);\n\n // Forward nodeAttributes to rootNode.attributes for HTML root nodes\n // so attributes from outer components (e.g. data-component) reach the final HTML element\n if (isHtmlNode(rootNode) && Object.keys(nodeAttributes).length > 0) {\n if (!rootNode.attributes) {\n rootNode.attributes = {};\n }\n for (const [key, value] of Object.entries(nodeAttributes)) {\n if (key !== 'class' && key !== 'className') {\n rootNode.attributes[key] = value as string | number | boolean;\n }\n }\n }\n\n // Add defineVars data attributes for JS prop injection\n const defineVars = structuredComponentDef.defineVars;\n if (defineVars && componentName) {\n const varsToExpose = defineVars === true\n ? Object.keys(structuredComponentDef.interface || {})\n : defineVars;\n\n const propsForJS: Record<string, unknown> = {};\n for (const varName of varsToExpose) {\n if (resolvedProps[varName] !== undefined) {\n propsForJS[varName] = resolvedProps[varName];\n }\n }\n\n // Accumulate data-component (space-separated) and data-props (keyed by name)\n const processedRoot = processedStructure as import('../../shared/types').HtmlNode;\n if (!processedRoot.attributes) {\n processedRoot.attributes = {};\n }\n const existingComponent = (processedRoot.attributes?.['data-component'] as string)\n || (processedRoot.props?.['data-component'] as string)\n || '';\n processedRoot.attributes['data-component'] = existingComponent\n ? `${existingComponent} ${componentName}`\n : componentName;\n\n let existingPropsMap: Record<string, unknown> = {};\n const existingPropsStr = (processedRoot.attributes?.['data-props'] as string)\n || (processedRoot.props?.['data-props'] as string);\n if (existingPropsStr) {\n try { existingPropsMap = JSON.parse(existingPropsStr); } catch {}\n }\n existingPropsMap[componentName] = propsForJS;\n processedRoot.attributes['data-props'] = JSON.stringify(existingPropsMap);\n }\n }\n\n // Render the processed component structure with component context\n // Reset element path to component-relative for stable class names\n // Pass resolved props for interactive style mapping resolution\n return await renderNode(processedStructure, {\n ...ctx,\n componentContext: componentName,\n elementPath: [0],\n componentResolvedProps: resolvedProps,\n });\n\n } catch (error) {\n console.error(`\u274C SSR Error rendering component ${componentName}:`, error);\n return '';\n }\n}\n\n/**\n * Render a Link component as anchor tag\n */\nasync function renderLinkNode(\n propsWithStyleAndAttrs: Record<string, unknown>,\n children: unknown,\n ctx: SSRContext\n): Promise<string> {\n const to = 'to' in propsWithStyleAndAttrs ? propsWithStyleAndAttrs.to : undefined;\n const restProps: Record<string, unknown> = { ...propsWithStyleAndAttrs };\n delete restProps.to;\n const rawHref = (typeof to === 'string' ? to : undefined) || '#';\n const href = localizeHref(rawHref, ctx);\n\n // Build class attribute from utility classes\n const linkClassAttr = restProps.className\n ? ` class=\"${escapeHtml(String(restProps.className))}\"`\n : '';\n\n const attrs = buildAttributes(restProps, ['style', 'className', 'to']);\n const childrenHTML = Array.isArray(children)\n ? (await Promise.all((children as any[]).map((child, index) => {\n const childPath = ctx.elementPath ? [...ctx.elementPath, index] : [index];\n return renderNode(child, { ...ctx, elementPath: childPath });\n }))).join('')\n : await renderNode(children as ComponentNode, { ...ctx, elementPath: ctx.elementPath ? [...ctx.elementPath, 0] : [0] });\n\n return `<a href=\"${escapeHtml(String(href))}\"${linkClassAttr}${attrs}>${childrenHTML}</a>`;\n}\n\n/**\n * Render a regular HTML element\n */\nasync function renderHtmlElement(\n tag: string,\n propsWithStyleAndAttrs: Record<string, unknown>,\n children: unknown,\n ctx: SSRContext\n): Promise<string> {\n // Build class attribute from utility classes\n let classValue = propsWithStyleAndAttrs.className ? String(propsWithStyleAndAttrs.className) : '';\n\n // Localize and check <a> tag hrefs\n if (tag === 'a' && !ctx.templateMode) {\n const href = propsWithStyleAndAttrs.href as string | undefined;\n if (href && typeof href === 'string') {\n const localizedHref = localizeHref(href, ctx);\n if (localizedHref !== href) {\n propsWithStyleAndAttrs = { ...propsWithStyleAndAttrs, href: localizedHref };\n }\n if (ctx.pagePath && isCurrentLink(localizedHref, ctx.pagePath)) {\n classValue = classValue ? `${classValue} is-current` : 'is-current';\n }\n }\n }\n\n const classAttr = classValue ? ` class=\"${escapeHtml(classValue)}\"` : '';\n\n // Build style attribute (for CSS variables and remaining inline styles)\n const styleString = styleToString(propsWithStyleAndAttrs.style as Record<string, string | number> | undefined);\n const styleAttr = styleString ? ` style=\"${styleString}\"` : '';\n\n // For img tags, exclude image-specific props (handled specially in renderImageElement)\n const imageProps = ['src', 'alt', 'loading', 'width', 'height', 'sizes', 'srcset', 'fetchpriority'];\n const excludeProps = tag.toLowerCase() === 'img'\n ? ['style', 'className', ...imageProps]\n : ['style', 'className'];\n const attrs = buildAttributes(propsWithStyleAndAttrs, excludeProps);\n const childrenHTML = Array.isArray(children)\n ? (await Promise.all((children as any[]).map((child, index) => {\n const childPath = ctx.elementPath ? [...ctx.elementPath, index] : [index];\n return renderNode(child, { ...ctx, elementPath: childPath });\n }))).join('')\n : await renderNode(children as ComponentNode, { ...ctx, elementPath: ctx.elementPath ? [...ctx.elementPath, 0] : [0] });\n\n // Self-closing tags\n const voidElements = ['img', 'input', 'br', 'hr', 'meta', 'link', 'area', 'base', 'col', 'embed', 'source', 'track', 'wbr'];\n if (voidElements.includes(tag.toLowerCase())) {\n // Special handling for img tags - inject srcset and render as <picture> when AVIF available\n if (tag.toLowerCase() === 'img') {\n return renderImageElement(propsWithStyleAndAttrs, classAttr, attrs, ctx);\n }\n\n return `<${tag}${classAttr}${styleAttr}${attrs} />`;\n }\n\n return `<${tag}${classAttr}${styleAttr}${attrs}>${childrenHTML}</${tag}>`;\n}\n\n/**\n * Render an image element with responsive image support\n */\nfunction renderImageElement(\n propsWithStyleAndAttrs: Record<string, unknown>,\n classAttr: string,\n attrs: string,\n ctx: SSRContext\n): string {\n const imgProps = propsWithStyleAndAttrs;\n const src = imgProps.src as string | undefined;\n const alt = imgProps.alt as string | undefined;\n const loading = imgProps.loading as string | undefined;\n const sizes = imgProps.sizes as string | undefined;\n const fetchpriority = imgProps.fetchpriority as string | undefined;\n let width = imgProps.width as string | number | undefined;\n let height = imgProps.height as string | number | undefined;\n\n // Get image metadata from manifest\n const metadata = src ? ctx.imageMetadataMap?.get(src) : undefined;\n\n // Use dimensions from manifest if not explicitly set\n if (metadata) {\n if (width === undefined && metadata.width) width = metadata.width;\n if (height === undefined && metadata.height) height = metadata.height;\n }\n\n // Determine sizes attribute (prop > default)\n const sizesAttr = sizes || DEFAULT_SIZES;\n\n // Collect high-priority images for preloading in head\n if (fetchpriority === 'high' && metadata && ctx.preloadImages) {\n // Prefer AVIF, fallback to WebP\n if (metadata.avifSrcset) {\n ctx.preloadImages.push({\n srcset: metadata.avifSrcset,\n type: 'image/avif',\n sizes: sizesAttr,\n });\n } else if (metadata.srcset) {\n ctx.preloadImages.push({\n srcset: metadata.srcset,\n type: 'image/webp',\n sizes: sizesAttr,\n });\n }\n }\n\n // Build img attributes\n let imgAttrs = '';\n if (src) imgAttrs += ` src=\"${escapeHtml(String(src))}\"`;\n if (alt !== undefined) imgAttrs += ` alt=\"${escapeHtml(String(alt))}\"`;\n if (fetchpriority) imgAttrs += ` fetchpriority=\"${escapeHtml(String(fetchpriority))}\"`;\n if (loading) imgAttrs += ` loading=\"${escapeHtml(String(loading))}\"`;\n\n if (width !== undefined) imgAttrs += ` width=\"${escapeHtml(String(width))}\"`;\n if (height !== undefined) imgAttrs += ` height=\"${escapeHtml(String(height))}\"`;\n\n // Add blur placeholder as background if available\n let blurStyle = '';\n if (metadata?.blurHash) {\n blurStyle = ` style=\"background-image: url(${escapeHtml(metadata.blurHash)}); background-size: cover;\" onload=\"this.style.backgroundImage=''\"`;\n }\n\n // Render as <picture> element if AVIF is available\n // Layout classes go on <picture> (block container), image-specific classes on <img>\n if (metadata?.avifSrcset) {\n // Image-specific class prefixes that should stay on <img>\n const imgClassPrefixes = [\n 'objf-', 'objp-', 'flt-', 'tm-', 'bs-',\n 'br-', 'bt-', 'bb-', 'bl-', 'border-r-', 'bc-', 'b-'\n ];\n // Opacity classes (o-NUMBER) go on img, but overflow (o-h, o-a, o-s, o-v) stays on picture\n const opacityPattern = /^o-\\d/;\n\n const classMatch = classAttr.match(/class=\"([^\"]*)\"/);\n const allClasses = classMatch ? classMatch[1].split(/\\s+/).filter(Boolean) : [];\n\n const imgClasses: string[] = [];\n const pictureClasses: string[] = [];\n\n for (const cls of allClasses) {\n if (imgClassPrefixes.some(prefix => cls.startsWith(prefix)) || opacityPattern.test(cls)) {\n imgClasses.push(cls);\n } else {\n pictureClasses.push(cls);\n }\n }\n\n const pictureClassAttr = pictureClasses.length > 0\n ? ` class=\"${escapeHtml(pictureClasses.join(' '))}\"`\n : '';\n const imgClassAttr = imgClasses.length > 0\n ? ` class=\"${escapeHtml(imgClasses.join(' '))}\"`\n : '';\n\n return `<picture${pictureClassAttr}>` +\n `<source type=\"image/avif\" srcset=\"${escapeHtml(metadata.avifSrcset)}\" sizes=\"${escapeHtml(sizesAttr)}\" />` +\n `<source type=\"image/webp\" srcset=\"${escapeHtml(metadata.srcset)}\" sizes=\"${escapeHtml(sizesAttr)}\" />` +\n `<img${imgClassAttr}${imgAttrs}${blurStyle}${attrs} />` +\n `</picture>`;\n }\n\n // Fallback: regular img with WebP srcset\n if (metadata?.srcset) {\n imgAttrs += ` srcset=\"${escapeHtml(metadata.srcset)}\"`;\n imgAttrs += ` sizes=\"${escapeHtml(sizesAttr)}\"`;\n }\n\n return `<img${classAttr}${imgAttrs}${blurStyle}${attrs} />`;\n}\n\n/**\n * Render a locale list node (language switcher)\n */\nfunction renderLocaleList(node: import('../../shared/types').LocaleListNode, ctx: SSRContext): string {\n const { slugMappings, pagePath, i18nConfig, locale } = ctx;\n\n if (slugMappings && pagePath && i18nConfig && locale) {\n const slugIndex = buildSlugIndex(slugMappings);\n const localeLinks = getLocaleLinks(pagePath, locale, i18nConfig, slugIndex);\n const showCurrent = node.showCurrent !== false;\n const showSeparator = node.showSeparator !== false;\n const showFlag = node.showFlag !== false;\n const displayType = node.displayType || 'nativeName';\n const nodeStyle = node.style;\n\n // Build a map of locale code to icon for quick lookup\n const localeIconMap = new Map<string, string>();\n for (const localeConfig of i18nConfig.locales) {\n if (localeConfig.icon) {\n localeIconMap.set(localeConfig.code, localeConfig.icon);\n }\n }\n\n // Convert container styles to utility classes\n let containerClasses: string[] = [];\n if (nodeStyle) {\n containerClasses = responsiveStylesToClasses(nodeStyle as ResponsiveStyleObject);\n }\n\n // Handle interactive styles for locale-list wrapper\n const localeListInteractiveStyles = node.interactiveStyles as InteractiveStyles | undefined;\n const localeListGenerateElementClass = node.generateElementClass;\n let localeListCssVariables: Record<string, string> = {};\n let localeListStyleAttr = '';\n\n if ((localeListInteractiveStyles && localeListInteractiveStyles.length > 0) || localeListGenerateElementClass) {\n const elementClass = buildNodeElementClass(ctx, node.label);\n containerClasses.unshift(elementClass);\n\n if (localeListInteractiveStyles && localeListInteractiveStyles.length > 0) {\n localeListCssVariables = registerInteractiveStyles(ctx, elementClass, localeListInteractiveStyles);\n }\n localeListStyleAttr = buildCssVariableStyleAttr(localeListCssVariables);\n }\n\n const containerClassAttr = containerClasses.length > 0\n ? ` class=\"${escapeHtml(containerClasses.join(' '))}\"`\n : '';\n\n // Convert item styles to utility classes\n let itemClasses: string[] = [];\n if (node.itemStyle) {\n itemClasses = responsiveStylesToClasses(node.itemStyle as ResponsiveStyleObject);\n }\n const itemClassAttr = itemClasses.length > 0\n ? ` class=\"${escapeHtml(itemClasses.join(' '))}\"`\n : '';\n\n // Convert active item styles to utility classes\n let activeItemClasses: string[] = [];\n if (node.activeItemStyle) {\n activeItemClasses = responsiveStylesToClasses(node.activeItemStyle as ResponsiveStyleObject);\n }\n\n // Convert separator styles to utility classes\n let separatorClasses: string[] = [];\n if (node.separatorStyle) {\n separatorClasses = responsiveStylesToClasses(node.separatorStyle as ResponsiveStyleObject);\n }\n const separatorClassAttr = separatorClasses.length > 0\n ? ` class=\"${escapeHtml(separatorClasses.join(' '))}\"`\n : '';\n\n // Convert flag styles to utility classes\n let flagClasses: string[] = [];\n if (node.flagStyle) {\n flagClasses = responsiveStylesToClasses(node.flagStyle as ResponsiveStyleObject);\n }\n const flagClassAttr = flagClasses.length > 0\n ? ` class=\"${escapeHtml(flagClasses.join(' '))}\"`\n : '';\n\n // Current item gets both itemStyle + activeItemStyle (additive/override)\n const currentItemClasses = [...itemClasses, ...activeItemClasses];\n const currentItemClassAttr = currentItemClasses.length > 0\n ? ` class=\"${escapeHtml(currentItemClasses.join(' '))}\"`\n : '';\n\n // Build links HTML\n const links: string[] = [];\n for (const link of localeLinks) {\n if (!showCurrent && link.isCurrent) continue;\n const currentAttr = link.isCurrent ? ' data-current=\"true\"' : ' data-current=\"false\"';\n const classAttrForLink = link.isCurrent ? currentItemClassAttr : itemClassAttr;\n const hreflangAttr = ` hreflang=\"${escapeHtml(link.langTag)}\"`;\n\n // Build link content with optional flag icon + text in div\n let linkContent = '';\n const localeIcon = localeIconMap.get(link.locale);\n if (showFlag && localeIcon) {\n linkContent += `<img src=\"${escapeHtml(localeIcon)}\" alt=\"${escapeHtml(link.nativeName)} flag\"${flagClassAttr}>`;\n }\n\n // Get display text based on displayType\n let displayText: string;\n switch (displayType) {\n case 'code':\n displayText = link.locale.toUpperCase();\n break;\n case 'name':\n displayText = link.name;\n break;\n case 'nativeName':\n default:\n displayText = link.nativeName;\n break;\n }\n linkContent += `<div>${escapeHtml(displayText)}</div>`;\n\n links.push(`<a href=\"${escapeHtml(link.path)}\"${hreflangAttr}${currentAttr} data-locale=\"${escapeHtml(link.locale)}\"${classAttrForLink}>${linkContent}</a>`);\n }\n\n // Join links with separator (empty span styled via separatorStyle) or concatenate directly\n const linksHTML = showSeparator\n ? links.join(`<span${separatorClassAttr}></span>`)\n : links.join('');\n\n // Extract attributes from node\n const nodeAttributes = extractAttributesFromNode(node as any);\n const attrsStr = buildAttributes(nodeAttributes);\n\n return `<div data-locale-list=\"true\"${containerClassAttr}${localeListStyleAttr}${attrsStr}>${linksHTML}</div>`;\n }\n // If context is missing, return empty div\n return '<div data-locale-list=\"true\"></div>';\n}\n\n/**\n * Main SSR render function - generates complete HTML with pre-rendered content\n */\nexport async function renderPageSSR(\n pageData: JSONPage,\n globalComponents: Record<string, ComponentDefinition> = {},\n pagePath: string = '/',\n baseUrl: string = '',\n locale?: string,\n i18nConfig?: I18nConfig,\n slugMappings?: SlugMap[],\n cmsContext?: CMSContext,\n cmsService?: CMSService,\n isProductionBuild?: boolean\n): Promise<{ html: string; meta: string; title: string; javascript: string; componentCSS?: string; locale: string; interactiveStylesMap: Map<string, InteractiveStyles>; preloadImages: PreloadImage[]; neededCollections: Set<string> }> {\n // Extract page content\n const rootNode = pageData?.root || undefined;\n if (!rootNode) {\n throw new Error('Page data must have a root node');\n }\n\n // Load i18n config if not provided\n const config = i18nConfig || await loadI18nConfig();\n\n // Extract locale from path if not explicitly provided\n const { locale: pathLocale, pathWithoutLocale } = extractLocaleFromPath(pagePath, config);\n const effectiveLocale = locale || pathLocale || config.defaultLocale;\n\n // Extract meta information and process CMS templates in meta\n let meta = extractPageMeta(pageData);\n if (cmsContext?.cms) {\n // Process CMS templates in meta fields (with i18n support)\n if (typeof meta.title === 'string') {\n meta = { ...meta, title: processCMSTemplate(meta.title, cmsContext.cms, effectiveLocale, config) };\n }\n if (typeof meta.description === 'string') {\n meta = { ...meta, description: processCMSTemplate(meta.description, cmsContext.cms, effectiveLocale, config) };\n }\n if (typeof meta.ogTitle === 'string') {\n meta = { ...meta, ogTitle: processCMSTemplate(meta.ogTitle, cmsContext.cms, effectiveLocale, config) };\n }\n if (typeof meta.ogDescription === 'string') {\n meta = { ...meta, ogDescription: processCMSTemplate(meta.ogDescription, cmsContext.cms, effectiveLocale, config) };\n }\n }\n\n const pageComponents = pageData?.components || {};\n\n // Render the component tree to HTML with i18n and CMS support\n // Also collect interactive styles, preload images, and needed collections during render\n const { html: contentHTML, interactiveStylesMap, preloadImages, neededCollections } = rootNode\n ? await buildComponentHTML(rootNode, globalComponents, pageComponents, effectiveLocale, config, slugMappings, pagePath, cmsContext, cmsService, isProductionBuild)\n : { html: '', interactiveStylesMap: new Map<string, InteractiveStyles>(), preloadImages: [], neededCollections: new Set<string>() };\n\n // Collect JavaScript and CSS from all components\n const javascript = await collectComponentJavaScript(globalComponents, pageComponents);\n const componentCSS = collectComponentCSS(globalComponents, pageComponents);\n\n // Build full URL for meta tags\n const fullUrl = baseUrl ? `${baseUrl}${pagePath}` : pagePath;\n\n // Generate meta tags with i18n resolution and hreflang tags\n const metaTags = generateMetaTags(meta, fullUrl, effectiveLocale, config, {\n slugMappings,\n pagePath,\n baseUrl,\n });\n\n // Resolve title for use in HTML template\n const resolvedTitle = resolveI18nValue(meta.title, effectiveLocale, config);\n\n // Return pre-rendered HTML (will be injected into template)\n return {\n html: contentHTML,\n meta: metaTags,\n title: typeof resolvedTitle === 'string' ? resolvedTitle : 'UPLO',\n javascript,\n // Component CSS is still included in the final HTML document\n componentCSS,\n locale: effectiveLocale,\n interactiveStylesMap,\n preloadImages,\n neededCollections,\n };\n}\n", "/**\n * Build-time validation tool\n * Scans all rendered HTML and warns about styles that don't generate utility classes\n */\n\nimport { propertyMap } from '../shared/utilityClassConfig';\nimport type { StyleObject, ResponsiveStyleObject } from '../shared/types';\n\ninterface MissingStyleReport {\n property: string;\n value: string;\n locations: string[];\n count: number;\n}\n\n// Track missing styles\nconst missingStylesMap = new Map<string, MissingStyleReport>();\n\n/**\n * Check if a style property and value can be converted to a utility class\n *\n * All CSS properties now generate utility classes:\n * - Known properties (in propertyMap) use standard prefixes\n * - Unknown properties generate dynamic classes with auto-prefixes\n */\nfunction canGenerateClass(property: string, value: unknown): boolean {\n // Skip internal component properties that shouldn't be styles\n const internalProps = new Set([\n 'type', 'tag', 'props', 'component', 'children', 'id', 'key',\n 'ref', 'className', 'style', 'node'\n ]);\n\n if (internalProps.has(property)) {\n return true; // Skip reporting these - they're not CSS styles\n }\n\n // Skip if value is null, undefined, or empty - these don't need utility classes\n if (value === null || value === undefined || value === '') {\n return true; // Skip reporting - nothing to convert\n }\n\n // Try to convert to string and check\n const strValue = String(value).trim();\n if (!strValue) {\n return false;\n }\n\n // Object values cannot be converted to utility classes\n if (typeof value === 'object') {\n return false;\n }\n\n // All CSS properties (including unknown ones) now generate utility classes:\n // - Known properties use standard prefixes from propertyMap\n // - Unknown properties generate dynamic classes registered in the dynamic registry\n // - CSS var() calls, space-separated values, and functions are all handled\n return true;\n}\n\n/**\n * Validate a style object and report missing utility class coverage\n */\nexport function validateStyleCoverage(\n styles: StyleObject | ResponsiveStyleObject | undefined,\n location: string\n): void {\n if (!styles || typeof styles !== 'object') {\n return;\n }\n\n // Check if it's a responsive style object\n if ('base' in styles || 'tablet' in styles || 'mobile' in styles) {\n // Process each breakpoint\n const responsive = styles as ResponsiveStyleObject;\n for (const [breakpoint, breakpointStyles] of Object.entries(responsive)) {\n if (typeof breakpointStyles === 'object' && breakpointStyles !== null) {\n validateStyleCoverage(breakpointStyles, `${location} (${breakpoint})`);\n }\n }\n return;\n }\n\n // Process regular style object\n const styleObj = styles as StyleObject;\n for (const [property, value] of Object.entries(styleObj)) {\n if (!canGenerateClass(property, value)) {\n const key = `${property}:${String(value)}`;\n const existing = missingStylesMap.get(key);\n\n if (existing) {\n existing.count++;\n existing.locations.push(location);\n } else {\n missingStylesMap.set(key, {\n property,\n value: String(value),\n locations: [location],\n count: 1,\n });\n }\n }\n }\n}\n\n/**\n * Print warnings for all missing utility class mappings found during build\n */\nexport function printMissingStyleWarnings(verbose = false): void {\n if (missingStylesMap.size === 0) {\n return;\n }\n\n const warnings: string[] = [];\n warnings.push(\n '\\n\u26A0\uFE0F WARNING: Found styles that cannot be converted to utility classes\\n'\n );\n warnings.push(\n 'These styles use object values which cannot be serialized to class names:\\n'\n );\n\n // Sort by frequency\n const sorted = Array.from(missingStylesMap.values()).sort(\n (a, b) => b.count - a.count\n );\n\n for (const report of sorted) {\n warnings.push(\n ` \u2022 ${report.property}: \"${report.value}\" (used ${report.count} time${report.count > 1 ? 's' : ''})`\n );\n\n if (verbose && report.locations.length > 0) {\n for (const location of report.locations.slice(0, 3)) {\n warnings.push(` \u2514\u2500 ${location}`);\n }\n if (report.locations.length > 3) {\n warnings.push(\n ` \u2514\u2500 ... and ${report.locations.length - 3} more locations`\n );\n }\n }\n }\n\n warnings.push('\\n\uD83D\uDCA1 Note:');\n warnings.push(' \u2022 All string/number values are now converted to utility classes');\n warnings.push(' \u2022 Object values (non-primitive) cannot be converted and will remain as-is');\n warnings.push(' \u2022 This warning only appears for object-type style values\\n');\n\n console.warn(warnings.join('\\n'));\n}\n\n/**\n * Reset the validation state (useful for testing)\n */\nexport function resetValidation(): void {\n missingStylesMap.clear();\n}\n\n/**\n * Get all missing styles found during validation\n */\nexport function getMissingStyles(): MissingStyleReport[] {\n return Array.from(missingStylesMap.values());\n}\n", "/**\n * Client Data Injector\n *\n * Utilities for injecting CMS collection data into HTML for client-side filtering.\n * Generates inline JSON script tags that MenoFilter can read.\n */\n\nimport type { CMSItem, CMSClientDataConfig } from '../../shared/types/cms';\n\n/** System fields that are always included in client data */\nconst SYSTEM_FIELDS = ['_id', '_url', '_filename', '_slug'];\n\n/**\n * Filter CMS items to only include specified fields.\n * System fields (_id, _url, _filename, _slug) are always included.\n *\n * @param items CMS items to filter\n * @param fields Fields to include (undefined or empty = all fields)\n * @returns Filtered items with only specified fields\n */\nexport function filterItemFields(\n items: CMSItem[],\n fields: string[] | undefined\n): CMSItem[] {\n // If no field restriction, return all items as-is\n if (!fields || fields.length === 0) {\n return items;\n }\n\n // Build set of allowed fields (user fields + system fields)\n const allowedFields = new Set([...SYSTEM_FIELDS, ...fields]);\n\n // Filter each item to only include allowed fields\n return items.map(item => {\n const filtered: CMSItem = { _id: item._id };\n\n for (const [key, value] of Object.entries(item)) {\n if (allowedFields.has(key)) {\n filtered[key] = value;\n }\n }\n\n return filtered;\n });\n}\n\n/**\n * Generate inline JSON script tag for collection data.\n * Uses type=\"application/json\" so it doesn't execute, just stores data.\n *\n * @param collection Collection ID\n * @param items Items to embed\n * @returns HTML script tag string\n */\nexport function generateInlineDataScript(\n collection: string,\n items: CMSItem[]\n): string {\n // Escape HTML entities in JSON to prevent XSS\n const jsonString = JSON.stringify(items)\n .replace(/</g, '\\\\u003c')\n .replace(/>/g, '\\\\u003e')\n .replace(/&/g, '\\\\u0026');\n\n return `<script type=\"application/json\" id=\"meno-cms-${escapeAttr(collection)}\">${jsonString}</script>`;\n}\n\n/**\n * Escape attribute value for safe HTML insertion\n */\nfunction escapeAttr(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n}\n\n/**\n * Determine the effective strategy for a collection based on config and item count.\n *\n * @param config Client data config\n * @param itemCount Number of items in collection\n * @returns Effective strategy ('inline' or 'static')\n */\nexport function determineStrategy(\n config: CMSClientDataConfig,\n itemCount: number\n): 'inline' | 'static' {\n if (config.strategy === 'inline') return 'inline';\n if (config.strategy === 'static') return 'static';\n\n // Auto strategy: use threshold to decide\n const threshold = config.threshold ?? 500;\n return itemCount <= threshold ? 'inline' : 'static';\n}\n\n/**\n * Collection data prepared for client-side injection\n */\nexport interface ClientDataCollection {\n /** Collection ID */\n collection: string;\n /** Filtered items for client */\n items: CMSItem[];\n /** Client data config */\n config: CMSClientDataConfig;\n /** Determined strategy */\n strategy: 'inline' | 'static';\n}\n\n/**\n * Prepare collection data for client-side injection.\n * Filters fields and determines strategy.\n *\n * @param collection Collection ID\n * @param items All items in collection\n * @param config Client data config from schema\n * @returns Prepared collection data, or null if not enabled\n */\nexport function prepareClientData(\n collection: string,\n items: CMSItem[],\n config: CMSClientDataConfig | undefined\n): ClientDataCollection | null {\n // Skip if not enabled\n if (!config?.enabled) {\n return null;\n }\n\n const strategy = determineStrategy(config, items.length);\n const filteredItems = filterItemFields(items, config.fields);\n\n return {\n collection,\n items: filteredItems,\n config,\n strategy,\n };\n}\n\n/**\n * Generate all inline data scripts for collections using inline strategy.\n *\n * @param collections Map of collection ID to prepared client data\n * @returns Combined HTML string with all data scripts\n */\nexport function generateAllInlineDataScripts(\n collections: Map<string, ClientDataCollection>\n): string {\n const scripts: string[] = [];\n\n for (const [collectionId, data] of collections) {\n if (data.strategy === 'inline') {\n scripts.push(generateInlineDataScript(collectionId, data.items));\n }\n }\n\n return scripts.join('\\n ');\n}\n", "/**\n * Library Loader\n * Generates HTML tags for external JS/CSS libraries\n */\n\nimport type {\n JSLibraryConfig,\n CSSLibraryConfig,\n LibrariesConfig,\n PageLibrariesConfig,\n} from './types/libraries';\nimport type { ComponentDefinition } from './types/components';\n\n/**\n * Escape HTML special characters in attribute values\n */\nfunction escapeAttr(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/\"/g, '&quot;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n}\n\n/**\n * Merge global and page-level library configurations\n * @param global Global libraries from project.config.json\n * @param page Page-level libraries from page meta\n * @returns Merged library configuration\n */\nexport function mergeLibraries(\n global: LibrariesConfig,\n page?: PageLibrariesConfig\n): LibrariesConfig {\n if (!page) {\n return global;\n }\n\n if (page.mode === 'replace') {\n return {\n js: page.js || [],\n css: page.css || [],\n };\n }\n\n // Default: extend\n return {\n js: [...(global.js || []), ...(page.js || [])],\n css: [...(global.css || []), ...(page.css || [])],\n };\n}\n\n/**\n * Generate <script> tag for a JS library\n * @param lib JavaScript library configuration\n * @returns HTML script tag string\n */\nexport function generateScriptTag(lib: JSLibraryConfig): string {\n const attrs: string[] = [`src=\"${escapeAttr(lib.url)}\"`];\n\n if (lib.type === 'module') {\n attrs.push('type=\"module\"');\n } else {\n // Default to defer for better performance\n const mode = lib.mode || 'defer';\n attrs.push(mode);\n }\n\n return `<script ${attrs.join(' ')}></script>`;\n}\n\n/**\n * Generate inline <style> tag with CSS content\n * @param content CSS content to embed\n * @param media Optional media query attribute\n * @returns HTML style tag string\n */\nexport function generateInlineStyleTag(content: string, media?: string): string {\n const attrs = media ? ` media=\"${escapeAttr(media)}\"` : '';\n return `<style${attrs}>${content}</style>`;\n}\n\n/**\n * Generate <link> tag for a CSS library\n * @param lib CSS library configuration\n * @returns HTML link tag string\n */\nexport function generateStylesheetTag(lib: CSSLibraryConfig): string {\n const attrs: string[] = [\n 'rel=\"stylesheet\"',\n `href=\"${escapeAttr(lib.url)}\"`,\n ];\n\n if (lib.media) {\n attrs.push(`media=\"${escapeAttr(lib.media)}\"`);\n }\n\n return `<link ${attrs.join(' ')}>`;\n}\n\n/**\n * Generated library tags grouped by position\n */\nexport interface LibraryTags {\n /** CSS tags for <head> */\n headCSS: string;\n /** JS tags for <head> */\n headJS: string;\n /** JS tags for before </body> */\n bodyEndJS: string;\n}\n\n/**\n * Generate all library tags grouped by position\n * @param libs Library configuration\n * @param inlineContents Optional map of URL \u2192 CSS content for inline embedding\n * @returns Object with tags grouped by position\n */\nexport function generateLibraryTags(libs: LibrariesConfig, inlineContents?: Map<string, string>): LibraryTags {\n const headCSS: string[] = [];\n const headJS: string[] = [];\n const bodyEndJS: string[] = [];\n\n // CSS always goes in head\n for (const css of libs.css || []) {\n const inlineContent = inlineContents?.get(css.url);\n if (inlineContent !== undefined) {\n headCSS.push(generateInlineStyleTag(inlineContent, css.media));\n } else {\n headCSS.push(generateStylesheetTag(css));\n }\n }\n\n // JS can go in head or body-end\n for (const js of libs.js || []) {\n const tag = generateScriptTag(js);\n if (js.position === 'head') {\n headJS.push(tag);\n } else {\n // Default to body-end\n bodyEndJS.push(tag);\n }\n }\n\n return {\n headCSS: headCSS.join('\\n '),\n headJS: headJS.join('\\n '),\n bodyEndJS: bodyEndJS.join('\\n '),\n };\n}\n\n/**\n * Collect library configurations from all component definitions, deduplicated by URL\n * @param globalComponents Global component definitions\n * @param pageComponents Page-specific component definitions\n * @returns Combined library configuration from all components\n */\nexport function collectComponentLibraries(\n globalComponents: Record<string, ComponentDefinition> = {},\n pageComponents: Record<string, ComponentDefinition> = {}\n): LibrariesConfig {\n const seenJS = new Set<string>();\n const seenCSS = new Set<string>();\n const jsLibs: JSLibraryConfig[] = [];\n const cssLibs: CSSLibraryConfig[] = [];\n\n const collect = (components: Record<string, ComponentDefinition>) => {\n for (const component of Object.values(components)) {\n const libs = component?.component?.libraries;\n if (!libs) continue;\n\n for (const js of libs.js || []) {\n if (!seenJS.has(js.url)) {\n seenJS.add(js.url);\n jsLibs.push(js);\n }\n }\n for (const css of libs.css || []) {\n if (!seenCSS.has(css.url)) {\n seenCSS.add(css.url);\n cssLibs.push(css);\n }\n }\n }\n };\n\n collect(globalComponents);\n collect(pageComponents);\n\n return { js: jsLibs, css: cssLibs };\n}\n\n/**\n * Origins extracted from library URLs, grouped by resource type\n */\nexport interface LibraryOrigins {\n /** Origins for script-src (from JS library URLs) */\n scriptOrigins: Set<string>;\n /** Origins for style-src (from CSS library URLs) */\n styleOrigins: Set<string>;\n}\n\n/**\n * Extract unique origin domains from library URLs for CSP headers.\n * Skips relative URLs (/, ./, ../) since they're covered by 'self'.\n * Silently skips malformed URLs.\n */\nexport function extractLibraryOrigins(libs: LibrariesConfig): LibraryOrigins {\n const scriptOrigins = new Set<string>();\n const styleOrigins = new Set<string>();\n\n for (const js of libs.js || []) {\n const origin = safeOrigin(js.url);\n if (origin) scriptOrigins.add(origin);\n }\n\n for (const css of libs.css || []) {\n const origin = safeOrigin(css.url);\n if (origin) styleOrigins.add(origin);\n }\n\n return { scriptOrigins, styleOrigins };\n}\n\n/**\n * Filter libraries based on context (editor, build, or preview).\n * Removes CSS libraries that have the corresponding disable flag set.\n * JS libraries pass through unchanged.\n * Preview context (dev server on port 8080) returns all libraries unfiltered.\n */\nexport function filterLibrariesByContext(\n libs: LibrariesConfig,\n context: 'editor' | 'build' | 'preview'\n): LibrariesConfig {\n if (context === 'preview') return libs;\n const key = context === 'editor' ? 'disableEditor' : 'disableBuild';\n return {\n js: libs.js,\n css: (libs.css || []).filter(css => !css[key]),\n };\n}\n\nfunction safeOrigin(url: string): string | null {\n if (!url || url.startsWith('/') || url.startsWith('./') || url.startsWith('../')) {\n return null;\n }\n try {\n return new URL(url).origin;\n } catch {\n return null;\n }\n}\n", "/**\n * CSS Variables Generator\n * Generates CSS color variable declarations for themes\n * and CSS custom property declarations from variables.json\n */\n\nimport type { ColorVariables, ThemeConfig } from '../shared/types/colors';\nimport { resolvePaletteColor } from '../shared/types/colors';\nimport type { VariablesConfig, CSSVariable } from '../shared/types/variables';\nimport type { BreakpointConfig } from '../shared/breakpoints';\nimport type { ResponsiveScales, BreakpointScales } from '../shared/responsiveScaling';\nimport { scalePropertyValue } from '../shared/responsiveScaling';\n\n/**\n * Generate CSS color variable declarations from color variables\n * Creates :root { --variable-name: value; } CSS\n */\nexport function generateColorVariablesCSS(colors: ColorVariables): string {\n const cssVars: string[] = [];\n\n for (const [name, value] of Object.entries(colors.colors)) {\n cssVars.push(` --${name}: ${value};`);\n }\n\n if (cssVars.length === 0) {\n return '';\n }\n\n return `:root {\\n${cssVars.join('\\n')}\\n}`;\n}\n\n/**\n * Generate CSS color variable declarations for multiple themes\n * Creates [theme=\"dark\"] { --variable-name: value; } selectors for each theme\n */\nexport function generateThemeColorVariablesCSS(themeConfig: ThemeConfig): string {\n const cssBlocks: string[] = [];\n const palette = themeConfig.palette;\n\n for (const [themeName, theme] of Object.entries(themeConfig.themes)) {\n const cssVars: string[] = [];\n\n for (const [name, value] of Object.entries(theme.colors)) {\n const resolved = resolvePaletteColor(value, palette);\n cssVars.push(` --${name}: ${resolved};`);\n }\n\n if (cssVars.length > 0) {\n cssBlocks.push(`[theme=\"${themeName}\"] {\\n${cssVars.join('\\n')}\\n}`);\n }\n }\n\n // Also include :root with default theme colors\n const defaultTheme = themeConfig.themes[themeConfig.default];\n if (defaultTheme) {\n const cssVars: string[] = [];\n for (const [name, value] of Object.entries(defaultTheme.colors)) {\n const resolved = resolvePaletteColor(value, palette);\n cssVars.push(` --${name}: ${resolved};`);\n }\n if (cssVars.length > 0) {\n cssBlocks.unshift(`:root {\\n${cssVars.join('\\n')}\\n}`);\n }\n }\n\n return cssBlocks.join('\\n\\n');\n}\n\n/**\n * Generate CSS custom property declarations from variables.json config\n * Produces :root block for base values and @media blocks for responsive scaling\n */\nexport function generateVariablesCSS(\n config: VariablesConfig,\n breakpoints?: BreakpointConfig,\n responsiveScales?: ResponsiveScales\n): string {\n if (!config.variables || config.variables.length === 0) {\n return '';\n }\n\n const cssBlocks: string[] = [];\n\n // Base :root block with all variables\n const baseVars = config.variables.map(v => ` ${v.cssVar}: ${v.value};`);\n cssBlocks.push(`:root {\\n${baseVars.join('\\n')}\\n}`);\n\n // Generate @media blocks for responsive scaling\n if (breakpoints && responsiveScales?.enabled) {\n const baseRef = responsiveScales.baseReference || 16;\n\n // Sort breakpoints by value descending (largest first)\n const sortedBreakpoints = Object.entries(breakpoints)\n .sort((a, b) => b[1].breakpoint - a[1].breakpoint);\n\n for (const [bpName, bpEntry] of sortedBreakpoints) {\n const scaledVars: string[] = [];\n\n for (const variable of config.variables) {\n // Per-variable override takes priority \u2014 stored string is the CSS value\n if (variable.scales && variable.scales[bpName]) {\n const overrideValue = variable.scales[bpName];\n if (overrideValue !== variable.value) {\n scaledVars.push(` ${variable.cssVar}: ${overrideValue};`);\n }\n continue;\n }\n\n // Global category scale (existing logic)\n if (variable.type === 'none') continue;\n const categoryScales = responsiveScales[variable.type] as BreakpointScales | undefined;\n const scale = categoryScales?.[bpName] ?? null;\n if (scale === null) continue;\n\n const scaled = scalePropertyValue(variable.value, baseRef, scale);\n if (scaled !== null && scaled !== variable.value) {\n scaledVars.push(` ${variable.cssVar}: ${scaled};`);\n }\n }\n\n if (scaledVars.length > 0) {\n cssBlocks.push(\n `@media (max-width: ${bpEntry.breakpoint}px) {\\n :root {\\n${scaledVars.join('\\n')}\\n }\\n}`\n );\n }\n }\n }\n\n return cssBlocks.join('\\n');\n}\n\n", "/**\n * Client-side Form Handler\n * Handles form submissions via fetch for forms with data-submit-handler=\"fetch\"\n *\n * This script is designed to be included inline in SSR output.\n * It's a self-executing module that attaches to forms automatically.\n */\n\nexport const formHandlerScript = `\n(function() {\n // Find all forms with fetch handler\n const forms = document.querySelectorAll('form[data-submit-handler=\"fetch\"]');\n\n forms.forEach(function(form) {\n form.addEventListener('submit', async function(e) {\n e.preventDefault();\n\n const action = form.getAttribute('action');\n const method = form.getAttribute('method') || 'POST';\n const successMessage = form.getAttribute('data-success-message') || 'Form submitted successfully!';\n const errorMessage = form.getAttribute('data-error-message') || 'Something went wrong. Please try again.';\n\n // Find or create message element\n let messageEl = form.querySelector('[data-form-message]');\n if (!messageEl) {\n messageEl = document.createElement('div');\n messageEl.setAttribute('data-form-message', 'true');\n form.appendChild(messageEl);\n }\n\n // Find submit button and disable it\n const submitBtn = form.querySelector('button[type=\"submit\"], input[type=\"submit\"]');\n const originalBtnText = submitBtn ? submitBtn.textContent || submitBtn.value : '';\n\n if (submitBtn) {\n submitBtn.disabled = true;\n if (submitBtn.tagName === 'BUTTON') {\n submitBtn.textContent = 'Sending...';\n } else {\n submitBtn.value = 'Sending...';\n }\n }\n\n // Hide any previous message\n messageEl.style.display = 'none';\n\n try {\n const formData = new FormData(form);\n\n const response = await fetch(action, {\n method: method.toUpperCase(),\n body: formData,\n });\n\n const data = await response.json();\n\n if (response.ok && data.success) {\n // Success\n messageEl.textContent = data.message || successMessage;\n messageEl.style.display = 'block';\n messageEl.style.backgroundColor = '#d4edda';\n messageEl.style.color = '#155724';\n messageEl.style.border = '1px solid #c3e6cb';\n\n // Optionally reset form\n form.reset();\n } else {\n // Error from server\n messageEl.textContent = data.error || errorMessage;\n messageEl.style.display = 'block';\n messageEl.style.backgroundColor = '#f8d7da';\n messageEl.style.color = '#721c24';\n messageEl.style.border = '1px solid #f5c6cb';\n }\n } catch (error) {\n // Network or other error\n messageEl.textContent = errorMessage;\n messageEl.style.display = 'block';\n messageEl.style.backgroundColor = '#f8d7da';\n messageEl.style.color = '#721c24';\n messageEl.style.border = '1px solid #f5c6cb';\n } finally {\n // Re-enable submit button\n if (submitBtn) {\n submitBtn.disabled = false;\n if (submitBtn.tagName === 'BUTTON') {\n submitBtn.textContent = originalBtnText;\n } else {\n submitBtn.value = originalBtnText;\n }\n }\n }\n });\n });\n})();\n`;\n\n/**\n * Check if page HTML contains forms that need the fetch handler\n */\nexport function needsFormHandler(html: string): boolean {\n return html.includes('data-submit-handler=\"fetch\"');\n}\n", "// AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY\n// Generated from: lib/client/meno-filter/MenoFilter.ts + init.ts\n// Regenerate with: bun scripts/build-meno-filter.ts\n//\n// This file is the production inline script injected into SSR HTML.\n// Edit the source TypeScript files, then run the build script.\n\n/**\n * MenoFilter Inline Script\n *\n * Self-contained script for client-side CMS filtering.\n * Injected into pages that use cms-list or MenoFilter.\n *\n * Features:\n * - Filter by field values with operators ($gt, $lt, $in, etc.)\n * - Search with debounce\n * - Sort ascending/descending\n * - Pagination\n * - Data attribute auto-binding\n * - Facet counts\n * - Lifecycle events\n */\n\nexport const menoFilterScript = `\"use strict\";var MenoFilterBundle=(()=>{var b=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var Z=Object.prototype.hasOwnProperty;var K=(r,e,t)=>e in r?b(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var X=(r,e)=>{for(var t in e)b(r,t,{get:e[t],enumerable:!0})},V=(r,e,t,n)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let i of Y(e))!Z.call(r,i)&&i!==t&&b(r,i,{get:()=>e[i],enumerable:!(n=J(e,i))||n.enumerable});return r};var ee=r=>V(b({},\"__esModule\",{value:!0}),r);var g=(r,e,t)=>K(r,typeof e!=\"symbol\"?e+\"\":e,t);var we={};X(we,{autoInit:()=>$,default:()=>Pe,destroyAllMenoFilters:()=>Q,destroyMenoFilter:()=>k,getMenoFilterInstance:()=>Re,initMenoFilter:()=>C});var S=class S{constructor(e){g(this,\"collection\");g(this,\"items\",[]);g(this,\"filteredItems\",[]);g(this,\"initialized\",!1);g(this,\"criteria\",{});g(this,\"orCriteria\",[]);g(this,\"searchQuery\",\"\");g(this,\"searchFields\",[]);g(this,\"sortConfig\",null);g(this,\"perPage\");g(this,\"currentPage\",1);g(this,\"visibleCount\",0);g(this,\"filterMatch\");g(this,\"fieldTypes\",{});g(this,\"urlSync\",!1);g(this,\"urlMode\",\"replace\");g(this,\"popstateHandler\",()=>this.syncFromUrl());g(this,\"fuzzySearchEnabled\",!1);g(this,\"fuzzyThreshold\",.3);g(this,\"eventListeners\",new Map);g(this,\"watchers\",new Set);this.collection=e.collection,this.perPage=e.perPage??0,this.filterMatch=e.filterMatch??\"and\",this.fieldTypes=e.fieldTypes??{},this.fuzzySearchEnabled=e.fuzzySearch??!1,this.fuzzyThreshold=e.fuzzyThreshold??.3,S.instances.set(this.collection,this),e.urlSync&&this.enableUrlSync({mode:e.urlMode})}static get(e){return S.instances.get(e)}static getAll(){return new Map(S.instances)}static has(e){return S.instances.has(e)}static destroy(e){let t=S.instances.get(e);t&&(t.destroy(),S.instances.delete(e))}static destroyAll(){for(let e of S.instances.values())e.destroy();S.instances.clear()}async init(){if(this.initialized)return;let e=document.getElementById(\\`meno-cms-\\${this.collection}\\`);if(e?.textContent)try{this.items=JSON.parse(e.textContent),this.filteredItems=[...this.items],this.initialized=!0,this.emit(\"init\",this.items),this.notifyWatchers();return}catch(t){console.error(\\`MenoFilter: Failed to parse inline data for \"\\${this.collection}\"\\`,t)}try{let t=await fetch(\\`/data/\\${this.collection}/index.json\\`);if(t.ok){this.items=await t.json(),this.filteredItems=[...this.items],this.initialized=!0,this.emit(\"init\",this.items),this.notifyWatchers();return}}catch(t){console.error(\\`MenoFilter: Failed to fetch static data for \"\\${this.collection}\"\\`,t)}console.warn(\\`MenoFilter: No data found for collection \"\\${this.collection}\"\\`),this.items=[],this.filteredItems=[],this.initialized=!0,this.emit(\"init\",[]),this.notifyWatchers()}isInitialized(){return this.initialized}destroy(){this.eventListeners.clear(),this.watchers.clear(),this.items=[],this.filteredItems=[],this.criteria={},this.orCriteria=[],this.initialized=!1}filter(e){return this.emit(\"beforeFilter\",e),this.criteria=e,this.orCriteria=[],this.currentPage=1,this.applyAllFilters(),this.emit(\"afterFilter\",this.filteredItems),this.getPageItems()}filterOr(e){return this.emit(\"beforeFilter\",e),this.criteria={},this.orCriteria=e,this.currentPage=1,this.applyAllFilters(),this.emit(\"afterFilter\",this.filteredItems),this.getPageItems()}addFilter(e,t){return this.criteria[e]=t,this.currentPage=1,this.applyAllFilters(),this.emit(\"afterFilter\",this.filteredItems),this.getPageItems()}removeFilter(e){return delete this.criteria[e],this.currentPage=1,this.applyAllFilters(),this.emit(\"afterFilter\",this.filteredItems),this.getPageItems()}clearFilters(){return this.criteria={},this.orCriteria=[],this.currentPage=1,this.applyAllFilters(),this.emit(\"afterFilter\",this.filteredItems),this.getPageItems()}getFilters(){return{...this.criteria}}search(e,t){return this.emit(\"beforeSearch\",{query:e,fields:t}),this.searchQuery=e,this.searchFields=t??[],this.currentPage=1,this.applyAllFilters(),this.emit(\"afterSearch\",this.filteredItems),this.getPageItems()}clearSearch(){return this.searchQuery=\"\",this.searchFields=[],this.applyAllFilters(),this.getPageItems()}getSearch(){return{query:this.searchQuery,fields:[...this.searchFields]}}sort(e,t=\"asc\"){return this.emit(\"beforeSort\",{field:e,order:t}),this.sortConfig={field:e,order:t},this.currentPage=1,this.applyAllFilters(),this.emit(\"afterSort\",this.filteredItems),this.getPageItems()}clearSort(){return this.sortConfig=null,this.applyAllFilters(),this.getPageItems()}getSort(){return this.sortConfig?{...this.sortConfig}:null}setPage(e){let t=this.getTotalPages(),n=Math.max(1,Math.min(e,t||1));return n!==this.currentPage&&(this.currentPage=n,this.emit(\"pageChange\",this.getPageInfo()),this.notifyWatchers()),this.getPageItems()}nextPage(){return this.setPage(this.currentPage+1)}prevPage(){return this.setPage(this.currentPage-1)}setPerPage(e){return this.perPage=e,this.currentPage=1,this.emit(\"pageChange\",this.getPageInfo()),this.notifyWatchers(),this.getPageItems()}getPageInfo(){let e=this.getTotalPages();return{current:this.currentPage,total:e,hasNext:this.currentPage<e,hasPrev:this.currentPage>1,totalItems:this.filteredItems.length,perPage:this.perPage||this.filteredItems.length}}getTotalPages(){return this.perPage===0?1:Math.ceil(this.filteredItems.length/this.perPage)}getPageItems(){if(this.perPage===0)return this.filteredItems;let e=(this.currentPage-1)*this.perPage,t=e+this.perPage;return this.filteredItems.slice(e,t)}loadMore(e){let t=e??(this.perPage||10),n=Math.min(this.visibleCount+t,this.filteredItems.length);return n!==this.visibleCount&&(this.visibleCount=n,this.emit(\"loadMore\",this.getLoadMoreInfo()),this.notifyWatchers()),this.getVisibleItems()}getVisibleItems(){return this.visibleCount===0?this.getPageItems():this.filteredItems.slice(0,this.visibleCount)}getLoadMoreInfo(){let e=this.visibleCount||this.filteredItems.length;return{visible:e,total:this.filteredItems.length,remaining:Math.max(0,this.filteredItems.length-e),hasMore:e<this.filteredItems.length}}resetVisibleCount(){this.visibleCount=this.perPage||0}initLoadMore(e){this.visibleCount=e??(this.perPage||10),this.notifyWatchers()}getAll(){return this.items}getFiltered(){return this.filteredItems}getItems(){return this.getPageItems()}getById(e){return this.items.find(t=>t._id===e||t._filename===e)}getUniqueValues(e){let t=new Set;for(let n of this.items){let i=n[e];i!=null&&(Array.isArray(i)?i.forEach(s=>t.add(s)):t.add(i))}return Array.from(t)}countFacets(e,t){let n={};for(let i of e){let s=i[t];if(s!=null)if(Array.isArray(s))s.forEach(o=>{let a=String(o);n[a]=(n[a]||0)+1});else{let o=String(s);n[o]=(n[o]||0)+1}}return n}getFacets(e){return this.countFacets(this.filteredItems,e)}getAllFacets(e){return this.countFacets(this.items,e)}reset(){return this.criteria={},this.orCriteria=[],this.searchQuery=\"\",this.searchFields=[],this.sortConfig=null,this.currentPage=1,this.filteredItems=[...this.items],this.emit(\"reset\",null),this.notifyWatchers(),this.getPageItems()}setFieldType(e,t){this.fieldTypes[e]=t}setFieldTypes(e){this.fieldTypes={...this.fieldTypes,...e}}getFieldTypes(){return{...this.fieldTypes}}coerceValue(e,t){let n=this.fieldTypes[e];if(!n||n===\"string\"||t===null||t===void 0)return t;switch(n){case\"number\":{if(typeof t==\"number\")return t;let i=parseFloat(String(t));return isNaN(i)?t:i}case\"date\":{if(t instanceof Date)return t.getTime();let i=new Date(String(t)).getTime();return isNaN(i)?t:i}case\"boolean\":return t===!0||t===\"true\"||t===\"1\";default:return t}}filterRange(e,t){let n={};return t.min!==void 0&&t.min!==\"\"&&(n.$gte=t.min),t.max!==void 0&&t.max!==\"\"&&(n.$lte=t.max),Object.keys(n).length===0?this.removeFilter(e):this.addFilter(e,n)}clearRangeFilter(e){return this.removeFilter(e)}enableUrlSync(e){typeof window>\"u\"||(this.urlSync=!0,this.urlMode=e?.mode??\"replace\",window.addEventListener(\"popstate\",this.popstateHandler),this.syncFromUrl())}disableUrlSync(){typeof window>\"u\"||(this.urlSync=!1,window.removeEventListener(\"popstate\",this.popstateHandler))}syncToUrl(){if(typeof window>\"u\")return;let e=new URLSearchParams;for(let[i,s]of Object.entries(this.criteria))if(!(s==null||s===\"\"))if(typeof s==\"object\"&&s!==null&&!Array.isArray(s))for(let[o,a]of Object.entries(s))a!=null&&a!==\"\"&&e.set(\\`filter.\\${i}.\\${o}\\`,String(a));else Array.isArray(s)?e.set(\\`filter.\\${i}\\`,s.join(\",\")):e.set(\\`filter.\\${i}\\`,String(s));this.sortConfig&&e.set(\"sort\",\\`\\${this.sortConfig.field}:\\${this.sortConfig.order}\\`),this.searchQuery&&(e.set(\"search\",this.searchQuery),this.searchFields.length>0&&e.set(\"search.fields\",this.searchFields.join(\",\"))),this.currentPage>1&&e.set(\"page\",String(this.currentPage)),this.perPage>0&&e.set(\"perPage\",String(this.perPage));let t=e.toString(),n=t?\\`\\${window.location.pathname}?\\${t}\\`:window.location.pathname;this.urlMode===\"push\"?history.pushState(null,\"\",n):history.replaceState(null,\"\",n)}syncFromUrl(){if(typeof window>\"u\")return;let e=new URLSearchParams(window.location.search);if(e.size===0)return;let t={};for(let[a,l]of e.entries()){if(!a.startsWith(\"filter.\"))continue;let u=a.split(\".\"),c=u[1],d=u[2];d?((!t[c]||typeof t[c]!=\"object\")&&(t[c]={}),t[c][d]=l):l.includes(\",\")?t[c]=l.split(\",\"):t[c]=l}let n=e.get(\"sort\");if(n){let[a,l=\"asc\"]=n.split(\":\");this.sortConfig={field:a,order:l}}let i=e.get(\"search\");if(i){this.searchQuery=i;let a=e.get(\"search.fields\");a&&(this.searchFields=a.split(\",\"))}let s=e.get(\"page\");if(s){let a=parseInt(s,10);!isNaN(a)&&a>0&&(this.currentPage=a)}let o=e.get(\"perPage\");if(o){let a=parseInt(o,10);!isNaN(a)&&a>0&&(this.perPage=a)}Object.keys(t).length>0&&(this.criteria=t),this.applyAllFilters()}setFuzzySearch(e,t){this.fuzzySearchEnabled=e,t!==void 0&&(this.fuzzyThreshold=Math.max(0,Math.min(1,t)))}isFuzzySearchEnabled(){return this.fuzzySearchEnabled}getTrigrams(e){let t=[],n=\\` \\${e} \\`;for(let i=0;i<n.length-2;i++)t.push(n.slice(i,i+3));return t}fuzzyMatch(e,t){if(t.length<3)return e.toLowerCase().includes(t.toLowerCase());let n=e.toLowerCase(),i=t.toLowerCase();if(n.includes(i))return!0;let s=this.getTrigrams(n),o=this.getTrigrams(i),a=new Set(o),l=new Set(s),u=0;for(let h of a)l.has(h)&&u++;let c=a.size+l.size-u;return c===0?!1:u/c>=this.fuzzyThreshold}on(e,t){return this.eventListeners.has(e)||this.eventListeners.set(e,new Set),this.eventListeners.get(e).add(t),()=>this.off(e,t)}off(e,t){this.eventListeners.get(e)?.delete(t)}emit(e,t){let n=this.eventListeners.get(e);if(n)for(let i of n)try{i(t)}catch(s){console.error(\\`MenoFilter: Error in \\${e} listener\\`,s)}}watch(e){return this.watchers.add(e),e(this.getState()),()=>this.watchers.delete(e)}subscribe(e){let t=n=>e(n.pageItems);return this.watchers.add(t),e(this.getPageItems()),()=>this.watchers.delete(t)}getState(){return{items:this.items,filteredItems:this.filteredItems,pageItems:this.getPageItems(),filters:{...this.criteria},sort:this.sortConfig?{...this.sortConfig}:null,search:{query:this.searchQuery,fields:[...this.searchFields]},page:this.getPageInfo()}}notifyWatchers(){let e=this.getState();for(let t of this.watchers)try{t(e)}catch(n){console.error(\"MenoFilter: Error in watcher\",n)}this.urlSync&&this.syncToUrl()}applyAllFilters(){let e=[...this.items];if(Object.keys(this.criteria).length>0&&(e=e.filter(t=>this.matchesCriteria(t,this.criteria))),this.orCriteria.length>0&&(e=e.filter(t=>this.orCriteria.some(n=>this.matchesCriteria(t,n)))),this.searchQuery){let t=this.searchQuery;e=e.filter(n=>(this.searchFields.length>0?this.searchFields:Object.keys(n)).some(s=>{let o=n[s];return typeof o!=\"string\"?!1:this.fuzzySearchEnabled?this.fuzzyMatch(o,t):o.toLowerCase().includes(t.toLowerCase())}))}if(this.sortConfig){let{field:t,order:n}=this.sortConfig;e.sort((i,s)=>{let o=i[t],a=s[t];if(o==null)return n===\"asc\"?1:-1;if(a==null)return n===\"asc\"?-1:1;let l=0;return typeof o==\"string\"&&typeof a==\"string\"?l=o.localeCompare(a):typeof o==\"number\"&&typeof a==\"number\"?l=o-a:l=String(o).localeCompare(String(a)),n===\"desc\"?-l:l})}this.filteredItems=e,this.visibleCount>0&&(this.visibleCount=Math.min(this.perPage||10,e.length)),this.notifyWatchers()}matchesCriteria(e,t){let n=Object.entries(t);return this.filterMatch===\"or\"?n.some(([i,s])=>this.matchesFieldValue(e,i,s)):n.every(([i,s])=>this.matchesFieldValue(e,i,s))}matchesFieldValue(e,t,n){if(n==null||n===\"\"||n===\"*\")return!0;let i=e[t];if(this.isOperatorObject(n))return this.matchesOperators(i,n,t);if(Array.isArray(i))return i.includes(n);if(Array.isArray(n))return n.includes(i);let s=this.coerceValue(t,i),o=this.coerceValue(t,n);return s===o}isOperatorObject(e){return typeof e!=\"object\"||e===null||Array.isArray(e)?!1:Object.keys(e).some(n=>n.startsWith(\"$\"))}matchesOperators(e,t,n){for(let[i,s]of Object.entries(t))if(!this.matchesOperator(e,i,s,n))return!1;return!0}matchesOperator(e,t,n,i){let s=i?this.coerceValue(i,e):e,o=i?this.coerceValue(i,n):n;switch(t){case\"$eq\":return s===o;case\"$neq\":return s!==o;case\"$gt\":return typeof s==\"number\"&&typeof o==\"number\"?s>o:String(s)>String(o);case\"$gte\":return typeof s==\"number\"&&typeof o==\"number\"?s>=o:String(s)>=String(o);case\"$lt\":return typeof s==\"number\"&&typeof o==\"number\"?s<o:String(s)<String(o);case\"$lte\":return typeof s==\"number\"&&typeof o==\"number\"?s<=o:String(s)<=String(o);case\"$contains\":return Array.isArray(e)?e.includes(n):typeof e==\"string\"&&typeof n==\"string\"?e.toLowerCase().includes(n.toLowerCase()):!1;case\"$notContains\":return Array.isArray(e)?!e.includes(n):typeof e==\"string\"&&typeof n==\"string\"?!e.toLowerCase().includes(n.toLowerCase()):!0;case\"$startsWith\":return typeof e==\"string\"&&typeof n==\"string\"?e.toLowerCase().startsWith(n.toLowerCase()):!1;case\"$endsWith\":return typeof e==\"string\"&&typeof n==\"string\"?e.toLowerCase().endsWith(n.toLowerCase()):!1;case\"$in\":return Array.isArray(n)?n.includes(e):!1;case\"$nin\":return Array.isArray(n)?!n.includes(e):!0;case\"$empty\":let a=e==null||e===\"\"||Array.isArray(e)&&e.length===0;return n?a:!a;default:return console.warn(\\`MenoFilter: Unknown operator \"\\${t}\"\\`),!0}}};g(S,\"instances\",new Map);var F=S;var f={FILTER:\"data-meno-filter\",LIST:\"data-meno-list\",ITEM:\"data-meno-item\",FILTER_FIELD:\"data-meno-filter-field\",FILTER_VALUE:\"data-meno-filter-value\",FILTER_MODE:\"data-meno-filter-mode\",SEARCH:\"data-meno-search\",SEARCH_FIELDS:\"data-meno-search-fields\",SEARCH_FUZZY:\"data-meno-search-fuzzy\",SEARCH_THRESHOLD:\"data-meno-search-threshold\",SORT:\"data-meno-sort\",SORT_ORDER:\"data-meno-sort-order\",CLEAR:\"data-meno-clear\",RESET:\"data-meno-reset\",PER_PAGE:\"data-meno-per-page\",FILTER_MATCH:\"data-meno-filter-match\",DEBOUNCE:\"data-meno-debounce\",PAGE:\"data-meno-page\",PAGE_CURRENT:\"data-meno-page-current\",PAGE_TOTAL:\"data-meno-page-total\",PAGE_BUTTONS:\"data-meno-page-buttons\",PER_PAGE_SELECT:\"data-meno-per-page-select\",LOAD_MORE:\"data-meno-load-more\",REMAINING:\"data-meno-remaining\",COUNT:\"data-meno-count\",FACET:\"data-meno-facet\",EMPTY:\"data-meno-empty\",ACTIVE_FILTERS:\"data-meno-active-filters\",ACTIVE_FILTER_TEMPLATE:\"data-meno-active-filter-template\",FILTER_REMOVE:\"data-meno-filter-remove\",ACTIVE_CLASS:\"data-meno-active-class\",TYPES:\"data-meno-types\",RANGE:\"data-meno-range\",RANGE_BOUND:\"data-meno-range-bound\",URL_SYNC:\"data-meno-url-sync\",URL_MODE:\"data-meno-url-mode\"};function te(r,e){let t;return(...n)=>{clearTimeout(t),t=setTimeout(()=>r(...n),e)}}function x(r){let e=r.closest(\\`[\\${f.FILTER_MODE}]\\`);if(!e)return null;let t=e.getAttribute(f.FILTER_MODE);return t===\"single\"||t===\"multi\"?t:null}function ne(r,e,t,n){let i=[];n!==void 0&&(typeof n==\"object\"&&n!==null&&\"$in\"in n?i=[...n.$in||[]]:typeof n==\"string\"&&(i=[n]));let s=i.indexOf(t);s===-1?i.push(t):i.splice(s,1),i.length===0?r.removeFilter(e):i.length===1?r.addFilter(e,i[0]):r.addFilter(e,{$in:i})}function O(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.FILTER_FIELD}][\\${f.FILTER_VALUE}]\\`);for(let l of i){if(l.tagName===\"INPUT\")continue;let u=l.getAttribute(f.FILTER_FIELD),c=l.getAttribute(f.FILTER_VALUE),d=()=>{let h=x(l),p=t.getFilters()[u];h===\"multi\"?ne(t,u,c,p):h===\"single\"?p!==c&&t.addFilter(u,c):p===c?t.removeFilter(u):t.addFilter(u,c)};l.addEventListener(\"click\",d),n.push(()=>l.removeEventListener(\"click\",d))}let s=e.querySelectorAll(\\`input[type=\"checkbox\"][\\${f.FILTER_FIELD}]\\`);for(let l of s){let u=l.getAttribute(f.FILTER_FIELD),c=()=>{if(x(l)===\"single\"&&l.checked){let h=e.querySelectorAll(\\`input[type=\"checkbox\"][\\${f.FILTER_FIELD}=\"\\${u}\"]\\`);for(let m of h)m!==l&&(m.checked=!1)}re(e,t,u)};l.addEventListener(\"change\",c),n.push(()=>l.removeEventListener(\"change\",c))}let o=e.querySelectorAll(\\`select[\\${f.FILTER_FIELD}]\\`);for(let l of o){let u=l.getAttribute(f.FILTER_FIELD),c=()=>{let d=l.value;d===\"\"||d===\"all\"||d===\"*\"?t.removeFilter(u):t.addFilter(u,d)};l.addEventListener(\"change\",c),n.push(()=>l.removeEventListener(\"change\",c))}let a=e.querySelectorAll(\\`input[type=\"radio\"][\\${f.FILTER_FIELD}]\\`);for(let l of a){let u=l.getAttribute(f.FILTER_FIELD),c=l.getAttribute(f.FILTER_VALUE)||l.value,d=()=>{l.checked&&(c===\"\"||c===\"all\"||c===\"*\"?t.removeFilter(u):t.addFilter(u,c))};l.addEventListener(\"change\",d),n.push(()=>l.removeEventListener(\"change\",d))}}function re(r,e,t){let n=r.querySelectorAll(\\`input[type=\"checkbox\"][\\${f.FILTER_FIELD}=\"\\${t}\"]:checked\\`),i=Array.from(n).map(s=>s.getAttribute(f.FILTER_VALUE)||s.value);i.length===0?e.removeFilter(t):i.length===1?e.addFilter(t,i[0]):e.addFilter(t,{$in:i})}function N(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.SEARCH}]\\`);for(let s of i){let o=s.getAttribute(f.SEARCH_FIELDS),a=o?o.split(\",\").map(d=>d.trim()):void 0,l,u=parseInt(e.getAttribute(f.DEBOUNCE)||\"300\",10),c=()=>{clearTimeout(l),l=setTimeout(()=>{t.search(s.value,a)},u)};s.addEventListener(\"input\",c),n.push(()=>{s.removeEventListener(\"input\",c),clearTimeout(l)})}}function _(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.SORT}]\\`);for(let o of i){if(o.tagName===\"SELECT\")continue;let a=o.getAttribute(f.SORT),l=o.getAttribute(f.SORT_ORDER)||\"asc\",u=()=>{let c=t.getSort();c?.field===a?c.order===l?t.sort(a,l===\"asc\"?\"desc\":\"asc\"):t.clearSort():t.sort(a,l)};o.addEventListener(\"click\",u),n.push(()=>o.removeEventListener(\"click\",u))}let s=e.querySelectorAll(\\`select[\\${f.SORT}]\\`);for(let o of s){let a=()=>{let l=o.value;if(!l){t.clearSort();return}let[u,c=\"asc\"]=l.split(\":\");t.sort(u,c)};o.addEventListener(\"change\",a),n.push(()=>o.removeEventListener(\"change\",a))}}function q(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.CLEAR}]\\`);for(let o of i){let a=()=>{t.clearFilters()};o.addEventListener(\"click\",a),n.push(()=>o.removeEventListener(\"click\",a))}let s=e.querySelectorAll(\\`[\\${f.RESET}]\\`);for(let o of s){let a=()=>{t.reset(),ie(e)};o.addEventListener(\"click\",a),n.push(()=>o.removeEventListener(\"click\",a))}}function ie(r){let e=r.querySelectorAll(\\`input[type=\"checkbox\"][\\${f.FILTER_FIELD}]\\`);for(let s of e)s.checked=!1;let t=r.querySelectorAll(\\`select[\\${f.FILTER_FIELD}]\\`);for(let s of t)s.selectedIndex=0;let n=r.querySelectorAll(\\`[\\${f.SEARCH}]\\`);for(let s of n)s.value=\"\";let i=r.querySelectorAll(\\`select[\\${f.SORT}]\\`);for(let s of i)s.selectedIndex=0}function D(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.PAGE}]\\`);for(let o of i){let a=o.getAttribute(f.PAGE),l=()=>{switch(a){case\"prev\":t.prevPage();break;case\"next\":t.nextPage();break;case\"first\":t.setPage(1);break;case\"last\":t.setPage(t.getPageInfo().total);break;default:let u=parseInt(a||\"1\",10);isNaN(u)||t.setPage(u)}};o.addEventListener(\"click\",l),n.push(()=>o.removeEventListener(\"click\",l))}let s=e.querySelectorAll(\\`[\\${f.PER_PAGE_SELECT}]\\`);for(let o of s){let a=()=>{let l=parseInt(o.value,10);!isNaN(l)&&l>0&&t.setPerPage(l)};o.addEventListener(\"change\",a),n.push(()=>o.removeEventListener(\"change\",a))}}function z(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelector(\\`[\\${f.LOAD_MORE}]\\`);if(!i)return;r.loadMoreMode=!0,t.initLoadMore();let s=()=>{let o=i.getAttribute(f.LOAD_MORE),a=o&&o!==\"\"?parseInt(o,10):void 0;t.loadMore(a)};i.addEventListener(\"click\",s),n.push(()=>i.removeEventListener(\"click\",s))}function H(r){if(r.value)return r.type===\"date\"?r.valueAsNumber||(r.value?new Date(r.value).getTime():void 0):r.valueAsNumber||(r.value?parseFloat(r.value):void 0)}function U(r){let{wrapper:e,filter:t,cleanup:n}=r,i=e.querySelectorAll(\\`[\\${f.RANGE}]\\`);if(i.length===0)return;let s=parseInt(e.getAttribute(f.DEBOUNCE)||\"300\",10),o=new Map;for(let a of i){let l=a.getAttribute(f.RANGE);if(!l)continue;let u=a.getAttribute(f.RANGE_BOUND);!u||u!==\"min\"&&u!==\"max\"||(o.has(l)||o.set(l,{}),o.get(l)[u]=a)}for(let[a,l]of o){let u=te(()=>{let c=l.min?H(l.min):void 0,d=l.max?H(l.max):void 0;t.filterRange(a,{min:c,max:d})},s);if(l.min){let c=()=>u();l.min.addEventListener(\"input\",c),n.push(()=>l.min.removeEventListener(\"input\",c))}if(l.max){let c=()=>u();l.max.addEventListener(\"input\",c),n.push(()=>l.max.removeEventListener(\"input\",c))}}}function I(r){return r.replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\").replace(/'/g,\"&#x27;\")}function j(r){return r.endsWith(\"ies\")?r.slice(0,-3)+\"y\":r.endsWith(\"es\")?r.slice(0,-2):r.endsWith(\"s\")?r.slice(0,-1):r}function R(r,e){return e.split(\".\").reduce((t,n)=>t&&typeof t==\"object\"?t[n]:void 0,r)}function G(r,e,t,n,i){let s=r;s=s.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}\\\\\\\\.(\\\\\\\\w+)\\\\\\\\}\\\\\\\\}\\`,\"g\"),(l,u)=>{let c=e[u];return I(c!=null?String(c):\"\")}),s=s.replace(/\\\\{\\\\{item\\\\.(\\\\w+)\\\\}\\\\}/g,(l,u)=>{let c=e[u];return I(c!=null?String(c):\"\")}),s=s.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}Index\\\\\\\\}\\\\\\\\}\\`,\"g\"),String(n)),s=s.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}First\\\\\\\\}\\\\\\\\}\\`,\"g\"),n===0?\"true\":\"false\"),s=s.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}Last\\\\\\\\}\\\\\\\\}\\`,\"g\"),n===i-1?\"true\":\"false\"),s=s.replace(/\\\\{\\\\{itemIndex\\\\}\\\\}/g,String(n)),s=s.replace(/\\\\{\\\\{itemFirst\\\\}\\\\}/g,n===0?\"true\":\"false\"),s=s.replace(/\\\\{\\\\{itemLast\\\\}\\\\}/g,n===i-1?\"true\":\"false\");let o=document.createElement(\"div\");o.innerHTML=s;let a=o.firstElementChild;return W(a,e,t),a}function se(r,e,t,n,i,s,o){let a=r;o!==t&&(a=a.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${o}\\\\\\\\.(\\\\\\\\w+)\\\\\\\\}\\\\\\\\}\\`,\"g\"),(c,d)=>{let h=s[d];return I(h!=null?String(h):\"\")})),a=a.replace(/\\\\{\\\\{parentItem\\\\.(\\\\w+)\\\\}\\\\}/g,(c,d)=>{let h=s[d];return I(h!=null?String(h):\"\")}),o===\"item\"&&(a=a.replace(/\\\\{\\\\{item\\\\.(\\\\w+)\\\\}\\\\}/g,(c,d)=>{let h=s[d];return I(h!=null?String(h):\"\")})),a=a.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}\\\\\\\\.(\\\\\\\\w+)\\\\\\\\}\\\\\\\\}\\`,\"g\"),(c,d)=>{let h=e[d];return I(h!=null?String(h):\"\")}),t!==\"item\"&&o!==\"item\"&&(a=a.replace(/\\\\{\\\\{item\\\\.(\\\\w+)\\\\}\\\\}/g,(c,d)=>{let h=e[d];return I(h!=null?String(h):\"\")})),a=a.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}Index\\\\\\\\}\\\\\\\\}\\`,\"g\"),String(n)),a=a.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}First\\\\\\\\}\\\\\\\\}\\`,\"g\"),n===0?\"true\":\"false\"),a=a.replace(new RegExp(\\`\\\\\\\\{\\\\\\\\{\\${t}Last\\\\\\\\}\\\\\\\\}\\`,\"g\"),n===i-1?\"true\":\"false\"),a=a.replace(/\\\\{\\\\{itemIndex\\\\}\\\\}/g,String(n)),a=a.replace(/\\\\{\\\\{itemFirst\\\\}\\\\}/g,n===0?\"true\":\"false\"),a=a.replace(/\\\\{\\\\{itemLast\\\\}\\\\}/g,n===i-1?\"true\":\"false\");let l=document.createElement(\"div\");l.innerHTML=a;let u=l.firstElementChild;return W(u,e,t),u}function W(r,e,t){let n=r.querySelectorAll('[data-cms-list-nested=\"true\"]');for(let i of n)oe(i,e,t)}function oe(r,e,t){let n=r.getAttribute(\"data-cms-config\");if(!n)return;let i;try{i=JSON.parse(n)}catch{return}let s=i.collection,o=r.querySelector(\"template[data-nested-template]\");if(!o)return;let a=o.innerHTML.trim(),l=i.itemAs||j(s),u=ae(s);if(!u){console.warn(\\`MenoFilter: No data for nested collection \"\\${s}\". Ensure clientData.enabled is true in schema.\\`);return}let c;i.items?c=le(i.items,e,t).map(p=>u.find(E=>E._id===p||E._filename===p)).filter(p=>p!==void 0):c=ce(u,i.filter,e,t),i.sort&&(c=de(c,i.sort)),i.offset&&(c=c.slice(i.offset)),i.limit&&(c=c.slice(0,i.limit));let d=[];for(let m=0;m<c.length;m++){let p=se(a,c[m],l,m,c.length,e,t);d.push(p)}Array.from(r.children).filter(m=>m.tagName!==\"TEMPLATE\").forEach(m=>m.remove());for(let m of d)r.appendChild(m);r.setAttribute(\"data-cms-list-hydrated\",\"true\")}function ae(r){let e=document.getElementById(\\`meno-cms-\\${r}\\`);if(!e?.textContent)return null;try{return JSON.parse(e.textContent)}catch{return null}}function le(r,e,t){if(Array.isArray(r))return r;if(typeof r!=\"string\"||!r.startsWith(\"{{\"))return[r];let n=r.match(/^\\\\{\\\\{(\\\\w+)\\\\.([^}]+)\\\\}\\\\}$/);if(!n)return[];let[,i,s]=n;if(i!==t&&i!==\"item\")return[];let o=R(e,s);return o==null?[]:Array.isArray(o)?o.map(String):[String(o)]}function ce(r,e,t,n){if(!e)return r;let i=ue(e,t,n);return r.filter(s=>fe(s,i))}function ue(r,e,t){if(Array.isArray(r))return r.map(n=>({...n,value:P(n.value,e,t)}));if(r&&typeof r==\"object\"){if(\"field\"in r&&\"value\"in r)return{...r,value:P(r.value,e,t)};let n={};for(let[i,s]of Object.entries(r))n[i]=P(s,e,t);return n}return r}function P(r,e,t){if(typeof r!=\"string\"||!r.startsWith(\"{{\"))return r;let n=r.match(/^\\\\{\\\\{(\\\\w+)\\\\.([^}]+)\\\\}\\\\}$/);if(!n)return r;let[,i,s]=n;return i!==t&&i!==\"item\"?r:R(e,s)}function fe(r,e){if(!e||typeof e!=\"object\")return!0;if(Array.isArray(e))return e.every(t=>B(r,t));if(\"field\"in e&&\"value\"in e)return B(r,e);for(let[t,n]of Object.entries(e))if(r[t]!==n)return!1;return!0}function B(r,e){let t=r[e.field],n=e.value;return Array.isArray(t)?t.includes(n):t===n}function de(r,e){if(!e)return r;let t=Array.isArray(e)?e[0]:e;if(!t||typeof t!=\"object\")return r;let{field:n,order:i=\"asc\"}=t;return[...r].sort((s,o)=>{let a=s[n],l=o[n],u=0;return typeof a==\"string\"&&typeof l==\"string\"?u=a.localeCompare(l):a!=null&&l!=null&&(u=String(a).localeCompare(String(l))),i===\"desc\"?-u:u})}function w(r){let{wrapper:e,filter:t}=r,n=t.getState();he(r),Ee(e,n),Te(e,t),Se(e,t,r),Le(e,n),ve(e,n),Fe(e,t),Me(e,t),be(e,t)}function he(r){let{wrapper:e,filter:t,itemTemplate:n}=r,i=e.querySelector(\\`[\\${f.LIST}]\\`);if(!i)return;if(t.getAll().length>0&&n){me(r,i);return}ge(r,i)}function me(r,e){let{filter:t,itemTemplate:n,ssrItems:i,itemAs:s,loadMoreMode:o}=r,a=o?t.getVisibleItems():t.getItems(),l=[],u=new Set;if(o)for(let c of Array.from(e.children)){if(c.tagName===\"TEMPLATE\")continue;let d=c.getAttribute(\"data-id\")||c.getAttribute(\"data-_id\");d&&u.add(d)}if(!o)for(let c of Array.from(e.children))c.tagName!==\"TEMPLATE\"&&(c.hasAttribute(\"data-meno-dynamic\")?c.remove():c.style.display=\"none\");for(let c=0;c<a.length;c++){let d=a[c],h=d._id;if(o&&u.has(h))continue;let m=i.get(h);if(m)m.style.display=\"\",e.appendChild(m),l.push(m);else if(n){let p=G(n,d,s,c,a.length);p.setAttribute(\"data-meno-dynamic\",\"true\"),p.setAttribute(\"data-id\",h),e.appendChild(p),l.push(p)}}}function ge(r,e){let{filter:t}=r,n=Array.from(e.children);if(n.length===0)return;let i=t.getFilters(),s=t.getSearch().query.toLowerCase(),o=t.getSearch().fields,a=t.getSort(),l=t.getPageInfo().perPage,u=t.getPageInfo().current,c=n.filter(E=>{for(let[v,y]of Object.entries(i)){let T=A(E,v);if(!ye(T,y))return!1}return!(s&&!pe(E,o).toLowerCase().includes(s))});a&&c.sort((E,v)=>{let y=A(E,a.field),T=A(v,a.field),L=0;return typeof y==\"string\"&&typeof T==\"string\"?L=y.localeCompare(T):y!=null&&T!=null?L=String(y).localeCompare(String(T)):y==null?L=1:L=-1,a.order===\"desc\"?-L:L});let d=c.length,h=l>0?(u-1)*l:0,m=l>0?h+l:d,p=c.slice(h,m);for(let E of n){let v=p.includes(E);E.style.display=v?\"\":\"none\"}if(a)for(let E of c)e.appendChild(E)}function A(r,e){let t=r.getAttribute(\\`data-\\${e}\\`);if(t!==null)return t;let n=r.querySelector(\\`[data-field=\"\\${e}\"]\\`);if(n)return n.textContent?.trim()||null;let i=r.querySelector(\\`[data-\\${e}]\\`);return i?i.getAttribute(\\`data-\\${e}\\`):null}function pe(r,e){return e.length>0?e.map(t=>A(r,t)||\"\").join(\" \"):r.textContent||\"\"}function ye(r,e){if(e==null||e===\"\")return!0;if(r===null)return!1;if(typeof e==\"object\"&&e!==null&&!Array.isArray(e)){let t=e;for(let[n,i]of Object.entries(t))switch(n){case\"$eq\":if(r!==i)return!1;break;case\"$neq\":if(r===i)return!1;break;case\"$contains\":if(!r.toLowerCase().includes(String(i).toLowerCase()))return!1;break;case\"$in\":if(!Array.isArray(i)||!i.includes(r))return!1;break;case\"$nin\":if(Array.isArray(i)&&i.includes(r))return!1;break}return!0}return r===String(e)}function Ee(r,e){let t=r.querySelectorAll(\\`[\\${f.COUNT}]\\`);for(let n of t){let i=n.getAttribute(f.COUNT),s;switch(i){case\"results\":s=e.page.totalItems;break;case\"total\":s=e.items.length;break;case\"visible\":s=e.pageItems.length;break;default:continue}n.textContent=String(s)}}function Te(r,e){let t=r.querySelectorAll(\\`[\\${f.FACET}]\\`);for(let n of t){let i=n.getAttribute(f.FACET);if(!i)continue;let[s,o]=i.split(\":\");if(!s||!o)continue;let l=e.getAllFacets(s)[o]||0;n.textContent=String(l)}}function Se(r,e,t){let n=r.querySelector(\\`[\\${f.ACTIVE_FILTERS}]\\`);if(!n)return;let i=r.querySelector(\\`template[\\${f.ACTIVE_FILTER_TEMPLATE}]\\`),s=e.getFilters(),o=Object.entries(s);if(n.innerHTML=\"\",o.length===0){n.style.display=\"none\";return}n.style.display=\"\";for(let[a,l]of o){let u=typeof l==\"object\"?\"[filter]\":String(l);if(i){let c=i.content.cloneNode(!0),d=c.querySelector(\"[data-meno-filter-label]\"),h=c.querySelector(\"[data-meno-filter-value]\"),m=c.querySelector(\\`[\\${f.FILTER_REMOVE}]\\`);if(d&&(d.textContent=a),h&&(h.textContent=u),m){let p=()=>{e.removeFilter(a)};m.addEventListener(\"click\",p),t.cleanup.push(()=>m.removeEventListener(\"click\",p))}n.appendChild(c)}else{let c=document.createElement(\"span\");c.className=\"meno-filter-tag\",c.innerHTML=\\`\\${a}: \\${u} <button type=\"button\">&times;</button>\\`;let d=c.querySelector(\"button\"),h=()=>{e.removeFilter(a)};d.addEventListener(\"click\",h),t.cleanup.push(()=>d.removeEventListener(\"click\",h)),n.appendChild(c)}}}function Le(r,e){let t=r.querySelector(\\`[\\${f.EMPTY}]\\`);t&&(e.pageItems.length===0?t.style.display=\"\":t.style.display=\"none\")}function ve(r,e){let{page:t}=e,n=r.querySelectorAll(\\`[\\${f.PAGE_CURRENT}]\\`);for(let l of n)l.textContent=String(t.current);let i=r.querySelectorAll(\\`[\\${f.PAGE_TOTAL}]\\`);for(let l of i)l.textContent=String(t.total);let s=r.querySelectorAll(\\`[\\${f.PAGE}=\"prev\"]\\`);for(let l of s)l.disabled=!t.hasPrev,l.style.opacity=t.hasPrev?\"\":\"0.5\";let o=r.querySelectorAll(\\`[\\${f.PAGE}=\"next\"]\\`);for(let l of o)l.disabled=!t.hasNext,l.style.opacity=t.hasNext?\"\":\"0.5\";let a=r.querySelector(\\`[\\${f.PAGE_BUTTONS}]\\`);a&&Ie(a,t,l=>{F.get(r.getAttribute(f.FILTER))?.setPage(l)})}function Ie(r,e,t){if(r.innerHTML=\"\",e.total<=1)return;let n=7,i=[];if(e.total<=n)i=Array.from({length:e.total},(s,o)=>o+1);else{let s=e.current;i=[1],s>3&&i.push(\"...\");for(let o=Math.max(2,s-1);o<=Math.min(e.total-1,s+1);o++)i.includes(o)||i.push(o);s<e.total-2&&i.push(\"...\"),i.includes(e.total)||i.push(e.total)}for(let s of i)if(s===\"...\"){let o=document.createElement(\"span\");o.textContent=\"...\",o.className=\"meno-page-dots\",r.appendChild(o)}else{let o=document.createElement(\"button\");o.type=\"button\",o.textContent=String(s),o.className=s===e.current?\"meno-page-btn active\":\"meno-page-btn\",o.addEventListener(\"click\",()=>t(s)),r.appendChild(o)}}function Fe(r,e){let t=e.getLoadMoreInfo(),n=r.querySelectorAll(\\`[\\${f.REMAINING}]\\`);for(let s of n)s.textContent=String(t.remaining);let i=r.querySelector(\\`[\\${f.LOAD_MORE}]\\`);i&&(i.style.display=t.hasMore?\"\":\"none\")}function Me(r,e){let t=e.getFilters(),n=r.getAttribute(f.ACTIVE_CLASS)||\"active\",i=r.querySelectorAll(\\`[\\${f.FILTER_FIELD}][\\${f.FILTER_VALUE}]\\`);for(let u of i){if(u.tagName===\"INPUT\")continue;let c=u.getAttribute(f.FILTER_FIELD),d=u.getAttribute(f.FILTER_VALUE);if(!c||!d)continue;let h=t[c],m=h!==void 0&&(h===d||Array.isArray(h)&&h.includes(d)||typeof h==\"object\"&&h!==null&&\"$in\"in h&&Array.isArray(h.$in)&&h.$in.includes(d));u.classList.toggle(n,m)}let s=r.querySelectorAll(\\`[\\${f.CLEAR}]\\`),o=Object.keys(t).length>0;for(let u of s)u.classList.toggle(n,!o);let a=e.getSort(),l=r.querySelectorAll(\\`[\\${f.SORT}]\\`);for(let u of l){if(u.tagName===\"SELECT\"){let h=u;a?h.value=\\`\\${a.field}:\\${a.order}\\`:h.value=\"\";continue}let c=u.getAttribute(f.SORT),d=a?.field===c;u.classList.toggle(n,d),d&&a?u.setAttribute(\"data-meno-sort-active\",a.order):u.removeAttribute(\"data-meno-sort-active\")}}function be(r,e){let t=e.getFilters(),n=r.querySelectorAll(\\`[\\${f.RANGE}]\\`);for(let i of n){let s=i.getAttribute(f.RANGE);if(!s)continue;let o=i.getAttribute(f.RANGE_BOUND);if(!o||o!==\"min\"&&o!==\"max\")continue;let a=t[s];if(!a||typeof a!=\"object\"||a===null)continue;let l=a,u=o===\"min\"?l.$gte:l.$lte;if(u!=null)if(i.type===\"date\"){let c=new Date(u);isNaN(c.getTime())||(i.value=c.toISOString().split(\"T\")[0])}else i.value=String(u)}}var M=new Map;async function C(){let r=document.querySelectorAll(\\`[\\${f.FILTER}]\\`);for(let e of r){let t=e.getAttribute(f.FILTER);t&&(M.has(t)||await Ae(e,t))}}async function Ae(r,e){let t=parseInt(r.getAttribute(f.PER_PAGE)||\"0\",10),n=r.getAttribute(f.FILTER_MATCH)||\"and\",i=parseInt(r.getAttribute(f.DEBOUNCE)||\"0\",10),s=r.getAttribute(f.URL_SYNC)===\"true\",o=r.getAttribute(f.URL_MODE)||\"replace\",a,l=r.getAttribute(f.TYPES);if(l)try{a=JSON.parse(l)}catch(T){console.warn(\"MenoFilter: Invalid data-meno-types JSON\",T)}let u=!1,c=.3,d=r.querySelector(\\`[\\${f.SEARCH}]\\`);if(d){u=d.getAttribute(f.SEARCH_FUZZY)===\"true\";let T=d.getAttribute(f.SEARCH_THRESHOLD);if(T){let L=parseFloat(T);isNaN(L)||(c=L)}}let h=new F({collection:e,perPage:t,filterMatch:n,debounce:i,urlSync:s,urlMode:o,fieldTypes:a,fuzzySearch:u,fuzzyThreshold:c}),m=[],{itemTemplate:p,ssrItems:E,itemAs:v}=Ce(r),y={wrapper:r,collection:e,filter:h,cleanup:m,itemTemplate:p,ssrItems:E,itemAs:v,loadMoreMode:!1};M.set(e,y),O(y),N(y),_(y),q(y),D(y),z(y),U(y),await h.init(),w(y),m.push(h.watch(()=>{w(y)}))}function Ce(r){let e=r.querySelector(\\`[\\${f.LIST}]\\`),t=new Map,n=\"item\";if(!e)return{itemTemplate:void 0,ssrItems:t,itemAs:n};let i=e.querySelector(\\`template[\\${f.ITEM}]\\`);if(i){let o=i.innerHTML.trim(),a=o.match(/\\\\{\\\\{(\\\\w+)\\\\./);a&&(n=a[1]);for(let l of Array.from(e.children)){if(l.tagName===\"TEMPLATE\")continue;let u=l.getAttribute(\"data-id\")||l.getAttribute(\"data-_id\");u&&t.set(u,l)}return{itemTemplate:o,ssrItems:t,itemAs:n}}let s=r.querySelector(\\`template[\\${f.ITEM}]\\`);if(s){let o=s.innerHTML.trim(),a=o.match(/\\\\{\\\\{(\\\\w+)\\\\./);return a&&(n=a[1]),{itemTemplate:o,ssrItems:t,itemAs:n}}for(let o=0;o<e.children.length;o++){let a=e.children[o];t.set(\\`__ssr_index_\\${o}\\`,a)}return{itemTemplate:void 0,ssrItems:t,itemAs:n}}function k(r){let e=M.get(r);if(e){for(let t of e.cleanup)t();e.filter.destroy(),M.delete(r),F.destroy(r)}}function Q(){for(let r of M.keys())k(r)}function Re(r){return M.get(r)}function $(){typeof document>\"u\"||(document.readyState===\"loading\"?document.addEventListener(\"DOMContentLoaded\",()=>C()):C())}$();var Pe={initMenoFilter:C,destroyMenoFilter:k,destroyAllMenoFilters:Q,autoInit:$};return ee(we);})();\nwindow.MenoFilter = MenoFilterBundle.MenoFilter;\n`;\n\n/**\n * Check if HTML contains elements that need MenoFilter\n */\nexport function needsMenoFilter(html: string): boolean {\n // Check for inline CMS data scripts\n if (/id=\"meno-cms-[^\"]+\"/i.test(html)) {\n return true;\n }\n // Check for cms-list nodes (static strategy)\n if (/data-cms-list=\"true\"/i.test(html)) {\n return true;\n }\n // Check for data-meno-filter wrappers\n if (/data-meno-filter=\"/i.test(html)) {\n return true;\n }\n return false;\n}\n\n/**\n * Check if any schemas have clientData enabled\n */\nexport function schemasNeedMenoFilter(\n schemas: Array<{ clientData?: { enabled: boolean } }>\n): boolean {\n return schemas.some((schema) => schema.clientData?.enabled === true);\n}\n\nexport default menoFilterScript;\n", "/**\n * HTML document generation for SSR\n * Generates complete HTML documents with SSR content\n * Supports CSP-compliant external scripts for static builds\n */\n\nimport type { ComponentDefinition, JSONPage, PageLibrariesConfig } from '../../shared/types';\nimport type { SlugMap } from '../../shared/slugTranslator';\nimport type { CMSService } from '../services/cmsService';\nimport { configService } from '../services/configService';\nimport { loadBreakpointConfig, loadResponsiveScalesConfig, loadIconsConfig, loadPrefetchConfig } from '../jsonLoader';\nimport { generateFontCSS, generateFontPreloadTags, loadProjectConfig } from '../../shared/fontLoader';\nimport { colorService } from '../services/ColorService';\nimport { generateThemeColorVariablesCSS, generateVariablesCSS } from '../cssGenerator';\nimport { variableService } from '../services/VariableService';\nimport { generateUtilityCSS, extractUtilityClassesFromHTML, generateAllInteractiveCSS } from '../../shared/cssGeneration';\nimport { printMissingStyleWarnings } from '../validateStyleCoverage';\nimport { formHandlerScript, needsFormHandler } from '../../client/scripts/formHandler';\nimport { menoFilterScript, needsMenoFilter } from '../../client/meno-filter/script.generated';\nimport { generateAllInlineDataScripts, prepareClientData, type ClientDataCollection } from './clientDataInjector';\nimport { mergeLibraries, generateLibraryTags, collectComponentLibraries, filterLibrariesByContext } from '../../shared/libraryLoader';\nimport { escapeHtml } from './attributeBuilder';\nimport { renderPageSSR, type PreloadImage } from './ssrRenderer';\nimport type { CMSContext } from './cmsSSRProcessor';\nimport { resolveProjectPath } from '../projectContext';\nimport { readTextFile } from '../runtime/fs';\n\n/**\n * Generate image preload link tags for high-priority images\n * Uses imagesrcset and imagesizes for responsive image preloading\n */\nfunction generateImagePreloadTags(preloadImages: PreloadImage[]): string {\n if (preloadImages.length === 0) return '';\n\n return preloadImages\n .map(img => `<link rel=\"preload\" as=\"image\" type=\"${img.type}\" imagesrcset=\"${escapeHtml(img.srcset)}\" imagesizes=\"${escapeHtml(img.sizes)}\" fetchpriority=\"high\">`)\n .join('\\n ');\n}\n\n/**\n * Minify CSS code using regex-based minification\n * Removes comments, unnecessary whitespace, and optimizes values\n */\nfunction minifyCSS(code: string): string {\n if (!code.trim()) return code;\n\n return code\n // Remove CSS comments\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n // Remove whitespace around special characters\n .replace(/\\s*([{};:,>~+])\\s*/g, '$1')\n // Collapse multiple spaces/newlines into single space\n .replace(/\\s+/g, ' ')\n // Remove space after opening brace\n .replace(/\\{\\s+/g, '{')\n // Remove space before closing brace\n .replace(/\\s+\\}/g, '}')\n // Remove trailing semicolons before closing braces\n .replace(/;}/g, '}')\n // Remove leading/trailing whitespace\n .trim();\n}\n\n/**\n * Result of SSR HTML generation with separate JS for CSP compliance\n */\nexport interface SSRHTMLResult {\n /** Complete HTML document */\n html: string;\n /** JavaScript code to be written to external file (for CSP compliance) */\n javascript: string | null;\n}\n\n/**\n * Options for SSR HTML generation\n */\nexport interface GenerateSSRHTMLOptions {\n /** Page data to render */\n pageData: JSONPage;\n /** Global component definitions */\n globalComponents?: Record<string, ComponentDefinition>;\n /** URL path for the page */\n pagePath?: string;\n /** Base URL for assets */\n baseUrl?: string;\n /** Use built bundle (production) vs dev server */\n useBuiltBundle?: boolean;\n /** Locale for i18n */\n locale?: string;\n /** Slug mappings for locale switching */\n slugMappings?: SlugMap[];\n /** CMS context for template rendering */\n cmsContext?: CMSContext;\n /** CMS service for CMSList queries */\n cmsService?: CMSService;\n /** When true, draft items are filtered out from CMS lists */\n isProductionBuild?: boolean;\n /**\n * Path to external scripts file (for CSP compliance).\n * When provided, JS is NOT inlined but referenced via this path.\n * Example: \"/_scripts/abc123.js\"\n */\n externalScriptPath?: string;\n /**\n * CMS template path for client-side hydration (dev mode only).\n * When provided, serializes CMS context to window.__MENO_CMS__ so the\n * client Router can load the template instead of the CMS URL.\n * Example: \"/templates/posts\"\n */\n cmsTemplatePath?: string;\n /**\n * Page-level library configuration (merged with global libraries)\n */\n pageLibraries?: PageLibrariesConfig;\n /**\n * Client-side CMS data for collections with clientData enabled.\n * Used for injecting inline JSON data for MenoFilter.\n */\n clientDataCollections?: Map<string, ClientDataCollection>;\n /**\n * Inject live reload script for on-demand SSR preview mode.\n * When true, adds a WebSocket client that reloads the page on HMR messages.\n */\n injectLiveReload?: boolean;\n /** Whether this is the visual editor (studio). Affects library filtering. */\n isEditor?: boolean;\n /** Actual bound server port for live reload WS (connects directly to SSR server) */\n serverPort?: number;\n}\n\n/**\n * Generate complete HTML document with SSR content (legacy positional args)\n */\nexport async function generateSSRHTML(\n pageData: JSONPage,\n globalComponents?: Record<string, ComponentDefinition>,\n pagePath?: string,\n baseUrl?: string,\n useBuiltBundle?: boolean,\n locale?: string,\n slugMappings?: SlugMap[],\n cmsContext?: CMSContext,\n cmsService?: CMSService,\n externalScriptPath?: string\n): Promise<string>;\n\n/**\n * Generate complete HTML document with SSR content (options object, returns separate JS for CSP)\n */\nexport async function generateSSRHTML(\n options: GenerateSSRHTMLOptions & { returnSeparateJS: true }\n): Promise<SSRHTMLResult>;\n\n/**\n * Generate complete HTML document with SSR content (options object)\n */\nexport async function generateSSRHTML(\n options: GenerateSSRHTMLOptions & { returnSeparateJS?: false }\n): Promise<string>;\n\n/**\n * Generate complete HTML document with SSR content\n */\nexport async function generateSSRHTML(\n pageDataOrOptions: JSONPage | (GenerateSSRHTMLOptions & { returnSeparateJS?: boolean }),\n globalComponents: Record<string, ComponentDefinition> = {},\n pagePath: string = '/',\n baseUrl: string = '',\n useBuiltBundle: boolean = false,\n locale?: string,\n slugMappings?: SlugMap[],\n cmsContext?: CMSContext,\n cmsService?: CMSService,\n externalScriptPath?: string\n): Promise<string | SSRHTMLResult> {\n // Handle options object vs legacy positional args\n let options: GenerateSSRHTMLOptions & { returnSeparateJS?: boolean };\n\n if ('pageData' in pageDataOrOptions) {\n options = pageDataOrOptions;\n } else {\n options = {\n pageData: pageDataOrOptions,\n globalComponents,\n pagePath,\n baseUrl,\n useBuiltBundle,\n locale,\n slugMappings,\n cmsContext,\n cmsService,\n externalScriptPath,\n };\n }\n\n const {\n pageData,\n globalComponents: components = {},\n pagePath: path = '/',\n baseUrl: base = '',\n useBuiltBundle: useBundled = false,\n locale: loc,\n slugMappings: slugs,\n cmsContext: cms,\n cmsService: cmsServ,\n externalScriptPath: extScriptPath,\n cmsTemplatePath,\n returnSeparateJS = false,\n pageLibraries,\n clientDataCollections,\n injectLiveReload = false,\n isEditor = false,\n isProductionBuild = false,\n serverPort,\n } = options;\n const rendered = await renderPageSSR(pageData, components, path, base, loc, undefined, slugs, cms, cmsServ, isProductionBuild);\n\n // Auto-inject data for nested collections (detected during SSR)\n // This enables client-side hydration for nested cms-list placeholders\n let finalClientDataCollections = clientDataCollections;\n if (rendered.neededCollections.size > 0 && cmsServ) {\n // Create a mutable copy if we need to add collections\n finalClientDataCollections = clientDataCollections\n ? new Map(clientDataCollections)\n : new Map();\n\n for (const collectionId of rendered.neededCollections) {\n // Skip if already provided\n if (finalClientDataCollections.has(collectionId)) continue;\n\n // Get schema to check if clientData is enabled\n const schema = cmsServ.getSchema(collectionId);\n if (!schema?.clientData?.enabled) {\n console.warn(\n `[SSR] Nested collection \"${collectionId}\" needs clientData.enabled for client-side hydration`\n );\n continue;\n }\n\n // Get items and prepare client data (force inline for nested collections)\n const items = await cmsServ.queryItems({\n collection: collectionId,\n excludeDraftLocale: loc,\n });\n const clientData = prepareClientData(collectionId, items, {\n ...schema.clientData,\n strategy: 'inline', // Force inline for nested collections\n });\n\n if (clientData) {\n finalClientDataCollections.set(collectionId, clientData);\n }\n }\n }\n\n // Load and merge external library configuration\n // Merge order: global \u2192 component \u2192 page (page can \"replace\" global+component, or \"extend\" all)\n await configService.load();\n const globalLibraries = configService.getLibraries() || { js: [], css: [] };\n const componentLibraries = collectComponentLibraries(components, pageData.components || {});\n // Merge global + component first (component libraries always extend)\n const globalPlusComponent = mergeLibraries(globalLibraries, componentLibraries) || { js: [], css: [] };\n // Then merge with page libraries (page can replace or extend)\n const mergedRaw = mergeLibraries(globalPlusComponent, pageLibraries) || { js: [], css: [] };\n // Deduplicate by URL so the same library isn't loaded twice\n const seenJS = new Set<string>();\n const seenCSS = new Set<string>();\n const mergedLibraries = {\n js: (mergedRaw.js || []).filter(lib => {\n if (seenJS.has(lib.url)) return false;\n seenJS.add(lib.url);\n return true;\n }),\n css: (mergedRaw.css || []).filter(lib => {\n if (seenCSS.has(lib.url)) return false;\n seenCSS.add(lib.url);\n return true;\n }),\n };\n const libraryContext = isEditor ? 'editor' : (useBundled && !injectLiveReload ? 'build' : 'preview');\n const filteredLibraries = filterLibrariesByContext(mergedLibraries, libraryContext);\n\n // Cache-bust local library URLs in dev/preview to avoid stale browser cache\n const devMode = !useBundled || injectLiveReload;\n const bustCache = devMode ? `?v=${Date.now()}` : '';\n const finalLibraries = bustCache ? {\n js: (filteredLibraries.js || []).map(lib =>\n lib.url.startsWith('/') ? { ...lib, url: lib.url + bustCache } : lib\n ),\n css: (filteredLibraries.css || []).map(lib =>\n lib.url.startsWith('/') ? { ...lib, url: lib.url + bustCache } : lib\n ),\n } : filteredLibraries;\n\n // Read local CSS files for inline embedding\n const inlineContents = new Map<string, string>();\n for (const css of finalLibraries.css || []) {\n // Inline by default for local files, unless explicitly set to false\n const shouldInline = css.inline !== false && css.url.startsWith('/');\n if (shouldInline) {\n try {\n const cleanUrl = css.url.split('?')[0]; // Strip cache-bust query param\n const filePath = resolveProjectPath(cleanUrl.slice(1));\n const content = await readTextFile(filePath);\n inlineContents.set(css.url, content);\n } catch {\n // File not found \u2014 fall back to <link> tag\n }\n }\n }\n\n const libraryTags = generateLibraryTags(finalLibraries, inlineContents);\n\n // Use built bundle in production, dev server in development\n const clientScript = useBundled\n ? '' // No client router in static build (true static HTML)\n : '<script type=\"module\" src=\"/client-router.tsx\"></script>'; // Dev server (development)\n\n // Collect all JavaScript (component JS + form handler + meno filter if needed)\n const needsForm = needsFormHandler(rendered.html);\n // Include MenoFilter if: inline clientData exists OR page has cms-list nodes (for static strategy)\n const needsFilter = (finalClientDataCollections && finalClientDataCollections.size > 0) || needsMenoFilter(rendered.html);\n const allJavaScript = [\n rendered.javascript || '',\n needsForm ? formHandlerScript : '',\n needsFilter ? menoFilterScript : ''\n ].filter(Boolean).join('\\n\\n');\n\n // Determine script output based on mode\n let componentScript = '';\n let externalJavaScript: string | null = null;\n\n if (allJavaScript) {\n if (extScriptPath) {\n // CSP-compliant: reference external script file (defer to avoid render-blocking)\n componentScript = `\\n <script src=\"${extScriptPath}\" defer></script>`;\n externalJavaScript = allJavaScript;\n } else if (returnSeparateJS) {\n // Return JS separately (for build-static to write to file)\n externalJavaScript = allJavaScript;\n } else {\n // Legacy inline mode (dev server)\n // Escape </script> sequences to prevent premature script tag closure\n const escapedJavaScript = allJavaScript.replace(/<\\/script>/gi, '<\\\\/script>');\n componentScript = `\\n <script>\\n${escapedJavaScript}\\n </script>`;\n }\n }\n\n // Ensure project config is loaded (reloads from disk if cache was cleared)\n await loadProjectConfig();\n const fontCSS = generateFontCSS();\n const fontPreloadTags = generateFontPreloadTags();\n\n // Load icons config for favicon and apple touch icon\n const iconsConfig = await loadIconsConfig();\n\n // Load and generate theme color variables CSS\n const themeConfig = await colorService.loadThemeConfig();\n const themeColorVariablesCSS = generateThemeColorVariablesCSS(themeConfig);\n\n // Include component CSS (no longer generating inline style classes)\n const componentCSS = rendered.componentCSS || '';\n\n // Extract and generate utility CSS from rendered HTML\n const usedUtilityClasses = extractUtilityClassesFromHTML(rendered.html);\n const breakpointConfig = await loadBreakpointConfig();\n const responsiveScalesConfig = await loadResponsiveScalesConfig();\n\n // Load and generate CSS custom properties from variables.json\n const variablesConfig = await variableService.loadConfig();\n const variablesCSS = generateVariablesCSS(variablesConfig, breakpointConfig, responsiveScalesConfig);\n const utilityCSS = generateUtilityCSS(usedUtilityClasses, breakpointConfig, responsiveScalesConfig);\n\n // Generate interactive styles CSS from map collected during render\n const interactiveCSS = rendered.interactiveStylesMap.size > 0\n ? generateAllInteractiveCSS(rendered.interactiveStylesMap, breakpointConfig)\n : '';\n\n // Print warnings for any unmapped styles found during build\n printMissingStyleWarnings(false);\n\n // Build base CSS (reset styles)\n const baseCSS = `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;\n}\nbutton {\n background: none;\n border: none;\n padding: 0;\n font: inherit;\n cursor: pointer;\n outline: inherit;\n}\nimg {\n display: block;\n width: 100%;\n height: 100%;\n}\npicture {\n display: block;\n}\n.olink {\n text-decoration: none;\n display: block;\n}\n.oem {\n display: inline-block;\n}`;\n\n // Combine all CSS\n const combinedCSS = [\n fontCSS,\n themeColorVariablesCSS,\n variablesCSS,\n baseCSS,\n componentCSS,\n utilityCSS,\n interactiveCSS\n ].filter(Boolean).join('\\n');\n\n // Minify CSS in production mode\n const finalCSS = useBundled ? minifyCSS(combinedCSS) : combinedCSS;\n\n // Load prefetch config for client-side prefetching\n const prefetchConfig = await loadPrefetchConfig();\n // Only include non-default values to minimize payload\n const menoConfig = prefetchConfig.enabled ? { prefetch: prefetchConfig } : {};\n // Config script - inline for dev, include in external JS for static build\n const hasConfig = Object.keys(menoConfig).length > 0;\n const configInlineScript = hasConfig && !extScriptPath && !returnSeparateJS\n ? `<script>window.__MENO_CONFIG__=${JSON.stringify(menoConfig)}</script>\\n `\n : '';\n // Add config to external JS if using external scripts\n if (hasConfig && externalJavaScript !== null) {\n externalJavaScript = `window.__MENO_CONFIG__=${JSON.stringify(menoConfig)};\\n\\n` + externalJavaScript;\n }\n\n // CMS context script - needed when a client-side Router is present (dev mode or studio preview)\n // Production builds are pure HTML with no client routing, so excluded\n const cmsInlineScript = cmsTemplatePath && cms && (!useBundled || injectLiveReload)\n ? `<script>window.__MENO_CMS__=${JSON.stringify({ item: cms.cms, templatePath: cmsTemplatePath })}</script>\\n `\n : '';\n\n // Client data scripts - inline JSON for MenoFilter (production builds only)\n const clientDataScripts = finalClientDataCollections && finalClientDataCollections.size > 0\n ? generateAllInlineDataScripts(finalClientDataCollections) + '\\n '\n : '';\n\n // Generate favicon and apple touch icon link tags\n const faviconTag = iconsConfig.favicon\n ? `<link rel=\"icon\" href=\"${escapeHtml(iconsConfig.favicon)}\" />`\n : '';\n const appleTouchIconTag = iconsConfig.appleTouchIcon\n ? `<link rel=\"apple-touch-icon\" href=\"${escapeHtml(iconsConfig.appleTouchIcon)}\" />`\n : '';\n const iconTags = [faviconTag, appleTouchIconTag].filter(Boolean).join('\\n ');\n\n // Script preload tag - eliminates critical request chain by discovering script early\n const scriptPreloadTag = extScriptPath\n ? `<link rel=\"preload\" href=\"${extScriptPath}\" as=\"script\">`\n : '';\n\n // Image preload tags for high-priority images (LCP optimization)\n const imagePreloadTags = generateImagePreloadTags(rendered.preloadImages);\n\n // Live reload script for on-demand SSR preview mode (in-place DOM update, no white flash)\n const wsUrl = serverPort\n ? `'ws://localhost:${serverPort}/hmr'`\n : `location.origin.replace('http','ws')+'/hmr'`;\n const liveReloadScript = injectLiveReload\n ? `<script>(function(){var ws,timer,gen=0;function connect(){ws=new WebSocket(${wsUrl});ws.onmessage=function(e){var d=JSON.parse(e.data);if(d.type==='hmr:libraries-update'){location.reload()}else if(d.type==='hmr:update'||d.type==='hmr:cms-update'||d.type==='hmr:colors-update'||d.type==='hmr:variables-update')hotReload()};ws.onclose=function(){clearTimeout(timer);timer=setTimeout(connect,1000)}}function hotReload(){var g=++gen;var sx=window.scrollX,sy=window.scrollY;fetch(location.href,{cache:'no-store'}).then(function(r){return r.text()}).then(function(html){if(g!==gen)return;var p=new DOMParser();var d=p.parseFromString(html,'text/html');var or=document.getElementById('root');var nr=d.getElementById('root');if(or&&nr)or.innerHTML=nr.innerHTML;var os=document.getElementById('meno-styles');var ns=d.getElementById('meno-styles');if(os&&ns){os.parentNode.replaceChild(ns.cloneNode(true),os)}var nh=d.documentElement;if(nh){document.documentElement.setAttribute('lang',nh.getAttribute('lang')||'en');document.documentElement.setAttribute('theme',nh.getAttribute('theme')||'light')}document.querySelectorAll('script[id^=\"meno-cms-\"]').forEach(function(s){s.remove()});d.querySelectorAll('script[id^=\"meno-cms-\"]').forEach(function(s){var c=document.createElement('script');c.type=s.type;c.id=s.id;c.textContent=s.textContent;document.head.appendChild(c)});window.__menoHotReload=true;document.querySelectorAll('body > script[src^=\"/libraries/\"]').forEach(function(o){o.remove()});d.querySelectorAll('body > script[src^=\"/libraries/\"]').forEach(function(n){var ls=document.createElement('script');ls.src=n.getAttribute('src')+(n.getAttribute('src').indexOf('?')>-1?'&':'?')+'_r='+Date.now();document.body.appendChild(ls)});var oscr=document.querySelector('script[src^=\"/_scripts/\"]');var nscr=d.querySelector('script[src^=\"/_scripts/\"]');if(nscr){var src=nscr.getAttribute('src');if(oscr)oscr.remove();var s=document.createElement('script');s.src=src+(src.indexOf('?')>-1?'&':'?')+'_r='+Date.now();s.onload=function(){document.dispatchEvent(new Event('DOMContentLoaded'));window.scrollTo(sx,sy)};s.onerror=function(){window.scrollTo(sx,sy)};document.body.appendChild(s)}else{if(oscr)oscr.remove();document.dispatchEvent(new Event('DOMContentLoaded'));window.scrollTo(sx,sy)}}).catch(function(){location.reload()})}connect()})()</script>`\n : '';\n\n // Scroll position handlers for preview mode iframe switching\n const scrollHandlerScript = injectLiveReload\n ? `<script>(function(){window.addEventListener('message',function(e){if(e.data.type==='GET_SCROLL_POSITION'){window.parent.postMessage({type:'SCROLL_POSITION_RESPONSE',scrollX:window.scrollX,scrollY:window.scrollY},'*')}else if(e.data.type==='SET_SCROLL_POSITION'){window.scrollTo(e.data.scrollX,e.data.scrollY)}})})()</script>`\n : '';\n\n // In production, output minified CSS on single line; in dev, preserve formatting\n const styleContent = useBundled\n ? finalCSS\n : `\\n ${combinedCSS.split('\\n').join('\\n ')}\\n `;\n\n const htmlDocument = `<!DOCTYPE html>\n<html lang=\"${rendered.locale}\" theme=\"${themeConfig.default}\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${iconTags ? iconTags + '\\n ' : ''}${scriptPreloadTag ? scriptPreloadTag + '\\n ' : ''}${imagePreloadTags ? imagePreloadTags + '\\n ' : ''}${fontPreloadTags ? fontPreloadTags + '\\n ' : ''}${libraryTags.headCSS ? libraryTags.headCSS + '\\n ' : ''}${libraryTags.headJS ? libraryTags.headJS + '\\n ' : ''}${rendered.meta}\n ${configInlineScript}${cmsInlineScript}${clientDataScripts}<style id=\"meno-styles\">${styleContent}</style>\n</head>\n<body>\n <div id=\"root\">\n ${rendered.html}\n </div>\n ${clientScript}${componentScript}${libraryTags.bodyEndJS ? '\\n ' + libraryTags.bodyEndJS : ''}${liveReloadScript ? '\\n ' + liveReloadScript : ''}${scrollHandlerScript ? '\\n ' + scrollHandlerScript : ''}\n</body>\n</html>`;\n\n // Return based on mode\n if (returnSeparateJS) {\n return {\n html: htmlDocument,\n javascript: externalJavaScript\n };\n }\n\n return htmlDocument;\n}\n", "/**\n * File System CMS Provider\n * Implements CMSProvider for loading CMS data from the file system\n */\n\nimport { existsSync, readdirSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport type { CMSProvider, CMSSchemaInfo } from '../../shared/interfaces/contentProvider';\nimport type { CMSSchema, CMSItem } from '../../shared/types';\nimport { validateCMSItem } from '../../shared/validation/validators';\nimport { isSafePathSegment, isValidIdentifier } from '../../shared/pathSecurity';\nimport { readJsonFile, fileExists } from '../runtime';\n\n/**\n * Load JSON file content from disk\n * Logs a warning if JSON parsing fails (helps debug malformed files)\n */\nasync function loadJSONFile(filePath: string): Promise<unknown | null> {\n try {\n if (await fileExists(filePath)) {\n return await readJsonFile(filePath);\n }\n return null;\n } catch (error) {\n console.warn(`[CMS] Failed to parse JSON at ${filePath}:`, error instanceof Error ? error.message : error);\n return null;\n }\n}\n\n/**\n * Normalize a raw CMS item by adding _slug and _filename fields\n */\nfunction normalizeItem(content: unknown, filename: string): CMSItem {\n return {\n ...content as CMSItem,\n _slug: filename,\n _filename: filename,\n };\n}\n\n/**\n * FileSystemCMSProvider\n * Loads CMS schemas from template files in root templates/ dir and CMS items from cms/<collection>/<slug>.json\n */\nexport class FileSystemCMSProvider implements CMSProvider {\n private schemaCache: Map<string, CMSSchemaInfo> | null = null;\n\n constructor(\n private templatesDir: string, // e.g., './templates' - CMS template pages\n private cmsDir: string // e.g., './cms' - items stored here\n ) {}\n\n /**\n * Validate collection name to prevent path traversal attacks\n * @throws Error if collection name is invalid\n */\n private validateCollection(collection: string): void {\n if (!isValidIdentifier(collection)) {\n throw new Error(`Invalid collection name: \"${collection}\". Collection names must contain only letters, numbers, hyphens, and underscores.`);\n }\n }\n\n /**\n * Validate filename to prevent path traversal attacks\n * @throws Error if filename is invalid\n */\n private validateFilename(filename: string): void {\n if (!isSafePathSegment(filename)) {\n throw new Error(`Invalid filename: \"${filename}\". Filenames cannot contain path separators or traversal sequences.`);\n }\n }\n\n /**\n * Load all CMS schemas from page files with source: 'cms' in templates/\n */\n async getAllSchemas(): Promise<Map<string, CMSSchemaInfo>> {\n // Return cached if available\n if (this.schemaCache) {\n return this.schemaCache;\n }\n\n const schemas = new Map<string, CMSSchemaInfo>();\n\n if (!existsSync(this.templatesDir)) {\n return schemas;\n }\n\n const files = readdirSync(this.templatesDir);\n const jsonFiles = files.filter(f => f.endsWith('.json'));\n\n const results = await Promise.all(\n jsonFiles.map(async file => {\n const filePath = join(this.templatesDir, file);\n const content = await loadJSONFile(filePath);\n return { filePath, content };\n })\n );\n\n for (const { filePath, content } of results) {\n if (\n content &&\n typeof content === 'object' &&\n 'meta' in content &&\n typeof (content as Record<string, unknown>).meta === 'object'\n ) {\n const meta = (content as Record<string, unknown>).meta as Record<string, unknown>;\n\n if (meta.source === 'cms' && meta.cms) {\n const schema = meta.cms as CMSSchema;\n schemas.set(schema.id, {\n schema,\n pagePath: filePath,\n });\n }\n }\n }\n\n this.schemaCache = schemas;\n return schemas;\n }\n\n /**\n * Load all items for a collection\n */\n async getItems(collection: string): Promise<CMSItem[]> {\n this.validateCollection(collection);\n const collectionDir = join(this.cmsDir, collection);\n\n if (!existsSync(collectionDir)) {\n return [];\n }\n\n const files = readdirSync(collectionDir);\n const jsonFiles = files.filter(f => f.endsWith('.json'));\n\n const results = await Promise.all(\n jsonFiles.map(async file => {\n const filePath = join(collectionDir, file);\n const content = await loadJSONFile(filePath);\n return { file, filePath, content };\n })\n );\n\n const items: CMSItem[] = [];\n for (const { file, filePath, content } of results) {\n if (content && typeof content === 'object') {\n const filename = file.replace('.json', '');\n const item = normalizeItem(content, filename);\n\n const validation = validateCMSItem(item);\n if (validation.valid) {\n items.push(validation.data);\n } else {\n console.warn(`Invalid CMS item at ${filePath}:`, validation.errors);\n }\n }\n }\n\n return items;\n }\n\n /**\n * Get single item by slug (backward compat - slug is actually filename)\n * @deprecated Use getItemByFilename instead\n */\n async getItemBySlug(collection: string, slug: string): Promise<CMSItem | null> {\n return this.getItemByFilename(collection, slug);\n }\n\n /**\n * Get single item by filename\n */\n async getItemByFilename(collection: string, filename: string): Promise<CMSItem | null> {\n this.validateCollection(collection);\n this.validateFilename(filename);\n const filePath = join(this.cmsDir, collection, `${filename}.json`);\n const content = await loadJSONFile(filePath);\n\n if (!content || typeof content !== 'object') {\n return null;\n }\n\n const item = normalizeItem(content, filename);\n const validation = validateCMSItem(item);\n\n if (validation.valid) {\n return validation.data;\n }\n\n console.warn(`Invalid CMS item at ${filePath}:`, validation.errors);\n return null;\n }\n\n /**\n * Get single item by ID\n */\n async getItemById(collection: string, id: string): Promise<CMSItem | null> {\n const items = await this.getItems(collection);\n return items.find(item => item._id === id) || null;\n }\n\n /**\n * Save item to file system\n * Uses _filename for file path (stable, doesn't change when slug changes)\n */\n async saveItem(collection: string, item: CMSItem): Promise<void> {\n this.validateCollection(collection);\n const { writeFile } = await import('fs/promises');\n\n // Get schema\n const schemas = await this.getAllSchemas();\n const schemaInfo = schemas.get(collection);\n\n if (!schemaInfo) {\n throw new Error(`Unknown collection: ${collection}`);\n }\n\n // Use _filename for file path (new behavior)\n // Falls back to slugField for backward compatibility with items without _filename\n let filename: string;\n\n if (item._filename) {\n filename = item._filename;\n } else {\n // Legacy fallback: use slug field value (may break for i18n slugs)\n const slugField = schemaInfo.schema.slugField;\n const slugValue = item[slugField];\n filename = typeof slugValue === 'string' ? slugValue : String(slugValue);\n }\n\n if (!filename || filename === '[object Object]') {\n throw new Error('Missing _filename field. Items must have _filename set on creation.');\n }\n\n // Validate filename to prevent path traversal\n this.validateFilename(filename);\n\n // Ensure collection directory exists\n const collectionDir = join(this.cmsDir, collection);\n if (!existsSync(collectionDir)) {\n mkdirSync(collectionDir, { recursive: true });\n }\n\n // Remove internal _slug field before saving (keep _filename in file for persistence)\n const { _slug, ...itemData } = item;\n\n const filePath = join(collectionDir, `${filename}.json`);\n await writeFile(filePath, JSON.stringify(itemData, null, 2), 'utf-8');\n }\n\n /**\n * Delete item by filename (or slug for backward compat)\n */\n async deleteItem(collection: string, filename: string): Promise<void> {\n this.validateCollection(collection);\n this.validateFilename(filename);\n const { unlink } = await import('fs/promises');\n const filePath = join(this.cmsDir, collection, `${filename}.json`);\n\n if (existsSync(filePath)) {\n await unlink(filePath);\n }\n }\n\n /**\n * Clear schema cache (useful when pages are modified)\n */\n clearSchemaCache(): void {\n this.schemaCache = null;\n }\n\n /**\n * Save a new collection schema by creating a page file in templates/\n */\n async saveSchema(collectionId: string, pageData: unknown): Promise<void> {\n if (!isValidIdentifier(collectionId)) {\n throw new Error(`Invalid collection ID: \"${collectionId}\". Collection IDs must contain only letters, numbers, hyphens, and underscores.`);\n }\n const { writeFile, mkdir } = await import('fs/promises');\n\n // Ensure templates directory exists\n if (!existsSync(this.templatesDir)) {\n await mkdir(this.templatesDir, { recursive: true });\n }\n\n // Create page file path in templates/ subdirectory\n const pageFilePath = join(this.templatesDir, `${collectionId}.json`);\n\n // Check if file already exists\n if (existsSync(pageFilePath)) {\n throw new Error(`Page file already exists: templates/${collectionId}.json`);\n }\n\n // Write the page file\n await writeFile(pageFilePath, JSON.stringify(pageData, null, 2), 'utf-8');\n\n // Create the CMS collection directory\n const collectionDir = join(this.cmsDir, collectionId);\n if (!existsSync(collectionDir)) {\n await mkdir(collectionDir, { recursive: true });\n }\n\n // Clear the schema cache so the new collection is detected\n this.clearSchemaCache();\n }\n\n /**\n * Update an existing collection schema\n * Preserves the root component tree, only updates meta.cms\n */\n async updateSchema(collectionId: string, updates: Partial<CMSSchema>): Promise<void> {\n if (!isValidIdentifier(collectionId)) {\n throw new Error(`Invalid collection ID: \"${collectionId}\". Collection IDs must contain only letters, numbers, hyphens, and underscores.`);\n }\n const { readFile, writeFile } = await import('fs/promises');\n\n const pageFilePath = join(this.templatesDir, `${collectionId}.json`);\n\n if (!existsSync(pageFilePath)) {\n throw new Error(`Collection not found: ${collectionId}`);\n }\n\n // Read existing page data\n const content = await readFile(pageFilePath, 'utf-8');\n const pageData = JSON.parse(content) as {\n meta: { cms: CMSSchema; [key: string]: unknown };\n [key: string]: unknown;\n };\n\n // Update only the cms schema in meta, preserving id\n pageData.meta.cms = {\n ...pageData.meta.cms,\n ...updates,\n id: collectionId, // ID cannot be changed\n };\n\n await writeFile(pageFilePath, JSON.stringify(pageData, null, 2), 'utf-8');\n this.clearSchemaCache();\n }\n}\n", "import { existsSync } from 'fs';\nimport { rename } from 'fs/promises';\nimport { join } from 'path';\nimport { projectPaths } from './projectContext';\n\n/**\n * Auto-migrate CMS templates from pages/templates/ to root templates/\n * Only runs if pages/templates/ exists and root templates/ does not\n */\nexport async function migrateTemplatesDirectory(): Promise<void> {\n const oldDir = join(projectPaths.pages(), 'templates');\n const newDir = projectPaths.templates();\n\n // Nothing to migrate\n if (!existsSync(oldDir)) return;\n\n // Don't clobber existing root templates/\n if (existsSync(newDir)) return;\n\n await rename(oldDir, newDir);\n console.log('Migrated CMS templates: pages/templates/ \u2192 templates/');\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["path", "path", "validateJS", "path", "templateCtx", "nodeAttributes", "utilityClasses", "elementClass", "attrClassName", "attrs", "classAttr", "escapeAttr", "path", "existsSync", "readdirSync", "join", "loadJSONFile", "existsSync", "readdirSync", "join", "writeFile", "existsSync", "join", "join", "existsSync"]
7
7
  }