XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
namespace XFESystem.Browser;

/// <summary>Trusted, interpreter-executed Web API prototypes. Host objects only expose explicit primitive callbacks.</summary>
internal static class BrowserDomBootstrap
{
    // Syntax is reusable; each evaluation still creates fresh prototypes,
    // WeakMaps, closures and globals belonging to its engine.
    private static readonly Lazy<Jint.Prepared<Acornima.Ast.Script>> prepared = new(() =>
        Jint.Engine.PrepareScript(Source, "xfesystem:dom-bootstrap", strict: false,
            options: new Jint.ScriptPreparationOptions { FoldConstants = false }));
    internal static Jint.Prepared<Acornima.Ast.Script> Prepared => prepared.Value;
    internal static readonly Jint.Prepared<Acornima.Ast.Script> FlushJobs = Jint.Engine.PrepareScript("void 0");
    internal const string Source = """
        (function() {
          const listenerAdded=__xfeListenerAdded,listenerRemoved=__xfeListenerRemoved,eventError=__xfeEventError,observerAdded=__xfeObserverAdded;
          const parseDom=__xfeParseDom;delete window.__xfeParseDom;
          class DOMParser {parseFromString(source,type){if(arguments.length<2)throw new TypeError('parseFromString requires source and MIME type');return parseDom(String(source),String(type));}}window.DOMParser=DOMParser;
          const encoding=__xfeEncoding;delete window.__xfeEncoding;
          const cssom=__xfeCssom;delete window.__xfeCssom;
          const httpRequest=__xfeHttpRequest;delete window.__xfeHttpRequest;
          const cancelHttpRequest=__xfeHttpCancel;delete window.__xfeHttpCancel;
          const mediaMatches=__xfeMediaMatches;delete window.__xfeMediaMatches;
          delete window.__xfeListenerAdded;delete window.__xfeListenerRemoved;delete window.__xfeEventError;delete window.__xfeObserverAdded;
          const listeners = new WeakMap(), state = new WeakMap();
          function eventState(e) { const s=state.get(e); if(!s) throw new TypeError('Expected Event'); return s; }
          class Event {
            constructor(type, init={}) { this.type=String(type); this.bubbles=!!init.bubbles; this.cancelable=!!init.cancelable;
              this.composed=!!init.composed; this.isTrusted=false; this.timeStamp=performance.now();
              state.set(this,{target:null,current:null,phase:0,canceled:false,stop:false,immediate:false,passive:false,path:[],dispatching:false}); }
            get target(){return eventState(this).target;} get currentTarget(){return eventState(this).current;}
            get eventPhase(){return eventState(this).phase;} get defaultPrevented(){return eventState(this).canceled;}
            preventDefault(){const s=eventState(this);if(this.cancelable&&!s.passive)s.canceled=true;}
            stopPropagation(){eventState(this).stop=true;}
            stopImmediatePropagation(){const s=eventState(this);s.stop=s.immediate=true;}
            composedPath(){return eventState(this).path.slice();}
            get cancelBubble(){return eventState(this).stop;} set cancelBubble(v){if(v)this.stopPropagation();}
            get returnValue(){return !this.defaultPrevented;} set returnValue(v){if(!v)this.preventDefault();}
            initEvent(type,bubbles=false,cancelable=false){if(!eventState(this).dispatching){this.type=String(type);this.bubbles=!!bubbles;this.cancelable=!!cancelable;}}
          }
          Event.NONE=0;Event.CAPTURING_PHASE=1;Event.AT_TARGET=2;Event.BUBBLING_PHASE=3;
          class CustomEvent extends Event {constructor(type,init={}){super(type,init);this.detail=init.detail??null;}}
          class UIEvent extends Event {constructor(type,init={}){super(type,init);this.detail=init.detail??0;this.view=window;}}
          class MouseEvent extends UIEvent {constructor(type,init={}){super(type,init);for(const k of ['clientX','clientY','screenX','screenY','button','buttons','ctrlKey','shiftKey','altKey','metaKey'])this[k]=init[k]??0;
              this.x=this.clientX;this.y=this.clientY;this.pageX=this.clientX+(window.scrollX||0);this.pageY=this.clientY+(window.scrollY||0);this.offsetX=init.offsetX??this.clientX;this.offsetY=init.offsetY??this.clientY;this.relatedTarget=init.relatedTarget??null;}
            getModifierState(key){return !!this[{Control:'ctrlKey',Shift:'shiftKey',Alt:'altKey',Meta:'metaKey'}[key]];}}
          class PointerEvent extends MouseEvent {constructor(type,init={}){super(type,init);this.pointerId=init.pointerId??1;this.pointerType=init.pointerType??'mouse';this.isPrimary=true;this.width=this.height=1;this.pressure=this.buttons?.5:0;this.tiltX=this.tiltY=0;}}
          class WheelEvent extends MouseEvent {constructor(type,init={}){super(type,init);this.deltaX=init.deltaX??0;this.deltaY=init.deltaY??0;this.deltaMode=0;}}
          const physicalKeyCodes={Semicolon:186,Equal:187,Comma:188,Minus:189,Period:190,Slash:191,Backquote:192,BracketLeft:219,Backslash:220,BracketRight:221,Quote:222,
            NumpadMultiply:106,NumpadAdd:107,NumpadSubtract:109,NumpadDecimal:110,NumpadDivide:111,NumpadEnter:13,ShiftLeft:16,ShiftRight:16,ControlLeft:17,ControlRight:17,AltLeft:18,AltRight:18,MetaLeft:91,MetaRight:92,ContextMenu:93,CapsLock:20,NumLock:144,ScrollLock:145};
          class KeyboardEvent extends UIEvent {constructor(type,init={}){super(type,init);this.key=init.key??'';this.code=init.code??'';this.repeat=!!init.repeat;
              this.ctrlKey=!!init.ctrlKey;this.shiftKey=!!init.shiftKey;this.altKey=!!init.altKey;this.metaKey=!!init.metaKey;
              this.charCode=type==='keypress'&&this.key.length>0?this.key.codePointAt(0):0;
              const physical=/^Key[A-Z]$/.test(this.code)?this.code.charCodeAt(3):/^Digit[0-9]$/.test(this.code)?this.code.charCodeAt(5):/^Numpad[0-9]$/.test(this.code)?96+Number(this.code[6]):physicalKeyCodes[this.code];
              this.keyCode=init.keyCode??(type==='keypress'?this.charCode:physical??(this.key.length===1?this.key.toUpperCase().charCodeAt(0):({Enter:13,Escape:27,Backspace:8,Tab:9,ArrowLeft:37,ArrowUp:38,ArrowRight:39,ArrowDown:40,Delete:46,Home:36,End:35,Insert:45,PageUp:33,PageDown:34,Shift:16,Control:17,Alt:18,Meta:91,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123}[this.key]??0)));this.which=this.keyCode;this.location=0;this.isComposing=false;}
            getModifierState(key){return !!this[{Control:'ctrlKey',Shift:'shiftKey',Alt:'altKey',Meta:'metaKey'}[key]];}}
          class InputEvent extends UIEvent {constructor(type,init={}){super(type,init);this.data=init.data??null;this.inputType=init.inputType??'';this.isComposing=false;}}
          function forgetListener(listener){if(listener.removed)return;listener.removed=true;listenerRemoved();if(listener.signal&&listener.abort){remove.call(listener.signal,'abort',listener.abort);listener.abort=null;}}
          function add(type,callback,options=false){if(callback==null)return;if(typeof callback!=='function'&&typeof callback.handleEvent!=='function')throw new TypeError('Invalid listener');options=options??false;
            type=String(type);const capture=typeof options==='boolean'?options:!!options.capture;
            const signal=typeof options==='object'?options.signal:null;if(signal!=null&&!(signal instanceof AbortSignal))throw new TypeError('Expected AbortSignal');if(signal?.aborted)return;
            let list=listeners.get(this);if(!list)listeners.set(this,list=[]);else if(list.length>64)listeners.set(this,list=list.filter(x=>!x.removed));
            if(!list.some(x=>!x.removed&&x.type===type&&x.callback===callback&&x.capture===capture)){
              listenerAdded();const listener={type,callback,capture,once:!!options.once,passive:!!options.passive,removed:false,signal};list.push(listener);
              if(signal){listener.abort=()=>forgetListener(listener);try{signal.addEventListener('abort',listener.abort,{once:true});}catch(error){forgetListener(listener);throw error;}}}}
          function remove(type,callback,options=false){const list=listeners.get(this)||[],capture=typeof options==='boolean'?options:!!options.capture;
            for(const x of list)if(!x.removed&&x.type===String(type)&&x.callback===callback&&x.capture===capture)forgetListener(x);}
          function invoke(target,event,capture,phase){const s=eventState(event);s.current=target;s.phase=phase;
            for(const l of (listeners.get(target)||[]).slice()){
              if(s.immediate)break;if(l.removed||l.type!==event.type||l.capture!==capture)continue;
              if(l.once)forgetListener(l);s.passive=l.passive;
              try{if(typeof l.callback==='function')l.callback.call(target,event);else l.callback.handleEvent(event);}catch(error){eventError(String(error));}
              s.passive=false;
            }
            if(!capture&&!s.immediate){const handler=target['on'+event.type];if(typeof handler==='function'){
              try{if(handler.call(target,event)===false)event.preventDefault();}catch(error){eventError(String(error));}}}
          }
          function dispatch(event){const s=eventState(event);if(s.dispatching)throw new Error('Event is already dispatching');if(!event.type)throw new TypeError('Empty event type');
            s.dispatching=true;s.target=this;s.stop=s.immediate=false;s.path=[this];let parent=this.parentNode;
            if(event instanceof MouseEvent&&typeof this.getBoundingClientRect==='function'){const rect=this.getBoundingClientRect();event.offsetX=event.clientX-rect.left;event.offsetY=event.clientY-rect.top;}
            while(parent){s.path.push(parent);parent=parent.parentNode;}if(s.path[s.path.length-1]===document)s.path.push(window);
            try{
              for(let i=s.path.length-1;i>0&&!s.stop;i--)invoke(s.path[i],event,true,1);
              if(!s.stop){invoke(this,event,true,2);if(!s.immediate)invoke(this,event,false,2);}
              if(event.bubbles)for(let i=1;i<s.path.length&&!s.stop;i++)invoke(s.path[i],event,false,3);
            }finally{s.current=null;s.phase=0;s.dispatching=false;s.passive=false;}
            return !s.canceled;
          }
          class EventTarget {addEventListener(...a){return add.apply(this,a);}removeEventListener(...a){return remove.apply(this,a);}dispatchEvent(e){return dispatch.call(this,e);}}
        """ + BrowserDomAbort.Source + """
          function requestHeaderFields(input){const entries=input==null?[]:typeof input[Symbol.iterator]==='function'?Array.from(input):Object.entries(input),fields=new Map();
            if(entries.length>32)throw new RangeError('Request header count limit reached');let characters=0;
            for(const pair of entries){if(!pair||pair.length!==2)throw new TypeError('Expected a request header pair');const name=String(pair[0]).toLowerCase(),raw=String(pair[1]),value=raw.trim();
              if(!name||name.length>128||!Array.from(name).every(c=>/[a-z0-9]/i.test(c)||"!#$%&'*+-.^_`|~".includes(c))||raw.length>2048||Array.from(raw).some(c=>c.charCodeAt(0)<32&&c!=='\t'||c.charCodeAt(0)===127||c.charCodeAt(0)>255))throw new DOMException('Invalid request header','SyntaxError');
              characters+=name.length+value.length;if(characters>8192)throw new RangeError('Request header character limit reached');fields.set(name,fields.has(name)?fields.get(name)+', '+value:value);}
            return Array.from(fields);}
          class XMLHttpRequest extends EventTarget {
            constructor(){super();this.readyState=0;this.status=0;this.statusText='';this.responseText='';this.responseURL='';this.responseType='';this.timeout=0;this.withCredentials=false;this._generation=0;}
            open(method,url,async=true){if(async===false)throw new TypeError('Synchronous XMLHttpRequest is unavailable');if(this._requestId)cancelHttpRequest(this._requestId);this._requestId=0;this._headers=[];this._method=String(method).toUpperCase();this._url=String(url);this._generation++;this.readyState=1;this.dispatchEvent(new Event('readystatechange'));}
            setRequestHeader(name,value){if(this.readyState!==1)throw new DOMException('Request is not open','InvalidStateError');this._headers=requestHeaderFields(this._headers.concat([[name,value]]));}
            getResponseHeader(name){return String(name).toLowerCase()==='content-type'?this._contentType||null:null;}
            getAllResponseHeaders(){return this._contentType?'content-type: '+this._contentType+'\r\n':'';}
            overrideMimeType(type){this._mime=String(type);}
            abort(){if(this._requestId)cancelHttpRequest(this._requestId);this._requestId=0;this._generation++;this.readyState=0;this.status=0;this.dispatchEvent(new Event('abort'));this.dispatchEvent(new Event('loadend'));}
            send(body=null){if(this.readyState!==1)throw new Error('InvalidStateError');const generation=this._generation;
              const complete=(reply,error)=>{if(generation!==this._generation)return;this._requestId=0;this.status=reply?.status||0;this.responseURL=reply?.url||'';this._contentType=reply?.contentType||'';
                this.readyState=2;this.dispatchEvent(new Event('readystatechange'));this.responseText=reply?.text||'';this.readyState=3;this.dispatchEvent(new Event('readystatechange'));
                this.response=this.responseType==='json'?(()=>{try{return JSON.parse(this.responseText);}catch{return null;}})():this.responseText;
                this.readyState=4;this.dispatchEvent(new Event('readystatechange'));this.dispatchEvent(new Event(error?'error':'load'));this.dispatchEvent(new Event('loadend'));};
              if(this._method!=='GET'){setTimeout(()=>complete(null,'Only GET requests are supported'),0);return;}this._requestId=httpRequest(this._url,complete,this._headers);}
          }
          Object.assign(XMLHttpRequest,{UNSENT:0,OPENED:1,HEADERS_RECEIVED:2,LOADING:3,DONE:4});window.XMLHttpRequest=XMLHttpRequest;
          window.fetch=function(url,options={}){return new Promise((resolve,reject)=>{if(options.method&&String(options.method).toUpperCase()!=='GET'){reject(new TypeError('Only GET fetch is supported'));return;}
            const signal=options.signal;if(signal!=null&&!(signal instanceof AbortSignal)){reject(new TypeError('Expected AbortSignal'));return;}if(signal?.aborted){reject(signal.reason);return;}
            let settled=false,requestId=0;const aborted=()=>{if(settled)return;settled=true;if(requestId)cancelHttpRequest(requestId);reject(signal.reason);};if(signal)signal.addEventListener('abort',aborted,{once:true});
            requestId=httpRequest(String(url),(reply,error)=>{if(settled)return;settled=true;if(signal)signal.removeEventListener('abort',aborted);if(error){reject(new TypeError(error));return;}resolve({ok:reply.status>=200&&reply.status<300,status:reply.status,url:reply.url,
              headers:{get(name){return String(name).toLowerCase()==='content-type'?reply.contentType:null;}},text(){return Promise.resolve(reply.text);},json(){return Promise.resolve().then(()=>JSON.parse(reply.text));}});},requestHeaderFields(options.headers));if(settled)cancelHttpRequest(requestId);});};
          class Node extends EventTarget {} class Element extends Node {}
        """ + BrowserDomCustomElements.Source + """
          class Document extends Node {} class DocumentFragment extends Node {} class Text extends Node {}
          class Comment extends Node {}
          class NodeFilter {constructor(){throw new TypeError('Illegal constructor');}}
          const filterConstants={FILTER_ACCEPT:1,FILTER_REJECT:2,FILTER_SKIP:3,SHOW_ALL:4294967295,SHOW_ELEMENT:1,SHOW_ATTRIBUTE:2,SHOW_TEXT:4,SHOW_CDATA_SECTION:8,SHOW_ENTITY_REFERENCE:16,SHOW_ENTITY:32,SHOW_PROCESSING_INSTRUCTION:64,SHOW_COMMENT:128,SHOW_DOCUMENT:256,SHOW_DOCUMENT_TYPE:512,SHOW_DOCUMENT_FRAGMENT:1024,SHOW_NOTATION:2048};
          for(const [name,value] of Object.entries(filterConstants)){Object.defineProperty(NodeFilter,name,{value,enumerable:true});Object.defineProperty(NodeFilter.prototype,name,{value,enumerable:true});}
          class TreeWalker {constructor(){throw new TypeError('Illegal constructor');}}
          Object.assign(window,{NodeFilter,TreeWalker});
          const htmlElements={};
          for(const [tag,name] of Object.entries({a:'HTMLAnchorElement',area:'HTMLAreaElement',body:'HTMLBodyElement',button:'HTMLButtonElement',canvas:'HTMLCanvasElement',div:'HTMLDivElement',form:'HTMLFormElement',head:'HTMLHeadElement',html:'HTMLHtmlElement',iframe:'HTMLIFrameElement',img:'HTMLImageElement',input:'HTMLInputElement',label:'HTMLLabelElement',link:'HTMLLinkElement',meta:'HTMLMetaElement',option:'HTMLOptionElement',script:'HTMLScriptElement',select:'HTMLSelectElement',span:'HTMLSpanElement',style:'HTMLStyleElement',textarea:'HTMLTextAreaElement',video:'HTMLVideoElement'})){
            const constructor=class extends HTMLElement{};Object.defineProperty(constructor,'name',{value:name});window[name]=constructor;htmlElements[tag]=constructor;}
          function Image(width,height){const image=document.createElement('img');if(width!==undefined)image.setAttribute('width',width);if(height!==undefined)image.setAttribute('height',height);return image;}
          window.Image=Image;
          htmlElements.img.prototype.decode=function(){const image=this,source=image.src;
            return new Promise((resolve,reject)=>{
              function failed(){const error=new Error('The image could not be decoded');error.name='EncodingError';return error;}
              function cleanup(){image.removeEventListener('load',finish);image.removeEventListener('error',finish);}
              function finish(){cleanup();queueMicrotask(()=>{if(image.src===source&&image.complete&&image.naturalWidth>0)resolve();else reject(failed());});}
              if(image.complete){finish();return;}
              image.addEventListener('load',finish);image.addEventListener('error',finish);image.__decodeImage();
            });};
          Node.ELEMENT_NODE=1;Node.TEXT_NODE=3;Node.COMMENT_NODE=8;Node.DOCUMENT_NODE=9;Node.DOCUMENT_FRAGMENT_NODE=11;
          Object.assign(Node.prototype,{ELEMENT_NODE:1,TEXT_NODE:3,COMMENT_NODE:8,DOCUMENT_NODE:9,DOCUMENT_FRAGMENT_NODE:11});
          Object.assign(window,{Event,CustomEvent,UIEvent,MouseEvent,PointerEvent,WheelEvent,KeyboardEvent,InputEvent,EventTarget,Node,Element,HTMLElement,Document,DocumentFragment,Text,Comment});
          window.addEventListener=add;window.removeEventListener=remove;window.dispatchEvent=dispatch;
          const observers=new Set();
          class MutationObserver {
            constructor(callback){if(typeof callback!=='function')throw new TypeError('Expected callback');this.callback=callback;this.targets=[];this.records=[];this.queued=false;}
            observe(target,options){if(!target||!options||(!options.childList&&!options.attributes&&!options.characterData))throw new TypeError('Invalid observer options');
              if(!observers.has(this))observerAdded(observers.size+1);const existing=this.targets.find(x=>x.target===target);
              if(existing){existing.options=options;return;}if(this.targets.length>=1024)throw new Error('Mutation observer target limit reached');this.targets.push({target,options});observers.add(this);}
            disconnect(){observers.delete(this);this.targets=[];this.records=[];}
            takeRecords(){const records=this.records;this.records=[];return records;}
          }
          window.MutationObserver=MutationObserver;
          const resizeObservers=new Set();let resizeQueued=false;
          function notifyResize(){if(resizeQueued||resizeObservers.size===0)return;resizeQueued=true;requestAnimationFrame(function(){resizeQueued=false;
            for(const observer of Array.from(resizeObservers)){const entries=[];
              for(const observed of observer.targets){const rect=observed.target.getBoundingClientRect();
                if(observed.width===rect.width&&observed.height===rect.height)continue;observed.width=rect.width;observed.height=rect.height;
                const css=getComputedStyle(observed.target),edge=name=>parseFloat(css.getPropertyValue(name))||0;
                const px=edge('padding-left'),py=edge('padding-top'),width=Math.max(0,rect.width-px-edge('padding-right')-edge('border-left-width')-edge('border-right-width')),
                  height=Math.max(0,rect.height-py-edge('padding-bottom')-edge('border-top-width')-edge('border-bottom-width'));
                const size={inlineSize:width,blockSize:height};entries.push({target:observed.target,contentRect:{x:px,y:py,left:px,top:py,right:px+width,bottom:py+height,width,height},contentBoxSize:[size],borderBoxSize:[{inlineSize:rect.width,blockSize:rect.height}],devicePixelContentBoxSize:[size]});}
              if(entries.length)observer.callback(entries,observer);
            }
          });}
          class ResizeObserver {
            constructor(callback){if(typeof callback!=='function')throw new TypeError('Expected callback');this.callback=callback;this.targets=[];}
            observe(target){if(!target||typeof target.getBoundingClientRect!=='function')throw new TypeError('Expected Element');
              if(this.targets.some(x=>x.target===target))return;if(this.targets.length>=1024)throw new Error('Resize observer target limit reached');
              if(!resizeObservers.has(this))observerAdded(resizeObservers.size+1);this.targets.push({target,width:null,height:null});resizeObservers.add(this);notifyResize();}
            unobserve(target){this.targets=this.targets.filter(x=>x.target!==target);if(!this.targets.length)resizeObservers.delete(this);}
            disconnect(){this.targets=[];resizeObservers.delete(this);}
          }
          window.ResizeObserver=ResizeObserver;
          function mutation(target,type,name,oldValue,added,removed){customMutation(target,type,name,oldValue,added,removed);for(const observer of observers){
            if(!observer.targets.some(x=>(x.target===target||(x.options.subtree&&x.target.contains(target)))&&!!x.options[type]))continue;
            if(observer.records.length>=1024)throw new Error('Mutation record limit reached');
            observer.records.push({type,target,attributeName:name,oldValue,addedNodes:added||[],removedNodes:removed||[]});
            if(!observer.queued){observer.queued=true;queueMicrotask(function(){observer.queued=false;const records=observer.takeRecords();if(records.length)observer.callback(records,observer);});}
          }notifyResize();}
          function list(array){Object.defineProperty(array,'item',{value:function(i){return this[i]??null;}});Object.defineProperty(array,'namedItem',{value:function(name){return this.find(e=>e.id===name||e.getAttribute?.('name')===name)??null;}});return array;}
        """ + BrowserDomCollections.Source + """
          function style(node){return new Proxy({getPropertyValue(name){return node.__styleGet(String(name));},setProperty(name,value,priority=''){node.__styleSet(String(name),String(value),String(priority));},
            removeProperty(name){const old=node.__styleGet(String(name));node.__styleSet(String(name),'','');return old;},
            get cssText(){return node.getAttribute('style')||'';},set cssText(value){node.setAttribute('style',String(value));}},
            {get(target,name){if(typeof name==='symbol'||name in target)return target[name];return node.__styleGet(String(name).replace(/[A-Z]/g,x=>'-'+x.toLowerCase()));},
              set(target,name,value){if(name in target){target[name]=value;return true;}node.__styleSet(String(name).replace(/[A-Z]/g,x=>'-'+x.toLowerCase()),String(value),'');return true;}});}
          function classList(node){function tokens(){return (node.className||'').trim().split(/\s+/).filter(Boolean);}function put(t){node.className=t.join(' ');}
            return {contains(token){return tokens().includes(String(token));},add(...a){const t=tokens();for(const v of a){if(!v||/\s/.test(v))throw new Error('Invalid class token');if(!t.includes(String(v)))t.push(String(v));}put(t);},
              remove(...a){put(tokens().filter(v=>!a.includes(v)));},toggle(token,force){const exists=this.contains(token),want=force===undefined?!exists:!!force;if(want)this.add(token);else this.remove(token);return want;},
              replace(oldValue,newValue){const t=tokens(),i=t.indexOf(oldValue);if(i<0)return false;t[i]=newValue;put(t);return true;},item(i){return tokens()[i]??null;},
              get length(){return tokens().length;},get value(){return node.className;},set value(v){node.className=String(v);},toString(){return node.className;},[Symbol.iterator](){return tokens()[Symbol.iterator]();}};}
          class DOMStringMap {constructor(){throw new TypeError('Illegal constructor');}}
          Object.defineProperty(DOMStringMap.prototype,Symbol.toStringTag,{value:'DOMStringMap',configurable:true});
          window.DOMStringMap=DOMStringMap;
          const sheetStates=new WeakMap();
          class CSSRule {constructor(text){Object.defineProperty(this,'cssText',{get(){return text;},enumerable:true});Object.defineProperty(this,'type',{value:text.startsWith('@')?0:1,enumerable:true});} }
          Object.assign(CSSRule,{STYLE_RULE:1,IMPORT_RULE:3,MEDIA_RULE:4,FONT_FACE_RULE:5,PAGE_RULE:6,KEYFRAMES_RULE:7,KEYFRAME_RULE:8,SUPPORTS_RULE:12});
          class CSSStyleSheet {
            constructor(){const id=cssom.create(),rules=liveList(()=>cssom.rules(id).map(text=>new CSSRule(text)),'CSSRuleList');sheetStates.set(this,{id,rules});this.disabled=false;}
            get cssRules(){return sheetStates.get(this).rules;}
            get rules(){return this.cssRules;}
            get ownerNode(){return null;}get parentStyleSheet(){return null;}get href(){return null;}
            insertRule(rule,index=0){return cssom.insert(sheetStates.get(this).id,String(rule),Number(index));}
            deleteRule(index){cssom.delete(sheetStates.get(this).id,Number(index));}
            replaceSync(text){cssom.replace(sheetStates.get(this).id,String(text));}
            replace(text){return Promise.resolve().then(()=>{this.replaceSync(text);return this;});}
          }
          window.CSSStyleSheet=CSSStyleSheet;window.CSSRule=CSSRule;
          function dataset(node){
            const attribute=key=>'data-'+String(key).replace(/[A-Z]/g,c=>'-'+c.toLowerCase());
            const names=()=>Array.from(node.attributes).map(a=>a.name).filter(n=>n.startsWith('data-')&&!/[A-Z]/.test(n))
              .map(n=>n.slice(5).replace(/-([a-z])/g,(_,c)=>c.toUpperCase()));
            const put=(key,value)=>{if(typeof key!=='string')return false;if(/-[a-z]/.test(key)){const error=new Error('A dataset property may not contain a hyphen followed by a lowercase letter');error.name='SyntaxError';throw error;}
              node.setAttribute(attribute(key),String(value));return true;};
            return new Proxy(Object.create(DOMStringMap.prototype),{
              get(target,key,receiver){if(typeof key==='string'){const value=node.getAttribute(attribute(key));if(value!==null)return value;}return Reflect.get(target,key,receiver);},
              set(target,key,value){return put(key,value);},
              has(target,key){return typeof key==='string'&&node.hasAttribute(attribute(key))||Reflect.has(target,key);},
              ownKeys(){return names();},
              getOwnPropertyDescriptor(target,key){if(typeof key==='string'&&node.hasAttribute(attribute(key)))return {value:node.getAttribute(attribute(key)),writable:true,enumerable:true,configurable:true};return Reflect.getOwnPropertyDescriptor(target,key);},
              defineProperty(target,key,descriptor){if(descriptor.get||descriptor.set||descriptor.configurable===false||descriptor.enumerable===false||descriptor.writable===false)return false;return put(key,descriptor.value);},
              deleteProperty(target,key){if(typeof key==='string')node.removeAttribute(attribute(key));return true;}
            });}
          function init(node,type,tag){Object.setPrototypeOf(node,type===9?Document.prototype:type===11?DocumentFragment.prototype:type===3?Text.prototype:type===8?Comment.prototype:(htmlElements[tag]||HTMLElement).prototype);
            if(type===1){Object.defineProperty(node,'style',{value:style(node)});Object.defineProperty(node,'classList',{value:classList(node)});Object.defineProperty(node,'dataset',{value:dataset(node)});}
            return node;}
          function computed(node){return new Proxy({getPropertyValue(name){return node.__computed(String(name));}},
            {get(target,name){if(typeof name==='symbol'||name in target)return target[name];return node.__computed(String(name).replace(/[A-Z]/g,x=>'-'+x.toLowerCase()));}});}
          window.getComputedStyle=computed;
          const mediaLists=[],mediaListToken={},mediaListStates=new WeakMap();
          class MediaQueryList extends EventTarget {
            constructor(token,query){super();if(token!==mediaListToken)throw new TypeError('Illegal constructor');Object.defineProperty(this,'media',{value:String(query),enumerable:true});this.onchange=null;mediaListStates.set(this,mediaMatches(this.media));}
            get matches(){return mediaMatches(this.media);}addListener(callback){this.addEventListener('change',callback);}removeListener(callback){this.removeEventListener('change',callback);}
          }
          class MediaQueryListEvent extends Event {constructor(type,init={}){super(type,init);this.matches=!!init.matches;this.media=String(init.media??'');}}
          window.MediaQueryList=MediaQueryList;window.MediaQueryListEvent=MediaQueryListEvent;
          window.matchMedia=function(query){if(mediaLists.length>=128)throw new Error('Media query list limit reached');const value=new MediaQueryList(mediaListToken,query);mediaLists.push(value);return value;};
          window.addEventListener('resize',function(){for(const value of mediaLists){const matches=value.matches;if(matches!==mediaListStates.get(value)){mediaListStates.set(value,matches);value.dispatchEvent(new MediaQueryListEvent('change',{matches,media:value.media}));}}});
          window.CSS={supports:function(){return false;},escape:function(value){return String(value).replace(/[^a-zA-Z0-9_-]/g,c=>'\\'+c.codePointAt(0).toString(16)+' ');}};
          class TextEncoder {get encoding(){return 'utf-8';}encode(value=''){return encoding.encode(String(value));}
            encodeInto(value,destination){if(!(destination instanceof Uint8Array))throw new TypeError('Expected Uint8Array');let read=0,written=0;
              for(const character of String(value)){const bytes=this.encode(character);if(written+bytes.length>destination.length)break;destination.set(bytes,written);written+=bytes.length;read+=character.length;}return {read,written};}}
          class TextDecoder {constructor(label='utf-8',options={}){label=String(label).trim().toLowerCase();const names={'utf-8':'utf-8',utf8:'utf-8','unicode-1-1-utf-8':'utf-8','utf-16':'utf-16le','utf-16le':'utf-16le','utf-16be':'utf-16be'};
              if(!Object.hasOwn(names,label))throw new RangeError('Only UTF-8 and UTF-16 decoding are supported');this.encoding=names[label];this.fatal=!!options.fatal;this.ignoreBOM=!!options.ignoreBOM;this.id=encoding.decoder(this.fatal,this.ignoreBOM,this.encoding);}
            decode(value,options={}){return encoding.decode(this.id,value,!!options.stream);}}
          window.TextEncoder=TextEncoder;window.TextDecoder=TextDecoder;
          window.btoa=function(value){if(arguments.length<1)throw new TypeError('btoa requires an argument');return encoding.btoa(String(value));};
          window.atob=function(value){if(arguments.length<1)throw new TypeError('atob requires an argument');return encoding.atob(String(value));};
          if(typeof encoding.random==='function')window.crypto={getRandomValues(array){
            if(!ArrayBuffer.isView(array)||array instanceof Float32Array||array instanceof Float64Array||array instanceof DataView)throw new TypeError('Expected an integer typed array');
            if(array.byteLength>65536){const error=new Error('Random request exceeds 65536 bytes');error.name='QuotaExceededError';throw error;}
            encoding.random(new Uint8Array(array.buffer,array.byteOffset,array.byteLength));return array;},
            randomUUID(){const bytes=this.getRandomValues(new Uint8Array(16));bytes[6]=(bytes[6]&15)|64;bytes[8]=(bytes[8]&63)|128;
              const hex=Array.from(bytes,b=>b.toString(16).padStart(2,'0')).join('');return hex.slice(0,8)+'-'+hex.slice(8,12)+'-'+hex.slice(12,16)+'-'+hex.slice(16,20)+'-'+hex.slice(20);}};
          return {init,list,nodeList,liveList,mutation,notifyResize,upgrade:upgradeCustomElement,initTreeWalker(value){Object.setPrototypeOf(value,TreeWalker.prototype);},filterNode(filter,node){return Number(typeof filter==='function'?filter(node):filter.acceptNode(node))>>>0&65535;},configureWindow(){navigator.serviceWorker=Object.assign(new EventTarget(),{controller:null,getRegistration(){return Promise.resolve(undefined);},getRegistrations(){return Promise.resolve([]);},register(){return Promise.reject(new TypeError('Service workers are unavailable'));}});},pixelArray:function(length){return new Uint8ClampedArray(length);},byteArray:function(length){return new Uint8Array(length);},bytesOf:function(value){
            if(value===undefined)return new Uint8Array(0);if(ArrayBuffer.isView(value))return new Uint8Array(value.buffer,value.byteOffset,value.byteLength);if(value instanceof ArrayBuffer)return new Uint8Array(value);throw new TypeError('Expected ArrayBuffer or view');},
            dispatch:function(target,event){const result=dispatch.call(target,event);if(event.type==='resize'||event.type==='load')notifyResize();return result;},event:function(type,init){
            const ctor=/^key/.test(type)?KeyboardEvent:/^(input|beforeinput)$/.test(type)?InputEvent:type==='wheel'?WheelEvent:/^pointer/.test(type)?PointerEvent:/^(mouse|click|dblclick|contextmenu)/.test(type)?MouseEvent:Event;
            return new ctor(type,init);}};
        })()
        """;
}