markdown-flow-ui 0.1.100-beta.39 → 0.1.100-beta.40

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.
Files changed (58) hide show
  1. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/@braintree_sanitize-url@7.1.1/node_modules/@braintree/sanitize-url/dist/index.cjs.js +1 -1
  2. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/@braintree_sanitize-url@7.1.1/node_modules/@braintree/sanitize-url/dist/index.es.js +1 -1
  3. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.cjs.js +1 -1
  4. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.es.js +1 -1
  5. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/hast-util-to-jsx-runtime@2.3.6/node_modules/hast-util-to-jsx-runtime/lib/index.cjs.js +1 -1
  6. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/hast-util-to-jsx-runtime@2.3.6/node_modules/hast-util-to-jsx-runtime/lib/index.es.js +1 -1
  7. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-YG6GDRKO.cjs.js +1 -1
  8. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-YG6GDRKO.es.js +1 -1
  9. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-S3R3BYOJ.cjs.js +1 -1
  10. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-S3R3BYOJ.es.js +1 -1
  11. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-TZMSLE5B.cjs.js +1 -1
  12. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-TZMSLE5B.es.js +1 -1
  13. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-LVOFAZNH.cjs.js +1 -1
  14. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-LVOFAZNH.es.js +1 -1
  15. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-WL72ISMW.cjs.js +1 -1
  16. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-WL72ISMW.es.js +1 -1
  17. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-util@5.44.4_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-util/es/ref.cjs.js +1 -1
  18. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-util@5.44.4_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-util/es/ref.es.js +1 -1
  19. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/style-to-object@1.0.11/node_modules/style-to-object/cjs/index.cjs.js +1 -1
  20. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/style-to-object@1.0.11/node_modules/style-to-object/cjs/index.es.js +1 -1
  21. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/unified@11.0.5/node_modules/unified/lib/index.cjs.js +1 -1
  22. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/unified@11.0.5/node_modules/unified/lib/index.es.js +1 -1
  23. package/dist/_virtual/index.cjs10.js +1 -1
  24. package/dist/_virtual/index.cjs11.js +1 -1
  25. package/dist/_virtual/index.cjs5.js +1 -1
  26. package/dist/_virtual/index.cjs6.js +1 -1
  27. package/dist/_virtual/index.cjs7.js +1 -1
  28. package/dist/_virtual/index.cjs8.js +1 -1
  29. package/dist/_virtual/index.cjs9.js +1 -1
  30. package/dist/_virtual/index.es10.js +2 -3
  31. package/dist/_virtual/index.es10.js.map +1 -1
  32. package/dist/_virtual/index.es11.js +3 -2
  33. package/dist/_virtual/index.es11.js.map +1 -1
  34. package/dist/_virtual/index.es5.js +4 -4
  35. package/dist/_virtual/index.es6.js +4 -4
  36. package/dist/_virtual/index.es7.js +3 -2
  37. package/dist/_virtual/index.es7.js.map +1 -1
  38. package/dist/_virtual/index.es8.js +2 -2
  39. package/dist/_virtual/index.es9.js +2 -3
  40. package/dist/_virtual/index.es9.js.map +1 -1
  41. package/dist/components/ContentRender/ContentRender.cjs.js +2 -2
  42. package/dist/components/ContentRender/ContentRender.cjs.js.map +1 -1
  43. package/dist/components/ContentRender/ContentRender.es.js +211 -140
  44. package/dist/components/ContentRender/ContentRender.es.js.map +1 -1
  45. package/dist/components/ContentRender/IframeSandbox.cjs.js +4 -4
  46. package/dist/components/ContentRender/IframeSandbox.cjs.js.map +1 -1
  47. package/dist/components/ContentRender/IframeSandbox.es.js +211 -260
  48. package/dist/components/ContentRender/IframeSandbox.es.js.map +1 -1
  49. package/dist/components/ContentRender/SandboxApp.cjs.js +2 -2
  50. package/dist/components/ContentRender/SandboxApp.cjs.js.map +1 -1
  51. package/dist/components/ContentRender/SandboxApp.es.js +109 -135
  52. package/dist/components/ContentRender/SandboxApp.es.js.map +1 -1
  53. package/dist/components/ContentRender/index.cjs.js +1 -1
  54. package/dist/components/ContentRender/index.es.js +5 -6
  55. package/dist/components/MarkdownFlow/MarkdownFlow.cjs.js +1 -1
  56. package/dist/components/MarkdownFlow/MarkdownFlow.cjs.js.map +1 -1
  57. package/dist/components/MarkdownFlow/MarkdownFlow.es.js +2 -2
  58. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"IframeSandbox.es.js","sources":["../../../src/components/ContentRender/IframeSandbox.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createRoot, Root } from \"react-dom/client\";\nimport { Loader2 } from \"lucide-react\";\nimport SandboxApp from \"./SandboxApp\";\nimport { splitContentSegments } from \"./utils/split-content\";\nimport ContentRender from \"./ContentRender\";\nimport {\n SANDBOX_INTERACTION_MESSAGE_SOURCE,\n SANDBOX_INTERACTION_MESSAGE_TYPE,\n} from \"../../lib/sandboxInteraction\";\n\ntype InjectBlackboardLibraries =\n typeof import(\"./blackboard-vendor\").injectBlackboardLibraries;\n\n// Cache the sandbox vendor loader so every iframe reuses the same preload request.\nlet blackboardVendorPromise: Promise<InjectBlackboardLibraries> | null = null;\n\nconst loadBlackboardVendor = () => {\n if (!blackboardVendorPromise) {\n blackboardVendorPromise = import(\"./blackboard-vendor\").then(\n (m) => m.injectBlackboardLibraries\n );\n }\n\n return blackboardVendorPromise;\n};\n\nif (typeof window !== \"undefined\") {\n // Warm sandbox vendor in browser so the first iframe render can start sooner.\n void loadBlackboardVendor();\n}\n\nconst loadBlackboardVendorOnDemandWithMetrics = () => {\n const loadStart = performance.now();\n const startedAt = new Date().toISOString();\n console.log(\"[IframeSandbox][SandboxLoad] start\", { startedAt });\n\n return loadBlackboardVendor()\n .then((inject) => {\n console.log(\"[IframeSandbox][SandboxLoad] done\", {\n startedAt,\n endedAt: new Date().toISOString(),\n durationMs: Number((performance.now() - loadStart).toFixed(2)),\n });\n return inject;\n })\n .catch((error) => {\n console.error(\"[IframeSandbox][SandboxLoad] failed\", {\n startedAt,\n endedAt: new Date().toISOString(),\n durationMs: Number((performance.now() - loadStart).toFixed(2)),\n error,\n });\n throw error;\n });\n};\n\nconst COMPLETE_IMAGE_TAG_PATTERN = /<img\\b[^>]*>/i;\nconst POST_IMAGE_STREAM_DEBOUNCE_MS = 180;\nconst SANDBOX_INTERACTION_THROTTLE_MS = 240;\nconst COMPLETE_IMAGE_SOURCE_PATTERN =\n /<img\\b[^>]*\\bsrc\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>/gi;\nconst SANDBOX_IMAGE_PRELOAD_CACHE = new Map<string, Promise<void>>();\nconst SANDBOX_IMAGE_READY_CACHE = new Set<string>();\n\nconst extractCompleteImageSources = (html: string) => {\n const matches = Array.from(html.matchAll(COMPLETE_IMAGE_SOURCE_PATTERN));\n return Array.from(\n new Set(\n matches\n .map((match) => match[1]?.trim())\n .filter((src): src is string => Boolean(src))\n )\n );\n};\n\nconst preloadSandboxImage = (src: string) => {\n if (!src) {\n return Promise.resolve();\n }\n\n const cached = SANDBOX_IMAGE_PRELOAD_CACHE.get(src);\n if (cached) {\n return cached;\n }\n\n const nextPromise = new Promise<void>((resolve) => {\n if (typeof window === \"undefined\") {\n SANDBOX_IMAGE_READY_CACHE.add(src);\n resolve();\n return;\n }\n\n const image = new window.Image();\n image.decoding = \"sync\";\n image.loading = \"eager\";\n image.fetchPriority = \"high\";\n\n const settleWhenRenderable = () => {\n const decodePromise =\n typeof image.decode === \"function\"\n ? image.decode().catch(() => undefined)\n : Promise.resolve();\n\n void decodePromise.finally(() => {\n SANDBOX_IMAGE_READY_CACHE.add(src);\n resolve();\n });\n };\n\n image.onload = () => {\n settleWhenRenderable();\n };\n image.onerror = () => {\n SANDBOX_IMAGE_READY_CACHE.add(src);\n resolve();\n };\n image.src = src;\n\n if (image.complete && image.naturalWidth > 0) {\n settleWhenRenderable();\n }\n });\n\n SANDBOX_IMAGE_PRELOAD_CACHE.set(src, nextPromise);\n return nextPromise;\n};\n\nconst preloadSandboxImages = (sources: string[] = []) =>\n Promise.allSettled(sources.map((source) => preloadSandboxImage(source)));\n\nexport interface IframeSandboxProps {\n content: string;\n className?: string;\n loadingText?: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n fullScreenButtonText?: string;\n hideFullScreen?: boolean;\n mode?: \"content\" | \"blackboard\";\n type: \"sandbox\" | \"markdown\";\n replaceRootScreenHeightWithFull?: boolean;\n}\n\nconst normalizeTailwindHeightTokens = (className: string) =>\n className\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => token.split(\":\").pop() || token);\n\nconst parseViewportHeightCss = (value: string) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const matched = normalized.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);\n if (!matched) return null;\n return `${matched[1]}${matched[2].toLowerCase()}`;\n};\n\nconst extractViewportHeightFromTailwindClass = (className: string) => {\n if (!className.trim()) return null;\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n if (\n normalizedTokens.includes(\"h-screen\") ||\n normalizedTokens.includes(\"h-dvh\") ||\n normalizedTokens.includes(\"min-h-screen\") ||\n normalizedTokens.includes(\"min-h-dvh\")\n ) {\n return \"100dvh\";\n }\n if (\n normalizedTokens.includes(\"h-svh\") ||\n normalizedTokens.includes(\"min-h-svh\")\n ) {\n return \"100svh\";\n }\n if (\n normalizedTokens.includes(\"h-lvh\") ||\n normalizedTokens.includes(\"min-h-lvh\")\n ) {\n return \"100lvh\";\n }\n const arbitraryToken = normalizedTokens.find((token) =>\n /^(h|min-h)-\\[[0-9.]+(vh|dvh|svh|lvh)\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(\n /^(h|min-h)-\\[([0-9.]+)(vh|dvh|svh|lvh)\\]$/i\n );\n if (!matched) return null;\n return `${matched[2]}${matched[3].toLowerCase()}`;\n};\n\nconst SANDBOX_IGNORED_TAG_NAMES = new Set([\n \"base\",\n \"link\",\n \"meta\",\n \"script\",\n \"style\",\n \"template\",\n \"title\",\n]);\n\nconst isSandboxRenderableElement = (element: Element) =>\n !SANDBOX_IGNORED_TAG_NAMES.has(element.tagName.toLowerCase());\n\nconst getFirstRenderableElementChild = (root: ParentNode) =>\n Array.from(root.childNodes).find(\n (node): node is HTMLElement =>\n node.nodeType === Node.ELEMENT_NODE &&\n isSandboxRenderableElement(node as HTMLElement)\n ) || null;\n\nconst getInspectableSandboxElementChain = (root: ParentNode) => {\n const chain: HTMLElement[] = [];\n let current = getFirstRenderableElementChild(root);\n\n while (current) {\n chain.push(current);\n\n const childElements = Array.from(current.children).filter(\n (element): element is HTMLElement => isSandboxRenderableElement(element)\n );\n\n if (childElements.length !== 1) {\n break;\n }\n\n current = childElements[0];\n }\n\n return chain;\n};\n\nconst extractViewportHeightFromElement = (element: HTMLElement) => {\n const heightAttrValue = element.getAttribute(\"height\");\n const attrViewportHeight = heightAttrValue\n ? parseViewportHeightCss(heightAttrValue)\n : null;\n\n if (attrViewportHeight) {\n return attrViewportHeight;\n }\n\n const styleHeightValue =\n element.getAttribute(\"style\")?.match(/\\bheight\\s*:\\s*([^;]+)/i)?.[1] ||\n null;\n const styleViewportHeight = styleHeightValue\n ? parseViewportHeightCss(styleHeightValue)\n : null;\n\n if (styleViewportHeight) {\n return styleViewportHeight;\n }\n\n return extractViewportHeightFromTailwindClass(\n element.getAttribute(\"class\") || \"\"\n );\n};\n\nconst isFullViewportHeightCss = (value: string | null) =>\n value === \"100vh\" ||\n value === \"100dvh\" ||\n value === \"100svh\" ||\n value === \"100lvh\";\n\nconst inspectSandboxPrimaryHeight = (root: ParentNode) => {\n const inspectableElements = getInspectableSandboxElementChain(root);\n let viewportHeightCss: string | null = null;\n let hasFullViewportHeight = false;\n\n inspectableElements.forEach((element) => {\n const elementViewportHeight = extractViewportHeightFromElement(element);\n\n if (!viewportHeightCss && elementViewportHeight) {\n viewportHeightCss = elementViewportHeight;\n }\n\n if (isFullViewportHeightCss(elementViewportHeight)) {\n hasFullViewportHeight = true;\n }\n });\n\n return {\n viewportHeightCss,\n hasFullViewportHeight,\n };\n};\n\nconst inspectRootHeightFromHtmlString = (html: string) => {\n const normalized = html.trim();\n\n if (!normalized) {\n return {\n viewportHeightCss: null,\n hasFullViewportHeight: false,\n };\n }\n\n const rootMatch = normalized.match(/^<([a-zA-Z][\\w:-]*)(\\s[^>]*?)?>/);\n const attrs = rootMatch?.[2] || \"\";\n const heightAttrValue = attrs.match(/\\bheight\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const styleAttrValue = attrs.match(/\\bstyle\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const styleHeightValue = styleAttrValue?.match(\n /\\bheight\\s*:\\s*([^;]+)/i\n )?.[1];\n const classAttrValue = attrs.match(/\\bclass\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const viewportHeightCss =\n (heightAttrValue ? parseViewportHeightCss(heightAttrValue) : null) ||\n (styleHeightValue ? parseViewportHeightCss(styleHeightValue) : null) ||\n (classAttrValue\n ? extractViewportHeightFromTailwindClass(classAttrValue)\n : null);\n\n return {\n viewportHeightCss,\n hasFullViewportHeight: isFullViewportHeightCss(viewportHeightCss),\n };\n};\n\nconst inspectSandboxPrimaryHeightFromHtml = (html: string) => {\n const normalized = html.trim();\n\n if (!normalized) {\n return {\n viewportHeightCss: null,\n hasFullViewportHeight: false,\n };\n }\n\n if (typeof document === \"undefined\") {\n return inspectRootHeightFromHtmlString(normalized);\n }\n\n const template = document.createElement(\"template\");\n template.innerHTML = normalized;\n\n return inspectSandboxPrimaryHeight(template.content);\n};\n\nconst replaceRootScreenHeightToken = (className: string) =>\n className\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => {\n const segments = token.split(\":\");\n if (\n segments[segments.length - 1] !== \"h-screen\" &&\n segments[segments.length - 1] !== \"min-h-screen\"\n ) {\n return token;\n }\n segments[segments.length - 1] = \"h-full\";\n return segments.join(\":\");\n })\n .join(\" \");\n\nconst replaceRootScreenHeightWithFullClass = (\n html: string,\n enabled: boolean\n) => {\n if (!enabled || !html.trim()) {\n return html;\n }\n\n return html.replace(\n /^(\\s*<[a-zA-Z][\\w:-]*)(\\s[^>]*?)?>/,\n (match, tagStart: string, attrs = \"\") => {\n const classMatch = attrs.match(/\\bclass\\s*=\\s*([\"'])([^\"']*)\\1/i);\n\n if (!classMatch) {\n return match;\n }\n\n const nextClassName = replaceRootScreenHeightToken(classMatch[2]);\n\n if (nextClassName === classMatch[2]) {\n return match;\n }\n\n return `${tagStart}${attrs.replace(\n classMatch[0],\n `class=${classMatch[1]}${nextClassName}${classMatch[1]}`\n )}>`;\n }\n );\n};\n\nconst IframeSandbox: React.FC<IframeSandboxProps> = ({\n content,\n type,\n className,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n hideFullScreen = false,\n mode = \"content\",\n replaceRootScreenHeightWithFull = false,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const rootRef = useRef<Root | null>(null);\n const docRef = useRef<Document | null>(null);\n const updateHeightRef = useRef<() => void>(() => {});\n const [height, setHeight] = useState(480);\n const lastSandboxInteractionTimeRef = useRef(0);\n const [resetToken, setResetToken] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [, setIsSandboxVendorReady] = useState(true);\n const shouldInjectSandboxVendor = type === \"sandbox\";\n\n const isBlackboardMode = mode === \"blackboard\";\n const prevHtmlRef = useRef<string>(\"\");\n const htmlContent = React.useMemo(() => {\n const segments = splitContentSegments(content);\n // console.log('segments=====', segments);\n const sandboxSegments = segments.filter((seg) => seg.type === \"sandbox\");\n const sandboxContent =\n mode === \"blackboard\"\n ? sandboxSegments[sandboxSegments.length - 1]?.value || \"\"\n : sandboxSegments.map((seg) => seg.value).join(\"\\n\");\n return sandboxContent || \"\";\n }, [content, mode]);\n const normalizedHtmlContent = React.useMemo(\n () =>\n replaceRootScreenHeightWithFullClass(\n htmlContent,\n replaceRootScreenHeightWithFull\n ),\n [htmlContent, replaceRootScreenHeightWithFull]\n );\n const completeImageSources = React.useMemo(\n () => extractCompleteImageSources(normalizedHtmlContent),\n [normalizedHtmlContent]\n );\n const htmlHeightMeta = React.useMemo(\n () => inspectSandboxPrimaryHeightFromHtml(htmlContent),\n [htmlContent]\n );\n const shouldStretchRootHeight = React.useMemo(\n () =>\n replaceRootScreenHeightWithFull && htmlHeightMeta.hasFullViewportHeight,\n [htmlHeightMeta.hasFullViewportHeight, replaceRootScreenHeightWithFull]\n );\n const [renderHtmlContent, setRenderHtmlContent] = useState(\n normalizedHtmlContent\n );\n const prevIncomingHtmlRef = useRef(normalizedHtmlContent);\n const pendingHtmlRef = useRef(normalizedHtmlContent);\n const deferRenderTimerRef = useRef<number | null>(null);\n const initialPaintFrameRef = useRef<number | null>(null);\n const initialPaintCommitFrameRef = useRef<number | null>(null);\n const imagePreloadRequestIdRef = useRef(0);\n\n const emitSandboxInteraction = useCallback((eventType: string) => {\n if (typeof window === \"undefined\") {\n return;\n }\n const now = Date.now();\n if (\n now - lastSandboxInteractionTimeRef.current <\n SANDBOX_INTERACTION_THROTTLE_MS\n ) {\n return;\n }\n lastSandboxInteractionTimeRef.current = now;\n window.postMessage(\n {\n source: SANDBOX_INTERACTION_MESSAGE_SOURCE,\n type: SANDBOX_INTERACTION_MESSAGE_TYPE,\n eventType,\n },\n window.location.origin\n );\n }, []);\n\n const clearDeferredRenderTimer = () => {\n if (deferRenderTimerRef.current === null) return;\n window.clearTimeout(deferRenderTimerRef.current);\n deferRenderTimerRef.current = null;\n };\n\n const clearInitialPaintFrames = () => {\n if (initialPaintFrameRef.current !== null) {\n window.cancelAnimationFrame(initialPaintFrameRef.current);\n initialPaintFrameRef.current = null;\n }\n if (initialPaintCommitFrameRef.current !== null) {\n window.cancelAnimationFrame(initialPaintCommitFrameRef.current);\n initialPaintCommitFrameRef.current = null;\n }\n };\n\n useEffect(\n () => () => {\n clearDeferredRenderTimer();\n clearInitialPaintFrames();\n },\n []\n );\n\n useEffect(() => {\n void preloadSandboxImages(completeImageSources);\n }, [completeImageSources]);\n\n useEffect(() => {\n const prevIncomingHtml = prevIncomingHtmlRef.current;\n prevIncomingHtmlRef.current = normalizedHtmlContent;\n\n const isAppendOnlyStream =\n !!prevIncomingHtml &&\n normalizedHtmlContent.length > prevIncomingHtml.length &&\n normalizedHtmlContent.startsWith(prevIncomingHtml);\n const containsCompleteImage = COMPLETE_IMAGE_TAG_PATTERN.test(\n normalizedHtmlContent\n );\n const hasPendingImagePreload =\n isAppendOnlyStream &&\n containsCompleteImage &&\n completeImageSources.some(\n (source) => !SANDBOX_IMAGE_READY_CACHE.has(source)\n );\n const shouldDeferRender = isAppendOnlyStream && containsCompleteImage;\n\n pendingHtmlRef.current = normalizedHtmlContent;\n clearDeferredRenderTimer();\n\n if (hasPendingImagePreload) {\n const requestId = imagePreloadRequestIdRef.current + 1;\n imagePreloadRequestIdRef.current = requestId;\n\n void preloadSandboxImages(completeImageSources).then(() => {\n if (imagePreloadRequestIdRef.current !== requestId) {\n return;\n }\n\n setRenderHtmlContent(pendingHtmlRef.current);\n });\n return;\n }\n\n if (!shouldDeferRender) {\n setRenderHtmlContent(normalizedHtmlContent);\n return;\n }\n\n deferRenderTimerRef.current = window.setTimeout(() => {\n setRenderHtmlContent(pendingHtmlRef.current);\n deferRenderTimerRef.current = null;\n }, POST_IMAGE_STREAM_DEBOUNCE_MS);\n }, [completeImageSources, normalizedHtmlContent]);\n\n const rootViewportHeightCss = React.useMemo(\n () =>\n inspectSandboxPrimaryHeightFromHtml(renderHtmlContent).viewportHeightCss,\n [renderHtmlContent]\n );\n const hasRootVhHeight = Boolean(rootViewportHeightCss);\n const sandboxViewportHeight =\n isBlackboardMode && type === \"sandbox\"\n ? shouldStretchRootHeight\n ? \"100%\"\n : (rootViewportHeightCss ?? `${height}px`)\n : undefined;\n const shouldShowHtmlFallbackWhilePreparingSandbox = false;\n useEffect(() => {\n if (mode !== \"blackboard\") {\n prevHtmlRef.current = normalizedHtmlContent;\n return;\n }\n const prev = prevHtmlRef.current;\n const isContinuation = prev && normalizedHtmlContent.startsWith(prev);\n if (!isContinuation && prev) {\n setResetToken((token) => token + 1);\n }\n prevHtmlRef.current = normalizedHtmlContent;\n }, [mode, normalizedHtmlContent]);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe) return undefined;\n\n const doc = iframe.contentDocument;\n if (!doc) return undefined;\n\n doc.open();\n doc.write(`<!DOCTYPE html>\n<html${mode === \"blackboard\" ? ' style=\"height: 100%;\"' : \"\"}>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <style>\n :root { color-scheme: light; }\n html, body, #root { width: 100%; height: 100%; }\n html, body { margin: 0; padding: 0; overflow: auto; }\n *, *::before, *::after { box-sizing: border-box; }\n </style>\n </head>\n <body>\n <div id=\"root\"></div>\n </body>\n</html>`);\n doc.close();\n\n // Force iframe theme to stay in light mode regardless of host OS preference.\n doc.documentElement.setAttribute(\"data-theme\", \"light\");\n doc.documentElement.style.colorScheme = \"light\";\n doc.body?.style.setProperty(\"color-scheme\", \"light\");\n\n docRef.current = doc;\n\n const shouldBridgeSandboxInteraction =\n isBlackboardMode && type === \"sandbox\";\n const handleSandboxPointerDown = () =>\n emitSandboxInteraction(\"pointerdown\");\n const handleSandboxMouseDown = () => emitSandboxInteraction(\"mousedown\");\n const handleSandboxTouchStart = () => emitSandboxInteraction(\"touchstart\");\n\n if (shouldBridgeSandboxInteraction) {\n doc.addEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.addEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.addEventListener(\"touchstart\", handleSandboxTouchStart, true);\n }\n\n const rootEl = doc.getElementById(\"root\");\n if (!rootEl) return undefined;\n\n const root = createRoot(rootEl);\n rootRef.current = root;\n let isDestroyed = false;\n\n const parseExplicitHeight = (\n value: string,\n parentViewportHeight: number\n ) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const numeric = Number.parseFloat(normalized);\n if (Number.isNaN(numeric)) return null;\n if (/(dvh|svh|lvh|vh)$/i.test(normalized)) {\n return (numeric / 100) * parentViewportHeight;\n }\n if (normalized.endsWith(\"px\") || /^[0-9.]+$/.test(normalized)) {\n return numeric;\n }\n return null;\n };\n const parseTailwindHeightClass = (\n className: string,\n parentViewportHeight: number\n ) => {\n if (!className.trim()) return null;\n const viewportHeightCss =\n extractViewportHeightFromTailwindClass(className);\n if (viewportHeightCss) {\n return parseExplicitHeight(viewportHeightCss, parentViewportHeight);\n }\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n const arbitraryToken = normalizedTokens.find((token) =>\n /^h-\\[[0-9.]+px\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(/^h-\\[([0-9.]+)px\\]$/i);\n if (!matched) return null;\n const numeric = Number.parseFloat(matched[1]);\n if (Number.isNaN(numeric)) return null;\n return numeric;\n };\n\n const resolveExplicitHeight = () => {\n if (!iframeRef.current || !doc.body) return null;\n const parentViewportHeight =\n iframeRef.current.ownerDocument?.documentElement?.clientHeight ||\n window.innerHeight;\n const { viewportHeightCss } = inspectSandboxPrimaryHeight(doc.body);\n const parsed = viewportHeightCss\n ? parseExplicitHeight(viewportHeightCss, parentViewportHeight)\n : null;\n\n if (parsed !== null) {\n return Math.ceil(parsed);\n }\n\n const wrapper = doc.body.querySelector(\n \".sandbox-wrapper\"\n ) as HTMLElement | null;\n const target = wrapper?.querySelector(\n \".sandbox-container > *\"\n ) as HTMLElement | null;\n\n if (!target) return null;\n\n const heightValue = target.style.height || target.getAttribute(\"height\");\n const explicitPixelHeight = heightValue\n ? parseExplicitHeight(heightValue, parentViewportHeight)\n : null;\n\n if (explicitPixelHeight !== null) {\n return Math.ceil(explicitPixelHeight);\n }\n\n const classHeight = parseTailwindHeightClass(\n target.getAttribute(\"class\") || \"\",\n parentViewportHeight\n );\n\n return classHeight !== null ? Math.ceil(classHeight) : null;\n };\n\n const updateHeight = () => {\n if (!iframeRef.current || !doc.body) return;\n const bodyRect = doc.body.getBoundingClientRect();\n const htmlRect = doc.documentElement?.getBoundingClientRect();\n const bodyHeight = bodyRect.height;\n const htmlHeight = htmlRect?.height || 0;\n const contentHeight = Math.max(bodyHeight, htmlHeight);\n const explicitHeight = resolveExplicitHeight();\n const nextHeight = Math.max(\n 200,\n explicitHeight ?? Math.ceil(contentHeight)\n );\n setHeight(nextHeight);\n };\n const scheduleHeightUpdate = () => {\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n updateHeight();\n });\n };\n updateHeightRef.current = scheduleHeightUpdate;\n\n updateHeight();\n scheduleHeightUpdate();\n\n if (!shouldInjectSandboxVendor) {\n setIsSandboxVendorReady(true);\n } else {\n // Inject Tailwind/DaisyUI/GSAP before rendering sandbox content to avoid FOUC.\n loadBlackboardVendorOnDemandWithMetrics()\n .then((inject) => {\n if (isDestroyed) return;\n inject(doc);\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n setIsSandboxVendorReady(true);\n scheduleHeightUpdate();\n });\n })\n .catch(() => {\n if (isDestroyed) return;\n setIsSandboxVendorReady(true);\n scheduleHeightUpdate();\n });\n }\n\n const resizeObserver = new ResizeObserver(() => updateHeight());\n resizeObserver.observe(doc.body);\n if (rootEl) {\n resizeObserver.observe(rootEl);\n }\n\n return () => {\n isDestroyed = true;\n resizeObserver.disconnect();\n if (shouldBridgeSandboxInteraction) {\n doc.removeEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.removeEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.removeEventListener(\"touchstart\", handleSandboxTouchStart, true);\n }\n // Defer unmount to avoid React warning when parent is mid-render\n setTimeout(() => {\n root.unmount();\n rootRef.current = null;\n docRef.current = null;\n updateHeightRef.current = () => {};\n }, 0);\n };\n }, []);\n\n useEffect(() => {\n const onFullscreenChange = () => {\n setIsFullscreen(Boolean(document.fullscreenElement));\n };\n document.addEventListener(\"fullscreenchange\", onFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", onFullscreenChange);\n }, []);\n\n const toggleFullscreen = () => {\n const target = containerRef.current || iframeRef.current;\n if (!target) return;\n if (document.fullscreenElement) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n if (target.requestFullscreen) {\n target.requestFullscreen().catch(() => {});\n }\n };\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n\n root.render(\n <SandboxApp\n html={renderHtmlContent}\n loadingText={loadingText}\n styleLoadingText={styleLoadingText}\n scriptLoadingText={scriptLoadingText}\n fullScreenButtonText={fullScreenButtonText}\n hideFullScreen={hideFullScreen}\n resetToken={resetToken}\n hasRootVhHeight={hasRootVhHeight}\n mode={mode}\n stretchRootHeight={shouldStretchRootHeight}\n />\n );\n\n initialPaintFrameRef.current = window.requestAnimationFrame(() => {\n updateHeightRef.current?.();\n initialPaintFrameRef.current = null;\n });\n }, [\n renderHtmlContent,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n resetToken,\n mode,\n ]);\n const containerClassName = [\n \"w-full relative content-render-iframe-sandbox\",\n isBlackboardMode\n ? \"h-full overflow-auto flex flex-col\"\n : \"aspect-[16/9] overflow-hidden flex items-center justify-center\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const shouldShowSandboxLoading = false;\n\n return (\n <div\n ref={containerRef}\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className={containerClassName}\n style={\n sandboxViewportHeight\n ? {\n height: sandboxViewportHeight,\n minHeight: sandboxViewportHeight,\n }\n : undefined\n }\n >\n {!hideFullScreen && (\n <button\n type=\"button\"\n onClick={toggleFullscreen}\n className={\n \"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer\"\n }\n >\n {isFullscreen ? \"退出全屏\" : fullScreenButtonText || \"全屏浏览\"}\n </button>\n )}\n {mode === \"blackboard\" && type === \"markdown\" ? (\n <div\n onMouseDown={() => emitSandboxInteraction(\"mousedown\")}\n onPointerDown={() => emitSandboxInteraction(\"pointerdown\")}\n onTouchStart={() => emitSandboxInteraction(\"touchstart\")}\n >\n <ContentRender content={content} />\n </div>\n ) : (\n <>\n {shouldShowHtmlFallbackWhilePreparingSandbox ? (\n <div\n aria-hidden\n className=\"absolute inset-0 z-10 overflow-hidden\"\n style={{\n height: sandboxViewportHeight ?? \"100%\",\n minHeight: sandboxViewportHeight,\n }}\n >\n <div\n className=\"h-full w-full\"\n dangerouslySetInnerHTML={{ __html: renderHtmlContent }}\n />\n </div>\n ) : null}\n <iframe\n ref={iframeRef}\n sandbox=\"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox\"\n allow=\"fullscreen\"\n allowFullScreen\n className={[className, \"w-full h-full mx-auto my-auto block\"]\n .filter(Boolean)\n .join(\" \")}\n style={{\n height: sandboxViewportHeight ?? \"100%\",\n minHeight: sandboxViewportHeight,\n margin: \"auto\",\n visibility: \"visible\",\n }}\n />\n {shouldShowSandboxLoading ? (\n <div className=\"pointer-events-none absolute inset-0 z-20 flex items-center justify-center\">\n <Loader2\n aria-label={loadingText || \"Preparing sandbox styles\"}\n className=\"text-primary h-7 w-7 animate-spin\"\n />\n </div>\n ) : null}\n </>\n )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["blackboardVendorPromise","loadBlackboardVendor","m","loadBlackboardVendorOnDemandWithMetrics","loadStart","startedAt","inject","error","COMPLETE_IMAGE_TAG_PATTERN","POST_IMAGE_STREAM_DEBOUNCE_MS","SANDBOX_INTERACTION_THROTTLE_MS","COMPLETE_IMAGE_SOURCE_PATTERN","SANDBOX_IMAGE_PRELOAD_CACHE","SANDBOX_IMAGE_READY_CACHE","extractCompleteImageSources","html","matches","match","src","preloadSandboxImage","cached","nextPromise","resolve","image","settleWhenRenderable","preloadSandboxImages","sources","source","normalizeTailwindHeightTokens","className","token","parseViewportHeightCss","value","normalized","matched","extractViewportHeightFromTailwindClass","normalizedTokens","arbitraryToken","SANDBOX_IGNORED_TAG_NAMES","isSandboxRenderableElement","element","getFirstRenderableElementChild","root","node","getInspectableSandboxElementChain","chain","current","childElements","extractViewportHeightFromElement","heightAttrValue","attrViewportHeight","styleHeightValue","styleViewportHeight","isFullViewportHeightCss","inspectSandboxPrimaryHeight","inspectableElements","viewportHeightCss","hasFullViewportHeight","elementViewportHeight","inspectRootHeightFromHtmlString","attrs","classAttrValue","inspectSandboxPrimaryHeightFromHtml","template","replaceRootScreenHeightToken","segments","replaceRootScreenHeightWithFullClass","enabled","tagStart","classMatch","nextClassName","IframeSandbox","content","type","loadingText","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","replaceRootScreenHeightWithFull","containerRef","useRef","iframeRef","rootRef","docRef","updateHeightRef","height","setHeight","useState","lastSandboxInteractionTimeRef","resetToken","setResetToken","isFullscreen","setIsFullscreen","setIsSandboxVendorReady","shouldInjectSandboxVendor","isBlackboardMode","prevHtmlRef","htmlContent","React","sandboxSegments","splitContentSegments","seg","normalizedHtmlContent","completeImageSources","htmlHeightMeta","shouldStretchRootHeight","renderHtmlContent","setRenderHtmlContent","prevIncomingHtmlRef","pendingHtmlRef","deferRenderTimerRef","initialPaintFrameRef","initialPaintCommitFrameRef","imagePreloadRequestIdRef","emitSandboxInteraction","useCallback","eventType","now","SANDBOX_INTERACTION_MESSAGE_SOURCE","SANDBOX_INTERACTION_MESSAGE_TYPE","clearDeferredRenderTimer","clearInitialPaintFrames","useEffect","prevIncomingHtml","isAppendOnlyStream","containsCompleteImage","hasPendingImagePreload","shouldDeferRender","requestId","rootViewportHeightCss","hasRootVhHeight","sandboxViewportHeight","prev","iframe","doc","shouldBridgeSandboxInteraction","handleSandboxPointerDown","handleSandboxMouseDown","handleSandboxTouchStart","rootEl","createRoot","isDestroyed","parseExplicitHeight","parentViewportHeight","numeric","parseTailwindHeightClass","resolveExplicitHeight","parsed","target","heightValue","explicitPixelHeight","classHeight","updateHeight","bodyRect","htmlRect","bodyHeight","htmlHeight","contentHeight","explicitHeight","nextHeight","scheduleHeightUpdate","resizeObserver","onFullscreenChange","toggleFullscreen","jsx","SandboxApp","containerClassName","jsxs","ContentRender","Fragment"],"mappings":";;;;;;;AAeA,IAAIA,KAAqE;AAEzE,MAAMC,KAAuB,OACtBD,OACHA,KAA0B,OAAO,2BAAqB,EAAE;AAAA,EACtD,CAACE,MAAMA,EAAE;AAAA,IAINF;AAGL,OAAO,SAAW,OAEfC,GAAA;AAGP,MAAME,KAA0C,MAAM;AACpD,QAAMC,IAAY,YAAY,IAAA,GACxBC,KAAY,oBAAI,KAAA,GAAO,YAAA;AAC7B,iBAAQ,IAAI,sCAAsC,EAAE,WAAAA,EAAA,CAAW,GAExDJ,GAAA,EACJ,KAAK,CAACK,OACL,QAAQ,IAAI,qCAAqC;AAAA,IAC/C,WAAAD;AAAA,IACA,UAAS,oBAAI,KAAA,GAAO,YAAA;AAAA,IACpB,YAAY,QAAQ,YAAY,IAAA,IAAQD,GAAW,QAAQ,CAAC,CAAC;AAAA,EAAA,CAC9D,GACME,EACR,EACA,MAAM,CAACC,MAAU;AAChB,kBAAQ,MAAM,uCAAuC;AAAA,MACnD,WAAAF;AAAA,MACA,UAAS,oBAAI,KAAA,GAAO,YAAA;AAAA,MACpB,YAAY,QAAQ,YAAY,IAAA,IAAQD,GAAW,QAAQ,CAAC,CAAC;AAAA,MAC7D,OAAAG;AAAA,IAAA,CACD,GACKA;AAAA,EACR,CAAC;AACL,GAEMC,KAA6B,iBAC7BC,KAAgC,KAChCC,KAAkC,KAClCC,KACJ,mDACIC,yBAAkC,IAAA,GAClCC,wBAAgC,IAAA,GAEhCC,KAA8B,CAACC,MAAiB;AACpD,QAAMC,IAAU,MAAM,KAAKD,EAAK,SAASJ,EAA6B,CAAC;AACvE,SAAO,MAAM;AAAA,IACX,IAAI;AAAA,MACFK,EACG,IAAI,CAACC,MAAUA,EAAM,CAAC,GAAG,KAAA,CAAM,EAC/B,OAAO,CAACC,MAAuB,EAAQA,CAAI;AAAA,IAAA;AAAA,EAChD;AAEJ,GAEMC,KAAsB,CAACD,MAAgB;AAC3C,MAAI,CAACA;AACH,WAAO,QAAQ,QAAA;AAGjB,QAAME,IAASR,GAA4B,IAAIM,CAAG;AAClD,MAAIE;AACF,WAAOA;AAGT,QAAMC,IAAc,IAAI,QAAc,CAACC,MAAY;AACjD,QAAI,OAAO,SAAW,KAAa;AACjC,MAAAT,EAA0B,IAAIK,CAAG,GACjCI,EAAA;AACA;AAAA,IACF;AAEA,UAAMC,IAAQ,IAAI,OAAO,MAAA;AACzB,IAAAA,EAAM,WAAW,QACjBA,EAAM,UAAU,SAChBA,EAAM,gBAAgB;AAEtB,UAAMC,IAAuB,MAAM;AAMjC,OAJE,OAAOD,EAAM,UAAW,aACpBA,EAAM,OAAA,EAAS,MAAM,MAAA;AAAA,OAAe,IACpC,QAAQ,QAAA,GAEK,QAAQ,MAAM;AAC/B,QAAAV,EAA0B,IAAIK,CAAG,GACjCI,EAAA;AAAA,MACF,CAAC;AAAA,IACH;AAEA,IAAAC,EAAM,SAAS,MAAM;AACnB,MAAAC,EAAA;AAAA,IACF,GACAD,EAAM,UAAU,MAAM;AACpB,MAAAV,EAA0B,IAAIK,CAAG,GACjCI,EAAA;AAAA,IACF,GACAC,EAAM,MAAML,GAERK,EAAM,YAAYA,EAAM,eAAe,KACzCC,EAAA;AAAA,EAEJ,CAAC;AAED,SAAAZ,GAA4B,IAAIM,GAAKG,CAAW,GACzCA;AACT,GAEMI,KAAuB,CAACC,IAAoB,CAAA,MAChD,QAAQ,WAAWA,EAAQ,IAAI,CAACC,MAAWR,GAAoBQ,CAAM,CAAC,CAAC,GAenEC,KAAgC,CAACC,MACrCA,EACG,MAAM,KAAK,EACX,OAAO,OAAO,EACd,IAAI,CAACC,MAAUA,EAAM,MAAM,GAAG,EAAE,IAAA,KAASA,CAAK,GAE7CC,IAAyB,CAACC,MAAkB;AAChD,QAAMC,IAAaD,EAAM,KAAA,EAAO,YAAA;AAChC,MAAI,CAACC,EAAY,QAAO;AACxB,QAAMC,IAAUD,EAAW,MAAM,8BAA8B;AAC/D,SAAKC,IACE,GAAGA,EAAQ,CAAC,CAAC,GAAGA,EAAQ,CAAC,EAAE,YAAA,CAAa,KAD1B;AAEvB,GAEMC,KAAyC,CAACN,MAAsB;AACpE,MAAI,CAACA,EAAU,KAAA,EAAQ,QAAO;AAC9B,QAAMO,IAAmBR,GAA8BC,CAAS;AAChE,MACEO,EAAiB,SAAS,UAAU,KACpCA,EAAiB,SAAS,OAAO,KACjCA,EAAiB,SAAS,cAAc,KACxCA,EAAiB,SAAS,WAAW;AAErC,WAAO;AAET,MACEA,EAAiB,SAAS,OAAO,KACjCA,EAAiB,SAAS,WAAW;AAErC,WAAO;AAET,MACEA,EAAiB,SAAS,OAAO,KACjCA,EAAiB,SAAS,WAAW;AAErC,WAAO;AAET,QAAMC,IAAiBD,EAAiB;AAAA,IAAK,CAACN,MAC5C,2CAA2C,KAAKA,CAAK;AAAA,EAAA;AAEvD,MAAI,CAACO,EAAgB,QAAO;AAC5B,QAAMH,IAAUG,EAAe;AAAA,IAC7B;AAAA,EAAA;AAEF,SAAKH,IACE,GAAGA,EAAQ,CAAC,CAAC,GAAGA,EAAQ,CAAC,EAAE,YAAA,CAAa,KAD1B;AAEvB,GAEMI,yBAAgC,IAAI;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC,GAEKC,KAA6B,CAACC,MAClC,CAACF,GAA0B,IAAIE,EAAQ,QAAQ,aAAa,GAExDC,KAAiC,CAACC,MACtC,MAAM,KAAKA,EAAK,UAAU,EAAE;AAAA,EAC1B,CAACC,MACCA,EAAK,aAAa,KAAK,gBACvBJ,GAA2BI,CAAmB;AAClD,KAAK,MAEDC,KAAoC,CAACF,MAAqB;AAC9D,QAAMG,IAAuB,CAAA;AAC7B,MAAIC,IAAUL,GAA+BC,CAAI;AAEjD,SAAOI,KAAS;AACd,IAAAD,EAAM,KAAKC,CAAO;AAElB,UAAMC,IAAgB,MAAM,KAAKD,EAAQ,QAAQ,EAAE;AAAA,MACjD,CAACN,MAAoCD,GAA2BC,CAAO;AAAA,IAAA;AAGzE,QAAIO,EAAc,WAAW;AAC3B;AAGF,IAAAD,IAAUC,EAAc,CAAC;AAAA,EAC3B;AAEA,SAAOF;AACT,GAEMG,KAAmC,CAACR,MAAyB;AACjE,QAAMS,IAAkBT,EAAQ,aAAa,QAAQ,GAC/CU,IAAqBD,IACvBlB,EAAuBkB,CAAe,IACtC;AAEJ,MAAIC;AACF,WAAOA;AAGT,QAAMC,IACJX,EAAQ,aAAa,OAAO,GAAG,MAAM,yBAAyB,IAAI,CAAC,KACnE,MACIY,IAAsBD,IACxBpB,EAAuBoB,CAAgB,IACvC;AAEJ,SAAIC,KAIGjB;AAAA,IACLK,EAAQ,aAAa,OAAO,KAAK;AAAA,EAAA;AAErC,GAEMa,KAA0B,CAACrB,MAC/BA,MAAU,WACVA,MAAU,YACVA,MAAU,YACVA,MAAU,UAENsB,KAA8B,CAACZ,MAAqB;AACxD,QAAMa,IAAsBX,GAAkCF,CAAI;AAClE,MAAIc,IAAmC,MACnCC,IAAwB;AAE5B,SAAAF,EAAoB,QAAQ,CAACf,MAAY;AACvC,UAAMkB,IAAwBV,GAAiCR,CAAO;AAEtE,IAAI,CAACgB,KAAqBE,MACxBF,IAAoBE,IAGlBL,GAAwBK,CAAqB,MAC/CD,IAAwB;AAAA,EAE5B,CAAC,GAEM;AAAA,IACL,mBAAAD;AAAA,IACA,uBAAAC;AAAA,EAAA;AAEJ,GAEME,KAAkC,CAAC5C,MAAiB;AACxD,QAAMkB,IAAalB,EAAK,KAAA;AAExB,MAAI,CAACkB;AACH,WAAO;AAAA,MACL,mBAAmB;AAAA,MACnB,uBAAuB;AAAA,IAAA;AAK3B,QAAM2B,IADY3B,EAAW,MAAM,iCAAiC,IAC1C,CAAC,KAAK,IAC1BgB,IAAkBW,EAAM,MAAM,kCAAkC,IAAI,CAAC,GAErET,IADiBS,EAAM,MAAM,iCAAiC,IAAI,CAAC,GAChC;AAAA,IACvC;AAAA,EAAA,IACE,CAAC,GACCC,IAAiBD,EAAM,MAAM,iCAAiC,IAAI,CAAC,GACnEJ,KACHP,IAAkBlB,EAAuBkB,CAAe,IAAI,UAC5DE,IAAmBpB,EAAuBoB,CAAgB,IAAI,UAC9DU,IACG1B,GAAuC0B,CAAc,IACrD;AAEN,SAAO;AAAA,IACL,mBAAAL;AAAA,IACA,uBAAuBH,GAAwBG,CAAiB;AAAA,EAAA;AAEpE,GAEMM,KAAsC,CAAC/C,MAAiB;AAC5D,QAAMkB,IAAalB,EAAK,KAAA;AAExB,MAAI,CAACkB;AACH,WAAO;AAAA,MACL,mBAAmB;AAAA,MACnB,uBAAuB;AAAA,IAAA;AAI3B,MAAI,OAAO,WAAa;AACtB,WAAO0B,GAAgC1B,CAAU;AAGnD,QAAM8B,IAAW,SAAS,cAAc,UAAU;AAClD,SAAAA,EAAS,YAAY9B,GAEdqB,GAA4BS,EAAS,OAAO;AACrD,GAEMC,KAA+B,CAACnC,MACpCA,EACG,MAAM,KAAK,EACX,OAAO,OAAO,EACd,IAAI,CAACC,MAAU;AACd,QAAMmC,IAAWnC,EAAM,MAAM,GAAG;AAChC,SACEmC,EAASA,EAAS,SAAS,CAAC,MAAM,cAClCA,EAASA,EAAS,SAAS,CAAC,MAAM,iBAE3BnC,KAETmC,EAASA,EAAS,SAAS,CAAC,IAAI,UACzBA,EAAS,KAAK,GAAG;AAC1B,CAAC,EACA,KAAK,GAAG,GAEPC,KAAuC,CAC3CnD,GACAoD,MAEI,CAACA,KAAW,CAACpD,EAAK,SACbA,IAGFA,EAAK;AAAA,EACV;AAAA,EACA,CAACE,GAAOmD,GAAkBR,IAAQ,OAAO;AACvC,UAAMS,IAAaT,EAAM,MAAM,iCAAiC;AAEhE,QAAI,CAACS;AACH,aAAOpD;AAGT,UAAMqD,IAAgBN,GAA6BK,EAAW,CAAC,CAAC;AAEhE,WAAIC,MAAkBD,EAAW,CAAC,IACzBpD,IAGF,GAAGmD,CAAQ,GAAGR,EAAM;AAAA,MACzBS,EAAW,CAAC;AAAA,MACZ,SAASA,EAAW,CAAC,CAAC,GAAGC,CAAa,GAAGD,EAAW,CAAC,CAAC;AAAA,IAAA,CACvD;AAAA,EACH;AAAA,GAIEE,KAA8C,CAAC;AAAA,EACnD,SAAAC;AAAA,EACA,MAAAC;AAAA,EACA,WAAA5C;AAAA,EACA,aAAA6C;AAAA,EACA,kBAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,sBAAAC;AAAA,EACA,gBAAAC,IAAiB;AAAA,EACjB,MAAAC,IAAO;AAAA,EACP,iCAAAC,IAAkC;AACpC,MAAM;AACJ,QAAMC,KAAeC,EAAuB,IAAI,GAC1CC,IAAYD,EAA0B,IAAI,GAC1CE,IAAUF,EAAoB,IAAI,GAClCG,KAASH,EAAwB,IAAI,GACrCI,IAAkBJ,EAAmB,MAAM;AAAA,EAAC,CAAC,GAC7C,CAACK,IAAQC,EAAS,IAAIC,EAAS,GAAG,GAClCC,KAAgCR,EAAO,CAAC,GACxC,CAACS,IAAYC,EAAa,IAAIH,EAAS,CAAC,GACxC,CAACI,IAAcC,EAAe,IAAIL,EAAS,EAAK,GAChD,GAAGM,CAAuB,IAAIN,EAAS,EAAI,GAC3CO,KAA4BvB,MAAS,WAErCwB,IAAmBlB,MAAS,cAC5BmB,IAAchB,EAAe,EAAE,GAC/BiB,IAAcC,EAAM,QAAQ,MAAM;AAGtC,UAAMC,IAFWC,GAAqB9B,CAAO,EAEZ,OAAO,CAAC+B,MAAQA,EAAI,SAAS,SAAS;AAKvE,YAHExB,MAAS,eACLsB,EAAgBA,EAAgB,SAAS,CAAC,GAAG,SAAS,KACtDA,EAAgB,IAAI,CAACE,MAAQA,EAAI,KAAK,EAAE,KAAK;AAAA,CAAI,MAC9B;AAAA,EAC3B,GAAG,CAAC/B,GAASO,CAAI,CAAC,GACZyB,IAAwBJ,EAAM;AAAA,IAClC,MACElC;AAAA,MACEiC;AAAA,MACAnB;AAAA,IAAA;AAAA,IAEJ,CAACmB,GAAanB,CAA+B;AAAA,EAAA,GAEzCyB,IAAuBL,EAAM;AAAA,IACjC,MAAMtF,GAA4B0F,CAAqB;AAAA,IACvD,CAACA,CAAqB;AAAA,EAAA,GAElBE,KAAiBN,EAAM;AAAA,IAC3B,MAAMtC,GAAoCqC,CAAW;AAAA,IACrD,CAACA,CAAW;AAAA,EAAA,GAERQ,KAA0BP,EAAM;AAAA,IACpC,MACEpB,KAAmC0B,GAAe;AAAA,IACpD,CAACA,GAAe,uBAAuB1B,CAA+B;AAAA,EAAA,GAElE,CAAC4B,GAAmBC,CAAoB,IAAIpB;AAAA,IAChDe;AAAA,EAAA,GAEIM,KAAsB5B,EAAOsB,CAAqB,GAClDO,IAAiB7B,EAAOsB,CAAqB,GAC7CQ,IAAsB9B,EAAsB,IAAI,GAChD+B,IAAuB/B,EAAsB,IAAI,GACjDgC,IAA6BhC,EAAsB,IAAI,GACvDiC,IAA2BjC,EAAO,CAAC,GAEnCkC,IAAyBC,GAAY,CAACC,MAAsB;AAChE,QAAI,OAAO,SAAW;AACpB;AAEF,UAAMC,IAAM,KAAK,IAAA;AACjB,IACEA,IAAM7B,GAA8B,UACpChF,OAIFgF,GAA8B,UAAU6B,GACxC,OAAO;AAAA,MACL;AAAA,QACE,QAAQC;AAAA,QACR,MAAMC;AAAA,QACN,WAAAH;AAAA,MAAA;AAAA,MAEF,OAAO,SAAS;AAAA,IAAA;AAAA,EAEpB,GAAG,CAAA,CAAE,GAECI,KAA2B,MAAM;AACrC,IAAIV,EAAoB,YAAY,SACpC,OAAO,aAAaA,EAAoB,OAAO,GAC/CA,EAAoB,UAAU;AAAA,EAChC,GAEMW,KAA0B,MAAM;AACpC,IAAIV,EAAqB,YAAY,SACnC,OAAO,qBAAqBA,EAAqB,OAAO,GACxDA,EAAqB,UAAU,OAE7BC,EAA2B,YAAY,SACzC,OAAO,qBAAqBA,EAA2B,OAAO,GAC9DA,EAA2B,UAAU;AAAA,EAEzC;AAEA,EAAAU;AAAA,IACE,MAAM,MAAM;AACV,MAAAF,GAAA,GACAC,GAAA;AAAA,IACF;AAAA,IACA,CAAA;AAAA,EAAC,GAGHC,EAAU,MAAM;AACd,IAAKnG,GAAqBgF,CAAoB;AAAA,EAChD,GAAG,CAACA,CAAoB,CAAC,GAEzBmB,EAAU,MAAM;AACd,UAAMC,IAAmBf,GAAoB;AAC7C,IAAAA,GAAoB,UAAUN;AAE9B,UAAMsB,IACJ,CAAC,CAACD,KACFrB,EAAsB,SAASqB,EAAiB,UAChDrB,EAAsB,WAAWqB,CAAgB,GAC7CE,IAAwBvH,GAA2B;AAAA,MACvDgG;AAAA,IAAA,GAEIwB,IACJF,KACAC,KACAtB,EAAqB;AAAA,MACnB,CAAC9E,MAAW,CAACd,EAA0B,IAAIc,CAAM;AAAA,IAAA,GAE/CsG,IAAoBH,KAAsBC;AAKhD,QAHAhB,EAAe,UAAUP,GACzBkB,GAAA,GAEIM,GAAwB;AAC1B,YAAME,IAAYf,EAAyB,UAAU;AACrD,MAAAA,EAAyB,UAAUe,GAE9BzG,GAAqBgF,CAAoB,EAAE,KAAK,MAAM;AACzD,QAAIU,EAAyB,YAAYe,KAIzCrB,EAAqBE,EAAe,OAAO;AAAA,MAC7C,CAAC;AACD;AAAA,IACF;AAEA,QAAI,CAACkB,GAAmB;AACtB,MAAApB,EAAqBL,CAAqB;AAC1C;AAAA,IACF;AAEA,IAAAQ,EAAoB,UAAU,OAAO,WAAW,MAAM;AACpD,MAAAH,EAAqBE,EAAe,OAAO,GAC3CC,EAAoB,UAAU;AAAA,IAChC,GAAGvG,EAA6B;AAAA,EAClC,GAAG,CAACgG,GAAsBD,CAAqB,CAAC;AAEhD,QAAM2B,KAAwB/B,EAAM;AAAA,IAClC,MACEtC,GAAoC8C,CAAiB,EAAE;AAAA,IACzD,CAACA,CAAiB;AAAA,EAAA,GAEdwB,KAAkB,EAAQD,IAC1BE,IACJpC,KAAoBxB,MAAS,YACzBkC,KACE,SACCwB,MAAyB,GAAG5C,EAAM,OACrC;AAEN,EAAAqC,EAAU,MAAM;AACd,QAAI7C,MAAS,cAAc;AACzB,MAAAmB,EAAY,UAAUM;AACtB;AAAA,IACF;AACA,UAAM8B,IAAOpC,EAAY;AAEzB,IAAI,EADmBoC,KAAQ9B,EAAsB,WAAW8B,CAAI,MAC7CA,KACrB1C,GAAc,CAAC9D,MAAUA,IAAQ,CAAC,GAEpCoE,EAAY,UAAUM;AAAA,EACxB,GAAG,CAACzB,GAAMyB,CAAqB,CAAC,GAEhCoB,EAAU,MAAM;AACd,UAAMW,IAASpD,EAAU;AACzB,QAAI,CAACoD,EAAQ;AAEb,UAAMC,IAAMD,EAAO;AACnB,QAAI,CAACC,EAAK;AAEV,IAAAA,EAAI,KAAA,GACJA,EAAI,MAAM;AAAA,OACPzD,MAAS,eAAe,2BAA2B,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAcpD,GACJyD,EAAI,MAAA,GAGJA,EAAI,gBAAgB,aAAa,cAAc,OAAO,GACtDA,EAAI,gBAAgB,MAAM,cAAc,SACxCA,EAAI,MAAM,MAAM,YAAY,gBAAgB,OAAO,GAEnDnD,GAAO,UAAUmD;AAEjB,UAAMC,IACJxC,KAAoBxB,MAAS,WACzBiE,IAA2B,MAC/BtB,EAAuB,aAAa,GAChCuB,IAAyB,MAAMvB,EAAuB,WAAW,GACjEwB,IAA0B,MAAMxB,EAAuB,YAAY;AAEzE,IAAIqB,MACFD,EAAI,iBAAiB,eAAeE,GAA0B,EAAI,GAClEF,EAAI,iBAAiB,aAAaG,GAAwB,EAAI,GAC9DH,EAAI,iBAAiB,cAAcI,GAAyB,EAAI;AAGlE,UAAMC,IAASL,EAAI,eAAe,MAAM;AACxC,QAAI,CAACK,EAAQ;AAEb,UAAMnG,KAAOoG,GAAWD,CAAM;AAC9B,IAAAzD,EAAQ,UAAU1C;AAClB,QAAIqG,IAAc;AAElB,UAAMC,IAAsB,CAC1BhH,GACAiH,MACG;AACH,YAAMhH,IAAaD,EAAM,KAAA,EAAO,YAAA;AAChC,UAAI,CAACC,EAAY,QAAO;AACxB,YAAMiH,IAAU,OAAO,WAAWjH,CAAU;AAC5C,aAAI,OAAO,MAAMiH,CAAO,IAAU,OAC9B,qBAAqB,KAAKjH,CAAU,IAC9BiH,IAAU,MAAOD,IAEvBhH,EAAW,SAAS,IAAI,KAAK,YAAY,KAAKA,CAAU,IACnDiH,IAEF;AAAA,IACT,GACMC,KAA2B,CAC/BtH,GACAoH,MACG;AACH,UAAI,CAACpH,EAAU,KAAA,EAAQ,QAAO;AAC9B,YAAM2B,IACJrB,GAAuCN,CAAS;AAClD,UAAI2B;AACF,eAAOwF,EAAoBxF,GAAmByF,CAAoB;AAGpE,YAAM5G,IADmBT,GAA8BC,CAAS,EACxB;AAAA,QAAK,CAACC,MAC5C,qBAAqB,KAAKA,CAAK;AAAA,MAAA;AAEjC,UAAI,CAACO,EAAgB,QAAO;AAC5B,YAAMH,IAAUG,EAAe,MAAM,sBAAsB;AAC3D,UAAI,CAACH,EAAS,QAAO;AACrB,YAAMgH,IAAU,OAAO,WAAWhH,EAAQ,CAAC,CAAC;AAC5C,aAAI,OAAO,MAAMgH,CAAO,IAAU,OAC3BA;AAAA,IACT,GAEME,KAAwB,MAAM;AAClC,UAAI,CAACjE,EAAU,WAAW,CAACqD,EAAI,KAAM,QAAO;AAC5C,YAAMS,IACJ9D,EAAU,QAAQ,eAAe,iBAAiB,gBAClD,OAAO,aACH,EAAE,mBAAA3B,EAAA,IAAsBF,GAA4BkF,EAAI,IAAI,GAC5Da,IAAS7F,IACXwF,EAAoBxF,GAAmByF,CAAoB,IAC3D;AAEJ,UAAII,MAAW;AACb,eAAO,KAAK,KAAKA,CAAM;AAMzB,YAAMC,IAHUd,EAAI,KAAK;AAAA,QACvB;AAAA,MAAA,GAEsB;AAAA,QACtB;AAAA,MAAA;AAGF,UAAI,CAACc,EAAQ,QAAO;AAEpB,YAAMC,IAAcD,EAAO,MAAM,UAAUA,EAAO,aAAa,QAAQ,GACjEE,IAAsBD,IACxBP,EAAoBO,GAAaN,CAAoB,IACrD;AAEJ,UAAIO,MAAwB;AAC1B,eAAO,KAAK,KAAKA,CAAmB;AAGtC,YAAMC,IAAcN;AAAA,QAClBG,EAAO,aAAa,OAAO,KAAK;AAAA,QAChCL;AAAA,MAAA;AAGF,aAAOQ,MAAgB,OAAO,KAAK,KAAKA,CAAW,IAAI;AAAA,IACzD,GAEMC,IAAe,MAAM;AACzB,UAAI,CAACvE,EAAU,WAAW,CAACqD,EAAI,KAAM;AACrC,YAAMmB,IAAWnB,EAAI,KAAK,sBAAA,GACpBoB,IAAWpB,EAAI,iBAAiB,sBAAA,GAChCqB,IAAaF,EAAS,QACtBG,IAAaF,GAAU,UAAU,GACjCG,IAAgB,KAAK,IAAIF,GAAYC,CAAU,GAC/CE,IAAiBZ,GAAA,GACjBa,IAAa,KAAK;AAAA,QACtB;AAAA,QACAD,KAAkB,KAAK,KAAKD,CAAa;AAAA,MAAA;AAE3C,MAAAvE,GAAUyE,CAAU;AAAA,IACtB,GACMC,IAAuB,MAAM;AACjC,4BAAsB,MAAM;AAC1B,QAAInB,KACJW,EAAA;AAAA,MACF,CAAC;AAAA,IACH;AACA,IAAApE,EAAgB,UAAU4E,GAE1BR,EAAA,GACAQ,EAAA,GAEKlE,KAIH7F,GAAA,EACG,KAAK,CAACG,MAAW;AAChB,MAAIyI,MACJzI,EAAOkI,CAAG,GACV,sBAAsB,MAAM;AAC1B,QAAIO,MACJhD,EAAwB,EAAI,GAC5BmE,EAAA;AAAA,MACF,CAAC;AAAA,IACH,CAAC,EACA,MAAM,MAAM;AACX,MAAInB,MACJhD,EAAwB,EAAI,GAC5BmE,EAAA;AAAA,IACF,CAAC,IAjBHnE,EAAwB,EAAI;AAoB9B,UAAMoE,KAAiB,IAAI,eAAe,MAAMT,GAAc;AAC9D,WAAAS,GAAe,QAAQ3B,EAAI,IAAI,GAC3BK,KACFsB,GAAe,QAAQtB,CAAM,GAGxB,MAAM;AACX,MAAAE,IAAc,IACdoB,GAAe,WAAA,GACX1B,MACFD,EAAI,oBAAoB,eAAeE,GAA0B,EAAI,GACrEF,EAAI,oBAAoB,aAAaG,GAAwB,EAAI,GACjEH,EAAI,oBAAoB,cAAcI,GAAyB,EAAI,IAGrE,WAAW,MAAM;AACf,QAAAlG,GAAK,QAAA,GACL0C,EAAQ,UAAU,MAClBC,GAAO,UAAU,MACjBC,EAAgB,UAAU,MAAM;AAAA,QAAC;AAAA,MACnC,GAAG,CAAC;AAAA,IACN;AAAA,EACF,GAAG,CAAA,CAAE,GAELsC,EAAU,MAAM;AACd,UAAMwC,IAAqB,MAAM;AAC/B,MAAAtE,GAAgB,EAAQ,SAAS,iBAAkB;AAAA,IACrD;AACA,oBAAS,iBAAiB,oBAAoBsE,CAAkB,GACzD,MACL,SAAS,oBAAoB,oBAAoBA,CAAkB;AAAA,EACvE,GAAG,CAAA,CAAE;AAEL,QAAMC,KAAmB,MAAM;AAC7B,UAAMf,IAASrE,GAAa,WAAWE,EAAU;AACjD,QAAKmE,GACL;AAAA,UAAI,SAAS,mBAAmB;AAC9B,iBAAS,iBAAiB,MAAM,MAAM;AAAA,QAAC,CAAC;AACxC;AAAA,MACF;AACA,MAAIA,EAAO,qBACTA,EAAO,oBAAoB,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA;AAAA,EAE7C;AAEA,EAAA1B,EAAU,MAAM;AACd,UAAMlF,IAAO0C,EAAQ;AACrB,IAAK1C,MAELA,EAAK;AAAA,MACH4H,gBAAAA,EAAAA;AAAAA,QAACC;AAAA,QAAA;AAAA,UACC,MAAM3D;AAAA,UACN,aAAAlC;AAAA,UACA,kBAAAC;AAAA,UACA,mBAAAC;AAAA,UACA,sBAAAC;AAAA,UACA,gBAAAC;AAAA,UACA,YAAAa;AAAA,UACA,iBAAAyC;AAAA,UACA,MAAArD;AAAA,UACA,mBAAmB4B;AAAA,QAAA;AAAA,MAAA;AAAA,IACrB,GAGFM,EAAqB,UAAU,OAAO,sBAAsB,MAAM;AAChE,MAAA3B,EAAgB,UAAA,GAChB2B,EAAqB,UAAU;AAAA,IACjC,CAAC;AAAA,EACH,GAAG;AAAA,IACDL;AAAA,IACAlC;AAAA,IACAC;AAAA,IACAC;AAAA,IACAC;AAAA,IACAc;AAAA,IACAZ;AAAA,EAAA,CACD;AACD,QAAMyF,KAAqB;AAAA,IACzB;AAAA,IACAvE,IACI,uCACA;AAAA,EAAA,EAEH,OAAO,OAAO,EACd,KAAK,GAAG;AAIX,SACEwE,gBAAAA,EAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKxF;AAAA,MACL,gBAAcmD,KAAkB,SAAS;AAAA,MACzC,WAAWoC;AAAA,MACX,OACEnC,IACI;AAAA,QACE,QAAQA;AAAA,QACR,WAAWA;AAAA,MAAA,IAEb;AAAA,MAGL,UAAA;AAAA,QAAA,CAACvD,KACAwF,gBAAAA,EAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAASD;AAAA,YACT,WACE;AAAA,YAGD,UAAAxE,KAAe,SAAShB,KAAwB;AAAA,UAAA;AAAA,QAAA;AAAA,QAGpDE,MAAS,gBAAgBN,MAAS,aACjC6F,gBAAAA,EAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,aAAa,MAAMlD,EAAuB,WAAW;AAAA,YACrD,eAAe,MAAMA,EAAuB,aAAa;AAAA,YACzD,cAAc,MAAMA,EAAuB,YAAY;AAAA,YAEvD,UAAAkD,gBAAAA,EAAAA,IAACI,MAAc,SAAAlG,EAAA,CAAkB;AAAA,UAAA;AAAA,QAAA,IAGnCiG,gBAAAA,EAAAA,KAAAE,YAAA,EACG,UAAA;AAAA,UAcG;AAAA,UACJL,gBAAAA,EAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAKnF;AAAA,cACL,SAAQ;AAAA,cACR,OAAM;AAAA,cACN,iBAAe;AAAA,cACf,WAAW,CAACtD,GAAW,qCAAqC,EACzD,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,cACX,OAAO;AAAA,gBACL,QAAQwG,KAAyB;AAAA,gBACjC,WAAWA;AAAA,gBACX,QAAQ;AAAA,gBACR,YAAY;AAAA,cAAA;AAAA,YACd;AAAA,UAAA;AAAA,UASE;AAAA,QAAA,EAAA,CACN;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;"}
1
+ {"version":3,"file":"IframeSandbox.es.js","sources":["../../../src/components/ContentRender/IframeSandbox.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createRoot, Root } from \"react-dom/client\";\nimport { Loader2 } from \"lucide-react\";\nimport SandboxApp from \"./SandboxApp\";\nimport { splitContentSegments } from \"./utils/split-content\";\nimport ContentRender from \"./ContentRender\";\nimport {\n SANDBOX_INTERACTION_MESSAGE_SOURCE,\n SANDBOX_INTERACTION_MESSAGE_TYPE,\n} from \"../../lib/sandboxInteraction\";\n\ntype InjectBlackboardLibraries =\n typeof import(\"./blackboard-vendor\").injectBlackboardLibraries;\n\n// Cache the sandbox vendor loader so every iframe reuses the same preload request.\nlet blackboardVendorPromise: Promise<InjectBlackboardLibraries> | null = null;\n\nconst loadBlackboardVendor = () => {\n if (!blackboardVendorPromise) {\n blackboardVendorPromise = import(\"./blackboard-vendor\").then(\n (m) => m.injectBlackboardLibraries\n );\n }\n\n return blackboardVendorPromise;\n};\n\nconst loadBlackboardVendorOnDemandWithMetrics = () => {\n const loadStart = performance.now();\n const startedAt = new Date().toISOString();\n console.log(\"[IframeSandbox][SandboxLoad] start\", { startedAt });\n\n return loadBlackboardVendor()\n .then((inject) => {\n console.log(\"[IframeSandbox][SandboxLoad] done\", {\n startedAt,\n endedAt: new Date().toISOString(),\n durationMs: Number((performance.now() - loadStart).toFixed(2)),\n });\n return inject;\n })\n .catch((error) => {\n console.error(\"[IframeSandbox][SandboxLoad] failed\", {\n startedAt,\n endedAt: new Date().toISOString(),\n durationMs: Number((performance.now() - loadStart).toFixed(2)),\n error,\n });\n throw error;\n });\n};\n\nconst COMPLETE_IMAGE_TAG_PATTERN = /<img\\b[^>]*>/i;\nconst POST_IMAGE_STREAM_DEBOUNCE_MS = 180;\nconst SANDBOX_INTERACTION_THROTTLE_MS = 240;\n\nexport interface IframeSandboxProps {\n content: string;\n className?: string;\n loadingText?: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n fullScreenButtonText?: string;\n hideFullScreen?: boolean;\n mode?: \"content\" | \"blackboard\";\n type: \"sandbox\" | \"markdown\";\n replaceRootScreenHeightWithFull?: boolean;\n}\n\nconst normalizeTailwindHeightTokens = (className: string) =>\n className\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => token.split(\":\").pop() || token);\n\nconst parseViewportHeightCss = (value: string) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const matched = normalized.match(/^([0-9.]+)(vh|dvh|svh|lvh)$/i);\n if (!matched) return null;\n return `${matched[1]}${matched[2].toLowerCase()}`;\n};\n\nconst extractViewportHeightFromTailwindClass = (className: string) => {\n if (!className.trim()) return null;\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n if (\n normalizedTokens.includes(\"h-screen\") ||\n normalizedTokens.includes(\"h-dvh\") ||\n normalizedTokens.includes(\"min-h-screen\") ||\n normalizedTokens.includes(\"min-h-dvh\")\n ) {\n return \"100dvh\";\n }\n if (\n normalizedTokens.includes(\"h-svh\") ||\n normalizedTokens.includes(\"min-h-svh\")\n ) {\n return \"100svh\";\n }\n if (\n normalizedTokens.includes(\"h-lvh\") ||\n normalizedTokens.includes(\"min-h-lvh\")\n ) {\n return \"100lvh\";\n }\n const arbitraryToken = normalizedTokens.find((token) =>\n /^(h|min-h)-\\[[0-9.]+(vh|dvh|svh|lvh)\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(\n /^(h|min-h)-\\[([0-9.]+)(vh|dvh|svh|lvh)\\]$/i\n );\n if (!matched) return null;\n return `${matched[2]}${matched[3].toLowerCase()}`;\n};\n\nconst SANDBOX_IGNORED_TAG_NAMES = new Set([\n \"base\",\n \"link\",\n \"meta\",\n \"script\",\n \"style\",\n \"template\",\n \"title\",\n]);\n\nconst isSandboxRenderableElement = (element: Element) =>\n !SANDBOX_IGNORED_TAG_NAMES.has(element.tagName.toLowerCase());\n\nconst getFirstRenderableElementChild = (root: ParentNode) =>\n Array.from(root.childNodes).find(\n (node): node is HTMLElement =>\n node.nodeType === Node.ELEMENT_NODE &&\n isSandboxRenderableElement(node as HTMLElement)\n ) || null;\n\nconst getInspectableSandboxElementChain = (root: ParentNode) => {\n const chain: HTMLElement[] = [];\n let current = getFirstRenderableElementChild(root);\n\n while (current) {\n chain.push(current);\n\n const childElements = Array.from(current.children).filter(\n (element): element is HTMLElement => isSandboxRenderableElement(element)\n );\n\n if (childElements.length !== 1) {\n break;\n }\n\n current = childElements[0];\n }\n\n return chain;\n};\n\nconst extractViewportHeightFromElement = (element: HTMLElement) => {\n const heightAttrValue = element.getAttribute(\"height\");\n const attrViewportHeight = heightAttrValue\n ? parseViewportHeightCss(heightAttrValue)\n : null;\n\n if (attrViewportHeight) {\n return attrViewportHeight;\n }\n\n const styleHeightValue =\n element.getAttribute(\"style\")?.match(/\\bheight\\s*:\\s*([^;]+)/i)?.[1] ||\n null;\n const styleViewportHeight = styleHeightValue\n ? parseViewportHeightCss(styleHeightValue)\n : null;\n\n if (styleViewportHeight) {\n return styleViewportHeight;\n }\n\n return extractViewportHeightFromTailwindClass(\n element.getAttribute(\"class\") || \"\"\n );\n};\n\nconst isFullViewportHeightCss = (value: string | null) =>\n value === \"100vh\" ||\n value === \"100dvh\" ||\n value === \"100svh\" ||\n value === \"100lvh\";\n\nconst inspectSandboxPrimaryHeight = (root: ParentNode) => {\n const inspectableElements = getInspectableSandboxElementChain(root);\n let viewportHeightCss: string | null = null;\n let hasFullViewportHeight = false;\n\n inspectableElements.forEach((element) => {\n const elementViewportHeight = extractViewportHeightFromElement(element);\n\n if (!viewportHeightCss && elementViewportHeight) {\n viewportHeightCss = elementViewportHeight;\n }\n\n if (isFullViewportHeightCss(elementViewportHeight)) {\n hasFullViewportHeight = true;\n }\n });\n\n return {\n viewportHeightCss,\n hasFullViewportHeight,\n };\n};\n\nconst inspectRootHeightFromHtmlString = (html: string) => {\n const normalized = html.trim();\n\n if (!normalized) {\n return {\n viewportHeightCss: null,\n hasFullViewportHeight: false,\n };\n }\n\n const rootMatch = normalized.match(/^<([a-zA-Z][\\w:-]*)(\\s[^>]*?)?>/);\n const attrs = rootMatch?.[2] || \"\";\n const heightAttrValue = attrs.match(/\\bheight\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const styleAttrValue = attrs.match(/\\bstyle\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const styleHeightValue = styleAttrValue?.match(\n /\\bheight\\s*:\\s*([^;]+)/i\n )?.[1];\n const classAttrValue = attrs.match(/\\bclass\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n const viewportHeightCss =\n (heightAttrValue ? parseViewportHeightCss(heightAttrValue) : null) ||\n (styleHeightValue ? parseViewportHeightCss(styleHeightValue) : null) ||\n (classAttrValue\n ? extractViewportHeightFromTailwindClass(classAttrValue)\n : null);\n\n return {\n viewportHeightCss,\n hasFullViewportHeight: isFullViewportHeightCss(viewportHeightCss),\n };\n};\n\nconst inspectSandboxPrimaryHeightFromHtml = (html: string) => {\n const normalized = html.trim();\n\n if (!normalized) {\n return {\n viewportHeightCss: null,\n hasFullViewportHeight: false,\n };\n }\n\n if (typeof document === \"undefined\") {\n return inspectRootHeightFromHtmlString(normalized);\n }\n\n const template = document.createElement(\"template\");\n template.innerHTML = normalized;\n\n return inspectSandboxPrimaryHeight(template.content);\n};\n\nconst replaceRootScreenHeightToken = (className: string) =>\n className\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => {\n const segments = token.split(\":\");\n if (\n segments[segments.length - 1] !== \"h-screen\" &&\n segments[segments.length - 1] !== \"min-h-screen\"\n ) {\n return token;\n }\n segments[segments.length - 1] = \"h-full\";\n return segments.join(\":\");\n })\n .join(\" \");\n\nconst replaceRootScreenHeightWithFullClass = (\n html: string,\n enabled: boolean\n) => {\n if (!enabled || !html.trim()) {\n return html;\n }\n\n return html.replace(\n /^(\\s*<[a-zA-Z][\\w:-]*)(\\s[^>]*?)?>/,\n (match, tagStart: string, attrs = \"\") => {\n const classMatch = attrs.match(/\\bclass\\s*=\\s*([\"'])([^\"']*)\\1/i);\n\n if (!classMatch) {\n return match;\n }\n\n const nextClassName = replaceRootScreenHeightToken(classMatch[2]);\n\n if (nextClassName === classMatch[2]) {\n return match;\n }\n\n return `${tagStart}${attrs.replace(\n classMatch[0],\n `class=${classMatch[1]}${nextClassName}${classMatch[1]}`\n )}>`;\n }\n );\n};\n\nconst IframeSandbox: React.FC<IframeSandboxProps> = ({\n content,\n type,\n className,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n hideFullScreen = false,\n mode = \"content\",\n replaceRootScreenHeightWithFull = false,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const rootRef = useRef<Root | null>(null);\n const docRef = useRef<Document | null>(null);\n const updateHeightRef = useRef<() => void>(() => {});\n const [height, setHeight] = useState(480);\n const lastSandboxInteractionTimeRef = useRef(0);\n const [resetToken, setResetToken] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [, setIsSandboxVendorReady] = useState(true);\n const shouldInjectSandboxVendor = type === \"sandbox\";\n\n const isBlackboardMode = mode === \"blackboard\";\n const prevHtmlRef = useRef<string>(\"\");\n const htmlContent = React.useMemo(() => {\n const segments = splitContentSegments(content);\n // console.log('segments=====', segments);\n const sandboxSegments = segments.filter((seg) => seg.type === \"sandbox\");\n const sandboxContent =\n mode === \"blackboard\"\n ? sandboxSegments[sandboxSegments.length - 1]?.value || \"\"\n : sandboxSegments.map((seg) => seg.value).join(\"\\n\");\n return sandboxContent || \"\";\n }, [content, mode]);\n const normalizedHtmlContent = React.useMemo(\n () =>\n replaceRootScreenHeightWithFullClass(\n htmlContent,\n replaceRootScreenHeightWithFull\n ),\n [htmlContent, replaceRootScreenHeightWithFull]\n );\n const htmlHeightMeta = React.useMemo(\n () => inspectSandboxPrimaryHeightFromHtml(htmlContent),\n [htmlContent]\n );\n const shouldStretchRootHeight = React.useMemo(\n () =>\n replaceRootScreenHeightWithFull && htmlHeightMeta.hasFullViewportHeight,\n [htmlHeightMeta.hasFullViewportHeight, replaceRootScreenHeightWithFull]\n );\n const [renderHtmlContent, setRenderHtmlContent] = useState(\n normalizedHtmlContent\n );\n const prevIncomingHtmlRef = useRef(normalizedHtmlContent);\n const pendingHtmlRef = useRef(normalizedHtmlContent);\n const deferRenderTimerRef = useRef<number | null>(null);\n const initialPaintFrameRef = useRef<number | null>(null);\n\n const emitSandboxInteraction = useCallback((eventType: string) => {\n if (typeof window === \"undefined\") {\n return;\n }\n const now = Date.now();\n if (\n now - lastSandboxInteractionTimeRef.current <\n SANDBOX_INTERACTION_THROTTLE_MS\n ) {\n return;\n }\n lastSandboxInteractionTimeRef.current = now;\n window.postMessage(\n {\n source: SANDBOX_INTERACTION_MESSAGE_SOURCE,\n type: SANDBOX_INTERACTION_MESSAGE_TYPE,\n eventType,\n },\n window.location.origin\n );\n }, []);\n\n const clearDeferredRenderTimer = () => {\n if (deferRenderTimerRef.current === null) return;\n window.clearTimeout(deferRenderTimerRef.current);\n deferRenderTimerRef.current = null;\n };\n\n const clearInitialPaintFrames = () => {\n if (initialPaintFrameRef.current !== null) {\n window.cancelAnimationFrame(initialPaintFrameRef.current);\n initialPaintFrameRef.current = null;\n }\n };\n\n useEffect(\n () => () => {\n clearDeferredRenderTimer();\n clearInitialPaintFrames();\n },\n []\n );\n\n useEffect(() => {\n const prevIncomingHtml = prevIncomingHtmlRef.current;\n prevIncomingHtmlRef.current = normalizedHtmlContent;\n\n const isAppendOnlyStream =\n !!prevIncomingHtml &&\n normalizedHtmlContent.length > prevIncomingHtml.length &&\n normalizedHtmlContent.startsWith(prevIncomingHtml);\n const containsCompleteImage = COMPLETE_IMAGE_TAG_PATTERN.test(\n normalizedHtmlContent\n );\n const shouldDeferRender = isAppendOnlyStream && containsCompleteImage;\n\n pendingHtmlRef.current = normalizedHtmlContent;\n clearDeferredRenderTimer();\n\n if (!shouldDeferRender) {\n setRenderHtmlContent(normalizedHtmlContent);\n return;\n }\n\n deferRenderTimerRef.current = window.setTimeout(() => {\n setRenderHtmlContent(pendingHtmlRef.current);\n deferRenderTimerRef.current = null;\n }, POST_IMAGE_STREAM_DEBOUNCE_MS);\n }, [normalizedHtmlContent]);\n\n const rootViewportHeightCss = React.useMemo(\n () =>\n inspectSandboxPrimaryHeightFromHtml(renderHtmlContent).viewportHeightCss,\n [renderHtmlContent]\n );\n const hasRootVhHeight = Boolean(rootViewportHeightCss);\n const sandboxViewportHeight =\n isBlackboardMode && type === \"sandbox\"\n ? shouldStretchRootHeight\n ? \"100%\"\n : (rootViewportHeightCss ?? `${height}px`)\n : undefined;\n const shouldShowHtmlFallbackWhilePreparingSandbox = false;\n useEffect(() => {\n if (mode !== \"blackboard\") {\n prevHtmlRef.current = normalizedHtmlContent;\n return;\n }\n const prev = prevHtmlRef.current;\n const isContinuation = prev && normalizedHtmlContent.startsWith(prev);\n if (!isContinuation && prev) {\n setResetToken((token) => token + 1);\n }\n prevHtmlRef.current = normalizedHtmlContent;\n }, [mode, normalizedHtmlContent]);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe) return undefined;\n\n const doc = iframe.contentDocument;\n if (!doc) return undefined;\n\n doc.open();\n doc.write(`<!DOCTYPE html>\n<html${mode === \"blackboard\" ? ' style=\"height: 100%;\"' : \"\"}>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <style>\n :root { color-scheme: light; }\n html, body, #root { width: 100%; height: 100%; }\n html, body { margin: 0; padding: 0; overflow: auto; }\n *, *::before, *::after { box-sizing: border-box; }\n </style>\n </head>\n <body>\n <div id=\"root\"></div>\n </body>\n</html>`);\n doc.close();\n\n // Force iframe theme to stay in light mode regardless of host OS preference.\n doc.documentElement.setAttribute(\"data-theme\", \"light\");\n doc.documentElement.style.colorScheme = \"light\";\n doc.body?.style.setProperty(\"color-scheme\", \"light\");\n\n docRef.current = doc;\n\n const shouldBridgeSandboxInteraction =\n isBlackboardMode && type === \"sandbox\";\n const handleSandboxPointerDown = () =>\n emitSandboxInteraction(\"pointerdown\");\n const handleSandboxMouseDown = () => emitSandboxInteraction(\"mousedown\");\n const handleSandboxTouchStart = () => emitSandboxInteraction(\"touchstart\");\n\n if (shouldBridgeSandboxInteraction) {\n doc.addEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.addEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.addEventListener(\"touchstart\", handleSandboxTouchStart, true);\n }\n\n const rootEl = doc.getElementById(\"root\");\n if (!rootEl) return undefined;\n\n const root = createRoot(rootEl);\n rootRef.current = root;\n let isDestroyed = false;\n\n const parseExplicitHeight = (\n value: string,\n parentViewportHeight: number\n ) => {\n const normalized = value.trim().toLowerCase();\n if (!normalized) return null;\n const numeric = Number.parseFloat(normalized);\n if (Number.isNaN(numeric)) return null;\n if (/(dvh|svh|lvh|vh)$/i.test(normalized)) {\n return (numeric / 100) * parentViewportHeight;\n }\n if (normalized.endsWith(\"px\") || /^[0-9.]+$/.test(normalized)) {\n return numeric;\n }\n return null;\n };\n const parseTailwindHeightClass = (\n className: string,\n parentViewportHeight: number\n ) => {\n if (!className.trim()) return null;\n const viewportHeightCss =\n extractViewportHeightFromTailwindClass(className);\n if (viewportHeightCss) {\n return parseExplicitHeight(viewportHeightCss, parentViewportHeight);\n }\n const normalizedTokens = normalizeTailwindHeightTokens(className);\n const arbitraryToken = normalizedTokens.find((token) =>\n /^h-\\[[0-9.]+px\\]$/i.test(token)\n );\n if (!arbitraryToken) return null;\n const matched = arbitraryToken.match(/^h-\\[([0-9.]+)px\\]$/i);\n if (!matched) return null;\n const numeric = Number.parseFloat(matched[1]);\n if (Number.isNaN(numeric)) return null;\n return numeric;\n };\n\n const resolveExplicitHeight = () => {\n if (!iframeRef.current || !doc.body) return null;\n const parentViewportHeight =\n iframeRef.current.ownerDocument?.documentElement?.clientHeight ||\n window.innerHeight;\n const { viewportHeightCss } = inspectSandboxPrimaryHeight(doc.body);\n const parsed = viewportHeightCss\n ? parseExplicitHeight(viewportHeightCss, parentViewportHeight)\n : null;\n\n if (parsed !== null) {\n return Math.ceil(parsed);\n }\n\n const wrapper = doc.body.querySelector(\n \".sandbox-wrapper\"\n ) as HTMLElement | null;\n const target = wrapper?.querySelector(\n \".sandbox-container > *\"\n ) as HTMLElement | null;\n\n if (!target) return null;\n\n const heightValue = target.style.height || target.getAttribute(\"height\");\n const explicitPixelHeight = heightValue\n ? parseExplicitHeight(heightValue, parentViewportHeight)\n : null;\n\n if (explicitPixelHeight !== null) {\n return Math.ceil(explicitPixelHeight);\n }\n\n const classHeight = parseTailwindHeightClass(\n target.getAttribute(\"class\") || \"\",\n parentViewportHeight\n );\n\n return classHeight !== null ? Math.ceil(classHeight) : null;\n };\n\n const updateHeight = () => {\n if (!iframeRef.current || !doc.body) return;\n const bodyRect = doc.body.getBoundingClientRect();\n const htmlRect = doc.documentElement?.getBoundingClientRect();\n const bodyHeight = bodyRect.height;\n const htmlHeight = htmlRect?.height || 0;\n const contentHeight = Math.max(bodyHeight, htmlHeight);\n const explicitHeight = resolveExplicitHeight();\n const nextHeight = Math.max(\n 200,\n explicitHeight ?? Math.ceil(contentHeight)\n );\n setHeight(nextHeight);\n };\n const scheduleHeightUpdate = () => {\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n updateHeight();\n });\n };\n updateHeightRef.current = scheduleHeightUpdate;\n\n updateHeight();\n scheduleHeightUpdate();\n\n if (!shouldInjectSandboxVendor) {\n setIsSandboxVendorReady(true);\n } else {\n // Inject Tailwind/DaisyUI/GSAP before rendering sandbox content to avoid FOUC.\n loadBlackboardVendorOnDemandWithMetrics()\n .then((inject) => {\n if (isDestroyed) return;\n inject(doc);\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n setIsSandboxVendorReady(true);\n scheduleHeightUpdate();\n });\n })\n .catch(() => {\n if (isDestroyed) return;\n setIsSandboxVendorReady(true);\n scheduleHeightUpdate();\n });\n }\n\n const resizeObserver = new ResizeObserver(() => updateHeight());\n resizeObserver.observe(doc.body);\n if (rootEl) {\n resizeObserver.observe(rootEl);\n }\n\n return () => {\n isDestroyed = true;\n resizeObserver.disconnect();\n if (shouldBridgeSandboxInteraction) {\n doc.removeEventListener(\"pointerdown\", handleSandboxPointerDown, true);\n doc.removeEventListener(\"mousedown\", handleSandboxMouseDown, true);\n doc.removeEventListener(\"touchstart\", handleSandboxTouchStart, true);\n }\n // Defer unmount to avoid React warning when parent is mid-render\n setTimeout(() => {\n root.unmount();\n rootRef.current = null;\n docRef.current = null;\n updateHeightRef.current = () => {};\n }, 0);\n };\n }, []);\n\n useEffect(() => {\n const onFullscreenChange = () => {\n setIsFullscreen(Boolean(document.fullscreenElement));\n };\n document.addEventListener(\"fullscreenchange\", onFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", onFullscreenChange);\n }, []);\n\n const toggleFullscreen = () => {\n const target = containerRef.current || iframeRef.current;\n if (!target) return;\n if (document.fullscreenElement) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n if (target.requestFullscreen) {\n target.requestFullscreen().catch(() => {});\n }\n };\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n\n root.render(\n <SandboxApp\n html={renderHtmlContent}\n loadingText={loadingText}\n styleLoadingText={styleLoadingText}\n scriptLoadingText={scriptLoadingText}\n fullScreenButtonText={fullScreenButtonText}\n hideFullScreen={hideFullScreen}\n resetToken={resetToken}\n hasRootVhHeight={hasRootVhHeight}\n mode={mode}\n stretchRootHeight={shouldStretchRootHeight}\n />\n );\n\n initialPaintFrameRef.current = window.requestAnimationFrame(() => {\n updateHeightRef.current?.();\n initialPaintFrameRef.current = null;\n });\n }, [\n renderHtmlContent,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n resetToken,\n mode,\n ]);\n const containerClassName = [\n \"w-full relative content-render-iframe-sandbox\",\n isBlackboardMode\n ? \"h-full overflow-auto flex flex-col\"\n : \"aspect-[16/9] overflow-hidden flex items-center justify-center\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const shouldShowSandboxLoading = false;\n\n return (\n <div\n ref={containerRef}\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className={containerClassName}\n style={\n sandboxViewportHeight\n ? {\n height: sandboxViewportHeight,\n minHeight: sandboxViewportHeight,\n }\n : undefined\n }\n >\n {!hideFullScreen && (\n <button\n type=\"button\"\n onClick={toggleFullscreen}\n className={\n \"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer\"\n }\n >\n {isFullscreen ? \"退出全屏\" : fullScreenButtonText || \"全屏浏览\"}\n </button>\n )}\n {mode === \"blackboard\" && type === \"markdown\" ? (\n <div\n onMouseDown={() => emitSandboxInteraction(\"mousedown\")}\n onPointerDown={() => emitSandboxInteraction(\"pointerdown\")}\n onTouchStart={() => emitSandboxInteraction(\"touchstart\")}\n >\n <ContentRender content={content} />\n </div>\n ) : (\n <>\n {shouldShowHtmlFallbackWhilePreparingSandbox ? (\n <div\n aria-hidden\n className=\"absolute inset-0 z-10 overflow-hidden\"\n style={{\n height: sandboxViewportHeight ?? \"100%\",\n minHeight: sandboxViewportHeight,\n }}\n >\n <div\n className=\"h-full w-full\"\n dangerouslySetInnerHTML={{ __html: renderHtmlContent }}\n />\n </div>\n ) : null}\n <iframe\n ref={iframeRef}\n sandbox=\"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox\"\n allow=\"fullscreen\"\n allowFullScreen\n className={[className, \"w-full h-full mx-auto my-auto block\"]\n .filter(Boolean)\n .join(\" \")}\n style={{\n height: sandboxViewportHeight ?? \"100%\",\n minHeight: sandboxViewportHeight,\n margin: \"auto\",\n visibility: \"visible\",\n }}\n />\n {shouldShowSandboxLoading ? (\n <div className=\"pointer-events-none absolute inset-0 z-20 flex items-center justify-center\">\n <Loader2\n aria-label={loadingText || \"Preparing sandbox styles\"}\n className=\"text-primary h-7 w-7 animate-spin\"\n />\n </div>\n ) : null}\n </>\n )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["blackboardVendorPromise","loadBlackboardVendor","m","loadBlackboardVendorOnDemandWithMetrics","loadStart","startedAt","inject","error","COMPLETE_IMAGE_TAG_PATTERN","POST_IMAGE_STREAM_DEBOUNCE_MS","SANDBOX_INTERACTION_THROTTLE_MS","normalizeTailwindHeightTokens","className","token","parseViewportHeightCss","value","normalized","matched","extractViewportHeightFromTailwindClass","normalizedTokens","arbitraryToken","SANDBOX_IGNORED_TAG_NAMES","isSandboxRenderableElement","element","getFirstRenderableElementChild","root","node","getInspectableSandboxElementChain","chain","current","childElements","extractViewportHeightFromElement","heightAttrValue","attrViewportHeight","styleHeightValue","styleViewportHeight","isFullViewportHeightCss","inspectSandboxPrimaryHeight","inspectableElements","viewportHeightCss","hasFullViewportHeight","elementViewportHeight","inspectRootHeightFromHtmlString","html","attrs","classAttrValue","inspectSandboxPrimaryHeightFromHtml","template","replaceRootScreenHeightToken","segments","replaceRootScreenHeightWithFullClass","enabled","match","tagStart","classMatch","nextClassName","IframeSandbox","content","type","loadingText","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","replaceRootScreenHeightWithFull","containerRef","useRef","iframeRef","rootRef","docRef","updateHeightRef","height","setHeight","useState","lastSandboxInteractionTimeRef","resetToken","setResetToken","isFullscreen","setIsFullscreen","setIsSandboxVendorReady","shouldInjectSandboxVendor","isBlackboardMode","prevHtmlRef","htmlContent","React","sandboxSegments","splitContentSegments","seg","normalizedHtmlContent","htmlHeightMeta","shouldStretchRootHeight","renderHtmlContent","setRenderHtmlContent","prevIncomingHtmlRef","pendingHtmlRef","deferRenderTimerRef","initialPaintFrameRef","emitSandboxInteraction","useCallback","eventType","now","SANDBOX_INTERACTION_MESSAGE_SOURCE","SANDBOX_INTERACTION_MESSAGE_TYPE","clearDeferredRenderTimer","clearInitialPaintFrames","useEffect","prevIncomingHtml","isAppendOnlyStream","containsCompleteImage","shouldDeferRender","rootViewportHeightCss","hasRootVhHeight","sandboxViewportHeight","prev","iframe","doc","shouldBridgeSandboxInteraction","handleSandboxPointerDown","handleSandboxMouseDown","handleSandboxTouchStart","rootEl","createRoot","isDestroyed","parseExplicitHeight","parentViewportHeight","numeric","parseTailwindHeightClass","resolveExplicitHeight","parsed","target","heightValue","explicitPixelHeight","classHeight","updateHeight","bodyRect","htmlRect","bodyHeight","htmlHeight","contentHeight","explicitHeight","nextHeight","scheduleHeightUpdate","resizeObserver","onFullscreenChange","toggleFullscreen","jsx","SandboxApp","containerClassName","jsxs","ContentRender","Fragment"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const C=require("../../_virtual/jsx-runtime.cjs.js"),o=require("react"),Z=require("../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/lucide-react@0.525.0_react@19.0.1/node_modules/lucide-react/dist/esm/icons/loader-circle.cjs.js"),ee=["src","srcset","sizes","alt","class","width","height","style","loading","decoding","crossorigin","referrerpolicy","fetchpriority"],V=i=>ee.map(t=>`${t}:${i.getAttribute(t)||""}`).join("|"),te=i=>{const t=new Map;return i.querySelectorAll("img").forEach(e=>{const c=e,n=V(c),u=t.get(n)||[];u.push(c),t.set(n,u)}),t},re=i=>{i.querySelectorAll("img").forEach(t=>{const e=t;e.getAttribute("loading")||e.setAttribute("loading","eager"),e.getAttribute("decoding")||e.setAttribute("decoding","async"),e.getAttribute("fetchpriority")||e.setAttribute("fetchpriority","high")})},se=(i,t)=>{const e=Array.from(i.attributes),c=new Set(e.map(n=>n.name));Array.from(t.attributes).forEach(n=>{c.has(n.name)||t.removeAttribute(n.name)}),e.forEach(n=>{t.setAttribute(n.name,n.value)})},ne=i=>{const t=Array.from(i.querySelectorAll("img"));return t.length===0?Promise.resolve():Promise.allSettled(t.map(e=>{const c=()=>typeof e.decode!="function"?Promise.resolve():e.decode().catch(()=>{});return e.complete&&e.naturalWidth>0?c():new Promise(n=>{const u=()=>{c().finally(()=>n())};e.addEventListener("load",u,{once:!0}),e.addEventListener("error",()=>n(),{once:!0})})})).then(()=>{})},oe=(i,t)=>{t.size&&i.querySelectorAll("img").forEach(e=>{const c=e,n=V(c),u=t.get(n),b=u?.shift();if(!b)return;const v=b.cloneNode(!0);se(c,v),c.replaceWith(v),u&&u.length===0&&t.delete(n)})},ie=({html:i,styleLoadingText:t,scriptLoadingText:e,resetToken:c=0,mode:n="content",hasRootVhHeight:u=!1,stretchRootHeight:b=!1})=>{const v=o.useRef(null),I=o.useRef(null),[,k]=o.useState(!0),[K,j]=o.useState(!1),[O,N]=o.useState(!1),q=o.useRef([]),F=o.useRef([]),D=o.useRef(0),P=o.useRef(0),x=o.useRef(null),S=o.useRef(null),E=o.useRef(!1),R=o.useRef(!1),L=o.useRef(!1),_=o.useRef(c),U=200,m=s=>{s.current&&(clearTimeout(s.current),s.current=null)},z=(s,l,f,T)=>{const y=performance.now()-f.current,p=Math.max(0,U-y);m(l),l.current=window.setTimeout(()=>{s(!1),T?.(),l.current=null},p)};o.useEffect(()=>{const s=I.current?.ownerDocument;if(!s)return;const l="sandbox-spinner-style";let f=s.getElementById(l);f||(f=s.createElement("style"),f.id=l,s.head?.appendChild(f)),f.textContent=`
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const A=require("../../_virtual/jsx-runtime.cjs.js"),t=require("react"),Y=require("../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/lucide-react@0.525.0_react@19.0.1/node_modules/lucide-react/dist/esm/icons/loader-circle.cjs.js"),Z=["src","srcset","sizes","alt","class","width","height","style","loading","decoding","crossorigin","referrerpolicy","fetchpriority"],O=a=>Z.map(r=>`${r}:${a.getAttribute(r)||""}`).join("|"),ee=a=>{const r=new Map;return a.querySelectorAll("img").forEach(l=>{const c=l,s=O(c),f=r.get(s)||[];f.push(c),r.set(s,f)}),r},te=(a,r)=>{const l=Array.from(a.attributes),c=new Set(l.map(s=>s.name));Array.from(r.attributes).forEach(s=>{c.has(s.name)||r.removeAttribute(s.name)}),l.forEach(s=>{r.setAttribute(s.name,s.value)})},re=(a,r)=>{r.size&&a.querySelectorAll("img").forEach(l=>{const c=l,s=O(c),f=r.get(s),y=f?.shift();if(!y)return;const g=y.cloneNode(!0);te(c,g),c.replaceWith(g),f&&f.length===0&&r.delete(s)})},se=({html:a,styleLoadingText:r,scriptLoadingText:l,resetToken:c=0,mode:s="content",hasRootVhHeight:f=!1,stretchRootHeight:y=!1})=>{const g=t.useRef(null),C=t.useRef(null),[,_]=t.useState(!0),[U,I]=t.useState(!1),[V,j]=t.useState(!1),N=t.useRef([]),M=t.useRef([]),B=t.useRef(0),D=t.useRef(0),x=t.useRef(null),b=t.useRef(null),R=t.useRef(!1),S=t.useRef(!1),T=t.useRef(!1),G=t.useRef(c),$=200,d=n=>{n.current&&(clearTimeout(n.current),n.current=null)},L=(n,i,u,q)=>{const w=performance.now()-u.current,p=Math.max(0,$-w);d(i),i.current=window.setTimeout(()=>{n(!1),q?.(),i.current=null},p)};t.useEffect(()=>{const n=C.current?.ownerDocument;if(!n)return;const i="sandbox-spinner-style";let u=n.getElementById(i);u||(u=n.createElement("style"),u.id=i,n.head?.appendChild(u)),u.textContent=`
2
2
  @keyframes sandbox-spin { from { transform: rotate(0deg);} to { transform: rotate(360deg);} }
3
3
  .sandbox-wrapper { align-items: center; }
4
4
  .sandbox-container { position: relative; width: 100%; }
@@ -7,5 +7,5 @@
7
7
  .justify-\\[safe_center\\]{
8
8
  justify-content: safe center;
9
9
  }
10
- `},[]),o.useEffect(()=>{c!==_.current&&(L.current=!1,_.current=c),m(x),m(S),E.current=!1,R.current=!1;const s=I.current;if(!s)return;const l=s.ownerDocument,f=l?.body;if(!f)return;const T=te(s);q.current.forEach(r=>r.remove()),q.current=[],F.current.forEach(r=>r.remove()),F.current=[];const y=L.current;k(!y),j(!1),N(!1);const p=l.createElement("div");p.innerHTML=i;const B=(i.match(/<script[\s>]/gi)||[]).length,J=(i.match(/<\/script>/gi)||[]).length,X=B>0&&B===J,g=[];Array.from(p.querySelectorAll("style, script")).forEach(r=>{if(r.tagName.toLowerCase()==="style"){const a=l.createElement("style");a.textContent=r.textContent||"",Array.from(r.attributes).forEach(h=>{a.setAttribute(h.name,h.value)}),g.push(a)}else{const a=l.createElement("script");Array.from(r.attributes).forEach(h=>{a.setAttribute(h.name,h.value)}),a.textContent=r.textContent||"",g.push(a)}r.remove()}),re(p),oe(p,T);const G=g.some(r=>r.tagName.toLowerCase()==="style"),W=g.some(r=>r.tagName.toLowerCase()==="script");G&&(E.current=!0,D.current=performance.now(),m(x),j(!0)),W&&(R.current=!0,P.current=performance.now(),m(S),N(!0));const H=!!p.firstElementChild;k(!H&&!y),H&&(L.current=!0);const d=y&&s.childNodes.length>0&&p.querySelector("img")!==null?s.cloneNode(!0):null;d&&(d.setAttribute("aria-hidden","true"),d.style.position="absolute",d.style.inset="0",d.style.zIndex="2",d.style.pointerEvents="none",d.style.background="transparent");const Y=Array.from(p.childNodes);s.replaceChildren(...Y),d&&(s.appendChild(d),ne(s).finally(()=>{requestAnimationFrame(()=>{d.remove()})})),g.forEach(r=>{if(r.tagName.toLowerCase()==="style"){l.head?.appendChild(r),q.current.push(r);return}if(X){const a=r,h=a.textContent||"";if(!a.src)try{new Function(h)}catch{a.remove();return}try{f.appendChild(a),F.current.push(a)}catch{a.remove()}}else r.remove()}),requestAnimationFrame(()=>{G&&z(j,x,D,()=>{E.current=!1}),W&&z(N,S,P,()=>{R.current=!1})})},[i,c]),o.useEffect(()=>()=>{m(x),m(S)},[]);const A=O||R.current?e||"Building scripts cache...":K||E.current?t||"Building styles...":null,M=n==="blackboard",w=M&&b,$={position:"relative",width:"100%",height:"100%",display:"flex",flexDirection:"column",justifyContent:w?"flex-start":M?"space-around":"flex-start"},Q={pointerEvents:A?"none":void 0,margin:M?void 0:"auto 0",width:"100%",height:w?"100%":void 0,minHeight:w?0:void 0,flex:w?"1 1 auto":void 0};return C.jsxRuntimeExports.jsxs("div",{ref:v,"data-root-vh":u?"true":"false",className:"sandbox-wrapper",style:$,"aria-busy":!!A,children:[C.jsxRuntimeExports.jsx("div",{ref:I,className:"sandbox-container",style:Q}),A&&C.jsxRuntimeExports.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(51, 51, 51, 0.80)",color:"#ffffff",fontSize:16,fontWeight:700,gap:10,pointerEvents:"auto",zIndex:20},children:[C.jsxRuntimeExports.jsx(Z.default,{"aria-hidden":!0,size:20,style:{animation:"sandbox-spin 1s linear infinite"}}),A]})]})};exports.default=ie;
10
+ `},[]),t.useEffect(()=>{c!==G.current&&(T.current=!1,G.current=c),d(x),d(b),R.current=!1,S.current=!1;const n=C.current;if(!n)return;const i=n.ownerDocument,u=i?.body;if(!u)return;const q=ee(n);N.current.forEach(e=>e.remove()),N.current=[],M.current.forEach(e=>e.remove()),M.current=[];const w=T.current;_(!w),I(!1),j(!1);const p=i.createElement("div");p.innerHTML=a;const z=(a.match(/<script[\s>]/gi)||[]).length,Q=(a.match(/<\/script>/gi)||[]).length,J=z>0&&z===Q,h=[];Array.from(p.querySelectorAll("style, script")).forEach(e=>{if(e.tagName.toLowerCase()==="style"){const o=i.createElement("style");o.textContent=e.textContent||"",Array.from(e.attributes).forEach(m=>{o.setAttribute(m.name,m.value)}),h.push(o)}else{const o=i.createElement("script");Array.from(e.attributes).forEach(m=>{o.setAttribute(m.name,m.value)}),o.textContent=e.textContent||"",h.push(o)}e.remove()}),re(p,q);const W=h.some(e=>e.tagName.toLowerCase()==="style"),F=h.some(e=>e.tagName.toLowerCase()==="script");W&&(R.current=!0,B.current=performance.now(),d(x),I(!0)),F&&(S.current=!0,D.current=performance.now(),d(b),j(!0));const H=!!p.firstElementChild;_(!H&&!w),H&&(T.current=!0);const X=Array.from(p.childNodes);n.replaceChildren(...X),h.forEach(e=>{if(e.tagName.toLowerCase()==="style"){i.head?.appendChild(e),N.current.push(e);return}if(J){const o=e,m=o.textContent||"";if(!o.src)try{new Function(m)}catch{o.remove();return}try{u.appendChild(o),M.current.push(o)}catch{o.remove()}}else e.remove()}),requestAnimationFrame(()=>{W&&L(I,x,B,()=>{R.current=!1}),F&&L(j,b,D,()=>{S.current=!1})})},[a,c]),t.useEffect(()=>()=>{d(x),d(b)},[]);const E=V||S.current?l||"Building scripts cache...":U||R.current?r||"Building styles...":null,k=s==="blackboard",v=k&&y,K={position:"relative",width:"100%",height:"100%",display:"flex",flexDirection:"column",justifyContent:v?"flex-start":k?"space-around":"flex-start"},P={pointerEvents:E?"none":void 0,margin:k?void 0:"auto 0",width:"100%",height:v?"100%":void 0,minHeight:v?0:void 0,flex:v?"1 1 auto":void 0};return A.jsxRuntimeExports.jsxs("div",{ref:g,"data-root-vh":f?"true":"false",className:"sandbox-wrapper",style:K,"aria-busy":!!E,children:[A.jsxRuntimeExports.jsx("div",{ref:C,className:"sandbox-container",style:P}),E&&A.jsxRuntimeExports.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(51, 51, 51, 0.80)",color:"#ffffff",fontSize:16,fontWeight:700,gap:10,pointerEvents:"auto",zIndex:20},children:[A.jsxRuntimeExports.jsx(Y.default,{"aria-hidden":!0,size:20,style:{animation:"sandbox-spin 1s linear infinite"}}),E]})]})};exports.default=se;
11
11
  //# sourceMappingURL=SandboxApp.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SandboxApp.cjs.js","sources":["../../../src/components/ContentRender/SandboxApp.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { Loader2 } from \"lucide-react\";\n\nexport interface SandboxAppProps {\n html: string;\n loadingText?: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n fullScreenButtonText?: string;\n hideFullScreen?: boolean;\n resetToken?: number;\n mode?: \"content\" | \"blackboard\";\n hasRootVhHeight?: boolean;\n stretchRootHeight?: boolean;\n}\n\nconst IMAGE_REUSE_ATTRIBUTES = [\n \"src\",\n \"srcset\",\n \"sizes\",\n \"alt\",\n \"class\",\n \"width\",\n \"height\",\n \"style\",\n \"loading\",\n \"decoding\",\n \"crossorigin\",\n \"referrerpolicy\",\n \"fetchpriority\",\n];\n\nconst getImageReuseKey = (image: HTMLImageElement) =>\n IMAGE_REUSE_ATTRIBUTES.map(\n (attribute) => `${attribute}:${image.getAttribute(attribute) || \"\"}`\n ).join(\"|\");\n\nconst collectReusableImages = (root: ParentNode) => {\n const imageMap = new Map<string, HTMLImageElement[]>();\n root.querySelectorAll(\"img\").forEach((node) => {\n const image = node as HTMLImageElement;\n const key = getImageReuseKey(image);\n const bucket = imageMap.get(key) || [];\n bucket.push(image);\n imageMap.set(key, bucket);\n });\n return imageMap;\n};\n\nconst applyImageLoadingHints = (root: ParentNode) => {\n root.querySelectorAll(\"img\").forEach((node) => {\n const image = node as HTMLImageElement;\n\n if (!image.getAttribute(\"loading\")) {\n image.setAttribute(\"loading\", \"eager\");\n }\n\n if (!image.getAttribute(\"decoding\")) {\n image.setAttribute(\"decoding\", \"async\");\n }\n\n if (!image.getAttribute(\"fetchpriority\")) {\n image.setAttribute(\"fetchpriority\", \"high\");\n }\n });\n};\n\nconst syncImageAttributes = (\n sourceImage: HTMLImageElement,\n targetImage: HTMLImageElement\n) => {\n const sourceAttributes = Array.from(sourceImage.attributes);\n const sourceAttributeNames = new Set(\n sourceAttributes.map((attribute) => attribute.name)\n );\n\n Array.from(targetImage.attributes).forEach((attribute) => {\n if (!sourceAttributeNames.has(attribute.name)) {\n targetImage.removeAttribute(attribute.name);\n }\n });\n\n sourceAttributes.forEach((attribute) => {\n targetImage.setAttribute(attribute.name, attribute.value);\n });\n};\n\nconst waitForImagesReady = (root: ParentNode) => {\n const images = Array.from(root.querySelectorAll(\"img\")) as HTMLImageElement[];\n\n if (images.length === 0) {\n return Promise.resolve();\n }\n\n return Promise.allSettled(\n images.map((image) => {\n const waitForDecode = () => {\n if (typeof image.decode !== \"function\") {\n return Promise.resolve();\n }\n\n return image.decode().catch(() => undefined);\n };\n\n if (image.complete && image.naturalWidth > 0) {\n return waitForDecode();\n }\n\n return new Promise<void>((resolve) => {\n const settle = () => {\n void waitForDecode().finally(() => resolve());\n };\n\n image.addEventListener(\"load\", settle, { once: true });\n image.addEventListener(\"error\", () => resolve(), { once: true });\n });\n })\n ).then(() => undefined);\n};\n\nconst reuseRenderedImages = (\n root: ParentNode,\n imageMap: Map<string, HTMLImageElement[]>\n) => {\n if (!imageMap.size) return;\n\n root.querySelectorAll(\"img\").forEach((node) => {\n const nextImage = node as HTMLImageElement;\n const key = getImageReuseKey(nextImage);\n const bucket = imageMap.get(key);\n const preservedImage = bucket?.shift();\n if (!preservedImage) return;\n\n // Clone the already-rendered image instead of moving the live node out of\n // the visible tree before the next DOM commit.\n const clonedImage = preservedImage.cloneNode(true) as HTMLImageElement;\n syncImageAttributes(nextImage, clonedImage);\n nextImage.replaceWith(clonedImage);\n\n if (bucket && bucket.length === 0) {\n imageMap.delete(key);\n }\n });\n};\n\nconst SandboxApp: React.FC<SandboxAppProps> = ({\n html,\n styleLoadingText,\n scriptLoadingText,\n resetToken = 0,\n mode = \"content\",\n hasRootVhHeight = false,\n stretchRootHeight = false,\n}) => {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [, setIsWaitingFirstDiv] = useState(true);\n const [isGeneratingStyles, setIsGeneratingStyles] = useState(false);\n const [isGeneratingScripts, setIsGeneratingScripts] = useState(false);\n const appendedStylesRef = useRef<HTMLStyleElement[]>([]);\n const appendedScriptsRef = useRef<HTMLScriptElement[]>([]);\n const styleStartRef = useRef(0);\n const scriptStartRef = useRef(0);\n const styleTimerRef = useRef<number | null>(null);\n const scriptTimerRef = useRef<number | null>(null);\n const hasStylesRef = useRef(false);\n const hasScriptsRef = useRef(false);\n const hasRenderedContentRef = useRef(false);\n const prevResetTokenRef = useRef(resetToken);\n const MIN_LOADING_MS = 200;\n\n const clearTimer = (timerRef: React.MutableRefObject<number | null>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const settleStateWithMinimumDelay = (\n setter: React.Dispatch<React.SetStateAction<boolean>>,\n timerRef: React.MutableRefObject<number | null>,\n startRef: React.MutableRefObject<number>,\n onDone?: () => void\n ) => {\n const elapsed = performance.now() - startRef.current;\n const delay = Math.max(0, MIN_LOADING_MS - elapsed);\n clearTimer(timerRef);\n timerRef.current = window.setTimeout(() => {\n setter(false);\n onDone?.();\n timerRef.current = null;\n }, delay);\n };\n\n useEffect(() => {\n const doc = containerRef.current?.ownerDocument;\n if (!doc) return;\n const styleId = \"sandbox-spinner-style\";\n let styleEl = doc.getElementById(styleId) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = doc.createElement(\"style\");\n styleEl.id = styleId;\n doc.head?.appendChild(styleEl);\n }\n styleEl.textContent = `\n @keyframes sandbox-spin { from { transform: rotate(0deg);} to { transform: rotate(360deg);} }\n .sandbox-wrapper { align-items: center; }\n .sandbox-container { position: relative; width: 100%; }\n .sandbox-container svg,\n .sandbox-container img { display: block; margin-left: auto; margin-right: auto; }\n .justify-\\\\[safe_center\\\\]{\n justify-content: safe center;\n }\n `;\n }, []);\n\n useEffect(() => {\n if (resetToken !== prevResetTokenRef.current) {\n hasRenderedContentRef.current = false;\n prevResetTokenRef.current = resetToken;\n }\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n const body = doc?.body;\n if (!body) return;\n const reusableImages = collectReusableImages(container);\n\n appendedStylesRef.current.forEach((node) => node.remove());\n appendedStylesRef.current = [];\n appendedScriptsRef.current.forEach((node) => node.remove());\n appendedScriptsRef.current = [];\n\n const hasRenderedBefore = hasRenderedContentRef.current;\n setIsWaitingFirstDiv(!hasRenderedBefore);\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n const wrapper = doc.createElement(\"div\");\n wrapper.innerHTML = html;\n\n const openScriptCount = (html.match(/<script[\\s>]/gi) || []).length;\n const closeScriptCount = (html.match(/<\\/script>/gi) || []).length;\n const shouldExecuteScripts =\n openScriptCount > 0 && openScriptCount === closeScriptCount;\n\n const resourceQueue: HTMLElement[] = [];\n\n Array.from(wrapper.querySelectorAll(\"style, script\")).forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n const cloned = doc.createElement(\"style\");\n cloned.textContent = node.textContent || \"\";\n Array.from(node.attributes).forEach((attr) => {\n cloned.setAttribute(attr.name, attr.value);\n });\n resourceQueue.push(cloned);\n } else {\n const replacement = doc.createElement(\"script\");\n Array.from(node.attributes).forEach((attr) => {\n replacement.setAttribute(attr.name, attr.value);\n });\n replacement.textContent = node.textContent || \"\";\n resourceQueue.push(replacement);\n }\n node.remove();\n });\n applyImageLoadingHints(wrapper);\n reuseRenderedImages(wrapper, reusableImages);\n\n const hasStyles = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"style\"\n );\n const hasScripts = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"script\"\n );\n if (hasStyles) {\n hasStylesRef.current = true;\n styleStartRef.current = performance.now();\n clearTimer(styleTimerRef);\n setIsGeneratingStyles(true);\n }\n if (hasScripts) {\n hasScriptsRef.current = true;\n scriptStartRef.current = performance.now();\n clearTimer(scriptTimerRef);\n setIsGeneratingScripts(true);\n }\n\n const hasFirstElement = !!wrapper.firstElementChild;\n setIsWaitingFirstDiv(!hasFirstElement && !hasRenderedBefore);\n if (hasFirstElement) {\n hasRenderedContentRef.current = true;\n }\n\n const shouldKeepPreviousFrameVisible =\n hasRenderedBefore &&\n container.childNodes.length > 0 &&\n wrapper.querySelector(\"img\") !== null;\n const previousFrameOverlay = shouldKeepPreviousFrameVisible\n ? (container.cloneNode(true) as HTMLDivElement)\n : null;\n\n if (previousFrameOverlay) {\n previousFrameOverlay.setAttribute(\"aria-hidden\", \"true\");\n previousFrameOverlay.style.position = \"absolute\";\n previousFrameOverlay.style.inset = \"0\";\n previousFrameOverlay.style.zIndex = \"2\";\n previousFrameOverlay.style.pointerEvents = \"none\";\n previousFrameOverlay.style.background = \"transparent\";\n }\n\n const contentNodes = Array.from(wrapper.childNodes);\n container.replaceChildren(...contentNodes);\n\n if (previousFrameOverlay) {\n container.appendChild(previousFrameOverlay);\n void waitForImagesReady(container).finally(() => {\n requestAnimationFrame(() => {\n previousFrameOverlay.remove();\n });\n });\n }\n\n resourceQueue.forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n doc.head?.appendChild(node);\n appendedStylesRef.current.push(node as HTMLStyleElement);\n return;\n }\n\n if (shouldExecuteScripts) {\n const scriptNode = node as HTMLScriptElement;\n const scriptText = scriptNode.textContent || \"\";\n const shouldValidate = !scriptNode.src;\n\n if (shouldValidate) {\n try {\n // Validate script is syntactically complete before executing\n\n new Function(scriptText);\n } catch {\n scriptNode.remove();\n return;\n }\n }\n\n try {\n body.appendChild(scriptNode);\n appendedScriptsRef.current.push(scriptNode);\n } catch {\n scriptNode.remove();\n }\n } else {\n // Defer execution until all script tags are fully received\n node.remove();\n }\n });\n requestAnimationFrame(() => {\n if (hasStyles) {\n settleStateWithMinimumDelay(\n setIsGeneratingStyles,\n styleTimerRef,\n styleStartRef,\n () => {\n hasStylesRef.current = false;\n }\n );\n }\n if (hasScripts) {\n settleStateWithMinimumDelay(\n setIsGeneratingScripts,\n scriptTimerRef,\n scriptStartRef,\n () => {\n hasScriptsRef.current = false;\n }\n );\n }\n });\n }, [html, resetToken]);\n\n useEffect(\n () => () => {\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n },\n []\n );\n\n const overlayMessage = (() => {\n if (isGeneratingScripts || hasScriptsRef.current)\n return scriptLoadingText || \"Building scripts cache...\";\n if (isGeneratingStyles || hasStylesRef.current)\n return styleLoadingText || \"Building styles...\";\n return null;\n })();\n\n const isBlackboard = mode === \"blackboard\";\n const shouldStretchRootHeight = isBlackboard && stretchRootHeight;\n const sandboxWrapperStyle: React.CSSProperties = {\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n // Keep blackboard scroll behavior while centering content in non-blackboard mode\n justifyContent: shouldStretchRootHeight\n ? \"flex-start\"\n : isBlackboard\n ? \"space-around\"\n : \"flex-start\",\n };\n const sandboxContainerStyle: React.CSSProperties = {\n pointerEvents: overlayMessage ? \"none\" : undefined,\n margin: isBlackboard ? undefined : \"auto 0\",\n width: \"100%\",\n height: shouldStretchRootHeight ? \"100%\" : undefined,\n minHeight: shouldStretchRootHeight ? 0 : undefined,\n flex: shouldStretchRootHeight ? \"1 1 auto\" : undefined,\n };\n\n return (\n <div\n ref={wrapperRef}\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className=\"sandbox-wrapper\"\n style={sandboxWrapperStyle}\n aria-busy={!!overlayMessage}\n >\n <div\n ref={containerRef}\n className=\"sandbox-container\"\n style={sandboxContainerStyle}\n />\n {overlayMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"rgba(51, 51, 51, 0.80)\",\n color: \"#ffffff\",\n fontSize: 16,\n fontWeight: 700,\n gap: 10,\n pointerEvents: \"auto\",\n zIndex: 20,\n }}\n >\n <Loader2\n aria-hidden\n size={20}\n style={{ animation: \"sandbox-spin 1s linear infinite\" }}\n />\n {overlayMessage}\n </div>\n )}\n </div>\n );\n};\n\nexport default SandboxApp;\n"],"names":["IMAGE_REUSE_ATTRIBUTES","getImageReuseKey","image","attribute","collectReusableImages","root","imageMap","node","key","bucket","applyImageLoadingHints","syncImageAttributes","sourceImage","targetImage","sourceAttributes","sourceAttributeNames","waitForImagesReady","images","waitForDecode","resolve","settle","reuseRenderedImages","nextImage","preservedImage","clonedImage","SandboxApp","html","styleLoadingText","scriptLoadingText","resetToken","mode","hasRootVhHeight","stretchRootHeight","wrapperRef","useRef","containerRef","setIsWaitingFirstDiv","useState","isGeneratingStyles","setIsGeneratingStyles","isGeneratingScripts","setIsGeneratingScripts","appendedStylesRef","appendedScriptsRef","styleStartRef","scriptStartRef","styleTimerRef","scriptTimerRef","hasStylesRef","hasScriptsRef","hasRenderedContentRef","prevResetTokenRef","MIN_LOADING_MS","clearTimer","timerRef","settleStateWithMinimumDelay","setter","startRef","onDone","elapsed","delay","useEffect","doc","styleId","styleEl","container","body","reusableImages","hasRenderedBefore","wrapper","openScriptCount","closeScriptCount","shouldExecuteScripts","resourceQueue","cloned","attr","replacement","hasStyles","hasScripts","hasFirstElement","previousFrameOverlay","contentNodes","scriptNode","scriptText","overlayMessage","isBlackboard","shouldStretchRootHeight","sandboxWrapperStyle","sandboxContainerStyle","jsxs","jsx","Loader2"],"mappings":"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"}
1
+ {"version":3,"file":"SandboxApp.cjs.js","sources":["../../../src/components/ContentRender/SandboxApp.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { Loader2 } from \"lucide-react\";\n\nexport interface SandboxAppProps {\n html: string;\n loadingText?: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n fullScreenButtonText?: string;\n hideFullScreen?: boolean;\n resetToken?: number;\n mode?: \"content\" | \"blackboard\";\n hasRootVhHeight?: boolean;\n stretchRootHeight?: boolean;\n}\n\nconst IMAGE_REUSE_ATTRIBUTES = [\n \"src\",\n \"srcset\",\n \"sizes\",\n \"alt\",\n \"class\",\n \"width\",\n \"height\",\n \"style\",\n \"loading\",\n \"decoding\",\n \"crossorigin\",\n \"referrerpolicy\",\n \"fetchpriority\",\n];\n\nconst getImageReuseKey = (image: HTMLImageElement) =>\n IMAGE_REUSE_ATTRIBUTES.map(\n (attribute) => `${attribute}:${image.getAttribute(attribute) || \"\"}`\n ).join(\"|\");\n\nconst collectReusableImages = (root: ParentNode) => {\n const imageMap = new Map<string, HTMLImageElement[]>();\n root.querySelectorAll(\"img\").forEach((node) => {\n const image = node as HTMLImageElement;\n const key = getImageReuseKey(image);\n const bucket = imageMap.get(key) || [];\n bucket.push(image);\n imageMap.set(key, bucket);\n });\n return imageMap;\n};\n\nconst syncImageAttributes = (\n sourceImage: HTMLImageElement,\n targetImage: HTMLImageElement\n) => {\n const sourceAttributes = Array.from(sourceImage.attributes);\n const sourceAttributeNames = new Set(\n sourceAttributes.map((attribute) => attribute.name)\n );\n\n Array.from(targetImage.attributes).forEach((attribute) => {\n if (!sourceAttributeNames.has(attribute.name)) {\n targetImage.removeAttribute(attribute.name);\n }\n });\n\n sourceAttributes.forEach((attribute) => {\n targetImage.setAttribute(attribute.name, attribute.value);\n });\n};\n\nconst reuseRenderedImages = (\n root: ParentNode,\n imageMap: Map<string, HTMLImageElement[]>\n) => {\n if (!imageMap.size) return;\n\n root.querySelectorAll(\"img\").forEach((node) => {\n const nextImage = node as HTMLImageElement;\n const key = getImageReuseKey(nextImage);\n const bucket = imageMap.get(key);\n const preservedImage = bucket?.shift();\n if (!preservedImage) return;\n\n // Clone the already-rendered image instead of moving the live node out of\n // the visible tree before the next DOM commit.\n const clonedImage = preservedImage.cloneNode(true) as HTMLImageElement;\n syncImageAttributes(nextImage, clonedImage);\n nextImage.replaceWith(clonedImage);\n\n if (bucket && bucket.length === 0) {\n imageMap.delete(key);\n }\n });\n};\n\nconst SandboxApp: React.FC<SandboxAppProps> = ({\n html,\n styleLoadingText,\n scriptLoadingText,\n resetToken = 0,\n mode = \"content\",\n hasRootVhHeight = false,\n stretchRootHeight = false,\n}) => {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [, setIsWaitingFirstDiv] = useState(true);\n const [isGeneratingStyles, setIsGeneratingStyles] = useState(false);\n const [isGeneratingScripts, setIsGeneratingScripts] = useState(false);\n const appendedStylesRef = useRef<HTMLStyleElement[]>([]);\n const appendedScriptsRef = useRef<HTMLScriptElement[]>([]);\n const styleStartRef = useRef(0);\n const scriptStartRef = useRef(0);\n const styleTimerRef = useRef<number | null>(null);\n const scriptTimerRef = useRef<number | null>(null);\n const hasStylesRef = useRef(false);\n const hasScriptsRef = useRef(false);\n const hasRenderedContentRef = useRef(false);\n const prevResetTokenRef = useRef(resetToken);\n const MIN_LOADING_MS = 200;\n\n const clearTimer = (timerRef: React.MutableRefObject<number | null>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const settleStateWithMinimumDelay = (\n setter: React.Dispatch<React.SetStateAction<boolean>>,\n timerRef: React.MutableRefObject<number | null>,\n startRef: React.MutableRefObject<number>,\n onDone?: () => void\n ) => {\n const elapsed = performance.now() - startRef.current;\n const delay = Math.max(0, MIN_LOADING_MS - elapsed);\n clearTimer(timerRef);\n timerRef.current = window.setTimeout(() => {\n setter(false);\n onDone?.();\n timerRef.current = null;\n }, delay);\n };\n\n useEffect(() => {\n const doc = containerRef.current?.ownerDocument;\n if (!doc) return;\n const styleId = \"sandbox-spinner-style\";\n let styleEl = doc.getElementById(styleId) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = doc.createElement(\"style\");\n styleEl.id = styleId;\n doc.head?.appendChild(styleEl);\n }\n styleEl.textContent = `\n @keyframes sandbox-spin { from { transform: rotate(0deg);} to { transform: rotate(360deg);} }\n .sandbox-wrapper { align-items: center; }\n .sandbox-container { position: relative; width: 100%; }\n .sandbox-container svg,\n .sandbox-container img { display: block; margin-left: auto; margin-right: auto; }\n .justify-\\\\[safe_center\\\\]{\n justify-content: safe center;\n }\n `;\n }, []);\n\n useEffect(() => {\n if (resetToken !== prevResetTokenRef.current) {\n hasRenderedContentRef.current = false;\n prevResetTokenRef.current = resetToken;\n }\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n const body = doc?.body;\n if (!body) return;\n const reusableImages = collectReusableImages(container);\n\n appendedStylesRef.current.forEach((node) => node.remove());\n appendedStylesRef.current = [];\n appendedScriptsRef.current.forEach((node) => node.remove());\n appendedScriptsRef.current = [];\n\n const hasRenderedBefore = hasRenderedContentRef.current;\n setIsWaitingFirstDiv(!hasRenderedBefore);\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n const wrapper = doc.createElement(\"div\");\n wrapper.innerHTML = html;\n\n const openScriptCount = (html.match(/<script[\\s>]/gi) || []).length;\n const closeScriptCount = (html.match(/<\\/script>/gi) || []).length;\n const shouldExecuteScripts =\n openScriptCount > 0 && openScriptCount === closeScriptCount;\n\n const resourceQueue: HTMLElement[] = [];\n\n Array.from(wrapper.querySelectorAll(\"style, script\")).forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n const cloned = doc.createElement(\"style\");\n cloned.textContent = node.textContent || \"\";\n Array.from(node.attributes).forEach((attr) => {\n cloned.setAttribute(attr.name, attr.value);\n });\n resourceQueue.push(cloned);\n } else {\n const replacement = doc.createElement(\"script\");\n Array.from(node.attributes).forEach((attr) => {\n replacement.setAttribute(attr.name, attr.value);\n });\n replacement.textContent = node.textContent || \"\";\n resourceQueue.push(replacement);\n }\n node.remove();\n });\n reuseRenderedImages(wrapper, reusableImages);\n\n const hasStyles = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"style\"\n );\n const hasScripts = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"script\"\n );\n if (hasStyles) {\n hasStylesRef.current = true;\n styleStartRef.current = performance.now();\n clearTimer(styleTimerRef);\n setIsGeneratingStyles(true);\n }\n if (hasScripts) {\n hasScriptsRef.current = true;\n scriptStartRef.current = performance.now();\n clearTimer(scriptTimerRef);\n setIsGeneratingScripts(true);\n }\n\n const hasFirstElement = !!wrapper.firstElementChild;\n setIsWaitingFirstDiv(!hasFirstElement && !hasRenderedBefore);\n if (hasFirstElement) {\n hasRenderedContentRef.current = true;\n }\n\n const contentNodes = Array.from(wrapper.childNodes);\n container.replaceChildren(...contentNodes);\n\n resourceQueue.forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n doc.head?.appendChild(node);\n appendedStylesRef.current.push(node as HTMLStyleElement);\n return;\n }\n\n if (shouldExecuteScripts) {\n const scriptNode = node as HTMLScriptElement;\n const scriptText = scriptNode.textContent || \"\";\n const shouldValidate = !scriptNode.src;\n\n if (shouldValidate) {\n try {\n // Validate script is syntactically complete before executing\n\n new Function(scriptText);\n } catch {\n scriptNode.remove();\n return;\n }\n }\n\n try {\n body.appendChild(scriptNode);\n appendedScriptsRef.current.push(scriptNode);\n } catch {\n scriptNode.remove();\n }\n } else {\n // Defer execution until all script tags are fully received\n node.remove();\n }\n });\n requestAnimationFrame(() => {\n if (hasStyles) {\n settleStateWithMinimumDelay(\n setIsGeneratingStyles,\n styleTimerRef,\n styleStartRef,\n () => {\n hasStylesRef.current = false;\n }\n );\n }\n if (hasScripts) {\n settleStateWithMinimumDelay(\n setIsGeneratingScripts,\n scriptTimerRef,\n scriptStartRef,\n () => {\n hasScriptsRef.current = false;\n }\n );\n }\n });\n }, [html, resetToken]);\n\n useEffect(\n () => () => {\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n },\n []\n );\n\n const overlayMessage = (() => {\n if (isGeneratingScripts || hasScriptsRef.current)\n return scriptLoadingText || \"Building scripts cache...\";\n if (isGeneratingStyles || hasStylesRef.current)\n return styleLoadingText || \"Building styles...\";\n return null;\n })();\n\n const isBlackboard = mode === \"blackboard\";\n const shouldStretchRootHeight = isBlackboard && stretchRootHeight;\n const sandboxWrapperStyle: React.CSSProperties = {\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n // Keep blackboard scroll behavior while centering content in non-blackboard mode\n justifyContent: shouldStretchRootHeight\n ? \"flex-start\"\n : isBlackboard\n ? \"space-around\"\n : \"flex-start\",\n };\n const sandboxContainerStyle: React.CSSProperties = {\n pointerEvents: overlayMessage ? \"none\" : undefined,\n margin: isBlackboard ? undefined : \"auto 0\",\n width: \"100%\",\n height: shouldStretchRootHeight ? \"100%\" : undefined,\n minHeight: shouldStretchRootHeight ? 0 : undefined,\n flex: shouldStretchRootHeight ? \"1 1 auto\" : undefined,\n };\n\n return (\n <div\n ref={wrapperRef}\n data-root-vh={hasRootVhHeight ? \"true\" : \"false\"}\n className=\"sandbox-wrapper\"\n style={sandboxWrapperStyle}\n aria-busy={!!overlayMessage}\n >\n <div\n ref={containerRef}\n className=\"sandbox-container\"\n style={sandboxContainerStyle}\n />\n {overlayMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"rgba(51, 51, 51, 0.80)\",\n color: \"#ffffff\",\n fontSize: 16,\n fontWeight: 700,\n gap: 10,\n pointerEvents: \"auto\",\n zIndex: 20,\n }}\n >\n <Loader2\n aria-hidden\n size={20}\n style={{ animation: \"sandbox-spin 1s linear infinite\" }}\n />\n {overlayMessage}\n </div>\n )}\n </div>\n );\n};\n\nexport default SandboxApp;\n"],"names":["IMAGE_REUSE_ATTRIBUTES","getImageReuseKey","image","attribute","collectReusableImages","root","imageMap","node","key","bucket","syncImageAttributes","sourceImage","targetImage","sourceAttributes","sourceAttributeNames","reuseRenderedImages","nextImage","preservedImage","clonedImage","SandboxApp","html","styleLoadingText","scriptLoadingText","resetToken","mode","hasRootVhHeight","stretchRootHeight","wrapperRef","useRef","containerRef","setIsWaitingFirstDiv","useState","isGeneratingStyles","setIsGeneratingStyles","isGeneratingScripts","setIsGeneratingScripts","appendedStylesRef","appendedScriptsRef","styleStartRef","scriptStartRef","styleTimerRef","scriptTimerRef","hasStylesRef","hasScriptsRef","hasRenderedContentRef","prevResetTokenRef","MIN_LOADING_MS","clearTimer","timerRef","settleStateWithMinimumDelay","setter","startRef","onDone","elapsed","delay","useEffect","doc","styleId","styleEl","container","body","reusableImages","hasRenderedBefore","wrapper","openScriptCount","closeScriptCount","shouldExecuteScripts","resourceQueue","cloned","attr","replacement","hasStyles","hasScripts","hasFirstElement","contentNodes","scriptNode","scriptText","overlayMessage","isBlackboard","shouldStretchRootHeight","sandboxWrapperStyle","sandboxContainerStyle","jsxs","jsx","Loader2"],"mappings":"8VAgBMA,EAAyB,CAC7B,MACA,SACA,QACA,MACA,QACA,QACA,SACA,QACA,UACA,WACA,cACA,iBACA,eACF,EAEMC,EAAoBC,GACxBF,EAAuB,IACpBG,GAAc,GAAGA,CAAS,IAAID,EAAM,aAAaC,CAAS,GAAK,EAAE,EACpE,EAAE,KAAK,GAAG,EAENC,GAAyBC,GAAqB,CAClD,MAAMC,MAAe,IACrB,OAAAD,EAAK,iBAAiB,KAAK,EAAE,QAASE,GAAS,CAC7C,MAAML,EAAQK,EACRC,EAAMP,EAAiBC,CAAK,EAC5BO,EAASH,EAAS,IAAIE,CAAG,GAAK,CAAA,EACpCC,EAAO,KAAKP,CAAK,EACjBI,EAAS,IAAIE,EAAKC,CAAM,CAC1B,CAAC,EACMH,CACT,EAEMI,GAAsB,CAC1BC,EACAC,IACG,CACH,MAAMC,EAAmB,MAAM,KAAKF,EAAY,UAAU,EACpDG,EAAuB,IAAI,IAC/BD,EAAiB,IAAKV,GAAcA,EAAU,IAAI,CAAA,EAGpD,MAAM,KAAKS,EAAY,UAAU,EAAE,QAAST,GAAc,CACnDW,EAAqB,IAAIX,EAAU,IAAI,GAC1CS,EAAY,gBAAgBT,EAAU,IAAI,CAE9C,CAAC,EAEDU,EAAiB,QAASV,GAAc,CACtCS,EAAY,aAAaT,EAAU,KAAMA,EAAU,KAAK,CAC1D,CAAC,CACH,EAEMY,GAAsB,CAC1BV,EACAC,IACG,CACEA,EAAS,MAEdD,EAAK,iBAAiB,KAAK,EAAE,QAASE,GAAS,CAC7C,MAAMS,EAAYT,EACZC,EAAMP,EAAiBe,CAAS,EAChCP,EAASH,EAAS,IAAIE,CAAG,EACzBS,EAAiBR,GAAQ,MAAA,EAC/B,GAAI,CAACQ,EAAgB,OAIrB,MAAMC,EAAcD,EAAe,UAAU,EAAI,EACjDP,GAAoBM,EAAWE,CAAW,EAC1CF,EAAU,YAAYE,CAAW,EAE7BT,GAAUA,EAAO,SAAW,GAC9BH,EAAS,OAAOE,CAAG,CAEvB,CAAC,CACH,EAEMW,GAAwC,CAAC,CAC7C,KAAAC,EACA,iBAAAC,EACA,kBAAAC,EACA,WAAAC,EAAa,EACb,KAAAC,EAAO,UACP,gBAAAC,EAAkB,GAClB,kBAAAC,EAAoB,EACtB,IAAM,CACJ,MAAMC,EAAaC,EAAAA,OAAuB,IAAI,EACxCC,EAAeD,EAAAA,OAAuB,IAAI,EAC1C,EAAGE,CAAoB,EAAIC,EAAAA,SAAS,EAAI,EACxC,CAACC,EAAoBC,CAAqB,EAAIF,EAAAA,SAAS,EAAK,EAC5D,CAACG,EAAqBC,CAAsB,EAAIJ,EAAAA,SAAS,EAAK,EAC9DK,EAAoBR,EAAAA,OAA2B,EAAE,EACjDS,EAAqBT,EAAAA,OAA4B,EAAE,EACnDU,EAAgBV,EAAAA,OAAO,CAAC,EACxBW,EAAiBX,EAAAA,OAAO,CAAC,EACzBY,EAAgBZ,EAAAA,OAAsB,IAAI,EAC1Ca,EAAiBb,EAAAA,OAAsB,IAAI,EAC3Cc,EAAed,EAAAA,OAAO,EAAK,EAC3Be,EAAgBf,EAAAA,OAAO,EAAK,EAC5BgB,EAAwBhB,EAAAA,OAAO,EAAK,EACpCiB,EAAoBjB,EAAAA,OAAOL,CAAU,EACrCuB,EAAiB,IAEjBC,EAAcC,GAAoD,CAClEA,EAAS,UACX,aAAaA,EAAS,OAAO,EAC7BA,EAAS,QAAU,KAEvB,EAEMC,EAA8B,CAClCC,EACAF,EACAG,EACAC,IACG,CACH,MAAMC,EAAU,YAAY,IAAA,EAAQF,EAAS,QACvCG,EAAQ,KAAK,IAAI,EAAGR,EAAiBO,CAAO,EAClDN,EAAWC,CAAQ,EACnBA,EAAS,QAAU,OAAO,WAAW,IAAM,CACzCE,EAAO,EAAK,EACZE,IAAA,EACAJ,EAAS,QAAU,IACrB,EAAGM,CAAK,CACV,EAEAC,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAM3B,EAAa,SAAS,cAClC,GAAI,CAAC2B,EAAK,OACV,MAAMC,EAAU,wBAChB,IAAIC,EAAUF,EAAI,eAAeC,CAAO,EACnCC,IACHA,EAAUF,EAAI,cAAc,OAAO,EACnCE,EAAQ,GAAKD,EACbD,EAAI,MAAM,YAAYE,CAAO,GAE/BA,EAAQ,YAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAUxB,EAAG,CAAA,CAAE,EAELH,EAAAA,UAAU,IAAM,CACVhC,IAAesB,EAAkB,UACnCD,EAAsB,QAAU,GAChCC,EAAkB,QAAUtB,GAE9BwB,EAAWP,CAAa,EACxBO,EAAWN,CAAc,EACzBC,EAAa,QAAU,GACvBC,EAAc,QAAU,GAExB,MAAMgB,EAAY9B,EAAa,QAC/B,GAAI,CAAC8B,EAAW,OAChB,MAAMH,EAAMG,EAAU,cAChBC,EAAOJ,GAAK,KAClB,GAAI,CAACI,EAAM,OACX,MAAMC,EAAiBzD,GAAsBuD,CAAS,EAEtDvB,EAAkB,QAAQ,QAAS7B,GAASA,EAAK,QAAQ,EACzD6B,EAAkB,QAAU,CAAA,EAC5BC,EAAmB,QAAQ,QAAS9B,GAASA,EAAK,QAAQ,EAC1D8B,EAAmB,QAAU,CAAA,EAE7B,MAAMyB,EAAoBlB,EAAsB,QAChDd,EAAqB,CAACgC,CAAiB,EACvC7B,EAAsB,EAAK,EAC3BE,EAAuB,EAAK,EAC5B,MAAM4B,EAAUP,EAAI,cAAc,KAAK,EACvCO,EAAQ,UAAY3C,EAEpB,MAAM4C,GAAmB5C,EAAK,MAAM,gBAAgB,GAAK,CAAA,GAAI,OACvD6C,GAAoB7C,EAAK,MAAM,cAAc,GAAK,CAAA,GAAI,OACtD8C,EACJF,EAAkB,GAAKA,IAAoBC,EAEvCE,EAA+B,CAAA,EAErC,MAAM,KAAKJ,EAAQ,iBAAiB,eAAe,CAAC,EAAE,QAASxD,GAAS,CACtE,GAAIA,EAAK,QAAQ,YAAA,IAAkB,QAAS,CAC1C,MAAM6D,EAASZ,EAAI,cAAc,OAAO,EACxCY,EAAO,YAAc7D,EAAK,aAAe,GACzC,MAAM,KAAKA,EAAK,UAAU,EAAE,QAAS8D,GAAS,CAC5CD,EAAO,aAAaC,EAAK,KAAMA,EAAK,KAAK,CAC3C,CAAC,EACDF,EAAc,KAAKC,CAAM,CAC3B,KAAO,CACL,MAAME,EAAcd,EAAI,cAAc,QAAQ,EAC9C,MAAM,KAAKjD,EAAK,UAAU,EAAE,QAAS8D,GAAS,CAC5CC,EAAY,aAAaD,EAAK,KAAMA,EAAK,KAAK,CAChD,CAAC,EACDC,EAAY,YAAc/D,EAAK,aAAe,GAC9C4D,EAAc,KAAKG,CAAW,CAChC,CACA/D,EAAK,OAAA,CACP,CAAC,EACDQ,GAAoBgD,EAASF,CAAc,EAE3C,MAAMU,EAAYJ,EAAc,KAC7B5D,GAASA,EAAK,QAAQ,gBAAkB,OAAA,EAErCiE,EAAaL,EAAc,KAC9B5D,GAASA,EAAK,QAAQ,gBAAkB,QAAA,EAEvCgE,IACF7B,EAAa,QAAU,GACvBJ,EAAc,QAAU,YAAY,IAAA,EACpCS,EAAWP,CAAa,EACxBP,EAAsB,EAAI,GAExBuC,IACF7B,EAAc,QAAU,GACxBJ,EAAe,QAAU,YAAY,IAAA,EACrCQ,EAAWN,CAAc,EACzBN,EAAuB,EAAI,GAG7B,MAAMsC,EAAkB,CAAC,CAACV,EAAQ,kBAClCjC,EAAqB,CAAC2C,GAAmB,CAACX,CAAiB,EACvDW,IACF7B,EAAsB,QAAU,IAGlC,MAAM8B,EAAe,MAAM,KAAKX,EAAQ,UAAU,EAClDJ,EAAU,gBAAgB,GAAGe,CAAY,EAEzCP,EAAc,QAAS5D,GAAS,CAC9B,GAAIA,EAAK,QAAQ,YAAA,IAAkB,QAAS,CAC1CiD,EAAI,MAAM,YAAYjD,CAAI,EAC1B6B,EAAkB,QAAQ,KAAK7B,CAAwB,EACvD,MACF,CAEA,GAAI2D,EAAsB,CACxB,MAAMS,EAAapE,EACbqE,EAAaD,EAAW,aAAe,GAG7C,GAFuB,CAACA,EAAW,IAGjC,GAAI,CAGF,IAAI,SAASC,CAAU,CACzB,MAAQ,CACND,EAAW,OAAA,EACX,MACF,CAGF,GAAI,CACFf,EAAK,YAAYe,CAAU,EAC3BtC,EAAmB,QAAQ,KAAKsC,CAAU,CAC5C,MAAQ,CACNA,EAAW,OAAA,CACb,CACF,MAEEpE,EAAK,OAAA,CAET,CAAC,EACD,sBAAsB,IAAM,CACtBgE,GACFtB,EACEhB,EACAO,EACAF,EACA,IAAM,CACJI,EAAa,QAAU,EACzB,CAAA,EAGA8B,GACFvB,EACEd,EACAM,EACAF,EACA,IAAM,CACJI,EAAc,QAAU,EAC1B,CAAA,CAGN,CAAC,CACH,EAAG,CAACvB,EAAMG,CAAU,CAAC,EAErBgC,EAAAA,UACE,IAAM,IAAM,CACVR,EAAWP,CAAa,EACxBO,EAAWN,CAAc,CAC3B,EACA,CAAA,CAAC,EAGH,MAAMoC,EACA3C,GAAuBS,EAAc,QAChCrB,GAAqB,4BAC1BU,GAAsBU,EAAa,QAC9BrB,GAAoB,qBACtB,KAGHyD,EAAetD,IAAS,aACxBuD,EAA0BD,GAAgBpD,EAC1CsD,EAA2C,CAC/C,SAAU,WACV,MAAO,OACP,OAAQ,OACR,QAAS,OACT,cAAe,SAEf,eAAgBD,EACZ,aACAD,EACE,eACA,YAAA,EAEFG,EAA6C,CACjD,cAAeJ,EAAiB,OAAS,OACzC,OAAQC,EAAe,OAAY,SACnC,MAAO,OACP,OAAQC,EAA0B,OAAS,OAC3C,UAAWA,EAA0B,EAAI,OACzC,KAAMA,EAA0B,WAAa,MAAA,EAG/C,OACEG,EAAAA,kBAAAA,KAAC,MAAA,CACC,IAAKvD,EACL,eAAcF,EAAkB,OAAS,QACzC,UAAU,kBACV,MAAOuD,EACP,YAAW,CAAC,CAACH,EAEb,SAAA,CAAAM,EAAAA,kBAAAA,IAAC,MAAA,CACC,IAAKtD,EACL,UAAU,oBACV,MAAOoD,CAAA,CAAA,EAERJ,GACCK,EAAAA,kBAAAA,KAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,MAAO,EACP,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,WAAY,yBACZ,MAAO,UACP,SAAU,GACV,WAAY,IACZ,IAAK,GACL,cAAe,OACf,OAAQ,EAAA,EAGV,SAAA,CAAAC,EAAAA,kBAAAA,IAACC,EAAAA,QAAA,CACC,cAAW,GACX,KAAM,GACN,MAAO,CAAE,UAAW,iCAAA,CAAkC,CAAA,EAEvDP,CAAA,CAAA,CAAA,CACH,CAAA,CAAA,CAIR"}