@artinstack/migrator 0.1.15 → 0.1.17

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.
@@ -2,7 +2,7 @@ import {
2
2
  WORDPRESS_BUILDER_REGISTRY,
3
3
  WORDPRESS_WIDGET_REGISTRY,
4
4
  WP_WIDGET_PLACEHOLDER
5
- } from "./chunk-LQFNO26V.js";
5
+ } from "./chunk-M6NY4OT7.js";
6
6
  import {
7
7
  normalizeAssetUrl
8
8
  } from "./chunk-DZI5C6KR.js";
@@ -323,6 +323,32 @@ function convertWrapperRule(content, rule) {
323
323
  function isPlaceholderImageUrl(url) {
324
324
  return /placehold\.it|placeholder\.com|via\.placeholder/i.test(url);
325
325
  }
326
+ function resolveLinkRuleParams(params, rule) {
327
+ let text = extractQuotedParam(params, rule.textParam) ?? extractBareOrQuotedParam(params, rule.textParam);
328
+ let url = extractQuotedParam(params, rule.urlParam) ?? extractBareOrQuotedParam(params, rule.urlParam);
329
+ const moduleKey = extractBareOrQuotedParam(params, "key");
330
+ if (moduleKey && activeTatsuContext?.modulesByKey.has(moduleKey)) {
331
+ const jsonAtts = activeTatsuContext.modulesByKey.get(moduleKey);
332
+ if (!text) text = resolveTatsuJsonScalar(jsonAtts[rule.textParam]);
333
+ if (!url) url = resolveTatsuJsonScalar(jsonAtts[rule.urlParam]);
334
+ }
335
+ return { text, url };
336
+ }
337
+ function convertLinkRule(content, rule) {
338
+ const prefix = escapeRegExp(rule.shortcodePrefix);
339
+ const pattern = new RegExp(
340
+ `\\[${prefix}\\b([^\\]]*)\\]\\s*(?:\\[\\/${prefix}\\b[^\\]]*\\])?`,
341
+ "gi"
342
+ );
343
+ return content.replace(pattern, (_, params) => {
344
+ const { text, url } = resolveLinkRuleParams(params, rule);
345
+ if (!text?.trim() && !url?.trim()) return "";
346
+ const label = text?.trim() || "Link";
347
+ const href = url?.trim() || "#";
348
+ const classAttr = rule.className ? ` class="${escapeLayoutAttr(rule.className)}"` : "";
349
+ return `<a href="${escapeLayoutAttr(href)}"${classAttr}>${escapeHtmlText(label)}</a>`;
350
+ });
351
+ }
326
352
  function convertIconImageRule(content, rule) {
327
353
  const prefix = escapeRegExp(rule.shortcodePrefix);
328
354
  const pattern = new RegExp(
@@ -494,6 +520,22 @@ function emitVideoWidgetFromParams(params, inner) {
494
520
  "data-embed-url": url
495
521
  });
496
522
  }
523
+ function normalizeSanitizedGoogleMapsEmbedUrl(url) {
524
+ const trimmed = url.trim();
525
+ if (!trimmed) return void 0;
526
+ try {
527
+ const parsed = new URL(trimmed);
528
+ if (!/^(www\.)?google\.com$/i.test(parsed.hostname)) return void 0;
529
+ if (!parsed.pathname.includes("/maps/embed")) return void 0;
530
+ parsed.protocol = "https:";
531
+ if (!parsed.hostname.startsWith("www.")) {
532
+ parsed.hostname = `www.${parsed.hostname}`;
533
+ }
534
+ return parsed.toString();
535
+ } catch {
536
+ return void 0;
537
+ }
538
+ }
497
539
  function buildGoogleMapsEmbedUrlFromMapParams(params) {
498
540
  const direct = extractShortcodeParam(params, [
499
541
  "embed_url",
@@ -503,25 +545,19 @@ function buildGoogleMapsEmbedUrlFromMapParams(params) {
503
545
  "iframe_url",
504
546
  "embed"
505
547
  ]);
506
- if (direct && /google\.com\/maps|maps\.google\.com/i.test(direct)) {
507
- return { embedUrl: direct.trim() };
548
+ if (direct) {
549
+ const embedUrl = normalizeSanitizedGoogleMapsEmbedUrl(direct);
550
+ if (embedUrl) return { embedUrl };
508
551
  }
509
552
  const lat = extractBareOrQuotedParam(params, "lat") ?? extractBareOrQuotedParam(params, "latitude") ?? extractBareOrQuotedParam(params, "map_lat");
510
553
  const lng = extractBareOrQuotedParam(params, "lng") ?? extractBareOrQuotedParam(params, "longitude") ?? extractBareOrQuotedParam(params, "map_lng");
554
+ const zoom = extractBareOrQuotedParam(params, "zoom") ?? "14";
511
555
  const address = extractBareOrQuotedParam(params, "address") ?? extractBareOrQuotedParam(params, "map_address") ?? extractBareOrQuotedParam(params, "location") ?? extractBareOrQuotedParam(params, "map_location") ?? extractBareOrQuotedParam(params, "q");
512
556
  if (lat && lng) {
513
- const zoom = extractBareOrQuotedParam(params, "zoom") ?? "14";
514
- return {
515
- embedUrl: `https://maps.google.com/maps?q=${encodeURIComponent(`${lat},${lng}`)}&z=${zoom}&output=embed`,
516
- lat,
517
- lng
518
- };
557
+ return { lat, lng, zoom };
519
558
  }
520
559
  if (address) {
521
- return {
522
- embedUrl: `https://maps.google.com/maps?q=${encodeURIComponent(address)}&output=embed`,
523
- query: address
524
- };
560
+ return { query: address, zoom };
525
561
  }
526
562
  return {};
527
563
  }
@@ -536,8 +572,9 @@ function flattenMapShortcodes(content, widgetRegistry) {
536
572
  const resolved = buildGoogleMapsEmbedUrlFromMapParams(params);
537
573
  return emitWidgetStub("map", {
538
574
  ...resolved.embedUrl ? { "data-embed-url": resolved.embedUrl } : {},
539
- ...resolved.lat ? { "data-wp-map-lat": resolved.lat } : {},
540
- ...resolved.lng ? { "data-wp-map-lng": resolved.lng } : {},
575
+ ...resolved.lat ? { "data-latitude": resolved.lat } : {},
576
+ ...resolved.lng ? { "data-longitude": resolved.lng } : {},
577
+ ...resolved.zoom ? { "data-zoom": resolved.zoom } : {},
541
578
  ...resolved.query ? { "data-wp-map-query": resolved.query } : {}
542
579
  });
543
580
  });
@@ -717,6 +754,180 @@ function collectTestimonialItemsFromInner(inner, itemTag) {
717
754
  });
718
755
  return items;
719
756
  }
757
+ function isWhitespaceOnlyHtml(html) {
758
+ return !decodeBasicHtmlEntities(stripHtmlTags(html)).trim();
759
+ }
760
+ function extractLeadingTitleH6(inner) {
761
+ const match = inner.match(/^\s*<h6[^>]*>([\s\S]*?)<\/h6>/i);
762
+ if (!match) return { remainder: inner.trim() };
763
+ const h6Content = match[1] ?? "";
764
+ if (/<img\b/i.test(h6Content)) return { remainder: inner.trim() };
765
+ const title = decodeBasicHtmlEntities(stripHtmlTags(h6Content)).trim();
766
+ const remainder = inner.slice(match[0].length).trim();
767
+ if (!title || isWhitespaceOnlyHtml(h6Content)) {
768
+ return { remainder: inner.trim() };
769
+ }
770
+ return { title, remainder };
771
+ }
772
+ function isTrackingPixelImage(imgTag, src) {
773
+ if (/amazon-adsystem\.com/i.test(src)) return true;
774
+ const widthMatch = imgTag.match(/\bwidth\s*=\s*["']?(\d+)["']?/i);
775
+ const heightMatch = imgTag.match(/\bheight\s*=\s*["']?(\d+)["']?/i);
776
+ return widthMatch?.[1] === "1" && heightMatch?.[1] === "1";
777
+ }
778
+ function extractLinkedBadgeImage(inner) {
779
+ const linkedImg = inner.match(
780
+ /<a\b[^>]*\bhref\s*=\s*["']([^"']+)["'][^>]*>[\s\S]*?<img\b([^>]*)>/i
781
+ );
782
+ if (linkedImg) {
783
+ const link = linkedImg[1]?.trim();
784
+ const imgAttrs = linkedImg[2] ?? "";
785
+ const srcMatch = imgAttrs.match(/\bsrc\s*=\s*["']([^"']+)["']/i);
786
+ const src = srcMatch?.[1]?.trim();
787
+ if (src && !isTrackingPixelImage(imgAttrs, src)) {
788
+ return { image: src, link: link || void 0 };
789
+ }
790
+ }
791
+ const imgMatch = inner.match(/<img\b([^>]*)>/i);
792
+ if (imgMatch) {
793
+ const imgAttrs = imgMatch[1] ?? "";
794
+ const srcMatch = imgAttrs.match(/\bsrc\s*=\s*["']([^"']+)["']/i);
795
+ const src = srcMatch?.[1]?.trim();
796
+ if (src && !isTrackingPixelImage(imgAttrs, src)) {
797
+ return { image: src };
798
+ }
799
+ }
800
+ return {};
801
+ }
802
+ function extractGridContentTitle(inner) {
803
+ const pattern = /<h6[^>]*>([\s\S]*?)<\/h6>/gi;
804
+ let match;
805
+ while ((match = pattern.exec(inner)) !== null) {
806
+ const h6Inner = match[1] ?? "";
807
+ if (/<img\b/i.test(h6Inner)) continue;
808
+ const title = decodeBasicHtmlEntities(stripHtmlTags(h6Inner)).trim();
809
+ if (title) return title;
810
+ }
811
+ return void 0;
812
+ }
813
+ function extractGridContentBody(inner) {
814
+ const pattern = /<p[^>]*>([\s\S]*?)<\/p>/gi;
815
+ let match;
816
+ while ((match = pattern.exec(inner)) !== null) {
817
+ const body = match[1]?.trim() ?? "";
818
+ if (body && !isWhitespaceOnlyHtml(body)) return body;
819
+ }
820
+ return void 0;
821
+ }
822
+ function parseTitleIconFeatureCardAttrs(params, inner) {
823
+ const icon = extractBareOrQuotedParam(params, "icon");
824
+ const iconBg = extractBareOrQuotedParam(params, "icon_bg");
825
+ const iconColor = extractBareOrQuotedParam(params, "icon_color");
826
+ const { title, remainder } = extractLeadingTitleH6(inner);
827
+ const body = remainder.trim() || void 0;
828
+ if (!title && !body) return null;
829
+ return {
830
+ "data-wp-feature-icon": icon,
831
+ "data-wp-feature-icon-bg": iconBg,
832
+ "data-wp-feature-icon-color": iconColor,
833
+ "data-wp-feature-title": title,
834
+ "data-wp-feature-body": body
835
+ };
836
+ }
837
+ function parseGridContentFeatureCardAttrs(_params, inner) {
838
+ const { image, link } = extractLinkedBadgeImage(inner);
839
+ const title = extractGridContentTitle(inner);
840
+ const body = extractGridContentBody(inner);
841
+ if (!title && !body && !image) return null;
842
+ return {
843
+ "data-wp-feature-image": image,
844
+ "data-wp-feature-link": link,
845
+ "data-wp-feature-title": title,
846
+ "data-wp-feature-body": body
847
+ };
848
+ }
849
+ function parseFeatureCardItemAttrs(tag, params, inner) {
850
+ if (tag.toLowerCase() === "tatsu_title_icon") {
851
+ return parseTitleIconFeatureCardAttrs(params, inner);
852
+ }
853
+ if (tag.toLowerCase() === "grid_content") {
854
+ return parseGridContentFeatureCardAttrs(params, inner);
855
+ }
856
+ return null;
857
+ }
858
+ function emitFeatureCardStub(attrs) {
859
+ const parts = ["data-wp-feature-card"];
860
+ for (const [key, value] of Object.entries(attrs)) {
861
+ if (value) parts.push(`${key}="${escapeLayoutAttr(value)}"`);
862
+ }
863
+ return `<div ${parts.join(" ")}>${WP_WIDGET_PLACEHOLDER}</div>`;
864
+ }
865
+ function emitFeaturesGridWidgetStub(sectionAttrs, items) {
866
+ const sectionParts = ['data-wp-widget="features-grid"'];
867
+ for (const [key, value] of Object.entries(sectionAttrs)) {
868
+ if (value) sectionParts.push(`${key}="${escapeLayoutAttr(value)}"`);
869
+ }
870
+ const children = items.map((item) => emitFeatureCardStub(item)).join("");
871
+ return `<section ${sectionParts.join(" ")}>${children}</section>`;
872
+ }
873
+ function inferFeatureColumns(wrapperParams, itemCount) {
874
+ const explicit = normalizeShortcodeCount(extractBareOrQuotedParam(wrapperParams, "column")) ?? normalizeShortcodeCount(extractBareOrQuotedParam(wrapperParams, "columns")) ?? normalizeShortcodeCount(extractBareOrQuotedParam(wrapperParams, "col"));
875
+ if (explicit) return explicit;
876
+ if (itemCount <= 1) return "1";
877
+ if (itemCount === 2) return "2";
878
+ if (itemCount >= 4) return "4";
879
+ return "3";
880
+ }
881
+ function collectFeatureCardItemsFromInner(inner, itemTags) {
882
+ const items = [];
883
+ for (const itemTag of itemTags) {
884
+ const escaped = escapeRegExp(itemTag);
885
+ const pattern = new RegExp(
886
+ `\\[${escaped}\\b([^\\]]*)\\]([\\s\\S]*?)\\[\\/${escaped}\\b[^\\]]*\\]`,
887
+ "gi"
888
+ );
889
+ inner.replace(pattern, (_, params, itemInner) => {
890
+ const item = parseFeatureCardItemAttrs(itemTag, params, itemInner);
891
+ if (item) items.push(item);
892
+ return "";
893
+ });
894
+ }
895
+ return items;
896
+ }
897
+ function flattenFeatureCardShortcodes(content, widgetRegistry) {
898
+ const itemTags = widgetRegistry.featureCardShortcodeTags;
899
+ let html = content;
900
+ for (const wrapperTag of widgetRegistry.featuresGridWrapperTags) {
901
+ const escaped = escapeRegExp(wrapperTag);
902
+ const pattern = new RegExp(
903
+ `\\[${escaped}\\b([^\\]]*)\\]([\\s\\S]*?)\\[\\/${escaped}\\b[^\\]]*\\]`,
904
+ "gi"
905
+ );
906
+ html = html.replace(pattern, (fullMatch, wrapperParams, inner) => {
907
+ const items = collectFeatureCardItemsFromInner(inner, itemTags);
908
+ if (items.length === 0) return fullMatch;
909
+ return emitFeaturesGridWidgetStub(
910
+ {
911
+ "data-wp-feature-columns": inferFeatureColumns(wrapperParams, items.length)
912
+ },
913
+ items
914
+ );
915
+ });
916
+ }
917
+ for (const tag of itemTags) {
918
+ const escaped = escapeRegExp(tag);
919
+ const pattern = new RegExp(
920
+ `\\[${escaped}\\b([^\\]]*)\\]([\\s\\S]*?)\\[\\/${escaped}\\b[^\\]]*\\]`,
921
+ "gi"
922
+ );
923
+ html = html.replace(pattern, (fullMatch, params, inner) => {
924
+ const item = parseFeatureCardItemAttrs(tag, params, inner);
925
+ if (!item) return fullMatch;
926
+ return emitFeatureCardStub(item);
927
+ });
928
+ }
929
+ return html;
930
+ }
720
931
  function flattenTestimonialsShortcodes(content, widgetRegistry) {
721
932
  const itemTag = widgetRegistry.testimonialItemTag;
722
933
  let html = content;
@@ -873,6 +1084,7 @@ function flattenWordPressWidgets(content, widgetRegistry = WORDPRESS_WIDGET_REGI
873
1084
  html = flattenSliderShortcodes(html, widgetRegistry);
874
1085
  html = flattenBlogListingShortcodes(html, widgetRegistry);
875
1086
  html = flattenTestimonialsShortcodes(html, widgetRegistry);
1087
+ html = flattenFeatureCardShortcodes(html, widgetRegistry);
876
1088
  html = flattenMapShortcodes(html, widgetRegistry);
877
1089
  html = flattenContactFormShortcodes(html, widgetRegistry);
878
1090
  html = flattenVideoShortcodes(html, widgetRegistry);
@@ -905,6 +1117,9 @@ function flattenWordPressBuilders(content, options = {}) {
905
1117
  for (const rule of theme.iconImageRules ?? []) {
906
1118
  html = convertIconImageRule(html, rule);
907
1119
  }
1120
+ for (const rule of theme.linkRules ?? []) {
1121
+ html = convertLinkRule(html, rule);
1122
+ }
908
1123
  for (const layoutMap of collectLayoutMaps(theme)) {
909
1124
  html = applyStructuralLayoutMap(html, layoutMap);
910
1125
  }
@@ -932,4 +1147,4 @@ export {
932
1147
  normalizeVideoEmbedUrl,
933
1148
  flattenWordPressBuilders
934
1149
  };
935
- //# sourceMappingURL=chunk-ZK3LH7PO.js.map
1150
+ //# sourceMappingURL=chunk-7IGOKUKE.js.map
@@ -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 isWhitespaceOnlyHtml(html: string): boolean {\n return !decodeBasicHtmlEntities(stripHtmlTags(html)).trim();\n}\n\nfunction extractLeadingTitleH6(inner: string): { title?: string; remainder: string } {\n const match = inner.match(/^\\s*<h6[^>]*>([\\s\\S]*?)<\\/h6>/i);\n if (!match) return { remainder: inner.trim() };\n\n const h6Content = match[1] ?? \"\";\n if (/<img\\b/i.test(h6Content)) return { remainder: inner.trim() };\n\n const title = decodeBasicHtmlEntities(stripHtmlTags(h6Content)).trim();\n const remainder = inner.slice(match[0]!.length).trim();\n if (!title || isWhitespaceOnlyHtml(h6Content)) {\n return { remainder: inner.trim() };\n }\n return { title, remainder };\n}\n\nfunction isTrackingPixelImage(imgTag: string, src: string): boolean {\n if (/amazon-adsystem\\.com/i.test(src)) return true;\n const widthMatch = imgTag.match(/\\bwidth\\s*=\\s*[\"']?(\\d+)[\"']?/i);\n const heightMatch = imgTag.match(/\\bheight\\s*=\\s*[\"']?(\\d+)[\"']?/i);\n return widthMatch?.[1] === \"1\" && heightMatch?.[1] === \"1\";\n}\n\nfunction extractLinkedBadgeImage(inner: string): { image?: string; link?: string } {\n const linkedImg = inner.match(\n /<a\\b[^>]*\\bhref\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>[\\s\\S]*?<img\\b([^>]*)>/i,\n );\n if (linkedImg) {\n const link = linkedImg[1]?.trim();\n const imgAttrs = linkedImg[2] ?? \"\";\n const srcMatch = imgAttrs.match(/\\bsrc\\s*=\\s*[\"']([^\"']+)[\"']/i);\n const src = srcMatch?.[1]?.trim();\n if (src && !isTrackingPixelImage(imgAttrs, src)) {\n return { image: src, link: link || undefined };\n }\n }\n\n const imgMatch = inner.match(/<img\\b([^>]*)>/i);\n if (imgMatch) {\n const imgAttrs = imgMatch[1] ?? \"\";\n const srcMatch = imgAttrs.match(/\\bsrc\\s*=\\s*[\"']([^\"']+)[\"']/i);\n const src = srcMatch?.[1]?.trim();\n if (src && !isTrackingPixelImage(imgAttrs, src)) {\n return { image: src };\n }\n }\n\n return {};\n}\n\nfunction extractGridContentTitle(inner: string): string | undefined {\n const pattern = /<h6[^>]*>([\\s\\S]*?)<\\/h6>/gi;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(inner)) !== null) {\n const h6Inner = match[1] ?? \"\";\n if (/<img\\b/i.test(h6Inner)) continue;\n const title = decodeBasicHtmlEntities(stripHtmlTags(h6Inner)).trim();\n if (title) return title;\n }\n return undefined;\n}\n\nfunction extractGridContentBody(inner: string): string | undefined {\n const pattern = /<p[^>]*>([\\s\\S]*?)<\\/p>/gi;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(inner)) !== null) {\n const body = match[1]?.trim() ?? \"\";\n if (body && !isWhitespaceOnlyHtml(body)) return body;\n }\n return undefined;\n}\n\nfunction parseTitleIconFeatureCardAttrs(\n params: string,\n inner: string,\n): Record<string, string | undefined> | null {\n const icon = extractBareOrQuotedParam(params, \"icon\");\n const iconBg = extractBareOrQuotedParam(params, \"icon_bg\");\n const iconColor = extractBareOrQuotedParam(params, \"icon_color\");\n const { title, remainder } = extractLeadingTitleH6(inner);\n const body = remainder.trim() || undefined;\n\n if (!title && !body) return null;\n\n return {\n \"data-wp-feature-icon\": icon,\n \"data-wp-feature-icon-bg\": iconBg,\n \"data-wp-feature-icon-color\": iconColor,\n \"data-wp-feature-title\": title,\n \"data-wp-feature-body\": body,\n };\n}\n\nfunction parseGridContentFeatureCardAttrs(\n _params: string,\n inner: string,\n): Record<string, string | undefined> | null {\n const { image, link } = extractLinkedBadgeImage(inner);\n const title = extractGridContentTitle(inner);\n const body = extractGridContentBody(inner);\n\n if (!title && !body && !image) return null;\n\n return {\n \"data-wp-feature-image\": image,\n \"data-wp-feature-link\": link,\n \"data-wp-feature-title\": title,\n \"data-wp-feature-body\": body,\n };\n}\n\nfunction parseFeatureCardItemAttrs(\n tag: string,\n params: string,\n inner: string,\n): Record<string, string | undefined> | null {\n if (tag.toLowerCase() === \"tatsu_title_icon\") {\n return parseTitleIconFeatureCardAttrs(params, inner);\n }\n if (tag.toLowerCase() === \"grid_content\") {\n return parseGridContentFeatureCardAttrs(params, inner);\n }\n return null;\n}\n\nfunction emitFeatureCardStub(attrs: Record<string, string | undefined>): string {\n const parts = [\"data-wp-feature-card\"];\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 emitFeaturesGridWidgetStub(\n sectionAttrs: Record<string, string | undefined>,\n items: Array<Record<string, string | undefined>>,\n): string {\n const sectionParts = ['data-wp-widget=\"features-grid\"'];\n for (const [key, value] of Object.entries(sectionAttrs)) {\n if (value) sectionParts.push(`${key}=\"${escapeLayoutAttr(value)}\"`);\n }\n const children = items.map((item) => emitFeatureCardStub(item)).join(\"\");\n return `<section ${sectionParts.join(\" \")}>${children}</section>`;\n}\n\nfunction inferFeatureColumns(wrapperParams: string, itemCount: number): string {\n const explicit =\n normalizeShortcodeCount(extractBareOrQuotedParam(wrapperParams, \"column\")) ??\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 collectFeatureCardItemsFromInner(\n inner: string,\n itemTags: readonly string[],\n): Array<Record<string, string | undefined>> {\n const items: Array<Record<string, string | undefined>> = [];\n for (const itemTag of itemTags) {\n const escaped = escapeRegExp(itemTag);\n const pattern = new RegExp(\n `\\\\[${escaped}\\\\b([^\\\\]]*)\\\\]([\\\\s\\\\S]*?)\\\\[\\\\/${escaped}\\\\b[^\\\\]]*\\\\]`,\n \"gi\",\n );\n inner.replace(pattern, (_, params: string, itemInner: string) => {\n const item = parseFeatureCardItemAttrs(itemTag, params, itemInner);\n if (item) items.push(item);\n return \"\";\n });\n }\n return items;\n}\n\nfunction flattenFeatureCardShortcodes(\n content: string,\n widgetRegistry: WordPressWidgetRegistry,\n): string {\n const itemTags = widgetRegistry.featureCardShortcodeTags;\n let html = content;\n\n for (const wrapperTag of widgetRegistry.featuresGridWrapperTags) {\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 = collectFeatureCardItemsFromInner(inner, itemTags);\n if (items.length === 0) return fullMatch;\n\n return emitFeaturesGridWidgetStub(\n {\n \"data-wp-feature-columns\": inferFeatureColumns(wrapperParams, items.length),\n },\n items,\n );\n });\n }\n\n for (const tag of itemTags) {\n const escaped = escapeRegExp(tag);\n const pattern = new RegExp(\n `\\\\[${escaped}\\\\b([^\\\\]]*)\\\\]([\\\\s\\\\S]*?)\\\\[\\\\/${escaped}\\\\b[^\\\\]]*\\\\]`,\n \"gi\",\n );\n html = html.replace(pattern, (fullMatch, params: string, inner: string) => {\n const item = parseFeatureCardItemAttrs(tag, params, inner);\n if (!item) return fullMatch;\n return emitFeatureCardStub(item);\n });\n }\n\n return html;\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 = flattenFeatureCardShortcodes(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-LQFNO26V.js";
12
+ } from "./chunk-M6NY4OT7.js";
13
13
  import {
14
14
  linkToPath,
15
15
  sanitizeSlug
@@ -1565,4 +1565,4 @@ export {
1565
1565
  resolveAdapterImportSummary,
1566
1566
  runDryRun
1567
1567
  };
1568
- //# sourceMappingURL=chunk-GVAKKEWX.js.map
1568
+ //# sourceMappingURL=chunk-H62Y7JAJ.js.map
@@ -201,6 +201,7 @@ var WORDPRESS_WIDGET_REGISTRY = {
201
201
  mapShortcodePrefixes: [
202
202
  "blox_gmap",
203
203
  "tatsu_gmap",
204
+ "tatsu_gmaps",
204
205
  "tatsu_map",
205
206
  "et_pb_map",
206
207
  "vc_gmaps",
@@ -225,6 +226,8 @@ var WORDPRESS_WIDGET_REGISTRY = {
225
226
  blogShortcodeTags: ["blog", "recent_posts"],
226
227
  testimonialsWrapperTags: ["testimonials"],
227
228
  testimonialItemTag: "testimonial",
229
+ featureCardShortcodeTags: ["tatsu_title_icon", "grid_content"],
230
+ featuresGridWrapperTags: ["grids"],
228
231
  sliderShortcodeTags: ["rev_slider", "masterslider"],
229
232
  galleryShortcode: "gallery",
230
233
  idGalleryShortcodes: ["oshine_gallery", "vc_gallery", "nggallery"]
@@ -258,6 +261,14 @@ var WORDPRESS_BUILDER_REGISTRY = [
258
261
  iconImageRules: [
259
262
  { shortcodePrefix: "tatsu_icon", imageParam: "icon_image", hrefParam: "href" }
260
263
  ],
264
+ linkRules: [
265
+ {
266
+ shortcodePrefix: "tatsu_button",
267
+ textParam: "button_text",
268
+ urlParam: "url",
269
+ className: "tatsu-button"
270
+ }
271
+ ],
261
272
  scaffoldingPrefixes: ["tatsu_"]
262
273
  },
263
274
  {
@@ -375,4 +386,4 @@ export {
375
386
  UNRESOLVABLE_SHORTCODE_PREFIXES,
376
387
  WORDPRESS_BUILDER_REGISTRY
377
388
  };
378
- //# sourceMappingURL=chunk-LQFNO26V.js.map
389
+ //# sourceMappingURL=chunk-M6NY4OT7.js.map