markdown-flow-ui 0.1.102-beat.3 → 0.1.102-beat.4
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.
- package/dist/_virtual/index.cjs10.js +1 -1
- package/dist/_virtual/index.cjs11.js +1 -1
- package/dist/_virtual/index.cjs7.js +1 -1
- package/dist/_virtual/index.cjs8.js +1 -1
- package/dist/_virtual/index.cjs9.js +1 -1
- package/dist/_virtual/index.es10.js +3 -2
- package/dist/_virtual/index.es10.js.map +1 -1
- package/dist/_virtual/index.es11.js +2 -3
- package/dist/_virtual/index.es11.js.map +1 -1
- package/dist/_virtual/index.es7.js +2 -3
- package/dist/_virtual/index.es7.js.map +1 -1
- package/dist/_virtual/index.es8.js +3 -2
- package/dist/_virtual/index.es8.js.map +1 -1
- package/dist/_virtual/index.es9.js +2 -2
- package/dist/components/ContentRender/IframeSandbox.cjs.js +3 -3
- package/dist/components/ContentRender/IframeSandbox.cjs.js.map +1 -1
- package/dist/components/ContentRender/IframeSandbox.es.js +70 -70
- package/dist/components/ContentRender/IframeSandbox.es.js.map +1 -1
- package/dist/node_modules/@braintree/sanitize-url/dist/index.cjs.js +1 -1
- package/dist/node_modules/@braintree/sanitize-url/dist/index.es.js +1 -1
- package/dist/node_modules/classnames/index.cjs.js +1 -1
- package/dist/node_modules/classnames/index.es.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-AAMF2YG6.cjs.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-AAMF2YG6.es.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-OMD6QJNC.cjs.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-OMD6QJNC.es.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-U37J5Y7L.cjs.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/chunk-U37J5Y7L.es.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-WV7ZQ7D5.cjs.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-WV7ZQ7D5.es.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-4MX5Z3NR.cjs.js +1 -1
- package/dist/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-4MX5Z3NR.es.js +1 -1
- package/dist/node_modules/rc-util/es/ref.cjs.js +1 -1
- package/dist/node_modules/rc-util/es/ref.es.js +1 -1
- package/dist/node_modules/style-to-object/cjs/index.cjs.js +1 -1
- package/dist/node_modules/style-to-object/cjs/index.es.js +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../node_modules/rc-util/node_modules/react-is/index.cjs.js");var r=e.__require();exports.reactIsExports=r;
|
|
2
2
|
//# sourceMappingURL=index.cjs10.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={};exports.__exports=e;
|
|
2
2
|
//# sourceMappingURL=index.cjs11.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={exports:{}};exports.__module=e;
|
|
2
2
|
//# sourceMappingURL=index.cjs7.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../node_modules/@braintree/sanitize-url/dist/index.cjs.js");var r=e.__require();exports.distExports=r;
|
|
2
2
|
//# sourceMappingURL=index.cjs8.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={};exports.__exports=e;
|
|
2
2
|
//# sourceMappingURL=index.cjs9.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es10.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.es10.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es11.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.es11.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es7.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.es7.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es8.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.es8.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const
|
|
2
|
-
<html${
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const E=require("../../_virtual/jsx-runtime.cjs.js"),t=require("react"),je=require("react-dom/client"),Ne=require("./SandboxApp.cjs.js"),Ve=require("./ContentRender.cjs.js"),w=require("./utils/iframe-viewport-height.cjs.js"),Re=require("../../lib/sandboxInteraction.cjs.js");let J=null;const Pe=()=>(J||(J=Promise.resolve().then(()=>require("./blackboard-vendor.cjs.js")).then(l=>l.injectBlackboardLibraries)),J),qe=/<img\b[^>]*>/i,De=180,ke=240,Be=l=>l.split(/\s+/).filter(Boolean).map(i=>{const s=i.split(":");return s[s.length-1]!=="h-screen"&&s[s.length-1]!=="min-h-screen"?i:(s[s.length-1]="h-full",s.join(":"))}).join(" "),Le=(l,i)=>!i||!l.trim()?l:l.replace(/^(\s*<[a-zA-Z][\w:-]*)(\s[^>]*?)?>/,(s,A,R="")=>{const h=R.match(/\bclass\s*=\s*(["'])([^"']*)\1/i);if(!h)return s;const F=Be(h[2]);return F===h[2]?s:`${A}${R.replace(h[0],`class=${h[1]}${F}${h[1]}`)}>`}),ze=({content:l,type:i,className:s,styleLoadingText:A,scriptLoadingText:R,fullScreenButtonText:h,hideFullScreen:F=!1,mode:g="content",replaceRootScreenHeightWithFull:ve=!1,minAspectRatio:K=16/9,maxAspectRatio:k})=>{const B=t.useRef(null),b=t.useRef(null),L=t.useRef(null),v=t.useRef(()=>{}),[Se,Q]=t.useState(480),ee=t.useRef(0),[te,ne]=t.useState(480),[I,re]=t.useState(0),[oe,Ce]=t.useState(0),[z,ye]=t.useState(!1),Me=i==="sandbox",f=g==="blackboard",S=i==="sandbox",H=S&&ve,G=t.useRef(""),O=t.useMemo(()=>i==="sandbox"?l:"",[l,i]),o=t.useMemo(()=>Le(O,H),[O,H]),ie=t.useMemo(()=>H?w.inspectViewportHeightFromHtmlRootString(O):w.EMPTY_ROOT_HEIGHT_META,[O,H]),se=t.useMemo(()=>H&&ie.hasFullViewportHeight,[ie.hasFullViewportHeight,H]),[_,le]=t.useState(o),ce=t.useRef(o),W=t.useRef(o),C=t.useRef(null),y=t.useRef(null),ue=t.useRef(null),x=t.useCallback(n=>{if(typeof window>"u")return;const e=Date.now();e-ee.current<ke||(ee.current=e,window.postMessage({source:Re.SANDBOX_INTERACTION_MESSAGE_SOURCE,type:Re.SANDBOX_INTERACTION_MESSAGE_TYPE,eventType:n},window.location.origin))},[]),$=()=>{C.current!==null&&(window.clearTimeout(C.current),C.current=null)},Te=()=>{y.current!==null&&(window.cancelAnimationFrame(y.current),y.current=null)};t.useEffect(()=>()=>{$(),Te()},[]),t.useEffect(()=>{const n=ce.current;ce.current=o;const e=!!n&&o.length>n.length&&o.startsWith(n),c=qe.test(o);if(!(e&&c)){$(),W.current=o,le(o);return}W.current=o,$(),C.current=window.setTimeout(()=>{le(W.current),C.current=null},De)},[o]);const j=t.useMemo(()=>!S||!f?null:w.inspectViewportHeightFromHtmlRootString(_).viewportHeightCss,[_,S,f]);t.useEffect(()=>{ue.current=j},[j]);const ae=!!j,M=f&&i==="sandbox"?se?"100%":j??`${Se}px`:void 0;t.useEffect(()=>{if(g!=="blackboard"){G.current=o;return}const n=G.current;!(n&&o.startsWith(n))&&n&&Ce(c=>c+1),G.current=o},[g,o]),t.useEffect(()=>{const n=b.current;if(!n)return;const e=n.contentDocument;if(!e)return;e.open(),e.write(`<!DOCTYPE html>
|
|
2
|
+
<html${g==="blackboard"?' style="height: 100%;"':""}>
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
<body>
|
|
14
14
|
<div id="root"></div>
|
|
15
15
|
</body>
|
|
16
|
-
</html>`),e.close(),e.documentElement.setAttribute("data-theme","light"),e.documentElement.style.colorScheme="light",e.body?.style.setProperty("color-scheme","light");const c=
|
|
16
|
+
</html>`),e.close(),e.documentElement.setAttribute("data-theme","light"),e.documentElement.style.colorScheme="light",e.body?.style.setProperty("color-scheme","light");const c=f&&i==="sandbox",U=()=>x("pointerdown"),he=()=>x("mousedown"),fe=()=>x("touchstart");c&&(e.addEventListener("pointerdown",U,!0),e.addEventListener("mousedown",he,!0),e.addEventListener("touchstart",fe,!0));const N=e.getElementById("root");if(!N)return;const me=je.createRoot(N);L.current=me;let p=!1;const ge=r=>({heightAttrValue:r.getAttribute("height"),styleAttrValue:r.getAttribute("style"),classAttrValue:r.getAttribute("class")}),be=r=>{const a=Array.from(r.children);return a.length===1?a[0]:null},Ie=()=>{if(!S||!f||!b.current||!e.body)return null;const r=b.current.ownerDocument?.documentElement?.clientHeight||window.innerHeight,a=ue.current,d=a?w.parseExplicitHeight(a,r):null;if(d!==null)return Math.ceil(d);const u=e.body.querySelector(".sandbox-wrapper")?.firstElementChild;if(!u)return null;const T=Array.from(u.children),we=T.length===1?T[0]:null,He=w.inspectViewportHeightFromNodeChain(we,{getNode:ge,getSingleChild:be}).viewportHeightCss;if(He){const Ee=w.parseExplicitHeight(He,r);if(Ee!==null)return Math.ceil(Ee)}const xe=w.resolveExplicitHeightFromNodeChain(we,r,{getNode:ge,getSingleChild:be});return xe!==null?Math.ceil(xe):null},Oe=()=>{if(!e.body)return 0;const r=b.current;if(!r)return 0;const a=r.style.height;r.style.height="0px";let d=0,m=0;try{d=e.body.querySelector(".sandbox-container")?.scrollHeight||0,m=e.body.scrollHeight}finally{r.style.height=a}return Math.max(d,m)};let V=200,P=0;const _e=60,q=()=>{if(!S||!b.current||!e.body)return;const r=Oe(),a=Ie();if(a!==null){const u=Math.max(200,a);P=0,V=u,Q(T=>T===u?T:u),ne(u);return}const d=Math.max(200,Math.ceil(r)+1);let m=d;d>V+2?(P++,P>_e&&(m=V)):P=0,V=d,Q(u=>u===m?u:m),ne(m)},D=()=>{requestAnimationFrame(()=>{p||q()})};v.current=D,q(),D(),Me&&Pe().then(r=>{p||(r(e),requestAnimationFrame(()=>{p||D()}))}).catch(()=>{p||D()});let X=!1;const Y=new ResizeObserver(()=>{X||(X=!0,requestAnimationFrame(()=>{X=!1,p||q()}))});Y.observe(e.body),N&&Y.observe(N);let Z=!1;const pe=new MutationObserver(()=>{Z||(Z=!0,requestAnimationFrame(()=>{Z=!1,p||q()}))});return pe.observe(e.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class"]}),()=>{p=!0,Y.disconnect(),pe.disconnect(),c&&(e.removeEventListener("pointerdown",U,!0),e.removeEventListener("mousedown",he,!0),e.removeEventListener("touchstart",fe,!0)),setTimeout(()=>{me.unmount(),L.current=null,v.current=()=>{}},0)}},[]),t.useEffect(()=>{const n=()=>{ye(!!document.fullscreenElement)};return document.addEventListener("fullscreenchange",n),()=>document.removeEventListener("fullscreenchange",n)},[]),t.useEffect(()=>{const n=B.current;if(!n)return;const e=new ResizeObserver(c=>{re(c[0]?.contentRect.width??n.clientWidth)});return e.observe(n),re(n.clientWidth),()=>e.disconnect()},[]);const de=t.useMemo(()=>{if(f||I===0||z)return;const n=Math.round(I/K),e=k?Math.round(I/k):1/0;return{height:Math.max(n,Math.min(e,te))}},[f,I,te,z,K,k]),Ae=()=>{const n=B.current||b.current;if(n){if(document.fullscreenElement){document.exitFullscreen().catch(()=>{});return}n.requestFullscreen&&n.requestFullscreen().catch(()=>{})}};t.useEffect(()=>{const n=L.current;if(!n)return;n.render(E.jsxRuntimeExports.jsx(Ne.default,{html:_,styleLoadingText:A,scriptLoadingText:R,resetToken:oe,hasRootVhHeight:ae,mode:g,stretchRootHeight:se})),y.current=window.requestAnimationFrame(()=>{v.current?.(),y.current=null});const e=setTimeout(()=>v.current?.(),100),c=setTimeout(()=>v.current?.(),500);return()=>{clearTimeout(e),clearTimeout(c)}},[_,A,R,oe,g]);const Fe=["w-full relative content-render-iframe-sandbox",f?"h-full overflow-auto flex flex-col":de?"overflow-hidden flex items-center justify-center":"aspect-[16/9] overflow-hidden flex items-center justify-center"].filter(Boolean).join(" ");return E.jsxRuntimeExports.jsxs("div",{ref:B,"data-root-vh":ae?"true":"false",className:Fe,style:M?{height:M,minHeight:M}:de,children:[!F&&E.jsxRuntimeExports.jsx("button",{type:"button",onClick:Ae,className:"absolute top-2 right-2 z-50 p-1.5 bg-black/75 text-white rounded-md cursor-pointer",children:z?"退出全屏":h||"全屏浏览"}),g==="blackboard"&&i==="markdown"?E.jsxRuntimeExports.jsx("div",{onMouseDown:()=>x("mousedown"),onPointerDown:()=>x("pointerdown"),onTouchStart:()=>x("touchstart"),children:E.jsxRuntimeExports.jsx(Ve.default,{content:l})}):E.jsxRuntimeExports.jsx("iframe",{ref:b,sandbox:"allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox",allow:"fullscreen",allowFullScreen:!0,className:[s,"w-full h-full mx-auto my-auto block"].filter(Boolean).join(" "),style:{height:M??"100%",minHeight:M,margin:"auto",visibility:"visible"}})]})};exports.default=ze;
|
|
17
17
|
//# sourceMappingURL=IframeSandbox.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IframeSandbox.cjs.js","sources":["../../../src/components/ContentRender/IframeSandbox.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createRoot, Root } from \"react-dom/client\";\nimport SandboxApp from \"./SandboxApp\";\nimport ContentRender from \"./ContentRender\";\nimport {\n EMPTY_ROOT_HEIGHT_META,\n inspectViewportHeightFromHtmlRootString,\n inspectViewportHeightFromNodeChain,\n parseExplicitHeight,\n resolveExplicitHeightFromNodeChain,\n} from \"./utils/iframe-viewport-height\";\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 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 /** Min aspect ratio for content mode (width/height). Default 16/9. Controls minimum height = width / ratio. */\n minAspectRatio?: number;\n /** Max aspect ratio for content mode (width/height). Default: no limit (iframe grows to fit all content, no scrollbar). Set to e.g. 4/3 to cap height and allow scrollbar. */\n maxAspectRatio?: number;\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 styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n hideFullScreen = false,\n mode = \"content\",\n replaceRootScreenHeightWithFull = false,\n minAspectRatio = 16 / 9,\n maxAspectRatio,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const rootRef = useRef<Root | null>(null);\n const updateHeightRef = useRef<() => void>(() => {});\n const [height, setHeight] = useState(480);\n const lastSandboxInteractionTimeRef = useRef(0);\n const [contentHeight, setContentHeight] = useState(480);\n const [containerWidth, setContainerWidth] = useState(0);\n const [resetToken, setResetToken] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const shouldInjectSandboxVendor = type === \"sandbox\";\n\n const isBlackboardMode = mode === \"blackboard\";\n const shouldMeasureDynamicHeight = type === \"sandbox\";\n const shouldProcessRootScreenHeight =\n shouldMeasureDynamicHeight && replaceRootScreenHeightWithFull;\n const prevHtmlRef = useRef<string>(\"\");\n const htmlContent = React.useMemo(\n () => (type === \"sandbox\" ? content : \"\"),\n [content, type]\n );\n const normalizedHtmlContent = React.useMemo(\n () =>\n replaceRootScreenHeightWithFullClass(\n htmlContent,\n shouldProcessRootScreenHeight\n ),\n [htmlContent, shouldProcessRootScreenHeight]\n );\n const originalRootHeightMeta = React.useMemo(\n () =>\n shouldProcessRootScreenHeight\n ? inspectViewportHeightFromHtmlRootString(htmlContent)\n : EMPTY_ROOT_HEIGHT_META,\n [htmlContent, shouldProcessRootScreenHeight]\n );\n const shouldStretchRootHeight = React.useMemo(\n () =>\n shouldProcessRootScreenHeight &&\n originalRootHeightMeta.hasFullViewportHeight,\n [\n originalRootHeightMeta.hasFullViewportHeight,\n shouldProcessRootScreenHeight,\n ]\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 renderViewportHeightCssRef = useRef<string | 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 if (!shouldDeferRender) {\n clearDeferredRenderTimer();\n pendingHtmlRef.current = normalizedHtmlContent;\n setRenderHtmlContent(normalizedHtmlContent);\n return;\n }\n\n pendingHtmlRef.current = normalizedHtmlContent;\n clearDeferredRenderTimer();\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 if (!shouldMeasureDynamicHeight) {\n return null;\n }\n\n return inspectViewportHeightFromHtmlRootString(renderHtmlContent)\n .viewportHeightCss;\n }, [renderHtmlContent, shouldMeasureDynamicHeight]);\n\n useEffect(() => {\n renderViewportHeightCssRef.current = rootViewportHeightCss;\n }, [rootViewportHeightCss]);\n\n const hasRootVhHeight = Boolean(rootViewportHeightCss);\n const sandboxViewportHeight =\n isBlackboardMode && type === \"sandbox\"\n ? shouldStretchRootHeight\n ? \"100%\"\n : (rootViewportHeightCss ?? `${height}px`)\n : undefined;\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 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 const getHeightInspectionNode = (node: HTMLElement) => ({\n heightAttrValue: node.getAttribute(\"height\"),\n styleAttrValue: node.getAttribute(\"style\"),\n classAttrValue: node.getAttribute(\"class\"),\n });\n const getSingleChildElement = (node: HTMLElement) => {\n const childElements = Array.from(node.children) as HTMLElement[];\n\n return childElements.length === 1 ? childElements[0] : null;\n };\n\n const resolveExplicitHeight = () => {\n if (!shouldMeasureDynamicHeight) return null;\n if (!iframeRef.current || !doc.body) return null;\n const parentViewportHeight =\n iframeRef.current.ownerDocument?.documentElement?.clientHeight ||\n window.innerHeight;\n // Reuse parsed height metadata from the current html snapshot first to\n // avoid re-inspecting the same DOM chain on every height tick.\n const precomputedViewportHeightCss = renderViewportHeightCssRef.current;\n const parsed = precomputedViewportHeightCss\n ? parseExplicitHeight(\n precomputedViewportHeightCss,\n parentViewportHeight\n )\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 container = wrapper?.firstElementChild as HTMLElement | null;\n if (!container) return null;\n const containerChildren = Array.from(container.children) as HTMLElement[];\n const rootContentElement =\n containerChildren.length === 1 ? containerChildren[0] : null;\n const runtimeHeightMeta = inspectViewportHeightFromNodeChain(\n rootContentElement,\n {\n getNode: getHeightInspectionNode,\n getSingleChild: getSingleChildElement,\n }\n );\n const runtimeViewportHeightCss = runtimeHeightMeta.viewportHeightCss;\n\n if (runtimeViewportHeightCss) {\n const runtimeViewportHeight = parseExplicitHeight(\n runtimeViewportHeightCss,\n parentViewportHeight\n );\n\n if (runtimeViewportHeight !== null) {\n return Math.ceil(runtimeViewportHeight);\n }\n }\n\n const explicitPixelHeight = resolveExplicitHeightFromNodeChain(\n rootContentElement,\n parentViewportHeight,\n {\n getNode: getHeightInspectionNode,\n getSingleChild: getSingleChildElement,\n }\n );\n\n return explicitPixelHeight !== null\n ? Math.ceil(explicitPixelHeight)\n : null;\n };\n\n const measureContentHeight = () => {\n if (!doc.body) return 0;\n const iframe = iframeRef.current;\n if (!iframe) return 0;\n\n // Temporarily shrink the iframe to 0px to break the circular dependency\n // with viewport-relative units (100vh, min-h-screen, 100dvh, etc.).\n // When iframe height is 0, 100vh resolves to 0 inside the iframe,\n // so we measure only the intrinsic content height.\n // Since shrink and restore happen within the same synchronous JS\n // execution (before the browser paints), there is no visual flicker.\n // Note: savedHeight may be \"\" on first call (height comes from CSS class\n // `h-full`), restoring \"\" correctly removes the inline override.\n const savedHeight = iframe.style.height;\n iframe.style.height = \"0px\";\n\n let containerScrollH = 0;\n let bodyScrollH = 0;\n try {\n const sandboxContainer = doc.body.querySelector(\n \".sandbox-container\"\n ) as HTMLElement | null;\n containerScrollH = sandboxContainer?.scrollHeight || 0;\n bodyScrollH = doc.body.scrollHeight;\n } finally {\n // Restore immediately — must run even if measurement throws\n iframe.style.height = savedHeight;\n }\n\n return Math.max(containerScrollH, bodyScrollH);\n };\n\n let prevRawHeight = 200;\n let consecutiveGrowthCount = 0;\n // The shrink-to-0 measurement technique already prevents the main\n // feedback loop caused by viewport-relative units. This guard is a\n // last-resort safety net for pathological cases (e.g. JS inside the\n // sandbox that keeps resizing on every frame). A high threshold\n // avoids freezing legitimate streaming content which may grow over\n // many consecutive frames.\n const MAX_CONSECUTIVE_GROWTH = 60;\n\n const updateHeight = () => {\n if (!shouldMeasureDynamicHeight) return;\n if (!iframeRef.current || !doc.body) return;\n const measuredHeight = measureContentHeight();\n const explicitHeight = resolveExplicitHeight();\n\n // When an explicit viewport height is declared (e.g. height=\"100vh\"),\n // the shrink-measure approach already handles it correctly.\n // Skip the growth guard to avoid freezing intentional height changes.\n if (explicitHeight !== null) {\n const nextHeight = Math.max(200, explicitHeight);\n consecutiveGrowthCount = 0;\n prevRawHeight = nextHeight;\n setHeight((prev) => (prev === nextHeight ? prev : nextHeight));\n setContentHeight(nextHeight);\n return;\n }\n\n // Add 1px buffer to avoid scrollbar caused by sub-pixel rounding\n const rawHeight = Math.max(200, Math.ceil(measuredHeight) + 1);\n\n // Safety guard: if measured height keeps growing consecutively beyond\n // a threshold, freeze at the last stable value to prevent any\n // residual feedback loop. Always track the raw measurement so that\n // legitimate future growth (e.g. user interaction) is not blocked.\n let nextHeight = rawHeight;\n if (rawHeight > prevRawHeight + 2) {\n consecutiveGrowthCount++;\n if (consecutiveGrowthCount > MAX_CONSECUTIVE_GROWTH) {\n nextHeight = prevRawHeight;\n }\n } else {\n consecutiveGrowthCount = 0;\n }\n prevRawHeight = rawHeight;\n\n setHeight((prev) => (prev === nextHeight ? prev : nextHeight));\n setContentHeight(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 // Inject Tailwind/DaisyUI/GSAP before rendering sandbox content to avoid FOUC.\n loadBlackboardVendor()\n .then((inject) => {\n if (isDestroyed) return;\n inject(doc);\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n scheduleHeightUpdate();\n });\n })\n .catch(() => {\n if (isDestroyed) return;\n scheduleHeightUpdate();\n });\n }\n\n let resizeRafPending = false;\n const resizeObserver = new ResizeObserver(() => {\n if (resizeRafPending) return;\n resizeRafPending = true;\n requestAnimationFrame(() => {\n resizeRafPending = false;\n if (!isDestroyed) updateHeight();\n });\n });\n resizeObserver.observe(doc.body);\n if (rootEl) {\n resizeObserver.observe(rootEl);\n }\n\n // MutationObserver as backup: detect DOM changes that ResizeObserver might miss\n // (e.g. content injected by scripts, images loading, dynamic rendering).\n // Uses the same RAF deduplication pattern as ResizeObserver above.\n let mutationRafPending = false;\n const mutationObserver = new MutationObserver(() => {\n if (mutationRafPending) return;\n mutationRafPending = true;\n requestAnimationFrame(() => {\n mutationRafPending = false;\n if (!isDestroyed) updateHeight();\n });\n });\n mutationObserver.observe(doc.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"style\", \"class\"],\n });\n\n return () => {\n isDestroyed = true;\n resizeObserver.disconnect();\n mutationObserver.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 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 useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const ro = new ResizeObserver((entries) => {\n setContainerWidth(entries[0]?.contentRect.width ?? el.clientWidth);\n });\n ro.observe(el);\n setContainerWidth(el.clientWidth);\n return () => ro.disconnect();\n }, []);\n\n const contentModeStyle = useMemo<React.CSSProperties | undefined>(() => {\n if (isBlackboardMode || containerWidth === 0 || isFullscreen)\n return undefined;\n const minH = Math.round(containerWidth / minAspectRatio);\n // No maxAspectRatio → no upper limit, iframe grows to fit all content (no scrollbar).\n // With maxAspectRatio → cap height at width / ratio (scrollbar appears if content exceeds).\n const maxH = maxAspectRatio\n ? Math.round(containerWidth / maxAspectRatio)\n : Infinity;\n const clampedH = Math.max(minH, Math.min(maxH, contentHeight));\n return { height: clampedH };\n }, [\n isBlackboardMode,\n containerWidth,\n contentHeight,\n isFullscreen,\n minAspectRatio,\n maxAspectRatio,\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 styleLoadingText={styleLoadingText}\n scriptLoadingText={scriptLoadingText}\n resetToken={resetToken}\n hasRootVhHeight={hasRootVhHeight}\n mode={mode}\n stretchRootHeight={shouldStretchRootHeight}\n />\n );\n\n // SandboxApp renders content via DOM manipulation in its useEffect.\n // Schedule multiple measurements to catch async content (scripts, images, styles).\n initialPaintFrameRef.current = window.requestAnimationFrame(() => {\n updateHeightRef.current?.();\n initialPaintFrameRef.current = null;\n });\n const t1 = setTimeout(() => updateHeightRef.current?.(), 100);\n const t2 = setTimeout(() => updateHeightRef.current?.(), 500);\n return () => {\n clearTimeout(t1);\n clearTimeout(t2);\n };\n }, [\n renderHtmlContent,\n styleLoadingText,\n scriptLoadingText,\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 : contentModeStyle\n ? \"overflow-hidden flex items-center justify-center\"\n : \"aspect-[16/9] overflow-hidden flex items-center justify-center\",\n ]\n .filter(Boolean)\n .join(\" \");\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 : contentModeStyle\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 <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 )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["blackboardVendorPromise","loadBlackboardVendor","m","COMPLETE_IMAGE_TAG_PATTERN","POST_IMAGE_STREAM_DEBOUNCE_MS","SANDBOX_INTERACTION_THROTTLE_MS","replaceRootScreenHeightToken","className","token","segments","replaceRootScreenHeightWithFullClass","html","enabled","match","tagStart","attrs","classMatch","nextClassName","IframeSandbox","content","type","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","replaceRootScreenHeightWithFull","minAspectRatio","maxAspectRatio","containerRef","useRef","iframeRef","rootRef","updateHeightRef","height","setHeight","useState","lastSandboxInteractionTimeRef","contentHeight","setContentHeight","containerWidth","setContainerWidth","resetToken","setResetToken","isFullscreen","setIsFullscreen","shouldInjectSandboxVendor","isBlackboardMode","shouldMeasureDynamicHeight","shouldProcessRootScreenHeight","prevHtmlRef","htmlContent","React","normalizedHtmlContent","originalRootHeightMeta","inspectViewportHeightFromHtmlRootString","EMPTY_ROOT_HEIGHT_META","shouldStretchRootHeight","renderHtmlContent","setRenderHtmlContent","prevIncomingHtmlRef","pendingHtmlRef","deferRenderTimerRef","initialPaintFrameRef","renderViewportHeightCssRef","emitSandboxInteraction","useCallback","eventType","now","SANDBOX_INTERACTION_MESSAGE_SOURCE","SANDBOX_INTERACTION_MESSAGE_TYPE","clearDeferredRenderTimer","clearInitialPaintFrames","useEffect","prevIncomingHtml","isAppendOnlyStream","containsCompleteImage","rootViewportHeightCss","hasRootVhHeight","sandboxViewportHeight","prev","iframe","doc","shouldBridgeSandboxInteraction","handleSandboxPointerDown","handleSandboxMouseDown","handleSandboxTouchStart","rootEl","root","createRoot","isDestroyed","getHeightInspectionNode","node","getSingleChildElement","childElements","resolveExplicitHeight","parentViewportHeight","precomputedViewportHeightCss","parsed","parseExplicitHeight","container","containerChildren","rootContentElement","runtimeViewportHeightCss","inspectViewportHeightFromNodeChain","runtimeViewportHeight","explicitPixelHeight","resolveExplicitHeightFromNodeChain","measureContentHeight","savedHeight","containerScrollH","bodyScrollH","prevRawHeight","consecutiveGrowthCount","MAX_CONSECUTIVE_GROWTH","updateHeight","measuredHeight","explicitHeight","nextHeight","rawHeight","scheduleHeightUpdate","inject","resizeRafPending","resizeObserver","mutationRafPending","mutationObserver","onFullscreenChange","el","ro","entries","contentModeStyle","useMemo","minH","maxH","toggleFullscreen","target","jsx","SandboxApp","t1","t2","containerClassName","jsxs","ContentRender"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IframeSandbox.cjs.js","sources":["../../../src/components/ContentRender/IframeSandbox.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createRoot, Root } from \"react-dom/client\";\nimport SandboxApp from \"./SandboxApp\";\nimport ContentRender from \"./ContentRender\";\nimport {\n EMPTY_ROOT_HEIGHT_META,\n inspectViewportHeightFromHtmlRootString,\n inspectViewportHeightFromNodeChain,\n parseExplicitHeight,\n resolveExplicitHeightFromNodeChain,\n} from \"./utils/iframe-viewport-height\";\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 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 /** Min aspect ratio for content mode (width/height). Default 16/9. Controls minimum height = width / ratio. */\n minAspectRatio?: number;\n /** Max aspect ratio for content mode (width/height). Default: no limit (iframe grows to fit all content, no scrollbar). Set to e.g. 4/3 to cap height and allow scrollbar. */\n maxAspectRatio?: number;\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 styleLoadingText,\n scriptLoadingText,\n fullScreenButtonText,\n hideFullScreen = false,\n mode = \"content\",\n replaceRootScreenHeightWithFull = false,\n minAspectRatio = 16 / 9,\n maxAspectRatio,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const rootRef = useRef<Root | null>(null);\n const updateHeightRef = useRef<() => void>(() => {});\n const [height, setHeight] = useState(480);\n const lastSandboxInteractionTimeRef = useRef(0);\n const [contentHeight, setContentHeight] = useState(480);\n const [containerWidth, setContainerWidth] = useState(0);\n const [resetToken, setResetToken] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const shouldInjectSandboxVendor = type === \"sandbox\";\n\n const isBlackboardMode = mode === \"blackboard\";\n const shouldMeasureDynamicHeight = type === \"sandbox\";\n const shouldProcessRootScreenHeight =\n shouldMeasureDynamicHeight && replaceRootScreenHeightWithFull;\n const prevHtmlRef = useRef<string>(\"\");\n const htmlContent = React.useMemo(\n () => (type === \"sandbox\" ? content : \"\"),\n [content, type]\n );\n const normalizedHtmlContent = React.useMemo(\n () =>\n replaceRootScreenHeightWithFullClass(\n htmlContent,\n shouldProcessRootScreenHeight\n ),\n [htmlContent, shouldProcessRootScreenHeight]\n );\n const originalRootHeightMeta = React.useMemo(\n () =>\n shouldProcessRootScreenHeight\n ? inspectViewportHeightFromHtmlRootString(htmlContent)\n : EMPTY_ROOT_HEIGHT_META,\n [htmlContent, shouldProcessRootScreenHeight]\n );\n const shouldStretchRootHeight = React.useMemo(\n () =>\n shouldProcessRootScreenHeight &&\n originalRootHeightMeta.hasFullViewportHeight,\n [\n originalRootHeightMeta.hasFullViewportHeight,\n shouldProcessRootScreenHeight,\n ]\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 renderViewportHeightCssRef = useRef<string | 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 if (!shouldDeferRender) {\n clearDeferredRenderTimer();\n pendingHtmlRef.current = normalizedHtmlContent;\n setRenderHtmlContent(normalizedHtmlContent);\n return;\n }\n\n pendingHtmlRef.current = normalizedHtmlContent;\n clearDeferredRenderTimer();\n deferRenderTimerRef.current = window.setTimeout(() => {\n setRenderHtmlContent(pendingHtmlRef.current);\n deferRenderTimerRef.current = null;\n }, POST_IMAGE_STREAM_DEBOUNCE_MS);\n }, [normalizedHtmlContent]);\n\n // Viewport-relative height inspection is only meaningful in blackboard mode\n // where the sandbox should fill the viewport. In content mode, the sandbox\n // should use its intrinsic content height measured via shrink-to-0.\n const rootViewportHeightCss = React.useMemo(() => {\n if (!shouldMeasureDynamicHeight || !isBlackboardMode) {\n return null;\n }\n\n return inspectViewportHeightFromHtmlRootString(renderHtmlContent)\n .viewportHeightCss;\n }, [renderHtmlContent, shouldMeasureDynamicHeight, isBlackboardMode]);\n\n useEffect(() => {\n renderViewportHeightCssRef.current = rootViewportHeightCss;\n }, [rootViewportHeightCss]);\n\n const hasRootVhHeight = Boolean(rootViewportHeightCss);\n const sandboxViewportHeight =\n isBlackboardMode && type === \"sandbox\"\n ? shouldStretchRootHeight\n ? \"100%\"\n : (rootViewportHeightCss ?? `${height}px`)\n : undefined;\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 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 const getHeightInspectionNode = (node: HTMLElement) => ({\n heightAttrValue: node.getAttribute(\"height\"),\n styleAttrValue: node.getAttribute(\"style\"),\n classAttrValue: node.getAttribute(\"class\"),\n });\n const getSingleChildElement = (node: HTMLElement) => {\n const childElements = Array.from(node.children) as HTMLElement[];\n\n return childElements.length === 1 ? childElements[0] : null;\n };\n\n const resolveExplicitHeight = () => {\n if (!shouldMeasureDynamicHeight || !isBlackboardMode) return null;\n if (!iframeRef.current || !doc.body) return null;\n const parentViewportHeight =\n iframeRef.current.ownerDocument?.documentElement?.clientHeight ||\n window.innerHeight;\n // Reuse parsed height metadata from the current html snapshot first to\n // avoid re-inspecting the same DOM chain on every height tick.\n const precomputedViewportHeightCss = renderViewportHeightCssRef.current;\n const parsed = precomputedViewportHeightCss\n ? parseExplicitHeight(\n precomputedViewportHeightCss,\n parentViewportHeight\n )\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 container = wrapper?.firstElementChild as HTMLElement | null;\n if (!container) return null;\n const containerChildren = Array.from(container.children) as HTMLElement[];\n const rootContentElement =\n containerChildren.length === 1 ? containerChildren[0] : null;\n const runtimeHeightMeta = inspectViewportHeightFromNodeChain(\n rootContentElement,\n {\n getNode: getHeightInspectionNode,\n getSingleChild: getSingleChildElement,\n }\n );\n const runtimeViewportHeightCss = runtimeHeightMeta.viewportHeightCss;\n\n if (runtimeViewportHeightCss) {\n const runtimeViewportHeight = parseExplicitHeight(\n runtimeViewportHeightCss,\n parentViewportHeight\n );\n\n if (runtimeViewportHeight !== null) {\n return Math.ceil(runtimeViewportHeight);\n }\n }\n\n const explicitPixelHeight = resolveExplicitHeightFromNodeChain(\n rootContentElement,\n parentViewportHeight,\n {\n getNode: getHeightInspectionNode,\n getSingleChild: getSingleChildElement,\n }\n );\n\n return explicitPixelHeight !== null\n ? Math.ceil(explicitPixelHeight)\n : null;\n };\n\n const measureContentHeight = () => {\n if (!doc.body) return 0;\n const iframe = iframeRef.current;\n if (!iframe) return 0;\n\n // Temporarily shrink the iframe to 0px to break the circular dependency\n // with viewport-relative units (100vh, min-h-screen, 100dvh, etc.).\n // When iframe height is 0, 100vh resolves to 0 inside the iframe,\n // so we measure only the intrinsic content height.\n // Since shrink and restore happen within the same synchronous JS\n // execution (before the browser paints), there is no visual flicker.\n // Note: savedHeight may be \"\" on first call (height comes from CSS class\n // `h-full`), restoring \"\" correctly removes the inline override.\n const savedHeight = iframe.style.height;\n iframe.style.height = \"0px\";\n\n let containerScrollH = 0;\n let bodyScrollH = 0;\n try {\n const sandboxContainer = doc.body.querySelector(\n \".sandbox-container\"\n ) as HTMLElement | null;\n containerScrollH = sandboxContainer?.scrollHeight || 0;\n bodyScrollH = doc.body.scrollHeight;\n } finally {\n // Restore immediately — must run even if measurement throws\n iframe.style.height = savedHeight;\n }\n\n return Math.max(containerScrollH, bodyScrollH);\n };\n\n let prevRawHeight = 200;\n let consecutiveGrowthCount = 0;\n // The shrink-to-0 measurement technique already prevents the main\n // feedback loop caused by viewport-relative units. This guard is a\n // last-resort safety net for pathological cases (e.g. JS inside the\n // sandbox that keeps resizing on every frame). A high threshold\n // avoids freezing legitimate streaming content which may grow over\n // many consecutive frames.\n const MAX_CONSECUTIVE_GROWTH = 60;\n\n const updateHeight = () => {\n if (!shouldMeasureDynamicHeight) return;\n if (!iframeRef.current || !doc.body) return;\n const measuredHeight = measureContentHeight();\n const explicitHeight = resolveExplicitHeight();\n\n // When an explicit viewport height is declared (e.g. height=\"100vh\"),\n // the shrink-measure approach already handles it correctly.\n // Skip the growth guard to avoid freezing intentional height changes.\n if (explicitHeight !== null) {\n const nextHeight = Math.max(200, explicitHeight);\n consecutiveGrowthCount = 0;\n prevRawHeight = nextHeight;\n setHeight((prev) => (prev === nextHeight ? prev : nextHeight));\n setContentHeight(nextHeight);\n return;\n }\n\n // Add 1px buffer to avoid scrollbar caused by sub-pixel rounding\n const rawHeight = Math.max(200, Math.ceil(measuredHeight) + 1);\n\n // Safety guard: if measured height keeps growing consecutively beyond\n // a threshold, freeze at the last stable value to prevent any\n // residual feedback loop. Always track the raw measurement so that\n // legitimate future growth (e.g. user interaction) is not blocked.\n let nextHeight = rawHeight;\n if (rawHeight > prevRawHeight + 2) {\n consecutiveGrowthCount++;\n if (consecutiveGrowthCount > MAX_CONSECUTIVE_GROWTH) {\n nextHeight = prevRawHeight;\n }\n } else {\n consecutiveGrowthCount = 0;\n }\n prevRawHeight = rawHeight;\n\n setHeight((prev) => (prev === nextHeight ? prev : nextHeight));\n setContentHeight(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 // Inject Tailwind/DaisyUI/GSAP before rendering sandbox content to avoid FOUC.\n loadBlackboardVendor()\n .then((inject) => {\n if (isDestroyed) return;\n inject(doc);\n requestAnimationFrame(() => {\n if (isDestroyed) return;\n scheduleHeightUpdate();\n });\n })\n .catch(() => {\n if (isDestroyed) return;\n scheduleHeightUpdate();\n });\n }\n\n let resizeRafPending = false;\n const resizeObserver = new ResizeObserver(() => {\n if (resizeRafPending) return;\n resizeRafPending = true;\n requestAnimationFrame(() => {\n resizeRafPending = false;\n if (!isDestroyed) updateHeight();\n });\n });\n resizeObserver.observe(doc.body);\n if (rootEl) {\n resizeObserver.observe(rootEl);\n }\n\n // MutationObserver as backup: detect DOM changes that ResizeObserver might miss\n // (e.g. content injected by scripts, images loading, dynamic rendering).\n // Uses the same RAF deduplication pattern as ResizeObserver above.\n let mutationRafPending = false;\n const mutationObserver = new MutationObserver(() => {\n if (mutationRafPending) return;\n mutationRafPending = true;\n requestAnimationFrame(() => {\n mutationRafPending = false;\n if (!isDestroyed) updateHeight();\n });\n });\n mutationObserver.observe(doc.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"style\", \"class\"],\n });\n\n return () => {\n isDestroyed = true;\n resizeObserver.disconnect();\n mutationObserver.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 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 useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const ro = new ResizeObserver((entries) => {\n setContainerWidth(entries[0]?.contentRect.width ?? el.clientWidth);\n });\n ro.observe(el);\n setContainerWidth(el.clientWidth);\n return () => ro.disconnect();\n }, []);\n\n const contentModeStyle = useMemo<React.CSSProperties | undefined>(() => {\n if (isBlackboardMode || containerWidth === 0 || isFullscreen)\n return undefined;\n const minH = Math.round(containerWidth / minAspectRatio);\n // No maxAspectRatio → no upper limit, iframe grows to fit all content (no scrollbar).\n // With maxAspectRatio → cap height at width / ratio (scrollbar appears if content exceeds).\n const maxH = maxAspectRatio\n ? Math.round(containerWidth / maxAspectRatio)\n : Infinity;\n const clampedH = Math.max(minH, Math.min(maxH, contentHeight));\n return { height: clampedH };\n }, [\n isBlackboardMode,\n containerWidth,\n contentHeight,\n isFullscreen,\n minAspectRatio,\n maxAspectRatio,\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 styleLoadingText={styleLoadingText}\n scriptLoadingText={scriptLoadingText}\n resetToken={resetToken}\n hasRootVhHeight={hasRootVhHeight}\n mode={mode}\n stretchRootHeight={shouldStretchRootHeight}\n />\n );\n\n // SandboxApp renders content via DOM manipulation in its useEffect.\n // Schedule multiple measurements to catch async content (scripts, images, styles).\n initialPaintFrameRef.current = window.requestAnimationFrame(() => {\n updateHeightRef.current?.();\n initialPaintFrameRef.current = null;\n });\n const t1 = setTimeout(() => updateHeightRef.current?.(), 100);\n const t2 = setTimeout(() => updateHeightRef.current?.(), 500);\n return () => {\n clearTimeout(t1);\n clearTimeout(t2);\n };\n }, [\n renderHtmlContent,\n styleLoadingText,\n scriptLoadingText,\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 : contentModeStyle\n ? \"overflow-hidden flex items-center justify-center\"\n : \"aspect-[16/9] overflow-hidden flex items-center justify-center\",\n ]\n .filter(Boolean)\n .join(\" \");\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 : contentModeStyle\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 <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 )}\n </div>\n );\n};\n\nexport default IframeSandbox;\n"],"names":["blackboardVendorPromise","loadBlackboardVendor","m","COMPLETE_IMAGE_TAG_PATTERN","POST_IMAGE_STREAM_DEBOUNCE_MS","SANDBOX_INTERACTION_THROTTLE_MS","replaceRootScreenHeightToken","className","token","segments","replaceRootScreenHeightWithFullClass","html","enabled","match","tagStart","attrs","classMatch","nextClassName","IframeSandbox","content","type","styleLoadingText","scriptLoadingText","fullScreenButtonText","hideFullScreen","mode","replaceRootScreenHeightWithFull","minAspectRatio","maxAspectRatio","containerRef","useRef","iframeRef","rootRef","updateHeightRef","height","setHeight","useState","lastSandboxInteractionTimeRef","contentHeight","setContentHeight","containerWidth","setContainerWidth","resetToken","setResetToken","isFullscreen","setIsFullscreen","shouldInjectSandboxVendor","isBlackboardMode","shouldMeasureDynamicHeight","shouldProcessRootScreenHeight","prevHtmlRef","htmlContent","React","normalizedHtmlContent","originalRootHeightMeta","inspectViewportHeightFromHtmlRootString","EMPTY_ROOT_HEIGHT_META","shouldStretchRootHeight","renderHtmlContent","setRenderHtmlContent","prevIncomingHtmlRef","pendingHtmlRef","deferRenderTimerRef","initialPaintFrameRef","renderViewportHeightCssRef","emitSandboxInteraction","useCallback","eventType","now","SANDBOX_INTERACTION_MESSAGE_SOURCE","SANDBOX_INTERACTION_MESSAGE_TYPE","clearDeferredRenderTimer","clearInitialPaintFrames","useEffect","prevIncomingHtml","isAppendOnlyStream","containsCompleteImage","rootViewportHeightCss","hasRootVhHeight","sandboxViewportHeight","prev","iframe","doc","shouldBridgeSandboxInteraction","handleSandboxPointerDown","handleSandboxMouseDown","handleSandboxTouchStart","rootEl","root","createRoot","isDestroyed","getHeightInspectionNode","node","getSingleChildElement","childElements","resolveExplicitHeight","parentViewportHeight","precomputedViewportHeightCss","parsed","parseExplicitHeight","container","containerChildren","rootContentElement","runtimeViewportHeightCss","inspectViewportHeightFromNodeChain","runtimeViewportHeight","explicitPixelHeight","resolveExplicitHeightFromNodeChain","measureContentHeight","savedHeight","containerScrollH","bodyScrollH","prevRawHeight","consecutiveGrowthCount","MAX_CONSECUTIVE_GROWTH","updateHeight","measuredHeight","explicitHeight","nextHeight","rawHeight","scheduleHeightUpdate","inject","resizeRafPending","resizeObserver","mutationRafPending","mutationObserver","onFullscreenChange","el","ro","entries","contentModeStyle","useMemo","minH","maxH","toggleFullscreen","target","jsx","SandboxApp","t1","t2","containerClassName","jsxs","ContentRender"],"mappings":"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"}
|