@mirage-engine/core 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,85 +1,155 @@
1
- (function(u,T){typeof exports=="object"&&typeof module!="undefined"?T(exports,require("three")):typeof define=="function"&&define.amd?define(["exports","three"],T):(u=typeof globalThis!="undefined"?globalThis:u||self,T(u.MirageEngine={},u.THREE))})(this,function(u,T){"use strict";var re=Object.defineProperty;var ie=(u,T,w)=>T in u?re(u,T,{enumerable:!0,configurable:!0,writable:!0,value:w}):u[T]=w;var h=(u,T,w)=>(ie(u,typeof T!="symbol"?T+"":T,w),w);function w(s){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const r=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(e,t,r.get?r:{enumerable:!0,get:()=>s[t]})}}return e.default=s,Object.freeze(e)}const d=w(T),D=0,M=1,O=2,Y=4,B=8,L=16,C=1,E=2,H=0,P=["include-tree","exclude-tree","include-self","exclude-self","end"];function $(s,e,t){const r=e.split(`
2
- `),i=[];return r.forEach(a=>{const n=a.split(" ");let o=n[0];for(let l=1;l<n.length;l++){const c=n[l];s.measureText(o+" "+c).width<t?o+=" "+c:(i.push(o),o=c)}i.push(o)}),i}function k(s,e,t,r,i=2){const a=document.createElement("canvas"),n=a.getContext("2d");if(!n)throw new Error("[Mirage] Failed to create canvas context");const l=(window.devicePixelRatio||1)*i;a.width=t*l,a.height=r*l,n.scale(l,l),n.font=e.font,n.fillStyle=e.color,n.textBaseline="top",n.globalAlpha=1;const c=$(n,s,t),v=e.lineHeight;c.forEach((m,g)=>{const R=g*v+2;let y=0;e.textAlign==="center"?y=t/2:e.textAlign==="right"&&(y=t),n.textAlign=e.textAlign,n.fillText(m,y,R)});const p=new d.CanvasTexture(a);return p.colorSpace=d.SRGBColorSpace,p.minFilter=d.LinearFilter,p.magFilter=d.LinearFilter,p.needsUpdate=!0,p}function S(s){return typeof s=="number"?s:parseFloat(s)||0}function U(s,e){var o,l,c,v;if(!e){s.set(0,0,0,0);return}const t=e.split("/")[0].trim().split(/\s+/),r=S(t[0]),i=S((o=t[1])!=null?o:t[0]),a=S((l=t[2])!=null?l:t[0]),n=S((v=(c=t[3])!=null?c:t[1])!=null?v:t[0]);s.set(r,i,a,n)}const G=`
3
- varying vec2 vUv;
4
- varying vec4 vScreenPos;
5
- void main() {
6
- vUv = uv;
7
- gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
8
- vScreenPos = gl_Position;
9
- }
10
- `,J=`
11
-
12
- varying vec2 vUv;
1
+ (function(y,w){typeof exports=="object"&&typeof module!="undefined"?w(exports,require("three")):typeof define=="function"&&define.amd?define(["exports","three"],w):(y=typeof globalThis!="undefined"?globalThis:y||self,w(y.MirageEngine={},y.THREE))})(this,function(y,w){"use strict";var ct=Object.defineProperty,lt=Object.defineProperties;var ht=Object.getOwnPropertyDescriptors;var Be=Object.getOwnPropertySymbols;var ut=Object.prototype.hasOwnProperty,dt=Object.prototype.propertyIsEnumerable;var we=(y,w,M)=>w in y?ct(y,w,{enumerable:!0,configurable:!0,writable:!0,value:M}):y[w]=M,J=(y,w)=>{for(var M in w||(w={}))ut.call(w,M)&&we(y,M,w[M]);if(Be)for(var M of Be(w))dt.call(w,M)&&we(y,M,w[M]);return y},Se=(y,w)=>lt(y,ht(w));var d=(y,w,M)=>(we(y,typeof w!="symbol"?w+"":w,M),M);var Xe=(y,w,M)=>new Promise((v,ne)=>{var V=D=>{try{A(M.next(D))}catch(F){ne(F)}},oe=D=>{try{A(M.throw(D))}catch(F){ne(F)}},A=D=>D.done?v(D.value):Promise.resolve(D.value).then(V,oe);A((M=M.apply(y,w)).next())});function M(s){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const i=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(e,t,i.get?i:{enumerable:!0,get:()=>s[t]})}}return e.default=s,Object.freeze(e)}const v=M(w),ne={INCLUDE_TREE:"include-tree",EXCLUDE_TREE:"exclude-tree",INCLUDE_SELF:"include-self",EXCLUDE_SELF:"exclude-self",END:"end"},V={NAME:"data-mirage-dom",KEY:"mirageDom",VALUES:{HIDE:"hide"}},oe={TRAVELER:"traveler",NATIVE:"native",CAPTURE_1:"1",CAPTURE_2:"2",CAPTURE_3:"3",CAPTURE_4:"4",CAPTURE_5:"5"},A={NAME:"data-mirage-travel",KEY:"mirageTravel",VALUES:oe,MAX_LAYERS:Object.keys(oe).length-1},D={NAME:"data-mirage-filter",KEY:"mirageFilter",VALUES:ne},F={NAME:"data-mirage-select",KEY:"mirageSelect",VALUES:ne},Re={NAME:"data-mirage-shader",KEY:"mirageShader"},Ne={NAME:"data-mirage-sandwich",KEY:"mirageSandwich",VALUES:{FRONT:"front"}},ae=0,K=1,ee=2,Le=4,pe=8,me=16;function Ye(s){const e=s.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);return e?{r:parseInt(e[1])/255,g:parseInt(e[2])/255,b:parseInt(e[3])/255}:{r:1,g:1,b:1}}function Me(s){const e={};if(s.opacity&&(e.opacity=parseFloat(s.opacity)),s.backgroundColor&&s.backgroundColor!=="rgba(0, 0, 0, 0)"){const t=Ye(s.backgroundColor);e.backgroundColor=[t.r,t.g,t.b]}if(s.backgroundImage?e.backgroundImage=s.backgroundImage:s.background&&(e.backgroundImage=s.background),s.borderRadius&&(e.borderRadius=parseFloat(s.borderRadius)),s.width&&(e.width=parseFloat(s.width)),s.height&&(e.height=parseFloat(s.height)),s.transform&&s.transform!=="none"){const t=new DOMMatrix(s.transform);e.x=t.m41,e.y=t.m42,e.z=t.m43}return e}class De{constructor(e,t){d(this,"target");d(this,"observer");d(this,"pendingDeletions",new Set);d(this,"pendingStyles",new Map);d(this,"isDomDirty",!1);d(this,"isRunning",!1);d(this,"pendingMask",ae);d(this,"mutationTimer",null);d(this,"cssTimer",null);d(this,"resizeConfig");d(this,"resizeTimer",null);d(this,"isResizing",!1);d(this,"lastScrollX",0);d(this,"lastScrollY",0);d(this,"scrollTimer",null);d(this,"onBeforeRender",new Set);d(this,"onLayoutChange",new Set);d(this,"onStyleChange",new Set);d(this,"onScrollChange",new Set);d(this,"onRender",new Set);d(this,"onTransitionFinished",e=>{this.target.contains(e.target)&&this.mutationTimer===null&&(this.cssTimer&&clearTimeout(this.cssTimer),this.pendingStyles.size==0&&(this.pendingMask|=K|ee,this.cssTimer=window.setTimeout(()=>{this.isDomDirty=!0,this.cssTimer=null},50)))});d(this,"onWindowResize",()=>{if(!this.resizeConfig.enabled){this.isDomDirty=!0;return}this.isResizing||(this.isResizing=!0,this.resizeConfig.onStart&&this.resizeConfig.onStart()),this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=window.setTimeout(()=>{this.isDomDirty=!0,this.resizeConfig.onEnd&&this.resizeConfig.onEnd(),this.isResizing=!1,this.resizeTimer=null},this.resizeConfig.delay)});d(this,"renderLoop",()=>{if(!this.isRunning)return;this.onBeforeRender.forEach(i=>i()),this.isDomDirty&&(this.isDomDirty=!1,this.onLayoutChange.forEach(i=>i(this.pendingMask,this.pendingDeletions)),this.pendingDeletions.clear(),this.pendingMask=ae);const e=window.scrollX,t=window.scrollY;(e!==this.lastScrollX||t!==this.lastScrollY)&&(this.onScrollChange.forEach(i=>i(e,t)),this.lastScrollX=e,this.lastScrollY=t,this.scrollTimer&&clearTimeout(this.scrollTimer),this.scrollTimer=window.setTimeout(()=>{this.pendingMask|=K,this.isDomDirty=!0,this.scrollTimer=null},150)),this.pendingStyles.size>0&&(this.onStyleChange.forEach(i=>i(this.pendingStyles)),this.pendingStyles.clear()),this.onRender.forEach(i=>i()),requestAnimationFrame(this.renderLoop)});var r,c;this.target=e;const i=(r=t.resizeDebounce)!=null?r:!0;i===!1?this.resizeConfig={enabled:!1,delay:0}:i===!0?this.resizeConfig={enabled:!0,delay:150}:this.resizeConfig={enabled:!0,delay:(c=i.delay)!=null?c:150,onStart:i.onStart,onEnd:i.onEnd},this.observer=new MutationObserver(n=>{let o=ae;for(const a of n)if(a.type==="childList")o|=pe,a.removedNodes.length>0&&a.removedNodes.forEach(l=>{l instanceof HTMLElement&&this.pendingDeletions.add(l)});else if(a.type==="attributes")if(a.attributeName==="style"){o|=K|ee;const l=a.target,h=Me(l.style);this.pendingStyles.set(l,h)}else(a.attributeName==="class"||a.attributeName&&a.attributeName.startsWith("data-"))&&(o|=K|ee);else a.type==="characterData"&&(o|=me|K);if(o!==ae){if(this.pendingMask|=o,o&pe){this.clearTimers(),this.isDomDirty=!0;return}this.mutationTimer&&clearTimeout(this.mutationTimer),this.mutationTimer=window.setTimeout(()=>{this.mutationTimer=null,this.isDomDirty=!0},200)}})}start(){this.isRunning||(this.isRunning=!0,this.observer.observe(this.target,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),this.target.addEventListener("transitionend",this.onTransitionFinished),this.target.addEventListener("animationend",this.onTransitionFinished),window.addEventListener("resize",this.onWindowResize),this.isDomDirty=!0,this.lastScrollX=window.scrollX,this.lastScrollY=window.scrollY,this.renderLoop())}stop(){this.isRunning=!1,this.observer.disconnect(),this.clearTimers(),this.target.removeEventListener("transitionend",this.onTransitionFinished),this.target.removeEventListener("animationend",this.onTransitionFinished),window.removeEventListener("resize",this.onWindowResize)}clearTimers(){this.mutationTimer&&(clearTimeout(this.mutationTimer),this.mutationTimer=null),this.cssTimer&&(clearTimeout(this.cssTimer),this.cssTimer=null),this.scrollTimer&&(clearTimeout(this.scrollTimer),this.scrollTimer=null)}}const W=1,Z=2,ze=0,U={BASE:0,SELECTED:1,getCaptureLayer:s=>31-s,HIDDEN:31},ve=Object.values(D.VALUES);class Ae{static getBaseline(e){if(this.cache.has(e))return this.cache.get(e);const t=this.calculateBaselineFromDOM(e);return this.cache.set(e,t),t}static calculateBaselineFromDOM(e){if(typeof document=="undefined")return 0;const t=document.createElement("div"),i=document.createElement("span"),r=document.createElement("img");t.style.visibility="hidden",t.style.position="absolute",t.style.top="0px",t.style.left="0px",t.style.font=e,t.style.margin="0",t.style.padding="0",t.style.border="none",i.style.margin="0",i.style.padding="0",i.style.border="none",i.style.lineHeight="normal",r.width=1,r.height=1,r.style.verticalAlign="baseline",i.appendChild(document.createTextNode("Hidden Text")),t.appendChild(i),t.appendChild(r),document.body.appendChild(t);const c=r.offsetTop-i.offsetTop;return document.body.removeChild(t),c}}d(Ae,"cache",new Map);class Pe extends v.MeshBasicMaterial{constructor(t,i,r,c,n=2){super({transparent:!0,side:v.FrontSide,color:16777215});d(this,"canvas");d(this,"ctx");d(this,"qualityFactor");if(this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),!this.ctx)throw new Error("[Mirage] Failed to create canvas context");this.qualityFactor=n,this.map=new v.CanvasTexture(this.canvas),this.map.colorSpace=v.LinearSRGBColorSpace,this.map.minFilter=v.LinearFilter,this.map.magFilter=v.LinearFilter,this.updateText(t,i,r,c)}wrapText(t,i){const r=t.split(`
2
+ `),c=[];return r.forEach(n=>{const o=n.match(/[^\s\-]+\-?|\-|\s+/g)||[];if(o.length===0){c.push("");return}let a=o[0];for(let l=1;l<o.length;l++){const h=o[l];this.ctx.measureText(a+h).width<=i+2?a+=h:(a&&c.push(a),a=h.trimStart())}a&&c.push(a)}),c}updateText(t,i,r,c,n){n!==void 0&&(this.qualityFactor=n);const a=(window.devicePixelRatio||1)*this.qualityFactor,l=r*a,h=c*a;this.canvas.width!==l||this.canvas.height!==h?(this.canvas.width=l,this.canvas.height=h):this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.setTransform(a,0,0,a,0,0),this.ctx.font=i.font,this.ctx.fillStyle=i.color,this.ctx.textBaseline="alphabetic",this.ctx.globalAlpha=1;const f=this.wrapText(t,r),b=i.lineHeight,p=Ae.getBaseline(i.font);f.forEach((u,g)=>{const S=g*b+p;let k=0;i.textAlign==="center"?k=r/2:i.textAlign==="right"&&(k=r),this.ctx.textAlign=i.textAlign,this.ctx.fillText(u,k,S)}),this.map&&(this.map.needsUpdate=!0)}dispose(){this.map&&this.map.dispose(),super.dispose()}}function te(s){return typeof s=="number"?s:parseFloat(s)||0}function ce(s){if(!s||s==="transparent")return{color:new v.Color(16777215),alpha:0};const e=s.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);if(e){const t=parseInt(e[1],10),i=parseInt(e[2],10),r=parseInt(e[3],10),c=e[4]!==void 0?parseFloat(e[4]):1;return{color:new v.Color(`rgb(${t}, ${i}, ${r})`),alpha:c}}return{color:new v.Color(s),alpha:1}}function Ve(s){const e=[];let t="",i=0;for(let r=0;r<s.length;r++){const c=s[r];if(c==="(")i++;else if(c===")")i--;else if(c===","&&i===0){e.push(t.trim()),t="";continue}t+=c}return t&&e.push(t.trim()),e}function We(s){if(!s||typeof s!="string"||!s.includes("linear-gradient"))return null;const e=s.match(/linear-gradient\((.*)\)/);if(!e)return null;const t=e[1],i=Ve(t);let r=Math.PI,c=0;const n=i[0].trim();if(n.startsWith("to "))n==="to top"?r=0:n==="to right"?r=Math.PI/2:n==="to bottom"?r=Math.PI:n==="to left"?r=Math.PI*1.5:n==="to top right"||n==="to right top"?r=Math.PI/4:n==="to bottom right"||n==="to right bottom"?r=Math.PI*.75:n==="to bottom left"||n==="to left bottom"?r=Math.PI*1.25:(n==="to top left"||n==="to left top")&&(r=Math.PI*1.75),c=1;else if(n.endsWith("deg")||n.endsWith("rad")||n.endsWith("turn")){const a=parseFloat(n);n.endsWith("deg")?r=a*(Math.PI/180):n.endsWith("rad")?r=a:n.endsWith("turn")&&(r=a*Math.PI*2),c=1}const o=[];for(let a=c;a<i.length&&!(o.length>=8);a++){const l=i[a].trim(),h=l.lastIndexOf(" ");let f=l,b=null;if(h!==-1&&!l.endsWith(")")){const u=l.substring(h+1);(u.endsWith("%")||u.endsWith("px")||!isNaN(parseFloat(u)))&&(f=l.substring(0,h).trim(),b=u)}const p=ce(f);o.push({color:p.color,alpha:p.alpha,rawStop:b,stop:0})}if(o.length>0){for(let l=0;l<o.length;l++)o[l].rawStop!==null&&(o[l].stop=parseFloat(o[l].rawStop)/100);o[0].rawStop===null&&(o[0].stop=0),o.length>1&&o[o.length-1].rawStop===null&&(o[o.length-1].stop=1);let a=0;for(let l=1;l<o.length;l++)if(o[l].rawStop!==null||l===o.length-1){const h=l-a;if(h>1){const f=o[a].stop,p=(o[l].stop-f)/h;for(let u=1;u<h;u++)o[a+u].stop=f+p*u}a=l}}return{angle:r,stops:o}}const He=`varying vec2 vUv;
3
+ varying vec4 vScreenPos;
4
+ void main() {
5
+ vUv = uv;
6
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
7
+ vScreenPos = gl_Position;
8
+ }`,Ge=`varying vec2 vUv;
9
+ uniform vec2 uSize;
10
+ uniform vec4 uBorderRadius;
11
+ uniform float uBorderWidth;
12
+ uniform vec4 uBgColor;
13
+ uniform vec4 uBorderColor;
14
+ uniform float uOpacity;
15
+
16
+ uniform int uGradientCount;
17
+ uniform float uGradientAngle;
18
+ uniform vec4 uGradientColors[8];
19
+ uniform float uGradientStops[8];
20
+
21
+ #INJECT_DECLARATIONS
22
+
23
+ vec3 linearToSrgb(vec3 linearColor) {
24
+ vec3 linearPart = 12.92 * linearColor;
25
+ vec3 curvePart = 1.055 * pow(linearColor, vec3(1.0 / 2.4)) - 0.055;
26
+ vec3 switchCondition = step(vec3(0.0031308), linearColor);
27
+ return mix(linearPart, curvePart, switchCondition);
28
+ }
29
+
30
+ vec3 srgbToLinear(vec3 srgbColor) {
31
+ vec3 linearPart = srgbColor / 12.92;
32
+ vec3 curvePart = pow((srgbColor + vec3(0.055)) / 1.055, vec3(2.4));
33
+ vec3 switchCondition = step(vec3(0.04045), srgbColor);
34
+ return mix(linearPart, curvePart, switchCondition);
35
+ }
36
+
37
+ vec4 blendSrcOverInLinear(vec4 front, vec4 back) {
38
+ front.rgb = srgbToLinear(front.rgb);
39
+ back.rgb = srgbToLinear(back.rgb);
40
+ float aOut = front.a + back.a * (1.0 - front.a);
41
+ float safeAlpha = max(aOut, 0.0001);
42
+ vec3 cOut = (front.rgb * front.a + back.rgb * back.a * (1.0 - front.a)) / safeAlpha;
43
+ return vec4(linearToSrgb(cOut), aOut);
44
+ }
45
+
46
+ vec4 blendSrcOver(vec4 front, vec4 back) {
47
+ float aOut = front.a + back.a * (1.0 - front.a);
48
+ float safeAlpha = max(aOut, 0.0001);
49
+ vec3 cOut = (front.rgb * front.a + back.rgb * back.a * (1.0 - front.a)) / safeAlpha;
50
+ return vec4(cOut, aOut);
51
+ }
52
+
53
+ float sdRoundedBox(vec2 p, vec2 b, float r) {
54
+ vec2 q = abs(p) - b + r;
55
+ return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
56
+ }
57
+
58
+ float sdVisualBox(vec2 p, vec2 b, float r) {
59
+ vec2 q = abs(p) - b + r;
60
+ float n = 2.01;
61
+ float d = pow(pow(max(q.x, 0.0), n) + pow(max(q.y, 0.0), n), 1.0/n) - r;
62
+ return min(max(q.x, q.y), 0.0) + d;
63
+ }
64
+
65
+ vec4 calculateGradientLayer(vec2 uv) {
66
+ if (uGradientCount < 2) return uGradientColors[0];
67
+
68
+ vec2 dir = vec2(sin(uGradientAngle), cos(uGradientAngle));
69
+ vec2 p = (uv - 0.5) * uSize;
70
+ float proj = dot(p, dir);
71
+ float L = abs(uSize.x * dir.x) + abs(uSize.y * dir.y);
72
+ float t = clamp((proj / L) + 0.5, 0.0, 1.0);
13
73
 
14
- uniform vec2 uSize;
15
- uniform vec4 uBorderRadius;
16
- uniform float uBorderWidth;
17
- uniform vec3 uBgColor;
18
- uniform vec3 uBorderColor;
19
- uniform float uOpacity;
20
- uniform float uBgOpacity;
21
- uniform float uBorderOpacity;
22
-
23
- #INJECT_DECLARATIONS
24
-
25
- float sdRoundedBox(vec2 p, vec2 b, float r) {
26
- vec2 q = abs(p) - b + r;
27
-
28
- return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
29
- }
30
-
31
- void main() {
32
- vec2 p = (vUv - 0.5) * uSize;
33
- vec2 halfSize = uSize * 0.5;
34
-
35
- #INJECT_UV_MODIFIER
74
+ vec4 color = uGradientColors[0];
75
+ for (int i = 1; i < 8; i++) {
76
+ if (i >= uGradientCount) break;
77
+ float prevStop = uGradientStops[i-1];
78
+ float currStop = uGradientStops[i];
36
79
 
37
- // color decision pipeline
38
- vec4 baseColor = vec4(uBgColor, uBgOpacity);
80
+ float factor = clamp((t - prevStop) / (currStop - prevStop + 0.00001), 0.0, 1.0);
81
+ color = mix(color, uGradientColors[i], factor);
82
+ }
83
+ // return vec4(linearToSrgb(color.rgb), color.a);
84
+ return vec4(color);
85
+ }
39
86
 
40
- #INJECT_BASE_COLOR
87
+ void main() {
88
+ vec2 p = (vUv - 0.5) * uSize;
89
+ vec2 halfSize = uSize * 0.5;
41
90
 
42
- // sdf shape pipeline
43
- vec2 xRadii = mix(uBorderRadius.xw, uBorderRadius.yz, step(0.0, p.x));
44
- float r = mix(xRadii.y, xRadii.x, step(0.0, p.y));
45
- float d = sdRoundedBox(p, halfSize, r);
91
+ #INJECT_UV_MODIFIER
46
92
 
47
- float aa = 1.0;
48
- float bgMask = 1.0 - smoothstep(0.0, aa, d);
93
+ // color decision pipeline
94
+ vec4 baseColor = vec4(uBgColor.rgb, uBgColor.a);
49
95
 
50
- float halfBorder = uBorderWidth * 0.5;
51
- float borderD = abs(d + halfBorder) - halfBorder;
52
- float borderAlpha = (1.0 - smoothstep(0.0, aa, borderD)) * uBorderOpacity;
53
- if (uBorderWidth <= 0.01) {
54
- borderAlpha = 0.0;
55
- }
96
+ if (uGradientCount > 0) {
97
+ vec4 gradColor = calculateGradientLayer(vUv);
98
+ baseColor = blendSrcOver(gradColor, baseColor);
99
+ }
56
100
 
57
- // final blending (border + background)
58
- float aFront = borderAlpha;
59
- float aBack = baseColor.a;
60
- float aOut = aFront + aBack * (1.0 - aFront);
101
+ #INJECT_BASE_COLOR
61
102
 
62
- float safeAlpha = max(aOut, 0.0001);
63
- vec3 cOut = (uBorderColor * aFront + baseColor.rgb * aBack * (1.0 - aFront)) / safeAlpha;
64
- vec4 finalColor = vec4(cOut, aOut);
103
+ // Hybrid SDF
104
+ vec2 xRadii = mix(uBorderRadius.xw, uBorderRadius.yz, step(0.0, p.x));
105
+ float r = mix(xRadii.y, xRadii.x, step(0.0, p.y));
106
+ r = min(r, min(halfSize.x, halfSize.y));
65
107
 
66
- // final color control (Tint, Noise)
67
- #INJECT_COLOR_MODIFIER
108
+ float d = sdRoundedBox(p, halfSize, r);
68
109
 
69
- float finalOpacity = finalColor.a * bgMask * uOpacity;
70
- if (finalOpacity < 0.001) discard;
110
+ float d_smooth = sdVisualBox(p, halfSize, r);
111
+ float d_visual = d_smooth / fwidth(d_smooth);
71
112
 
72
- gl_FragColor = vec4(finalColor.rgb, finalOpacity);
113
+ // rendering pipeline
114
+ float bgMask = 1.0 - smoothstep(-0.5, 0.5, d_visual);
73
115
 
74
- #include <colorspace_fragment>
116
+ float halfBorder = uBorderWidth * 0.5;
117
+ float borderD = abs(d + halfBorder) - halfBorder;
118
+ float borderAlpha = (1.0 - smoothstep(0.0, 1.0, borderD)) * uBorderColor.a;
119
+ if (uBorderWidth <= 0.01) {
120
+ borderAlpha = 0.0;
75
121
  }
76
- `;function F(s){if(!s||s==="transparent")return{color:new d.Color(16777215),alpha:0};const e=s.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);if(e){const t=parseInt(e[1],10),r=parseInt(e[2],10),i=parseInt(e[3],10),a=e[4]!==void 0?parseFloat(e[4]):1;return{color:new d.Color(`rgb(${t}, ${r}, ${i})`),alpha:a}}return{color:new d.Color(s),alpha:1}}function j(s,e,t,r=null,i){var y;const a=r!==null,n=a?`
77
- uniform sampler2D uTexture;
78
- varying vec4 vScreenPos;
79
- `:"",o=a?`
80
- vec2 screenUv = (vScreenPos.xy / vScreenPos.w) * 0.5 + 0.5;
81
- vec2 resultUv = screenUv;
82
- ${(i==null?void 0:i.uvModifier)||""}
83
- `:"",l=a?`
84
- baseColor = texture2D(uTexture, resultUv);
85
- `:"",c=(i==null?void 0:i.colorModifier)||"",v=J.replace("#INJECT_DECLARATIONS",n).replace("#INJECT_UV_MODIFIER",o).replace("#INJECT_BASE_COLOR",l).replace("#INJECT_COLOR_MODIFIER",c),p=F(s.backgroundColor),m=F(s.borderColor),g={uSize:{value:new d.Vector2(e,t)},uBorderRadius:{value:new d.Vector4(0,0,0,0)},uBorderWidth:{value:S(s.borderWidth)},uBgColor:{value:p.color},uBorderColor:{value:m.color},uOpacity:{value:(y=s.opacity)!=null?y:1},uBgOpacity:{value:p.alpha},uBorderOpacity:{value:m.alpha},uTexture:{value:null}};return U(g.uBorderRadius.value,s.borderRadius),a&&(g.uTexture.value=r),new d.ShaderMaterial({uniforms:g,vertexShader:G,fragmentShader:v,transparent:!0,side:d.FrontSide})}function V(s,e,t,r,i){var o;const a=F(e.backgroundColor),n=F(e.borderColor);s.uniforms.uSize.value.set(t,r),U(s.uniforms.uBorderRadius.value,e.borderRadius),s.uniforms.uBorderWidth.value=S(e.borderWidth),s.uniforms.uBgColor.value.copy(a.color),s.uniforms.uBorderColor.value.copy(n.color),s.uniforms.uOpacity.value=(o=e.opacity)!=null?o:1,s.uniforms.uBgOpacity.value=a.alpha,s.uniforms.uBorderOpacity.value=n.alpha,s.uniforms.uTexture&&i!==void 0&&(s.uniforms.uTexture.value=i)}const I={create(s,e,t,r,i,a=2,n=null,o){if(s==="BOX")return j(e,r,i,n,o);if(s==="TEXT"){const l=k(t||"",e,r,i,a);return new d.MeshBasicMaterial({map:l,transparent:!0,side:d.FrontSide,color:16777215})}return new d.MeshBasicMaterial({visible:!1})},update(s,e,t,r,i,a,n=2,o){if(e==="BOX")V(s,t,i,a,o);else if(e==="TEXT"){const l=s;l.map&&l.map.dispose();const c=k(r||"",t,i,a,n);l.map=c,l.needsUpdate=!0}}};class Z{constructor(e,t,r){h(this,"canvas");h(this,"scene");h(this,"camera");h(this,"renderer");h(this,"renderTarget",null);h(this,"renderOrder",0);h(this,"qualityFactor",2);h(this,"mode","overlay");h(this,"clipArea",1);h(this,"target");h(this,"mountContainer");h(this,"targetRect");h(this,"meshMap",new Map);var n,o,l;this.target=e,this.mountContainer=r,this.mode=(n=t.mode)!=null?n:"overlay",this.clipArea=(o=t.travelerClipArea)!=null?o:1,this.canvas=document.createElement("canvas"),this.scene=new d.Scene,this.targetRect=this.target.getBoundingClientRect();const i=this.targetRect.width,a=this.targetRect.height;this.camera=new d.OrthographicCamera(i/-2,i/2,a/2,a/-2,1,1e3),this.camera.position.z=100,this.camera.layers.set(0),this.renderer=new d.WebGLRenderer({canvas:this.canvas,alpha:!0,antialias:!0}),this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setSize(i,a),this.applyTextQuality((l=t.quality)!=null?l:"medium")}createRenderTarget(){this.renderTarget=new d.WebGLRenderTarget(this.targetRect.width*this.qualityFactor,this.targetRect.height*this.qualityFactor,{minFilter:d.LinearFilter,magFilter:d.LinearFilter,format:d.RGBAFormat,stencilBuffer:!1,depthBuffer:!0,samples:4})}applyTextQuality(e){if(typeof e=="number"){this.qualityFactor=Math.max(.1,e);return}switch(e){case"low":this.qualityFactor=1;break;case"high":this.qualityFactor=4;break;case"medium":default:this.qualityFactor=2;break}}mount(){this.mountContainer.prepend(this.canvas),this.canvas.style.pointerEvents=this.mode==="overlay"?"none":"auto",this.updateCanvasLayout()}updateCanvasLayout(){this.canvas.style.width=`${this.targetRect.width}px`,this.canvas.style.height=`${this.targetRect.height}px`,this.mode==="duplicate"?(this.canvas.style.position="",this.canvas.style.top="",this.canvas.style.left="",this.canvas.style.display="block"):(this.canvas.style.position="absolute",this.canvas.style.top=`${this.target.offsetTop}px`,this.canvas.style.left=`${this.target.offsetLeft}px`,this.canvas.style.display="block")}dispose(){this.renderer.dispose(),this.canvas.remove()}setSize(e,t){this.renderer.setSize(e,t),this.renderTarget&&this.renderTarget.setSize(e*this.qualityFactor,t*this.qualityFactor),this.camera.left=e/-2,this.camera.right=e/2,this.camera.top=t/2,this.camera.bottom=t/-2,this.camera.updateProjectionMatrix()}syncScene(e){const t=this.target.getBoundingClientRect(),r=Math.abs(t.width-this.targetRect.width)>.1||Math.abs(t.height-this.targetRect.height)>.1,i=this.mode==="overlay"&&(Math.abs(t.top-this.targetRect.top)>.1||Math.abs(t.left-this.targetRect.left)>.1);r?(this.targetRect=t,this.setSize(this.targetRect.width,this.targetRect.height),this.updateCanvasLayout()):i?(this.targetRect=t,this.updateCanvasLayout()):this.targetRect=t,this.renderOrder=0;const a=new Set;this.reconcileNode(e,a);for(const[n,o]of this.meshMap.entries())a.has(n)||(this.scene.remove(o),o.geometry.dispose(),o.material instanceof d.Material&&o.material.dispose(),this.meshMap.delete(n))}reconcileNode(e,t){var i;t.add(e.element);let r=this.meshMap.get(e.element);if(!r){const a=new d.PlaneGeometry(1,1);let n;n=I.create("BOX",e.styles,"",e.rect.width,e.rect.height,this.qualityFactor,e.isTraveler?(i=this.renderTarget)==null?void 0:i.texture:void 0,e.shaderHooks),r=new d.Mesh(a,n),e.type==="TEXT"&&(r.name="BG_MESH"),this.scene.add(r),this.meshMap.set(e.element,r)}if(r.userData.domRect=e.rect,this.updateMeshProperties(r,e),this.updateMeshLayers(r,e),e.isTraveler&&r.layers.enable(28),e.type==="BOX")for(const a of e.children)this.reconcileNode(a,t);else e.type==="TEXT"&&this.reconcileTextChild(r,e)}reconcileTextChild(e,t){var o,l;let r=e.children.find(c=>c.name==="TEXT_CHILD");const i=JSON.stringify(t.textStyles),a=(o=r==null?void 0:r.userData)==null?void 0:o.styleHash;if(!r||t.dirtyMask&L||i!==a){r&&((l=r.material.map)==null||l.dispose(),r.geometry.dispose(),e.remove(r));const c=I.create("TEXT",t.textStyles,t.textContent||"",t.rect.width,t.rect.height,this.qualityFactor),v=new d.PlaneGeometry(1,1);r=new d.Mesh(v,c),r.name="TEXT_CHILD",r.userData={styleHash:i},this.updateMeshLayers(r,t),r.position.z=.005,e.add(r)}if(r){const c=e.userData.domRect,v=c.x+c.width/2,p=c.y+c.height/2,m=t.rect.x+t.rect.width/2,g=t.rect.y+t.rect.height/2,R=m-v,y=-(g-p);r.position.set(R,y,.005)}}updateMeshProperties(e,t){var g;const{rect:r,styles:i}=t,a=this.renderer.getPixelRatio(),n=this.renderer.domElement.width/a,o=this.renderer.domElement.height/a;e.scale.set(r.width,r.height,1);const l=.001;this.renderOrder++;const c=this.targetRect.left+window.scrollX,v=this.targetRect.top+window.scrollY,p=r.x-c,m=r.y-v;e.position.set(p-n/2+r.width/2,-m+o/2-r.height/2,i.zIndex+this.renderOrder*l),I.update(e.material,"BOX",t.styles,"",t.rect.width,t.rect.height,this.qualityFactor,t.isTraveler?(g=this.renderTarget)==null?void 0:g.texture:void 0)}updateMeshLayers(e,t){const r=(1-(t.visibility&C))*30;e.layers.set(r),t.visibility===(C|E)&&e.layers.enable(29)}captureRenderTarget(){const e=[];for(const l of this.meshMap.values())l.layers.mask&1<<28&&e.push(l);if(e.length===0)return;const t=new d.Color,r=this.renderer.getClearAlpha();this.renderer.getClearColor(t),this.renderer.setClearColor(0,0),this.renderer.setRenderTarget(this.renderTarget),this.renderer.clear(),this.renderer.autoClear=!1,this.renderer.setScissorTest(!0),this.camera.layers.set(29);const i=new d.Vector3,a=this.targetRect.width,n=this.targetRect.height,o=this.renderer.getPixelRatio();for(const l of e){i.setFromMatrixPosition(l.matrixWorld),i.project(this.camera);const c=(i.x+1)/2*a,v=(i.y+1)/2*n;let p=0,m=1;typeof this.clipArea=="number"?m=this.clipArea:this.clipArea.endsWith("%")?m=parseFloat(this.clipArea)/100:this.clipArea.endsWith("px")&&(p=parseFloat(this.clipArea));const g=l.scale.x*m+.5,R=l.scale.y*m+.5,y=c-g/2,_=v-R/2,N=(y*this.qualityFactor-p)/o,A=(_*this.qualityFactor-p)/o,z=(g*this.qualityFactor+p*2)/o,f=(R*this.qualityFactor+p*2)/o;this.renderer.setScissor(N,A,z,f),this.renderer.render(this.scene,this.camera)}this.renderer.setScissorTest(!1),this.renderer.autoClear=!0,this.renderer.setRenderTarget(null),this.camera.layers.set(28),this.renderer.setClearColor(t,r)}render(){this.renderTarget&&this.captureRenderTarget(),this.renderer.render(this.scene,this.camera)}showScissoredRenderTarget(){if(!this.renderTarget)return;const e=this.targetRect.width,t=this.targetRect.height,r=new d.PlaneGeometry(e,t),i=new d.MeshBasicMaterial({map:this.renderTarget.texture,side:d.DoubleSide,transparent:!0,opacity:.8}),a=new d.Mesh(r,i);a.position.set(0,0,90),a.layers.set(28),this.scene.add(a)}}function Q(s){const e=document.createRange();e.selectNodeContents(s);const t=e.getBoundingClientRect();return{left:t.left,top:t.top,width:t.width,height:t.height}}function K(s){const e=parseFloat(s.fontSize);let t=parseFloat(s.lineHeight);isNaN(t)&&(t=e*1.2);let r=parseFloat(s.letterSpacing);return isNaN(r)&&(r=0),{font:`${s.fontStyle} ${s.fontWeight} ${s.fontSize} ${s.fontFamily}`,color:s.color,textAlign:s.textAlign||"start",textBaseline:"alphabetic",direction:s.direction||"inherit",lineHeight:t,letterSpacing:r}}function q(s,e=M|O|Y|L|B,t,r){if(s.nodeType===Node.TEXT_NODE){const f=s;if(!f.textContent||!f.textContent.trim())return null;const x=f.textContent.replace(/\s+/g," ").trim();if(x.length===0)return null;const b=Q(f);if(b.width===0||b.height===0)return null;const W=f.parentElement,X=W?window.getComputedStyle(W):null;return X?{id:Math.random().toString(36).substring(2,9),type:"TEXT",element:f,rect:{x:b.left+window.scrollX,y:b.top+window.scrollY,width:b.width,height:b.height},styles:{backgroundColor:"transparent",opacity:parseFloat(X.opacity),zIndex:0,borderRadius:"0px",borderColor:"transparent",borderWidth:"0px"},textContent:x,textStyles:K(X),dirtyMask:e,visibility:t,isTraveler:!1,children:[]}:null}const i=s,a=i.dataset.mirageFilter;let n=t,o=t;if(a){const f=new Set(a.split(/\s+/));for(const x of f)if(!P.includes(x))throw new Error(`[MirageEngine] Invalid filter token: '${x}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`);if(f.has("end"))return null;if(f.has("include-tree")&&f.has("exclude-tree"))throw new Error("[MirageEngine] Conflicting filters: 'include-tree' and 'exclude-tree' cannot be used together on the same element.");if(f.has("include-self")&&f.has("exclude-self"))throw new Error("[MirageEngine] Conflicting filters: 'include-self' and 'exclude-self' cannot be used together on the same element.");f.has("include-tree")?n=n|C:f.has("exclude-tree")&&(n=n&~C),o=n,f.has("include-self")?o=o|C:f.has("exclude-self")&&(o=o&~C)}o=o|t&E;const l=i.dataset.mirageTravel;let c=!1;l&&new Set(l.split(/\s+/)).has("traveler")&&(o=o&~E,n=n&~E,c=!0);const v=i.dataset.mirageShader;let p;v&&(p=JSON.parse(v));const m=i.getBoundingClientRect(),g=window.getComputedStyle(i);if(m.width===0||m.height===0||g.display==="none")return null;let R=i.getAttribute("data-mid");R||(R=Math.random().toString(36).substring(2,11),i.setAttribute("data-mid",R));const y=parseInt(g.zIndex),_={backgroundColor:g.backgroundColor,opacity:parseFloat(g.opacity),zIndex:isNaN(y)?0:y,borderRadius:g.borderRadius,borderColor:g.borderColor,borderWidth:g.borderWidth};let N,A;const z=[];return Array.from(i.childNodes).forEach(f=>{const x=f.nodeType===Node.TEXT_NODE?o:n,b=q(f,e,x);b&&z.push(b)}),{id:R,type:"BOX",element:i,rect:{x:m.left+window.scrollX,y:m.top+window.scrollY,width:m.width,height:m.height},styles:_,textContent:N,textStyles:A,dirtyMask:e,visibility:o,isTraveler:c,children:z,shaderHooks:p}}class ee{constructor(e,t,r){h(this,"target");h(this,"renderer");h(this,"filter");h(this,"observer");h(this,"isDomDirty",!1);h(this,"isRunning",!1);h(this,"isTravelEnabled",!1);h(this,"pendingMask",D);h(this,"mutationTimer",null);h(this,"cssTimer",null);h(this,"resizeConfig");h(this,"resizeTimer",null);h(this,"isResizing",!1);h(this,"onTransitionFinished",e=>{this.target.contains(e.target)&&this.mutationTimer===null&&(this.cssTimer&&clearTimeout(this.cssTimer),this.pendingMask|=M|O,this.cssTimer=window.setTimeout(()=>{this.isDomDirty=!0,this.cssTimer=null},50))});h(this,"onWindowResize",()=>{if(!this.resizeConfig.enabled){this.isDomDirty=!0;return}this.isResizing||(this.isResizing=!0,this.resizeConfig.onStart&&this.resizeConfig.onStart()),this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=window.setTimeout(()=>{this.isDomDirty=!0,this.resizeConfig.onEnd&&this.resizeConfig.onEnd(),this.isResizing=!1,this.resizeTimer=null},this.resizeConfig.delay)});h(this,"renderLoop",()=>{this.isRunning&&(this.isDomDirty&&this.forceUpdateScene(),this.renderer.render(),requestAnimationFrame(this.renderLoop))});var a,n;this.target=e,this.renderer=t,this.filter=r.filter;const i=(a=r.resizeDebounce)!=null?a:!0;i===!1?this.resizeConfig={enabled:!1,delay:0}:i===!0?this.resizeConfig={enabled:!0,delay:150}:this.resizeConfig={enabled:!0,delay:(n=i.delay)!=null?n:150,onStart:i.onStart,onEnd:i.onEnd},this.observer=new MutationObserver(o=>{let l=D;for(const c of o)c.type==="childList"?l|=B:c.type==="attributes"&&(c.attributeName==="style"||c.attributeName==="class")&&(l|=M|O);if(l!==D){if(this.pendingMask|=l,l&B){this.clearTimers(),console.log("Structural Change detected"),this.isDomDirty=!0;return}this.mutationTimer&&clearTimeout(this.mutationTimer),this.mutationTimer=window.setTimeout(()=>{this.mutationTimer=null,this.isDomDirty=!0},200)}})}start(){this.isRunning||(this.isRunning=!0,this.observer.observe(this.target,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),this.target.addEventListener("transitionend",this.onTransitionFinished),this.target.addEventListener("animationend",this.onTransitionFinished),window.addEventListener("resize",this.onWindowResize),this.forceUpdateScene(),this.renderLoop())}stop(){this.isRunning=!1,this.observer.disconnect(),this.clearTimers(),this.target.removeEventListener("transitionend",this.onTransitionFinished),this.target.removeEventListener("animationend",this.onTransitionFinished),window.removeEventListener("resize",this.onWindowResize)}clearTimers(){this.mutationTimer&&(clearTimeout(this.mutationTimer),this.mutationTimer=null),this.cssTimer&&(clearTimeout(this.cssTimer),this.cssTimer=null)}forceUpdateScene(){this.isDomDirty=!1;const e=document.querySelector("[data-mirage-travel='traveler']")!==null;e&&!this.isTravelEnabled&&(this.isTravelEnabled=!0,this.renderer.createRenderTarget());const t=q(this.target,this.pendingMask,e?C|E:C,this.filter);t&&this.renderer.syncScene(t),this.pendingMask=D}}class te{constructor(e,t){h(this,"renderer");h(this,"syncer");h(this,"target");var i,a,n;this.target=e;let r;if(t.mode==="duplicate"?r=(a=(i=t.container)!=null?i:this.target.parentElement)!=null?a:void 0:r=(n=this.target.parentElement)!=null?n:void 0,!r)throw new Error("[Mirage] Cannot find a container (parent or option).");this.renderer=new Z(this.target,t,r),this.renderer.mount(),this.syncer=new ee(this.target,this.renderer,t)}start(){this.syncer.start()}stop(){this.syncer.stop()}dispose(){this.syncer.stop(),this.renderer.dispose()}}u.ALLOWED_FILTERS=P,u.DIRTY_CONTENT=L,u.DIRTY_NONE=D,u.DIRTY_RECT=M,u.DIRTY_STRUCTURE=B,u.DIRTY_STYLE=O,u.DIRTY_ZINDEX=Y,u.EXCLUDED=H,u.Engine=te,u.SYSTEM_LAYER=E,u.USER_LAYER=C,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
122
+
123
+ // final blending (border + background) using blendSrcOver
124
+ vec4 borderLayer = vec4(uBorderColor.rgb, borderAlpha);
125
+ vec4 finalColor = blendSrcOver(borderLayer, baseColor);
126
+ // final color control (Tint, Noise)
127
+ #INJECT_COLOR_MODIFIER
128
+
129
+ float finalOpacity = finalColor.a * bgMask * uOpacity;
130
+ if (finalOpacity < 0.001) discard;
131
+
132
+ gl_FragColor = vec4(finalColor.rgb, finalOpacity);
133
+
134
+
135
+ // #include <colorspace_fragment>
136
+ }
137
+ `,qe=`uniform sampler2D uTexture;
138
+ varying vec4 vScreenPos;
139
+ uniform vec2 uTextureRepeat;
140
+ uniform vec2 uTextureOffset;`,$e=`vec2 screenUv = (vScreenPos.xy / vScreenPos.w) * 0.5 + 0.5;
141
+ vec2 resultUv = screenUv;
142
+
143
+ `,je=`vec4 texColor = texture2D(uTexture, resultUv);
144
+ baseColor = blendSrcOver(baseColor, texColor);`,Ie={vertexShader:He,fragmentShader:Ge},ye={declChunk:qe,uvChunk:$e,baseColorChunk:je};function Ke(s,e,t,i=null,r){var I;const c=i!==null||!!s.imageSrc;let n="";const o={};if(r!=null&&r.uniforms)for(const[C,T]of Object.entries(r.uniforms))typeof T=="number"?(n+=`uniform float ${C};
145
+ `,o[C]={value:T}):Array.isArray(T)?T.length===2?(n+=`uniform vec2 ${C};
146
+ `,o[C]={value:new v.Vector2(...T)}):T.length===3?(n+=`uniform vec3 ${C};
147
+ `,o[C]={value:new v.Vector3(...T)}):T.length===4&&(n+=`uniform vec4 ${C};
148
+ `,o[C]={value:new v.Vector4(...T)}):(n+=`uniform float ${C};
149
+ `,o[C]={value:T});const a=(c?ye.declChunk:"")+`
150
+ `+n,l=s.isTraveler?ye.uvChunk:`vec2 resultUv = vUv * uTextureRepeat + uTextureOffset;
151
+ `,h=c?l+((r==null?void 0:r.uvModifier)||""):"",f=c?ye.baseColorChunk:"",b=(r==null?void 0:r.colorModifier)||"",p=Ie.fragmentShader.replace("#INJECT_DECLARATIONS",a).replace("#INJECT_UV_MODIFIER",h).replace("#INJECT_BASE_COLOR",f).replace("#INJECT_COLOR_MODIFIER",b),u=ce(s.backgroundColor),g=ce(s.borderColor),S={uSize:{value:new v.Vector2(e,t)},uBgColor:{value:new v.Vector4(u.color.r,u.color.g,u.color.b,u.alpha)},uBorderColor:{value:new v.Vector4(g.color.r,g.color.g,g.color.b,g.alpha)},uBorderRadius:{value:new v.Vector4(0,0,0,0)},uBorderWidth:{value:te(s.borderWidth)},uOpacity:{value:(I=s.opacity)!=null?I:1},uTexture:{value:null},uTextureRepeat:{value:new v.Vector2(1,1)},uTextureOffset:{value:new v.Vector2(0,0)},uGradientCount:{value:0},uGradientAngle:{value:0},uGradientColors:{value:Array.from({length:8},()=>new v.Vector4(0,0,0,0))},uGradientStops:{value:new Float32Array(8)}};ke(S.uBorderRadius.value,s.borderRadius),c&&(S.uTexture.value=i);const k=new v.ShaderMaterial({uniforms:J(J({},S),o),vertexShader:Ie.vertexShader,fragmentShader:p,transparent:!0,side:v.FrontSide});return s.backgroundImage&&Ee(k,{backgroundImage:s.backgroundImage}),k}function Je(s,e,t,i,r){const c=te(e.borderWidth);Ee(s,{width:t,height:i,borderRadius:e.borderRadius,borderWidth:c,backgroundColor:e.backgroundColor,borderColor:e.borderColor,opacity:e.opacity,texture:r,backgroundImage:e.backgroundImage})}function Ee(s,e){var i,r,c;if(e.width!==void 0&&e.height!==void 0&&s.uniforms.uSize.value.set(e.width,e.height),e.borderRadius!==void 0&&ke(s.uniforms.uBorderRadius.value,e.borderRadius),e.borderWidth!==void 0&&(s.uniforms.uBorderWidth.value=e.borderWidth),e.backgroundColor!==void 0)if(Array.isArray(e.backgroundColor)){const n=s.uniforms.uBgColor.value.w;s.uniforms.uBgColor.value.set(e.backgroundColor[0],e.backgroundColor[1],e.backgroundColor[2],n)}else if(typeof e.backgroundColor=="string"){const n=ce(e.backgroundColor);s.uniforms.uBgColor.value.set(n.color.r,n.color.g,n.color.b,n.alpha)}else{const n=s.uniforms.uBgColor.value.w;s.uniforms.uBgColor.value.set(e.backgroundColor.r,e.backgroundColor.g,e.backgroundColor.b,n)}if(e.borderColor!==void 0)if(Array.isArray(e.borderColor)){const n=s.uniforms.uBorderColor.value.w;s.uniforms.uBorderColor.value.set(e.borderColor[0],e.borderColor[1],e.borderColor[2],n)}else if(typeof e.borderColor=="string"){const n=ce(e.borderColor);s.uniforms.uBorderColor.value.set(n.color.r,n.color.g,n.color.b,n.alpha)}else{const n=s.uniforms.uBorderColor.value.w;s.uniforms.uBorderColor.value.set(e.borderColor.r,e.borderColor.g,e.borderColor.b,n)}e.opacity!==void 0&&(s.uniforms.uOpacity.value=e.opacity),e.bgOpacity!==void 0&&(s.uniforms.uBgColor.value.w=e.bgOpacity),e.borderOpacity!==void 0&&(s.uniforms.uBorderColor.value.w=e.borderOpacity),s.uniforms.uTexture&&e.texture!==void 0&&(s.uniforms.uTexture.value=e.texture);const t=e.texture!==void 0?e.texture:(i=s.uniforms.uTexture)==null?void 0:i.value;if(t&&(t.image instanceof ImageBitmap||t.image instanceof HTMLImageElement||t.image instanceof HTMLCanvasElement)){const n=t.image.width,o=t.image.height,a=(r=e.width)!=null?r:s.uniforms.uSize.value.x,l=(c=e.height)!=null?c:s.uniforms.uSize.value.y;if(n&&o&&a&&l){const h=n/o,f=a/l;if(h>f){const b=f/h;s.uniforms.uTextureRepeat.value.set(b,1),s.uniforms.uTextureOffset.value.set((1-b)/2,0)}else{const b=h/f;s.uniforms.uTextureRepeat.value.set(1,b),s.uniforms.uTextureOffset.value.set(0,(1-b)/2)}}}else s.uniforms.uTextureRepeat&&(s.uniforms.uTextureRepeat.value.set(1,1),s.uniforms.uTextureOffset.value.set(0,0));if(e.backgroundImage!==void 0){const n=We(e.backgroundImage);if(n){s.uniforms.uGradientCount.value=n.stops.length,s.uniforms.uGradientAngle.value=n.angle;for(let o=0;o<8;o++)if(o<n.stops.length){const a=n.stops[o];s.uniforms.uGradientColors.value[o].set(a.color.r,a.color.g,a.color.b,a.alpha),s.uniforms.uGradientStops.value[o]=a.stop}else s.uniforms.uGradientColors.value[o].set(0,0,0,0),s.uniforms.uGradientStops.value[o]=1}else s.uniforms.uGradientCount.value=0}for(const n of Object.keys(e))n!=="width"&&n!=="height"&&n!=="borderRadius"&&n!=="borderWidth"&&n!=="backgroundColor"&&n!=="borderColor"&&n!=="opacity"&&n!=="bgOpacity"&&n!=="borderOpacity"&&n!=="texture"&&n!=="backgroundImage"&&s.uniforms[n]!==void 0&&(s.uniforms[n].value!==void 0&&s.uniforms[n].value!==null&&typeof s.uniforms[n].value.set=="function"?Array.isArray(e[n])?s.uniforms[n].value.set(...e[n]):e[n]!==void 0&&(e[n].copy?s.uniforms[n].value.copy(e[n]):s.uniforms[n].value=e[n]):s.uniforms[n].value=e[n])}function ke(s,e){var o,a,l,h;if(e==null){s.set(0,0,0,0);return}if(typeof e=="number"){s.set(e,e,e,e);return}if(Array.isArray(e)){s.set(e[0],e[1],e[2],e[3]);return}const t=e.split("/")[0].trim().split(/\s+/),i=te(t[0]),r=te((o=t[1])!=null?o:t[0]),c=te((a=t[2])!=null?a:t[0]),n=te((h=(l=t[3])!=null?l:t[1])!=null?h:t[0]);s.set(i,r,c,n)}const q={create(s,e,t,i,r,c=2,n=null,o){return s==="BOX"?Ke(e,i,r,n,o):s==="TEXT"?new Pe(t||"",e,i,r,c):new v.MeshBasicMaterial({visible:!1})},update(s,e,t,i,r,c,n=2,o){e==="BOX"?Je(s,t,r,c,o):e==="TEXT"&&s.updateText(i||"",t,r,c,n)},forceUpdateUniforms(s,e){Ee(s,e)}};class Ze{constructor(e){d(this,"observer");d(this,"textures",new WeakMap);d(this,"loadStatus",new WeakMap);d(this,"elementUrls",new WeakMap);d(this,"onUpdate");this.onUpdate=e,this.observer=new IntersectionObserver(t=>{for(const i of t){const r=i.target;i.isIntersecting?this.loadTexture(r):this.disposeTexture(r)}},{rootMargin:"300px"})}register(e,t){if(e.nodeType!==Node.ELEMENT_NODE)return;this.elementUrls.get(e)!==t&&(this.elementUrls.set(e,t),this.observer.unobserve(e),this.observer.observe(e))}unregister(e){e.nodeType===Node.ELEMENT_NODE&&this.observer.unobserve(e),this.disposeTexture(e),this.elementUrls.delete(e),this.loadStatus.delete(e)}loadTexture(e){return Xe(this,null,function*(){if(this.loadStatus.get(e)||this.textures.has(e))return;const t=this.elementUrls.get(e);if(t){this.loadStatus.set(e,!0);try{let i;if(t.startsWith("data:image/svg+xml"))i=yield new Promise((c,n)=>{const o=new Image;o.onload=()=>c(o),o.onerror=n,o.src=t});else{const n=yield(yield fetch(t)).blob();i=yield createImageBitmap(n,{imageOrientation:"flipY"})}if(this.elementUrls.get(e)!==t){"close"in i&&i.close();return}const r=new v.Texture(i);i instanceof HTMLImageElement||(r.flipY=!1),r.colorSpace=v.LinearSRGBColorSpace,r.needsUpdate=!0,this.textures.set(e,r),this.onUpdate(e,r)}catch(i){console.warn("[MirageEngine] Failed to load texture:",t,i)}finally{this.elementUrls.has(e)&&this.loadStatus.set(e,!1)}}})}disposeTexture(e){const t=this.textures.get(e);t&&(t.dispose(),this.textures.delete(e),this.onUpdate(e,null)),this.loadStatus.set(e,!1)}get(e){return this.textures.get(e)}disposeAll(){this.observer.disconnect()}}class Qe{constructor(e,t,i,r){d(this,"canvas");d(this,"scene");d(this,"camera");d(this,"renderer");d(this,"renderTargets",[]);d(this,"renderOrder",0);d(this,"qualityFactor",2);d(this,"mode","overlay");d(this,"clipArea",1);d(this,"targetLayer","base");d(this,"target");d(this,"mountContainer");d(this,"registry");d(this,"targetRect");d(this,"travelersByLayer",Array.from({length:A.MAX_LAYERS},()=>new Set));d(this,"textureManager");d(this,"fixedMeshes",new Set);var o,a,l,h;this.target=e,this.mountContainer=i,this.registry=r,this.textureManager=new Ze((f,b)=>{const p=this.registry.get(f);p&&p.material instanceof v.ShaderMaterial&&q.forceUpdateUniforms(p.material,{texture:b})}),this.mode=(o=t.mode)!=null?o:"overlay",this.clipArea=(a=t.travelerClipArea)!=null?a:1,this.targetLayer=(l=t.layer)!=null?l:"base",this.canvas=document.createElement("canvas"),this.scene=new v.Scene,this.targetRect=this.target.getBoundingClientRect();const c=this.targetRect.width,n=this.targetRect.height;this.camera=new v.OrthographicCamera(c/-2,c/2,n/2,n/-2,1,1e3),this.camera.position.z=100,this.camera.layers.set(this.getSceneLayer()),this.renderer=new v.WebGLRenderer({canvas:this.canvas,alpha:!0,antialias:!0}),v.ColorManagement.enabled=!1,this.renderer.outputColorSpace=v.LinearSRGBColorSpace,this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setSize(c,n),this.applyTextQuality((h=t.quality)!=null?h:"medium")}getSceneLayer(){return typeof this.targetLayer=="number"?this.targetLayer:this.targetLayer==="selected"?U.SELECTED:U.BASE}createRenderTarget(){for(let e=0;e<A.MAX_LAYERS;e++)this.renderTargets.push(new v.WebGLRenderTarget(this.targetRect.width*this.qualityFactor,this.targetRect.height*this.qualityFactor,{minFilter:v.LinearFilter,magFilter:v.LinearFilter,format:v.RGBAFormat,stencilBuffer:!1,depthBuffer:!0}))}applyTextQuality(e){if(typeof e=="number"){this.qualityFactor=Math.max(.1,e);return}switch(e){case"low":this.qualityFactor=1;break;case"high":this.qualityFactor=4;break;case"medium":this.qualityFactor=2;break;default:this.qualityFactor=2;break}}mount(){this.mountContainer.prepend(this.canvas),this.canvas.style.pointerEvents=this.mode==="overlay"?"none":"auto",this.updateCanvasLayout()}updateCanvasLayout(){this.canvas.style.width=`${this.targetRect.width}px`,this.canvas.style.height=`${this.targetRect.height}px`,this.mode==="duplicate"?(this.canvas.style.position="",this.canvas.style.top="",this.canvas.style.left="",this.canvas.style.display="block"):(this.canvas.style.position="absolute",this.canvas.style.top=`${this.target.offsetTop}px`,this.canvas.style.left=`${this.target.offsetLeft}px`,this.canvas.style.display="block")}updateUniforms(e,t){const i=this.registry.get(e);i&&(i.traverse(r=>{r.isMesh&&r.material&&q.forceUpdateUniforms(r.material,t)}),i.userData.nativeMesh&&i.userData.nativeMesh.traverse(r=>{r.isMesh&&r.material&&q.forceUpdateUniforms(r.material,t)}))}dispose(){this.renderer.dispose(),this.canvas.remove(),this.textureManager.disposeAll()}setSize(e,t){this.renderer.setSize(e,t);for(const i of this.renderTargets)i.setSize(e*this.qualityFactor,t*this.qualityFactor);this.camera.left=e/-2,this.camera.right=e/2,this.camera.top=t/2,this.camera.bottom=t/-2,this.camera.updateProjectionMatrix()}syncScene(e,t){const i=this.target.getBoundingClientRect(),r=Math.abs(i.width-this.targetRect.width)>.1||Math.abs(i.height-this.targetRect.height)>.1,c=this.mode==="overlay"&&(Math.abs(i.top-this.targetRect.top)>.1||Math.abs(i.left-this.targetRect.left)>.1);r?(this.targetRect=i,this.setSize(this.targetRect.width,this.targetRect.height),this.updateCanvasLayout()):c?(this.targetRect=i,this.updateCanvasLayout()):this.targetRect=i,this.renderOrder=0,this.reconcileNode(e),t.size>0&&t.forEach(n=>{const o=this.registry.get(n);if(o){this.scene.remove(o);for(const a of this.travelersByLayer)a.delete(o);this.fixedMeshes.delete(o),o.geometry.dispose(),o.userData.nativeMesh&&(this.scene.remove(o.userData.nativeMesh),Array.isArray(o.userData.nativeMesh.material)?o.userData.nativeMesh.material.forEach(a=>a.dispose()):o.userData.nativeMesh.material.dispose(),o.userData.nativeMesh.geometry.dispose()),o.traverse(a=>{a instanceof v.Mesh&&(a.geometry&&a.geometry.dispose(),a.material&&(Array.isArray(a.material)?a.material.forEach(l=>l.dispose()):a.material.dispose()))}),this.registry.remove(n),this.textureManager.unregister(n)}})}reconcileNode(e){var i;let t=this.registry.get(e.element);if(!t){const r=new v.PlaneGeometry(1,1),c=e.isTraveler?(i=this.renderTargets[e.captureLayer-2])==null?void 0:i.texture:this.textureManager.get(e.element),n=q.create("BOX",e.styles,"",e.rect.width,e.rect.height,this.qualityFactor,c,e.shaderHooks);t=new v.Mesh(r,n),e.type==="TEXT"&&(t.name="BG_MESH"),this.scene.add(t),this.registry.register(e.element,t),t.userData.baseMaterial=n}if(this.updateMeshProperties(t,e),this.updateMeshLayers(t,e),e.isTraveler)for(let r=0;r<A.MAX_LAYERS;r++)r===e.captureLayer-2?this.travelersByLayer[r].add(t):this.travelersByLayer[r].delete(t);else for(const r of this.travelersByLayer)r.delete(t);if(e.isFixed?this.fixedMeshes.add(t):this.fixedMeshes.delete(t),e.styles.imageSrc?this.textureManager.register(e.element,e.styles.imageSrc):this.textureManager.unregister(e.element),e.type==="BOX")for(const r of e.children)this.reconcileNode(r);else e.type==="TEXT"&&(this.reconcileTextChild(t,e,!1),t.userData.nativeMesh&&e.nativeStyles&&this.reconcileTextChild(t.userData.nativeMesh,e,!0))}reconcileTextChild(e,t,i){var l;const r=t.textLines||[{text:t.textContent||"",rect:t.rect}],c=i?t.nativeStyles:t.textStyles,n=JSON.stringify(c)+t.textContent+r.map(h=>h.text).join("|"),o=(l=e.userData)==null?void 0:l.textChildStyleHash;if(t.dirtyMask&me||n!==o){e.children.filter(u=>u.name.startsWith("TEXT_CHILD")).forEach(u=>{var S;const g=u;(S=g.material.map)==null||S.dispose(),g.geometry.dispose(),e.remove(g)});const f=t.rect,b=f.x+f.width/2,p=f.y+f.height/2;r.forEach((u,g)=>{const S=q.create("TEXT",c,u.text,u.rect.width,u.rect.height,this.qualityFactor),k=new v.PlaneGeometry(1,1),I=new v.Mesh(k,S);I.name=`TEXT_CHILD_${g}`;const C=t.rect.width===0?1:u.rect.width/t.rect.width,T=t.rect.height===0?1:u.rect.height/t.rect.height;I.scale.set(C,T,1);const N=u.rect.x+u.rect.width/2,z=u.rect.y+u.rect.height/2,H=N-b,_=-(z-p);I.position.set(t.rect.width===0?0:H/t.rect.width,t.rect.height===0?0:_/t.rect.height,.005),e.add(I)}),e.userData.textChildStyleHash=n}e.children.forEach(h=>{if(!h.name.startsWith("TEXT_CHILD"))return;const f=h,b=t.visibility&W?U.BASE:U.HIDDEN;if(f.layers.set(b),t.visibility&Z&&f.layers.enable(U.SELECTED),t.visibility&W)if(!i&&t.nativeLayer!==void 0&&t.nativeStyles!==void 0)for(let p=t.captureLayer;p<t.nativeLayer;p++)f.layers.enable(U.getCaptureLayer(p));else if(i&&t.nativeLayer!==void 0)for(let p=Math.max(t.captureLayer,t.nativeLayer);p<=A.MAX_LAYERS+1;p++)f.layers.enable(U.getCaptureLayer(p));else for(let p=t.captureLayer;p<=A.MAX_LAYERS+1;p++)f.layers.enable(U.getCaptureLayer(p))})}updateMeshProperties(e,t){var N,z,H;const{rect:i,styles:r}=t,c=this.renderer.getPixelRatio(),n=this.renderer.domElement.width/c,o=this.renderer.domElement.height/c;e.material=e.userData.baseMaterial,e.scale.set(i.width,i.height,1),e.userData.domRect=Se(J({},i),{width:i.width,height:i.height});const a=.001;this.renderOrder++;const l=this.targetRect.left+window.scrollX,h=this.targetRect.top+window.scrollY,f=i.x-l,b=i.y-h,p=f-n/2+i.width/2,u=-b+o/2-i.height/2;e.position.set(p,u,r.zIndex+this.renderOrder*a);const g=i.x,S=i.y;e.userData.basePosition={x:p,y:u},e.userData.originalBasePosition={x:p,y:u},e.userData.baseSize={width:i.width,height:i.height},e.userData.baseDOM={x:g,y:S},e.userData.isFixed=t.isFixed,e.userData.initialScroll={x:window.scrollX,y:window.scrollY};const k=t.element.nodeType===Node.TEXT_NODE?t.element.parentElement:t.element,I=window.getComputedStyle(k);let C=0,T=0;if(I.transform&&I.transform!=="none"){const _=new DOMMatrix(I.transform);C=_.m41,T=_.m42}if(e.userData.baseTransform={x:C,y:T},delete e.userData.originRatioX,delete e.userData.originRatioY,q.update(e.userData.baseMaterial,"BOX",r,"",i.width,i.height,this.qualityFactor,t.isTraveler?(N=this.renderTargets[t.captureLayer-2])==null?void 0:N.texture:this.textureManager.get(t.element)),t.nativeStyles&&t.nativeRect){if(!e.userData.nativeMesh){const Q=q.create("BOX",t.nativeStyles,"",t.nativeRect.width,t.nativeRect.height,this.qualityFactor,t.isTraveler?(z=this.renderTargets[t.captureLayer-2])==null?void 0:z.texture:this.textureManager.get(t.element),t.shaderHooks),$=new v.Mesh(e.geometry,Q);t.type==="TEXT"&&($.name="BG_MESH"),this.scene.add($),e.userData.nativeMesh=$}const _=e.userData.nativeMesh,B=t.nativeRect.x-l,re=t.nativeRect.y-h,ie=B-n/2+t.nativeRect.width/2,se=-re+o/2-t.nativeRect.height/2;_.scale.set(t.nativeRect.width,t.nativeRect.height,1),_.position.set(ie,se,t.nativeStyles.zIndex+this.renderOrder*a),q.update(_.material,"BOX",t.nativeStyles,"",t.nativeRect.width,t.nativeRect.height,this.qualityFactor,t.isTraveler?(H=this.renderTargets[t.captureLayer-2])==null?void 0:H.texture:this.textureManager.get(t.element))}else e.userData.nativeMesh&&(this.scene.remove(e.userData.nativeMesh),e.userData.nativeMesh.material instanceof v.Material&&e.userData.nativeMesh.material.dispose(),delete e.userData.nativeMesh)}updateMeshLayers(e,t){const i=t.visibility&W?U.BASE:U.HIDDEN;if(e.layers.set(i),t.visibility&Z&&e.layers.enable(U.SELECTED),e.userData.nativeMesh&&t.nativeLayer!==void 0){const r=e.userData.nativeMesh;if(r.layers.set(U.HIDDEN),t.visibility&W){for(let c=t.captureLayer;c<t.nativeLayer;c++)e.layers.enable(U.getCaptureLayer(c));for(let c=Math.max(t.captureLayer,t.nativeLayer);c<=A.MAX_LAYERS+1;c++)r.layers.enable(U.getCaptureLayer(c))}}else if(t.visibility&W)for(let r=t.captureLayer;r<=A.MAX_LAYERS+1;r++)e.layers.enable(U.getCaptureLayer(r))}captureRenderTarget(e,t,i){if(e.size===0||!i)return;const r=new v.Color,c=this.renderer.getClearAlpha();this.renderer.getClearColor(r),this.renderer.setClearColor(0,0),this.renderer.setRenderTarget(i),this.renderer.clear(),this.renderer.autoClear=!1,this.renderer.setScissorTest(!0),this.camera.layers.set(t);const n=new v.Vector3,o=this.targetRect.width,a=this.targetRect.height,l=this.renderer.getPixelRatio();for(const h of e){n.setFromMatrixPosition(h.matrixWorld),n.project(this.camera);const f=(n.x+1)/2*o,b=(n.y+1)/2*a;let p=0,u=1;typeof this.clipArea=="number"?u=this.clipArea:this.clipArea.endsWith("%")?u=parseFloat(this.clipArea)/100:this.clipArea.endsWith("px")&&(p=parseFloat(this.clipArea));const g=h.scale.x*u+.5,S=h.scale.y*u+.5,k=f-g/2,I=b-S/2,C=(k*this.qualityFactor-p)/l,T=(I*this.qualityFactor-p)/l,N=(g*this.qualityFactor+p*2)/l,z=(S*this.qualityFactor+p*2)/l;this.renderer.setScissor(C,T,N,z),this.renderer.render(this.scene,this.camera)}this.renderer.setScissorTest(!1),this.renderer.autoClear=!0,this.renderer.setRenderTarget(null),this.camera.layers.set(this.getSceneLayer()),this.renderer.setClearColor(r,c)}render(){for(let e=0;e<A.MAX_LAYERS;e++){const t=e+1;this.captureRenderTarget(this.travelersByLayer[e],U.getCaptureLayer(t),this.renderTargets[e])}this.renderer.render(this.scene,this.camera)}}function et(s){const e=s.textContent||"",t=[];let i="",r=null,c=-1;const n=(l,h)=>{for(let f=0;f<l.length;f++){const b=l[f],p=document.createRange();p.setStart(s,h+f),p.setEnd(s,h+f+1);const u=p.getBoundingClientRect();if(u.width===0&&u.height===0){i+=b;continue}c===-1||Math.abs(u.top-c)>u.height/2?(i&&r&&t.push({text:i,rect:{left:r.left,top:r.top,width:r.right-r.left,height:r.bottom-r.top}}),i=b,r={left:u.left,top:u.top,right:u.right,bottom:u.bottom},c=u.top):(i+=b,r&&(r.left=Math.min(r.left,u.left),r.top=Math.min(r.top,u.top),r.right=Math.max(r.right,u.right),r.bottom=Math.max(r.bottom,u.bottom)))}},o=e.match(/[^\s\-]+\-?|\-|\s+/g)||[];let a=0;for(const l of o){const h=document.createRange();h.setStart(s,a),h.setEnd(s,a+l.length);const f=h.getClientRects();if(f.length>1)n(l,a);else{const b=f.length===1?f[0]:h.getBoundingClientRect();if(b.width===0&&b.height===0){i+=l,a+=l.length;continue}c===-1||Math.abs(b.top-c)>b.height/2?(i&&r&&t.push({text:i,rect:{left:r.left,top:r.top,width:r.right-r.left,height:r.bottom-r.top}}),i=l,r={left:b.left,top:b.top,right:b.right,bottom:b.bottom},c=b.top):(i+=l,r&&(r.left=Math.min(r.left,b.left),r.top=Math.min(r.top,b.top),r.right=Math.max(r.right,b.right),r.bottom=Math.max(r.bottom,b.bottom)))}a+=l.length}return i&&r&&t.push({text:i,rect:{left:r.left,top:r.top,width:r.right-r.left,height:r.bottom-r.top}}),t.filter(l=>l.text.trim().length>0&&l.rect.width>0&&l.rect.height>0)}function Oe(s){const e=parseFloat(s.fontSize);let t=parseFloat(s.lineHeight);isNaN(t)&&(t=e*1.2);let i=parseFloat(s.letterSpacing);return isNaN(i)&&(i=0),{font:`${s.fontStyle} ${s.fontWeight} ${s.fontSize} ${s.fontFamily}`,fontSize:s.fontSize,color:s.color,textAlign:s.textAlign||"start",textBaseline:"alphabetic",direction:s.direction||"inherit",lineHeight:t,letterSpacing:i}}function Ue(s,e=K|ee|Le|me|pe,t,i=1,r=0,c=2,n,o){var $,le,he,ue,de,fe;if(s.nodeType===Node.TEXT_NODE){const m=s;if(!m.textContent||!m.textContent.trim())return null;const R=m.textContent.replace(/\s+/g," ");if(R.length===0)return null;const O=et(m);if(O.length===0)return null;const X=m.parentElement,L=X?window.getComputedStyle(X):null;if(!L)return null;const Y=Math.min(...O.map(E=>E.rect.left)),x=Math.min(...O.map(E=>E.rect.top)),P=Math.max(...O.map(E=>E.rect.left+E.rect.width)),j=Math.max(...O.map(E=>E.rect.top+E.rect.height));return{id:Math.random().toString(36).substring(2,9),type:"TEXT",element:m,rect:{x:Y+window.scrollX,y:x+window.scrollY,width:P-Y,height:j-x},styles:{backgroundColor:"transparent",backgroundImage:"",opacity:X&&X.dataset[V.KEY]===V.VALUES.HIDE?1:parseFloat(L.opacity),zIndex:(isNaN(parseInt(L.zIndex))?0:parseInt(L.zIndex))+r,borderRadius:"0px",borderColor:"transparent",borderWidth:"0px",isTraveler:!1},textContent:R,textLines:O.map(E=>({text:E.text.trim(),rect:{x:E.rect.left+window.scrollX,y:E.rect.top+window.scrollY,width:E.rect.width,height:E.rect.height}})),textStyles:Oe(L),dirtyMask:e,visibility:t,isTraveler:!1,captureLayer:i,isFixed:L.position==="fixed",nativeLayer:n,nativeStyles:o?J(J({backgroundColor:"transparent",backgroundImage:"",opacity:X&&X.dataset[V.KEY]===V.VALUES.HIDE?1:parseFloat(L.opacity),zIndex:(isNaN(parseInt(L.zIndex))?0:parseInt(L.zIndex))+r,borderRadius:"0px",borderColor:"transparent",borderWidth:"0px",isTraveler:!1},Oe(L)),o):void 0,nativeRect:o?{x:Y+window.scrollX,y:x+window.scrollY,width:P-Y,height:j-x}:void 0,children:[]}}if(s.nodeType!==Node.ELEMENT_NODE)return null;const a=s,l=a.dataset[D.KEY];let h=t,f=t;if(l){const m=new Set(l.split(/\s+/));for(const R of m)if(!ve.includes(R))throw new Error(`[MirageEngine] Invalid filter token: '${R}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`);if(m.has(D.VALUES.END))return null;if(m.has(D.VALUES.INCLUDE_TREE)&&m.has(D.VALUES.EXCLUDE_TREE))throw new Error("[MirageEngine] Conflicting filters: 'include-tree' and 'exclude-tree' cannot be used together on the same element.");if(m.has(D.VALUES.INCLUDE_SELF)&&m.has(D.VALUES.EXCLUDE_SELF))throw new Error("[MirageEngine] Conflicting filters: 'include-self' and 'exclude-self' cannot be used together on the same element.");m.has(D.VALUES.INCLUDE_TREE)?h=h|W:m.has(D.VALUES.EXCLUDE_TREE)&&(h=h&~W),f=h,m.has(D.VALUES.INCLUDE_SELF)?f=f|W:m.has(D.VALUES.EXCLUDE_SELF)&&(f=f&~W)}const b=a.dataset[F.KEY];if(b){const m=new Set(b.split(/\s+/));for(const R of m)if(!ve.includes(R))throw new Error(`[MirageEngine] Invalid select token: '${R}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`);if(m.has(F.VALUES.END))return null;if(m.has(F.VALUES.INCLUDE_TREE)&&m.has(F.VALUES.EXCLUDE_TREE))throw new Error("[MirageEngine] Conflicting selects: 'include-tree' and 'exclude-tree' cannot be used together on the same element.");if(m.has(F.VALUES.INCLUDE_SELF)&&m.has(F.VALUES.EXCLUDE_SELF))throw new Error("[MirageEngine] Conflicting selects: 'include-self' and 'exclude-self' cannot be used together on the same element.");m.has(F.VALUES.INCLUDE_TREE)?h=h|Z:m.has(F.VALUES.EXCLUDE_TREE)&&(h=h&~Z),f=h,m.has(F.VALUES.INCLUDE_SELF)?f=f|Z:m.has(F.VALUES.EXCLUDE_SELF)&&(f=f&~Z)}const p=a.dataset[A.KEY];let u=!1,g=o?J({},o):{},S=n;if(p){let m=1;const R=p.indexOf("{"),O=p.lastIndexOf("}");let X=p;if(R!==-1&&O!==-1&&O>R){X=p.substring(0,R).trim();const x=p.substring(R,O+1);try{g=new Function("return "+x)()}catch(P){console.warn(`[MirageEngine] Failed to parse travel styles JSON: ${x}`)}}const L=X.split(/\s+/);let Y=!1;if(L.includes(A.VALUES.TRAVELER)){u=!0,Y=!0;const x=L.find(P=>!isNaN(parseInt(P,10)));x&&(m=parseInt(x,10))}else if(L.includes(A.VALUES.NATIVE)){u=!1;const x=L.find(P=>!isNaN(parseInt(P,10)));x&&(S=parseInt(x,10))}if(Y){const x=m+1;if(x<i)throw new Error(`[MirageEngine] Traveler layer (${m}) cannot be smaller than inherited capture layer (${i-1}).`);i=Math.min(x,A.MAX_LAYERS+1)}}const k=a.dataset[Re.KEY];let I;k&&(I=JSON.parse(k));const C=a.getBoundingClientRect(),T=window.getComputedStyle(a);if(C.width===0||C.height===0||T.display==="none")return null;let N=a.getAttribute("data-mid");N||(N=Math.random().toString(36).substring(2,11),a.setAttribute("data-mid",N));const z=parseInt(T.zIndex),H=(isNaN(z)?0:z)+r;let _;if(a.tagName==="IMG")_=a.src;else if(a.tagName.toLowerCase()==="svg"){const m=a.cloneNode(!0),R=g==null?void 0:g.color,O=g==null?void 0:g.fill,X=g==null?void 0:g.stroke,L=g==null?void 0:g.opacity,Y=(E,_e)=>{const G=window.getComputedStyle(E),ge=_e,ot=G.fill===G.color,at=G.stroke===G.color,Te=O||(ot?R:void 0)||G.fill;Te&&Te!=="none"&&(ge.style.fill=Te);const Ce=X||(at?R:void 0)||G.stroke;Ce&&Ce!=="none"&&(ge.style.stroke=Ce),G.strokeWidth&&G.strokeWidth!=="0px"&&(ge.style.strokeWidth=G.strokeWidth);const Fe=R||G.color;Fe&&(ge.style.color=Fe);const xe=L||G.opacity;xe&&xe!=="1"&&(ge.style.opacity=xe);for(let be=0;be<E.children.length;be++)Y(E.children[be],_e.children[be])};Y(a,m);const x=a.getBoundingClientRect(),P=window.devicePixelRatio*c;m.hasAttribute("viewBox")||m.setAttribute("viewBox",`0 0 ${x.width} ${x.height}`),m.setAttribute("width",(x.width*P).toString()),m.setAttribute("height",(x.height*P).toString());let j=new XMLSerializer().serializeToString(m);j.includes("xmlns=")||(j=j.replace("<svg",'<svg xmlns="http://www.w3.org/2000/svg"')),_=`data:image/svg+xml;utf8,${encodeURIComponent(j)}`}else if(T.backgroundImage&&T.backgroundImage!=="none"){const m=T.backgroundImage.match(/url\(['"]?(.*?)['"]?\)/);m&&(_=m[1])}const B={backgroundColor:T.backgroundColor,backgroundImage:T.backgroundImage,opacity:a.dataset[V.KEY]===V.VALUES.HIDE?1:parseFloat(T.opacity),zIndex:H,borderRadius:T.borderRadius,borderColor:T.borderColor,borderWidth:T.borderWidth,imageSrc:_,isTraveler:u},re=B;let ie,se;const Q=[];return a.tagName.toLowerCase()!=="svg"&&Array.from(a.childNodes).forEach(m=>{const R=m.nodeType===Node.TEXT_NODE?f:h,O=Ue(m,e,R,i,H,c,S,m.nodeType===Node.TEXT_NODE&&Object.keys(g).length>0?g:void 0);O&&Q.push(O)}),{id:N,type:"BOX",element:a,rect:{x:C.left+window.scrollX,y:C.top+window.scrollY,width:C.width,height:C.height},styles:re,textContent:ie,textStyles:se,dirtyMask:e,visibility:f,isTraveler:u,captureLayer:i,nativeLayer:S,nativeStyles:S!==void 0?Se(J({},B),{backgroundColor:($=g.backgroundColor)!=null?$:B.backgroundColor,backgroundImage:(le=g.backgroundImage)!=null?le:B.backgroundImage,opacity:(he=g.opacity)!=null?he:B.opacity,zIndex:g.zIndex!==void 0?g.zIndex+H:B.zIndex,borderRadius:(ue=g.borderRadius)!=null?ue:B.borderRadius,borderColor:(de=g.borderColor)!=null?de:B.borderColor,borderWidth:(fe=g.borderWidth)!=null?fe:B.borderWidth,isTraveler:B.isTraveler}):void 0,nativeRect:S!==void 0?{x:g.x!==void 0?parseFloat(g.x):C.left+window.scrollX,y:g.y!==void 0?parseFloat(g.y):C.top+window.scrollY,width:g.width!==void 0?parseFloat(g.width):C.width,height:g.height!==void 0?parseFloat(g.height):C.height}:void 0,isFixed:T.position==="fixed",children:Q,shaderHooks:I}}function tt(s,e){e.size!==0&&e.forEach((t,i)=>{var N,z,H,_,B,re,ie,se,Q,$,le,he,ue,de,fe,m,R,O;const r=s.get(i);if(!r||!r.userData.basePosition)return;let{x:c,y:n}=r.userData.basePosition;const{width:o,height:a}=r.userData.baseSize,l=(N=t.width)!=null?N:o,h=(z=t.height)!=null?z:a,f=l-o,b=h-a;if(t.width!==void 0&&r.userData.originRatioX===void 0&&Math.abs(f)>.1){const X=i.getBoundingClientRect(),L=(H=t.x)!=null?H:0,Y=(B=(_=r.userData.baseTransform)==null?void 0:_.x)!=null?B:0,x=r.userData.isFixed?0:window.scrollX;let E=-(X.left+x-L+Y-r.userData.baseDOM.x)/f;Math.abs(E)<.05?E=0:Math.abs(E-1)<.05?E=1:Math.abs(E-.5)<.05&&(E=.5),r.userData.originRatioX=E}if(t.height!==void 0&&r.userData.originRatioY===void 0&&Math.abs(b)>.1){const X=i.getBoundingClientRect(),L=(re=t.y)!=null?re:0,Y=(se=(ie=r.userData.baseTransform)==null?void 0:ie.y)!=null?se:0,x=r.userData.isFixed?0:window.scrollY;let E=-(X.top+x-L+Y-r.userData.baseDOM.y)/b;Math.abs(E)<.05?E=0:Math.abs(E-1)<.05?E=1:Math.abs(E-.5)<.05&&(E=.5),r.userData.originRatioY=E}const p=(Q=r.userData.originRatioX)!=null?Q:.5,u=($=r.userData.originRatioY)!=null?$:.5,g=f*(.5-p),S=b*(.5-u),k=(he=(le=r.userData.baseTransform)==null?void 0:le.x)!=null?he:0,I=(de=(ue=r.userData.baseTransform)==null?void 0:ue.y)!=null?de:0,C=((fe=t.x)!=null?fe:k)-k,T=((m=t.y)!=null?m:I)-I;r.position.setX(c+g+C),r.position.setY(n-(S+T)),r.scale.set(l,h,1),q.forceUpdateUniforms(r.material,{backgroundColor:t.backgroundColor,backgroundImage:t.backgroundImage,opacity:t.opacity,borderRadius:(O=t.borderRadius)!=null?O:(R=r.userData.baseStyles)==null?void 0:R.borderRadius,width:l,height:h})})}function rt(s,e,t){s.forEach(i=>{if(i.userData.isFixed&&i.userData.initialScroll&&i.userData.originalBasePosition){const r=e-i.userData.initialScroll.x,c=t-i.userData.initialScroll.y;i.userData.basePosition.x=i.userData.originalBasePosition.x+r,i.userData.basePosition.y=i.userData.originalBasePosition.y-c,i.position.x=i.userData.basePosition.x,i.position.y=i.userData.basePosition.y}})}class it{constructor(e,t,i,r){d(this,"target");d(this,"renderer");d(this,"registry");d(this,"isTravelEnabled",!1);d(this,"tracker");this.target=e,this.renderer=t,this.registry=i,this.tracker=new De(e,{resizeDebounce:r.resizeDebounce}),this.tracker.onLayoutChange.add((c,n)=>{document.querySelector(`[${A.NAME}~='${A.VALUES.TRAVELER}']`)!==null&&!this.isTravelEnabled&&(this.isTravelEnabled=!0,this.renderer.createRenderTarget());const a=Ue(this.target,c,W,1,0,this.renderer.qualityFactor);a&&this.renderer.syncScene(a,n)}),this.tracker.onScrollChange.add((c,n)=>{rt(this.renderer.fixedMeshes,c,n)}),this.tracker.onStyleChange.add(c=>{tt(this.registry,c)}),this.tracker.onRender.add(()=>{this.renderer.render()})}start(){this.tracker.start()}stop(){this.tracker.stop()}}class st{constructor(){d(this,"store");this.store=new WeakMap}register(e,t){this.store.set(e,t)}get(e){return this.store.get(e)}has(e){return this.store.has(e)}remove(e){this.store.delete(e)}}class nt{constructor(e,t){d(this,"renderer");d(this,"syncer");d(this,"target");d(this,"registry");var r,c,n;if(this.target=e,this.registry=new st,!document.getElementById("mirage-engine-styles")){const o=document.createElement("style");o.id="mirage-engine-styles",o.textContent=`
152
+ [${V.NAME}="${V.VALUES.HIDE}"] {
153
+ opacity: 0 !important;
154
+ }
155
+ `,document.head.appendChild(o)}let i;if(t.mode==="duplicate"?i=(c=(r=t.container)!=null?r:this.target.parentElement)!=null?c:void 0:i=(n=this.target.parentElement)!=null?n:void 0,!i)throw new Error("[Mirage] Cannot find a container (parent or option).");this.renderer=new Qe(this.target,t,i,this.registry),this.renderer.mount(),this.syncer=new it(this.target,this.renderer,this.registry,t)}start(){this.syncer.start()}stop(){this.syncer.stop()}dispose(){this.syncer.stop(),this.renderer.dispose()}getTracker(){return this.syncer.tracker}updateUniforms(e,t){this.renderer.updateUniforms(e,t)}getCanvas(){return this.renderer.canvas}test(){const e=this.registry.get(document.querySelector("#box2"));if(!e)return;const t={ArrowRight:!1,ArrowLeft:!1,ArrowUp:!1,ArrowDown:!1};window.addEventListener("keydown",c=>{t[c.key]!==void 0&&(t[c.key]=!0)}),window.addEventListener("keyup",c=>{t[c.key]!==void 0&&(t[c.key]=!1)});const i=2,r=()=>{requestAnimationFrame(r),t.ArrowRight&&e.position.setX(e.position.x+i),t.ArrowLeft&&e.position.setX(e.position.x-i),t.ArrowUp&&e.position.setY(e.position.y+i),t.ArrowDown&&e.position.setY(e.position.y-i)};r()}}y.ALLOWED_FILTERS=ve,y.ATTR_DOM=V,y.ATTR_FILTER=D,y.ATTR_SANDWICH=Ne,y.ATTR_SELECT=F,y.ATTR_SHADER=Re,y.ATTR_TRAVEL=A,y.DIRTY_CONTENT=me,y.DIRTY_NONE=ae,y.DIRTY_RECT=K,y.DIRTY_STRUCTURE=pe,y.DIRTY_STYLE=ee,y.DIRTY_ZINDEX=Le,y.EXCLUDED=ze,y.Engine=nt,y.SELECT_LAYER=Z,y.THREE_LAYERS=U,y.TRAVEL_VALUES=oe,y.Tracker=De,y.USER_LAYER=W,y.extractFromStyle=Me,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,6 @@
1
+ import { StyleData } from '@mirage-engine/dom-tracker';
2
+ import { MeshRegistry } from '../store/MeshRegistry';
3
+
4
+ import * as THREE from "three";
5
+ export declare function animateMeshByData(registry: MeshRegistry, data: Map<HTMLElement, StyleData>): void;
6
+ export declare function updateFixedMeshesScroll(fixedMeshes: Set<THREE.Mesh>, currentScrollX: number, currentScrollY: number): void;
@@ -4,8 +4,13 @@ export declare class Engine {
4
4
  private renderer;
5
5
  private syncer;
6
6
  private target;
7
+ private registry;
7
8
  constructor(target: HTMLElement, config: CoreConfig);
8
9
  start(): void;
9
10
  stop(): void;
10
11
  dispose(): void;
12
+ getTracker(): import('@mirage-engine/dom-tracker').Tracker;
13
+ updateUniforms(element: HTMLElement, uniforms: Record<string, any>): void;
14
+ getCanvas(): HTMLCanvasElement;
15
+ test(): void;
11
16
  }
@@ -1,26 +1,15 @@
1
1
  import { CoreConfig } from '../types/config';
2
2
  import { Renderer } from '../renderer/Renderer';
3
+ import { MeshRegistry } from '../store/MeshRegistry';
4
+ import { Tracker } from '@mirage-engine/dom-tracker';
3
5
 
4
6
  export declare class Syncer {
5
7
  private target;
6
8
  private renderer;
7
- private filter;
8
- private observer;
9
- private isDomDirty;
10
- private isRunning;
9
+ private registry;
11
10
  private isTravelEnabled;
12
- private pendingMask;
13
- private mutationTimer;
14
- private cssTimer;
15
- private resizeConfig;
16
- private resizeTimer;
17
- private isResizing;
18
- constructor(target: HTMLElement, renderer: Renderer, config: CoreConfig);
11
+ tracker: Tracker;
12
+ constructor(target: HTMLElement, renderer: Renderer, registry: MeshRegistry, config: CoreConfig);
19
13
  start(): void;
20
14
  stop(): void;
21
- private clearTimers;
22
- private onTransitionFinished;
23
- private onWindowResize;
24
- private forceUpdateScene;
25
- private renderLoop;
26
15
  }
@@ -1,4 +1,3 @@
1
1
  import { SceneNode, Visibility } from '../types';
2
- import { FilterConfig } from '../types/config';
3
2
 
4
- export declare function extractSceneGraph(sourceNode: HTMLElement | Node, initialMask: number | undefined, inheritedFlow: Visibility, filterConfig?: FilterConfig): SceneNode | null;
3
+ export declare function extractSceneGraph(sourceNode: HTMLElement | Node, initialMask: number | undefined, inheritedFlow: Visibility, captureLayer?: number, inheritedZIndex?: number, qualityFactor?: number, inheritedNativeLayer?: number, inheritedNativeStyles?: any): SceneNode | null;
@@ -1,32 +1,38 @@
1
- import { SceneNode, CoreConfig } from '../types';
2
-
1
+ import { SceneNode, CoreConfig, LayerTarget } from '../types';
2
+ import { MeshRegistry } from '../store/MeshRegistry';
3
+ import * as THREE from "three";
3
4
  export declare class Renderer {
4
5
  readonly canvas: HTMLCanvasElement;
5
6
  private readonly scene;
6
7
  private readonly camera;
7
8
  private readonly renderer;
8
- private renderTarget;
9
+ private renderTargets;
9
10
  private renderOrder;
10
- private qualityFactor;
11
+ qualityFactor: number;
11
12
  private mode;
12
13
  private clipArea;
14
+ targetLayer: number | LayerTarget;
13
15
  private target;
14
16
  private mountContainer;
17
+ private registry;
15
18
  private targetRect;
16
- private meshMap;
17
- constructor(target: HTMLElement, config: CoreConfig, mountContainer: HTMLElement);
19
+ private travelersByLayer;
20
+ private textureManager;
21
+ readonly fixedMeshes: Set<THREE.Mesh>;
22
+ constructor(target: HTMLElement, config: CoreConfig, mountContainer: HTMLElement, registry: MeshRegistry);
23
+ private getSceneLayer;
18
24
  createRenderTarget(): void;
19
25
  private applyTextQuality;
20
26
  mount(): void;
21
27
  private updateCanvasLayout;
28
+ updateUniforms(element: HTMLElement, uniforms: Record<string, any>): void;
22
29
  dispose(): void;
23
30
  setSize(width: number, height: number): void;
24
- syncScene(graphNode: SceneNode): void;
31
+ syncScene(graphNode: SceneNode, pendingDeletions: Set<HTMLElement>): void;
25
32
  private reconcileNode;
26
33
  private reconcileTextChild;
27
34
  private updateMeshProperties;
28
35
  private updateMeshLayers;
29
36
  private captureRenderTarget;
30
37
  render(): void;
31
- showScissoredRenderTarget(): void;
32
38
  }
@@ -0,0 +1,9 @@
1
+ import * as THREE from "three";
2
+ export declare class MeshRegistry {
3
+ private store;
4
+ constructor();
5
+ register(element: HTMLElement, mesh: THREE.Mesh): void;
6
+ get(element: HTMLElement): THREE.Mesh | undefined;
7
+ has(element: HTMLElement): boolean;
8
+ remove(element: HTMLElement): void;
9
+ }
@@ -0,0 +1,16 @@
1
+ import * as THREE from "three";
2
+ export type TextureReadyCallback = (element: HTMLElement, texture: THREE.Texture | null) => void;
3
+ export declare class TextureLifecycleManager {
4
+ private observer;
5
+ private textures;
6
+ private loadStatus;
7
+ private elementUrls;
8
+ private onUpdate;
9
+ constructor(onUpdate: TextureReadyCallback);
10
+ register(element: HTMLElement, url: string): void;
11
+ unregister(element: HTMLElement): void;
12
+ private loadTexture;
13
+ private disposeTexture;
14
+ get(element: HTMLElement): THREE.Texture<unknown> | undefined;
15
+ disposeAll(): void;
16
+ }
@@ -0,0 +1,19 @@
1
+ export interface StyleData {
2
+ x?: number;
3
+ y?: number;
4
+ z?: number;
5
+ scaleX?: number;
6
+ scaleY?: number;
7
+ scaleZ?: number;
8
+ rotateX?: number;
9
+ rotateY?: number;
10
+ rotateZ?: number;
11
+ matrix?: Float32Array;
12
+ opacity?: number;
13
+ backgroundColor?: [number, number, number];
14
+ backgroundImage?: string;
15
+ borderRadius?: number | [number, number, number, number];
16
+ width?: number;
17
+ height?: number;
18
+ zIndex?: number;
19
+ }
@@ -0,0 +1,63 @@
1
+ export declare const ATTR_DOM: {
2
+ readonly NAME: "data-mirage-dom";
3
+ readonly KEY: "mirageDom";
4
+ readonly VALUES: {
5
+ readonly HIDE: "hide";
6
+ };
7
+ };
8
+ export declare const TRAVEL_VALUES: {
9
+ readonly TRAVELER: "traveler";
10
+ readonly NATIVE: "native";
11
+ readonly CAPTURE_1: "1";
12
+ readonly CAPTURE_2: "2";
13
+ readonly CAPTURE_3: "3";
14
+ readonly CAPTURE_4: "4";
15
+ readonly CAPTURE_5: "5";
16
+ };
17
+ export declare const ATTR_TRAVEL: {
18
+ readonly NAME: "data-mirage-travel";
19
+ readonly KEY: "mirageTravel";
20
+ readonly VALUES: {
21
+ readonly TRAVELER: "traveler";
22
+ readonly NATIVE: "native";
23
+ readonly CAPTURE_1: "1";
24
+ readonly CAPTURE_2: "2";
25
+ readonly CAPTURE_3: "3";
26
+ readonly CAPTURE_4: "4";
27
+ readonly CAPTURE_5: "5";
28
+ };
29
+ readonly MAX_LAYERS: number;
30
+ };
31
+ export declare const ATTR_FILTER: {
32
+ readonly NAME: "data-mirage-filter";
33
+ readonly KEY: "mirageFilter";
34
+ readonly VALUES: {
35
+ INCLUDE_TREE: string;
36
+ EXCLUDE_TREE: string;
37
+ INCLUDE_SELF: string;
38
+ EXCLUDE_SELF: string;
39
+ END: string;
40
+ };
41
+ };
42
+ export declare const ATTR_SELECT: {
43
+ readonly NAME: "data-mirage-select";
44
+ readonly KEY: "mirageSelect";
45
+ readonly VALUES: {
46
+ INCLUDE_TREE: string;
47
+ EXCLUDE_TREE: string;
48
+ INCLUDE_SELF: string;
49
+ EXCLUDE_SELF: string;
50
+ END: string;
51
+ };
52
+ };
53
+ export declare const ATTR_SHADER: {
54
+ readonly NAME: "data-mirage-shader";
55
+ readonly KEY: "mirageShader";
56
+ };
57
+ export declare const ATTR_SANDWICH: {
58
+ readonly NAME: "data-mirage-sandwich";
59
+ readonly KEY: "mirageSandwich";
60
+ readonly VALUES: {
61
+ readonly FRONT: "front";
62
+ };
63
+ };
@@ -16,9 +16,18 @@ export interface SceneNode {
16
16
  styles: BoxStyles;
17
17
  textContent?: string;
18
18
  textStyles?: TextStyles;
19
+ textLines?: {
20
+ text: string;
21
+ rect: NodeRect;
22
+ }[];
19
23
  dirtyMask: number;
20
24
  visibility: Visibility;
21
25
  isTraveler: boolean;
26
+ captureLayer: number;
27
+ nativeLayer?: number;
28
+ nativeStyles?: BoxStyles | TextStyles;
29
+ nativeRect?: NodeRect;
30
+ isFixed: boolean;
22
31
  shaderHooks?: ShaderHooks;
23
32
  children: SceneNode[];
24
33
  }