@artinstack/migrator 0.1.14 → 0.1.16

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/parsers/wordpress/builders/flatten.ts"],"sourcesContent":["import { normalizeAssetUrl } from \"../../../lib/media-urls.js\";\nimport type {\n BuilderIconImageRule,\n BuilderLinkRule,\n BuilderPlaceholderRule,\n BuilderTextRule,\n BuilderThemeConfig,\n BuilderUrlRule,\n BuilderWrapperRule,\n FractionalLayoutMap,\n ExtendedPrefixedLayoutMap,\n PrefixedLayoutMap,\n StructuralLayoutMap,\n TextHtmlTag,\n BuilderHtmlTag,\n} from \"./registry.js\";\nimport {\n WORDPRESS_BUILDER_REGISTRY,\n WORDPRESS_WIDGET_REGISTRY,\n WP_WIDGET_PLACEHOLDER,\n type WordPressWidgetRegistry,\n} from \"./registry.js\";\n\nexport interface FlattenWordPressBuildersOptions {\n registry?: BuilderThemeConfig[];\n widgetRegistry?: WordPressWidgetRegistry;\n /** Serialized `_tatsu_page_content` JSON — fills blank section/column attrs (OSS-28). */\n tatsuPageContent?: string;\n}\n\nexport interface TatsuPageContext {\n modulesByKey: Map<string, Record<string, unknown>>;\n}\n\nexport interface FlattenWordPressBuildersResult {\n html: string;\n detectedThemes: string[];\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/** Read a quoted shortcode attribute value (supports multiline). */\nexport function extractQuotedParam(params: string, name: string): string | undefined {\n const pattern = new RegExp(`\\\\b${escapeRegExp(name)}\\\\s*=\\\\s*`, \"i\");\n const match = pattern.exec(params);\n if (!match) return undefined;\n\n let index = match.index + match[0].length;\n while (index < params.length && /\\s/.test(params[index]!)) index += 1;\n\n if (params.slice(index, index + 6) === \"&quot;\") {\n index += 6;\n let value = \"\";\n while (index < params.length) {\n if (params.slice(index, index + 6) === \"&quot;\") break;\n value += params[index]!;\n index += 1;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n }\n\n const quote = params[index];\n if (quote !== '\"' && quote !== \"'\") return undefined;\n index += 1;\n\n let value = \"\";\n while (index < params.length) {\n const char = params[index]!;\n if (char === \"\\\\\" && index + 1 < params.length) {\n value += params[index + 1];\n index += 2;\n continue;\n }\n if (char === quote) break;\n value += char;\n index += 1;\n }\n\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction escapeLayoutAttr(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/</g, \"&lt;\");\n}\n\n/** Parse `width=\"1/2\"` / `columns=\"1/3+1/3+1/3\"` style strings → percentage or column count. */\nexport function parseFractionWidth(fraction: string | undefined): string | undefined {\n if (!fraction?.trim()) return undefined;\n const trimmed = fraction.trim();\n const match = trimmed.match(/^(\\d+)\\s*\\/\\s*(\\d+)$/);\n if (!match) return undefined;\n const numerator = Number(match[1]);\n const denominator = Number(match[2]);\n if (!Number.isFinite(numerator) || !Number.isFinite(denominator) || denominator <= 0) {\n return undefined;\n }\n const percent = (numerator / denominator) * 100;\n const rounded = Math.round(percent * 100) / 100;\n return `${rounded % 1 === 0 ? rounded.toFixed(0) : rounded}%`;\n}\n\n/** Parse row `layout=\"1/2+1/2\"` style strings → column count. */\nexport function parseRowLayoutCols(layout: string | undefined): number | undefined {\n if (!layout?.trim()) return undefined;\n const parts = layout.split(\"+\").map((part) => part.trim()).filter(Boolean);\n return parts.length > 1 ? parts.length : undefined;\n}\n\nlet activeTatsuContext: TatsuPageContext | undefined;\n\nfunction isBlankShortcodeAttr(value: string | undefined): boolean {\n return !value?.trim();\n}\n\nfunction resolveTatsuJsonScalar(value: unknown): string | undefined {\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n return trimmed || undefined;\n }\n if (typeof value === \"number\" && Number.isFinite(value)) return String(value);\n if (value && typeof value === \"object\" && \"d\" in value) {\n return resolveTatsuJsonScalar((value as Record<string, unknown>).d);\n }\n return undefined;\n}\n\nfunction normalizeHttpMediaUrl(url: string | undefined): string | undefined {\n if (!url?.trim()) return undefined;\n const trimmed = url.trim();\n if (trimmed.startsWith(\"http\")) return trimmed;\n if (trimmed.startsWith(\"//\")) return `https:${trimmed}`;\n return undefined;\n}\n\ninterface MergedTatsuLayoutAttrs {\n bgImage?: string;\n bgVideoMp4?: string;\n bgVideoWebm?: string;\n overlayColor?: string;\n fullscreen?: boolean;\n builderLayout?: string;\n}\n\nfunction mergeTatsuLayoutAttrs(\n params: string,\n moduleKey: string | undefined,\n context: TatsuPageContext | undefined,\n): MergedTatsuLayoutAttrs {\n const jsonAtts = moduleKey ? context?.modulesByKey.get(moduleKey) : undefined;\n\n const pick = (name: string, jsonName = name): string | undefined => {\n const fromShortcode = extractBareOrQuotedParam(params, name);\n if (!isBlankShortcodeAttr(fromShortcode)) return fromShortcode!.trim();\n return jsonAtts ? resolveTatsuJsonScalar(jsonAtts[jsonName]) : undefined;\n };\n\n const bgVideoMp4 = pick(\"bg_video_mp4_src\");\n const bgVideoWebm = pick(\"bg_video_webm_src\");\n const bgImage = pick(\"bg_image\");\n const overlayColor = pick(\"overlay_color\");\n\n const sectionHeight = pick(\"section_height_type\");\n const fullScreen = pick(\"full_screen\");\n const customHeight = pick(\"custom_height\");\n const fullscreen =\n sectionHeight?.toLowerCase() === \"full_screen\" ||\n fullScreen === \"1\" ||\n (customHeight?.includes(\"100vh\") ?? false);\n\n const builderLayout = jsonAtts ? resolveTatsuJsonScalar(jsonAtts.builderLayout) : undefined;\n\n return { bgImage, bgVideoMp4, bgVideoWebm, overlayColor, fullscreen, builderLayout };\n}\n\nfunction appendSectionHeroAttrs(attrs: string[], merged: MergedTatsuLayoutAttrs, params: string, bgParamName?: string): void {\n const paramName = bgParamName ?? \"bg_image\";\n const bgImage =\n normalizeHttpMediaUrl(merged.bgImage) ??\n normalizeHttpMediaUrl(extractBareOrQuotedParam(params, paramName)) ??\n normalizeHttpMediaUrl(extractQuotedParam(params, paramName));\n if (bgImage) {\n attrs.push(`data-bg-image=\"${escapeLayoutAttr(bgImage)}\"`);\n }\n\n const videoUrl =\n normalizeHttpMediaUrl(merged.bgVideoMp4) ?? normalizeHttpMediaUrl(merged.bgVideoWebm);\n if (videoUrl) {\n attrs.push('data-wp-hero-type=\"video\"');\n attrs.push(`data-video-url=\"${escapeLayoutAttr(videoUrl)}\"`);\n }\n\n if (merged.fullscreen) {\n attrs.push('data-layout-mode=\"fullscreen\"');\n }\n\n if (merged.overlayColor) {\n attrs.push(`data-overlay-color=\"${escapeLayoutAttr(merged.overlayColor)}\"`);\n }\n}\n\n/** Index Tatsu modules by `key` / `id` for shortcode ↔ JSON merge (OSS-28). */\nexport function buildTatsuPageContext(jsonText: string): TatsuPageContext | undefined {\n try {\n const parsed = JSON.parse(jsonText) as unknown;\n const modulesByKey = new Map<string, Record<string, unknown>>();\n walkTatsuModules(parsed, modulesByKey);\n return modulesByKey.size > 0 ? { modulesByKey } : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction walkTatsuModules(node: unknown, index: Map<string, Record<string, unknown>>): void {\n if (!node) return;\n if (Array.isArray(node)) {\n for (const child of node) walkTatsuModules(child, index);\n return;\n }\n if (typeof node !== \"object\") return;\n\n const obj = node as Record<string, unknown>;\n const atts = obj.atts;\n const keyFromAtts =\n atts && typeof atts === \"object\"\n ? resolveTatsuJsonScalar((atts as Record<string, unknown>).key)\n : undefined;\n const keyFromId = typeof obj.id === \"string\" ? obj.id.trim() : undefined;\n const key = keyFromAtts || keyFromId;\n\n if (key && atts && typeof atts === \"object\") {\n index.set(key, atts as Record<string, unknown>);\n }\n\n if (obj.inner) walkTatsuModules(obj.inner, index);\n}\n\nfunction openSectionDiv(params: string, bgParamName?: string): string {\n const attrs = ['data-layout=\"section\"'];\n const moduleKey = extractBareOrQuotedParam(params, \"key\");\n const merged = mergeTatsuLayoutAttrs(params, moduleKey, activeTatsuContext);\n appendSectionHeroAttrs(attrs, merged, params, bgParamName);\n return `<div ${attrs.join(\" \")}>`;\n}\n\nfunction openRowDiv(params: string, colsParamName?: string): string {\n const attrs = ['data-layout=\"row\"'];\n const cols = parseRowLayoutCols(extractQuotedParam(params, colsParamName ?? \"layout\"));\n if (cols) attrs.push(`data-cols=\"${cols}\"`);\n return `<div ${attrs.join(\" \")}>`;\n}\n\nfunction openColumnDiv(params: string, widthParamName?: string): string {\n const attrs = ['data-layout=\"column\"'];\n const width = parseFractionWidth(extractQuotedParam(params, widthParamName ?? \"width\"));\n if (width) attrs.push(`data-col-width=\"${width}\"`);\n return `<div ${attrs.join(\" \")}>`;\n}\n\nfunction applyPrefixedLayoutMap(content: string, map: PrefixedLayoutMap): string {\n let html = content;\n html = html.replace(map.sectionRegex, (_, params: string) => openSectionDiv(params, map.bgParamName));\n html = html.replace(map.sectionCloseRegex, \"</div>\");\n html = html.replace(map.rowRegex, (_, params: string) => openRowDiv(params, map.colsParamName));\n html = html.replace(map.rowCloseRegex, \"</div>\");\n html = html.replace(map.columnRegex, '<div data-layout=\"column\">');\n html = html.replace(map.columnCloseRegex, \"</div>\");\n return html;\n}\n\nfunction applyFractionalLayoutMap(content: string, map: FractionalLayoutMap): string {\n let html = content;\n html = html.replace(map.sectionRegex, (_, params: string) => openSectionDiv(params, map.bgParamName));\n html = html.replace(map.sectionCloseRegex, \"</div>\");\n html = html.replace(map.rowRegex, (_, params: string) => openRowDiv(params));\n html = html.replace(map.rowCloseRegex, \"</div>\");\n\n for (let index = 0; index < map.columnTokens.length; index += 1) {\n const token = map.columnTokens[index]!;\n const width = map.columnWidths[token];\n const openRegex = map.columnOpenRegexes[index]!;\n const closeRegex = map.columnCloseRegexes[index]!;\n html = html.replace(openRegex, () => {\n const attrs = ['data-layout=\"column\"'];\n if (width) attrs.push(`data-col-width=\"${width}\"`);\n return `<div ${attrs.join(\" \")}>`;\n });\n html = html.replace(closeRegex, \"</div>\");\n }\n return html;\n}\n\nfunction applyExtendedPrefixedLayoutMap(content: string, map: ExtendedPrefixedLayoutMap): string {\n let html = content;\n const levels = [...map.levels].sort((left, right) => {\n const leftMax = Math.max(...left.tokens.map((token) => token.length));\n const rightMax = Math.max(...right.tokens.map((token) => token.length));\n return rightMax - leftMax;\n });\n\n for (const level of levels) {\n const tokens = [...level.tokens].sort((left, right) => right.length - left.length);\n for (const token of tokens) {\n const openRegex = new RegExp(`\\\\[${escapeRegExp(token)}\\\\b([^\\\\]]*)\\\\]`, \"gi\");\n const closeRegex = new RegExp(`\\\\[\\\\/${escapeRegExp(token)}\\\\b[^\\\\]]*\\\\]`, \"gi\");\n\n html = html.replace(openRegex, (_, params: string) => {\n switch (level.role) {\n case \"section\":\n return openSectionDiv(params, level.bgParamName);\n case \"row\":\n return openRowDiv(params, level.colsParamName);\n case \"column\":\n return openColumnDiv(params, level.widthParamName);\n }\n });\n html = html.replace(closeRegex, \"</div>\");\n }\n }\n\n return html;\n}\n\n/** Map builder layout shortcodes → editor-neutral `data-layout` HTML. */\nexport function applyStructuralLayoutMap(content: string, map: StructuralLayoutMap): string {\n switch (map.kind) {\n case \"prefixed\":\n return applyPrefixedLayoutMap(content, map);\n case \"fractional\":\n return applyFractionalLayoutMap(content, map);\n case \"extended-prefixed\":\n return applyExtendedPrefixedLayoutMap(content, map);\n }\n}\n\nfunction collectLayoutMaps(theme: BuilderThemeConfig): StructuralLayoutMap[] {\n const maps: StructuralLayoutMap[] = [];\n if (theme.layoutMap) maps.push(theme.layoutMap);\n if (theme.layoutMaps?.length) maps.push(...theme.layoutMaps);\n return maps;\n}\n\nfunction extractShortcodeParam(params: string, names: string[]): string | undefined {\n for (const name of names) {\n const value = extractQuotedParam(params, name);\n if (value) return value;\n }\n return undefined;\n}\n\nfunction escapeHtmlText(text: string): string {\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction textToHtml(text: string, tag: TextHtmlTag): string {\n const paragraphs = text.split(/\\n{2,}/).map((part) => part.trim()).filter(Boolean);\n if (paragraphs.length === 0) return \"\";\n\n return paragraphs\n .map((paragraph) => {\n const inner = escapeHtmlText(paragraph).replace(/\\n/g, \"<br />\");\n return `<${tag}>${inner}</${tag}>`;\n })\n .join(\"\\n\");\n}\n\nfunction emitHtmlTag(tag: BuilderHtmlTag, url: string): string {\n const normalized = normalizeAssetUrl(url) ?? url;\n const escaped = normalized\n .replace(/&/g, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/</g, \"&lt;\");\n\n switch (tag) {\n case \"img\":\n return `<img src=\"${escaped}\" alt=\"\" />`;\n case \"video\":\n return `<video src=\"${escaped}\" controls></video>`;\n case \"iframe\":\n return `<iframe src=\"${escaped}\" loading=\"lazy\"></iframe>`;\n }\n}\n\nfunction convertUrlRule(content: string, rule: BuilderUrlRule): string {\n const prefix = escapeRegExp(rule.shortcodePrefix);\n const pattern = new RegExp(\n `\\\\[${prefix}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${prefix}\\\\b[^\\\\]]*\\\\])?`,\n \"gi\",\n );\n\n return content.replace(pattern, (block, params: string) => {\n const url = extractShortcodeParam(params, rule.urlParams);\n if (!url) return block;\n return emitHtmlTag(rule.tag, url);\n });\n}\n\nfunction convertTextRule(content: string, rule: BuilderTextRule): string {\n const prefix = escapeRegExp(rule.shortcodePrefix);\n const pattern = new RegExp(\n `\\\\[${prefix}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${prefix}\\\\b[^\\\\]]*\\\\])?`,\n \"gis\",\n );\n\n return content.replace(pattern, (block, params: string) => {\n const parts: string[] = [];\n for (const field of rule.fields) {\n const text = extractQuotedParam(params, field.param);\n if (!text) continue;\n const html = textToHtml(text, field.tag);\n if (html) parts.push(html);\n }\n return parts.length > 0 ? parts.join(\"\\n\") : block;\n });\n}\n\nfunction convertWrapperRule(content: string, rule: BuilderWrapperRule): string {\n const prefix = escapeRegExp(rule.shortcodePrefix);\n const pattern = new RegExp(\n `\\\\[${prefix}\\\\b([^\\\\]]*)\\\\]([\\\\s\\\\S]*?)\\\\[\\\\/${prefix}\\\\b[^\\\\]]*\\\\]`,\n \"gi\",\n );\n\n return content.replace(pattern, (_, params: string, inner: string) => {\n const parts: string[] = [];\n if (rule.urlParams?.length) {\n const url = extractShortcodeParam(params, rule.urlParams);\n if (url) parts.push(emitHtmlTag(\"img\", url));\n }\n parts.push(inner.trim());\n return parts.filter(Boolean).join(\"\\n\");\n });\n}\n\nfunction isPlaceholderImageUrl(url: string): boolean {\n return /placehold\\.it|placeholder\\.com|via\\.placeholder/i.test(url);\n}\n\nfunction resolveLinkRuleParams(\n params: string,\n rule: BuilderLinkRule,\n): { text?: string; url?: string } {\n let text =\n extractQuotedParam(params, rule.textParam) ??\n extractBareOrQuotedParam(params, rule.textParam);\n let url =\n extractQuotedParam(params, rule.urlParam) ??\n extractBareOrQuotedParam(params, rule.urlParam);\n\n const moduleKey = extractBareOrQuotedParam(params, \"key\");\n if (moduleKey && activeTatsuContext?.modulesByKey.has(moduleKey)) {\n const jsonAtts = activeTatsuContext.modulesByKey.get(moduleKey)!;\n if (!text) text = resolveTatsuJsonScalar(jsonAtts[rule.textParam]);\n if (!url) url = resolveTatsuJsonScalar(jsonAtts[rule.urlParam]);\n }\n\n return { text, url };\n}\n\nfunction convertLinkRule(content: string, rule: BuilderLinkRule): string {\n const prefix = escapeRegExp(rule.shortcodePrefix);\n const pattern = new RegExp(\n `\\\\[${prefix}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${prefix}\\\\b[^\\\\]]*\\\\])?`,\n \"gi\",\n );\n\n return content.replace(pattern, (_, params: string) => {\n const { text, url } = resolveLinkRuleParams(params, rule);\n if (!text?.trim() && !url?.trim()) return \"\";\n const label = text?.trim() || \"Link\";\n const href = url?.trim() || \"#\";\n const classAttr = rule.className\n ? ` class=\"${escapeLayoutAttr(rule.className)}\"`\n : \"\";\n return `<a href=\"${escapeLayoutAttr(href)}\"${classAttr}>${escapeHtmlText(label)}</a>`;\n });\n}\n\nfunction convertIconImageRule(content: string, rule: BuilderIconImageRule): string {\n const prefix = escapeRegExp(rule.shortcodePrefix);\n const pattern = new RegExp(\n `\\\\[${prefix}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${prefix}\\\\b[^\\\\]]*\\\\])?`,\n \"gi\",\n );\n\n return content.replace(pattern, (_, params: string) => {\n const iconImage =\n extractQuotedParam(params, rule.imageParam) ?? extractQuotedParam(params, \"image\");\n if (!iconImage?.startsWith(\"http\") || isPlaceholderImageUrl(iconImage)) {\n return \"\";\n }\n const img = emitHtmlTag(\"img\", iconImage);\n if (rule.hrefParam) {\n const href = extractQuotedParam(params, rule.hrefParam);\n if (href?.startsWith(\"http\")) {\n const escapedHref = href\n .replace(/&/g, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/</g, \"&lt;\");\n return `<a href=\"${escapedHref}\">${img}</a>`;\n }\n }\n return img;\n });\n}\n\nfunction convertPlaceholderRule(content: string, rule: BuilderPlaceholderRule): string {\n const prefix = escapeRegExp(rule.shortcodePrefix);\n const pattern = new RegExp(\n `\\\\[${prefix}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${prefix}\\\\b[^\\\\]]*\\\\])?`,\n \"gi\",\n );\n return content.replace(pattern, rule.html);\n}\n\nfunction stripScaffoldingPrefix(content: string, prefix: string): string {\n const escaped = escapeRegExp(prefix);\n const opener = new RegExp(`\\\\[${escaped}[a-z0-9_-]*[^\\\\]]*\\\\]`, \"gi\");\n const closer = new RegExp(`\\\\[\\\\/${escaped}[a-z0-9_-]*[^\\\\]]*\\\\]`, \"gi\");\n return content.replace(opener, \"\").replace(closer, \"\");\n}\n\nfunction stripLegacyTokens(content: string, tokens: string[]): string {\n let result = content;\n for (const token of tokens) {\n const escaped = escapeRegExp(token);\n const opener = new RegExp(`\\\\[${escaped}\\\\b[^\\\\]]*\\\\]`, \"gi\");\n const closer = new RegExp(`\\\\[\\\\/${escaped}\\\\b[^\\\\]]*\\\\]`, \"gi\");\n result = result.replace(opener, \"\").replace(closer, \"\");\n }\n return result;\n}\n\nfunction detectThemes(content: string, registry: BuilderThemeConfig[]): BuilderThemeConfig[] {\n return registry.filter((theme) => theme.detect.test(content));\n}\n\nfunction extractBareOrQuotedParam(params: string, name: string): string | undefined {\n const quoted = extractQuotedParam(params, name);\n if (quoted) return quoted;\n const pattern = new RegExp(`\\\\b${escapeRegExp(name)}\\\\s*=\\\\s*([^\\\\s\"'\\\\]]+)`, \"i\");\n const match = pattern.exec(params);\n return match?.[1]?.trim() || undefined;\n}\n\nexport type SliderPluginId = \"revslider\" | \"masterslider\";\n\nexport interface ParsedSliderReference {\n plugin: SliderPluginId;\n alias: string;\n slidertitle?: string;\n}\n\n/** Parse `[rev_slider …]` / `[masterslider …]` markup (OSS-27 meta + in-body stubs). */\nexport function parseSliderShortcodeMarkup(markup: string): ParsedSliderReference | undefined {\n const trimmed = markup.trim();\n if (!trimmed) return undefined;\n\n const revMatch = trimmed.match(/\\[rev_slider\\b([^\\]]*)\\]/i);\n if (revMatch) {\n const params = revMatch[1] ?? \"\";\n const alias = extractBareOrQuotedParam(params, \"alias\");\n if (alias) {\n return {\n plugin: \"revslider\",\n alias,\n slidertitle: extractBareOrQuotedParam(params, \"slidertitle\"),\n };\n }\n }\n\n const masterMatch = trimmed.match(/\\[masterslider\\b([^\\]]*)\\]/i);\n if (masterMatch) {\n const params = masterMatch[1] ?? \"\";\n const alias = extractBareOrQuotedParam(params, \"alias\");\n if (alias) return { plugin: \"masterslider\", alias };\n }\n\n return undefined;\n}\n\n/** Parse Oshine `_slider` meta (`revslider_alias`, `masterslider_alias`, or `none`). */\nexport function parseSliderMetaValue(value: string): ParsedSliderReference | undefined {\n const trimmed = value.trim();\n if (!trimmed || trimmed.toLowerCase() === \"none\") return undefined;\n\n const lower = trimmed.toLowerCase();\n if (lower.startsWith(\"revslider_\")) {\n const alias = trimmed.slice(\"revslider_\".length).trim();\n if (alias) return { plugin: \"revslider\", alias };\n }\n if (lower.startsWith(\"masterslider_\")) {\n const alias = trimmed.slice(\"masterslider_\".length).trim();\n if (alias) return { plugin: \"masterslider\", alias };\n }\n\n return undefined;\n}\n\nfunction emitWidgetStub(\n widget: string,\n attrs: Record<string, string | undefined>,\n tag: \"div\" | \"section\" = \"div\",\n): string {\n const parts = [`data-wp-widget=\"${escapeLayoutAttr(widget)}\"`];\n for (const [key, value] of Object.entries(attrs)) {\n if (value) parts.push(`${key}=\"${escapeLayoutAttr(value)}\"`);\n }\n return `<${tag} ${parts.join(\" \")}>${WP_WIDGET_PLACEHOLDER}</${tag}>`;\n}\n\n/** Normalize YouTube/Vimeo share URLs to canonical embed URLs. */\nexport function normalizeVideoEmbedUrl(\n raw: string,\n): { provider: \"youtube\" | \"vimeo\" | \"external\"; embedUrl: string } | undefined {\n const trimmed = raw.trim();\n if (!trimmed || trimmed.startsWith(\"data:\")) return undefined;\n\n try {\n const url = new URL(trimmed.startsWith(\"//\") ? `https:${trimmed}` : trimmed);\n const host = url.hostname.replace(/^www\\./, \"\").replace(/^m\\./, \"\");\n\n if (host === \"youtu.be\") {\n const id = url.pathname.split(\"/\").filter(Boolean)[0];\n if (id) {\n return { provider: \"youtube\", embedUrl: `https://www.youtube-nocookie.com/embed/${id}` };\n }\n }\n\n if (host === \"youtube.com\" || host === \"youtube-nocookie.com\") {\n const embedMatch = url.pathname.match(/\\/embed\\/([^/?#]+)/);\n if (embedMatch?.[1]) {\n const start = url.searchParams.get(\"start\");\n const suffix = start ? `?start=${start}` : \"\";\n return {\n provider: \"youtube\",\n embedUrl: `https://www.youtube-nocookie.com/embed/${embedMatch[1]}${suffix}`,\n };\n }\n const videoId = url.searchParams.get(\"v\");\n if (videoId) {\n const t = url.searchParams.get(\"t\") ?? url.searchParams.get(\"start\");\n const startSeconds = t?.endsWith(\"s\") ? t.slice(0, -1) : t;\n const suffix = startSeconds ? `?start=${startSeconds}` : \"\";\n return {\n provider: \"youtube\",\n embedUrl: `https://www.youtube-nocookie.com/embed/${videoId}${suffix}`,\n };\n }\n }\n\n if (host === \"vimeo.com\") {\n const segments = url.pathname.split(\"/\").filter(Boolean);\n const id = segments[segments.length - 1];\n if (id && /^\\d+$/.test(id)) {\n return { provider: \"vimeo\", embedUrl: `https://player.vimeo.com/video/${id}` };\n }\n }\n\n if (host === \"player.vimeo.com\") {\n const match = url.pathname.match(/\\/video\\/(\\d+)/);\n if (match?.[1]) {\n return { provider: \"vimeo\", embedUrl: `https://player.vimeo.com/video/${match[1]}` };\n }\n }\n } catch {\n return undefined;\n }\n\n return undefined;\n}\n\nfunction emitVideoWidgetFromParams(params: string, inner: string): string {\n const url =\n extractShortcodeParam(params, [\"url\", \"src\", \"video\", \"link\", \"youtube_url\", \"vimeo_url\"]) ??\n inner.trim().match(/^https?:\\/\\/\\S+/)?.[0];\n\n if (!url) {\n return emitWidgetStub(\"video\", { \"data-video-provider\": \"external\" });\n }\n\n const normalized = normalizeVideoEmbedUrl(url);\n if (normalized) {\n return emitWidgetStub(\"video\", {\n \"data-video-provider\": normalized.provider,\n \"data-embed-url\": normalized.embedUrl,\n });\n }\n\n if (/\\.(mp4|webm|ogg)(\\?|#|$)/i.test(url)) {\n return emitHtmlTag(\"video\", url);\n }\n\n return emitWidgetStub(\"video\", {\n \"data-video-provider\": \"external\",\n \"data-embed-url\": url,\n });\n}\n\n/** Host sanitize allowlist: iframe src must start with `https://www.google.com/maps/embed`. */\nexport function normalizeSanitizedGoogleMapsEmbedUrl(url: string): string | undefined {\n const trimmed = url.trim();\n if (!trimmed) return undefined;\n try {\n const parsed = new URL(trimmed);\n if (!/^(www\\.)?google\\.com$/i.test(parsed.hostname)) return undefined;\n if (!parsed.pathname.includes(\"/maps/embed\")) return undefined;\n parsed.protocol = \"https:\";\n if (!parsed.hostname.startsWith(\"www.\")) {\n parsed.hostname = `www.${parsed.hostname}`;\n }\n return parsed.toString();\n } catch {\n return undefined;\n }\n}\n\n/** Build map widget stub fields from shortcode params (OSS-20). */\nexport function buildGoogleMapsEmbedUrlFromMapParams(params: string): {\n embedUrl?: string;\n lat?: string;\n lng?: string;\n zoom?: string;\n query?: string;\n} {\n const direct = extractShortcodeParam(params, [\n \"embed_url\",\n \"url\",\n \"src\",\n \"map_url\",\n \"iframe_url\",\n \"embed\",\n ]);\n if (direct) {\n const embedUrl = normalizeSanitizedGoogleMapsEmbedUrl(direct);\n if (embedUrl) return { embedUrl };\n }\n\n const lat =\n extractBareOrQuotedParam(params, \"lat\") ??\n extractBareOrQuotedParam(params, \"latitude\") ??\n extractBareOrQuotedParam(params, \"map_lat\");\n const lng =\n extractBareOrQuotedParam(params, \"lng\") ??\n extractBareOrQuotedParam(params, \"longitude\") ??\n extractBareOrQuotedParam(params, \"map_lng\");\n const zoom = extractBareOrQuotedParam(params, \"zoom\") ?? \"14\";\n const address =\n extractBareOrQuotedParam(params, \"address\") ??\n extractBareOrQuotedParam(params, \"map_address\") ??\n extractBareOrQuotedParam(params, \"location\") ??\n extractBareOrQuotedParam(params, \"map_location\") ??\n extractBareOrQuotedParam(params, \"q\");\n\n if (lat && lng) {\n return { lat, lng, zoom };\n }\n\n if (address) {\n return { query: address, zoom };\n }\n\n return {};\n}\n\nfunction flattenMapShortcodes(content: string, widgetRegistry: WordPressWidgetRegistry): string {\n let html = content;\n for (const prefix of widgetRegistry.mapShortcodePrefixes) {\n const pattern = new RegExp(\n `\\\\[${escapeRegExp(prefix)}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${escapeRegExp(prefix)}\\\\b[^\\\\]]*\\\\])?`,\n \"gi\",\n );\n html = html.replace(pattern, (_, params: string) => {\n const resolved = buildGoogleMapsEmbedUrlFromMapParams(params);\n return emitWidgetStub(\"map\", {\n ...(resolved.embedUrl ? { \"data-embed-url\": resolved.embedUrl } : {}),\n ...(resolved.lat ? { \"data-latitude\": resolved.lat } : {}),\n ...(resolved.lng ? { \"data-longitude\": resolved.lng } : {}),\n ...(resolved.zoom ? { \"data-zoom\": resolved.zoom } : {}),\n ...(resolved.query ? { \"data-wp-map-query\": resolved.query } : {}),\n });\n });\n }\n return html;\n}\n\nfunction flattenContactFormShortcodes(content: string, widgetRegistry: WordPressWidgetRegistry): string {\n let html = content;\n for (const rule of widgetRegistry.contactFormRules) {\n const pattern = new RegExp(\n `\\\\[${escapeRegExp(rule.tag)}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${escapeRegExp(rule.tag)}\\\\b[^\\\\]]*\\\\])?`,\n \"gi\",\n );\n html = html.replace(pattern, (_, params: string) => {\n const id = extractBareOrQuotedParam(params, rule.idParam);\n return emitWidgetStub(\n \"contact-form\",\n {\n \"data-wp-form-source\": rule.source,\n ...(id ? { \"data-wp-form-id\": id } : {}),\n },\n \"section\",\n );\n });\n }\n return html;\n}\n\nfunction emitInlineGalleryFromIds(idList: string[]): string {\n const images = idList\n .map((id) => `<img data-wp-attachment-id=\"${escapeLayoutAttr(id)}\" alt=\"\" />`)\n .join(\"\");\n return `<figure data-wp-inline-gallery>${images}</figure>`;\n}\n\nfunction parseGalleryAttachmentIds(params: string): string[] | undefined {\n const ids = extractBareOrQuotedParam(params, \"ids\");\n const idList = ids\n ?.split(\",\")\n .map((part) => part.trim())\n .filter((part) => /^\\d+$/.test(part));\n return idList?.length ? idList : undefined;\n}\n\nfunction flattenIdGalleryShortcode(content: string, tag: string): string {\n const escaped = escapeRegExp(tag);\n const pattern = new RegExp(`\\\\[${escaped}\\\\b([^\\\\]]*)\\\\](?:\\\\s*\\\\[\\\\/${escaped}\\\\])?`, \"gi\");\n return content.replace(pattern, (fullMatch, params: string) => {\n const idList = parseGalleryAttachmentIds(params);\n if (idList?.length) {\n return emitInlineGalleryFromIds(idList);\n }\n return fullMatch;\n });\n}\n\nfunction flattenGalleryShortcodes(content: string, widgetRegistry: WordPressWidgetRegistry): string {\n const tag = escapeRegExp(widgetRegistry.galleryShortcode);\n const pattern = new RegExp(`\\\\[${tag}\\\\b([^\\\\]]*)\\\\](?:\\\\s*\\\\[\\\\/${tag}\\\\])?`, \"gi\");\n return content.replace(pattern, (_, params: string) => {\n const idList = parseGalleryAttachmentIds(params);\n\n if (idList?.length) {\n return emitInlineGalleryFromIds(idList);\n }\n\n const category = extractBareOrQuotedParam(params, \"category\") ?? extractBareOrQuotedParam(params, \"type\");\n return emitWidgetStub(\"portfolio\", {\n \"data-wp-gallery-dynamic\": \"1\",\n ...(category ? { \"data-wp-portfolio-category\": category } : {}),\n });\n });\n}\n\nfunction flattenIdBasedGalleryShortcodes(\n content: string,\n widgetRegistry: WordPressWidgetRegistry,\n): string {\n let html = content;\n for (const tag of widgetRegistry.idGalleryShortcodes) {\n html = flattenIdGalleryShortcode(html, tag);\n }\n return html;\n}\n\nconst SHORTCODE_WORD_COUNTS: Record<string, string> = {\n one: \"1\",\n two: \"2\",\n three: \"3\",\n four: \"4\",\n five: \"5\",\n six: \"6\",\n seven: \"7\",\n eight: \"8\",\n nine: \"9\",\n ten: \"10\",\n};\n\nfunction normalizeShortcodeCount(raw: string | undefined): string | undefined {\n if (!raw?.trim()) return undefined;\n const trimmed = raw.trim().toLowerCase();\n if (/^\\d+$/.test(trimmed)) return trimmed;\n return SHORTCODE_WORD_COUNTS[trimmed];\n}\n\nfunction inferBlogListingLayout(params: string): string {\n const raw =\n extractBareOrQuotedParam(params, \"builderLayout\") ??\n extractBareOrQuotedParam(params, \"layout\") ??\n extractBareOrQuotedParam(params, \"style\");\n if (raw) {\n const normalized = raw.trim().toLowerCase();\n if (normalized === \"list\" || normalized === \"grid\" || normalized === \"featured\" || normalized === \"sidebar\") {\n return normalized;\n }\n }\n\n const moduleKey = extractBareOrQuotedParam(params, \"key\");\n if (moduleKey && activeTatsuContext) {\n const merged = mergeTatsuLayoutAttrs(params, moduleKey, activeTatsuContext);\n const fromJson = merged.builderLayout?.trim().toLowerCase();\n if (fromJson === \"list\" || fromJson === \"grid\" || fromJson === \"featured\" || fromJson === \"sidebar\") {\n return fromJson;\n }\n }\n\n return \"grid\";\n}\n\nfunction decodeBasicHtmlEntities(text: string): string {\n return text\n .replace(/&quot;/g, '\"')\n .replace(/&apos;/g, \"'\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&amp;/g, \"&\");\n}\n\nfunction stripHtmlTags(html: string): string {\n return html.replace(/<[^>]+>/g, \" \").replace(/\\s+/g, \" \").trim();\n}\n\nfunction extractTestimonialQuoteFromInner(inner: string): string | undefined {\n const trimmed = inner.trim();\n if (!trimmed) return undefined;\n\n const paragraphMatch = trimmed.match(/<p[^>]*>([\\s\\S]*?)<\\/p>/i);\n if (paragraphMatch?.[1]) {\n const quote = decodeBasicHtmlEntities(stripHtmlTags(paragraphMatch[1])).trim();\n return quote || undefined;\n }\n\n const blockquoteMatch = trimmed.match(/<blockquote[^>]*>([\\s\\S]*?)<\\/blockquote>/i);\n if (blockquoteMatch?.[1]) {\n const quote = decodeBasicHtmlEntities(stripHtmlTags(blockquoteMatch[1])).trim();\n return quote || undefined;\n }\n\n const plain = decodeBasicHtmlEntities(stripHtmlTags(trimmed)).trim();\n return plain || undefined;\n}\n\nfunction parseTestimonialItemAttrs(\n params: string,\n inner: string,\n): Record<string, string | undefined> | null {\n const author =\n extractBareOrQuotedParam(params, \"author\") ??\n extractBareOrQuotedParam(params, \"name\");\n const role =\n extractBareOrQuotedParam(params, \"author_role\") ??\n extractBareOrQuotedParam(params, \"role\") ??\n extractBareOrQuotedParam(params, \"title\");\n const image =\n extractBareOrQuotedParam(params, \"author_image\") ??\n extractBareOrQuotedParam(params, \"image\") ??\n extractBareOrQuotedParam(params, \"avatar\");\n const quote =\n extractBareOrQuotedParam(params, \"quote\") ??\n extractBareOrQuotedParam(params, \"content\") ??\n extractTestimonialQuoteFromInner(inner);\n const rating =\n extractBareOrQuotedParam(params, \"rating\") ??\n extractBareOrQuotedParam(params, \"stars\");\n\n if (!author && !quote) return null;\n\n return {\n \"data-wp-testimonial-author\": author,\n \"data-wp-testimonial-role\": role,\n \"data-wp-testimonial-image\": image,\n \"data-wp-testimonial-quote\": quote,\n ...(rating ? { \"data-wp-testimonial-rating\": rating } : {}),\n };\n}\n\nfunction emitTestimonialItemStub(attrs: Record<string, string | undefined>): string {\n const parts: string[] = [];\n for (const [key, value] of Object.entries(attrs)) {\n if (value) parts.push(`${key}=\"${escapeLayoutAttr(value)}\"`);\n }\n return `<div ${parts.join(\" \")}>${WP_WIDGET_PLACEHOLDER}</div>`;\n}\n\nfunction emitTestimonialsWidgetStub(\n sectionAttrs: Record<string, string | undefined>,\n items: Array<Record<string, string | undefined>>,\n): string {\n const sectionParts = ['data-wp-widget=\"testimonials\"'];\n for (const [key, value] of Object.entries(sectionAttrs)) {\n if (value) sectionParts.push(`${key}=\"${escapeLayoutAttr(value)}\"`);\n }\n const children = items.map((item) => emitTestimonialItemStub(item)).join(\"\");\n return `<section ${sectionParts.join(\" \")}>${children}</section>`;\n}\n\nfunction inferTestimonialColumns(\n wrapperParams: string,\n itemCount: number,\n): string {\n const explicit =\n normalizeShortcodeCount(extractBareOrQuotedParam(wrapperParams, \"columns\")) ??\n normalizeShortcodeCount(extractBareOrQuotedParam(wrapperParams, \"col\"));\n if (explicit) return explicit;\n if (itemCount <= 1) return \"1\";\n if (itemCount === 2) return \"2\";\n if (itemCount >= 4) return \"4\";\n return \"3\";\n}\n\nfunction collectTestimonialItemsFromInner(\n inner: string,\n itemTag: string,\n): Array<Record<string, string | undefined>> {\n const escaped = escapeRegExp(itemTag);\n const pattern = new RegExp(\n `\\\\[${escaped}\\\\b([^\\\\]]*)\\\\]([\\\\s\\\\S]*?)\\\\[\\\\/${escaped}\\\\b[^\\\\]]*\\\\]`,\n \"gi\",\n );\n const items: Array<Record<string, string | undefined>> = [];\n inner.replace(pattern, (_, params: string, itemInner: string) => {\n const item = parseTestimonialItemAttrs(params, itemInner);\n if (item) items.push(item);\n return \"\";\n });\n return items;\n}\n\nfunction flattenTestimonialsShortcodes(\n content: string,\n widgetRegistry: WordPressWidgetRegistry,\n): string {\n const itemTag = widgetRegistry.testimonialItemTag;\n let html = content;\n\n for (const wrapperTag of widgetRegistry.testimonialsWrapperTags) {\n const escaped = escapeRegExp(wrapperTag);\n const pattern = new RegExp(\n `\\\\[${escaped}\\\\b([^\\\\]]*)\\\\]([\\\\s\\\\S]*?)\\\\[\\\\/${escaped}\\\\b[^\\\\]]*\\\\]`,\n \"gi\",\n );\n html = html.replace(pattern, (fullMatch, wrapperParams: string, inner: string) => {\n const items = collectTestimonialItemsFromInner(inner, itemTag);\n if (items.length === 0) return fullMatch;\n\n return emitTestimonialsWidgetStub(\n {\n \"data-wp-testimonial-columns\": inferTestimonialColumns(wrapperParams, items.length),\n \"data-wp-testimonial-show-stars\": items.some((item) => item[\"data-wp-testimonial-rating\"])\n ? \"true\"\n : \"false\",\n },\n items,\n );\n });\n }\n\n const itemPattern = new RegExp(\n `\\\\[${escapeRegExp(itemTag)}\\\\b([^\\\\]]*)\\\\]([\\\\s\\\\S]*?)\\\\[\\\\/${escapeRegExp(itemTag)}\\\\b[^\\\\]]*\\\\]`,\n \"gi\",\n );\n return html.replace(itemPattern, (fullMatch, params: string, inner: string) => {\n const item = parseTestimonialItemAttrs(params, inner);\n if (!item) return fullMatch;\n return emitTestimonialsWidgetStub(\n {\n \"data-wp-testimonial-columns\": \"1\",\n \"data-wp-testimonial-show-stars\": item[\"data-wp-testimonial-rating\"] ? \"true\" : \"false\",\n },\n [item],\n );\n });\n}\n\nfunction flattenSliderShortcodes(content: string, widgetRegistry: WordPressWidgetRegistry): string {\n let html = content;\n for (const tag of widgetRegistry.sliderShortcodeTags) {\n const escaped = escapeRegExp(tag);\n const plugin: SliderPluginId = tag.toLowerCase() === \"masterslider\" ? \"masterslider\" : \"revslider\";\n const pattern = new RegExp(`\\\\[${escaped}\\\\b([^\\\\]]*)\\\\](?:\\\\s*\\\\[\\\\/${escaped}\\\\b[^\\\\]]*\\\\])?`, \"gi\");\n html = html.replace(pattern, (_, params: string) => {\n const alias = extractBareOrQuotedParam(params, \"alias\");\n const slidertitle = extractBareOrQuotedParam(params, \"slidertitle\");\n return emitWidgetStub(\"slider\", {\n \"data-wp-slider-plugin\": plugin,\n ...(alias ? { \"data-wp-slider-alias\": alias } : {}),\n ...(slidertitle ? { \"data-wp-slider-title\": slidertitle } : {}),\n });\n });\n }\n return html;\n}\n\nfunction flattenBlogListingShortcodes(\n content: string,\n widgetRegistry: WordPressWidgetRegistry,\n): string {\n let html = content;\n for (const tag of widgetRegistry.blogShortcodeTags) {\n const escaped = escapeRegExp(tag);\n const pattern = new RegExp(`\\\\[${escaped}\\\\b([^\\\\]]*)\\\\](?:\\\\s*\\\\[\\\\/${escaped}\\\\])?`, \"gi\");\n html = html.replace(pattern, (_, params: string) => {\n const limit =\n normalizeShortcodeCount(extractBareOrQuotedParam(params, \"number_of_posts\")) ??\n normalizeShortcodeCount(extractBareOrQuotedParam(params, \"count\")) ??\n normalizeShortcodeCount(extractBareOrQuotedParam(params, \"posts_per_page\")) ??\n normalizeShortcodeCount(extractBareOrQuotedParam(params, \"number\"));\n const filterBy = extractBareOrQuotedParam(params, \"filter_by\")?.toLowerCase();\n const categories = extractBareOrQuotedParam(params, \"categories\");\n const tags = extractBareOrQuotedParam(params, \"tags\");\n const col = extractBareOrQuotedParam(params, \"col\");\n\n return emitWidgetStub(\n \"blog-listing\",\n {\n \"data-wp-blog-layout\": inferBlogListingLayout(params),\n ...(limit ? { \"data-wp-blog-limit\": limit } : {}),\n ...(col ? { \"data-wp-blog-columns\": col } : {}),\n ...(filterBy === \"category\" && categories ? { \"data-wp-blog-category\": categories } : {}),\n ...(filterBy === \"tag\" && tags ? { \"data-wp-blog-tags\": tags } : {}),\n },\n \"section\",\n );\n });\n }\n return html;\n}\n\nfunction flattenPortfolioShortcodes(content: string, widgetRegistry: WordPressWidgetRegistry): string {\n const tag = escapeRegExp(widgetRegistry.portfolioShortcode);\n const pattern = new RegExp(`\\\\[${tag}\\\\b([^\\\\]]*)\\\\](?:\\\\s*\\\\[\\\\/${tag}\\\\])?`, \"gi\");\n return content.replace(pattern, (_, params: string) => {\n const category = extractBareOrQuotedParam(params, \"category\");\n const slug = extractBareOrQuotedParam(params, \"slug\");\n return emitWidgetStub(\"portfolio\", {\n ...(category ? { \"data-wp-portfolio-category\": category } : {}),\n ...(slug ? { \"data-wp-portfolio-slug\": slug } : {}),\n });\n });\n}\n\nfunction flattenVideoShortcodes(content: string, widgetRegistry: WordPressWidgetRegistry): string {\n let html = content;\n for (const prefix of widgetRegistry.videoShortcodePrefixes) {\n const wrapped = new RegExp(\n `\\\\[${escapeRegExp(prefix)}\\\\b([^\\\\]]*)\\\\]([\\\\s\\\\S]*?)\\\\[\\\\/${escapeRegExp(prefix)}\\\\b[^\\\\]]*\\\\]`,\n \"gi\",\n );\n html = html.replace(wrapped, (_, params: string, inner: string) =>\n emitVideoWidgetFromParams(params, inner),\n );\n\n const selfClosing = new RegExp(\n `\\\\[${escapeRegExp(prefix)}\\\\b([^\\\\]]*)\\\\]`,\n \"gi\",\n );\n html = html.replace(selfClosing, (_, params: string) => emitVideoWidgetFromParams(params, \"\"));\n }\n return html;\n}\n\n/** Detect embedded HTML contact forms (e.g. Tatsu `[tatsu_code]` with `<form>`). */\nexport function looksLikeContactFormHtml(formHtml: string): boolean {\n if (!/<form\\b/i.test(formHtml)) return false;\n\n const lower = formHtml.toLowerCase();\n if (/searchform|wp-login-form|loginform|lostpasswordform/i.test(lower)) return false;\n if (/type\\s*=\\s*[\"']search[\"']/i.test(formHtml)) return false;\n if (/newsletter|subscribe/i.test(lower) && !/<textarea\\b/i.test(formHtml)) return false;\n\n const hasEmailField =\n /type\\s*=\\s*[\"']email[\"']/i.test(formHtml) ||\n /name\\s*=\\s*[\"'][^\"']*email/i.test(formHtml) ||\n /class\\s*=\\s*[\"'][^\"']*email/i.test(formHtml);\n const hasMessageField =\n /<textarea\\b/i.test(formHtml) ||\n /name\\s*=\\s*[\"'][^\"']*(message|comment|body|enquiry|inquiry)/i.test(formHtml);\n const hasContactHint =\n /contact|serverless-contact|get-in-touch|request-quote|quote-request/i.test(lower);\n\n if (hasEmailField && hasMessageField) return true;\n if (hasContactHint && hasEmailField) return true;\n if (hasContactHint && hasMessageField) return true;\n\n return false;\n}\n\nfunction stripContactFormHelperScripts(html: string): string {\n return html.replace(\n /<script\\b[^>]*\\bsrc\\s*=\\s*[\"'][^\"']*(?:recaptcha|contact_form|contact-form)[^\"']*[\"'][^>]*>\\s*<\\/script>\\s*/gi,\n \"\",\n );\n}\n\nfunction flattenCustomHtmlContactForms(content: string): string {\n let html = content.replace(/<form\\b[^>]*>[\\s\\S]*?<\\/form>/gi, (formHtml) => {\n if (!looksLikeContactFormHtml(formHtml)) return formHtml;\n\n const formId =\n formHtml.match(/\\bid\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1]?.trim() ||\n formHtml.match(/\\bname\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1]?.trim();\n\n return emitWidgetStub(\n \"contact-form\",\n {\n \"data-wp-form-source\": \"custom-html\",\n ...(formId ? { \"data-wp-form-id\": formId } : {}),\n },\n \"section\",\n );\n });\n\n html = stripContactFormHelperScripts(html);\n return html;\n}\n\n/** Cross-builder widget + video stubs (before scaffolding strip). */\nfunction flattenWordPressWidgets(\n content: string,\n widgetRegistry: WordPressWidgetRegistry = WORDPRESS_WIDGET_REGISTRY,\n): string {\n let html = content;\n html = flattenGalleryShortcodes(html, widgetRegistry);\n html = flattenIdBasedGalleryShortcodes(html, widgetRegistry);\n html = flattenPortfolioShortcodes(html, widgetRegistry);\n html = flattenSliderShortcodes(html, widgetRegistry);\n html = flattenBlogListingShortcodes(html, widgetRegistry);\n html = flattenTestimonialsShortcodes(html, widgetRegistry);\n html = flattenMapShortcodes(html, widgetRegistry);\n html = flattenContactFormShortcodes(html, widgetRegistry);\n html = flattenVideoShortcodes(html, widgetRegistry);\n html = flattenCustomHtmlContactForms(html);\n return html;\n}\n\n/**\n * Pre-DTO WordPress builder flattening — Bucket 1 (asset/text shortcodes → HTML) then\n * Bucket 2 (layout scaffolding stripped). Decoupled from sink-time rewriteInlineImages.\n */\nexport function flattenWordPressBuilders(\n content: string,\n options: FlattenWordPressBuildersOptions = {},\n): FlattenWordPressBuildersResult {\n if (!content.trim()) {\n return { html: content, detectedThemes: [] };\n }\n\n activeTatsuContext = options.tatsuPageContent\n ? buildTatsuPageContext(options.tatsuPageContent)\n : undefined;\n\n try {\n const registry = options.registry ?? WORDPRESS_BUILDER_REGISTRY;\n const themes = detectThemes(content, registry);\n\n const widgetRegistry = options.widgetRegistry ?? WORDPRESS_WIDGET_REGISTRY;\n // Widget stubs before scaffolding strips (e.g. blox_gmap, tatsu_video, portfolio).\n let html = flattenWordPressWidgets(content, widgetRegistry);\n for (const theme of themes) {\n for (const rule of theme.wrapperRules ?? []) {\n html = convertWrapperRule(html, rule);\n }\n for (const rule of theme.textRules ?? []) {\n html = convertTextRule(html, rule);\n }\n for (const rule of theme.urlRules ?? []) {\n html = convertUrlRule(html, rule);\n }\n for (const rule of theme.placeholderRules ?? []) {\n html = convertPlaceholderRule(html, rule);\n }\n for (const rule of theme.iconImageRules ?? []) {\n html = convertIconImageRule(html, rule);\n }\n for (const rule of theme.linkRules ?? []) {\n html = convertLinkRule(html, rule);\n }\n for (const layoutMap of collectLayoutMaps(theme)) {\n html = applyStructuralLayoutMap(html, layoutMap);\n }\n for (const prefix of theme.scaffoldingPrefixes ?? []) {\n html = stripScaffoldingPrefix(html, prefix);\n }\n if (theme.legacyScaffoldingTokens?.length) {\n html = stripLegacyTokens(html, theme.legacyScaffoldingTokens);\n }\n }\n\n // Catch widget shortcodes revealed after wrapper unwrap (e.g. blox_gmap inside tatsu_text_with_shortcodes).\n html = flattenWordPressWidgets(html, widgetRegistry);\n\n html = html.replace(/\\n{3,}/g, \"\\n\\n\").trim();\n\n return {\n html,\n detectedThemes: themes.map((theme) => theme.id),\n };\n } finally {\n activeTatsuContext = undefined;\n }\n}\n"],"mappings":"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","names":["value","trimmed"]}
@@ -9,7 +9,7 @@ import {
9
9
  import {
10
10
  UNRESOLVABLE_SHORTCODE_PREFIXES,
11
11
  rewriteInlineImages
12
- } from "./chunk-HUSXCKPI.js";
12
+ } from "./chunk-BF2AZ7S2.js";
13
13
  import {
14
14
  linkToPath,
15
15
  sanitizeSlug
@@ -21,7 +21,7 @@ import {
21
21
  discoverRawImgSrcs,
22
22
  isMigrationMediaRef,
23
23
  normalizeAssetUrl
24
- } from "./chunk-S4GMDRGX.js";
24
+ } from "./chunk-DZI5C6KR.js";
25
25
 
26
26
  // src/sinks/types.ts
27
27
  var MIGRATION_WRITE_STAGES = [
@@ -1565,4 +1565,4 @@ export {
1565
1565
  resolveAdapterImportSummary,
1566
1566
  runDryRun
1567
1567
  };
1568
- //# sourceMappingURL=chunk-5TRCJONX.js.map
1568
+ //# sourceMappingURL=chunk-ZDQBXTIV.js.map
package/dist/cli/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getAdapter
4
- } from "../chunk-ZKIAIP3B.js";
4
+ } from "../chunk-H23JQVJZ.js";
5
5
  import {
6
6
  analyzeConflicts,
7
7
  buildMigrationReport,
@@ -17,16 +17,16 @@ import {
17
17
  runMigration,
18
18
  staleUrlsFromEstimate,
19
19
  writeFilesystemExport
20
- } from "../chunk-5TRCJONX.js";
20
+ } from "../chunk-ZDQBXTIV.js";
21
21
  import {
22
22
  collectEntities
23
23
  } from "../chunk-PD5AZX3B.js";
24
- import "../chunk-S55525RD.js";
25
- import "../chunk-HUSXCKPI.js";
24
+ import "../chunk-PHL6U6CP.js";
25
+ import "../chunk-BF2AZ7S2.js";
26
26
  import "../chunk-XRCF73DA.js";
27
27
  import {
28
28
  createWpContentGatewayRewrite
29
- } from "../chunk-S4GMDRGX.js";
29
+ } from "../chunk-DZI5C6KR.js";
30
30
 
31
31
  // src/cli/index.ts
32
32
  import { writeFile } from "fs/promises";
package/dist/index.d.ts CHANGED
@@ -3,9 +3,9 @@ export { A as AdapterContext, E as EntityKey, h as EntityType, i as MigrationCur
3
3
  export { EntityState, MigrationCheckpoint, TrackedEntity, buildPortfolioMediaLinks, isTerminalState, normalizedAssetExifSchema, normalizedAssetSchema, normalizedCategorySchema, normalizedEntitySchema, normalizedPageSchema, normalizedPortfolioSchema, normalizedPostSchema, normalizedTagSchema, shouldProcessEntity, sourceMetadataSchema, validateNormalizedAsset, validateNormalizedCategory, validateNormalizedEntity, validateNormalizedPage, validateNormalizedPortfolio, validateNormalizedPost, validateNormalizedTag } from './normalizer/index.js';
4
4
  export { B as BundleCounts, E as EntityBundle, b as bundleCounts, c as collectEntities, e as emptyBundle } from './bundle-BgoXkWMy.js';
5
5
  export { AssetDiscoverySummary, ConflictReport, DryRunOptions, DryRunResult, FALLBACK_ASSET_BYTES, FilesystemMigrationSink, MIGRATION_WRITE_STAGES, MigrationRedirect, MigrationReport, MigrationRunMode, MigrationRunOptions, MigrationRunResult, MigrationSink, MigrationWriteStage, StorageEstimate, UploadAssetInput, UploadAssetResult, WriteFilesystemOptions, analyzeConflicts, buildMigrationReport, buildRedirectMap, bundleToCombinedJson, createFilesystemMigrationSink, detectRedirectLoops, emptyConflictReport, estimateStorage, hasBlockingConflicts, hasWarnings, portfolioMediaMatchesBundle, resolveAdapterImportSummary, runDryRun, runMigration, runMigrationFromBundle, staleUrlsFromEstimate, summarizeAssetDiscovery, writeFilesystemExport } from './sinks/index.js';
6
- export { R as RewriteInlineImageRef, a as RewriteInlineImagesOptions, b as RewriteInlineImagesResult, S as StampMigrationMediaRefsOptions, U as UploadedAssetRef, r as rewriteInlineImages, s as stampMigrationMediaRefs } from './rewrite-inline-images-BsgSquzV.js';
6
+ export { R as RewriteInlineImageRef, a as RewriteInlineImagesOptions, b as RewriteInlineImagesResult, S as StampMigrationMediaRefsOptions, U as UploadedAssetRef, r as rewriteInlineImages, s as stampMigrationMediaRefs } from './rewrite-inline-images-escjz3gT.js';
7
7
  export { ExpandMigrationMediaRefsResult, GrapesComponent, GrapesProjectSnapshot, GrapesStyleRule, HtmlToGrapesOptions, HtmlToTiptapOptions, LayoutKind, LayoutTypeMap, TiptapDoc, TiptapMark, TiptapNode, ValidateGrapesProjectSnapshotOptions, ValidateTiptapDocOptions, cssToStyles, expandMigrationMediaRefs, grapesComponentSchema, grapesProjectSnapshotSchema, grapesStyleRuleSchema, htmlToGrapes, htmlToTiptap, tiptapDocSchema, tiptapMarkSchema, tiptapNodeSchema, validateGrapesProjectSnapshot, validateTiptapDoc } from './transformers/index.js';
8
- export { C as CanonicalInlineAssetUrl, a as ContentAssetDiscovery, M as MIGRATION_MEDIA_REF_SCHEME, O as OriginUrlRewriteConfig, b as OriginUrlRewriteRule, c as buildContentMediaUrlIndex, d as buildMigrationMediaUrlIndex, e as canonicalizeInlineAssetUrl, f as createMigrationMediaRefReplaceWith, g as createWpContentGatewayRewrite, h as discoverContentAssetUrls, i as discoverContentAssets, j as discoverFeaturedAssetCandidateUrls, k as discoverRawImgSrcs, l as extractInlineImageSrcs, m as formatMigrationMediaRef, n as isLikelyImageUrl, o as isMigrationMediaRef, p as normalizeAssetUrl, q as parseMigrationMediaRef, r as resolveFeaturedContentAssetUrl, s as resolveMigrationMediaSourceId, t as rewriteOriginUrlsInText } from './media-urls-u49RCyPn.js';
8
+ export { C as CanonicalInlineAssetUrl, a as ContentAssetDiscovery, M as MIGRATION_MEDIA_REF_SCHEME, O as OriginUrlRewriteConfig, b as OriginUrlRewriteRule, c as buildContentMediaUrlIndex, d as buildMigrationMediaUrlIndex, e as canonicalizeInlineAssetUrl, f as createMigrationMediaRefReplaceWith, g as createWpContentGatewayRewrite, h as discoverContentAssetUrls, i as discoverContentAssets, j as discoverFeaturedAssetCandidateUrls, k as discoverRawImgSrcs, l as extractInlineImageSrcs, m as formatMigrationMediaRef, n as isLikelyContentAssetUrl, o as isLikelyImageUrl, p as isLikelyVideoUrl, q as isMigrationMediaRef, r as normalizeAssetUrl, s as parseMigrationMediaRef, t as resolveFeaturedContentAssetUrl, u as resolveMigrationMediaSourceId, v as rewriteOriginUrlsInText } from './media-urls-ScJvYI7b.js';
9
9
  export { linkToPath, sanitizeSlug } from './lib/index.js';
10
10
  import { z } from 'zod';
11
11
  import 'node:stream';
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  squarespaceAdapter,
14
14
  wixAdapter,
15
15
  wordpressAdapter
16
- } from "./chunk-ZKIAIP3B.js";
16
+ } from "./chunk-H23JQVJZ.js";
17
17
  import {
18
18
  normalizedAssetExifSchema,
19
19
  normalizedAssetSchema,
@@ -58,7 +58,7 @@ import {
58
58
  staleUrlsFromEstimate,
59
59
  summarizeAssetDiscovery,
60
60
  writeFilesystemExport
61
- } from "./chunk-5TRCJONX.js";
61
+ } from "./chunk-ZDQBXTIV.js";
62
62
  import {
63
63
  buildPortfolioMediaLinks,
64
64
  bundleCounts,
@@ -81,12 +81,12 @@ import {
81
81
  tiptapNodeSchema,
82
82
  validateGrapesProjectSnapshot,
83
83
  validateTiptapDoc
84
- } from "./chunk-X4TJQWZF.js";
85
- import "./chunk-S55525RD.js";
84
+ } from "./chunk-6RP7HWTY.js";
85
+ import "./chunk-PHL6U6CP.js";
86
86
  import {
87
87
  rewriteInlineImages,
88
88
  stampMigrationMediaRefs
89
- } from "./chunk-HUSXCKPI.js";
89
+ } from "./chunk-BF2AZ7S2.js";
90
90
  import "./chunk-EJTWYEAX.js";
91
91
  import {
92
92
  linkToPath,
@@ -105,14 +105,16 @@ import {
105
105
  discoverRawImgSrcs,
106
106
  extractInlineImageSrcs,
107
107
  formatMigrationMediaRef,
108
+ isLikelyContentAssetUrl,
108
109
  isLikelyImageUrl,
110
+ isLikelyVideoUrl,
109
111
  isMigrationMediaRef,
110
112
  normalizeAssetUrl,
111
113
  parseMigrationMediaRef,
112
114
  resolveFeaturedContentAssetUrl,
113
115
  resolveMigrationMediaSourceId,
114
116
  rewriteOriginUrlsInText
115
- } from "./chunk-S4GMDRGX.js";
117
+ } from "./chunk-DZI5C6KR.js";
116
118
  export {
117
119
  FALLBACK_ASSET_BYTES,
118
120
  FilesystemMigrationSink,
@@ -161,7 +163,9 @@ export {
161
163
  hasWarnings,
162
164
  htmlToGrapes,
163
165
  htmlToTiptap,
166
+ isLikelyContentAssetUrl,
164
167
  isLikelyImageUrl,
168
+ isLikelyVideoUrl,
165
169
  isMigrationMediaRef,
166
170
  isTerminalState,
167
171
  linkToPath,
@@ -1,4 +1,4 @@
1
- export { C as CanonicalInlineAssetUrl, a as ContentAssetDiscovery, M as MIGRATION_MEDIA_REF_SCHEME, O as OriginUrlRewriteConfig, b as OriginUrlRewriteRule, c as buildContentMediaUrlIndex, d as buildMigrationMediaUrlIndex, e as canonicalizeInlineAssetUrl, f as createMigrationMediaRefReplaceWith, g as createWpContentGatewayRewrite, h as discoverContentAssetUrls, i as discoverContentAssets, j as discoverFeaturedAssetCandidateUrls, k as discoverRawImgSrcs, l as extractInlineImageSrcs, m as formatMigrationMediaRef, n as isLikelyImageUrl, o as isMigrationMediaRef, p as normalizeAssetUrl, q as parseMigrationMediaRef, r as resolveFeaturedContentAssetUrl, s as resolveMigrationMediaSourceId, t as rewriteOriginUrlsInText } from '../media-urls-u49RCyPn.js';
1
+ export { C as CanonicalInlineAssetUrl, a as ContentAssetDiscovery, M as MIGRATION_MEDIA_REF_SCHEME, O as OriginUrlRewriteConfig, b as OriginUrlRewriteRule, c as buildContentMediaUrlIndex, d as buildMigrationMediaUrlIndex, e as canonicalizeInlineAssetUrl, f as createMigrationMediaRefReplaceWith, g as createWpContentGatewayRewrite, h as discoverContentAssetUrls, i as discoverContentAssets, j as discoverFeaturedAssetCandidateUrls, k as discoverRawImgSrcs, l as extractInlineImageSrcs, m as formatMigrationMediaRef, n as isLikelyContentAssetUrl, o as isLikelyImageUrl, p as isLikelyVideoUrl, q as isMigrationMediaRef, r as normalizeAssetUrl, s as parseMigrationMediaRef, t as resolveFeaturedContentAssetUrl, u as resolveMigrationMediaSourceId, v as rewriteOriginUrlsInText } from '../media-urls-ScJvYI7b.js';
2
2
 
3
3
  /** Lowercase URL-safe slug from WordPress post_name or title. */
4
4
  declare function sanitizeSlug(raw: string): string;
package/dist/lib/index.js CHANGED
@@ -16,14 +16,16 @@ import {
16
16
  discoverRawImgSrcs,
17
17
  extractInlineImageSrcs,
18
18
  formatMigrationMediaRef,
19
+ isLikelyContentAssetUrl,
19
20
  isLikelyImageUrl,
21
+ isLikelyVideoUrl,
20
22
  isMigrationMediaRef,
21
23
  normalizeAssetUrl,
22
24
  parseMigrationMediaRef,
23
25
  resolveFeaturedContentAssetUrl,
24
26
  resolveMigrationMediaSourceId,
25
27
  rewriteOriginUrlsInText
26
- } from "../chunk-S4GMDRGX.js";
28
+ } from "../chunk-DZI5C6KR.js";
27
29
  export {
28
30
  MIGRATION_MEDIA_REF_SCHEME,
29
31
  buildContentMediaUrlIndex,
@@ -37,7 +39,9 @@ export {
37
39
  discoverRawImgSrcs,
38
40
  extractInlineImageSrcs,
39
41
  formatMigrationMediaRef,
42
+ isLikelyContentAssetUrl,
40
43
  isLikelyImageUrl,
44
+ isLikelyVideoUrl,
41
45
  isMigrationMediaRef,
42
46
  linkToPath,
43
47
  normalizeAssetUrl,
@@ -11,7 +11,7 @@ declare function rewriteOriginUrlsInText(text: string, config: OriginUrlRewriteC
11
11
  /** Build a rule that rewrites API-gateway `/prod/wp-content/` paths to a public origin. */
12
12
  declare function createWpContentGatewayRewrite(gatewayBase: string, publicOrigin: string): OriginUrlRewriteConfig;
13
13
  interface ContentAssetDiscovery {
14
- /** Network-resolvable image paths (`<img>`, backgrounds, shortcode `image=` attrs, …). */
14
+ /** Network-resolvable image and self-hosted video paths (`<img>`, `<video>`, `data-video-url`, …). */
15
15
  urls: string[];
16
16
  /**
17
17
  * WordPress attachment post ids referenced in content without an inline URL in this
@@ -25,6 +25,10 @@ declare function discoverRawImgSrcs(content: string): string[];
25
25
  declare function normalizeAssetUrl(raw: string): string | undefined;
26
26
  /** Heuristic: URL likely points at a raster/vector image asset, not a page link. */
27
27
  declare function isLikelyImageUrl(url: string): boolean;
28
+ /** Heuristic: URL likely points at a self-hosted video asset (mp4/webm/ogg/mov), not a page or embed. */
29
+ declare function isLikelyVideoUrl(url: string): boolean;
30
+ /** Image or self-hosted video URL suitable for vault ingest (not oEmbed / page links). */
31
+ declare function isLikelyContentAssetUrl(url: string): boolean;
28
32
  /**
29
33
  * Ordered featured-image candidates when `_thumbnail_id` is missing — heroes
30
34
  * (`data-bg-image`, CSS backgrounds, `bg_image=`) before inline assets; within
@@ -35,15 +39,15 @@ declare function discoverFeaturedAssetCandidateUrls(content: string): string[];
35
39
  /** Best featured-image URL from post/page HTML when attachment id is unavailable. */
36
40
  declare function resolveFeaturedContentAssetUrl(content: string): string | undefined;
37
41
  /**
38
- * Generic content-discovery pass: collect resolvable image URLs and attachment ids
42
+ * Generic content-discovery pass: collect resolvable image/video URLs and attachment ids
39
43
  * that still need an index / REST / crawl resolution step.
40
44
  */
41
45
  declare function discoverContentAssets(content: string): ContentAssetDiscovery;
42
46
  /**
43
- * Generic content-discovery pass: collect image URLs from HTML `<img>` tags,
44
- * section hero markers (`data-bg-image`), inline CSS backgrounds, and common
45
- * shortcode/builder attributes (`src=`, `image=`, `bg_image=`, …) without
46
- * parsing builder-specific structure (Tatsu, Elementor, etc.).
47
+ * Generic content-discovery pass: collect image and self-hosted video URLs from HTML
48
+ * `<img>` / `<video>` / `<source>`, section hero markers (`data-bg-image`, `data-video-url`),
49
+ * inline CSS backgrounds, and common shortcode/builder attributes without parsing
50
+ * builder-specific structure (Tatsu, Elementor, etc.).
47
51
  */
48
52
  declare function discoverContentAssetUrls(content: string): string[];
49
53
  /** @deprecated Use discoverContentAssetUrls — kept for call-site clarity during transition. */
@@ -85,4 +89,4 @@ declare function buildContentMediaUrlIndex(entries: Iterable<{
85
89
  sourceId: string;
86
90
  }>, originUrlRewrite?: OriginUrlRewriteConfig): Map<string, string>;
87
91
 
88
- export { type CanonicalInlineAssetUrl as C, MIGRATION_MEDIA_REF_SCHEME as M, type OriginUrlRewriteConfig as O, type ContentAssetDiscovery as a, type OriginUrlRewriteRule as b, buildContentMediaUrlIndex as c, buildMigrationMediaUrlIndex as d, canonicalizeInlineAssetUrl as e, createMigrationMediaRefReplaceWith as f, createWpContentGatewayRewrite as g, discoverContentAssetUrls as h, discoverContentAssets as i, discoverFeaturedAssetCandidateUrls as j, discoverRawImgSrcs as k, extractInlineImageSrcs as l, formatMigrationMediaRef as m, isLikelyImageUrl as n, isMigrationMediaRef as o, normalizeAssetUrl as p, parseMigrationMediaRef as q, resolveFeaturedContentAssetUrl as r, resolveMigrationMediaSourceId as s, rewriteOriginUrlsInText as t };
92
+ export { type CanonicalInlineAssetUrl as C, MIGRATION_MEDIA_REF_SCHEME as M, type OriginUrlRewriteConfig as O, type ContentAssetDiscovery as a, type OriginUrlRewriteRule as b, buildContentMediaUrlIndex as c, buildMigrationMediaUrlIndex as d, canonicalizeInlineAssetUrl as e, createMigrationMediaRefReplaceWith as f, createWpContentGatewayRewrite as g, discoverContentAssetUrls as h, discoverContentAssets as i, discoverFeaturedAssetCandidateUrls as j, discoverRawImgSrcs as k, extractInlineImageSrcs as l, formatMigrationMediaRef as m, isLikelyContentAssetUrl as n, isLikelyImageUrl as o, isLikelyVideoUrl as p, isMigrationMediaRef as q, normalizeAssetUrl as r, parseMigrationMediaRef as s, resolveFeaturedContentAssetUrl as t, resolveMigrationMediaSourceId as u, rewriteOriginUrlsInText as v };
@@ -1,4 +1,4 @@
1
- import { O as OriginUrlRewriteConfig } from './media-urls-u49RCyPn.js';
1
+ import { O as OriginUrlRewriteConfig } from './media-urls-ScJvYI7b.js';
2
2
 
3
3
  interface RewriteInlineImageRef {
4
4
  originalSrc: string;
@@ -26,7 +26,7 @@ interface RewriteInlineImagesResult {
26
26
  referencedSources: string[];
27
27
  unresolved: string[];
28
28
  }
29
- /** Rewrite `<img src>` / `srcset`, `data-bg-image`, and inline CSS backgrounds using uploaded asset targets. */
29
+ /** Rewrite `<img src>` / `srcset`, `data-bg-image`, `data-video-url`, `<video>` / `<source src>`, and inline CSS backgrounds. */
30
30
  declare function rewriteInlineImages(html: string, options: RewriteInlineImagesOptions, uploadedBySourceId: Map<string, UploadedAssetRef>): RewriteInlineImagesResult;
31
31
  interface StampMigrationMediaRefsOptions {
32
32
  /** Pre-built url/pathname → sourceId map (from attachments + inline assets). */
@@ -1,9 +1,9 @@
1
1
  import { d as NormalizedCategory, e as NormalizedTag, b as NormalizedAsset, c as NormalizedPortfolio, N as NormalizedPost, a as NormalizedPage, l as PortfolioMediaLink, E as EntityKey, f as NormalizedEntity, g as MigrationPlatform, W as WxrImportSummary, M as MigrationAdapter } from '../types-Bicgdp4Z.js';
2
2
  import { Readable } from 'node:stream';
3
- import { a as RewriteInlineImagesOptions } from '../rewrite-inline-images-BsgSquzV.js';
4
- export { b as RewriteInlineImagesResult, r as rewriteInlineImages } from '../rewrite-inline-images-BsgSquzV.js';
3
+ import { a as RewriteInlineImagesOptions } from '../rewrite-inline-images-escjz3gT.js';
4
+ export { b as RewriteInlineImagesResult, r as rewriteInlineImages } from '../rewrite-inline-images-escjz3gT.js';
5
5
  import { E as EntityBundle } from '../bundle-BgoXkWMy.js';
6
- import '../media-urls-u49RCyPn.js';
6
+ import '../media-urls-ScJvYI7b.js';
7
7
 
8
8
  interface CreatePostResult {
9
9
  targetId: string;
@@ -20,13 +20,13 @@ import {
20
20
  staleUrlsFromEstimate,
21
21
  summarizeAssetDiscovery,
22
22
  writeFilesystemExport
23
- } from "../chunk-5TRCJONX.js";
23
+ } from "../chunk-ZDQBXTIV.js";
24
24
  import "../chunk-PD5AZX3B.js";
25
25
  import {
26
26
  rewriteInlineImages
27
- } from "../chunk-HUSXCKPI.js";
27
+ } from "../chunk-BF2AZ7S2.js";
28
28
  import "../chunk-XRCF73DA.js";
29
- import "../chunk-S4GMDRGX.js";
29
+ import "../chunk-DZI5C6KR.js";
30
30
  export {
31
31
  FALLBACK_ASSET_BYTES,
32
32
  FilesystemMigrationSink,
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { n as ValidationResult } from '../types-Bicgdp4Z.js';
3
- export { R as RewriteInlineImageRef, a as RewriteInlineImagesOptions, b as RewriteInlineImagesResult, S as StampMigrationMediaRefsOptions, U as UploadedAssetRef, r as rewriteInlineImages, s as stampMigrationMediaRefs } from '../rewrite-inline-images-BsgSquzV.js';
4
- export { d as buildMigrationMediaUrlIndex } from '../media-urls-u49RCyPn.js';
3
+ export { R as RewriteInlineImageRef, a as RewriteInlineImagesOptions, b as RewriteInlineImagesResult, S as StampMigrationMediaRefsOptions, U as UploadedAssetRef, r as rewriteInlineImages, s as stampMigrationMediaRefs } from '../rewrite-inline-images-escjz3gT.js';
4
+ export { d as buildMigrationMediaUrlIndex } from '../media-urls-ScJvYI7b.js';
5
5
 
6
6
  type LayoutKind = "section" | "row" | "column";
7
7
  /** Map OSS-2 `data-layout` markers to Grapes component types (host may override). */
@@ -11,15 +11,15 @@ import {
11
11
  tiptapNodeSchema,
12
12
  validateGrapesProjectSnapshot,
13
13
  validateTiptapDoc
14
- } from "../chunk-X4TJQWZF.js";
15
- import "../chunk-S55525RD.js";
14
+ } from "../chunk-6RP7HWTY.js";
15
+ import "../chunk-PHL6U6CP.js";
16
16
  import {
17
17
  rewriteInlineImages,
18
18
  stampMigrationMediaRefs
19
- } from "../chunk-HUSXCKPI.js";
19
+ } from "../chunk-BF2AZ7S2.js";
20
20
  import {
21
21
  buildMigrationMediaUrlIndex
22
- } from "../chunk-S4GMDRGX.js";
22
+ } from "../chunk-DZI5C6KR.js";
23
23
  export {
24
24
  buildMigrationMediaUrlIndex,
25
25
  cssToStyles,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artinstack/migrator",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "Stateless content normalizer and migration framework — WordPress, SmugMug, Squarespace → platform-agnostic schema",
5
5
  "license": "MIT",
6
6
  "author": "ArtInStack",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/transformers/rewrite-inline-images.ts","../src/parsers/wordpress/builders/registry.ts"],"sourcesContent":["import * as cheerio from \"cheerio\";\n\nimport {\n buildMigrationMediaUrlIndex,\n createMigrationMediaRefReplaceWith,\n isMigrationMediaRef,\n normalizeAssetUrl,\n resolveMigrationMediaSourceId,\n type OriginUrlRewriteConfig,\n} from \"../lib/media-urls.js\";\n\nexport interface RewriteInlineImageRef {\n originalSrc: string;\n sourceAssetId?: string;\n}\n\nexport interface UploadedAssetRef {\n targetId: string;\n publicUrl?: string;\n}\n\nexport interface RewriteInlineImagesOptions {\n resolveAsset: (src: string) => RewriteInlineImageRef | undefined;\n /**\n * Replace a resolved source id with a migration ref or CDN URL.\n * When omitted, defaults to OSS-14 `artinstack-migration://asset/…` refs.\n */\n replaceWith?: (ref: RewriteInlineImageRef, uploaded?: UploadedAssetRef) => string;\n /**\n * When true, skip URLs that cannot be matched to an uploaded vault target.\n * Default: false when using migration refs; true when a custom `replaceWith` is supplied.\n */\n requireUploaded?: boolean;\n}\n\nexport interface RewriteInlineImagesResult {\n html: string;\n referencedSources: string[];\n unresolved: string[];\n}\n\n/** Inline CSS `background` / `background-image: url(…)` (quoted or bare). */\nconst BACKGROUND_IMAGE_URL_PATTERN =\n /background(?:-image)?\\s*:[^;]*?url\\s*\\(\\s*(['\"]?)([^'\")]+)\\1\\s*\\)/gi;\n\nfunction resolveRewriteOptions(\n options: RewriteInlineImagesOptions,\n): Required<Pick<RewriteInlineImagesOptions, \"replaceWith\" | \"requireUploaded\">> {\n const replaceWith = options.replaceWith ?? createMigrationMediaRefReplaceWith();\n const requireUploaded = options.requireUploaded ?? Boolean(options.replaceWith);\n return { replaceWith, requireUploaded };\n}\n\nfunction tryRewriteUrl(\n src: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n referencedSources: Set<string>,\n unresolved: Set<string>,\n): string | undefined {\n const normalized = normalizeAssetUrl(src);\n if (!normalized) return undefined;\n\n if (isMigrationMediaRef(normalized)) {\n referencedSources.add(normalized);\n return normalized;\n }\n\n referencedSources.add(normalized);\n const ref = options.resolveAsset(normalized);\n if (!ref?.sourceAssetId) {\n unresolved.add(normalized);\n return undefined;\n }\n\n const { replaceWith, requireUploaded } = resolveRewriteOptions(options);\n const uploaded = uploadedBySourceId.get(ref.sourceAssetId);\n if (requireUploaded && !uploaded) {\n unresolved.add(normalized);\n return undefined;\n }\n\n return replaceWith(ref, uploaded);\n}\n\nfunction rewriteBackgroundUrlsInStyle(\n style: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n referencedSources: Set<string>,\n unresolved: Set<string>,\n): string {\n return style.replace(BACKGROUND_IMAGE_URL_PATTERN, (full, quote: string, rawUrl: string) => {\n const replaced = tryRewriteUrl(rawUrl.trim(), options, uploadedBySourceId, referencedSources, unresolved);\n if (!replaced) return full;\n\n const urlCall = quote\n ? `url(${quote}${replaced}${quote})`\n : `url(${replaced})`;\n return full.replace(/url\\s*\\(\\s*(['\"]?)([^'\")]+)\\1\\s*\\)/i, urlCall);\n });\n}\n\nfunction rewriteSrcset(\n srcset: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n referencedSources: Set<string>,\n unresolved: Set<string>,\n): string {\n return srcset\n .split(\",\")\n .map((entry) => {\n const trimmed = entry.trim();\n if (!trimmed) return entry;\n const [urlPart, descriptor] = trimmed.split(/\\s+/, 2);\n const replaced = tryRewriteUrl(urlPart ?? \"\", options, uploadedBySourceId, referencedSources, unresolved);\n if (!replaced) return entry;\n return descriptor ? `${replaced} ${descriptor}` : replaced;\n })\n .join(\", \");\n}\n\n/** Rewrite `<img src>` / `srcset`, `data-bg-image`, and inline CSS backgrounds using uploaded asset targets. */\nexport function rewriteInlineImages(\n html: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n): RewriteInlineImagesResult {\n if (!html.trim()) {\n return { html, referencedSources: [], unresolved: [] };\n }\n\n const $ = cheerio.load(html, { xml: false });\n const referencedSources = new Set<string>();\n const unresolved = new Set<string>();\n\n $(\"img\").each((_, element) => {\n const img = $(element);\n const src = img.attr(\"src\")?.trim();\n if (src && !src.startsWith(\"data:\")) {\n const replaced = tryRewriteUrl(src, options, uploadedBySourceId, referencedSources, unresolved);\n if (replaced) img.attr(\"src\", replaced);\n }\n\n const srcset = img.attr(\"srcset\")?.trim();\n if (srcset) {\n img.attr(\"srcset\", rewriteSrcset(srcset, options, uploadedBySourceId, referencedSources, unresolved));\n }\n });\n\n $(\"[data-bg-image]\").each((_, element) => {\n const node = $(element);\n const bgImage = node.attr(\"data-bg-image\")?.trim();\n if (!bgImage || bgImage.startsWith(\"data:\")) return;\n const replaced = tryRewriteUrl(bgImage, options, uploadedBySourceId, referencedSources, unresolved);\n if (replaced) node.attr(\"data-bg-image\", replaced);\n });\n\n $(\"[style]\").each((_, element) => {\n const node = $(element);\n const style = node.attr(\"style\");\n if (!style?.includes(\"background\")) return;\n const rewritten = rewriteBackgroundUrlsInStyle(\n style,\n options,\n uploadedBySourceId,\n referencedSources,\n unresolved,\n );\n if (rewritten !== style) node.attr(\"style\", rewritten);\n });\n\n return {\n html: $.root().html() ?? html,\n referencedSources: [...referencedSources],\n unresolved: [...unresolved],\n };\n}\n\nexport interface StampMigrationMediaRefsOptions {\n /** Pre-built url/pathname → sourceId map (from attachments + inline assets). */\n urlToSourceId: Map<string, string>;\n /** Canonicalize lookup keys during stamp (OSS-15). */\n originUrlRewrite?: OriginUrlRewriteConfig;\n replaceWith?: RewriteInlineImagesOptions[\"replaceWith\"];\n requireUploaded?: boolean;\n}\n\n/**\n * OSS-14 — replace resolved `wp-content/uploads` URLs with `artinstack-migration://asset/…`\n * refs. Does not invent refs for unknown URLs (left unchanged + listed in `unresolved`).\n */\nexport function stampMigrationMediaRefs(\n html: string,\n options: StampMigrationMediaRefsOptions,\n): RewriteInlineImagesResult {\n return rewriteInlineImages(\n html,\n {\n resolveAsset: (src) => {\n const sourceAssetId = resolveMigrationMediaSourceId(\n src,\n options.urlToSourceId,\n options.originUrlRewrite,\n );\n if (!sourceAssetId) return undefined;\n return { originalSrc: src, sourceAssetId };\n },\n replaceWith: options.replaceWith,\n requireUploaded: options.requireUploaded ?? false,\n },\n new Map(),\n );\n}\n\n/** Build a url index from attachment rows and/or normalized assets. */\nexport { buildMigrationMediaUrlIndex };\n","export type BuilderHtmlTag = \"img\" | \"video\" | \"iframe\";\nexport type TextHtmlTag = \"p\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\";\n\n/** Bucket 1 — shortcodes with asset URL params → standard HTML. */\nexport interface BuilderUrlRule {\n shortcodePrefix: string;\n urlParams: string[];\n tag: BuilderHtmlTag;\n}\n\n/** Bucket 1 — shortcodes with text params → semantic HTML. */\nexport interface BuilderTextRule {\n shortcodePrefix: string;\n fields: { param: string; tag: TextHtmlTag }[];\n}\n\n/** Bucket 1 — shortcodes with inner HTML (+ optional image param). */\nexport interface BuilderWrapperRule {\n shortcodePrefix: string;\n urlParams?: string[];\n}\n\n/** Bucket 1 — image-based icon modules (`icon_image` param) → linked `<img>`. */\nexport interface BuilderIconImageRule {\n shortcodePrefix: string;\n imageParam: string;\n hrefParam?: string;\n}\n\n/** Bucket 1 — dynamic embeds replaced with a static migration placeholder. */\nexport interface BuilderPlaceholderRule {\n shortcodePrefix: string;\n html: string;\n}\n\n/** Profile A — prefixed namespace tokens (Tatsu, Divi, WPBakery, …). */\nexport interface PrefixedLayoutMap {\n kind: \"prefixed\";\n sectionRegex: RegExp;\n sectionCloseRegex: RegExp;\n rowRegex: RegExp;\n rowCloseRegex: RegExp;\n columnRegex: RegExp;\n columnCloseRegex: RegExp;\n bgParamName?: string;\n colsParamName?: string;\n}\n\n/** Profile B — legacy Blox fractional column tokens (`one_third`, `one_half`, …). */\nexport interface FractionalLayoutMap {\n kind: \"fractional\";\n sectionRegex: RegExp;\n sectionCloseRegex: RegExp;\n rowRegex: RegExp;\n rowCloseRegex: RegExp;\n columnTokens: string[];\n columnOpenRegexes: RegExp[];\n columnCloseRegexes: RegExp[];\n columnWidths: Record<string, string>;\n bgParamName?: string;\n}\n\n/** Profile C — multiple tokens per layout role (Blox prefixed, WPBakery inner columns, …). */\nexport interface ExtendedPrefixedLayoutLevel {\n role: \"section\" | \"row\" | \"column\";\n tokens: string[];\n bgParamName?: string;\n colsParamName?: string;\n widthParamName?: string;\n}\n\nexport interface ExtendedPrefixedLayoutMap {\n kind: \"extended-prefixed\";\n levels: ExtendedPrefixedLayoutLevel[];\n}\n\nexport type StructuralLayoutMap =\n | PrefixedLayoutMap\n | FractionalLayoutMap\n | ExtendedPrefixedLayoutMap;\n\nfunction layoutEscapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction shortcodeOpenRegex(token: string): RegExp {\n return new RegExp(`\\\\[${layoutEscapeRegExp(token)}\\\\b([^\\\\]]*)\\\\]`, \"gi\");\n}\n\nfunction shortcodeCloseRegex(token: string): RegExp {\n return new RegExp(`\\\\[\\\\/${layoutEscapeRegExp(token)}\\\\b[^\\\\]]*\\\\]`, \"gi\");\n}\n\nconst FRACTIONAL_COLUMN_WIDTHS: Record<string, string> = {\n one_col: \"100%\",\n one_half: \"50%\",\n one_third: \"33.33%\",\n two_third: \"66.67%\",\n two_thirds: \"66.67%\",\n one_fourth: \"25%\",\n three_fourth: \"75%\",\n three_fourths: \"75%\",\n};\n\nexport function parseFractionalColumnWidth(token: string): string | undefined {\n return FRACTIONAL_COLUMN_WIDTHS[token];\n}\n\n/** Profile A — section/row/column share a static namespace prefix. */\nexport function prefixedLayoutMap(config: {\n section: string;\n row: string;\n column: string;\n bgParamName?: string;\n colsParamName?: string;\n}): PrefixedLayoutMap {\n return {\n kind: \"prefixed\",\n sectionRegex: shortcodeOpenRegex(config.section),\n sectionCloseRegex: shortcodeCloseRegex(config.section),\n rowRegex: shortcodeOpenRegex(config.row),\n rowCloseRegex: shortcodeCloseRegex(config.row),\n columnRegex: shortcodeOpenRegex(config.column),\n columnCloseRegex: shortcodeCloseRegex(config.column),\n bgParamName: config.bgParamName,\n colsParamName: config.colsParamName,\n };\n}\n\n/** Profile B — legacy Blox/Oshine mathematical column shortcodes. */\n/** Profile C — map several shortcode names per section/row/column role (longest token first). */\nexport function extendedPrefixedLayoutMap(\n levels: ExtendedPrefixedLayoutLevel[],\n): ExtendedPrefixedLayoutMap {\n return { kind: \"extended-prefixed\", levels };\n}\n\nexport function fractionalLayoutMap(config: {\n section: string;\n row: string;\n columns: string[];\n bgParamName?: string;\n}): FractionalLayoutMap {\n const columnWidths: Record<string, string> = {};\n for (const token of config.columns) {\n const width = parseFractionalColumnWidth(token);\n if (width) columnWidths[token] = width;\n }\n\n return {\n kind: \"fractional\",\n sectionRegex: shortcodeOpenRegex(config.section),\n sectionCloseRegex: shortcodeCloseRegex(config.section),\n rowRegex: shortcodeOpenRegex(config.row),\n rowCloseRegex: shortcodeCloseRegex(config.row),\n columnTokens: config.columns,\n columnOpenRegexes: config.columns.map(shortcodeOpenRegex),\n columnCloseRegexes: config.columns.map(shortcodeCloseRegex),\n columnWidths,\n bgParamName: config.bgParamName,\n };\n}\n\n/** Per builder-family registry entry — declarative map executed by the flatten engine. */\nexport interface BuilderThemeConfig {\n id: string;\n detect: RegExp;\n layoutMap?: StructuralLayoutMap;\n /** Additional layout maps applied after `layoutMap` (e.g. Blox prefixed + legacy fractional). */\n layoutMaps?: StructuralLayoutMap[];\n urlRules?: BuilderUrlRule[];\n textRules?: BuilderTextRule[];\n wrapperRules?: BuilderWrapperRule[];\n iconImageRules?: BuilderIconImageRule[];\n placeholderRules?: BuilderPlaceholderRule[];\n scaffoldingPrefixes?: string[];\n legacyScaffoldingTokens?: string[];\n}\n\n/** @deprecated Alias — families not themes. */\nexport type BuilderFamilyConfig = BuilderThemeConfig;\n\n// ---------------------------------------------------------------------------\n// Widget registry (OSS-12 / OSS-16) — cross-builder; not BuilderThemeConfig\n// ---------------------------------------------------------------------------\n\n/** Keeps empty widget stubs from collapsing during cheerio text sweeps. */\nexport const WP_WIDGET_PLACEHOLDER = \"\\u200B\";\n\nexport interface WordPressContactFormWidgetRule {\n /** Shortcode tag name (e.g. `contact-form-7`). */\n tag: string;\n /** Value for `data-wp-form-source`. */\n source: string;\n /** Attribute holding the form id (e.g. `id`). */\n idParam: string;\n}\n\n/** Declarative widget tables consumed by `flattenWordPressWidgets()` in flatten.ts. */\nexport interface WordPressWidgetRegistry {\n mapShortcodePrefixes: readonly string[];\n contactFormRules: readonly WordPressContactFormWidgetRule[];\n videoShortcodePrefixes: readonly string[];\n /** Core / plugin portfolio dynamic shortcode tag. */\n portfolioShortcode: string;\n /** Builder blog roll modules (Tatsu/Oshine `[blog]`, etc.). */\n blogShortcodeTags: readonly string[];\n /** Testimonials carousel/list wrapper shortcodes (Oshine `[testimonials]`, etc.). */\n testimonialsWrapperTags: readonly string[];\n /** Inner testimonial item shortcode tag. */\n testimonialItemTag: string;\n /** In-body RevSlider / MasterSlider shortcodes → slider widget stub (alias only). */\n sliderShortcodeTags: readonly string[];\n /** WordPress core gallery shortcode tag (`ids=` split handled in engine). */\n galleryShortcode: string;\n /** Builder/plugin gallery shortcodes with explicit `ids=` attachment lists (OSS-12). */\n idGalleryShortcodes: readonly string[];\n}\n\nexport const WORDPRESS_WIDGET_REGISTRY: WordPressWidgetRegistry = {\n mapShortcodePrefixes: [\n \"blox_gmap\",\n \"tatsu_gmap\",\n \"tatsu_map\",\n \"et_pb_map\",\n \"vc_gmaps\",\n \"vc_map\",\n ],\n contactFormRules: [\n { tag: \"contact-form-7\", source: \"contact-form-7\", idParam: \"id\" },\n { tag: \"contact_form\", source: \"contact-form-7\", idParam: \"id\" },\n { tag: \"gravityform\", source: \"gravityforms\", idParam: \"id\" },\n { tag: \"ninja_form\", source: \"ninja-forms\", idParam: \"id\" },\n { tag: \"wpforms\", source: \"wpforms\", idParam: \"id\" },\n ],\n videoShortcodePrefixes: [\n \"youtube\",\n \"vimeo\",\n \"embed\",\n \"tatsu_video\",\n \"et_pb_video\",\n \"vc_video\",\n ],\n portfolioShortcode: \"portfolio\",\n blogShortcodeTags: [\"blog\", \"recent_posts\"],\n testimonialsWrapperTags: [\"testimonials\"],\n testimonialItemTag: \"testimonial\",\n sliderShortcodeTags: [\"rev_slider\", \"masterslider\"],\n galleryShortcode: \"gallery\",\n idGalleryShortcodes: [\"oshine_gallery\", \"vc_gallery\", \"nggallery\"],\n};\n\n/** Shortcodes that cannot become static HTML — reported in conflicts, never stripped. */\nexport const UNRESOLVABLE_SHORTCODE_PREFIXES = [\n \"woocommerce_cart\",\n \"woocommerce_checkout\",\n \"woocommerce_my_account\",\n] as const;\n\nexport const WORDPRESS_BUILDER_REGISTRY: BuilderThemeConfig[] = [\n {\n id: \"tatsu\",\n detect: /\\[(?:\\/)?tatsu_/i,\n layoutMap: prefixedLayoutMap({\n section: \"tatsu_section\",\n row: \"tatsu_row\",\n column: \"tatsu_column\",\n bgParamName: \"bg_image\",\n colsParamName: \"layout\",\n }),\n wrapperRules: [\n { shortcodePrefix: \"tatsu_text\" },\n { shortcodePrefix: \"tatsu_inline_text\" },\n { shortcodePrefix: \"tatsu_text_with_shortcodes\" },\n { shortcodePrefix: \"tatsu_icon_group\" },\n ],\n urlRules: [\n { shortcodePrefix: \"tatsu_image\", urlParams: [\"image\", \"url\", \"src\"], tag: \"img\" },\n { shortcodePrefix: \"tatsu_single_image\", urlParams: [\"image\", \"url\", \"src\"], tag: \"img\" },\n ],\n iconImageRules: [\n { shortcodePrefix: \"tatsu_icon\", imageParam: \"icon_image\", hrefParam: \"href\" },\n ],\n scaffoldingPrefixes: [\"tatsu_\"],\n },\n {\n id: \"divi\",\n detect: /\\[(?:\\/)?et_pb_/i,\n layoutMap: prefixedLayoutMap({\n section: \"et_pb_section\",\n row: \"et_pb_row\",\n column: \"et_pb_column\",\n bgParamName: \"background_image\",\n }),\n urlRules: [{ shortcodePrefix: \"et_pb_image\", urlParams: [\"src\", \"url\"], tag: \"img\" }],\n scaffoldingPrefixes: [\"et_pb_\"],\n },\n {\n id: \"wpbakery\",\n detect: /\\[(?:\\/)?vc_/i,\n layoutMap: extendedPrefixedLayoutMap([\n { role: \"section\", tokens: [\"vc_section\"], bgParamName: \"bg_image\" },\n { role: \"row\", tokens: [\"vc_row\"], colsParamName: \"layout\" },\n { role: \"column\", tokens: [\"vc_column_inner\", \"vc_column\"], widthParamName: \"width\" },\n ]),\n urlRules: [\n { shortcodePrefix: \"vc_single_image\", urlParams: [\"image\", \"src\", \"url\"], tag: \"img\" },\n ],\n scaffoldingPrefixes: [\"vc_\"],\n },\n {\n id: \"fusion\",\n detect: /\\[(?:\\/)?fusion_/i,\n layoutMap: prefixedLayoutMap({\n section: \"fusion_builder_container\",\n row: \"fusion_builder_row\",\n column: \"fusion_builder_column\",\n bgParamName: \"background_image\",\n }),\n scaffoldingPrefixes: [\"fusion_\"],\n },\n {\n id: \"beaver\",\n detect: /\\[(?:\\/)?fl_(?:row|col|builder)/i,\n layoutMap: extendedPrefixedLayoutMap([\n { role: \"row\", tokens: [\"fl_row\"] },\n { role: \"column\", tokens: [\"fl_col\"] },\n ]),\n scaffoldingPrefixes: [\"fl_\"],\n },\n {\n id: \"elementor\",\n detect: /\\[(?:\\/)?elementor[-_]/i,\n urlRules: [\n { shortcodePrefix: \"elementor-widget\", urlParams: [\"url\", \"src\", \"image\"], tag: \"img\" },\n ],\n scaffoldingPrefixes: [\"elementor_\"],\n },\n {\n id: \"oshine\",\n detect:\n /\\[(?:special_sub_title|special_heading5|blox_\\w+|grid_content|grids|testimonial\\b|portfolio\\b|recent_posts\\b|animate_icon\\w*|section\\b|row\\b|one_col|one_third|one_half|one_fourth|two_third|three_fourth|text\\b)/i,\n layoutMap: fractionalLayoutMap({\n section: \"section\",\n row: \"row\",\n columns: [\n \"one_col\",\n \"one_third\",\n \"two_third\",\n \"two_thirds\",\n \"one_half\",\n \"one_fourth\",\n \"three_fourth\",\n \"three_fourths\",\n ],\n bgParamName: \"bg_image\",\n }),\n layoutMaps: [\n extendedPrefixedLayoutMap([\n { role: \"section\", tokens: [\"blox_row\"], bgParamName: \"bg_image\" },\n { role: \"row\", tokens: [\"blox_row_inner\"], colsParamName: \"columns\" },\n {\n role: \"column\",\n tokens: [\"blox_column_inner\", \"blox_column\"],\n widthParamName: \"width\",\n },\n ]),\n ],\n textRules: [\n {\n shortcodePrefix: \"special_sub_title\",\n fields: [{ param: \"title_content\", tag: \"p\" }],\n },\n {\n shortcodePrefix: \"special_heading5\",\n fields: [\n { param: \"title_content\", tag: \"h2\" },\n { param: \"caption_content\", tag: \"h4\" },\n ],\n },\n ],\n wrapperRules: [\n { shortcodePrefix: \"grid_content\" },\n { shortcodePrefix: \"blox_text\" },\n ],\n urlRules: [\n { shortcodePrefix: \"blox_image\", urlParams: [\"image\", \"img\", \"src\", \"url\"], tag: \"img\" },\n ],\n scaffoldingPrefixes: [\"blox_\", \"animate_icon\"],\n legacyScaffoldingTokens: [\"text\", \"icon\", \"linebreak\", \"grids\", \"testimonials\"],\n },\n];\n\n/** @deprecated Use urlRules on BuilderThemeConfig — kept for type migration clarity. */\nexport type BuilderContentRule = BuilderUrlRule;\n"],"mappings":"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","names":[]}