pulse-ui-client 0.1.38 → 0.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -222,7 +222,7 @@ declare function PulseView({
|
|
|
222
222
|
externalComponents,
|
|
223
223
|
path,
|
|
224
224
|
cssModules
|
|
225
|
-
}: PulseViewProps): string | number | bigint | boolean |
|
|
225
|
+
}: PulseViewProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react0.ReactPortal | react0.ReactElement<unknown, string | react0.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react_jsx_runtime0.JSX.Element | null | undefined;
|
|
226
226
|
//#endregion
|
|
227
227
|
//#region src/client.d.ts
|
|
228
228
|
interface SocketIODirectives {
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e,{Fragment as t,Suspense as n,cloneElement as r,createContext as i,createElement as a,forwardRef as o,isValidElement as s,lazy as c,useCallback as l,useContext as u,useEffect as d,useMemo as f,useRef as p,useState as m}from"react";import{jsx as h,jsxs as g}from"react/jsx-runtime";import{useLocation as ee,useNavigate as _,useParams as te}from"react-router";import{io as v}from"socket.io-client";var y=class extends Error{constructor(e){super(e),this.name=`PulseChannelResetError`}};function ne(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID().replace(/-/g,``):Math.random().toString(16).slice(2)+Math.random().toString(16).slice(2)}function re(e){if(e instanceof Error)return e.message;if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}function ie(e){return typeof e.responseTo==`string`}function ae(e){return typeof e.event==`string`}var oe=class{handlers=new Map;pending=new Map;backlog=[];closed=!1;constructor(e,t){this.client=e,this.id=t}emit(e,t){this.ensureOpen(),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t})}request(e,t){this.ensureOpen();let n=ne();return new Promise((r,i)=>{this.pending.set(n,{resolve:r,reject:i}),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t,requestId:n})})}on(e,t){this.ensureOpen();let n=this.handlers.get(e);return n||(n=new Set,this.handlers.set(e,n)),n.add(t),this.flushBacklog(e),()=>{let n=this.handlers.get(e);n&&(n.delete(t),n.size===0&&this.handlers.delete(e))}}handleServerMessage(e){return ie(e)?(this.resolvePending(e),this.closed):this.closed?!0:ae(e)?e.event===`__close__`?(this.close(new y(`Channel closed by server`)),!0):(e.requestId?this.dispatchRequest(e):this.dispatchEvent(e),this.closed):this.closed}handleDisconnect(e){this.close(e)}dispose(e){this.close(e)}ensureOpen(){if(this.closed)throw new y(`Channel is closed`)}flushBacklog(e){if(this.backlog.length===0)return;let t=[];for(let n of this.backlog)n.event===e?this.dispatchEvent(n):t.push(n);this.backlog=t}dispatchEvent(e){let t=this.handlers.get(e.event);if(!t||t.size===0){this.backlog.push(e);return}for(let n of t)try{let t=n(e.payload);t&&typeof t.then==`function`&&t.catch(e=>{console.error(`Pulse channel handler error`,e)})}catch(e){console.error(`Pulse channel handler error`,e)}}async dispatchRequest(e){let t=this.handlers.get(e.event),n,r;if(t&&t.size>0)for(let i of t)try{let t=i(e.payload);if(n=await Promise.resolve(t),n!==void 0)break}catch(e){r=e;break}if(r){this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,error:re(r)});return}this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,payload:n})}resolvePending(e){let t=e.responseTo?this.pending.get(e.responseTo):void 0;t&&(this.pending.delete(e.responseTo),e.error!==void 0&&e.error!==null?t.reject(new y(String(e.error))):t.resolve(e.payload))}close(e){if(!this.closed){this.closed=!0;for(let t of this.pending.values())t.reject(e);this.pending.clear(),this.handlers.clear(),this.backlog=[]}}};function se(e,t){return new oe(e,t)}const ce=o(function({onSubmit:e,action:t,...n},r){return h(`form`,{...n,action:t,ref:r,onSubmit:l(n=>b({event:n,action:t,onSubmit:e}),[t,e])})});async function b({event:e,action:t,onSubmit:n,formData:r,force:i}){if(n?.(e),!i&&e.defaultPrevented)return;let a=e.currentTarget;e.preventDefault();let o=e.nativeEvent;r||=new FormData(a,o.submitter);let s=new URL(t,window.location.href);try{await fetch(s,{method:`POST`,credentials:`include`,body:r})}catch(e){if(process.env.NODE_ENV!==`production`)console.error(`[Pulse] Form submission failed`,e);else throw e}}function le({params:e,request:t}){let{"*":n=``,...r}=e,i=new URL(t.url);return{hash:i.hash,pathname:i.pathname,query:i.search,queryParams:Object.fromEntries(i.searchParams.entries()),pathParams:r,catchall:n.length>1?n.split(`/`):[]}}function x(){function e(e,t){return n=>{let r={};for(let t of e)r[t]=n[t];if(t)for(let e in t){let i=t[e];r[e]=i(n)}return r}}return e}const ue=e=>e.tagName.toLowerCase(),de=[`id`,`className`,`tagName`,`localName`,`clientHeight`,`clientLeft`,`clientTop`,`clientWidth`,`scrollHeight`,`scrollLeft`,`scrollTop`,`scrollWidth`,`slot`],fe=[`autofocus`,`tabIndex`,`nonce`],pe=[`accessKey`,`accessKeyLabel`,`autocapitalize`,`dir`,`draggable`,`hidden`,`inert`,`lang`,`offsetHeight`,`offsetLeft`,`offsetTop`,`offsetWidth`,`popover`,`spellcheck`,`title`,`translate`,`writingSuggestions`,`contentEditable`,`enterKeyHint`,`isContentEditable`,`inputMode`],me=x()(de,{tagName:ue}),he=x()(fe),ge=x()(pe);function S(e){return{...me(e),...he(e),...ge(e)}}function C(e,t){let n=x()(e,t);return e=>({...S(e),...n(e)})}const _e=C([`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`search`,`target`,`download`,`rel`,`hreflang`,`type`,`username`,`ping`,`referrerPolicy`,`text`]),ve=C([`alt`,`coords`,`download`,`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`rel`,`search`,`shape`,`target`,`username`,`ping`,`referrerPolicy`]),w=C([`autoplay`,`controls`,`crossOrigin`,`currentSrc`,`currentTime`,`defaultMuted`,`defaultPlaybackRate`,`duration`,`ended`,`loop`,`muted`,`networkState`,`paused`,`playbackRate`,`preload`,`readyState`,`seeking`,`src`,`volume`,`preservesPitch`]),ye=e=>w(e),be=C([`disabled`,`name`,`type`,`value`,`formAction`,`formEnctype`,`formMethod`,`formNoValidate`,`formTarget`,`popoverTargetAction`]),xe=C([`value`]),Se=C([`height`,`src`,`type`,`width`,`align`,`name`]),Ce=C([`disabled`,`name`,`type`,`validationMessage`,`willValidate`]),we=C([`acceptCharset`,`action`,`autocomplete`,`encoding`,`enctype`,`length`,`method`,`name`,`noValidate`,`target`,`rel`]),T=C([`allow`,`allowFullscreen`,`height`,`name`,`referrerPolicy`,`src`,`srcdoc`,`width`,`align`,`frameBorder`,`longDesc`,`marginHeight`,`marginWidth`,`scrolling`,`sandbox`]),E=C([`alt`,`crossOrigin`,`decoding`,`height`,`isMap`,`loading`,`naturalHeight`,`naturalWidth`,`referrerPolicy`,`sizes`,`src`,`srcset`,`useMap`,`width`,`align`,`border`,`complete`,`hspace`,`longDesc`,`lowsrc`,`name`,`vspace`,`x`,`y`,`fetchPriority`]),D=C(`accept.alt.autocomplete.checked.defaultChecked.defaultValue.dirName.disabled.height.indeterminate.max.maxLength.min.minLength.multiple.name.pattern.placeholder.readOnly.required.selectionDirection.selectionEnd.selectionStart.size.src.step.type.value.valueAsNumber.width.align.capture.formAction.formEnctype.formMethod.formNoValidate.formTarget.useMap.validationMessage.willValidate.popoverTargetAction`.split(`.`)),O=C([`htmlFor`]),k=C([`value`,`type`]),Te=C([`as`,`crossOrigin`,`disabled`,`fetchPriority`,`href`,`hreflang`,`imageSizes`,`imageSrcset`,`integrity`,`media`,`referrerPolicy`,`rel`,`type`,`charset`,`rev`,`target`,`sizes`]),Ee=C([`name`]),De=C([`high`,`low`,`max`,`min`,`optimum`,`value`]),A=C([`cite`,`dateTime`]),Oe=C([`reversed`,`start`,`type`,`compact`]),ke=C([`data`,`height`,`name`,`type`,`useMap`,`width`,`validationMessage`,`willValidate`,`align`,`archive`,`border`,`code`,`codeBase`,`codeType`,`declare`,`hspace`,`standby`,`vspace`]),Ae=C([`disabled`,`label`]),je=C([`defaultSelected`,`disabled`,`index`,`label`,`selected`,`text`,`value`]),Me=C([`defaultValue`,`name`,`type`,`value`,`htmlFor`,`validationMessage`,`willValidate`]),Ne=C([`max`,`position`,`value`]),j=C([`cite`]),Pe=e=>S(e),Fe=x()([`async`,`crossOrigin`,`defer`,`fetchPriority`,`integrity`,`noModule`,`referrerPolicy`,`src`,`text`,`type`,`charset`],{event:e=>e.event,htmlFor:e=>e.htmlFor}),Ie=e=>({...S(e),...Fe(e)}),Le=C([`autocomplete`,`disabled`,`length`,`multiple`,`name`,`required`,`selectedIndex`,`size`,`type`,`value`,`validationMessage`,`willValidate`]),Re=C([`name`]),ze=C([`height`,`media`,`sizes`,`src`,`srcset`,`type`,`width`]),Be=C([`align`]),M=C([`abbr`,`cellIndex`,`colSpan`,`headers`,`rowSpan`,`scope`,`align`,`axis`,`bgColor`,`ch`,`chOff`,`height`,`noWrap`,`vAlign`,`width`]),N=C([`span`,`align`,`ch`,`chOff`,`vAlign`,`width`]),Ve=C([`align`,`bgColor`,`border`,`cellPadding`,`cellSpacing`,`frame`,`rules`,`summary`,`width`]),He=C([`rowIndex`,`sectionRowIndex`,`align`,`bgColor`,`ch`,`chOff`,`vAlign`]),P=C([`align`,`ch`,`chOff`,`vAlign`]),Ue=e=>S(e),We=C([`autocomplete`,`cols`,`defaultValue`,`dirName`,`disabled`,`maxLength`,`minLength`,`name`,`placeholder`,`readOnly`,`required`,`rows`,`selectionDirection`,`selectionEnd`,`selectionStart`,`value`,`wrap`,`textLength`,`validationMessage`,`willValidate`]),Ge=C([`dateTime`]),Ke=C([`default`,`kind`,`label`,`readyState`,`src`,`srclang`]),qe=x()([`height`,`poster`,`videoHeight`,`videoWidth`,`width`,`playsInline`]),Je=e=>({...w(e),...qe(e)}),Ye=C([`clear`]),Xe=C([`href`,`target`]),Ze=C([`aLink`,`background`,`bgColor`,`link`,`text`,`vLink`]),Qe=C([`compact`]),$e=C([`open`]),et=C([`open`,`returnValue`]),F=C([`align`]),tt=e=>S(e),I=C([`align`]),nt={A:_e,AREA:ve,AUDIO:ye,BASE:Xe,BLOCKQUOTE:j,Q:j,BODY:Ze,BR:Ye,BUTTON:be,CANVAS:S,CAPTION:Be,CITE:Pe,COL:N,COLGROUP:N,DATA:xe,DETAILS:$e,DIALOG:et,DIV:F,DL:Qe,EMBED:Se,FIELDSET:Ce,FORM:we,H1:I,H2:I,H3:I,H4:I,H5:I,H6:I,HEAD:tt,HR:C([`align`,`color`,`noShade`,`size`,`width`]),HTML:C([`version`]),IFRAME:T,IMG:E,INPUT:D,LABEL:O,LI:k,LINK:Te,MAP:Ee,MENU:e=>S(e),META:C([`content`,`httpEquiv`,`name`,`scheme`]),METER:De,INS:A,DEL:A,OBJECT:ke,OL:Oe,OPTGROUP:Ae,OPTION:je,OUTPUT:Me,P:C([`align`]),PICTURE:e=>S(e),PRE:C([`width`]),PROGRESS:Ne,SCRIPT:Ie,SELECT:Le,SLOT:Re,SOURCE:ze,SPAN:e=>S(e),STYLE:C([`media`,`type`,`disabled`]),TABLE:Ve,TBODY:P,THEAD:P,TFOOT:P,TD:M,TH:M,TEMPLATE:Ue,TEXTAREA:We,TIME:Ge,TITLE:C([`text`]),TR:He,TRACK:Ke,UL:C([`compact`,`type`]),VIDEO:Je};function L(e){let t=nt[e.tagName.toUpperCase()];if(t)return t(e);throw Error(`Unexpected HTML element tag: ${e.tagName} (update .web/custom/serialize.ts)`)}const rt=e=>L(e.target),R=e=>e.relatedTarget?L(e.relatedTarget):null;function z(e,t){return x()(e,{target:rt,...t||{}})}const B=[`target`,`bubbles`,`cancelable`,`defaultPrevented`,`eventPhase`,`isTrusted`,`timeStamp`,`type`],V=[...B,`detail`],H=[...V,`altKey`,`button`,`buttons`,`clientX`,`clientY`,`ctrlKey`,`metaKey`,`movementX`,`movementY`,`pageX`,`pageY`,`screenX`,`screenY`,`shiftKey`],it=[...H,`pointerId`,`pressure`,`tangentialPressure`,`tiltX`,`tiltY`,`twist`,`width`,`height`,`pointerType`,`isPrimary`],at=z(B),ot=z(V),st=z(H,{relatedTarget:R}),ct=z(B,{clipboardData:e=>W(e.clipboardData)}),lt=z([...B,`data`]),ut=z(H,{relatedTarget:R,dataTransfer:e=>W(e.dataTransfer)}),dt=z(it,{relatedTarget:R}),ft=z(B,{relatedTarget:R}),pt=z(B),mt=z(B),ht=z(B),gt=z([...V,`altKey`,`ctrlKey`,`code`,`key`,`locale`,`location`,`metaKey`,`repeat`,`shiftKey`]),_t=z([...V,`altKey`,`ctrlKey`,`metaKey`,`shiftKey`,`changedTouches`,`targetTouches`,`touches`],{changedTouches:e=>U(e.changedTouches),targetTouches:e=>U(e.targetTouches),touches:e=>U(e.touches)}),vt=z([...H,`deltaMode`,`deltaX`,`deltaY`,`deltaZ`],{relatedTarget:R}),yt=z([...B,`animationName`,`elapsedTime`,`pseudoElement`]),bt=z([...B,`oldState`,`newState`]),xt=z([...B,`elapsedTime`,`propertyName`,`pseudoElement`]);function U(e){return Array.from(e).map(e=>({target:L(e.target),identifier:e.identifier,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY,pageX:e.pageX,pageY:e.pageY}))}function W(e){if(!e)return null;let t=[];if(e.items)for(let n=0;n<e.items.length;n++){let r=e.items[n];t.push({kind:r.kind,type:r.type})}return{drop_effect:e.dropEffect,effect_allowed:e.effectAllowed,items:t,types:Array.from(e.types||[])}}const G={};function K(e,t,n){for(let r of t)e[r]=n}K(G,[`pointerdown`,`pointermove`,`pointerup`,`pointercancel`,`gotpointercapture`,`lostpointercapture`,`pointerenter`,`pointerleave`,`pointerover`,`pointerout`],dt),K(G,[`click`,`contextmenu`,`dblclick`,`mousedown`,`mouseenter`,`mouseleave`,`mousemove`,`mouseout`,`mouseover`,`mouseup`],st),K(G,[`drag`,`dragend`,`dragenter`,`dragexit`,`dragleave`,`dragover`,`dragstart`,`drop`],ut),K(G,[`keydown`,`keypress`,`keyup`],gt),K(G,[`focus`,`blur`],ft),K(G,[`change`,`input`],ht),K(G,[`invalid`],mt),K(G,[`reset`,`submit`],pt),K(G,[`copy`,`cut`,`paste`],ct),K(G,[`compositionend`,`compositionstart`,`compositionupdate`],lt),K(G,[`touchcancel`,`touchend`,`touchmove`,`touchstart`],_t),K(G,[`scroll`],ot),K(G,[`wheel`],vt),K(G,[`animationstart`,`animationend`,`animationiteration`],yt),K(G,[`transitionend`],xt),K(G,[`toggle`],bt);function St(e){if(e&&typeof e==`object`&&`nativeEvent`in e&&typeof e.isDefaultPrevented==`function`){let t=e;if(typeof t.type!=`string`)return e;let n=G[t.type.toLowerCase()];return n?n(t):at(t)}return e}function q(e){let t=new Map,n=[],r=[],i=[],a=[],o=0;function s(e){if(e==null||typeof e==`number`||typeof e==`string`||typeof e==`boolean`)return e;let c=o++,l=t.get(e);if(l!==void 0)return n.push(c),l;if(t.set(e,c),e instanceof Date)return r.push(c),e.getTime();if(Array.isArray(e)){let t=e.length,n=Array(t);for(let r=0;r<t;r++)n[r]=s(e[r]);return n}if(e instanceof Map){a.push(c);let t={};for(let[n,r]of e.entries())t[String(n)]=s(r);return t}if(e instanceof Set){i.push(c);let t=e.size,n=Array(t),r=0;for(let t of e)n[r]=s(t),r+=1;return n}if(typeof e==`object`){let t={},n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t[i]=s(e[i])}return t}throw Error(`Unsupported value in serialization: ${e}`)}let c=s(e);return[[n,r,i,a],c]}function J(e,t){let[[n,r,i,a],o]=e,s=new Set(n),c=new Set(r),l=new Set(i),u=new Set(a),d=[];function f(e){let n=d.length;if(s.has(n))return d.push(null),d[e];if(c.has(n)){let t=new Date(e);return d.push(t),t}if(e==null||typeof e==`number`||typeof e==`string`||typeof e==`boolean`)return t?.coerceNullsToUndefined?e??void 0:e;if(Array.isArray(e)){if(l.has(n)){let t=new Set;d.push(t);for(let n=0;n<e.length;n++)t.add(f(e[n]));return t}let t=e.length,r=Array(t);d.push(r);for(let n=0;n<t;n++)r[n]=f(e[n]);return r}if(typeof e==`object`){if(u.has(n)){let t=new Map;d.push(t);let n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t.set(i,f(e[i]))}return t}let t={};d.push(t);let r=Object.keys(e);for(let n=0;n<r.length;n++){let i=r[n];t[i]=f(e[i])}return t}throw Error(`Unsupported value in deserialization: ${e}`)}return f(o)}var Ct=class{#activeViews;#socket=null;#messageQueue;#connectionListeners=new Set;#serverErrors=new Map;#serverErrorListeners=new Set;#channels=new Map;#url;#frameworkNavigate;#directives;constructor(e,t,n){if(this.#url=e,this.#directives=t,this.#frameworkNavigate=n,this.#socket=null,this.#activeViews=new Map,this.#messageQueue=[],typeof window<`u`&&typeof sessionStorage<`u`){let e=sessionStorage.getItem(`__PULSE_DIRECTIVES`);if(e)try{this.#directives=JSON.parse(e)}catch{}}}setDirectives(e){this.#directives=e}isConnected(){return this.#socket?.connected??!1}async connect(){if(!this.#socket)return new Promise((e,t)=>{let n=v(this.#url,{transports:[`websocket`,`webtransport`],auth:this.#directives.socketio?.auth,extraHeaders:this.#directives.socketio?.headers});this.#socket=n,n.on(`connect`,()=>{console.log(`[SocketIOTransport] Connected:`,this.#socket?.id);for(let[e,t]of this.#activeViews)n.emit(`message`,q({type:`mount`,path:e,routeInfo:t.routeInfo}));for(let e of this.#messageQueue)e.type===`mount`&&this.#activeViews.has(e.path)||e.type!==`navigate`&&n.emit(`message`,q(e));this.#messageQueue=[],this.notifyConnectionListeners(!0),e()}),n.on(`connect_error`,e=>{console.error(`[SocketIOTransport] Connection failed:`,e),this.notifyConnectionListeners(!1),t(e)}),n.on(`disconnect`,()=>{console.log(`[SocketIOTransport] Disconnected`),this.#handleTransportDisconnect(),this.notifyConnectionListeners(!1)}),n.on(`message`,e=>this.#handleServerMessage(J(e,{coerceNullsToUndefined:!0})))})}onConnectionChange(e){return this.#connectionListeners.add(e),this.#socket!==null&&e(this.isConnected()),()=>{this.#connectionListeners.delete(e)}}notifyConnectionListeners(e){for(let t of this.#connectionListeners)t(e)}onServerError(e){this.#serverErrorListeners.add(e);for(let[t,n]of this.#serverErrors)e(t,n);return()=>{this.#serverErrorListeners.delete(e)}}notifyServerError(e,t){for(let n of this.#serverErrorListeners)n(e,t)}sendMessage(e){this.isConnected()?this.#socket.emit(`message`,q(e)):this.#messageQueue.push(e)}mountView(e,t){if(this.#activeViews.has(e))throw Error(`Path ${e} is already mounted`);this.#activeViews.set(e,t),this.sendMessage({type:`mount`,path:e,routeInfo:t.routeInfo})}navigate(e,t){this.sendMessage({type:`navigate`,path:e,routeInfo:t})}unmount(e){this.sendMessage({type:`unmount`,path:e}),this.#activeViews.delete(e)}disconnect(){this.#socket?.disconnect(),this.#socket=null,this.#messageQueue=[],this.#connectionListeners.clear(),this.#activeViews.clear(),this.#serverErrors.clear(),this.#serverErrorListeners.clear();for(let{bridge:e}of this.#channels.values())e.dispose(new y(`Client disconnected`));this.#channels.clear()}#handleServerMessage(e){switch(e.type){case`vdom_init`:{let t=this.#activeViews.get(e.path);if(!t)return;t&&t.onInit(e),this.#serverErrors.has(e.path)&&(this.#serverErrors.delete(e.path),this.notifyServerError(e.path,null));break}case`vdom_update`:{let t=this.#activeViews.get(e.path);if(!t)return;t.onUpdate(e.ops),this.#serverErrors.has(e.path)&&(this.#serverErrors.delete(e.path),this.notifyServerError(e.path,null));break}case`server_error`:if(!this.#activeViews.has(e.path))return;this.#serverErrors.set(e.path,e.error),this.notifyServerError(e.path,e.error);break;case`api_call`:this.#performApiCall(e);break;case`navigate_to`:{let t=!!e.replace,n=e.path||``;if(n.startsWith(`//`)&&(n=`${window.location.protocol}${n}`),/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(n))if(n.startsWith(`http://`)||n.startsWith(`https://`))try{let e=new URL(n);if(e.origin===window.location.origin){let n=`${e.pathname}${e.search}${e.hash}`;this.#frameworkNavigate(n,{replace:t})}else t?window.location.replace(n):window.location.assign(n)}catch{t?window.location.replace(n):window.location.assign(n)}else t?window.location.replace(n):window.location.assign(n);else this.#frameworkNavigate(n,{replace:t});break}case`channel_message`:this.#routeChannelMessage(e);break;default:console.error(`Unexpected message:`,e)}}async#performApiCall(e){try{let t=await fetch(e.url,{method:e.method||`GET`,headers:{...e.headers||{},...e.body!=null&&!(`content-type`in(e.headers||{}))?{"content-type":`application/json`}:{}},body:e.body==null?void 0:typeof e.body==`string`?e.body:JSON.stringify(e.body),credentials:e.credentials||`include`}),n={};t.headers.forEach((e,t)=>{n[t]=e});let r=null;r=(t.headers.get(`content-type`)||``).includes(`application/json`)?await t.json().catch(()=>null):await t.text().catch(()=>null);let i={type:`api_result`,id:e.id,ok:t.ok,status:t.status,headers:n,body:r};this.sendMessage(i)}catch(t){let n={type:`api_result`,id:e.id,ok:!1,status:0,headers:{},body:{error:String(t)}};this.sendMessage(n)}}invokeCallback(e,t,n){this.sendMessage({type:`callback`,path:e,callback:t,args:n.map(St)})}acquireChannel(e){let t=this.#ensureChannelEntry(e);return t.refCount+=1,t.bridge}releaseChannel(e){let t=this.#channels.get(e);t&&(t.refCount=Math.max(0,t.refCount-1),t.refCount===0&&(t.bridge.dispose(new y(`Channel released`)),this.sendMessage({type:`channel_message`,channel:e,event:`__close__`,payload:{reason:`refcount_zero`}}),this.#channels.delete(e)))}#ensureChannelEntry(e){let t=this.#channels.get(e);return t||(t={bridge:se(this,e),refCount:0},this.#channels.set(e,t)),t}#routeChannelMessage(e){let t=this.#ensureChannelEntry(e.channel);t.bridge.handleServerMessage(e)&&t.refCount===0&&this.#channels.delete(e.channel)}#handleTransportDisconnect(){for(let e of this.#channels.values())e.bridge.handleDisconnect(new y(`Connection lost`))}};const Y=`$$fragment`;function wt(e){return typeof e==`object`&&!!e}function Tt(e){return typeof e==`object`&&!!e&&e.tag.startsWith(`$$`)&&e.tag!==Y}var Et=class{#callbacks;#callbackCache;#renderPropKeys;#cssProps;#callbackList;#client;#path;#components;#cssModules;constructor(e,t,n,r,i=[],a=[],o=[]){this.#client=e,this.#path=t,this.#components=n,this.#cssModules=r,this.#callbacks=new Set(i),this.#callbackCache=new Map,this.#renderPropKeys=new Set(a),this.#cssProps=new Set(o),this.#callbackList=[...this.#callbacks].sort()}hasCallbackPath(e){return this.#callbacks.has(e)}hasRenderPropPath(e){return this.#renderPropKeys.has(e)}hasAnyCallbackUnder(e){if(e===``)return this.#callbackList.length>0;let t=this.#lowerBound(this.#callbackList,e);return t<this.#callbackList.length&&this.#callbackList[t].startsWith(e)}applyCallbackDelta(e){if(e.remove)for(let t of e.remove)this.#callbacks.delete(t),this.#callbackCache.delete(t);if(e.add)for(let t of e.add)this.#callbacks.add(t);this.#callbackList=[...this.#callbacks].sort()}applyRenderPropsDelta(e){if(e.remove)for(let t of e.remove)this.#renderPropKeys.delete(t);if(e.add)for(let t of e.add)this.#renderPropKeys.add(t)}applyCssRefsDelta(e){if(e.remove)for(let t of e.remove)this.#cssProps.delete(t);if(e.add)for(let t of e.add)this.#cssProps.add(t)}getCallback(e,t){let n=this.#propPath(e,t),r=this.#callbackCache.get(n);return r||(r=(...e)=>this.#client.invokeCallback(this.#path,n,e),this.#callbackCache.set(n,r)),r}renderNode(e,n=``){if(e==null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`)return e;if(wt(e)){let{tag:r,props:i={},children:o=[]}=e,s={};for(let[e,t]of Object.entries(i))s[e]=this.transformValue(n,e,t);e.key&&(s.key=e.key);let c=[];for(let e=0;e<o.length;e+=1){let t=o[e],r=n?`${n}.${e}`:String(e);c.push(this.renderNode(t,r))}if(Tt(e)){let t=e.tag.slice(2),n=this.#components[t];if(!n)throw Error(`Could not find component ${t}. This is a Pulse internal error.`);return a(n,s,...c)}return a(r===Y?t:r,s,...c)}return process.env.NODE_ENV!==`production`&&console.error(`Unknown VDOM node type:`,e),null}#propPath(e,t){return e?`${e}.${t}`:t}transformValue(e,t,n){let r=this.#propPath(e,t);return this.#callbacks.has(r)?this.getCallback(e,t):this.#renderPropKeys.has(r)?this.renderNode(n,r):this.#cssProps.has(r)?this.#resolveCssToken(n):n}#resolveCssToken(e){let t=e.indexOf(`:`);if(t===-1)return e;let n=e.slice(0,t),r=e.slice(t+1);if(!n||!r)return e;let i=this.#cssModules[n];if(!i)throw Error(`Received CSS reference for unknown module '${n}'`);let a=i[r];if(typeof a!=`string`)throw Error(`Received CSS reference for missing class '${r}' in module '${n}'`);return a}init(e){this.#callbacks=new Set(e.callbacks);for(let e of Array.from(this.#callbackCache.keys()))this.#callbacks.has(e)||this.#callbackCache.delete(e);return this.#callbackList=[...this.#callbacks].sort(),this.#renderPropKeys=new Set(e.render_props),this.#cssProps=new Set(e.css_refs),this.renderNode(e.vdom)}#ensureChildrenArray(e){let t=e.props?.children;return t==null?[]:Array.isArray(t)?t.slice():[t]}applyUpdates(e,t){let n=e;for(let e of t){if(e.type===`update_callbacks`){this.applyCallbackDelta(e.data);continue}if(e.type===`update_css_refs`){this.applyCssRefsDelta(e.data);continue}if(e.type===`update_render_props`){this.applyRenderPropsDelta(e.data);continue}let t=e.path.split(`.`).filter(e=>e.length>0),i=(n,o,s)=>{if(o<t.length){this.#assertIsElement(n,t,o);let e=n,a=t[o],c=+a,l=s?`${s}.${a}`:a;if(Number.isNaN(c)){let t=e.props??{},n=t[a];return r(e,{...t,[a]:i(n,o+1,l)})}else{let t=this.#ensureChildrenArray(e),n=t[c];return t[c]=i(n,o+1,l),r(e,void 0,...t)}}switch(e.type){case`replace`:return this.renderNode(e.data,e.path);case`update_props`:{this.#assertIsElement(n,t,o);let i=n,c={...i.props??{}},l=e.data;if(l.remove&&l.remove.length>0)for(let e of l.remove)e in c&&delete c[e];if(l.set)for(let[e,t]of Object.entries(l.set))c[e]=this.transformValue(s,e,t);return(l.remove?.length??0)>0?(c.key=i.key,c.ref=i.ref,a(i.type,c,...this.#ensureChildrenArray(i))):r(i,c)}case`reconciliation`:{this.#assertIsElement(n,t,o);let i=n,a=this.#ensureChildrenArray(i),c=[],[l,u]=e.new,[d,f]=e.reuse,p=-1,m=-1,h=-1,g=-1;l.length>0&&(p=l[0],h=0),d.length>0&&(m=d[0],g=0);for(let t=0;t<e.N;++t)if(t===p){let e=u[h],n=s?`${s}.${t}`:String(t);c.push(this.renderNode(e,n)),p=h<l.length-1?l[++h]:-1}else if(t===m){let e=a[f[g]],n=s?`${s}.${t}`:String(t);this.hasAnyCallbackUnder(n)&&(e=this.#rebindCallbacksInSubtree(e,n)),c.push(e),m=g<d.length-1?d[++g]:-1}else c.push(a[t]);return r(i,null,...c)}default:throw Error(`[Pulse renderer] Unknown update type: ${e?.type}`)}};n=i(n,0,``)}return n}#assertIsElement(e,t,n){if(process.env.NODE_ENV!==`production`&&!s(e))throw console.error(`Invalid node:`,e),Error(`Invalid node at path ${t.slice(0,n).join(`.`)}`);return!0}#rebindCallbacksInSubtree(e,t){if(!s(e))return e;let n=e,i=n.props??{},a={...i};for(let e of Object.keys(i)){let n=t?`${t}.${e}`:e;this.hasCallbackPath(n)&&(a[e]=this.getCallback(t,e)),this.hasRenderPropPath(n)&&this.hasAnyCallbackUnder(n)&&(a[e]=this.#rebindCallbacksInSubtree(i[e],n))}return r(n,a,...this.#ensureChildrenArray(n).map((e,n)=>{let r=t?`${t}.${n}`:String(n);return this.hasAnyCallbackUnder(r)?this.#rebindCallbacksInSubtree(e,r):e}))}#lowerBound(e,t){let n=0,r=e.length;for(;n<r;){let i=n+r>>>1;e[i]<t?n=i+1:r=i}return n}};function Dt(e,t){let r=c(e);return({children:e,...i})=>h(n,{fallback:t,children:h(r,{...i,children:e})})}const X=i(null),Z=i(null),Q=()=>{let e=u(X);if(!e)throw Error(`usePulseClient must be used within a PulseProvider`);return e},Ot=e=>{let t=u(Z);if(!t)throw Error(`usePulsePrerender must be used within a PulseProvider`);let n=t.views[e];if(!n)throw Error(`No prerender found for '${e}'`);return n},$=typeof window<`u`;function kt({children:e,config:t,prerender:n}){let[r,i]=m(!0),a=_(),{directives:o}=n,s=f(()=>new Ct(t.serverAddress,o,a),[t.serverAddress,a]);return d(()=>s.setDirectives(o),[s,o]),d(()=>s.onConnectionChange(i),[s]),d(()=>{if($)return s.connect(),()=>s.disconnect()},[s]),h(X.Provider,{value:s,children:g(Z.Provider,{value:n,children:[!r&&h(`div`,{style:{position:`fixed`,bottom:`20px`,right:`20px`,backgroundColor:`red`,color:`white`,padding:`10px`,borderRadius:`5px`,zIndex:1e3},children:`Failed to connect to the server.`}),e]})})}function At({externalComponents:e,path:t,cssModules:n}){let r=Q(),i=Ot(t),a=f(()=>new Et(r,t,e,n,i.callbacks,i.render_props,i.css_refs),[r,t,e,n]),[o,s]=m(()=>a.init(i)),[c,l]=m(null),u=ee(),g=te(),_=f(()=>{let{"*":e=``,...t}=g,n=new URLSearchParams(u.search);return{hash:u.hash,pathname:u.pathname,query:u.search,queryParams:Object.fromEntries(n.entries()),pathParams:t,catchall:e.length>0?e.split(`/`):[]}},[u.hash,u.pathname,u.search,JSON.stringify(g)]);d(()=>{if($){r.mountView(t,{routeInfo:_,onInit:e=>{s(a.init(e))},onUpdate:e=>{s(t=>t==null?t:a.applyUpdates(t,e))}});let e=r.onServerError((e,n)=>{e===t&&l(n)});return()=>{e(),r.unmount(t)}}},[r,a,t]),d(()=>{$&&r.navigate(t,_)},[r,t,_]);let v=p(!1);return d(()=>(v.current?s(a.init(i)):v.current=!0,()=>{v.current=!1}),[i,a]),c?h(jt,{error:c}):o}function jt({error:e}){return g(`div`,{style:{padding:16,border:`1px solid #e00`,background:`#fff5f5`,color:`#900`,fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace`,whiteSpace:`pre-wrap`},children:[g(`div`,{style:{fontWeight:700,marginBottom:8},children:[`Server Error during `,e.phase]}),e.message&&h(`div`,{children:e.message}),e.stack&&g(`details`,{open:!0,style:{marginTop:8},children:[h(`summary`,{children:`Stack trace`}),h(`pre`,{style:{margin:0},children:e.stack})]})]})}function Mt(e){let t=Q(),n=f(()=>{if(!e)throw Error(`usePulseChannel requires a non-empty channelId`);return t.acquireChannel(e)},[t,e]);return d(()=>()=>{t.releaseChannel(e)},[t,e]),n}export{y as PulseChannelResetError,ce as PulseForm,kt as PulseProvider,At as PulseView,Dt as RenderLazy,J as deserialize,le as extractServerRouteInfo,q as serialize,b as submitForm,Mt as usePulseChannel,Q as usePulseClient};
|
|
1
|
+
import e,{Fragment as t,Suspense as n,cloneElement as r,createContext as i,createElement as a,forwardRef as o,isValidElement as s,lazy as c,useCallback as l,useContext as u,useEffect as d,useMemo as f,useRef as p,useState as m}from"react";import{jsx as h,jsxs as g}from"react/jsx-runtime";import{useLocation as ee,useNavigate as _,useParams as te}from"react-router";import{io as v}from"socket.io-client";var y=class extends Error{constructor(e){super(e),this.name=`PulseChannelResetError`}};function ne(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID().replace(/-/g,``):Math.random().toString(16).slice(2)+Math.random().toString(16).slice(2)}function re(e){if(e instanceof Error)return e.message;if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}function ie(e){return typeof e.responseTo==`string`}function ae(e){return typeof e.event==`string`}var oe=class{handlers=new Map;pending=new Map;backlog=[];closed=!1;constructor(e,t){this.client=e,this.id=t}emit(e,t){this.ensureOpen(),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t})}request(e,t){this.ensureOpen();let n=ne();return new Promise((r,i)=>{this.pending.set(n,{resolve:r,reject:i}),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t,requestId:n})})}on(e,t){this.ensureOpen();let n=this.handlers.get(e);return n||(n=new Set,this.handlers.set(e,n)),n.add(t),this.flushBacklog(e),()=>{let n=this.handlers.get(e);n&&(n.delete(t),n.size===0&&this.handlers.delete(e))}}handleServerMessage(e){return ie(e)?(this.resolvePending(e),this.closed):this.closed?!0:ae(e)?e.event===`__close__`?(this.close(new y(`Channel closed by server`)),!0):(e.requestId?this.dispatchRequest(e):this.dispatchEvent(e),this.closed):this.closed}handleDisconnect(e){this.close(e)}dispose(e){this.close(e)}ensureOpen(){if(this.closed)throw new y(`Channel is closed`)}flushBacklog(e){if(this.backlog.length===0)return;let t=[];for(let n of this.backlog)n.event===e?this.dispatchEvent(n):t.push(n);this.backlog=t}dispatchEvent(e){let t=this.handlers.get(e.event);if(!t||t.size===0){this.backlog.push(e);return}for(let n of t)try{let t=n(e.payload);t&&typeof t.then==`function`&&t.catch(e=>{console.error(`Pulse channel handler error`,e)})}catch(e){console.error(`Pulse channel handler error`,e)}}async dispatchRequest(e){let t=this.handlers.get(e.event),n,r;if(t&&t.size>0)for(let i of t)try{let t=i(e.payload);if(n=await Promise.resolve(t),n!==void 0)break}catch(e){r=e;break}if(r){this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,error:re(r)});return}this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,payload:n})}resolvePending(e){let t=e.responseTo?this.pending.get(e.responseTo):void 0;t&&(this.pending.delete(e.responseTo),e.error!==void 0&&e.error!==null?t.reject(new y(String(e.error))):t.resolve(e.payload))}close(e){if(!this.closed){this.closed=!0;for(let t of this.pending.values())t.reject(e);this.pending.clear(),this.handlers.clear(),this.backlog=[]}}};function se(e,t){return new oe(e,t)}const ce=o(function({onSubmit:e,action:t,...n},r){return h(`form`,{...n,action:t,ref:r,onSubmit:l(n=>b({event:n,action:t,onSubmit:e}),[t,e])})});async function b({event:e,action:t,onSubmit:n,formData:r,force:i}){if(n?.(e),!i&&e.defaultPrevented)return;let a=e.currentTarget;e.preventDefault();let o=e.nativeEvent;r||=new FormData(a,o.submitter);let s=new URL(t,window.location.href);try{await fetch(s,{method:`POST`,credentials:`include`,body:r})}catch(e){if(process.env.NODE_ENV!==`production`)console.error(`[Pulse] Form submission failed`,e);else throw e}}function le({params:e,request:t}){let{"*":n=``,...r}=e,i=new URL(t.url);return{hash:i.hash,pathname:i.pathname,query:i.search,queryParams:Object.fromEntries(i.searchParams.entries()),pathParams:r,catchall:n.length>1?n.split(`/`):[]}}function x(){function e(e,t){return n=>{let r={};for(let t of e)r[t]=n[t];if(t)for(let e in t){let i=t[e];r[e]=i(n)}return r}}return e}const ue=e=>e.tagName.toLowerCase(),de=[`id`,`className`,`tagName`,`localName`,`clientHeight`,`clientLeft`,`clientTop`,`clientWidth`,`scrollHeight`,`scrollLeft`,`scrollTop`,`scrollWidth`,`slot`],fe=[`autofocus`,`tabIndex`,`nonce`],pe=[`accessKey`,`accessKeyLabel`,`autocapitalize`,`dir`,`draggable`,`hidden`,`inert`,`lang`,`offsetHeight`,`offsetLeft`,`offsetTop`,`offsetWidth`,`popover`,`spellcheck`,`title`,`translate`,`writingSuggestions`,`contentEditable`,`enterKeyHint`,`isContentEditable`,`inputMode`],S=x()(de,{tagName:ue}),C=x()(fe),me=x()(pe);function w(e){return{...S(e),...C(e),...me(e)}}function T(e,t){let n=x()(e,t);return e=>({...w(e),...n(e)})}const he=T([`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`search`,`target`,`download`,`rel`,`hreflang`,`type`,`username`,`ping`,`referrerPolicy`,`text`]),ge=T([`alt`,`coords`,`download`,`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`rel`,`search`,`shape`,`target`,`username`,`ping`,`referrerPolicy`]),E=T([`autoplay`,`controls`,`crossOrigin`,`currentSrc`,`currentTime`,`defaultMuted`,`defaultPlaybackRate`,`duration`,`ended`,`loop`,`muted`,`networkState`,`paused`,`playbackRate`,`preload`,`readyState`,`seeking`,`src`,`volume`,`preservesPitch`]),_e=e=>E(e),ve=T([`disabled`,`name`,`type`,`value`,`formAction`,`formEnctype`,`formMethod`,`formNoValidate`,`formTarget`,`popoverTargetAction`]),ye=T([`value`]),be=T([`height`,`src`,`type`,`width`,`align`,`name`]),xe=T([`disabled`,`name`,`type`,`validationMessage`,`willValidate`]),Se=T([`acceptCharset`,`action`,`autocomplete`,`encoding`,`enctype`,`length`,`method`,`name`,`noValidate`,`target`,`rel`]),Ce=T([`allow`,`allowFullscreen`,`height`,`name`,`referrerPolicy`,`src`,`srcdoc`,`width`,`align`,`frameBorder`,`longDesc`,`marginHeight`,`marginWidth`,`scrolling`,`sandbox`]),we=T([`alt`,`crossOrigin`,`decoding`,`height`,`isMap`,`loading`,`naturalHeight`,`naturalWidth`,`referrerPolicy`,`sizes`,`src`,`srcset`,`useMap`,`width`,`align`,`border`,`complete`,`hspace`,`longDesc`,`lowsrc`,`name`,`vspace`,`x`,`y`,`fetchPriority`]),Te=T(`accept.alt.autocomplete.checked.defaultChecked.defaultValue.dirName.disabled.height.indeterminate.max.maxLength.min.minLength.multiple.name.pattern.placeholder.readOnly.required.selectionDirection.selectionEnd.selectionStart.size.src.step.type.value.valueAsNumber.width.align.capture.formAction.formEnctype.formMethod.formNoValidate.formTarget.useMap.validationMessage.willValidate.popoverTargetAction`.split(`.`)),Ee=T([`htmlFor`]),De=T([`value`,`type`]),Oe=T([`as`,`crossOrigin`,`disabled`,`fetchPriority`,`href`,`hreflang`,`imageSizes`,`imageSrcset`,`integrity`,`media`,`referrerPolicy`,`rel`,`type`,`charset`,`rev`,`target`,`sizes`]),ke=T([`name`]),Ae=T([`high`,`low`,`max`,`min`,`optimum`,`value`]),D=T([`cite`,`dateTime`]),je=T([`reversed`,`start`,`type`,`compact`]),Me=T([`data`,`height`,`name`,`type`,`useMap`,`width`,`validationMessage`,`willValidate`,`align`,`archive`,`border`,`code`,`codeBase`,`codeType`,`declare`,`hspace`,`standby`,`vspace`]),Ne=T([`disabled`,`label`]),Pe=T([`defaultSelected`,`disabled`,`index`,`label`,`selected`,`text`,`value`]),Fe=T([`defaultValue`,`name`,`type`,`value`,`htmlFor`,`validationMessage`,`willValidate`]),Ie=T([`max`,`position`,`value`]),O=T([`cite`]),Le=e=>w(e),Re=x()([`async`,`crossOrigin`,`defer`,`fetchPriority`,`integrity`,`noModule`,`referrerPolicy`,`src`,`text`,`type`,`charset`],{event:e=>e.event,htmlFor:e=>e.htmlFor}),ze=e=>({...w(e),...Re(e)}),Be=T([`autocomplete`,`disabled`,`length`,`multiple`,`name`,`required`,`selectedIndex`,`size`,`type`,`value`,`validationMessage`,`willValidate`]),Ve=T([`name`]),He=T([`height`,`media`,`sizes`,`src`,`srcset`,`type`,`width`]),Ue=T([`align`]),k=T([`abbr`,`cellIndex`,`colSpan`,`headers`,`rowSpan`,`scope`,`align`,`axis`,`bgColor`,`ch`,`chOff`,`height`,`noWrap`,`vAlign`,`width`]),A=T([`span`,`align`,`ch`,`chOff`,`vAlign`,`width`]),We=T([`align`,`bgColor`,`border`,`cellPadding`,`cellSpacing`,`frame`,`rules`,`summary`,`width`]),Ge=T([`rowIndex`,`sectionRowIndex`,`align`,`bgColor`,`ch`,`chOff`,`vAlign`]),j=T([`align`,`ch`,`chOff`,`vAlign`]),Ke=e=>w(e),qe=T([`autocomplete`,`cols`,`defaultValue`,`dirName`,`disabled`,`maxLength`,`minLength`,`name`,`placeholder`,`readOnly`,`required`,`rows`,`selectionDirection`,`selectionEnd`,`selectionStart`,`value`,`wrap`,`textLength`,`validationMessage`,`willValidate`]),Je=T([`dateTime`]),Ye=T([`default`,`kind`,`label`,`readyState`,`src`,`srclang`]),Xe=x()([`height`,`poster`,`videoHeight`,`videoWidth`,`width`,`playsInline`]),Ze=e=>({...E(e),...Xe(e)}),Qe=T([`clear`]),$e=T([`href`,`target`]),et=T([`aLink`,`background`,`bgColor`,`link`,`text`,`vLink`]),tt=T([`compact`]),nt=T([`open`]),rt=T([`open`,`returnValue`]),it=T([`align`]),at=e=>w(e),M=T([`align`]),ot=T([`align`,`color`,`noShade`,`size`,`width`]),st=T([`version`]),ct=e=>w(e),lt=T([`content`,`httpEquiv`,`name`,`scheme`]),ut=T([`align`]),dt=e=>w(e),ft=T([`width`]),pt=e=>w(e),mt=T([`media`,`type`,`disabled`]),ht=T([`text`]),gt=T([`compact`,`type`]);function N(e){return{...S(e),...C(e)}}function P(e,t){let n=x()(e,t);return e=>({...N(e),...n(e)})}const F={A:he,AREA:ge,AUDIO:_e,BASE:$e,BLOCKQUOTE:O,Q:O,BODY:et,BR:Qe,BUTTON:ve,CANVAS:w,CAPTION:Ue,CITE:Le,COL:A,COLGROUP:A,DATA:ye,DETAILS:nt,DIALOG:rt,DIV:it,DL:tt,EMBED:be,FIELDSET:xe,FORM:Se,H1:M,H2:M,H3:M,H4:M,H5:M,H6:M,HEAD:at,HR:ot,HTML:st,IFRAME:Ce,IMG:we,INPUT:Te,LABEL:Ee,LI:De,LINK:Oe,MAP:ke,MENU:ct,META:lt,METER:Ae,INS:D,DEL:D,OBJECT:Me,OL:je,OPTGROUP:Ne,OPTION:Pe,OUTPUT:Fe,P:ut,PICTURE:dt,PRE:ft,PROGRESS:Ie,SCRIPT:ze,SELECT:Be,SLOT:Ve,SOURCE:He,SPAN:pt,STYLE:mt,TABLE:We,TBODY:j,THEAD:j,TFOOT:j,TD:k,TH:k,TEMPLATE:Ke,TEXTAREA:qe,TIME:Je,TITLE:ht,TR:Ge,TRACK:Ye,UL:gt,VIDEO:Ze,SVG:P([`x`,`y`,`width`,`height`,`currentScale`,`currentTranslate`]),CIRCLE:P([`cx`,`cy`,`r`]),ELLIPSE:P([`cx`,`cy`,`rx`,`ry`]),LINE:P([`x1`,`y1`,`x2`,`y2`]),PATH:P([`pathLength`]),RECT:P([`x`,`y`,`width`,`height`,`rx`,`ry`]),POLYGON:P([`points`]),POLYLINE:P([`points`]),TEXT:P([`x`,`y`,`dx`,`dy`,`rotate`,`textLength`,`lengthAdjust`]),TSPAN:P([`x`,`y`,`dx`,`dy`,`rotate`,`textLength`,`lengthAdjust`]),IMAGE:P([`x`,`y`,`width`,`height`,`href`,`preserveAspectRatio`,`crossOrigin`]),USE:P([`x`,`y`,`width`,`height`,`href`]),DEFS:P([]),G:P([]),LINEARGRADIENT:P([`x1`,`y1`,`x2`,`y2`,`gradientUnits`,`gradientTransform`,`spreadMethod`]),RADIALGRADIENT:P([`cx`,`cy`,`r`,`fx`,`fy`,`fr`,`gradientUnits`,`gradientTransform`,`spreadMethod`]),STOP:P([`offset`]),PATTERN:P([`x`,`y`,`width`,`height`,`patternUnits`,`patternContentUnits`,`patternTransform`,`preserveAspectRatio`,`href`]),CLIPPATH:P([`clipPathUnits`]),MASK:P([`x`,`y`,`width`,`height`,`maskUnits`,`maskContentUnits`])};function _t(e){let t=F[e.tagName.toUpperCase()];if(t)return t(e);throw Error(`Unexpected HTML element tag: ${e.tagName} (update .web/custom/serialize.ts)`)}function vt(e){let t=F[e.tagName.toUpperCase()];return t?t(e):N(e)}function I(e){return e instanceof HTMLElement?_t(e):e instanceof SVGElement?vt(e):S(e)}const yt=e=>I(e.target),L=e=>e.relatedTarget?I(e.relatedTarget):null;function R(e,t){return x()(e,{target:yt,...t||{}})}const z=[`target`,`bubbles`,`cancelable`,`defaultPrevented`,`eventPhase`,`isTrusted`,`timeStamp`,`type`],B=[...z,`detail`],V=[...B,`altKey`,`button`,`buttons`,`clientX`,`clientY`,`ctrlKey`,`metaKey`,`movementX`,`movementY`,`pageX`,`pageY`,`screenX`,`screenY`,`shiftKey`],bt=[...V,`pointerId`,`pressure`,`tangentialPressure`,`tiltX`,`tiltY`,`twist`,`width`,`height`,`pointerType`,`isPrimary`],xt=R(z),St=R(B),Ct=R(V,{relatedTarget:L}),wt=R(z,{clipboardData:e=>U(e.clipboardData)}),Tt=R([...z,`data`]),Et=R(V,{relatedTarget:L,dataTransfer:e=>U(e.dataTransfer)}),Dt=R(bt,{relatedTarget:L}),Ot=R(z,{relatedTarget:L}),kt=R(z),At=R(z),jt=R(z),Mt=R([...B,`altKey`,`ctrlKey`,`code`,`key`,`locale`,`location`,`metaKey`,`repeat`,`shiftKey`]),Nt=R([...B,`altKey`,`ctrlKey`,`metaKey`,`shiftKey`,`changedTouches`,`targetTouches`,`touches`],{changedTouches:e=>H(e.changedTouches),targetTouches:e=>H(e.targetTouches),touches:e=>H(e.touches)}),Pt=R([...V,`deltaMode`,`deltaX`,`deltaY`,`deltaZ`],{relatedTarget:L}),Ft=R([...z,`animationName`,`elapsedTime`,`pseudoElement`]),It=R([...z,`oldState`,`newState`]),Lt=R([...z,`elapsedTime`,`propertyName`,`pseudoElement`]);function H(e){return Array.from(e).map(e=>({target:I(e.target),identifier:e.identifier,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY,pageX:e.pageX,pageY:e.pageY}))}function U(e){if(!e)return null;let t=[];if(e.items)for(let n=0;n<e.items.length;n++){let r=e.items[n];t.push({kind:r.kind,type:r.type})}return{drop_effect:e.dropEffect,effect_allowed:e.effectAllowed,items:t,types:Array.from(e.types||[])}}const W={};function G(e,t,n){for(let r of t)e[r]=n}G(W,[`pointerdown`,`pointermove`,`pointerup`,`pointercancel`,`gotpointercapture`,`lostpointercapture`,`pointerenter`,`pointerleave`,`pointerover`,`pointerout`],Dt),G(W,[`click`,`contextmenu`,`dblclick`,`mousedown`,`mouseenter`,`mouseleave`,`mousemove`,`mouseout`,`mouseover`,`mouseup`],Ct),G(W,[`drag`,`dragend`,`dragenter`,`dragexit`,`dragleave`,`dragover`,`dragstart`,`drop`],Et),G(W,[`keydown`,`keypress`,`keyup`],Mt),G(W,[`focus`,`blur`],Ot),G(W,[`change`,`input`],jt),G(W,[`invalid`],At),G(W,[`reset`,`submit`],kt),G(W,[`copy`,`cut`,`paste`],wt),G(W,[`compositionend`,`compositionstart`,`compositionupdate`],Tt),G(W,[`touchcancel`,`touchend`,`touchmove`,`touchstart`],Nt),G(W,[`scroll`],St),G(W,[`wheel`],Pt),G(W,[`animationstart`,`animationend`,`animationiteration`],Ft),G(W,[`transitionend`],Lt),G(W,[`toggle`],It);function Rt(e){if(e&&typeof e==`object`&&`nativeEvent`in e&&typeof e.isDefaultPrevented==`function`){let t=e;if(typeof t.type!=`string`)return e;let n=W[t.type.toLowerCase()];return n?n(t):xt(t)}return e}function K(e){let t=new Map,n=[],r=[],i=[],a=[],o=0;function s(e){if(e==null||typeof e==`number`||typeof e==`string`||typeof e==`boolean`)return e;let c=o++,l=t.get(e);if(l!==void 0)return n.push(c),l;if(t.set(e,c),e instanceof Date)return r.push(c),e.getTime();if(Array.isArray(e)){let t=e.length,n=Array(t);for(let r=0;r<t;r++)n[r]=s(e[r]);return n}if(e instanceof Map){a.push(c);let t={};for(let[n,r]of e.entries())t[String(n)]=s(r);return t}if(e instanceof Set){i.push(c);let t=e.size,n=Array(t),r=0;for(let t of e)n[r]=s(t),r+=1;return n}if(typeof e==`object`){let t={},n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t[i]=s(e[i])}return t}throw Error(`Unsupported value in serialization: ${e}`)}let c=s(e);return[[n,r,i,a],c]}function q(e,t){let[[n,r,i,a],o]=e,s=new Set(n),c=new Set(r),l=new Set(i),u=new Set(a),d=[];function f(e){let n=d.length;if(s.has(n))return d.push(null),d[e];if(c.has(n)){let t=new Date(e);return d.push(t),t}if(e==null||typeof e==`number`||typeof e==`string`||typeof e==`boolean`)return t?.coerceNullsToUndefined?e??void 0:e;if(Array.isArray(e)){if(l.has(n)){let t=new Set;d.push(t);for(let n=0;n<e.length;n++)t.add(f(e[n]));return t}let t=e.length,r=Array(t);d.push(r);for(let n=0;n<t;n++)r[n]=f(e[n]);return r}if(typeof e==`object`){if(u.has(n)){let t=new Map;d.push(t);let n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t.set(i,f(e[i]))}return t}let t={};d.push(t);let r=Object.keys(e);for(let n=0;n<r.length;n++){let i=r[n];t[i]=f(e[i])}return t}throw Error(`Unsupported value in deserialization: ${e}`)}return f(o)}var J=class{#activeViews;#socket=null;#messageQueue;#connectionListeners=new Set;#serverErrors=new Map;#serverErrorListeners=new Set;#channels=new Map;#url;#frameworkNavigate;#directives;constructor(e,t,n){if(this.#url=e,this.#directives=t,this.#frameworkNavigate=n,this.#socket=null,this.#activeViews=new Map,this.#messageQueue=[],typeof window<`u`&&typeof sessionStorage<`u`){let e=sessionStorage.getItem(`__PULSE_DIRECTIVES`);if(e)try{this.#directives=JSON.parse(e)}catch{}}}setDirectives(e){this.#directives=e}isConnected(){return this.#socket?.connected??!1}async connect(){if(!this.#socket)return new Promise((e,t)=>{let n=v(this.#url,{transports:[`websocket`,`webtransport`],auth:this.#directives.socketio?.auth,extraHeaders:this.#directives.socketio?.headers});this.#socket=n,n.on(`connect`,()=>{console.log(`[SocketIOTransport] Connected:`,this.#socket?.id);for(let[e,t]of this.#activeViews)n.emit(`message`,K({type:`mount`,path:e,routeInfo:t.routeInfo}));for(let e of this.#messageQueue)e.type===`mount`&&this.#activeViews.has(e.path)||e.type!==`navigate`&&n.emit(`message`,K(e));this.#messageQueue=[],this.notifyConnectionListeners(!0),e()}),n.on(`connect_error`,e=>{console.error(`[SocketIOTransport] Connection failed:`,e),this.notifyConnectionListeners(!1),t(e)}),n.on(`disconnect`,()=>{console.log(`[SocketIOTransport] Disconnected`),this.#handleTransportDisconnect(),this.notifyConnectionListeners(!1)}),n.on(`message`,e=>this.#handleServerMessage(q(e,{coerceNullsToUndefined:!0})))})}onConnectionChange(e){return this.#connectionListeners.add(e),this.#socket!==null&&e(this.isConnected()),()=>{this.#connectionListeners.delete(e)}}notifyConnectionListeners(e){for(let t of this.#connectionListeners)t(e)}onServerError(e){this.#serverErrorListeners.add(e);for(let[t,n]of this.#serverErrors)e(t,n);return()=>{this.#serverErrorListeners.delete(e)}}notifyServerError(e,t){for(let n of this.#serverErrorListeners)n(e,t)}sendMessage(e){this.isConnected()?this.#socket.emit(`message`,K(e)):this.#messageQueue.push(e)}mountView(e,t){if(this.#activeViews.has(e))throw Error(`Path ${e} is already mounted`);this.#activeViews.set(e,t),this.sendMessage({type:`mount`,path:e,routeInfo:t.routeInfo})}navigate(e,t){this.sendMessage({type:`navigate`,path:e,routeInfo:t})}unmount(e){this.sendMessage({type:`unmount`,path:e}),this.#activeViews.delete(e)}disconnect(){this.#socket?.disconnect(),this.#socket=null,this.#messageQueue=[],this.#connectionListeners.clear(),this.#activeViews.clear(),this.#serverErrors.clear(),this.#serverErrorListeners.clear();for(let{bridge:e}of this.#channels.values())e.dispose(new y(`Client disconnected`));this.#channels.clear()}#handleServerMessage(e){switch(e.type){case`vdom_init`:{let t=this.#activeViews.get(e.path);if(!t)return;t&&t.onInit(e),this.#serverErrors.has(e.path)&&(this.#serverErrors.delete(e.path),this.notifyServerError(e.path,null));break}case`vdom_update`:{let t=this.#activeViews.get(e.path);if(!t)return;t.onUpdate(e.ops),this.#serverErrors.has(e.path)&&(this.#serverErrors.delete(e.path),this.notifyServerError(e.path,null));break}case`server_error`:if(!this.#activeViews.has(e.path))return;this.#serverErrors.set(e.path,e.error),this.notifyServerError(e.path,e.error);break;case`api_call`:this.#performApiCall(e);break;case`navigate_to`:{let t=!!e.replace,n=e.path||``;if(n.startsWith(`//`)&&(n=`${window.location.protocol}${n}`),/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(n))if(n.startsWith(`http://`)||n.startsWith(`https://`))try{let e=new URL(n);if(e.origin===window.location.origin){let n=`${e.pathname}${e.search}${e.hash}`;this.#frameworkNavigate(n,{replace:t})}else t?window.location.replace(n):window.location.assign(n)}catch{t?window.location.replace(n):window.location.assign(n)}else t?window.location.replace(n):window.location.assign(n);else this.#frameworkNavigate(n,{replace:t});break}case`channel_message`:this.#routeChannelMessage(e);break;default:console.error(`Unexpected message:`,e)}}async#performApiCall(e){try{let t=await fetch(e.url,{method:e.method||`GET`,headers:{...e.headers||{},...e.body!=null&&!(`content-type`in(e.headers||{}))?{"content-type":`application/json`}:{}},body:e.body==null?void 0:typeof e.body==`string`?e.body:JSON.stringify(e.body),credentials:e.credentials||`include`}),n={};t.headers.forEach((e,t)=>{n[t]=e});let r=null;r=(t.headers.get(`content-type`)||``).includes(`application/json`)?await t.json().catch(()=>null):await t.text().catch(()=>null);let i={type:`api_result`,id:e.id,ok:t.ok,status:t.status,headers:n,body:r};this.sendMessage(i)}catch(t){let n={type:`api_result`,id:e.id,ok:!1,status:0,headers:{},body:{error:String(t)}};this.sendMessage(n)}}invokeCallback(e,t,n){this.sendMessage({type:`callback`,path:e,callback:t,args:n.map(Rt)})}acquireChannel(e){let t=this.#ensureChannelEntry(e);return t.refCount+=1,t.bridge}releaseChannel(e){let t=this.#channels.get(e);t&&(t.refCount=Math.max(0,t.refCount-1),t.refCount===0&&(t.bridge.dispose(new y(`Channel released`)),this.sendMessage({type:`channel_message`,channel:e,event:`__close__`,payload:{reason:`refcount_zero`}}),this.#channels.delete(e)))}#ensureChannelEntry(e){let t=this.#channels.get(e);return t||(t={bridge:se(this,e),refCount:0},this.#channels.set(e,t)),t}#routeChannelMessage(e){let t=this.#ensureChannelEntry(e.channel);t.bridge.handleServerMessage(e)&&t.refCount===0&&this.#channels.delete(e.channel)}#handleTransportDisconnect(){for(let e of this.#channels.values())e.bridge.handleDisconnect(new y(`Connection lost`))}};const Y=`$$fragment`;function zt(e){return typeof e==`object`&&!!e}function Bt(e){return typeof e==`object`&&!!e&&e.tag.startsWith(`$$`)&&e.tag!==Y}var Vt=class{#callbacks;#callbackCache;#renderPropKeys;#cssProps;#callbackList;#client;#path;#components;#cssModules;constructor(e,t,n,r,i=[],a=[],o=[]){this.#client=e,this.#path=t,this.#components=n,this.#cssModules=r,this.#callbacks=new Set(i),this.#callbackCache=new Map,this.#renderPropKeys=new Set(a),this.#cssProps=new Set(o),this.#callbackList=[...this.#callbacks].sort()}hasCallbackPath(e){return this.#callbacks.has(e)}hasRenderPropPath(e){return this.#renderPropKeys.has(e)}hasAnyCallbackUnder(e){if(e===``)return this.#callbackList.length>0;let t=this.#lowerBound(this.#callbackList,e);return t<this.#callbackList.length&&this.#callbackList[t].startsWith(e)}applyCallbackDelta(e){if(e.remove)for(let t of e.remove)this.#callbacks.delete(t),this.#callbackCache.delete(t);if(e.add)for(let t of e.add)this.#callbacks.add(t);this.#callbackList=[...this.#callbacks].sort()}applyRenderPropsDelta(e){if(e.remove)for(let t of e.remove)this.#renderPropKeys.delete(t);if(e.add)for(let t of e.add)this.#renderPropKeys.add(t)}applyCssRefsDelta(e){if(e.remove)for(let t of e.remove)this.#cssProps.delete(t);if(e.add)for(let t of e.add)this.#cssProps.add(t)}getCallback(e,t){let n=this.#propPath(e,t),r=this.#callbackCache.get(n);return r||(r=(...e)=>this.#client.invokeCallback(this.#path,n,e),this.#callbackCache.set(n,r)),r}renderNode(e,n=``){if(e==null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`)return e;if(zt(e)){let{tag:r,props:i={},children:o=[]}=e,s={};for(let[e,t]of Object.entries(i))s[e]=this.transformValue(n,e,t);e.key&&(s.key=e.key);let c=[];for(let e=0;e<o.length;e+=1){let t=o[e],r=n?`${n}.${e}`:String(e);c.push(this.renderNode(t,r))}if(Bt(e)){let t=e.tag.slice(2),n=this.#components[t];if(!n)throw Error(`Could not find component ${t}. This is a Pulse internal error.`);return a(n,s,...c)}return a(r===Y?t:r,s,...c)}return process.env.NODE_ENV!==`production`&&console.error(`Unknown VDOM node type:`,e),null}#propPath(e,t){return e?`${e}.${t}`:t}transformValue(e,t,n){let r=this.#propPath(e,t);return this.#callbacks.has(r)?this.getCallback(e,t):this.#renderPropKeys.has(r)?this.renderNode(n,r):this.#cssProps.has(r)?this.#resolveCssToken(n):n}#resolveCssToken(e){let t=e.indexOf(`:`);if(t===-1)return e;let n=e.slice(0,t),r=e.slice(t+1);if(!n||!r)return e;let i=this.#cssModules[n];if(!i)throw Error(`Received CSS reference for unknown module '${n}'`);let a=i[r];if(typeof a!=`string`)throw Error(`Received CSS reference for missing class '${r}' in module '${n}'`);return a}init(e){this.#callbacks=new Set(e.callbacks);for(let e of Array.from(this.#callbackCache.keys()))this.#callbacks.has(e)||this.#callbackCache.delete(e);return this.#callbackList=[...this.#callbacks].sort(),this.#renderPropKeys=new Set(e.render_props),this.#cssProps=new Set(e.css_refs),this.renderNode(e.vdom)}#ensureChildrenArray(e){let t=e.props?.children;return t==null?[]:Array.isArray(t)?t.slice():[t]}applyUpdates(e,t){let n=e;for(let e of t){if(e.type===`update_callbacks`){this.applyCallbackDelta(e.data);continue}if(e.type===`update_css_refs`){this.applyCssRefsDelta(e.data);continue}if(e.type===`update_render_props`){this.applyRenderPropsDelta(e.data);continue}let t=e.path.split(`.`).filter(e=>e.length>0),i=(n,o,s)=>{if(o<t.length){this.#assertIsElement(n,t,o);let e=n,a=t[o],c=+a,l=s?`${s}.${a}`:a;if(Number.isNaN(c)){let t=e.props??{},n=t[a];return r(e,{...t,[a]:i(n,o+1,l)})}else{let t=this.#ensureChildrenArray(e),n=t[c];return t[c]=i(n,o+1,l),r(e,void 0,...t)}}switch(e.type){case`replace`:return this.renderNode(e.data,e.path);case`update_props`:{this.#assertIsElement(n,t,o);let i=n,c={...i.props??{}},l=e.data;if(l.remove&&l.remove.length>0)for(let e of l.remove)e in c&&delete c[e];if(l.set)for(let[e,t]of Object.entries(l.set))c[e]=this.transformValue(s,e,t);return(l.remove?.length??0)>0?(c.key=i.key,c.ref=i.ref,a(i.type,c,...this.#ensureChildrenArray(i))):r(i,c)}case`reconciliation`:{this.#assertIsElement(n,t,o);let i=n,a=this.#ensureChildrenArray(i),c=[],[l,u]=e.new,[d,f]=e.reuse,p=-1,m=-1,h=-1,g=-1;l.length>0&&(p=l[0],h=0),d.length>0&&(m=d[0],g=0);for(let t=0;t<e.N;++t)if(t===p){let e=u[h],n=s?`${s}.${t}`:String(t);c.push(this.renderNode(e,n)),p=h<l.length-1?l[++h]:-1}else if(t===m){let e=a[f[g]],n=s?`${s}.${t}`:String(t);this.hasAnyCallbackUnder(n)&&(e=this.#rebindCallbacksInSubtree(e,n)),c.push(e),m=g<d.length-1?d[++g]:-1}else c.push(a[t]);return r(i,null,...c)}default:throw Error(`[Pulse renderer] Unknown update type: ${e?.type}`)}};n=i(n,0,``)}return n}#assertIsElement(e,t,n){if(process.env.NODE_ENV!==`production`&&!s(e))throw console.error(`Invalid node:`,e),Error(`Invalid node at path ${t.slice(0,n).join(`.`)}`);return!0}#rebindCallbacksInSubtree(e,t){if(!s(e))return e;let n=e,i=n.props??{},a={...i};for(let e of Object.keys(i)){let n=t?`${t}.${e}`:e;this.hasCallbackPath(n)&&(a[e]=this.getCallback(t,e)),this.hasRenderPropPath(n)&&this.hasAnyCallbackUnder(n)&&(a[e]=this.#rebindCallbacksInSubtree(i[e],n))}return r(n,a,...this.#ensureChildrenArray(n).map((e,n)=>{let r=t?`${t}.${n}`:String(n);return this.hasAnyCallbackUnder(r)?this.#rebindCallbacksInSubtree(e,r):e}))}#lowerBound(e,t){let n=0,r=e.length;for(;n<r;){let i=n+r>>>1;e[i]<t?n=i+1:r=i}return n}};function Ht(e,t){let r=c(e);return({children:e,...i})=>h(n,{fallback:t,children:h(r,{...i,children:e})})}const X=i(null),Z=i(null),Q=()=>{let e=u(X);if(!e)throw Error(`usePulseClient must be used within a PulseProvider`);return e},Ut=e=>{let t=u(Z);if(!t)throw Error(`usePulsePrerender must be used within a PulseProvider`);let n=t.views[e];if(!n)throw Error(`No prerender found for '${e}'`);return n},$=typeof window<`u`;function Wt({children:e,config:t,prerender:n}){let[r,i]=m(!0),a=_(),{directives:o}=n,s=f(()=>new J(t.serverAddress,o,a),[t.serverAddress,a]);return d(()=>s.setDirectives(o),[s,o]),d(()=>s.onConnectionChange(i),[s]),d(()=>{if($)return s.connect(),()=>s.disconnect()},[s]),h(X.Provider,{value:s,children:g(Z.Provider,{value:n,children:[!r&&h(`div`,{style:{position:`fixed`,bottom:`20px`,right:`20px`,backgroundColor:`red`,color:`white`,padding:`10px`,borderRadius:`5px`,zIndex:1e3},children:`Failed to connect to the server.`}),e]})})}function Gt({externalComponents:e,path:t,cssModules:n}){let r=Q(),i=Ut(t),a=f(()=>new Vt(r,t,e,n,i.callbacks,i.render_props,i.css_refs),[r,t,e,n]),[o,s]=m(()=>a.init(i)),[c,l]=m(null),u=ee(),g=te(),_=f(()=>{let{"*":e=``,...t}=g,n=new URLSearchParams(u.search);return{hash:u.hash,pathname:u.pathname,query:u.search,queryParams:Object.fromEntries(n.entries()),pathParams:t,catchall:e.length>0?e.split(`/`):[]}},[u.hash,u.pathname,u.search,JSON.stringify(g)]);d(()=>{if($){r.mountView(t,{routeInfo:_,onInit:e=>{s(a.init(e))},onUpdate:e=>{s(t=>t==null?t:a.applyUpdates(t,e))}});let e=r.onServerError((e,n)=>{e===t&&l(n)});return()=>{e(),r.unmount(t)}}},[r,a,t]),d(()=>{$&&r.navigate(t,_)},[r,t,_]);let v=p(!1);return d(()=>(v.current?s(a.init(i)):v.current=!0,()=>{v.current=!1}),[i,a]),c?h(Kt,{error:c}):o}function Kt({error:e}){return g(`div`,{style:{padding:16,border:`1px solid #e00`,background:`#fff5f5`,color:`#900`,fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace`,whiteSpace:`pre-wrap`},children:[g(`div`,{style:{fontWeight:700,marginBottom:8},children:[`Server Error during `,e.phase]}),e.message&&h(`div`,{children:e.message}),e.stack&&g(`details`,{open:!0,style:{marginTop:8},children:[h(`summary`,{children:`Stack trace`}),h(`pre`,{style:{margin:0},children:e.stack})]})]})}function qt(e){let t=Q(),n=f(()=>{if(!e)throw Error(`usePulseChannel requires a non-empty channelId`);return t.acquireChannel(e)},[t,e]);return d(()=>()=>{t.releaseChannel(e)},[t,e]),n}export{y as PulseChannelResetError,ce as PulseForm,Wt as PulseProvider,Gt as PulseView,Ht as RenderLazy,q as deserialize,le as extractServerRouteInfo,K as serialize,b as submitForm,qt as usePulseChannel,Q as usePulseClient};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["client: PulseSocketIOClient","id: string","remaining: ServerChannelRequestMessage[]","response: any","error: any","PulseForm","out: any","formExtractor","elementExtractors: Record<string, (elt: any) => object>","eventExtractorMap: { [key: string]: (evt: any) => object }","refs: number[]","dates: number[]","sets: number[]","maps: number[]","process","rec: Record<string, any>","objects: Array<any>","result","keys","result: Record<string, any>","#url","#directives","#frameworkNavigate","#socket","#activeViews","#messageQueue","#handleTransportDisconnect","#handleServerMessage","#connectionListeners","#serverErrorListeners","#serverErrors","#channels","#performApiCall","#routeChannelMessage","headersObj: Record<string, string>","body: any","reply: ClientApiResultMessage","#ensureChannelEntry","#client","#path","#components","#cssModules","#callbacks","#callbackCache","#renderPropKeys","#cssProps","#callbackList","#lowerBound","#propPath","newProps: Record<string, any>","#resolveCssToken","newTree: ReactNode","#assertIsElement","#ensureChildrenArray","nextProps: Record<string, any>","#rebindCallbacksInSubtree"],"sources":["../src/channel.ts","../src/form.tsx","../src/helpers.ts","../src/serialize/extractor.ts","../src/serialize/elements.ts","../src/serialize/events.ts","../src/serialize/serializer.ts","../src/client.tsx","../src/vdom.ts","../src/renderer.tsx","../src/pulse.tsx","../src/usePulseChannel.ts"],"sourcesContent":["import type { PulseSocketIOClient } from \"./client\";\nimport type {\n\tServerChannelMessage,\n\tServerChannelRequestMessage,\n\tServerChannelResponseMessage,\n} from \"./messages\";\n\nexport class PulseChannelResetError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PulseChannelResetError\";\n\t}\n}\n\nexport type ChannelEventHandler = (payload: any) => any | Promise<any>;\n\ninterface PendingRequest {\n\tresolve: (value: any) => void;\n\treject: (error: any) => void;\n}\n\nfunction randomId(): string {\n\tif (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n\t\treturn crypto.randomUUID().replace(/-/g, \"\");\n\t}\n\treturn Math.random().toString(16).slice(2) + Math.random().toString(16).slice(2);\n}\n\nfunction formatError(error: unknown): string {\n\tif (error instanceof Error) return error.message;\n\tif (typeof error === \"string\") return error;\n\ttry {\n\t\treturn JSON.stringify(error);\n\t} catch {\n\t\treturn String(error);\n\t}\n}\n\nfunction isServerResponseMessage(\n\tmessage: ServerChannelMessage,\n): message is ServerChannelResponseMessage {\n\treturn typeof (message as ServerChannelResponseMessage).responseTo === \"string\";\n}\n\nfunction isServerRequestMessage(\n\tmessage: ServerChannelMessage,\n): message is ServerChannelRequestMessage {\n\treturn typeof (message as ServerChannelRequestMessage).event === \"string\";\n}\n\nexport class ChannelBridge {\n\tprivate handlers = new Map<string, Set<ChannelEventHandler>>();\n\tprivate pending = new Map<string, PendingRequest>();\n\tprivate backlog: ServerChannelRequestMessage[] = [];\n\tprivate closed = false;\n\n\tconstructor(\n\t\tprivate client: PulseSocketIOClient,\n\t\tpublic readonly id: string,\n\t) {}\n\n\temit(event: string, payload?: any): void {\n\t\tthis.ensureOpen();\n\t\tthis.client.sendMessage({\n\t\t\ttype: \"channel_message\",\n\t\t\tchannel: this.id,\n\t\t\tevent,\n\t\t\tpayload,\n\t\t});\n\t}\n\n\trequest(event: string, payload?: any): Promise<any> {\n\t\tthis.ensureOpen();\n\t\tconst requestId = randomId();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.pending.set(requestId, { resolve, reject });\n\t\t\tthis.client.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: this.id,\n\t\t\t\tevent,\n\t\t\t\tpayload,\n\t\t\t\trequestId,\n\t\t\t});\n\t\t});\n\t}\n\n\ton(event: string, handler: ChannelEventHandler): () => void {\n\t\tthis.ensureOpen();\n\t\tlet bucket = this.handlers.get(event);\n\t\tif (!bucket) {\n\t\t\tbucket = new Set();\n\t\t\tthis.handlers.set(event, bucket);\n\t\t}\n\t\tbucket.add(handler);\n\t\tthis.flushBacklog(event);\n\t\treturn () => {\n\t\t\tconst set = this.handlers.get(event);\n\t\t\tif (!set) return;\n\t\t\tset.delete(handler);\n\t\t\tif (set.size === 0) {\n\t\t\t\tthis.handlers.delete(event);\n\t\t\t}\n\t\t};\n\t}\n\n\thandleServerMessage(message: ServerChannelMessage): boolean {\n\t\tif (isServerResponseMessage(message)) {\n\t\t\tthis.resolvePending(message);\n\t\t\treturn this.closed;\n\t\t}\n\t\tif (this.closed) {\n\t\t\treturn true;\n\t\t}\n\t\tif (!isServerRequestMessage(message)) {\n\t\t\treturn this.closed;\n\t\t}\n\n\t\tif (message.event === \"__close__\") {\n\t\t\tthis.close(new PulseChannelResetError(\"Channel closed by server\"));\n\t\t\treturn true;\n\t\t}\n\t\tif (message.requestId) {\n\t\t\tvoid this.dispatchRequest(\n\t\t\t\tmessage as ServerChannelRequestMessage & {\n\t\t\t\t\trequestId: string;\n\t\t\t\t},\n\t\t\t);\n\t\t} else {\n\t\t\tthis.dispatchEvent(message);\n\t\t}\n\t\treturn this.closed;\n\t}\n\n\thandleDisconnect(reason: PulseChannelResetError): void {\n\t\tthis.close(reason);\n\t}\n\n\tdispose(reason: PulseChannelResetError): void {\n\t\tthis.close(reason);\n\t}\n\n\tprivate ensureOpen(): void {\n\t\tif (this.closed) {\n\t\t\tthrow new PulseChannelResetError(\"Channel is closed\");\n\t\t}\n\t}\n\n\tprivate flushBacklog(event: string): void {\n\t\tif (this.backlog.length === 0) return;\n\t\tconst remaining: ServerChannelRequestMessage[] = [];\n\t\tfor (const item of this.backlog) {\n\t\t\tif (item.event === event) {\n\t\t\t\tthis.dispatchEvent(item);\n\t\t\t} else {\n\t\t\t\tremaining.push(item);\n\t\t\t}\n\t\t}\n\t\tthis.backlog = remaining;\n\t}\n\n\tprivate dispatchEvent(message: ServerChannelRequestMessage): void {\n\t\tconst handlers = this.handlers.get(message.event);\n\t\tif (!handlers || handlers.size === 0) {\n\t\t\tthis.backlog.push(message);\n\t\t\treturn;\n\t\t}\n\t\tfor (const handler of handlers) {\n\t\t\ttry {\n\t\t\t\tconst result = handler(message.payload);\n\t\t\t\tif (result && typeof (result as Promise<any>).then === \"function\") {\n\t\t\t\t\tvoid (result as Promise<any>).catch((err) => {\n\t\t\t\t\t\tconsole.error(\"Pulse channel handler error\", err);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"Pulse channel handler error\", err);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async dispatchRequest(\n\t\tmessage: ServerChannelRequestMessage & { requestId: string },\n\t): Promise<void> {\n\t\tconst handlers = this.handlers.get(message.event);\n\t\tlet response: any;\n\t\tlet error: any;\n\t\tif (handlers && handlers.size > 0) {\n\t\t\tfor (const handler of handlers) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = handler(message.payload);\n\t\t\t\t\tresponse = await Promise.resolve(result);\n\t\t\t\t\tif (response !== undefined) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\terror = err;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (error) {\n\t\t\tthis.client.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: this.id,\n\t\t\t\tevent: undefined,\n\t\t\t\tresponseTo: message.requestId,\n\t\t\t\terror: formatError(error),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tthis.client.sendMessage({\n\t\t\ttype: \"channel_message\",\n\t\t\tchannel: this.id,\n\t\t\tevent: undefined,\n\t\t\tresponseTo: message.requestId,\n\t\t\tpayload: response,\n\t\t});\n\t}\n\n\tprivate resolvePending(message: ServerChannelResponseMessage): void {\n\t\tconst entry = message.responseTo ? this.pending.get(message.responseTo) : undefined;\n\t\tif (!entry) {\n\t\t\treturn;\n\t\t}\n\t\tthis.pending.delete(message.responseTo!);\n\t\tif (message.error !== undefined && message.error !== null) {\n\t\t\tentry.reject(new PulseChannelResetError(String(message.error)));\n\t\t} else {\n\t\t\tentry.resolve(message.payload);\n\t\t}\n\t}\n\n\tprivate close(reason: PulseChannelResetError): void {\n\t\tif (this.closed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.closed = true;\n\t\tfor (const request of this.pending.values()) {\n\t\t\trequest.reject(reason);\n\t\t}\n\t\tthis.pending.clear();\n\t\tthis.handlers.clear();\n\t\tthis.backlog = [];\n\t\t// No-op: owning client manages registry lifecycle.\n\t}\n}\n\nexport function createChannelBridge(client: PulseSocketIOClient, id: string): ChannelBridge {\n\treturn new ChannelBridge(client, id);\n}\n","import React, { type FormEvent, forwardRef, useCallback } from \"react\";\n\nexport type PulseFormProps = React.ComponentPropsWithoutRef<\"form\"> & {\n\taction: string;\n};\n\n/**\n * PulseForm intercepts native form submissions and sends them through fetch so the\n * surrounding Pulse view stays mounted. Server-side handlers are still invoked via\n * the form action endpoint and reactive updates propagate over the socket.\n */\nexport const PulseForm = forwardRef<HTMLFormElement, PulseFormProps>(function PulseForm(\n\t{ onSubmit, action, ...rest },\n\tref,\n) {\n\treturn (\n\t\t<form\n\t\t\t{...rest}\n\t\t\taction={action}\n\t\t\tref={ref}\n\t\t\tonSubmit={useCallback(\n\t\t\t\t(event: FormEvent<HTMLFormElement>) => submitForm({ event, action, onSubmit }),\n\t\t\t\t[action, onSubmit],\n\t\t\t)}\n\t\t/>\n\t);\n});\n\ninterface SubmitForm {\n\tevent: React.FormEvent<HTMLFormElement>;\n\taction: string;\n\tonSubmit?: PulseFormProps[\"onSubmit\"];\n\tformData?: FormData;\n\tforce?: boolean;\n}\n\nexport async function submitForm({ event, action, onSubmit, formData, force }: SubmitForm) {\n\tonSubmit?.(event);\n\tif (!force && event.defaultPrevented) {\n\t\treturn;\n\t}\n\tconst form = event.currentTarget;\n\tevent.preventDefault();\n\tconst nativeEvent = event.nativeEvent as SubmitEvent;\n\tif (!formData) {\n\t\tformData = new FormData(form, nativeEvent.submitter);\n\t}\n\tconst url = new URL(action, window.location.href);\n\ttry {\n\t\tawait fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\t// Required for our hosting scenarios of same host + different ports or 2 subdomains\n\t\t\tcredentials: \"include\",\n\t\t\tbody: formData,\n\t\t});\n\t} catch (err) {\n\t\tif (process.env.NODE_ENV !== \"production\") {\n\t\t\tconsole.error(\"[Pulse] Form submission failed\", err);\n\t\t} else {\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n","import type { LoaderFunctionArgs } from \"react-router\";\n\nexport interface RouteInfo {\n\tpathname: string;\n\thash: string;\n\tquery: string;\n\tqueryParams: Record<string, string>;\n\tpathParams: Record<string, string | undefined>;\n\tcatchall: string[];\n}\n\nexport function extractServerRouteInfo({ params, request }: LoaderFunctionArgs) {\n\tconst { \"*\": catchall = \"\", ...pathParams } = params;\n\tconst parsedUrl = new URL(request.url);\n\n\treturn {\n\t\thash: parsedUrl.hash,\n\t\tpathname: parsedUrl.pathname,\n\t\tquery: parsedUrl.search,\n\t\tqueryParams: Object.fromEntries(parsedUrl.searchParams.entries()),\n\t\tpathParams,\n\t\tcatchall: catchall.length > 1 ? catchall.split(\"/\") : [],\n\t} satisfies RouteInfo;\n}\n","type Simplify<T> = { [K in keyof T]: T[K] } & {};\n\nexport function createExtractor<T extends object>() {\n\tfunction _createExtractor<\n\t\tconst K extends readonly (keyof T)[],\n\t\tC extends Partial<Record<K[number] | string, (src: T) => any>>,\n\t>(keys: K, computed?: C) {\n\t\treturn (\n\t\t\tsrc: T,\n\t\t): Simplify<\n\t\t\tPick<T, K[number]> & {\n\t\t\t\t[P in keyof C]-?: C[P] extends (...args: any) => infer R ? R : never;\n\t\t\t}\n\t\t> => {\n\t\t\tconst out: any = {};\n\t\t\tfor (const key of keys) {\n\t\t\t\tout[key as string] = (src as any)[key as string];\n\t\t\t}\n\t\t\tif (computed) {\n\t\t\t\tfor (const key in computed) {\n\t\t\t\t\tconst fn = computed[key]!;\n\t\t\t\t\tout[key] = fn(src);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out;\n\t\t};\n\t}\n\treturn _createExtractor;\n}\n","import { createExtractor } from \"./extractor\";\n\n// Base extractors (camelCase) similar to events.ts style\nconst lowerTagName = (e: Element) => e.tagName.toLowerCase();\n\nconst ELEMENT_KEYS = [\n\t\"id\",\n\t\"className\",\n\t\"tagName\",\n\t\"localName\",\n\t\"clientHeight\",\n\t\"clientLeft\",\n\t\"clientTop\",\n\t\"clientWidth\",\n\t\"scrollHeight\",\n\t\"scrollLeft\",\n\t\"scrollTop\",\n\t\"scrollWidth\",\n\t\"slot\",\n] as const satisfies readonly (keyof Element)[];\n\nconst HTML_OR_SVG_KEYS = [\n\t\"autofocus\",\n\t\"tabIndex\",\n\t\"nonce\",\n] as const satisfies readonly (keyof HTMLOrSVGElement)[];\n\nconst HTML_ELEMENT_BASE_KEYS = [\n\t\"accessKey\",\n\t\"accessKeyLabel\",\n\t\"autocapitalize\",\n\t\"dir\",\n\t\"draggable\",\n\t\"hidden\",\n\t\"inert\",\n\t\"lang\",\n\t\"offsetHeight\",\n\t\"offsetLeft\",\n\t\"offsetTop\",\n\t\"offsetWidth\",\n\t\"popover\",\n\t\"spellcheck\",\n\t\"title\",\n\t\"translate\",\n\t\"writingSuggestions\",\n\t\"contentEditable\",\n\t\"enterKeyHint\",\n\t\"isContentEditable\",\n\t\"inputMode\",\n] as const satisfies readonly (keyof HTMLElement)[];\n\nconst extractElement = createExtractor<Element>()(ELEMENT_KEYS, {\n\ttagName: lowerTagName,\n});\n\nconst extractHTMLOrSVGElement = createExtractor<HTMLOrSVGElement>()(HTML_OR_SVG_KEYS);\n\nconst extractHTMLElementBaseOnly = createExtractor<HTMLElement>()(HTML_ELEMENT_BASE_KEYS);\n\nfunction extractHTMLElementBase(elt: HTMLElement) {\n\treturn {\n\t\t...extractElement(elt),\n\t\t...extractHTMLOrSVGElement(elt as HTMLOrSVGElement),\n\t\t...extractHTMLElementBaseOnly(elt),\n\t};\n}\n\n// Helper to compose per-element extractors with the shared base\nfunction withBase<T extends HTMLElement>(\n\tkeys: readonly (keyof T)[],\n\tcomputed?: Partial<Record<string, (src: T) => any>>,\n) {\n\tconst only = createExtractor<T>()(keys, computed as any);\n\treturn (elt: T) => ({ ...extractHTMLElementBase(elt), ...only(elt) });\n}\n\nconst HTML_ANCHOR_KEYS = [\n\t\"hash\",\n\t\"host\",\n\t\"hostname\",\n\t\"href\",\n\t\"origin\",\n\t\"password\",\n\t\"pathname\",\n\t\"port\",\n\t\"protocol\",\n\t\"search\",\n\t\"target\",\n\t\"download\",\n\t\"rel\",\n\t\"hreflang\",\n\t\"type\",\n\t\"username\",\n\t\"ping\",\n\t\"referrerPolicy\",\n\t\"text\",\n] as const satisfies readonly (keyof HTMLAnchorElement)[];\nconst anchorExtractor = withBase<HTMLAnchorElement>(HTML_ANCHOR_KEYS);\n\nconst HTML_AREA_KEYS = [\n\t\"alt\",\n\t\"coords\",\n\t\"download\",\n\t\"hash\",\n\t\"host\",\n\t\"hostname\",\n\t\"href\",\n\t\"origin\",\n\t\"password\",\n\t\"pathname\",\n\t\"port\",\n\t\"protocol\",\n\t\"rel\",\n\t\"search\",\n\t\"shape\",\n\t\"target\",\n\t\"username\",\n\t\"ping\",\n\t\"referrerPolicy\",\n] as const satisfies readonly (keyof HTMLAreaElement)[];\nconst areaExtractor = withBase<HTMLAreaElement>(HTML_AREA_KEYS);\n\nconst HTML_MEDIA_KEYS = [\n\t\"autoplay\",\n\t\"controls\",\n\t\"crossOrigin\",\n\t\"currentSrc\",\n\t\"currentTime\",\n\t\"defaultMuted\",\n\t\"defaultPlaybackRate\",\n\t\"duration\",\n\t\"ended\",\n\t\"loop\",\n\t\"muted\",\n\t\"networkState\",\n\t\"paused\",\n\t\"playbackRate\",\n\t\"preload\",\n\t\"readyState\",\n\t\"seeking\",\n\t\"src\",\n\t\"volume\",\n\t\"preservesPitch\",\n] as const satisfies readonly (keyof HTMLMediaElement)[];\nconst mediaExtractor = withBase<HTMLMediaElement>(HTML_MEDIA_KEYS);\n\nconst audioExtractor = (elt: HTMLAudioElement) => mediaExtractor(elt);\n\nconst HTML_BUTTON_KEYS = [\n\t\"disabled\",\n\t\"name\",\n\t\"type\",\n\t\"value\",\n\t\"formAction\",\n\t\"formEnctype\",\n\t\"formMethod\",\n\t\"formNoValidate\",\n\t\"formTarget\",\n\t\"popoverTargetAction\",\n] as const satisfies readonly (keyof HTMLButtonElement)[];\nconst buttonExtractor = withBase<HTMLButtonElement>(HTML_BUTTON_KEYS);\n\nconst HTML_DATA_KEYS = [\"value\"] as const satisfies readonly (keyof HTMLDataElement)[];\nconst dataExtractor = withBase<HTMLDataElement>(HTML_DATA_KEYS);\n\nconst HTML_EMBED_KEYS = [\n\t\"height\",\n\t\"src\",\n\t\"type\",\n\t\"width\",\n\t\"align\",\n\t\"name\",\n] as const satisfies readonly (keyof HTMLEmbedElement)[];\nconst embedExtractor = withBase<HTMLEmbedElement>(HTML_EMBED_KEYS);\n\nconst HTML_FIELDSET_KEYS = [\n\t\"disabled\",\n\t\"name\",\n\t\"type\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLFieldSetElement)[];\nconst fieldsetExtractor = withBase<HTMLFieldSetElement>(HTML_FIELDSET_KEYS);\n\nconst HTML_FORM_KEYS = [\n\t\"acceptCharset\",\n\t\"action\",\n\t\"autocomplete\",\n\t\"encoding\",\n\t\"enctype\",\n\t\"length\",\n\t\"method\",\n\t\"name\",\n\t\"noValidate\",\n\t\"target\",\n\t\"rel\",\n] as const satisfies readonly (keyof HTMLFormElement)[];\nconst formExtractor = withBase<HTMLFormElement>(HTML_FORM_KEYS);\n\nconst HTML_IFRAME_KEYS = [\n\t\"allow\",\n\t\"allowFullscreen\",\n\t\"height\",\n\t\"name\",\n\t\"referrerPolicy\",\n\t\"src\",\n\t\"srcdoc\",\n\t\"width\",\n\t\"align\",\n\t\"frameBorder\",\n\t\"longDesc\",\n\t\"marginHeight\",\n\t\"marginWidth\",\n\t\"scrolling\",\n\t\"sandbox\",\n] as const satisfies readonly (keyof HTMLIFrameElement)[];\nconst iframeExtractor = withBase<HTMLIFrameElement>(HTML_IFRAME_KEYS);\n\nconst HTML_IMAGE_KEYS = [\n\t\"alt\",\n\t\"crossOrigin\",\n\t\"decoding\",\n\t\"height\",\n\t\"isMap\",\n\t\"loading\",\n\t\"naturalHeight\",\n\t\"naturalWidth\",\n\t\"referrerPolicy\",\n\t\"sizes\",\n\t\"src\",\n\t\"srcset\",\n\t\"useMap\",\n\t\"width\",\n\t\"align\",\n\t\"border\",\n\t\"complete\",\n\t\"hspace\",\n\t\"longDesc\",\n\t\"lowsrc\",\n\t\"name\",\n\t\"vspace\",\n\t\"x\",\n\t\"y\",\n\t\"fetchPriority\",\n] as const satisfies readonly (keyof HTMLImageElement)[];\nconst imageExtractor = withBase<HTMLImageElement>(HTML_IMAGE_KEYS);\n\nconst HTML_INPUT_KEYS = [\n\t\"accept\",\n\t\"alt\",\n\t\"autocomplete\",\n\t\"checked\",\n\t\"defaultChecked\",\n\t\"defaultValue\",\n\t\"dirName\",\n\t\"disabled\",\n\t\"height\",\n\t\"indeterminate\",\n\t\"max\",\n\t\"maxLength\",\n\t\"min\",\n\t\"minLength\",\n\t\"multiple\",\n\t\"name\",\n\t\"pattern\",\n\t\"placeholder\",\n\t\"readOnly\",\n\t\"required\",\n\t\"selectionDirection\",\n\t\"selectionEnd\",\n\t\"selectionStart\",\n\t\"size\",\n\t\"src\",\n\t\"step\",\n\t\"type\",\n\t\"value\",\n\t\"valueAsNumber\",\n\t\"width\",\n\t\"align\",\n\t\"capture\",\n\t\"formAction\",\n\t\"formEnctype\",\n\t\"formMethod\",\n\t\"formNoValidate\",\n\t\"formTarget\",\n\t\"useMap\",\n\t\"validationMessage\",\n\t\"willValidate\",\n\t\"popoverTargetAction\",\n] as const satisfies readonly (keyof HTMLInputElement)[];\nconst inputExtractor = withBase<HTMLInputElement>(HTML_INPUT_KEYS);\n\nconst HTML_LABEL_KEYS = [\"htmlFor\"] as const satisfies readonly (keyof HTMLLabelElement)[];\nconst labelExtractor = withBase<HTMLLabelElement>(HTML_LABEL_KEYS);\n\nconst HTML_LI_KEYS = [\"value\", \"type\"] as const satisfies readonly (keyof HTMLLIElement)[];\nconst liExtractor = withBase<HTMLLIElement>(HTML_LI_KEYS);\n\nconst HTML_LINK_KEYS = [\n\t\"as\",\n\t\"crossOrigin\",\n\t\"disabled\",\n\t\"fetchPriority\",\n\t\"href\",\n\t\"hreflang\",\n\t\"imageSizes\",\n\t\"imageSrcset\",\n\t\"integrity\",\n\t\"media\",\n\t\"referrerPolicy\",\n\t\"rel\",\n\t\"type\",\n\t\"charset\",\n\t\"rev\",\n\t\"target\",\n\t\"sizes\",\n] as const satisfies readonly (keyof HTMLLinkElement)[];\nconst linkExtractor = withBase<HTMLLinkElement>(HTML_LINK_KEYS);\n\nconst HTML_MAP_KEYS = [\"name\"] as const satisfies readonly (keyof HTMLMapElement)[];\nconst mapExtractor = withBase<HTMLMapElement>(HTML_MAP_KEYS);\n\nconst HTML_METER_KEYS = [\n\t\"high\",\n\t\"low\",\n\t\"max\",\n\t\"min\",\n\t\"optimum\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLMeterElement)[];\nconst meterExtractor = withBase<HTMLMeterElement>(HTML_METER_KEYS);\n\nconst HTML_MOD_KEYS = [\"cite\", \"dateTime\"] as const satisfies readonly (keyof HTMLModElement)[];\nconst modExtractor = withBase<HTMLModElement>(HTML_MOD_KEYS);\n\nconst HTML_OL_KEYS = [\n\t\"reversed\",\n\t\"start\",\n\t\"type\",\n\t\"compact\",\n] as const satisfies readonly (keyof HTMLOListElement)[];\nconst olistExtractor = withBase<HTMLOListElement>(HTML_OL_KEYS);\n\nconst HTML_OBJECT_KEYS = [\n\t\"data\",\n\t\"height\",\n\t\"name\",\n\t\"type\",\n\t\"useMap\",\n\t\"width\",\n\t\"validationMessage\",\n\t\"willValidate\",\n\t\"align\",\n\t\"archive\",\n\t\"border\",\n\t\"code\",\n\t\"codeBase\",\n\t\"codeType\",\n\t\"declare\",\n\t\"hspace\",\n\t\"standby\",\n\t\"vspace\",\n] as const satisfies readonly (keyof HTMLObjectElement)[];\nconst objectExtractor = withBase<HTMLObjectElement>(HTML_OBJECT_KEYS);\n\nconst HTML_OPTGROUP_KEYS = [\n\t\"disabled\",\n\t\"label\",\n] as const satisfies readonly (keyof HTMLOptGroupElement)[];\nconst optgroupExtractor = withBase<HTMLOptGroupElement>(HTML_OPTGROUP_KEYS);\n\nconst HTML_OPTION_KEYS = [\n\t\"defaultSelected\",\n\t\"disabled\",\n\t\"index\",\n\t\"label\",\n\t\"selected\",\n\t\"text\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLOptionElement)[];\nconst optionExtractor = withBase<HTMLOptionElement>(HTML_OPTION_KEYS);\n\nconst HTML_OUTPUT_KEYS = [\n\t\"defaultValue\",\n\t\"name\",\n\t\"type\",\n\t\"value\",\n\t\"htmlFor\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLOutputElement)[];\nconst outputExtractor = withBase<HTMLOutputElement>(HTML_OUTPUT_KEYS);\n\nconst HTML_PROGRESS_KEYS = [\n\t\"max\",\n\t\"position\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLProgressElement)[];\nconst progressExtractor = withBase<HTMLProgressElement>(HTML_PROGRESS_KEYS);\n\nconst HTML_QUOTE_KEYS = [\"cite\"] as const satisfies readonly (keyof HTMLQuoteElement)[];\nconst quoteExtractor = withBase<HTMLQuoteElement>(HTML_QUOTE_KEYS);\n\nconst citeExtractor = (elt: HTMLElement) => extractHTMLElementBase(elt);\n\nconst HTML_SCRIPT_KEYS = [\n\t\"async\",\n\t\"crossOrigin\",\n\t\"defer\",\n\t\"fetchPriority\",\n\t\"integrity\",\n\t\"noModule\",\n\t\"referrerPolicy\",\n\t\"src\",\n\t\"text\",\n\t\"type\",\n\t\"charset\",\n] as const satisfies readonly (keyof HTMLScriptElement)[];\nconst extractHTMLScriptOnly = createExtractor<HTMLScriptElement>()(HTML_SCRIPT_KEYS, {\n\tevent: (s) => (s as any).event,\n\thtmlFor: (s) => (s as any).htmlFor,\n});\nconst scriptExtractor = (elt: HTMLScriptElement) => ({\n\t...extractHTMLElementBase(elt),\n\t...extractHTMLScriptOnly(elt),\n});\n\nconst HTML_SELECT_KEYS = [\n\t\"autocomplete\",\n\t\"disabled\",\n\t\"length\",\n\t\"multiple\",\n\t\"name\",\n\t\"required\",\n\t\"selectedIndex\",\n\t\"size\",\n\t\"type\",\n\t\"value\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLSelectElement)[];\nconst selectExtractor = withBase<HTMLSelectElement>(HTML_SELECT_KEYS);\n\nconst HTML_SLOT_KEYS = [\"name\"] as const satisfies readonly (keyof HTMLSlotElement)[];\nconst slotExtractor = withBase<HTMLSlotElement>(HTML_SLOT_KEYS);\n\nconst HTML_SOURCE_KEYS = [\n\t\"height\",\n\t\"media\",\n\t\"sizes\",\n\t\"src\",\n\t\"srcset\",\n\t\"type\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLSourceElement)[];\nconst sourceExtractor = withBase<HTMLSourceElement>(HTML_SOURCE_KEYS);\n\nconst HTML_TABLE_CAPTION_KEYS = [\n\t\"align\",\n] as const satisfies readonly (keyof HTMLTableCaptionElement)[];\nconst tableCaptionExtractor = withBase<HTMLTableCaptionElement>(HTML_TABLE_CAPTION_KEYS);\n\nconst HTML_TABLE_CELL_KEYS = [\n\t\"abbr\",\n\t\"cellIndex\",\n\t\"colSpan\",\n\t\"headers\",\n\t\"rowSpan\",\n\t\"scope\",\n\t\"align\",\n\t\"axis\",\n\t\"bgColor\",\n\t\"ch\",\n\t\"chOff\",\n\t\"height\",\n\t\"noWrap\",\n\t\"vAlign\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableCellElement)[];\nconst tableCellExtractor = withBase<HTMLTableCellElement>(HTML_TABLE_CELL_KEYS);\n\nconst HTML_TABLE_COL_KEYS = [\n\t\"span\",\n\t\"align\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableColElement)[];\nconst tableColExtractor = withBase<HTMLTableColElement>(HTML_TABLE_COL_KEYS);\n\nconst HTML_TABLE_KEYS = [\n\t\"align\",\n\t\"bgColor\",\n\t\"border\",\n\t\"cellPadding\",\n\t\"cellSpacing\",\n\t\"frame\",\n\t\"rules\",\n\t\"summary\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableElement)[];\nconst tableExtractor = withBase<HTMLTableElement>(HTML_TABLE_KEYS);\n\nconst HTML_TR_KEYS = [\n\t\"rowIndex\",\n\t\"sectionRowIndex\",\n\t\"align\",\n\t\"bgColor\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n] as const satisfies readonly (keyof HTMLTableRowElement)[];\nconst tableRowExtractor = withBase<HTMLTableRowElement>(HTML_TR_KEYS);\n\nconst HTML_TSECTION_KEYS = [\n\t\"align\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n] as const satisfies readonly (keyof HTMLTableSectionElement)[];\nconst tableSectionExtractor = withBase<HTMLTableSectionElement>(HTML_TSECTION_KEYS);\n\nconst templateExtractor = (elt: HTMLTemplateElement) => extractHTMLElementBase(elt);\n\nconst HTML_TEXTAREA_KEYS = [\n\t\"autocomplete\",\n\t\"cols\",\n\t\"defaultValue\",\n\t\"dirName\",\n\t\"disabled\",\n\t\"maxLength\",\n\t\"minLength\",\n\t\"name\",\n\t\"placeholder\",\n\t\"readOnly\",\n\t\"required\",\n\t\"rows\",\n\t\"selectionDirection\",\n\t\"selectionEnd\",\n\t\"selectionStart\",\n\t\"value\",\n\t\"wrap\",\n\t\"textLength\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLTextAreaElement)[];\nconst textareaExtractor = withBase<HTMLTextAreaElement>(HTML_TEXTAREA_KEYS);\n\nconst HTML_TIME_KEYS = [\"dateTime\"] as const satisfies readonly (keyof HTMLTimeElement)[];\nconst timeExtractor = withBase<HTMLTimeElement>(HTML_TIME_KEYS);\n\nconst HTML_TRACK_KEYS = [\n\t\"default\",\n\t\"kind\",\n\t\"label\",\n\t\"readyState\",\n\t\"src\",\n\t\"srclang\",\n] as const satisfies readonly (keyof HTMLTrackElement)[];\nconst trackExtractor = withBase<HTMLTrackElement>(HTML_TRACK_KEYS);\n\nconst HTML_VIDEO_KEYS = [\n\t\"height\",\n\t\"poster\",\n\t\"videoHeight\",\n\t\"videoWidth\",\n\t\"width\",\n\t\"playsInline\",\n] as const satisfies readonly (keyof HTMLVideoElement)[];\nconst extractHTMLVideoOnly = createExtractor<HTMLVideoElement>()(HTML_VIDEO_KEYS);\nconst videoExtractor = (elt: HTMLVideoElement) => ({\n\t...mediaExtractor(elt),\n\t...extractHTMLVideoOnly(elt),\n});\n\nconst HTML_BR_KEYS = [\"clear\"] as const satisfies readonly (keyof HTMLBRElement)[];\nconst brExtractor = withBase<HTMLBRElement>(HTML_BR_KEYS);\n\nconst HTML_BASE_KEYS = [\"href\", \"target\"] as const satisfies readonly (keyof HTMLBaseElement)[];\nconst baseExtractor = withBase<HTMLBaseElement>(HTML_BASE_KEYS);\n\nconst HTML_BODY_KEYS = [\n\t\"aLink\",\n\t\"background\",\n\t\"bgColor\",\n\t\"link\",\n\t\"text\",\n\t\"vLink\",\n] as const satisfies readonly (keyof HTMLBodyElement)[];\nconst bodyExtractor = withBase<HTMLBodyElement>(HTML_BODY_KEYS);\n\nconst HTML_DLIST_KEYS = [\"compact\"] as const satisfies readonly (keyof HTMLDListElement)[];\nconst dlistExtractor = withBase<HTMLDListElement>(HTML_DLIST_KEYS);\n\nconst HTML_DETAILS_KEYS = [\"open\"] as const satisfies readonly (keyof HTMLDetailsElement)[];\nconst detailsExtractor = withBase<HTMLDetailsElement>(HTML_DETAILS_KEYS);\n\nconst HTML_DIALOG_KEYS = [\n\t\"open\",\n\t\"returnValue\",\n] as const satisfies readonly (keyof HTMLDialogElement)[];\nconst dialogExtractor = withBase<HTMLDialogElement>(HTML_DIALOG_KEYS);\n\nconst HTML_DIV_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLDivElement)[];\nconst divExtractor = withBase<HTMLDivElement>(HTML_DIV_KEYS);\n\nconst headExtractor = (elt: HTMLHeadElement) => extractHTMLElementBase(elt);\n\nconst HTML_HEADING_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLHeadingElement)[];\nconst headingExtractor = withBase<HTMLHeadingElement>(HTML_HEADING_KEYS);\n\nconst HTML_HR_KEYS = [\n\t\"align\",\n\t\"color\",\n\t\"noShade\",\n\t\"size\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLHRElement)[];\nconst hrExtractor = withBase<HTMLHRElement>(HTML_HR_KEYS);\n\nconst HTML_HTML_KEYS = [\"version\"] as const satisfies readonly (keyof HTMLHtmlElement)[];\nconst htmlExtractor = withBase<HTMLHtmlElement>(HTML_HTML_KEYS);\n\nconst menuExtractor = (elt: HTMLMenuElement) => extractHTMLElementBase(elt);\n\nconst HTML_META_KEYS = [\n\t\"content\",\n\t\"httpEquiv\",\n\t\"name\",\n\t\"scheme\",\n] as const satisfies readonly (keyof HTMLMetaElement)[];\nconst metaExtractor = withBase<HTMLMetaElement>(HTML_META_KEYS);\n\nconst HTML_P_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLParagraphElement)[];\nconst paragraphExtractor = withBase<HTMLParagraphElement>(HTML_P_KEYS);\n\nconst pictureExtractor = (elt: HTMLPictureElement) => extractHTMLElementBase(elt);\n\nconst HTML_PRE_KEYS = [\"width\"] as const satisfies readonly (keyof HTMLPreElement)[];\nconst preExtractor = withBase<HTMLPreElement>(HTML_PRE_KEYS);\n\nconst spanExtractor = (elt: HTMLSpanElement) => extractHTMLElementBase(elt);\n\nconst HTML_STYLE_KEYS = [\n\t\"media\",\n\t\"type\",\n\t\"disabled\",\n] as const satisfies readonly (keyof HTMLStyleElement)[];\nconst styleExtractor = withBase<HTMLStyleElement>(HTML_STYLE_KEYS);\n\nconst HTML_TITLE_KEYS = [\"text\"] as const satisfies readonly (keyof HTMLTitleElement)[];\nconst titleExtractor = withBase<HTMLTitleElement>(HTML_TITLE_KEYS);\n\nconst HTML_UL_KEYS = [\"compact\", \"type\"] as const satisfies readonly (keyof HTMLUListElement)[];\nconst ulistExtractor = withBase<HTMLUListElement>(HTML_UL_KEYS);\n\n// Map of tagName -> extractor (concise, like events.ts)\nconst elementExtractors: Record<string, (elt: any) => object> = {\n\tA: anchorExtractor,\n\tAREA: areaExtractor,\n\tAUDIO: audioExtractor,\n\tBASE: baseExtractor,\n\tBLOCKQUOTE: quoteExtractor,\n\tQ: quoteExtractor,\n\tBODY: bodyExtractor,\n\tBR: brExtractor,\n\tBUTTON: buttonExtractor,\n\tCANVAS: extractHTMLElementBase,\n\tCAPTION: tableCaptionExtractor,\n\tCITE: citeExtractor,\n\tCOL: tableColExtractor,\n\tCOLGROUP: tableColExtractor,\n\tDATA: dataExtractor,\n\tDETAILS: detailsExtractor,\n\tDIALOG: dialogExtractor,\n\tDIV: divExtractor,\n\tDL: dlistExtractor,\n\tEMBED: embedExtractor,\n\tFIELDSET: fieldsetExtractor,\n\tFORM: formExtractor,\n\tH1: headingExtractor,\n\tH2: headingExtractor,\n\tH3: headingExtractor,\n\tH4: headingExtractor,\n\tH5: headingExtractor,\n\tH6: headingExtractor,\n\tHEAD: headExtractor,\n\tHR: hrExtractor,\n\tHTML: htmlExtractor,\n\tIFRAME: iframeExtractor,\n\tIMG: imageExtractor,\n\tINPUT: inputExtractor,\n\tLABEL: labelExtractor,\n\tLI: liExtractor,\n\tLINK: linkExtractor,\n\tMAP: mapExtractor,\n\tMENU: menuExtractor,\n\tMETA: metaExtractor,\n\tMETER: meterExtractor,\n\tINS: modExtractor,\n\tDEL: modExtractor,\n\tOBJECT: objectExtractor,\n\tOL: olistExtractor,\n\tOPTGROUP: optgroupExtractor,\n\tOPTION: optionExtractor,\n\tOUTPUT: outputExtractor,\n\tP: paragraphExtractor,\n\tPICTURE: pictureExtractor,\n\tPRE: preExtractor,\n\tPROGRESS: progressExtractor,\n\tSCRIPT: scriptExtractor,\n\tSELECT: selectExtractor,\n\tSLOT: slotExtractor,\n\tSOURCE: sourceExtractor,\n\tSPAN: spanExtractor,\n\tSTYLE: styleExtractor,\n\tTABLE: tableExtractor,\n\tTBODY: tableSectionExtractor,\n\tTHEAD: tableSectionExtractor,\n\tTFOOT: tableSectionExtractor,\n\tTD: tableCellExtractor,\n\tTH: tableCellExtractor,\n\tTEMPLATE: templateExtractor,\n\tTEXTAREA: textareaExtractor,\n\tTIME: timeExtractor,\n\tTITLE: titleExtractor,\n\tTR: tableRowExtractor,\n\tTRACK: trackExtractor,\n\tUL: ulistExtractor,\n\tVIDEO: videoExtractor,\n};\n\nexport function extractHTMLElement(elt: HTMLElement): object {\n\tconst tagName = elt.tagName.toUpperCase();\n\n\tconst extractor = elementExtractors[tagName];\n\tif (extractor) {\n\t\treturn extractor(elt);\n\t}\n\tthrow new Error(`Unexpected HTML element tag: ${elt.tagName} (update .web/custom/serialize.ts)`);\n}\n","/* === IMPORTANT === */\n\nimport { extractHTMLElement } from \"./elements\";\nimport { createExtractor } from \"./extractor\";\n\n// Reusable computed mappers (helps bundlers/minifiers share references)\nconst mapTarget = (e: { target: EventTarget | null }) =>\n\textractHTMLElement(e.target as HTMLElement);\nconst mapRelated = (e: { relatedTarget: EventTarget | null }) =>\n\te.relatedTarget ? extractHTMLElement(e.relatedTarget as HTMLElement) : null;\n\nfunction makeExtractor<K extends readonly any[]>(\n\tkeys: K,\n\tcomputed?: Record<string, (evt: any) => any>,\n) {\n\treturn createExtractor<any>()(\n\t\tkeys as any,\n\t\t{\n\t\t\ttarget: mapTarget,\n\t\t\t...(computed || {}),\n\t\t} as any,\n\t);\n}\n\nconst SYNTHETIC_KEYS = [\n\t\"target\",\n\t\"bubbles\",\n\t\"cancelable\",\n\t\"defaultPrevented\",\n\t\"eventPhase\",\n\t\"isTrusted\",\n\t\"timeStamp\",\n\t\"type\",\n] as const satisfies readonly (keyof React.SyntheticEvent)[];\n\nconst UI_KEYS = [...SYNTHETIC_KEYS, \"detail\"] as const satisfies readonly (keyof React.UIEvent)[];\n\nconst MOUSE_KEYS = [\n\t...UI_KEYS,\n\t\"altKey\",\n\t\"button\",\n\t\"buttons\",\n\t\"clientX\",\n\t\"clientY\",\n\t\"ctrlKey\",\n\t\"metaKey\",\n\t\"movementX\",\n\t\"movementY\",\n\t\"pageX\",\n\t\"pageY\",\n\t\"screenX\",\n\t\"screenY\",\n\t\"shiftKey\",\n] as const satisfies readonly (keyof React.MouseEvent)[];\n\nconst POINTER_KEYS = [\n\t...MOUSE_KEYS,\n\t\"pointerId\",\n\t\"pressure\",\n\t\"tangentialPressure\",\n\t\"tiltX\",\n\t\"tiltY\",\n\t\"twist\",\n\t\"width\",\n\t\"height\",\n\t\"pointerType\",\n\t\"isPrimary\",\n] as const satisfies readonly (keyof React.PointerEvent)[];\n\nconst syntheticExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst uiExtractor = makeExtractor(UI_KEYS);\n\nconst mouseExtractor = makeExtractor(MOUSE_KEYS, { relatedTarget: mapRelated });\n\nconst clipboardExtractor = makeExtractor(SYNTHETIC_KEYS, {\n\tclipboardData: (e) => extractDataTransfer(e.clipboardData),\n});\n\nconst compositionExtractor = makeExtractor([...SYNTHETIC_KEYS, \"data\"] as const);\n\nconst dragExtractor = makeExtractor(MOUSE_KEYS, {\n\trelatedTarget: mapRelated,\n\tdataTransfer: (e) => extractDataTransfer(e.dataTransfer),\n});\n\nconst pointerExtractor = makeExtractor(POINTER_KEYS, {\n\trelatedTarget: mapRelated,\n});\n\nconst focusExtractor = makeExtractor(SYNTHETIC_KEYS, {\n\trelatedTarget: mapRelated,\n});\n\nconst formExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst invalidExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst changeExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst keyboardExtractor = makeExtractor([\n\t...UI_KEYS,\n\t\"altKey\",\n\t\"ctrlKey\",\n\t\"code\",\n\t\"key\",\n\t\"locale\",\n\t\"location\",\n\t\"metaKey\",\n\t\"repeat\",\n\t\"shiftKey\",\n] as const);\n\nconst touchExtractor = makeExtractor(\n\t[\n\t\t...UI_KEYS,\n\t\t\"altKey\",\n\t\t\"ctrlKey\",\n\t\t\"metaKey\",\n\t\t\"shiftKey\",\n\t\t\"changedTouches\",\n\t\t\"targetTouches\",\n\t\t\"touches\",\n\t] as const,\n\t{\n\t\tchangedTouches: (e) => mapTouchList(e.changedTouches),\n\t\ttargetTouches: (e) => mapTouchList(e.targetTouches),\n\t\ttouches: (e) => mapTouchList(e.touches),\n\t},\n);\n\nconst wheelExtractor = makeExtractor(\n\t[...MOUSE_KEYS, \"deltaMode\", \"deltaX\", \"deltaY\", \"deltaZ\"] as const,\n\t{\n\t\trelatedTarget: mapRelated,\n\t},\n);\n\nconst animationExtractor = makeExtractor([\n\t...SYNTHETIC_KEYS,\n\t\"animationName\",\n\t\"elapsedTime\",\n\t\"pseudoElement\",\n] as const);\n\nconst toggleExtractor = makeExtractor([...SYNTHETIC_KEYS, \"oldState\", \"newState\"] as const);\n\nconst transitionExtractor = makeExtractor([\n\t...SYNTHETIC_KEYS,\n\t\"elapsedTime\",\n\t\"propertyName\",\n\t\"pseudoElement\",\n] as const);\n\nfunction mapTouchList(list: any): any[] {\n\treturn Array.from(list as ArrayLike<any>).map((touch: any) => ({\n\t\ttarget: extractHTMLElement(touch.target as HTMLElement),\n\t\tidentifier: touch.identifier,\n\t\tscreenX: touch.screenX,\n\t\tscreenY: touch.screenY,\n\t\tclientX: touch.clientX,\n\t\tclientY: touch.clientY,\n\t\tpageX: touch.pageX,\n\t\tpageY: touch.pageY,\n\t}));\n}\n\n// Helper function to extract DataTransfer properties\nfunction extractDataTransfer(dt: DataTransfer | null): object | null {\n\tif (!dt) {\n\t\treturn null;\n\t}\n\tconst items = [];\n\tif (dt.items) {\n\t\tfor (let i = 0; i < dt.items.length; i++) {\n\t\t\tconst item = dt.items[i]!;\n\t\t\titems.push({\n\t\t\t\tkind: item.kind,\n\t\t\t\ttype: item.type,\n\t\t\t});\n\t\t}\n\t}\n\treturn {\n\t\tdrop_effect: dt.dropEffect,\n\t\teffect_allowed: dt.effectAllowed,\n\t\titems: items,\n\t\ttypes: Array.from(dt.types || []),\n\t};\n}\n\nconst eventExtractorMap: { [key: string]: (evt: any) => object } = {};\n\nfunction add(map: Record<string, any>, names: readonly string[], fn: any) {\n\tfor (const n of names) map[n] = fn;\n}\n\nadd(\n\teventExtractorMap,\n\t[\n\t\t\"pointerdown\",\n\t\t\"pointermove\",\n\t\t\"pointerup\",\n\t\t\"pointercancel\",\n\t\t\"gotpointercapture\",\n\t\t\"lostpointercapture\",\n\t\t\"pointerenter\",\n\t\t\"pointerleave\",\n\t\t\"pointerover\",\n\t\t\"pointerout\",\n\t],\n\tpointerExtractor,\n);\n\nadd(\n\teventExtractorMap,\n\t[\n\t\t\"click\",\n\t\t\"contextmenu\",\n\t\t\"dblclick\",\n\t\t\"mousedown\",\n\t\t\"mouseenter\",\n\t\t\"mouseleave\",\n\t\t\"mousemove\",\n\t\t\"mouseout\",\n\t\t\"mouseover\",\n\t\t\"mouseup\",\n\t],\n\tmouseExtractor,\n);\n\nadd(\n\teventExtractorMap,\n\t[\"drag\", \"dragend\", \"dragenter\", \"dragexit\", \"dragleave\", \"dragover\", \"dragstart\", \"drop\"],\n\tdragExtractor,\n);\n\nadd(eventExtractorMap, [\"keydown\", \"keypress\", \"keyup\"], keyboardExtractor);\nadd(eventExtractorMap, [\"focus\", \"blur\"], focusExtractor);\nadd(eventExtractorMap, [\"change\", \"input\"], changeExtractor);\nadd(eventExtractorMap, [\"invalid\"], invalidExtractor);\nadd(eventExtractorMap, [\"reset\", \"submit\"], formExtractor);\nadd(eventExtractorMap, [\"copy\", \"cut\", \"paste\"], clipboardExtractor);\nadd(\n\teventExtractorMap,\n\t[\"compositionend\", \"compositionstart\", \"compositionupdate\"],\n\tcompositionExtractor,\n);\nadd(eventExtractorMap, [\"touchcancel\", \"touchend\", \"touchmove\", \"touchstart\"], touchExtractor);\nadd(eventExtractorMap, [\"scroll\"], uiExtractor);\nadd(eventExtractorMap, [\"wheel\"], wheelExtractor);\nadd(\n\teventExtractorMap,\n\t[\"animationstart\", \"animationend\", \"animationiteration\"],\n\tanimationExtractor,\n);\nadd(eventExtractorMap, [\"transitionend\"], transitionExtractor);\nadd(eventExtractorMap, [\"toggle\"], toggleExtractor);\n\nexport function extractEvent(value: any): any {\n\t// Duck-typing for React's SyntheticEvent.\n\t// We check for properties that are unique to synthetic events.\n\tif (\n\t\tvalue &&\n\t\ttypeof value === \"object\" &&\n\t\t\"nativeEvent\" in value &&\n\t\ttypeof value.isDefaultPrevented === \"function\"\n\t) {\n\t\tconst evt = value as React.SyntheticEvent;\n\t\t// The `type` property is crucial for the lookup.\n\t\tif (typeof evt.type !== \"string\") {\n\t\t\treturn value;\n\t\t}\n\n\t\tconst extractor = eventExtractorMap[evt.type.toLowerCase()];\n\t\tif (extractor) {\n\t\t\treturn extractor(evt);\n\t\t}\n\n\t\t// Fallback for unknown event types: minimal synthetic extractor\n\t\treturn syntheticExtractor(evt);\n\t}\n\n\t// If it's not a duck-typed event, return it as is.\n\treturn value;\n}\n","export type Primitive = number | string | boolean | null | undefined;\nexport type JSON<T> = T | Array<JSON<T>> | { [K: string]: JSON<T> };\nexport type PlainJSON = JSON<Primitive>;\nexport type Serializable = any;\n\nexport type Serialized = [[number[], number[], number[], number[]], PlainJSON];\n\nexport function serialize(data: Serializable): Serialized {\n\tconst seen = new Map<any, number>();\n\tconst refs: number[] = [];\n\tconst dates: number[] = [];\n\tconst sets: number[] = [];\n\tconst maps: number[] = [];\n\n\t// Single global counter - increments once per node visit\n\tlet globalIndex = 0;\n\n\tfunction process(value: Serializable): PlainJSON {\n\t\tif (\n\t\t\tvalue == null ||\n\t\t\ttypeof value === \"number\" ||\n\t\t\ttypeof value === \"string\" ||\n\t\t\ttypeof value === \"boolean\"\n\t\t) {\n\t\t\treturn value;\n\t\t}\n\n\t\tconst idx = globalIndex++;\n\t\tconst prevRef = seen.get(value);\n\t\tif (prevRef !== undefined) {\n\t\t\t// Make sure to push the current index, but use the ref's index as the value!\n\t\t\trefs.push(idx);\n\t\t\treturn prevRef;\n\t\t}\n\n\t\tseen.set(value, idx);\n\n\t\tif (value instanceof Date) {\n\t\t\tdates.push(idx);\n\t\t\treturn value.getTime();\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tconst length = value.length;\n\t\t\tconst result = new Array(length);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tresult[i] = process(value[i]);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tif (value instanceof Map) {\n\t\t\tmaps.push(idx);\n\t\t\tconst rec: Record<string, any> = {};\n\t\t\tfor (const [key, entry] of value.entries()) {\n\t\t\t\trec[String(key)] = process(entry);\n\t\t\t}\n\t\t\treturn rec;\n\t\t}\n\n\t\tif (value instanceof Set) {\n\t\t\tsets.push(idx);\n\t\t\tconst size = value.size;\n\t\t\tconst result = new Array(size);\n\t\t\tlet i = 0;\n\t\t\tfor (const entry of value) {\n\t\t\t\tresult[i] = process(entry);\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tif (typeof value === \"object\") {\n\t\t\tconst rec: Record<string, any> = {};\n\t\t\tconst keys = Object.keys(value);\n\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\tconst key = keys[i];\n\t\t\t\trec[key] = process(value[key]);\n\t\t\t}\n\t\t\treturn rec;\n\t\t}\n\n\t\tthrow new Error(`Unsupported value in serialization: ${value}`);\n\t}\n\n\tconst payload = process(data);\n\treturn [[refs, dates, sets, maps], payload];\n}\n\nexport interface DeserializationOptions {\n\tcoerceNullsToUndefined?: boolean;\n}\n\nexport function deserialize<Data extends Serializable = Serializable>(\n\tpayload: Serialized,\n\toptions?: DeserializationOptions,\n): Data {\n\tconst [[refsA, datesA, setsA, mapsA], data] = payload;\n\n\tconst refs = new Set(refsA);\n\tconst dates = new Set(datesA);\n\tconst sets = new Set(setsA);\n\tconst maps = new Set(mapsA);\n\n\tconst objects: Array<any> = [];\n\n\tfunction reconstruct(value: PlainJSON): any {\n\t\tconst idx = objects.length;\n\t\tif (refs.has(idx)) {\n\t\t\t// We increment the counter on refs during serialization. We're never\n\t\t\t// going to use this entry, so we can just push null.\n\t\t\tobjects.push(null);\n\t\t\treturn objects[value as number];\n\t\t}\n\n\t\tif (dates.has(idx)) {\n\t\t\tconst dt = new Date(value as number);\n\t\t\tobjects.push(dt);\n\t\t\treturn dt;\n\t\t}\n\n\t\tif (\n\t\t\tvalue == null ||\n\t\t\ttypeof value === \"number\" ||\n\t\t\ttypeof value === \"string\" ||\n\t\t\ttypeof value === \"boolean\"\n\t\t) {\n\t\t\tif (options?.coerceNullsToUndefined) {\n\t\t\t\treturn value ?? undefined;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tif (sets.has(idx)) {\n\t\t\t\tconst result = new Set();\n\t\t\t\tobjects.push(result);\n\t\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\t\tresult.add(reconstruct(value[i]));\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tconst length = value.length;\n\t\t\tconst arr = new Array(length);\n\t\t\tobjects.push(arr);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tarr[i] = reconstruct(value[i]);\n\t\t\t}\n\t\t\treturn arr;\n\t\t}\n\n\t\tif (typeof value === \"object\") {\n\t\t\tif (maps.has(idx)) {\n\t\t\t\tconst result = new Map<string, any>();\n\t\t\t\tobjects.push(result);\n\t\t\t\tconst keys = Object.keys(value);\n\t\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\t\tconst key = keys[i];\n\t\t\t\t\tresult.set(key, reconstruct(value[key]));\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tconst result: Record<string, any> = {};\n\t\t\tobjects.push(result);\n\t\t\tconst keys = Object.keys(value);\n\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\tconst key = keys[i];\n\t\t\t\tresult[key] = reconstruct(value[key]);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tthrow new Error(`Unsupported value in deserialization: ${value}`);\n\t}\n\n\treturn reconstruct(data);\n}\n","import type { NavigateFunction } from \"react-router\";\nimport { io, type Socket } from \"socket.io-client\";\nimport type { ChannelBridge } from \"./channel\";\nimport { createChannelBridge, PulseChannelResetError } from \"./channel\";\nimport type { RouteInfo } from \"./helpers\";\nimport type {\n\tClientApiResultMessage,\n\tClientMessage,\n\tServerApiCallMessage,\n\tServerChannelMessage,\n\tServerErrorInfo,\n\tServerMessage,\n} from \"./messages\";\nimport type { PulsePrerenderView } from \"./pulse\";\nimport { extractEvent } from \"./serialize/events\";\nimport { deserialize, serialize } from \"./serialize/serializer\";\nimport type { VDOMUpdate } from \"./vdom\";\n\nexport interface SocketIODirectives {\n\theaders?: Record<string, string>;\n\tauth?: Record<string, string>;\n}\nexport interface Directives {\n\theaders?: Record<string, string>;\n\tsocketio?: SocketIODirectives;\n}\nexport interface MountedView {\n\trouteInfo: RouteInfo;\n\tonInit: (view: PulsePrerenderView) => void;\n\tonUpdate: (ops: VDOMUpdate[]) => void;\n}\nexport type ConnectionStatusListener = (connected: boolean) => void;\nexport type ServerErrorListener = (path: string, error: ServerErrorInfo | null) => void;\n\nexport interface PulseClient {\n\t// Connection management\n\tconnect(): Promise<void>;\n\tdisconnect(): void;\n\tisConnected(): boolean;\n\tonConnectionChange(listener: ConnectionStatusListener): () => void;\n\t// Messages\n\tnavigate(path: string, routeInfo: RouteInfo): Promise<void>;\n\tleave(path: string): Promise<void>;\n\tinvokeCallback(path: string, callback: string, args: any[]): Promise<void>;\n\t// VDOM subscription\n\tmountView(path: string, view: MountedView): () => void;\n}\n\nexport class PulseSocketIOClient {\n\t#activeViews: Map<string, MountedView>;\n\t#socket: Socket | null = null;\n\t#messageQueue: ClientMessage[];\n\t#connectionListeners: Set<ConnectionStatusListener> = new Set();\n\t#serverErrors: Map<string, ServerErrorInfo> = new Map();\n\t#serverErrorListeners: Set<ServerErrorListener> = new Set();\n\t#channels: Map<string, { bridge: ChannelBridge; refCount: number }> = new Map();\n\t#url: string;\n\t#frameworkNavigate: NavigateFunction;\n\t#directives: Directives;\n\n\tconstructor(url: string, directives: Directives, frameworkNavigate: NavigateFunction) {\n\t\tthis.#url = url;\n\t\tthis.#directives = directives;\n\t\tthis.#frameworkNavigate = frameworkNavigate;\n\t\tthis.#socket = null;\n\t\tthis.#activeViews = new Map();\n\t\tthis.#messageQueue = [];\n\t\t// Load directives from sessionStorage\n\t\tif (typeof window !== \"undefined\" && typeof sessionStorage !== \"undefined\") {\n\t\t\tconst stored = sessionStorage.getItem(\"__PULSE_DIRECTIVES\");\n\t\t\tif (stored) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.#directives = JSON.parse(stored);\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore parse errors\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tpublic setDirectives(directives: Directives) {\n\t\tthis.#directives = directives;\n\t}\n\tpublic isConnected(): boolean {\n\t\treturn this.#socket?.connected ?? false;\n\t}\n\n\tpublic async connect(): Promise<void> {\n\t\tif (this.#socket) {\n\t\t\treturn;\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst socket = io(this.#url, {\n\t\t\t\ttransports: [\"websocket\", \"webtransport\"],\n\t\t\t\tauth: this.#directives.socketio?.auth,\n\t\t\t\textraHeaders: this.#directives.socketio?.headers,\n\t\t\t});\n\t\t\tthis.#socket = socket;\n\n\t\t\tsocket.on(\"connect\", () => {\n\t\t\t\tconsole.log(\"[SocketIOTransport] Connected:\", this.#socket?.id);\n\t\t\t\t// Make sure to send a navigate payload for all the routes\n\t\t\t\tfor (const [path, route] of this.#activeViews) {\n\t\t\t\t\tsocket.emit(\n\t\t\t\t\t\t\"message\",\n\t\t\t\t\t\tserialize({\n\t\t\t\t\t\t\ttype: \"mount\",\n\t\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\t\trouteInfo: route.routeInfo,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tfor (const payload of this.#messageQueue) {\n\t\t\t\t\t// Already sent above\n\t\t\t\t\tif (payload.type === \"mount\" && this.#activeViews.has(payload.path)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t// We're remounting all the routes, so no need to navigate\n\t\t\t\t\tif (payload.type === \"navigate\") {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tsocket.emit(\"message\", serialize(payload));\n\t\t\t\t}\n\t\t\t\tthis.#messageQueue = [];\n\n\t\t\t\tthis.notifyConnectionListeners(true);\n\t\t\t\tresolve();\n\t\t\t});\n\n\t\t\tsocket.on(\"connect_error\", (err) => {\n\t\t\t\tconsole.error(\"[SocketIOTransport] Connection failed:\", err);\n\t\t\t\tthis.notifyConnectionListeners(false);\n\t\t\t\treject(err);\n\t\t\t});\n\n\t\t\tsocket.on(\"disconnect\", () => {\n\t\t\t\tconsole.log(\"[SocketIOTransport] Disconnected\");\n\t\t\t\tthis.#handleTransportDisconnect();\n\t\t\t\tthis.notifyConnectionListeners(false);\n\t\t\t});\n\n\t\t\t// Wrap in an arrow function to avoid losing the `this` reference\n\t\t\tsocket.on(\"message\", (data) =>\n\t\t\t\tthis.#handleServerMessage(deserialize(data, { coerceNullsToUndefined: true })),\n\t\t\t);\n\t\t});\n\t}\n\n\tonConnectionChange(listener: ConnectionStatusListener): () => void {\n\t\tthis.#connectionListeners.add(listener);\n\t\t// Only notify immediately if we've attempted connection (socket exists)\n\t\t// This prevents showing error before first connection attempt\n\t\tif (this.#socket !== null) {\n\t\t\tlistener(this.isConnected());\n\t\t}\n\t\treturn () => {\n\t\t\tthis.#connectionListeners.delete(listener);\n\t\t};\n\t}\n\n\tprivate notifyConnectionListeners(connected: boolean): void {\n\t\tfor (const listener of this.#connectionListeners) {\n\t\t\tlistener(connected);\n\t\t}\n\t}\n\n\tpublic onServerError(listener: ServerErrorListener): () => void {\n\t\tthis.#serverErrorListeners.add(listener);\n\t\t// Emit current errors to new listener\n\t\tfor (const [path, err] of this.#serverErrors) listener(path, err);\n\t\treturn () => {\n\t\t\tthis.#serverErrorListeners.delete(listener);\n\t\t};\n\t}\n\n\tprivate notifyServerError(path: string, error: ServerErrorInfo | null) {\n\t\tfor (const listener of this.#serverErrorListeners) listener(path, error);\n\t}\n\n\tpublic sendMessage(payload: ClientMessage) {\n\t\tif (this.isConnected()) {\n\t\t\t// console.log(\"[SocketIOTransport] Sending:\", payload);\n\t\t\tthis.#socket!.emit(\"message\", serialize(payload as any));\n\t\t} else {\n\t\t\t// console.log(\"[SocketIOTransport] Queuing message:\", payload);\n\t\t\tthis.#messageQueue.push(payload);\n\t\t}\n\t}\n\n\tpublic mountView(path: string, view: MountedView) {\n\t\tif (this.#activeViews.has(path)) {\n\t\t\tthrow new Error(`Path ${path} is already mounted`);\n\t\t}\n\t\tthis.#activeViews.set(path, view);\n\t\tvoid this.sendMessage({\n\t\t\ttype: \"mount\",\n\t\t\tpath,\n\t\t\trouteInfo: view.routeInfo,\n\t\t});\n\t}\n\n\tpublic navigate(path: string, routeInfo: RouteInfo) {\n\t\tthis.sendMessage({\n\t\t\ttype: \"navigate\",\n\t\t\tpath,\n\t\t\trouteInfo,\n\t\t});\n\t}\n\n\tpublic unmount(path: string) {\n\t\tvoid this.sendMessage({ type: \"unmount\", path });\n\t\tthis.#activeViews.delete(path);\n\t}\n\n\tpublic disconnect() {\n\t\tthis.#socket?.disconnect();\n\t\tthis.#socket = null;\n\t\tthis.#messageQueue = [];\n\t\tthis.#connectionListeners.clear();\n\t\tthis.#activeViews.clear();\n\t\tthis.#serverErrors.clear();\n\t\tthis.#serverErrorListeners.clear();\n\t\tfor (const { bridge } of this.#channels.values()) {\n\t\t\tbridge.dispose(new PulseChannelResetError(\"Client disconnected\"));\n\t\t}\n\t\tthis.#channels.clear();\n\t}\n\n\t#handleServerMessage(message: ServerMessage) {\n\t\t// console.log(\"[PulseClient] Received message:\", message);\n\t\tswitch (message.type) {\n\t\t\tcase \"vdom_init\": {\n\t\t\t\tconst route = this.#activeViews.get(message.path);\n\t\t\t\t// Ignore messages for paths that are not mounted\n\t\t\t\tif (!route) return;\n\t\t\t\tif (route) {\n\t\t\t\t\troute.onInit(message);\n\t\t\t\t}\n\t\t\t\t// Clear any prior error for this path on successful init\n\t\t\t\tif (this.#serverErrors.has(message.path)) {\n\t\t\t\t\tthis.#serverErrors.delete(message.path);\n\t\t\t\t\tthis.notifyServerError(message.path, null);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"vdom_update\": {\n\t\t\t\tconst route = this.#activeViews.get(message.path);\n\t\t\t\tif (!route) return; // Not an active path; discard\n\t\t\t\troute.onUpdate(message.ops);\n\t\t\t\t// Clear any prior error for this path on successful update\n\t\t\t\tif (this.#serverErrors.has(message.path)) {\n\t\t\t\t\tthis.#serverErrors.delete(message.path);\n\t\t\t\t\tthis.notifyServerError(message.path, null);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"server_error\": {\n\t\t\t\tif (!this.#activeViews.has(message.path)) return; // discard for inactive paths\n\t\t\t\tthis.#serverErrors.set(message.path, message.error);\n\t\t\t\tthis.notifyServerError(message.path, message.error);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"api_call\": {\n\t\t\t\tvoid this.#performApiCall(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"navigate_to\": {\n\t\t\t\t// `navigate_to` is navigational; allow regardless of activeViews membership\n\t\t\t\tconst replace = !!message.replace;\n\t\t\t\tlet dest = message.path || \"\";\n\t\t\t\t// Normalize protocol-relative URLs to absolute\n\t\t\t\tif (dest.startsWith(\"//\")) dest = `${window.location.protocol}${dest}`;\n\t\t\t\tconst hasScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(dest);\n\t\t\t\tif (hasScheme) {\n\t\t\t\t\tif (dest.startsWith(\"http://\") || dest.startsWith(\"https://\")) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst url = new URL(dest);\n\t\t\t\t\t\t\tif (url.origin === window.location.origin) {\n\t\t\t\t\t\t\t\tconst internal = `${url.pathname}${url.search}${url.hash}`;\n\t\t\t\t\t\t\t\tthis.#frameworkNavigate(internal, { replace });\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (replace) window.location.replace(dest);\n\t\t\t\t\t\t\t\telse window.location.assign(dest);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tif (replace) window.location.replace(dest);\n\t\t\t\t\t\t\telse window.location.assign(dest);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// mailto:, tel:, data:, etc.\n\t\t\t\t\t\tif (replace) window.location.replace(dest);\n\t\t\t\t\t\telse window.location.assign(dest);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Relative or root-relative path → SPA navigate\n\t\t\t\t\tthis.#frameworkNavigate(dest, { replace });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"channel_message\": {\n\t\t\t\tthis.#routeChannelMessage(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconsole.error(\"Unexpected message:\", message);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync #performApiCall(msg: ServerApiCallMessage) {\n\t\ttry {\n\t\t\tconst res = await fetch(msg.url, {\n\t\t\t\tmethod: msg.method || \"GET\",\n\t\t\t\theaders: {\n\t\t\t\t\t...(msg.headers || {}),\n\t\t\t\t\t...(msg.body != null && !(\"content-type\" in (msg.headers || {}))\n\t\t\t\t\t\t? { \"content-type\": \"application/json\" }\n\t\t\t\t\t\t: {}),\n\t\t\t\t},\n\t\t\t\tbody:\n\t\t\t\t\tmsg.body != null\n\t\t\t\t\t\t? typeof msg.body === \"string\"\n\t\t\t\t\t\t\t? msg.body\n\t\t\t\t\t\t\t: JSON.stringify(msg.body)\n\t\t\t\t\t\t: undefined,\n\t\t\t\tcredentials: msg.credentials || \"include\",\n\t\t\t});\n\t\t\tconst headersObj: Record<string, string> = {};\n\t\t\tres.headers.forEach((v, k) => {\n\t\t\t\theadersObj[k] = v;\n\t\t\t});\n\t\t\tlet body: any = null;\n\t\t\tconst ct = res.headers.get(\"content-type\") || \"\";\n\t\t\tif (ct.includes(\"application/json\")) {\n\t\t\t\tbody = await res.json().catch(() => null);\n\t\t\t} else {\n\t\t\t\tbody = await res.text().catch(() => null);\n\t\t\t}\n\t\t\tconst reply: ClientApiResultMessage = {\n\t\t\t\ttype: \"api_result\",\n\t\t\t\tid: msg.id,\n\t\t\t\tok: res.ok,\n\t\t\t\tstatus: res.status,\n\t\t\t\theaders: headersObj,\n\t\t\t\tbody,\n\t\t\t};\n\t\t\tthis.sendMessage(reply);\n\t\t} catch (err) {\n\t\t\tconst reply: ClientApiResultMessage = {\n\t\t\t\ttype: \"api_result\",\n\t\t\t\tid: msg.id,\n\t\t\t\tok: false,\n\t\t\t\tstatus: 0,\n\t\t\t\theaders: {},\n\t\t\t\tbody: { error: String(err) },\n\t\t\t};\n\t\t\tthis.sendMessage(reply);\n\t\t}\n\t}\n\n\tpublic invokeCallback(path: string, callback: string, args: any[]) {\n\t\tthis.sendMessage({\n\t\t\ttype: \"callback\",\n\t\t\tpath,\n\t\t\tcallback,\n\t\t\targs: args.map(extractEvent),\n\t\t});\n\t}\n\n\tpublic acquireChannel(id: string): ChannelBridge {\n\t\tconst entry = this.#ensureChannelEntry(id);\n\t\tentry.refCount += 1;\n\t\treturn entry.bridge;\n\t}\n\n\tpublic releaseChannel(id: string): void {\n\t\tconst entry = this.#channels.get(id);\n\t\tif (!entry) {\n\t\t\treturn;\n\t\t}\n\t\tentry.refCount = Math.max(0, entry.refCount - 1);\n\t\tif (entry.refCount === 0) {\n\t\t\tentry.bridge.dispose(new PulseChannelResetError(\"Channel released\"));\n\t\t\tthis.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: id,\n\t\t\t\tevent: \"__close__\",\n\t\t\t\tpayload: { reason: \"refcount_zero\" },\n\t\t\t});\n\t\t\tthis.#channels.delete(id);\n\t\t}\n\t}\n\n\t#ensureChannelEntry(id: string): {\n\t\tbridge: ChannelBridge;\n\t\trefCount: number;\n\t} {\n\t\tlet entry = this.#channels.get(id);\n\t\tif (!entry) {\n\t\t\tentry = {\n\t\t\t\tbridge: createChannelBridge(this, id),\n\t\t\t\trefCount: 0,\n\t\t\t};\n\t\t\tthis.#channels.set(id, entry);\n\t\t}\n\t\treturn entry;\n\t}\n\n\t#routeChannelMessage(message: ServerChannelMessage): void {\n\t\tconst entry = this.#ensureChannelEntry(message.channel);\n\t\tconst closed = entry.bridge.handleServerMessage(message);\n\t\tif (closed && entry.refCount === 0) {\n\t\t\tthis.#channels.delete(message.channel);\n\t\t}\n\t}\n\n\t#handleTransportDisconnect(): void {\n\t\tfor (const entry of this.#channels.values()) {\n\t\t\tentry.bridge.handleDisconnect(new PulseChannelResetError(\"Connection lost\"));\n\t\t}\n\t}\n}\n","import type { ComponentType } from \"react\";\n\n// Special prefixes for reserved node types\nexport const FRAGMENT_TAG = \"$$fragment\";\nexport const MOUNT_POINT_PREFIX = \"$$\";\n\n// export type LazyComponent = () => Promise<{ default: ComponentType<any> }>;\nexport type RegistryEntry = ComponentType<any>;\nexport type ComponentRegistry = Record<string, ComponentType<any>>;\n\nexport interface VDOMElement {\n\ttag: string;\n\tprops?: Record<string, any>;\n\tchildren?: VDOMNode[];\n\tkey?: string;\n\tlazy?: boolean;\n}\n\n// Primitive nodes that can be rendered\nexport type PrimitiveNode = string | number | boolean;\n\n// VDOMNode is either a primitive (string, number, boolean) or an element node.\n// Booleans are valid children in React but do not render anything.\n// Mount points are just UIElementNodes with tags starting with $$ComponentKey\nexport type VDOMNode = PrimitiveNode | VDOMElement;\n\nexport type VDOM = VDOMNode;\n\nexport interface VDOMUpdateBase {\n\ttype: string;\n\tpath: string; // Dot-separated path to the node\n}\n\nexport interface ReplaceUpdate extends VDOMUpdateBase {\n\ttype: \"replace\";\n\tdata: VDOMNode; // The new node\n}\n\nexport interface UpdatePropsUpdate extends VDOMUpdateBase {\n\ttype: \"update_props\";\n\tdata: {\n\t\tset?: Record<string, any>;\n\t\tremove?: string[];\n\t};\n}\n\nexport interface ReconciliationUpdate {\n\ttype: \"reconciliation\";\n\tpath: string;\n\tN: number;\n\tnew: [number[], VDOM[]];\n\treuse: [number[], number[]];\n}\n\nexport interface PathDelta {\n\tadd?: string[];\n\tremove?: string[];\n}\n\nexport interface UpdateCallbacksUpdate extends VDOMUpdateBase {\n\ttype: \"update_callbacks\";\n\tdata: PathDelta;\n}\n\nexport interface UpdateRenderPropsUpdate extends VDOMUpdateBase {\n\ttype: \"update_render_props\";\n\tdata: PathDelta;\n}\n\nexport interface UpdateCssRefsUpdate extends VDOMUpdateBase {\n\ttype: \"update_css_refs\";\n\tdata: PathDelta;\n}\n\nexport type VDOMUpdate =\n\t| ReplaceUpdate\n\t| UpdatePropsUpdate\n\t| ReconciliationUpdate\n\t| UpdateCallbacksUpdate\n\t| UpdateRenderPropsUpdate\n\t| UpdateCssRefsUpdate;\n\nexport type UpdateType = VDOMUpdate[\"type\"];\n\n// Utility functions for working with the UI tree structure\nexport function isElementNode(node: VDOMNode): node is VDOMElement {\n\t// Matches all non-text nodes\n\treturn typeof node === \"object\" && node !== null;\n}\n\nexport function isMountPointNode(node: VDOMNode): node is VDOMElement {\n\treturn (\n\t\ttypeof node === \"object\" &&\n\t\tnode !== null &&\n\t\tnode.tag.startsWith(MOUNT_POINT_PREFIX) &&\n\t\tnode.tag !== FRAGMENT_TAG\n\t);\n}\n\nexport function isTextNode(node: VDOMNode): node is string {\n\treturn typeof node === \"string\";\n}\n\nexport function isFragment(node: VDOMNode): boolean {\n\treturn typeof node === \"object\" && node !== null && node.tag === FRAGMENT_TAG;\n}\n","import {\n\ttype ComponentType,\n\tcloneElement,\n\tcreateElement,\n\ttype FC,\n\tFragment,\n\tisValidElement,\n\tlazy,\n\ttype PropsWithChildren,\n\ttype ReactElement,\n\ttype ReactNode,\n\tSuspense,\n} from \"react\";\nimport type { PulseSocketIOClient } from \"./client\";\nimport type { PulsePrerenderView } from \"./pulse\";\nimport type { ComponentRegistry, PathDelta, VDOMNode, VDOMUpdate } from \"./vdom\";\nimport { FRAGMENT_TAG, isElementNode, isMountPointNode, MOUNT_POINT_PREFIX } from \"./vdom\";\n\nexport class VDOMRenderer {\n\t#callbacks: Set<string>;\n\t#callbackCache: Map<string, (...args: any) => void>;\n\t#renderPropKeys: Set<string>;\n\t#cssProps: Set<string>;\n\t#callbackList: string[];\n\t#client: PulseSocketIOClient;\n\t#path: string;\n\t#components: ComponentRegistry;\n\t#cssModules: Record<string, Record<string, string>>;\n\n\tconstructor(\n\t\tclient: PulseSocketIOClient,\n\t\tpath: string,\n\t\tcomponents: ComponentRegistry,\n\t\tcssModules: Record<string, Record<string, string>>,\n\t\tinitialCallbacks: string[] = [],\n\t\tinitialRenderProps: string[] = [],\n\t\tinitialCssRefs: string[] = [],\n\t) {\n\t\tthis.#client = client;\n\t\tthis.#path = path;\n\t\tthis.#components = components;\n\t\tthis.#cssModules = cssModules;\n\t\tthis.#callbacks = new Set(initialCallbacks);\n\t\tthis.#callbackCache = new Map();\n\t\tthis.#renderPropKeys = new Set(initialRenderProps);\n\t\tthis.#cssProps = new Set(initialCssRefs);\n\t\tthis.#callbackList = [...this.#callbacks].sort();\n\t}\n\n\t// Accessors used by update logic to determine which props need rebinding\n\thasCallbackPath(path: string) {\n\t\treturn this.#callbacks.has(path);\n\t}\n\n\thasRenderPropPath(path: string) {\n\t\treturn this.#renderPropKeys.has(path);\n\t}\n\n\thasAnyCallbackUnder(prefix: string): boolean {\n\t\tif (prefix === \"\") return this.#callbackList.length > 0;\n\t\tconst i = this.#lowerBound(this.#callbackList, prefix);\n\t\treturn i < this.#callbackList.length && this.#callbackList[i]!.startsWith(prefix);\n\t}\n\n\tapplyCallbackDelta(delta: PathDelta) {\n\t\t// Only update the internal callback path registry and cache. We rely on\n\t\t// accompanying update_props operations that contain the \"$cb\" placeholder\n\t\t// to trigger prop updates; transformValue will resolve to functions.\n\t\tif (delta.remove) {\n\t\t\tfor (const key of delta.remove) {\n\t\t\t\tthis.#callbacks.delete(key);\n\t\t\t\tthis.#callbackCache.delete(key);\n\t\t\t}\n\t\t}\n\t\tif (delta.add) {\n\t\t\tfor (const key of delta.add) {\n\t\t\t\tthis.#callbacks.add(key);\n\t\t\t}\n\t\t}\n\t\tthis.#callbackList = [...this.#callbacks].sort();\n\t}\n\n\tapplyRenderPropsDelta(delta: PathDelta) {\n\t\tif (delta.remove) {\n\t\t\tfor (const key of delta.remove) {\n\t\t\t\tthis.#renderPropKeys.delete(key);\n\t\t\t}\n\t\t}\n\t\tif (delta.add) {\n\t\t\tfor (const key of delta.add) {\n\t\t\t\tthis.#renderPropKeys.add(key);\n\t\t\t}\n\t\t}\n\t}\n\n\tapplyCssRefsDelta(delta: PathDelta) {\n\t\tif (delta.remove) {\n\t\t\tfor (const prop of delta.remove) {\n\t\t\t\tthis.#cssProps.delete(prop);\n\t\t\t}\n\t\t}\n\t\tif (delta.add) {\n\t\t\tfor (const prop of delta.add) {\n\t\t\t\tthis.#cssProps.add(prop);\n\t\t\t}\n\t\t}\n\t}\n\n\tgetCallback(path: string, prop: string) {\n\t\tconst key = this.#propPath(path, prop);\n\t\tlet fn = this.#callbackCache.get(key);\n\t\tif (!fn) {\n\t\t\tfn = (...args: any[]) => this.#client.invokeCallback(this.#path, key, args);\n\t\t\tthis.#callbackCache.set(key, fn);\n\t\t}\n\t\treturn fn;\n\t}\n\n\trenderNode(node: VDOMNode, currentPath = \"\"): ReactNode {\n\t\t// Handle primitives early\n\t\tif (\n\t\t\tnode == null || // catches both null and undefined\n\t\t\ttypeof node === \"boolean\" ||\n\t\t\ttypeof node === \"number\" ||\n\t\t\ttypeof node === \"string\"\n\t\t) {\n\t\t\treturn node;\n\t\t}\n\n\t\t// Element nodes\n\t\tif (isElementNode(node)) {\n\t\t\tconst { tag, props = {}, children = [] } = node;\n\n\t\t\tconst newProps: Record<string, any> = {};\n\t\t\tfor (const [propName, propValue] of Object.entries(props)) {\n\t\t\t\tnewProps[propName] = this.transformValue(currentPath, propName, propValue);\n\t\t\t}\n\n\t\t\tif (node.key) {\n\t\t\t\tnewProps.key = node.key;\n\t\t\t}\n\n\t\t\tconst renderedChildren = [];\n\t\t\tfor (let index = 0; index < children.length; index += 1) {\n\t\t\t\tconst child = children[index]!;\n\t\t\t\tconst childPath = currentPath ? `${currentPath}.${index}` : String(index);\n\t\t\t\trenderedChildren.push(this.renderNode(child, childPath));\n\t\t\t}\n\n\t\t\tif (isMountPointNode(node)) {\n\t\t\t\tconst componentKey = node.tag.slice(MOUNT_POINT_PREFIX.length);\n\t\t\t\tconst Component = this.#components[componentKey]!;\n\t\t\t\tif (!Component) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Could not find component ${componentKey}. This is a Pulse internal error.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn createElement(Component, newProps, ...renderedChildren);\n\t\t\t}\n\n\t\t\treturn createElement(tag === FRAGMENT_TAG ? Fragment : tag, newProps, ...renderedChildren);\n\t\t}\n\n\t\t// Fallback for unknown node types\n\t\tif (process.env.NODE_ENV !== \"production\") {\n\t\t\tconsole.error(\"Unknown VDOM node type:\", node);\n\t\t}\n\t\treturn null;\n\t}\n\n\t#propPath(path: string, prop: string) {\n\t\treturn path ? `${path}.${prop}` : prop;\n\t}\n\n\ttransformValue(path: string, key: string, value: any) {\n\t\tconst propPath = this.#propPath(path, key);\n\t\tif (this.#callbacks.has(propPath)) {\n\t\t\treturn this.getCallback(path, key);\n\t\t}\n\t\tif (this.#renderPropKeys.has(propPath)) {\n\t\t\treturn this.renderNode(value, propPath);\n\t\t}\n\t\tif (this.#cssProps.has(propPath)) {\n\t\t\treturn this.#resolveCssToken(value);\n\t\t}\n\t\treturn value;\n\t}\n\n\t#resolveCssToken(token: string): string {\n\t\tconst idx = token.indexOf(\":\");\n\t\tif (idx === -1) {\n\t\t\treturn token;\n\t\t}\n\t\tconst moduleId = token.slice(0, idx);\n\t\tconst className = token.slice(idx + 1);\n\t\tif (!moduleId || !className) {\n\t\t\treturn token;\n\t\t}\n\t\tconst mod = this.#cssModules[moduleId];\n\t\tif (!mod) {\n\t\t\tthrow new Error(`Received CSS reference for unknown module '${moduleId}'`);\n\t\t}\n\t\tconst resolved = mod[className];\n\t\tif (typeof resolved !== \"string\") {\n\t\t\tthrow new Error(\n\t\t\t\t`Received CSS reference for missing class '${className}' in module '${moduleId}'`,\n\t\t\t);\n\t\t}\n\t\treturn resolved;\n\t}\n\n\tinit(view: PulsePrerenderView): ReactNode {\n\t\t// Set callbacks\n\t\tthis.#callbacks = new Set(view.callbacks);\n\t\t// prune stale cached callbacks\n\t\tfor (const k of Array.from(this.#callbackCache.keys())) {\n\t\t\tif (!this.#callbacks.has(k)) this.#callbackCache.delete(k);\n\t\t}\n\t\tthis.#callbackList = [...this.#callbacks].sort();\n\n\t\t// Set render props\n\t\tthis.#renderPropKeys = new Set(view.render_props);\n\n\t\t// Set CSS refs\n\t\tthis.#cssProps = new Set(view.css_refs);\n\n\t\treturn this.renderNode(view.vdom);\n\t}\n\n\t#ensureChildrenArray(el: ReactElement): ReactNode[] {\n\t\tconst children = (el.props as any)?.children as ReactNode | undefined;\n\t\tif (children == null) return [];\n\t\treturn Array.isArray(children) ? children.slice() : [children];\n\t}\n\n\tapplyUpdates(initialTree: ReactNode, updates: VDOMUpdate[]): ReactNode {\n\t\tlet newTree: ReactNode = initialTree;\n\t\tfor (const update of updates) {\n\t\t\tif (update.type === \"update_callbacks\") {\n\t\t\t\tthis.applyCallbackDelta(update.data);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (update.type === \"update_css_refs\") {\n\t\t\t\tthis.applyCssRefsDelta(update.data);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (update.type === \"update_render_props\") {\n\t\t\t\tthis.applyRenderPropsDelta(update.data);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst parts = update.path.split(\".\").filter((s) => s.length > 0);\n\n\t\t\tconst descend = (node: ReactNode, depth: number, path: string): ReactNode => {\n\t\t\t\tif (depth < parts.length) {\n\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\tconst element = node as ReactElement<Record<string, any> | null>;\n\t\t\t\t\tconst childKey = parts[depth]!;\n\t\t\t\t\tconst childIdx = +childKey;\n\t\t\t\t\tconst childPath = path ? `${path}.${childKey}` : childKey;\n\t\t\t\t\tif (!Number.isNaN(childIdx)) {\n\t\t\t\t\t\t// Regular child traversal\n\t\t\t\t\t\tconst childrenArr = this.#ensureChildrenArray(element);\n\t\t\t\t\t\tconst child = childrenArr[childIdx];\n\t\t\t\t\t\tchildrenArr[childIdx] = descend(child, depth + 1, childPath) as any;\n\t\t\t\t\t\treturn cloneElement(element, undefined, ...childrenArr);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Render prop traversal\n\t\t\t\t\t\tconst baseProps = (element.props ?? {}) as Record<string, any>;\n\t\t\t\t\t\tconst child = baseProps[childKey];\n\t\t\t\t\t\tconst props = {\n\t\t\t\t\t\t\t...baseProps,\n\t\t\t\t\t\t\t[childKey]: descend(child, depth + 1, childPath),\n\t\t\t\t\t\t};\n\t\t\t\t\t\treturn cloneElement(element, props);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tswitch (update.type) {\n\t\t\t\t\tcase \"replace\": {\n\t\t\t\t\t\treturn this.renderNode(update.data, update.path);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"update_props\": {\n\t\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\t\tconst element = node as ReactElement;\n\t\t\t\t\t\tconst currentProps = (element.props ?? {}) as Record<string, any>;\n\t\t\t\t\t\tconst nextProps: Record<string, any> = { ...currentProps };\n\t\t\t\t\t\tconst delta = update.data;\n\t\t\t\t\t\tif (delta.remove && delta.remove.length > 0) {\n\t\t\t\t\t\t\tfor (const key of delta.remove) {\n\t\t\t\t\t\t\t\tif (key in nextProps) {\n\t\t\t\t\t\t\t\t\tdelete nextProps[key];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (delta.set) {\n\t\t\t\t\t\t\tfor (const [k, v] of Object.entries(delta.set)) {\n\t\t\t\t\t\t\t\tnextProps[k] = this.transformValue(path, k, v);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If some props were removed, use `createElement` to fully override\n\t\t\t\t\t\t// the props, as `cloneElement` shallowly merges the new props with\n\t\t\t\t\t\t// the old ones.\n\t\t\t\t\t\tconst removedSomething = (delta.remove?.length ?? 0) > 0;\n\t\t\t\t\t\tif (removedSomething) {\n\t\t\t\t\t\t\t// Preserve key + ref\n\t\t\t\t\t\t\tnextProps.key = element.key;\n\t\t\t\t\t\t\tnextProps.ref = (element as any).ref;\n\t\t\t\t\t\t\treturn createElement(element.type, nextProps, ...this.#ensureChildrenArray(element));\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Don't touch children. Key and ref are transferred by cloneElement.\n\t\t\t\t\t\t\treturn cloneElement(element, nextProps);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase \"reconciliation\": {\n\t\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\t\tconst element = node as ReactElement;\n\t\t\t\t\t\tconst prevChildren = this.#ensureChildrenArray(element);\n\t\t\t\t\t\tconst nextChildren = [];\n\n\t\t\t\t\t\tconst [newIndices, newContents] = update.new;\n\t\t\t\t\t\tconst [reuseIndices, reuseSources] = update.reuse;\n\n\t\t\t\t\t\tlet nextNew = -1,\n\t\t\t\t\t\t\tnextReuse = -1,\n\t\t\t\t\t\t\tnewIdx = -1,\n\t\t\t\t\t\t\treuseIdx = -1;\n\t\t\t\t\t\tif (newIndices.length > 0) {\n\t\t\t\t\t\t\tnextNew = newIndices[0];\n\t\t\t\t\t\t\tnewIdx = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (reuseIndices.length > 0) {\n\t\t\t\t\t\t\tnextReuse = reuseIndices[0];\n\t\t\t\t\t\t\treuseIdx = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (let i = 0; i < update.N; ++i) {\n\t\t\t\t\t\t\tif (i === nextNew) {\n\t\t\t\t\t\t\t\tconst contents = newContents[newIdx];\n\t\t\t\t\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\t\t\t\t\tnextChildren.push(this.renderNode(contents, childPath));\n\t\t\t\t\t\t\t\tnextNew = newIdx < newIndices.length - 1 ? newIndices[++newIdx] : -1;\n\t\t\t\t\t\t\t} else if (i === nextReuse) {\n\t\t\t\t\t\t\t\tconst srcIdx = reuseSources[reuseIdx];\n\t\t\t\t\t\t\t\tlet src = prevChildren[srcIdx];\n\t\t\t\t\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\t\t\t\t\t// The node may have callbacks that need to be updated for this new path\n\t\t\t\t\t\t\t\tif (this.hasAnyCallbackUnder(childPath)) {\n\t\t\t\t\t\t\t\t\tsrc = this.#rebindCallbacksInSubtree(src, childPath);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tnextChildren.push(src);\n\t\t\t\t\t\t\t\tnextReuse = reuseIdx < reuseIndices.length - 1 ? reuseIndices[++reuseIdx] : -1;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// No need to rebind callbacks, the node hasn't moved\n\t\t\t\t\t\t\t\tnextChildren.push(prevChildren[i]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Pass null to reuse previous props\n\t\t\t\t\t\treturn cloneElement(element, null!, ...nextChildren);\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`[Pulse renderer] Unknown update type: ${(update as any)?.type}`);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tnewTree = descend(newTree, 0, \"\");\n\t\t}\n\t\treturn newTree;\n\t}\n\n\t#assertIsElement(node: ReactNode, parts: string[], depth: number): node is ReactElement {\n\t\tif (process.env.NODE_ENV !== \"production\" && !isValidElement(node)) {\n\t\t\tconsole.error(\"Invalid node:\", node);\n\t\t\tthrow new Error(`Invalid node at path ${parts.slice(0, depth).join(\".\")}`);\n\t\t}\n\t\treturn true;\n\t}\n\n\t// Rebind callback function props within a subtree after a path-changing move\n\t#rebindCallbacksInSubtree(node: ReactNode, path: string): ReactNode {\n\t\tif (!isValidElement(node)) return node;\n\t\tconst element = node as ReactElement<Record<string, any> | null>;\n\t\tconst baseProps = (element.props ?? {}) as Record<string, any>;\n\t\tconst nextProps: Record<string, any> = { ...baseProps };\n\n\t\t// Rebind only callback props; CSS refs are path-agnostic and render-props\n\t\t// are handled by the server-side renderer via explicit updates\n\t\tfor (const key of Object.keys(baseProps)) {\n\t\t\tconst propPath = path ? `${path}.${key}` : key;\n\t\t\tif (this.hasCallbackPath(propPath)) {\n\t\t\t\tnextProps[key] = this.getCallback(path, key);\n\t\t\t}\n\t\t\tif (this.hasRenderPropPath(propPath) && this.hasAnyCallbackUnder(propPath)) {\n\t\t\t\tnextProps[key] = this.#rebindCallbacksInSubtree(baseProps[key], propPath);\n\t\t\t}\n\t\t}\n\n\t\tconst children = this.#ensureChildrenArray(element).map((child, idx) => {\n\t\t\tconst childPath = path ? `${path}.${idx}` : String(idx);\n\t\t\tif (this.hasAnyCallbackUnder(childPath)) {\n\t\t\t\treturn this.#rebindCallbacksInSubtree(child, childPath);\n\t\t\t} else {\n\t\t\t\treturn child;\n\t\t\t}\n\t\t});\n\n\t\treturn cloneElement(element, nextProps, ...children);\n\t}\n\n\t// Binary-search lower bound for prefix matching on sorted callback paths\n\t#lowerBound(arr: string[], target: string): number {\n\t\tlet lo = 0;\n\t\tlet hi = arr.length;\n\t\twhile (lo < hi) {\n\t\t\tconst mid = (lo + hi) >>> 1;\n\t\t\tif (arr[mid]! < target) {\n\t\t\t\tlo = mid + 1;\n\t\t\t} else {\n\t\t\t\thi = mid;\n\t\t\t}\n\t\t}\n\t\treturn lo;\n\t}\n}\n\n// The `component` prop should be something like `() =>\n// import('~/path/to/component') (we'll need to remap if we're importing a named export and not the default)\nexport function RenderLazy(\n\tcomponent: () => Promise<{ default: ComponentType<any> }>,\n\tfallback?: ReactNode,\n): FC<PropsWithChildren<unknown>> {\n\tconst Component = lazy(component);\n\treturn ({ children, ...props }: PropsWithChildren<unknown>) => {\n\t\treturn (\n\t\t\t<Suspense fallback={fallback}>\n\t\t\t\t<Component {...props}>{children}</Component>\n\t\t\t</Suspense>\n\t\t);\n\t};\n}\n","import {\n\tcreateContext,\n\ttype ReactNode,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { useLocation, useNavigate, useParams } from \"react-router\";\nimport { type Directives, PulseSocketIOClient } from \"./client\";\nimport type { RouteInfo } from \"./helpers\";\nimport type { ServerErrorInfo } from \"./messages\";\nimport { VDOMRenderer } from \"./renderer\";\nimport type { ComponentRegistry, VDOM } from \"./vdom\";\n\n// =================================================================\n// Types\n// =================================================================\n\nexport interface PulseConfig {\n\tserverAddress: string;\n}\n\nexport type PulsePrerenderView = {\n\tvdom: VDOM;\n\tcallbacks: string[];\n\trender_props: string[];\n\tcss_refs: string[];\n};\n\nexport type PulsePrerender = {\n\tviews: Record<string, PulsePrerenderView>;\n\tdirectives: Directives;\n};\n// =================================================================\n// Context and Hooks\n// =================================================================\n\n// Context for the client, provided by PulseProvider\nconst PulseClientContext = createContext<PulseSocketIOClient | null>(null);\nconst PulsePrerenderContext = createContext<PulsePrerender | null>(null);\n\nexport const usePulseClient = () => {\n\tconst client = useContext(PulseClientContext);\n\tif (!client) {\n\t\tthrow new Error(\"usePulseClient must be used within a PulseProvider\");\n\t}\n\treturn client;\n};\n\nexport const usePulsePrerender = (path: string) => {\n\tconst ctx = useContext(PulsePrerenderContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"usePulsePrerender must be used within a PulseProvider\");\n\t}\n\tconst view = ctx.views[path];\n\tif (!view) {\n\t\tthrow new Error(`No prerender found for '${path}'`);\n\t}\n\treturn view;\n};\n\n// =================================================================\n// Provider\n// =================================================================\n\nexport interface PulseProviderProps {\n\tchildren: ReactNode;\n\tconfig: PulseConfig;\n\tprerender: PulsePrerender;\n}\n\nconst inBrowser = typeof window !== \"undefined\";\n\nexport function PulseProvider({ children, config, prerender }: PulseProviderProps) {\n\tconst [connected, setConnected] = useState(true);\n\tconst rrNavigate = useNavigate();\n\tconst { directives } = prerender;\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: another useEffect syncs the directives without recreating the client\n\tconst client = useMemo(() => {\n\t\treturn new PulseSocketIOClient(config.serverAddress, directives, rrNavigate);\n\t}, [config.serverAddress, rrNavigate]);\n\tuseEffect(() => client.setDirectives(directives), [client, directives]);\n\tuseEffect(() => client.onConnectionChange(setConnected), [client]);\n\tuseEffect(() => {\n\t\tif (inBrowser) {\n\t\t\tclient.connect();\n\t\t\treturn () => client.disconnect();\n\t\t}\n\t}, [client]);\n\n\treturn (\n\t\t<PulseClientContext.Provider value={client}>\n\t\t\t<PulsePrerenderContext.Provider value={prerender}>\n\t\t\t\t{!connected && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tposition: \"fixed\",\n\t\t\t\t\t\t\tbottom: \"20px\",\n\t\t\t\t\t\t\tright: \"20px\",\n\t\t\t\t\t\t\tbackgroundColor: \"red\",\n\t\t\t\t\t\t\tcolor: \"white\",\n\t\t\t\t\t\t\tpadding: \"10px\",\n\t\t\t\t\t\t\tborderRadius: \"5px\",\n\t\t\t\t\t\t\tzIndex: 1000,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tFailed to connect to the server.\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{children}\n\t\t\t</PulsePrerenderContext.Provider>\n\t\t</PulseClientContext.Provider>\n\t);\n}\n\n// =================================================================\n// View\n// =================================================================\n\nexport interface PulseViewProps {\n\texternalComponents: ComponentRegistry;\n\tpath: string;\n\tcssModules: Record<string, Record<string, string>>;\n}\n\nexport function PulseView({ externalComponents, path, cssModules }: PulseViewProps) {\n\tconst client = usePulseClient();\n\tconst initialView = usePulsePrerender(path);\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: We only want to lose the renderer on unmount. initialView will change on every navigation with our current setup, so we hack around it with another useEffect below. This is not ideal and will be fixed in the future.\n\tconst renderer = useMemo(\n\t\t() =>\n\t\t\tnew VDOMRenderer(\n\t\t\t\tclient,\n\t\t\t\tpath,\n\t\t\t\texternalComponents,\n\t\t\t\tcssModules,\n\t\t\t\tinitialView.callbacks,\n\t\t\t\tinitialView.render_props,\n\t\t\t\tinitialView.css_refs,\n\t\t\t),\n\t\t[client, path, externalComponents, cssModules],\n\t);\n\tconst [tree, setTree] = useState<ReactNode>(() => renderer.init(initialView));\n\tconst [serverError, setServerError] = useState<ServerErrorInfo | null>(null);\n\n\tconst location = useLocation();\n\tconst params = useParams();\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: using hacky deep equality for params\n\tconst routeInfo = useMemo(() => {\n\t\tconst { \"*\": catchall = \"\", ...pathParams } = params;\n\t\tconst queryParams = new URLSearchParams(location.search);\n\t\treturn {\n\t\t\thash: location.hash,\n\t\t\tpathname: location.pathname,\n\t\t\tquery: location.search,\n\t\t\tqueryParams: Object.fromEntries(queryParams.entries()),\n\t\t\tpathParams,\n\t\t\tcatchall: catchall.length > 0 ? catchall.split(\"/\") : [],\n\t\t} satisfies RouteInfo;\n\t}, [location.hash, location.pathname, location.search, JSON.stringify(params)]);\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: We don't want to unmount on navigation, so another useEffect sync the routeInfo on navigation.\n\tuseEffect(() => {\n\t\tif (inBrowser) {\n\t\t\tclient.mountView(path, {\n\t\t\t\trouteInfo,\n\t\t\t\tonInit: (view) => {\n\t\t\t\t\tsetTree(renderer.init(view));\n\t\t\t\t},\n\t\t\t\tonUpdate: (ops) => {\n\t\t\t\t\tsetTree((prev) => (prev == null ? prev : renderer.applyUpdates(prev, ops)));\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst offErr = client.onServerError((p, err) => {\n\t\t\t\tif (p === path) setServerError(err);\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\toffErr();\n\t\t\t\tclient.unmount(path);\n\t\t\t};\n\t\t}\n\t\t// routeInfo is NOT included here on purpose\n\t}, [client, renderer, path]);\n\n\tuseEffect(() => {\n\t\tif (inBrowser) {\n\t\t\tclient.navigate(path, routeInfo);\n\t\t}\n\t}, [client, path, routeInfo]);\n\t// Hack for our current prerendering setup on client-side navigation. Will be improved soon\n\tconst hasRendered = useRef(false);\n\tuseEffect(() => {\n\t\t// First rendering pass, no need to update the tree\n\t\tif (!hasRendered.current) {\n\t\t\thasRendered.current = true;\n\t\t}\n\t\t// 2nd+ rendering pass. Happens when a route stays mounted on navigation.\n\t\telse {\n\t\t\tsetTree(renderer.init(initialView));\n\t\t}\n\t\treturn () => {\n\t\t\thasRendered.current = false;\n\t\t};\n\t}, [initialView, renderer]);\n\n\tif (serverError) {\n\t\treturn <ServerError error={serverError} />;\n\t}\n\n\treturn tree;\n}\n\nfunction ServerError({ error }: { error: ServerErrorInfo }) {\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tpadding: 16,\n\t\t\t\tborder: \"1px solid #e00\",\n\t\t\t\tbackground: \"#fff5f5\",\n\t\t\t\tcolor: \"#900\",\n\t\t\t\tfontFamily:\n\t\t\t\t\t'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n\t\t\t\twhiteSpace: \"pre-wrap\",\n\t\t\t}}\n\t\t>\n\t\t\t<div style={{ fontWeight: 700, marginBottom: 8 }}>Server Error during {error.phase}</div>\n\t\t\t{error.message && <div>{error.message}</div>}\n\t\t\t{error.stack && (\n\t\t\t\t<details open style={{ marginTop: 8 }}>\n\t\t\t\t\t<summary>Stack trace</summary>\n\t\t\t\t\t<pre style={{ margin: 0 }}>{error.stack}</pre>\n\t\t\t\t</details>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { useEffect, useMemo } from \"react\";\nimport type { ChannelBridge } from \"./channel\";\nimport { usePulseClient } from \"./pulse\";\n\nexport function usePulseChannel(channelId: string): ChannelBridge {\n\tconst client = usePulseClient();\n\tconst bridge = useMemo(() => {\n\t\tif (!channelId) {\n\t\t\tthrow new Error(\"usePulseChannel requires a non-empty channelId\");\n\t\t}\n\t\treturn client.acquireChannel(channelId);\n\t}, [client, channelId]);\n\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tclient.releaseChannel(channelId);\n\t\t};\n\t}, [client, channelId]);\n\n\treturn bridge;\n}\n"],"mappings":"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ACA,WACA,OACA,iBACA,OACA,CACoE,CAuB/D,GAAgB,EArBC,CACtB,MACA,SACA,WACA,OACA,OACA,WACA,OACA,SACA,WACA,WACA,OACA,WACA,MACA,SACA,QACA,SACA,WACA,OACA,iBACA,CAC8D,CAwBzD,EAAiB,EAtBC,CACvB,WACA,WACA,cACA,aACA,cACA,eACA,sBACA,WACA,QACA,OACA,QACA,eACA,SACA,eACA,UACA,aACA,UACA,MACA,SACA,iBACA,CACiE,CAE5D,GAAkB,GAA0B,EAAe,EAAI,CAc/D,GAAkB,EAZC,CACxB,WACA,OACA,OACA,QACA,aACA,cACA,aACA,iBACA,aACA,sBACA,CACoE,CAG/D,GAAgB,EADC,CAAC,QAAQ,CAC+B,CAUzD,GAAiB,EARC,CACvB,SACA,MACA,OACA,QACA,QACA,OACA,CACiE,CAS5D,GAAoB,EAPC,CAC1B,WACA,OACA,OACA,oBACA,eACA,CAC0E,CAerEC,GAAgB,EAbC,CACtB,gBACA,SACA,eACA,WACA,UACA,SACA,SACA,OACA,aACA,SACA,MACA,CAC8D,CAmBzD,EAAkB,EAjBC,CACxB,QACA,kBACA,SACA,OACA,iBACA,MACA,SACA,QACA,QACA,cACA,WACA,eACA,cACA,YACA,UACA,CACoE,CA6B/D,EAAiB,EA3BC,CACvB,MACA,cACA,WACA,SACA,QACA,UACA,gBACA,eACA,iBACA,QACA,MACA,SACA,SACA,QACA,QACA,SACA,WACA,SACA,WACA,SACA,OACA,SACA,IACA,IACA,gBACA,CACiE,CA6C5D,EAAiB,EA3CC,8ZA0CvB,CACiE,CAG5D,EAAiB,EADC,CAAC,UAAU,CAC+B,CAG5D,EAAc,EADC,CAAC,QAAS,OAAO,CACmB,CAqBnD,GAAgB,EAnBC,CACtB,KACA,cACA,WACA,gBACA,OACA,WACA,aACA,cACA,YACA,QACA,iBACA,MACA,OACA,UACA,MACA,SACA,QACA,CAC8D,CAGzD,GAAe,EADC,CAAC,OAAO,CAC8B,CAUtD,GAAiB,EARC,CACvB,OACA,MACA,MACA,MACA,UACA,QACA,CACiE,CAG5D,EAAe,EADC,CAAC,OAAQ,WAAW,CACkB,CAQtD,GAAiB,EANF,CACpB,WACA,QACA,OACA,UACA,CAC8D,CAsBzD,GAAkB,EApBC,CACxB,OACA,SACA,OACA,OACA,SACA,QACA,oBACA,eACA,QACA,UACA,SACA,OACA,WACA,WACA,UACA,SACA,UACA,SACA,CACoE,CAM/D,GAAoB,EAJC,CAC1B,WACA,QACA,CAC0E,CAWrE,GAAkB,EATC,CACxB,kBACA,WACA,QACA,QACA,WACA,OACA,QACA,CACoE,CAW/D,GAAkB,EATC,CACxB,eACA,OACA,OACA,QACA,UACA,oBACA,eACA,CACoE,CAO/D,GAAoB,EALC,CAC1B,MACA,WACA,QACA,CAC0E,CAGrE,EAAiB,EADC,CAAC,OAAO,CACkC,CAE5D,GAAiB,GAAqB,EAAuB,EAAI,CAejE,GAAwB,GAAoC,CAbzC,CACxB,QACA,cACA,QACA,gBACA,YACA,WACA,iBACA,MACA,OACA,OACA,UACA,CACoF,CACpF,MAAQ,GAAO,EAAU,MACzB,QAAU,GAAO,EAAU,QAC3B,CAAC,CACI,GAAmB,IAA4B,CACpD,GAAG,EAAuB,EAAI,CAC9B,GAAG,GAAsB,EAAI,CAC7B,EAgBK,GAAkB,EAdC,CACxB,eACA,WACA,SACA,WACA,OACA,WACA,gBACA,OACA,OACA,QACA,oBACA,eACA,CACoE,CAG/D,GAAgB,EADC,CAAC,OAAO,CACgC,CAWzD,GAAkB,EATC,CACxB,SACA,QACA,QACA,MACA,SACA,OACA,QACA,CACoE,CAK/D,GAAwB,EAHE,CAC/B,QACA,CACuF,CAmBlF,EAAqB,EAjBE,CAC5B,OACA,YACA,UACA,UACA,UACA,QACA,QACA,OACA,UACA,KACA,QACA,SACA,SACA,SACA,QACA,CAC8E,CAUzE,EAAoB,EARE,CAC3B,OACA,QACA,KACA,QACA,SACA,QACA,CAC2E,CAatE,GAAiB,EAXC,CACvB,QACA,UACA,SACA,cACA,cACA,QACA,QACA,UACA,QACA,CACiE,CAW5D,GAAoB,EATL,CACpB,WACA,kBA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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["client: PulseSocketIOClient","id: string","remaining: ServerChannelRequestMessage[]","response: any","error: any","PulseForm","out: any","formExtractor","elementExtractors: Record<string, (elt: any) => object>","eventExtractorMap: { [key: string]: (evt: any) => object }","refs: number[]","dates: number[]","sets: number[]","maps: number[]","process","rec: Record<string, any>","objects: Array<any>","result","keys","result: Record<string, any>","#url","#directives","#frameworkNavigate","#socket","#activeViews","#messageQueue","#handleTransportDisconnect","#handleServerMessage","#connectionListeners","#serverErrorListeners","#serverErrors","#channels","#performApiCall","#routeChannelMessage","headersObj: Record<string, string>","body: any","reply: ClientApiResultMessage","#ensureChannelEntry","#client","#path","#components","#cssModules","#callbacks","#callbackCache","#renderPropKeys","#cssProps","#callbackList","#lowerBound","#propPath","newProps: Record<string, any>","#resolveCssToken","newTree: ReactNode","#assertIsElement","#ensureChildrenArray","nextProps: Record<string, any>","#rebindCallbacksInSubtree"],"sources":["../src/channel.ts","../src/form.tsx","../src/helpers.ts","../src/serialize/extractor.ts","../src/serialize/elements.ts","../src/serialize/events.ts","../src/serialize/serializer.ts","../src/client.tsx","../src/vdom.ts","../src/renderer.tsx","../src/pulse.tsx","../src/usePulseChannel.ts"],"sourcesContent":["import type { PulseSocketIOClient } from \"./client\";\nimport type {\n\tServerChannelMessage,\n\tServerChannelRequestMessage,\n\tServerChannelResponseMessage,\n} from \"./messages\";\n\nexport class PulseChannelResetError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PulseChannelResetError\";\n\t}\n}\n\nexport type ChannelEventHandler = (payload: any) => any | Promise<any>;\n\ninterface PendingRequest {\n\tresolve: (value: any) => void;\n\treject: (error: any) => void;\n}\n\nfunction randomId(): string {\n\tif (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n\t\treturn crypto.randomUUID().replace(/-/g, \"\");\n\t}\n\treturn Math.random().toString(16).slice(2) + Math.random().toString(16).slice(2);\n}\n\nfunction formatError(error: unknown): string {\n\tif (error instanceof Error) return error.message;\n\tif (typeof error === \"string\") return error;\n\ttry {\n\t\treturn JSON.stringify(error);\n\t} catch {\n\t\treturn String(error);\n\t}\n}\n\nfunction isServerResponseMessage(\n\tmessage: ServerChannelMessage,\n): message is ServerChannelResponseMessage {\n\treturn typeof (message as ServerChannelResponseMessage).responseTo === \"string\";\n}\n\nfunction isServerRequestMessage(\n\tmessage: ServerChannelMessage,\n): message is ServerChannelRequestMessage {\n\treturn typeof (message as ServerChannelRequestMessage).event === \"string\";\n}\n\nexport class ChannelBridge {\n\tprivate handlers = new Map<string, Set<ChannelEventHandler>>();\n\tprivate pending = new Map<string, PendingRequest>();\n\tprivate backlog: ServerChannelRequestMessage[] = [];\n\tprivate closed = false;\n\n\tconstructor(\n\t\tprivate client: PulseSocketIOClient,\n\t\tpublic readonly id: string,\n\t) {}\n\n\temit(event: string, payload?: any): void {\n\t\tthis.ensureOpen();\n\t\tthis.client.sendMessage({\n\t\t\ttype: \"channel_message\",\n\t\t\tchannel: this.id,\n\t\t\tevent,\n\t\t\tpayload,\n\t\t});\n\t}\n\n\trequest(event: string, payload?: any): Promise<any> {\n\t\tthis.ensureOpen();\n\t\tconst requestId = randomId();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.pending.set(requestId, { resolve, reject });\n\t\t\tthis.client.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: this.id,\n\t\t\t\tevent,\n\t\t\t\tpayload,\n\t\t\t\trequestId,\n\t\t\t});\n\t\t});\n\t}\n\n\ton(event: string, handler: ChannelEventHandler): () => void {\n\t\tthis.ensureOpen();\n\t\tlet bucket = this.handlers.get(event);\n\t\tif (!bucket) {\n\t\t\tbucket = new Set();\n\t\t\tthis.handlers.set(event, bucket);\n\t\t}\n\t\tbucket.add(handler);\n\t\tthis.flushBacklog(event);\n\t\treturn () => {\n\t\t\tconst set = this.handlers.get(event);\n\t\t\tif (!set) return;\n\t\t\tset.delete(handler);\n\t\t\tif (set.size === 0) {\n\t\t\t\tthis.handlers.delete(event);\n\t\t\t}\n\t\t};\n\t}\n\n\thandleServerMessage(message: ServerChannelMessage): boolean {\n\t\tif (isServerResponseMessage(message)) {\n\t\t\tthis.resolvePending(message);\n\t\t\treturn this.closed;\n\t\t}\n\t\tif (this.closed) {\n\t\t\treturn true;\n\t\t}\n\t\tif (!isServerRequestMessage(message)) {\n\t\t\treturn this.closed;\n\t\t}\n\n\t\tif (message.event === \"__close__\") {\n\t\t\tthis.close(new PulseChannelResetError(\"Channel closed by server\"));\n\t\t\treturn true;\n\t\t}\n\t\tif (message.requestId) {\n\t\t\tvoid this.dispatchRequest(\n\t\t\t\tmessage as ServerChannelRequestMessage & {\n\t\t\t\t\trequestId: string;\n\t\t\t\t},\n\t\t\t);\n\t\t} else {\n\t\t\tthis.dispatchEvent(message);\n\t\t}\n\t\treturn this.closed;\n\t}\n\n\thandleDisconnect(reason: PulseChannelResetError): void {\n\t\tthis.close(reason);\n\t}\n\n\tdispose(reason: PulseChannelResetError): void {\n\t\tthis.close(reason);\n\t}\n\n\tprivate ensureOpen(): void {\n\t\tif (this.closed) {\n\t\t\tthrow new PulseChannelResetError(\"Channel is closed\");\n\t\t}\n\t}\n\n\tprivate flushBacklog(event: string): void {\n\t\tif (this.backlog.length === 0) return;\n\t\tconst remaining: ServerChannelRequestMessage[] = [];\n\t\tfor (const item of this.backlog) {\n\t\t\tif (item.event === event) {\n\t\t\t\tthis.dispatchEvent(item);\n\t\t\t} else {\n\t\t\t\tremaining.push(item);\n\t\t\t}\n\t\t}\n\t\tthis.backlog = remaining;\n\t}\n\n\tprivate dispatchEvent(message: ServerChannelRequestMessage): void {\n\t\tconst handlers = this.handlers.get(message.event);\n\t\tif (!handlers || handlers.size === 0) {\n\t\t\tthis.backlog.push(message);\n\t\t\treturn;\n\t\t}\n\t\tfor (const handler of handlers) {\n\t\t\ttry {\n\t\t\t\tconst result = handler(message.payload);\n\t\t\t\tif (result && typeof (result as Promise<any>).then === \"function\") {\n\t\t\t\t\tvoid (result as Promise<any>).catch((err) => {\n\t\t\t\t\t\tconsole.error(\"Pulse channel handler error\", err);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"Pulse channel handler error\", err);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async dispatchRequest(\n\t\tmessage: ServerChannelRequestMessage & { requestId: string },\n\t): Promise<void> {\n\t\tconst handlers = this.handlers.get(message.event);\n\t\tlet response: any;\n\t\tlet error: any;\n\t\tif (handlers && handlers.size > 0) {\n\t\t\tfor (const handler of handlers) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = handler(message.payload);\n\t\t\t\t\tresponse = await Promise.resolve(result);\n\t\t\t\t\tif (response !== undefined) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\terror = err;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (error) {\n\t\t\tthis.client.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: this.id,\n\t\t\t\tevent: undefined,\n\t\t\t\tresponseTo: message.requestId,\n\t\t\t\terror: formatError(error),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tthis.client.sendMessage({\n\t\t\ttype: \"channel_message\",\n\t\t\tchannel: this.id,\n\t\t\tevent: undefined,\n\t\t\tresponseTo: message.requestId,\n\t\t\tpayload: response,\n\t\t});\n\t}\n\n\tprivate resolvePending(message: ServerChannelResponseMessage): void {\n\t\tconst entry = message.responseTo ? this.pending.get(message.responseTo) : undefined;\n\t\tif (!entry) {\n\t\t\treturn;\n\t\t}\n\t\tthis.pending.delete(message.responseTo!);\n\t\tif (message.error !== undefined && message.error !== null) {\n\t\t\tentry.reject(new PulseChannelResetError(String(message.error)));\n\t\t} else {\n\t\t\tentry.resolve(message.payload);\n\t\t}\n\t}\n\n\tprivate close(reason: PulseChannelResetError): void {\n\t\tif (this.closed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.closed = true;\n\t\tfor (const request of this.pending.values()) {\n\t\t\trequest.reject(reason);\n\t\t}\n\t\tthis.pending.clear();\n\t\tthis.handlers.clear();\n\t\tthis.backlog = [];\n\t\t// No-op: owning client manages registry lifecycle.\n\t}\n}\n\nexport function createChannelBridge(client: PulseSocketIOClient, id: string): ChannelBridge {\n\treturn new ChannelBridge(client, id);\n}\n","import React, { type FormEvent, forwardRef, useCallback } from \"react\";\n\nexport type PulseFormProps = React.ComponentPropsWithoutRef<\"form\"> & {\n\taction: string;\n};\n\n/**\n * PulseForm intercepts native form submissions and sends them through fetch so the\n * surrounding Pulse view stays mounted. Server-side handlers are still invoked via\n * the form action endpoint and reactive updates propagate over the socket.\n */\nexport const PulseForm = forwardRef<HTMLFormElement, PulseFormProps>(function PulseForm(\n\t{ onSubmit, action, ...rest },\n\tref,\n) {\n\treturn (\n\t\t<form\n\t\t\t{...rest}\n\t\t\taction={action}\n\t\t\tref={ref}\n\t\t\tonSubmit={useCallback(\n\t\t\t\t(event: FormEvent<HTMLFormElement>) => submitForm({ event, action, onSubmit }),\n\t\t\t\t[action, onSubmit],\n\t\t\t)}\n\t\t/>\n\t);\n});\n\ninterface SubmitForm {\n\tevent: React.FormEvent<HTMLFormElement>;\n\taction: string;\n\tonSubmit?: PulseFormProps[\"onSubmit\"];\n\tformData?: FormData;\n\tforce?: boolean;\n}\n\nexport async function submitForm({ event, action, onSubmit, formData, force }: SubmitForm) {\n\tonSubmit?.(event);\n\tif (!force && event.defaultPrevented) {\n\t\treturn;\n\t}\n\tconst form = event.currentTarget;\n\tevent.preventDefault();\n\tconst nativeEvent = event.nativeEvent as SubmitEvent;\n\tif (!formData) {\n\t\tformData = new FormData(form, nativeEvent.submitter);\n\t}\n\tconst url = new URL(action, window.location.href);\n\ttry {\n\t\tawait fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\t// Required for our hosting scenarios of same host + different ports or 2 subdomains\n\t\t\tcredentials: \"include\",\n\t\t\tbody: formData,\n\t\t});\n\t} catch (err) {\n\t\tif (process.env.NODE_ENV !== \"production\") {\n\t\t\tconsole.error(\"[Pulse] Form submission failed\", err);\n\t\t} else {\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n","import type { LoaderFunctionArgs } from \"react-router\";\n\nexport interface RouteInfo {\n\tpathname: string;\n\thash: string;\n\tquery: string;\n\tqueryParams: Record<string, string>;\n\tpathParams: Record<string, string | undefined>;\n\tcatchall: string[];\n}\n\nexport function extractServerRouteInfo({ params, request }: LoaderFunctionArgs) {\n\tconst { \"*\": catchall = \"\", ...pathParams } = params;\n\tconst parsedUrl = new URL(request.url);\n\n\treturn {\n\t\thash: parsedUrl.hash,\n\t\tpathname: parsedUrl.pathname,\n\t\tquery: parsedUrl.search,\n\t\tqueryParams: Object.fromEntries(parsedUrl.searchParams.entries()),\n\t\tpathParams,\n\t\tcatchall: catchall.length > 1 ? catchall.split(\"/\") : [],\n\t} satisfies RouteInfo;\n}\n","type Simplify<T> = { [K in keyof T]: T[K] } & {};\n\nexport function createExtractor<T extends object>() {\n\tfunction _createExtractor<\n\t\tconst K extends readonly (keyof T)[],\n\t\tC extends Partial<Record<K[number] | string, (src: T) => any>>,\n\t>(keys: K, computed?: C) {\n\t\treturn (\n\t\t\tsrc: T,\n\t\t): Simplify<\n\t\t\tPick<T, K[number]> & {\n\t\t\t\t[P in keyof C]-?: C[P] extends (...args: any) => infer R ? R : never;\n\t\t\t}\n\t\t> => {\n\t\t\tconst out: any = {};\n\t\t\tfor (const key of keys) {\n\t\t\t\tout[key as string] = (src as any)[key as string];\n\t\t\t}\n\t\t\tif (computed) {\n\t\t\t\tfor (const key in computed) {\n\t\t\t\t\tconst fn = computed[key]!;\n\t\t\t\t\tout[key] = fn(src);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out;\n\t\t};\n\t}\n\treturn _createExtractor;\n}\n","import { createExtractor } from \"./extractor\";\n\n// Base extractors (camelCase) similar to events.ts style\nconst lowerTagName = (e: Element) => e.tagName.toLowerCase();\n\nconst ELEMENT_KEYS = [\n\t\"id\",\n\t\"className\",\n\t\"tagName\",\n\t\"localName\",\n\t\"clientHeight\",\n\t\"clientLeft\",\n\t\"clientTop\",\n\t\"clientWidth\",\n\t\"scrollHeight\",\n\t\"scrollLeft\",\n\t\"scrollTop\",\n\t\"scrollWidth\",\n\t\"slot\",\n] as const satisfies readonly (keyof Element)[];\n\nconst HTML_OR_SVG_KEYS = [\n\t\"autofocus\",\n\t\"tabIndex\",\n\t\"nonce\",\n] as const satisfies readonly (keyof HTMLOrSVGElement)[];\n\nconst HTML_ELEMENT_BASE_KEYS = [\n\t\"accessKey\",\n\t\"accessKeyLabel\",\n\t\"autocapitalize\",\n\t\"dir\",\n\t\"draggable\",\n\t\"hidden\",\n\t\"inert\",\n\t\"lang\",\n\t\"offsetHeight\",\n\t\"offsetLeft\",\n\t\"offsetTop\",\n\t\"offsetWidth\",\n\t\"popover\",\n\t\"spellcheck\",\n\t\"title\",\n\t\"translate\",\n\t\"writingSuggestions\",\n\t\"contentEditable\",\n\t\"enterKeyHint\",\n\t\"isContentEditable\",\n\t\"inputMode\",\n] as const satisfies readonly (keyof HTMLElement)[];\n\nconst extractElementBase = createExtractor<Element>()(ELEMENT_KEYS, {\n\ttagName: lowerTagName,\n});\n\nconst extractHTMLOrSVGElement = createExtractor<HTMLOrSVGElement>()(HTML_OR_SVG_KEYS);\n\nconst extractHTMLElementBaseOnly = createExtractor<HTMLElement>()(HTML_ELEMENT_BASE_KEYS);\n\nfunction extractHTMLElementBase(elt: HTMLElement) {\n\treturn {\n\t\t...extractElementBase(elt),\n\t\t...extractHTMLOrSVGElement(elt as HTMLOrSVGElement),\n\t\t...extractHTMLElementBaseOnly(elt),\n\t};\n}\n\n// Helper to compose per-element extractors with the shared base\nfunction withBase<T extends HTMLElement>(\n\tkeys: readonly (keyof T)[],\n\tcomputed?: Partial<Record<string, (src: T) => any>>,\n) {\n\tconst only = createExtractor<T>()(keys, computed as any);\n\treturn (elt: T) => ({ ...extractHTMLElementBase(elt), ...only(elt) });\n}\n\nconst HTML_ANCHOR_KEYS = [\n\t\"hash\",\n\t\"host\",\n\t\"hostname\",\n\t\"href\",\n\t\"origin\",\n\t\"password\",\n\t\"pathname\",\n\t\"port\",\n\t\"protocol\",\n\t\"search\",\n\t\"target\",\n\t\"download\",\n\t\"rel\",\n\t\"hreflang\",\n\t\"type\",\n\t\"username\",\n\t\"ping\",\n\t\"referrerPolicy\",\n\t\"text\",\n] as const satisfies readonly (keyof HTMLAnchorElement)[];\nconst anchorExtractor = withBase<HTMLAnchorElement>(HTML_ANCHOR_KEYS);\n\nconst HTML_AREA_KEYS = [\n\t\"alt\",\n\t\"coords\",\n\t\"download\",\n\t\"hash\",\n\t\"host\",\n\t\"hostname\",\n\t\"href\",\n\t\"origin\",\n\t\"password\",\n\t\"pathname\",\n\t\"port\",\n\t\"protocol\",\n\t\"rel\",\n\t\"search\",\n\t\"shape\",\n\t\"target\",\n\t\"username\",\n\t\"ping\",\n\t\"referrerPolicy\",\n] as const satisfies readonly (keyof HTMLAreaElement)[];\nconst areaExtractor = withBase<HTMLAreaElement>(HTML_AREA_KEYS);\n\nconst HTML_MEDIA_KEYS = [\n\t\"autoplay\",\n\t\"controls\",\n\t\"crossOrigin\",\n\t\"currentSrc\",\n\t\"currentTime\",\n\t\"defaultMuted\",\n\t\"defaultPlaybackRate\",\n\t\"duration\",\n\t\"ended\",\n\t\"loop\",\n\t\"muted\",\n\t\"networkState\",\n\t\"paused\",\n\t\"playbackRate\",\n\t\"preload\",\n\t\"readyState\",\n\t\"seeking\",\n\t\"src\",\n\t\"volume\",\n\t\"preservesPitch\",\n] as const satisfies readonly (keyof HTMLMediaElement)[];\nconst mediaExtractor = withBase<HTMLMediaElement>(HTML_MEDIA_KEYS);\n\nconst audioExtractor = (elt: HTMLAudioElement) => mediaExtractor(elt);\n\nconst HTML_BUTTON_KEYS = [\n\t\"disabled\",\n\t\"name\",\n\t\"type\",\n\t\"value\",\n\t\"formAction\",\n\t\"formEnctype\",\n\t\"formMethod\",\n\t\"formNoValidate\",\n\t\"formTarget\",\n\t\"popoverTargetAction\",\n] as const satisfies readonly (keyof HTMLButtonElement)[];\nconst buttonExtractor = withBase<HTMLButtonElement>(HTML_BUTTON_KEYS);\n\nconst HTML_DATA_KEYS = [\"value\"] as const satisfies readonly (keyof HTMLDataElement)[];\nconst dataExtractor = withBase<HTMLDataElement>(HTML_DATA_KEYS);\n\nconst HTML_EMBED_KEYS = [\n\t\"height\",\n\t\"src\",\n\t\"type\",\n\t\"width\",\n\t\"align\",\n\t\"name\",\n] as const satisfies readonly (keyof HTMLEmbedElement)[];\nconst embedExtractor = withBase<HTMLEmbedElement>(HTML_EMBED_KEYS);\n\nconst HTML_FIELDSET_KEYS = [\n\t\"disabled\",\n\t\"name\",\n\t\"type\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLFieldSetElement)[];\nconst fieldsetExtractor = withBase<HTMLFieldSetElement>(HTML_FIELDSET_KEYS);\n\nconst HTML_FORM_KEYS = [\n\t\"acceptCharset\",\n\t\"action\",\n\t\"autocomplete\",\n\t\"encoding\",\n\t\"enctype\",\n\t\"length\",\n\t\"method\",\n\t\"name\",\n\t\"noValidate\",\n\t\"target\",\n\t\"rel\",\n] as const satisfies readonly (keyof HTMLFormElement)[];\nconst formExtractor = withBase<HTMLFormElement>(HTML_FORM_KEYS);\n\nconst HTML_IFRAME_KEYS = [\n\t\"allow\",\n\t\"allowFullscreen\",\n\t\"height\",\n\t\"name\",\n\t\"referrerPolicy\",\n\t\"src\",\n\t\"srcdoc\",\n\t\"width\",\n\t\"align\",\n\t\"frameBorder\",\n\t\"longDesc\",\n\t\"marginHeight\",\n\t\"marginWidth\",\n\t\"scrolling\",\n\t\"sandbox\",\n] as const satisfies readonly (keyof HTMLIFrameElement)[];\nconst iframeExtractor = withBase<HTMLIFrameElement>(HTML_IFRAME_KEYS);\n\nconst HTML_IMAGE_KEYS = [\n\t\"alt\",\n\t\"crossOrigin\",\n\t\"decoding\",\n\t\"height\",\n\t\"isMap\",\n\t\"loading\",\n\t\"naturalHeight\",\n\t\"naturalWidth\",\n\t\"referrerPolicy\",\n\t\"sizes\",\n\t\"src\",\n\t\"srcset\",\n\t\"useMap\",\n\t\"width\",\n\t\"align\",\n\t\"border\",\n\t\"complete\",\n\t\"hspace\",\n\t\"longDesc\",\n\t\"lowsrc\",\n\t\"name\",\n\t\"vspace\",\n\t\"x\",\n\t\"y\",\n\t\"fetchPriority\",\n] as const satisfies readonly (keyof HTMLImageElement)[];\nconst imageExtractor = withBase<HTMLImageElement>(HTML_IMAGE_KEYS);\n\nconst HTML_INPUT_KEYS = [\n\t\"accept\",\n\t\"alt\",\n\t\"autocomplete\",\n\t\"checked\",\n\t\"defaultChecked\",\n\t\"defaultValue\",\n\t\"dirName\",\n\t\"disabled\",\n\t\"height\",\n\t\"indeterminate\",\n\t\"max\",\n\t\"maxLength\",\n\t\"min\",\n\t\"minLength\",\n\t\"multiple\",\n\t\"name\",\n\t\"pattern\",\n\t\"placeholder\",\n\t\"readOnly\",\n\t\"required\",\n\t\"selectionDirection\",\n\t\"selectionEnd\",\n\t\"selectionStart\",\n\t\"size\",\n\t\"src\",\n\t\"step\",\n\t\"type\",\n\t\"value\",\n\t\"valueAsNumber\",\n\t\"width\",\n\t\"align\",\n\t\"capture\",\n\t\"formAction\",\n\t\"formEnctype\",\n\t\"formMethod\",\n\t\"formNoValidate\",\n\t\"formTarget\",\n\t\"useMap\",\n\t\"validationMessage\",\n\t\"willValidate\",\n\t\"popoverTargetAction\",\n] as const satisfies readonly (keyof HTMLInputElement)[];\nconst inputExtractor = withBase<HTMLInputElement>(HTML_INPUT_KEYS);\n\nconst HTML_LABEL_KEYS = [\"htmlFor\"] as const satisfies readonly (keyof HTMLLabelElement)[];\nconst labelExtractor = withBase<HTMLLabelElement>(HTML_LABEL_KEYS);\n\nconst HTML_LI_KEYS = [\"value\", \"type\"] as const satisfies readonly (keyof HTMLLIElement)[];\nconst liExtractor = withBase<HTMLLIElement>(HTML_LI_KEYS);\n\nconst HTML_LINK_KEYS = [\n\t\"as\",\n\t\"crossOrigin\",\n\t\"disabled\",\n\t\"fetchPriority\",\n\t\"href\",\n\t\"hreflang\",\n\t\"imageSizes\",\n\t\"imageSrcset\",\n\t\"integrity\",\n\t\"media\",\n\t\"referrerPolicy\",\n\t\"rel\",\n\t\"type\",\n\t\"charset\",\n\t\"rev\",\n\t\"target\",\n\t\"sizes\",\n] as const satisfies readonly (keyof HTMLLinkElement)[];\nconst linkExtractor = withBase<HTMLLinkElement>(HTML_LINK_KEYS);\n\nconst HTML_MAP_KEYS = [\"name\"] as const satisfies readonly (keyof HTMLMapElement)[];\nconst mapExtractor = withBase<HTMLMapElement>(HTML_MAP_KEYS);\n\nconst HTML_METER_KEYS = [\n\t\"high\",\n\t\"low\",\n\t\"max\",\n\t\"min\",\n\t\"optimum\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLMeterElement)[];\nconst meterExtractor = withBase<HTMLMeterElement>(HTML_METER_KEYS);\n\nconst HTML_MOD_KEYS = [\"cite\", \"dateTime\"] as const satisfies readonly (keyof HTMLModElement)[];\nconst modExtractor = withBase<HTMLModElement>(HTML_MOD_KEYS);\n\nconst HTML_OL_KEYS = [\n\t\"reversed\",\n\t\"start\",\n\t\"type\",\n\t\"compact\",\n] as const satisfies readonly (keyof HTMLOListElement)[];\nconst olistExtractor = withBase<HTMLOListElement>(HTML_OL_KEYS);\n\nconst HTML_OBJECT_KEYS = [\n\t\"data\",\n\t\"height\",\n\t\"name\",\n\t\"type\",\n\t\"useMap\",\n\t\"width\",\n\t\"validationMessage\",\n\t\"willValidate\",\n\t\"align\",\n\t\"archive\",\n\t\"border\",\n\t\"code\",\n\t\"codeBase\",\n\t\"codeType\",\n\t\"declare\",\n\t\"hspace\",\n\t\"standby\",\n\t\"vspace\",\n] as const satisfies readonly (keyof HTMLObjectElement)[];\nconst objectExtractor = withBase<HTMLObjectElement>(HTML_OBJECT_KEYS);\n\nconst HTML_OPTGROUP_KEYS = [\n\t\"disabled\",\n\t\"label\",\n] as const satisfies readonly (keyof HTMLOptGroupElement)[];\nconst optgroupExtractor = withBase<HTMLOptGroupElement>(HTML_OPTGROUP_KEYS);\n\nconst HTML_OPTION_KEYS = [\n\t\"defaultSelected\",\n\t\"disabled\",\n\t\"index\",\n\t\"label\",\n\t\"selected\",\n\t\"text\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLOptionElement)[];\nconst optionExtractor = withBase<HTMLOptionElement>(HTML_OPTION_KEYS);\n\nconst HTML_OUTPUT_KEYS = [\n\t\"defaultValue\",\n\t\"name\",\n\t\"type\",\n\t\"value\",\n\t\"htmlFor\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLOutputElement)[];\nconst outputExtractor = withBase<HTMLOutputElement>(HTML_OUTPUT_KEYS);\n\nconst HTML_PROGRESS_KEYS = [\n\t\"max\",\n\t\"position\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLProgressElement)[];\nconst progressExtractor = withBase<HTMLProgressElement>(HTML_PROGRESS_KEYS);\n\nconst HTML_QUOTE_KEYS = [\"cite\"] as const satisfies readonly (keyof HTMLQuoteElement)[];\nconst quoteExtractor = withBase<HTMLQuoteElement>(HTML_QUOTE_KEYS);\n\nconst citeExtractor = (elt: HTMLElement) => extractHTMLElementBase(elt);\n\nconst HTML_SCRIPT_KEYS = [\n\t\"async\",\n\t\"crossOrigin\",\n\t\"defer\",\n\t\"fetchPriority\",\n\t\"integrity\",\n\t\"noModule\",\n\t\"referrerPolicy\",\n\t\"src\",\n\t\"text\",\n\t\"type\",\n\t\"charset\",\n] as const satisfies readonly (keyof HTMLScriptElement)[];\nconst extractHTMLScriptOnly = createExtractor<HTMLScriptElement>()(HTML_SCRIPT_KEYS, {\n\tevent: (s) => (s as any).event,\n\thtmlFor: (s) => (s as any).htmlFor,\n});\nconst scriptExtractor = (elt: HTMLScriptElement) => ({\n\t...extractHTMLElementBase(elt),\n\t...extractHTMLScriptOnly(elt),\n});\n\nconst HTML_SELECT_KEYS = [\n\t\"autocomplete\",\n\t\"disabled\",\n\t\"length\",\n\t\"multiple\",\n\t\"name\",\n\t\"required\",\n\t\"selectedIndex\",\n\t\"size\",\n\t\"type\",\n\t\"value\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLSelectElement)[];\nconst selectExtractor = withBase<HTMLSelectElement>(HTML_SELECT_KEYS);\n\nconst HTML_SLOT_KEYS = [\"name\"] as const satisfies readonly (keyof HTMLSlotElement)[];\nconst slotExtractor = withBase<HTMLSlotElement>(HTML_SLOT_KEYS);\n\nconst HTML_SOURCE_KEYS = [\n\t\"height\",\n\t\"media\",\n\t\"sizes\",\n\t\"src\",\n\t\"srcset\",\n\t\"type\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLSourceElement)[];\nconst sourceExtractor = withBase<HTMLSourceElement>(HTML_SOURCE_KEYS);\n\nconst HTML_TABLE_CAPTION_KEYS = [\n\t\"align\",\n] as const satisfies readonly (keyof HTMLTableCaptionElement)[];\nconst tableCaptionExtractor = withBase<HTMLTableCaptionElement>(HTML_TABLE_CAPTION_KEYS);\n\nconst HTML_TABLE_CELL_KEYS = [\n\t\"abbr\",\n\t\"cellIndex\",\n\t\"colSpan\",\n\t\"headers\",\n\t\"rowSpan\",\n\t\"scope\",\n\t\"align\",\n\t\"axis\",\n\t\"bgColor\",\n\t\"ch\",\n\t\"chOff\",\n\t\"height\",\n\t\"noWrap\",\n\t\"vAlign\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableCellElement)[];\nconst tableCellExtractor = withBase<HTMLTableCellElement>(HTML_TABLE_CELL_KEYS);\n\nconst HTML_TABLE_COL_KEYS = [\n\t\"span\",\n\t\"align\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableColElement)[];\nconst tableColExtractor = withBase<HTMLTableColElement>(HTML_TABLE_COL_KEYS);\n\nconst HTML_TABLE_KEYS = [\n\t\"align\",\n\t\"bgColor\",\n\t\"border\",\n\t\"cellPadding\",\n\t\"cellSpacing\",\n\t\"frame\",\n\t\"rules\",\n\t\"summary\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableElement)[];\nconst tableExtractor = withBase<HTMLTableElement>(HTML_TABLE_KEYS);\n\nconst HTML_TR_KEYS = [\n\t\"rowIndex\",\n\t\"sectionRowIndex\",\n\t\"align\",\n\t\"bgColor\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n] as const satisfies readonly (keyof HTMLTableRowElement)[];\nconst tableRowExtractor = withBase<HTMLTableRowElement>(HTML_TR_KEYS);\n\nconst HTML_TSECTION_KEYS = [\n\t\"align\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n] as const satisfies readonly (keyof HTMLTableSectionElement)[];\nconst tableSectionExtractor = withBase<HTMLTableSectionElement>(HTML_TSECTION_KEYS);\n\nconst templateExtractor = (elt: HTMLTemplateElement) => extractHTMLElementBase(elt);\n\nconst HTML_TEXTAREA_KEYS = [\n\t\"autocomplete\",\n\t\"cols\",\n\t\"defaultValue\",\n\t\"dirName\",\n\t\"disabled\",\n\t\"maxLength\",\n\t\"minLength\",\n\t\"name\",\n\t\"placeholder\",\n\t\"readOnly\",\n\t\"required\",\n\t\"rows\",\n\t\"selectionDirection\",\n\t\"selectionEnd\",\n\t\"selectionStart\",\n\t\"value\",\n\t\"wrap\",\n\t\"textLength\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLTextAreaElement)[];\nconst textareaExtractor = withBase<HTMLTextAreaElement>(HTML_TEXTAREA_KEYS);\n\nconst HTML_TIME_KEYS = [\"dateTime\"] as const satisfies readonly (keyof HTMLTimeElement)[];\nconst timeExtractor = withBase<HTMLTimeElement>(HTML_TIME_KEYS);\n\nconst HTML_TRACK_KEYS = [\n\t\"default\",\n\t\"kind\",\n\t\"label\",\n\t\"readyState\",\n\t\"src\",\n\t\"srclang\",\n] as const satisfies readonly (keyof HTMLTrackElement)[];\nconst trackExtractor = withBase<HTMLTrackElement>(HTML_TRACK_KEYS);\n\nconst HTML_VIDEO_KEYS = [\n\t\"height\",\n\t\"poster\",\n\t\"videoHeight\",\n\t\"videoWidth\",\n\t\"width\",\n\t\"playsInline\",\n] as const satisfies readonly (keyof HTMLVideoElement)[];\nconst extractHTMLVideoOnly = createExtractor<HTMLVideoElement>()(HTML_VIDEO_KEYS);\nconst videoExtractor = (elt: HTMLVideoElement) => ({\n\t...mediaExtractor(elt),\n\t...extractHTMLVideoOnly(elt),\n});\n\nconst HTML_BR_KEYS = [\"clear\"] as const satisfies readonly (keyof HTMLBRElement)[];\nconst brExtractor = withBase<HTMLBRElement>(HTML_BR_KEYS);\n\nconst HTML_BASE_KEYS = [\"href\", \"target\"] as const satisfies readonly (keyof HTMLBaseElement)[];\nconst baseExtractor = withBase<HTMLBaseElement>(HTML_BASE_KEYS);\n\nconst HTML_BODY_KEYS = [\n\t\"aLink\",\n\t\"background\",\n\t\"bgColor\",\n\t\"link\",\n\t\"text\",\n\t\"vLink\",\n] as const satisfies readonly (keyof HTMLBodyElement)[];\nconst bodyExtractor = withBase<HTMLBodyElement>(HTML_BODY_KEYS);\n\nconst HTML_DLIST_KEYS = [\"compact\"] as const satisfies readonly (keyof HTMLDListElement)[];\nconst dlistExtractor = withBase<HTMLDListElement>(HTML_DLIST_KEYS);\n\nconst HTML_DETAILS_KEYS = [\"open\"] as const satisfies readonly (keyof HTMLDetailsElement)[];\nconst detailsExtractor = withBase<HTMLDetailsElement>(HTML_DETAILS_KEYS);\n\nconst HTML_DIALOG_KEYS = [\n\t\"open\",\n\t\"returnValue\",\n] as const satisfies readonly (keyof HTMLDialogElement)[];\nconst dialogExtractor = withBase<HTMLDialogElement>(HTML_DIALOG_KEYS);\n\nconst HTML_DIV_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLDivElement)[];\nconst divExtractor = withBase<HTMLDivElement>(HTML_DIV_KEYS);\n\nconst headExtractor = (elt: HTMLHeadElement) => extractHTMLElementBase(elt);\n\nconst HTML_HEADING_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLHeadingElement)[];\nconst headingExtractor = withBase<HTMLHeadingElement>(HTML_HEADING_KEYS);\n\nconst HTML_HR_KEYS = [\n\t\"align\",\n\t\"color\",\n\t\"noShade\",\n\t\"size\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLHRElement)[];\nconst hrExtractor = withBase<HTMLHRElement>(HTML_HR_KEYS);\n\nconst HTML_HTML_KEYS = [\"version\"] as const satisfies readonly (keyof HTMLHtmlElement)[];\nconst htmlExtractor = withBase<HTMLHtmlElement>(HTML_HTML_KEYS);\n\nconst menuExtractor = (elt: HTMLMenuElement) => extractHTMLElementBase(elt);\n\nconst HTML_META_KEYS = [\n\t\"content\",\n\t\"httpEquiv\",\n\t\"name\",\n\t\"scheme\",\n] as const satisfies readonly (keyof HTMLMetaElement)[];\nconst metaExtractor = withBase<HTMLMetaElement>(HTML_META_KEYS);\n\nconst HTML_P_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLParagraphElement)[];\nconst paragraphExtractor = withBase<HTMLParagraphElement>(HTML_P_KEYS);\n\nconst pictureExtractor = (elt: HTMLPictureElement) => extractHTMLElementBase(elt);\n\nconst HTML_PRE_KEYS = [\"width\"] as const satisfies readonly (keyof HTMLPreElement)[];\nconst preExtractor = withBase<HTMLPreElement>(HTML_PRE_KEYS);\n\nconst spanExtractor = (elt: HTMLSpanElement) => extractHTMLElementBase(elt);\n\nconst HTML_STYLE_KEYS = [\n\t\"media\",\n\t\"type\",\n\t\"disabled\",\n] as const satisfies readonly (keyof HTMLStyleElement)[];\nconst styleExtractor = withBase<HTMLStyleElement>(HTML_STYLE_KEYS);\n\nconst HTML_TITLE_KEYS = [\"text\"] as const satisfies readonly (keyof HTMLTitleElement)[];\nconst titleExtractor = withBase<HTMLTitleElement>(HTML_TITLE_KEYS);\n\nconst HTML_UL_KEYS = [\"compact\", \"type\"] as const satisfies readonly (keyof HTMLUListElement)[];\nconst ulistExtractor = withBase<HTMLUListElement>(HTML_UL_KEYS);\n\n// SVG element extractors\nfunction extractSVGElementBase(elt: SVGElement) {\n\treturn {\n\t\t...extractElementBase(elt),\n\t\t...extractHTMLOrSVGElement(elt as HTMLOrSVGElement),\n\t};\n}\n\n// Helper to compose per-SVG-element extractors with the shared base\nfunction withSVGBase<T extends SVGElement>(\n\tkeys: readonly (keyof T)[],\n\tcomputed?: Partial<Record<string, (src: T) => any>>,\n) {\n\tconst only = createExtractor<T>()(keys, computed as any);\n\treturn (elt: T) => ({ ...extractSVGElementBase(elt), ...only(elt) });\n}\n\nconst SVG_SVG_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"currentScale\",\n\t\"currentTranslate\",\n] as const satisfies readonly (keyof SVGSVGElement)[];\nconst svgExtractor = withSVGBase<SVGSVGElement>(SVG_SVG_KEYS);\n\nconst SVG_CIRCLE_KEYS = [\"cx\", \"cy\", \"r\"] as const satisfies readonly (keyof SVGCircleElement)[];\nconst circleExtractor = withSVGBase<SVGCircleElement>(SVG_CIRCLE_KEYS);\n\nconst SVG_ELLIPSE_KEYS = [\n\t\"cx\",\n\t\"cy\",\n\t\"rx\",\n\t\"ry\",\n] as const satisfies readonly (keyof SVGEllipseElement)[];\nconst ellipseExtractor = withSVGBase<SVGEllipseElement>(SVG_ELLIPSE_KEYS);\n\nconst SVG_LINE_KEYS = [\"x1\", \"y1\", \"x2\", \"y2\"] as const satisfies readonly (keyof SVGLineElement)[];\nconst lineExtractor = withSVGBase<SVGLineElement>(SVG_LINE_KEYS);\n\nconst SVG_PATH_KEYS = [\"pathLength\"] as const satisfies readonly (keyof SVGPathElement)[];\nconst pathExtractor = withSVGBase<SVGPathElement>(SVG_PATH_KEYS);\n\nconst SVG_RECT_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"rx\",\n\t\"ry\",\n] as const satisfies readonly (keyof SVGRectElement)[];\nconst rectExtractor = withSVGBase<SVGRectElement>(SVG_RECT_KEYS);\n\nconst SVG_POLYGON_KEYS = [\"points\"] as const satisfies readonly (keyof SVGPolygonElement)[];\nconst polygonExtractor = withSVGBase<SVGPolygonElement>(SVG_POLYGON_KEYS);\n\nconst SVG_POLYLINE_KEYS = [\"points\"] as const satisfies readonly (keyof SVGPolylineElement)[];\nconst polylineExtractor = withSVGBase<SVGPolylineElement>(SVG_POLYLINE_KEYS);\n\nconst SVG_TEXT_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"dx\",\n\t\"dy\",\n\t\"rotate\",\n\t\"textLength\",\n\t\"lengthAdjust\",\n] as const satisfies readonly (keyof SVGTextElement)[];\nconst textExtractor = withSVGBase<SVGTextElement>(SVG_TEXT_KEYS);\n\nconst SVG_TSPAN_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"dx\",\n\t\"dy\",\n\t\"rotate\",\n\t\"textLength\",\n\t\"lengthAdjust\",\n] as const satisfies readonly (keyof SVGTSpanElement)[];\nconst tspanExtractor = withSVGBase<SVGTSpanElement>(SVG_TSPAN_KEYS);\n\nconst SVG_IMAGE_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"href\",\n\t\"preserveAspectRatio\",\n\t\"crossOrigin\",\n] as const satisfies readonly (keyof SVGImageElement)[];\nconst svgImageExtractor = withSVGBase<SVGImageElement>(SVG_IMAGE_KEYS);\n\nconst SVG_USE_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"href\",\n] as const satisfies readonly (keyof SVGUseElement)[];\nconst useExtractor = withSVGBase<SVGUseElement>(SVG_USE_KEYS);\n\nconst SVG_DEFS_KEYS = [] as const satisfies readonly (keyof SVGDefsElement)[];\nconst defsExtractor = withSVGBase<SVGDefsElement>(SVG_DEFS_KEYS);\n\nconst SVG_GROUP_KEYS = [] as const satisfies readonly (keyof SVGGElement)[];\nconst gExtractor = withSVGBase<SVGGElement>(SVG_GROUP_KEYS);\n\nconst SVG_LINEAR_GRADIENT_KEYS = [\n\t\"x1\",\n\t\"y1\",\n\t\"x2\",\n\t\"y2\",\n\t\"gradientUnits\",\n\t\"gradientTransform\",\n\t\"spreadMethod\",\n] as const satisfies readonly (keyof SVGLinearGradientElement)[];\nconst linearGradientExtractor = withSVGBase<SVGLinearGradientElement>(SVG_LINEAR_GRADIENT_KEYS);\n\nconst SVG_RADIAL_GRADIENT_KEYS = [\n\t\"cx\",\n\t\"cy\",\n\t\"r\",\n\t\"fx\",\n\t\"fy\",\n\t\"fr\",\n\t\"gradientUnits\",\n\t\"gradientTransform\",\n\t\"spreadMethod\",\n] as const satisfies readonly (keyof SVGRadialGradientElement)[];\nconst radialGradientExtractor = withSVGBase<SVGRadialGradientElement>(SVG_RADIAL_GRADIENT_KEYS);\n\nconst SVG_STOP_KEYS = [\"offset\"] as const satisfies readonly (keyof SVGStopElement)[];\nconst stopExtractor = withSVGBase<SVGStopElement>(SVG_STOP_KEYS);\n\nconst SVG_PATTERN_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"patternUnits\",\n\t\"patternContentUnits\",\n\t\"patternTransform\",\n\t\"preserveAspectRatio\",\n\t\"href\",\n] as const satisfies readonly (keyof SVGPatternElement)[];\nconst patternExtractor = withSVGBase<SVGPatternElement>(SVG_PATTERN_KEYS);\n\nconst SVG_CLIP_PATH_KEYS = [\n\t\"clipPathUnits\",\n] as const satisfies readonly (keyof SVGClipPathElement)[];\nconst clipPathExtractor = withSVGBase<SVGClipPathElement>(SVG_CLIP_PATH_KEYS);\n\nconst SVG_MASK_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"maskUnits\",\n\t\"maskContentUnits\",\n] as const satisfies readonly (keyof SVGMaskElement)[];\nconst maskExtractor = withSVGBase<SVGMaskElement>(SVG_MASK_KEYS);\n\n// Map of tagName -> extractor (concise, like events.ts)\nconst elementExtractors: Record<string, (elt: any) => object> = {\n\tA: anchorExtractor,\n\tAREA: areaExtractor,\n\tAUDIO: audioExtractor,\n\tBASE: baseExtractor,\n\tBLOCKQUOTE: quoteExtractor,\n\tQ: quoteExtractor,\n\tBODY: bodyExtractor,\n\tBR: brExtractor,\n\tBUTTON: buttonExtractor,\n\tCANVAS: extractHTMLElementBase,\n\tCAPTION: tableCaptionExtractor,\n\tCITE: citeExtractor,\n\tCOL: tableColExtractor,\n\tCOLGROUP: tableColExtractor,\n\tDATA: dataExtractor,\n\tDETAILS: detailsExtractor,\n\tDIALOG: dialogExtractor,\n\tDIV: divExtractor,\n\tDL: dlistExtractor,\n\tEMBED: embedExtractor,\n\tFIELDSET: fieldsetExtractor,\n\tFORM: formExtractor,\n\tH1: headingExtractor,\n\tH2: headingExtractor,\n\tH3: headingExtractor,\n\tH4: headingExtractor,\n\tH5: headingExtractor,\n\tH6: headingExtractor,\n\tHEAD: headExtractor,\n\tHR: hrExtractor,\n\tHTML: htmlExtractor,\n\tIFRAME: iframeExtractor,\n\tIMG: imageExtractor,\n\tINPUT: inputExtractor,\n\tLABEL: labelExtractor,\n\tLI: liExtractor,\n\tLINK: linkExtractor,\n\tMAP: mapExtractor,\n\tMENU: menuExtractor,\n\tMETA: metaExtractor,\n\tMETER: meterExtractor,\n\tINS: modExtractor,\n\tDEL: modExtractor,\n\tOBJECT: objectExtractor,\n\tOL: olistExtractor,\n\tOPTGROUP: optgroupExtractor,\n\tOPTION: optionExtractor,\n\tOUTPUT: outputExtractor,\n\tP: paragraphExtractor,\n\tPICTURE: pictureExtractor,\n\tPRE: preExtractor,\n\tPROGRESS: progressExtractor,\n\tSCRIPT: scriptExtractor,\n\tSELECT: selectExtractor,\n\tSLOT: slotExtractor,\n\tSOURCE: sourceExtractor,\n\tSPAN: spanExtractor,\n\tSTYLE: styleExtractor,\n\tTABLE: tableExtractor,\n\tTBODY: tableSectionExtractor,\n\tTHEAD: tableSectionExtractor,\n\tTFOOT: tableSectionExtractor,\n\tTD: tableCellExtractor,\n\tTH: tableCellExtractor,\n\tTEMPLATE: templateExtractor,\n\tTEXTAREA: textareaExtractor,\n\tTIME: timeExtractor,\n\tTITLE: titleExtractor,\n\tTR: tableRowExtractor,\n\tTRACK: trackExtractor,\n\tUL: ulistExtractor,\n\tVIDEO: videoExtractor,\n\t// SVG elements\n\tSVG: svgExtractor,\n\tCIRCLE: circleExtractor,\n\tELLIPSE: ellipseExtractor,\n\tLINE: lineExtractor,\n\tPATH: pathExtractor,\n\tRECT: rectExtractor,\n\tPOLYGON: polygonExtractor,\n\tPOLYLINE: polylineExtractor,\n\tTEXT: textExtractor,\n\tTSPAN: tspanExtractor,\n\tIMAGE: svgImageExtractor,\n\tUSE: useExtractor,\n\tDEFS: defsExtractor,\n\tG: gExtractor,\n\tLINEARGRADIENT: linearGradientExtractor,\n\tRADIALGRADIENT: radialGradientExtractor,\n\tSTOP: stopExtractor,\n\tPATTERN: patternExtractor,\n\tCLIPPATH: clipPathExtractor,\n\tMASK: maskExtractor,\n};\n\nexport function extractHTMLElement(elt: HTMLElement): object {\n\tconst tagName = elt.tagName.toUpperCase();\n\n\tconst extractor = elementExtractors[tagName];\n\tif (extractor) {\n\t\treturn extractor(elt);\n\t}\n\tthrow new Error(`Unexpected HTML element tag: ${elt.tagName} (update .web/custom/serialize.ts)`);\n}\n\nexport function extractSVGElement(elt: SVGElement): object {\n\tconst tagName = elt.tagName.toUpperCase();\n\n\tconst extractor = elementExtractors[tagName];\n\tif (extractor) {\n\t\treturn extractor(elt);\n\t}\n\t// Fallback to base SVG element extractor for unknown SVG elements\n\treturn extractSVGElementBase(elt);\n}\n\nexport function extractElement(elt: Element): object {\n\tif (elt instanceof HTMLElement) {\n\t\treturn extractHTMLElement(elt);\n\t}\n\tif (elt instanceof SVGElement) {\n\t\treturn extractSVGElement(elt);\n\t}\n\t// Fallback for other Element types - use base element extractor\n\treturn extractElementBase(elt);\n}\n","/* === IMPORTANT === */\n\nimport { extractElement } from \"./elements\";\nimport { createExtractor } from \"./extractor\";\n\n// Reusable computed mappers (helps bundlers/minifiers share references)\nconst mapTarget = (e: { target: EventTarget | null }) => extractElement(e.target as Element);\nconst mapRelated = (e: { relatedTarget: EventTarget | null }) =>\n\te.relatedTarget ? extractElement(e.relatedTarget as Element) : null;\n\nfunction makeExtractor<K extends readonly any[]>(\n\tkeys: K,\n\tcomputed?: Record<string, (evt: any) => any>,\n) {\n\treturn createExtractor<any>()(\n\t\tkeys as any,\n\t\t{\n\t\t\ttarget: mapTarget,\n\t\t\t...(computed || {}),\n\t\t} as any,\n\t);\n}\n\nconst SYNTHETIC_KEYS = [\n\t\"target\",\n\t\"bubbles\",\n\t\"cancelable\",\n\t\"defaultPrevented\",\n\t\"eventPhase\",\n\t\"isTrusted\",\n\t\"timeStamp\",\n\t\"type\",\n] as const satisfies readonly (keyof React.SyntheticEvent)[];\n\nconst UI_KEYS = [...SYNTHETIC_KEYS, \"detail\"] as const satisfies readonly (keyof React.UIEvent)[];\n\nconst MOUSE_KEYS = [\n\t...UI_KEYS,\n\t\"altKey\",\n\t\"button\",\n\t\"buttons\",\n\t\"clientX\",\n\t\"clientY\",\n\t\"ctrlKey\",\n\t\"metaKey\",\n\t\"movementX\",\n\t\"movementY\",\n\t\"pageX\",\n\t\"pageY\",\n\t\"screenX\",\n\t\"screenY\",\n\t\"shiftKey\",\n] as const satisfies readonly (keyof React.MouseEvent)[];\n\nconst POINTER_KEYS = [\n\t...MOUSE_KEYS,\n\t\"pointerId\",\n\t\"pressure\",\n\t\"tangentialPressure\",\n\t\"tiltX\",\n\t\"tiltY\",\n\t\"twist\",\n\t\"width\",\n\t\"height\",\n\t\"pointerType\",\n\t\"isPrimary\",\n] as const satisfies readonly (keyof React.PointerEvent)[];\n\nconst syntheticExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst uiExtractor = makeExtractor(UI_KEYS);\n\nconst mouseExtractor = makeExtractor(MOUSE_KEYS, { relatedTarget: mapRelated });\n\nconst clipboardExtractor = makeExtractor(SYNTHETIC_KEYS, {\n\tclipboardData: (e) => extractDataTransfer(e.clipboardData),\n});\n\nconst compositionExtractor = makeExtractor([...SYNTHETIC_KEYS, \"data\"] as const);\n\nconst dragExtractor = makeExtractor(MOUSE_KEYS, {\n\trelatedTarget: mapRelated,\n\tdataTransfer: (e) => extractDataTransfer(e.dataTransfer),\n});\n\nconst pointerExtractor = makeExtractor(POINTER_KEYS, {\n\trelatedTarget: mapRelated,\n});\n\nconst focusExtractor = makeExtractor(SYNTHETIC_KEYS, {\n\trelatedTarget: mapRelated,\n});\n\nconst formExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst invalidExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst changeExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst keyboardExtractor = makeExtractor([\n\t...UI_KEYS,\n\t\"altKey\",\n\t\"ctrlKey\",\n\t\"code\",\n\t\"key\",\n\t\"locale\",\n\t\"location\",\n\t\"metaKey\",\n\t\"repeat\",\n\t\"shiftKey\",\n] as const);\n\nconst touchExtractor = makeExtractor(\n\t[\n\t\t...UI_KEYS,\n\t\t\"altKey\",\n\t\t\"ctrlKey\",\n\t\t\"metaKey\",\n\t\t\"shiftKey\",\n\t\t\"changedTouches\",\n\t\t\"targetTouches\",\n\t\t\"touches\",\n\t] as const,\n\t{\n\t\tchangedTouches: (e) => mapTouchList(e.changedTouches),\n\t\ttargetTouches: (e) => mapTouchList(e.targetTouches),\n\t\ttouches: (e) => mapTouchList(e.touches),\n\t},\n);\n\nconst wheelExtractor = makeExtractor(\n\t[...MOUSE_KEYS, \"deltaMode\", \"deltaX\", \"deltaY\", \"deltaZ\"] as const,\n\t{\n\t\trelatedTarget: mapRelated,\n\t},\n);\n\nconst animationExtractor = makeExtractor([\n\t...SYNTHETIC_KEYS,\n\t\"animationName\",\n\t\"elapsedTime\",\n\t\"pseudoElement\",\n] as const);\n\nconst toggleExtractor = makeExtractor([...SYNTHETIC_KEYS, \"oldState\", \"newState\"] as const);\n\nconst transitionExtractor = makeExtractor([\n\t...SYNTHETIC_KEYS,\n\t\"elapsedTime\",\n\t\"propertyName\",\n\t\"pseudoElement\",\n] as const);\n\nfunction mapTouchList(list: any): any[] {\n\treturn Array.from(list as ArrayLike<any>).map((touch: any) => ({\n\t\ttarget: extractElement(touch.target as Element),\n\t\tidentifier: touch.identifier,\n\t\tscreenX: touch.screenX,\n\t\tscreenY: touch.screenY,\n\t\tclientX: touch.clientX,\n\t\tclientY: touch.clientY,\n\t\tpageX: touch.pageX,\n\t\tpageY: touch.pageY,\n\t}));\n}\n\n// Helper function to extract DataTransfer properties\nfunction extractDataTransfer(dt: DataTransfer | null): object | null {\n\tif (!dt) {\n\t\treturn null;\n\t}\n\tconst items = [];\n\tif (dt.items) {\n\t\tfor (let i = 0; i < dt.items.length; i++) {\n\t\t\tconst item = dt.items[i]!;\n\t\t\titems.push({\n\t\t\t\tkind: item.kind,\n\t\t\t\ttype: item.type,\n\t\t\t});\n\t\t}\n\t}\n\treturn {\n\t\tdrop_effect: dt.dropEffect,\n\t\teffect_allowed: dt.effectAllowed,\n\t\titems: items,\n\t\ttypes: Array.from(dt.types || []),\n\t};\n}\n\nconst eventExtractorMap: { [key: string]: (evt: any) => object } = {};\n\nfunction add(map: Record<string, any>, names: readonly string[], fn: any) {\n\tfor (const n of names) map[n] = fn;\n}\n\nadd(\n\teventExtractorMap,\n\t[\n\t\t\"pointerdown\",\n\t\t\"pointermove\",\n\t\t\"pointerup\",\n\t\t\"pointercancel\",\n\t\t\"gotpointercapture\",\n\t\t\"lostpointercapture\",\n\t\t\"pointerenter\",\n\t\t\"pointerleave\",\n\t\t\"pointerover\",\n\t\t\"pointerout\",\n\t],\n\tpointerExtractor,\n);\n\nadd(\n\teventExtractorMap,\n\t[\n\t\t\"click\",\n\t\t\"contextmenu\",\n\t\t\"dblclick\",\n\t\t\"mousedown\",\n\t\t\"mouseenter\",\n\t\t\"mouseleave\",\n\t\t\"mousemove\",\n\t\t\"mouseout\",\n\t\t\"mouseover\",\n\t\t\"mouseup\",\n\t],\n\tmouseExtractor,\n);\n\nadd(\n\teventExtractorMap,\n\t[\"drag\", \"dragend\", \"dragenter\", \"dragexit\", \"dragleave\", \"dragover\", \"dragstart\", \"drop\"],\n\tdragExtractor,\n);\n\nadd(eventExtractorMap, [\"keydown\", \"keypress\", \"keyup\"], keyboardExtractor);\nadd(eventExtractorMap, [\"focus\", \"blur\"], focusExtractor);\nadd(eventExtractorMap, [\"change\", \"input\"], changeExtractor);\nadd(eventExtractorMap, [\"invalid\"], invalidExtractor);\nadd(eventExtractorMap, [\"reset\", \"submit\"], formExtractor);\nadd(eventExtractorMap, [\"copy\", \"cut\", \"paste\"], clipboardExtractor);\nadd(\n\teventExtractorMap,\n\t[\"compositionend\", \"compositionstart\", \"compositionupdate\"],\n\tcompositionExtractor,\n);\nadd(eventExtractorMap, [\"touchcancel\", \"touchend\", \"touchmove\", \"touchstart\"], touchExtractor);\nadd(eventExtractorMap, [\"scroll\"], uiExtractor);\nadd(eventExtractorMap, [\"wheel\"], wheelExtractor);\nadd(\n\teventExtractorMap,\n\t[\"animationstart\", \"animationend\", \"animationiteration\"],\n\tanimationExtractor,\n);\nadd(eventExtractorMap, [\"transitionend\"], transitionExtractor);\nadd(eventExtractorMap, [\"toggle\"], toggleExtractor);\n\nexport function extractEvent(value: any): any {\n\t// Duck-typing for React's SyntheticEvent.\n\t// We check for properties that are unique to synthetic events.\n\tif (\n\t\tvalue &&\n\t\ttypeof value === \"object\" &&\n\t\t\"nativeEvent\" in value &&\n\t\ttypeof value.isDefaultPrevented === \"function\"\n\t) {\n\t\tconst evt = value as React.SyntheticEvent;\n\t\t// The `type` property is crucial for the lookup.\n\t\tif (typeof evt.type !== \"string\") {\n\t\t\treturn value;\n\t\t}\n\n\t\tconst extractor = eventExtractorMap[evt.type.toLowerCase()];\n\t\tif (extractor) {\n\t\t\treturn extractor(evt);\n\t\t}\n\n\t\t// Fallback for unknown event types: minimal synthetic extractor\n\t\treturn syntheticExtractor(evt);\n\t}\n\n\t// If it's not a duck-typed event, return it as is.\n\treturn value;\n}\n","export type Primitive = number | string | boolean | null | undefined;\nexport type JSON<T> = T | Array<JSON<T>> | { [K: string]: JSON<T> };\nexport type PlainJSON = JSON<Primitive>;\nexport type Serializable = any;\n\nexport type Serialized = [[number[], number[], number[], number[]], PlainJSON];\n\nexport function serialize(data: Serializable): Serialized {\n\tconst seen = new Map<any, number>();\n\tconst refs: number[] = [];\n\tconst dates: number[] = [];\n\tconst sets: number[] = [];\n\tconst maps: number[] = [];\n\n\t// Single global counter - increments once per node visit\n\tlet globalIndex = 0;\n\n\tfunction process(value: Serializable): PlainJSON {\n\t\tif (\n\t\t\tvalue == null ||\n\t\t\ttypeof value === \"number\" ||\n\t\t\ttypeof value === \"string\" ||\n\t\t\ttypeof value === \"boolean\"\n\t\t) {\n\t\t\treturn value;\n\t\t}\n\n\t\tconst idx = globalIndex++;\n\t\tconst prevRef = seen.get(value);\n\t\tif (prevRef !== undefined) {\n\t\t\t// Make sure to push the current index, but use the ref's index as the value!\n\t\t\trefs.push(idx);\n\t\t\treturn prevRef;\n\t\t}\n\n\t\tseen.set(value, idx);\n\n\t\tif (value instanceof Date) {\n\t\t\tdates.push(idx);\n\t\t\treturn value.getTime();\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tconst length = value.length;\n\t\t\tconst result = new Array(length);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tresult[i] = process(value[i]);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tif (value instanceof Map) {\n\t\t\tmaps.push(idx);\n\t\t\tconst rec: Record<string, any> = {};\n\t\t\tfor (const [key, entry] of value.entries()) {\n\t\t\t\trec[String(key)] = process(entry);\n\t\t\t}\n\t\t\treturn rec;\n\t\t}\n\n\t\tif (value instanceof Set) {\n\t\t\tsets.push(idx);\n\t\t\tconst size = value.size;\n\t\t\tconst result = new Array(size);\n\t\t\tlet i = 0;\n\t\t\tfor (const entry of value) {\n\t\t\t\tresult[i] = process(entry);\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tif (typeof value === \"object\") {\n\t\t\tconst rec: Record<string, any> = {};\n\t\t\tconst keys = Object.keys(value);\n\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\tconst key = keys[i];\n\t\t\t\trec[key] = process(value[key]);\n\t\t\t}\n\t\t\treturn rec;\n\t\t}\n\n\t\tthrow new Error(`Unsupported value in serialization: ${value}`);\n\t}\n\n\tconst payload = process(data);\n\treturn [[refs, dates, sets, maps], payload];\n}\n\nexport interface DeserializationOptions {\n\tcoerceNullsToUndefined?: boolean;\n}\n\nexport function deserialize<Data extends Serializable = Serializable>(\n\tpayload: Serialized,\n\toptions?: DeserializationOptions,\n): Data {\n\tconst [[refsA, datesA, setsA, mapsA], data] = payload;\n\n\tconst refs = new Set(refsA);\n\tconst dates = new Set(datesA);\n\tconst sets = new Set(setsA);\n\tconst maps = new Set(mapsA);\n\n\tconst objects: Array<any> = [];\n\n\tfunction reconstruct(value: PlainJSON): any {\n\t\tconst idx = objects.length;\n\t\tif (refs.has(idx)) {\n\t\t\t// We increment the counter on refs during serialization. We're never\n\t\t\t// going to use this entry, so we can just push null.\n\t\t\tobjects.push(null);\n\t\t\treturn objects[value as number];\n\t\t}\n\n\t\tif (dates.has(idx)) {\n\t\t\tconst dt = new Date(value as number);\n\t\t\tobjects.push(dt);\n\t\t\treturn dt;\n\t\t}\n\n\t\tif (\n\t\t\tvalue == null ||\n\t\t\ttypeof value === \"number\" ||\n\t\t\ttypeof value === \"string\" ||\n\t\t\ttypeof value === \"boolean\"\n\t\t) {\n\t\t\tif (options?.coerceNullsToUndefined) {\n\t\t\t\treturn value ?? undefined;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tif (sets.has(idx)) {\n\t\t\t\tconst result = new Set();\n\t\t\t\tobjects.push(result);\n\t\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\t\tresult.add(reconstruct(value[i]));\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tconst length = value.length;\n\t\t\tconst arr = new Array(length);\n\t\t\tobjects.push(arr);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tarr[i] = reconstruct(value[i]);\n\t\t\t}\n\t\t\treturn arr;\n\t\t}\n\n\t\tif (typeof value === \"object\") {\n\t\t\tif (maps.has(idx)) {\n\t\t\t\tconst result = new Map<string, any>();\n\t\t\t\tobjects.push(result);\n\t\t\t\tconst keys = Object.keys(value);\n\t\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\t\tconst key = keys[i];\n\t\t\t\t\tresult.set(key, reconstruct(value[key]));\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tconst result: Record<string, any> = {};\n\t\t\tobjects.push(result);\n\t\t\tconst keys = Object.keys(value);\n\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\tconst key = keys[i];\n\t\t\t\tresult[key] = reconstruct(value[key]);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tthrow new Error(`Unsupported value in deserialization: ${value}`);\n\t}\n\n\treturn reconstruct(data);\n}\n","import type { NavigateFunction } from \"react-router\";\nimport { io, type Socket } from \"socket.io-client\";\nimport type { ChannelBridge } from \"./channel\";\nimport { createChannelBridge, PulseChannelResetError } from \"./channel\";\nimport type { RouteInfo } from \"./helpers\";\nimport type {\n\tClientApiResultMessage,\n\tClientMessage,\n\tServerApiCallMessage,\n\tServerChannelMessage,\n\tServerErrorInfo,\n\tServerMessage,\n} from \"./messages\";\nimport type { PulsePrerenderView } from \"./pulse\";\nimport { extractEvent } from \"./serialize/events\";\nimport { deserialize, serialize } from \"./serialize/serializer\";\nimport type { VDOMUpdate } from \"./vdom\";\n\nexport interface SocketIODirectives {\n\theaders?: Record<string, string>;\n\tauth?: Record<string, string>;\n}\nexport interface Directives {\n\theaders?: Record<string, string>;\n\tsocketio?: SocketIODirectives;\n}\nexport interface MountedView {\n\trouteInfo: RouteInfo;\n\tonInit: (view: PulsePrerenderView) => void;\n\tonUpdate: (ops: VDOMUpdate[]) => void;\n}\nexport type ConnectionStatusListener = (connected: boolean) => void;\nexport type ServerErrorListener = (path: string, error: ServerErrorInfo | null) => void;\n\nexport interface PulseClient {\n\t// Connection management\n\tconnect(): Promise<void>;\n\tdisconnect(): void;\n\tisConnected(): boolean;\n\tonConnectionChange(listener: ConnectionStatusListener): () => void;\n\t// Messages\n\tnavigate(path: string, routeInfo: RouteInfo): Promise<void>;\n\tleave(path: string): Promise<void>;\n\tinvokeCallback(path: string, callback: string, args: any[]): Promise<void>;\n\t// VDOM subscription\n\tmountView(path: string, view: MountedView): () => void;\n}\n\nexport class PulseSocketIOClient {\n\t#activeViews: Map<string, MountedView>;\n\t#socket: Socket | null = null;\n\t#messageQueue: ClientMessage[];\n\t#connectionListeners: Set<ConnectionStatusListener> = new Set();\n\t#serverErrors: Map<string, ServerErrorInfo> = new Map();\n\t#serverErrorListeners: Set<ServerErrorListener> = new Set();\n\t#channels: Map<string, { bridge: ChannelBridge; refCount: number }> = new Map();\n\t#url: string;\n\t#frameworkNavigate: NavigateFunction;\n\t#directives: Directives;\n\n\tconstructor(url: string, directives: Directives, frameworkNavigate: NavigateFunction) {\n\t\tthis.#url = url;\n\t\tthis.#directives = directives;\n\t\tthis.#frameworkNavigate = frameworkNavigate;\n\t\tthis.#socket = null;\n\t\tthis.#activeViews = new Map();\n\t\tthis.#messageQueue = [];\n\t\t// Load directives from sessionStorage\n\t\tif (typeof window !== \"undefined\" && typeof sessionStorage !== \"undefined\") {\n\t\t\tconst stored = sessionStorage.getItem(\"__PULSE_DIRECTIVES\");\n\t\t\tif (stored) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.#directives = JSON.parse(stored);\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore parse errors\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tpublic setDirectives(directives: Directives) {\n\t\tthis.#directives = directives;\n\t}\n\tpublic isConnected(): boolean {\n\t\treturn this.#socket?.connected ?? false;\n\t}\n\n\tpublic async connect(): Promise<void> {\n\t\tif (this.#socket) {\n\t\t\treturn;\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst socket = io(this.#url, {\n\t\t\t\ttransports: [\"websocket\", \"webtransport\"],\n\t\t\t\tauth: this.#directives.socketio?.auth,\n\t\t\t\textraHeaders: this.#directives.socketio?.headers,\n\t\t\t});\n\t\t\tthis.#socket = socket;\n\n\t\t\tsocket.on(\"connect\", () => {\n\t\t\t\tconsole.log(\"[SocketIOTransport] Connected:\", this.#socket?.id);\n\t\t\t\t// Make sure to send a navigate payload for all the routes\n\t\t\t\tfor (const [path, route] of this.#activeViews) {\n\t\t\t\t\tsocket.emit(\n\t\t\t\t\t\t\"message\",\n\t\t\t\t\t\tserialize({\n\t\t\t\t\t\t\ttype: \"mount\",\n\t\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\t\trouteInfo: route.routeInfo,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tfor (const payload of this.#messageQueue) {\n\t\t\t\t\t// Already sent above\n\t\t\t\t\tif (payload.type === \"mount\" && this.#activeViews.has(payload.path)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t// We're remounting all the routes, so no need to navigate\n\t\t\t\t\tif (payload.type === \"navigate\") {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tsocket.emit(\"message\", serialize(payload));\n\t\t\t\t}\n\t\t\t\tthis.#messageQueue = [];\n\n\t\t\t\tthis.notifyConnectionListeners(true);\n\t\t\t\tresolve();\n\t\t\t});\n\n\t\t\tsocket.on(\"connect_error\", (err) => {\n\t\t\t\tconsole.error(\"[SocketIOTransport] Connection failed:\", err);\n\t\t\t\tthis.notifyConnectionListeners(false);\n\t\t\t\treject(err);\n\t\t\t});\n\n\t\t\tsocket.on(\"disconnect\", () => {\n\t\t\t\tconsole.log(\"[SocketIOTransport] Disconnected\");\n\t\t\t\tthis.#handleTransportDisconnect();\n\t\t\t\tthis.notifyConnectionListeners(false);\n\t\t\t});\n\n\t\t\t// Wrap in an arrow function to avoid losing the `this` reference\n\t\t\tsocket.on(\"message\", (data) =>\n\t\t\t\tthis.#handleServerMessage(deserialize(data, { coerceNullsToUndefined: true })),\n\t\t\t);\n\t\t});\n\t}\n\n\tonConnectionChange(listener: ConnectionStatusListener): () => void {\n\t\tthis.#connectionListeners.add(listener);\n\t\t// Only notify immediately if we've attempted connection (socket exists)\n\t\t// This prevents showing error before first connection attempt\n\t\tif (this.#socket !== null) {\n\t\t\tlistener(this.isConnected());\n\t\t}\n\t\treturn () => {\n\t\t\tthis.#connectionListeners.delete(listener);\n\t\t};\n\t}\n\n\tprivate notifyConnectionListeners(connected: boolean): void {\n\t\tfor (const listener of this.#connectionListeners) {\n\t\t\tlistener(connected);\n\t\t}\n\t}\n\n\tpublic onServerError(listener: ServerErrorListener): () => void {\n\t\tthis.#serverErrorListeners.add(listener);\n\t\t// Emit current errors to new listener\n\t\tfor (const [path, err] of this.#serverErrors) listener(path, err);\n\t\treturn () => {\n\t\t\tthis.#serverErrorListeners.delete(listener);\n\t\t};\n\t}\n\n\tprivate notifyServerError(path: string, error: ServerErrorInfo | null) {\n\t\tfor (const listener of this.#serverErrorListeners) listener(path, error);\n\t}\n\n\tpublic sendMessage(payload: ClientMessage) {\n\t\tif (this.isConnected()) {\n\t\t\t// console.log(\"[SocketIOTransport] Sending:\", payload);\n\t\t\tthis.#socket!.emit(\"message\", serialize(payload as any));\n\t\t} else {\n\t\t\t// console.log(\"[SocketIOTransport] Queuing message:\", payload);\n\t\t\tthis.#messageQueue.push(payload);\n\t\t}\n\t}\n\n\tpublic mountView(path: string, view: MountedView) {\n\t\tif (this.#activeViews.has(path)) {\n\t\t\tthrow new Error(`Path ${path} is already mounted`);\n\t\t}\n\t\tthis.#activeViews.set(path, view);\n\t\tvoid this.sendMessage({\n\t\t\ttype: \"mount\",\n\t\t\tpath,\n\t\t\trouteInfo: view.routeInfo,\n\t\t});\n\t}\n\n\tpublic navigate(path: string, routeInfo: RouteInfo) {\n\t\tthis.sendMessage({\n\t\t\ttype: \"navigate\",\n\t\t\tpath,\n\t\t\trouteInfo,\n\t\t});\n\t}\n\n\tpublic unmount(path: string) {\n\t\tvoid this.sendMessage({ type: \"unmount\", path });\n\t\tthis.#activeViews.delete(path);\n\t}\n\n\tpublic disconnect() {\n\t\tthis.#socket?.disconnect();\n\t\tthis.#socket = null;\n\t\tthis.#messageQueue = [];\n\t\tthis.#connectionListeners.clear();\n\t\tthis.#activeViews.clear();\n\t\tthis.#serverErrors.clear();\n\t\tthis.#serverErrorListeners.clear();\n\t\tfor (const { bridge } of this.#channels.values()) {\n\t\t\tbridge.dispose(new PulseChannelResetError(\"Client disconnected\"));\n\t\t}\n\t\tthis.#channels.clear();\n\t}\n\n\t#handleServerMessage(message: ServerMessage) {\n\t\t// console.log(\"[PulseClient] Received message:\", message);\n\t\tswitch (message.type) {\n\t\t\tcase \"vdom_init\": {\n\t\t\t\tconst route = this.#activeViews.get(message.path);\n\t\t\t\t// Ignore messages for paths that are not mounted\n\t\t\t\tif (!route) return;\n\t\t\t\tif (route) {\n\t\t\t\t\troute.onInit(message);\n\t\t\t\t}\n\t\t\t\t// Clear any prior error for this path on successful init\n\t\t\t\tif (this.#serverErrors.has(message.path)) {\n\t\t\t\t\tthis.#serverErrors.delete(message.path);\n\t\t\t\t\tthis.notifyServerError(message.path, null);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"vdom_update\": {\n\t\t\t\tconst route = this.#activeViews.get(message.path);\n\t\t\t\tif (!route) return; // Not an active path; discard\n\t\t\t\troute.onUpdate(message.ops);\n\t\t\t\t// Clear any prior error for this path on successful update\n\t\t\t\tif (this.#serverErrors.has(message.path)) {\n\t\t\t\t\tthis.#serverErrors.delete(message.path);\n\t\t\t\t\tthis.notifyServerError(message.path, null);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"server_error\": {\n\t\t\t\tif (!this.#activeViews.has(message.path)) return; // discard for inactive paths\n\t\t\t\tthis.#serverErrors.set(message.path, message.error);\n\t\t\t\tthis.notifyServerError(message.path, message.error);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"api_call\": {\n\t\t\t\tvoid this.#performApiCall(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"navigate_to\": {\n\t\t\t\t// `navigate_to` is navigational; allow regardless of activeViews membership\n\t\t\t\tconst replace = !!message.replace;\n\t\t\t\tlet dest = message.path || \"\";\n\t\t\t\t// Normalize protocol-relative URLs to absolute\n\t\t\t\tif (dest.startsWith(\"//\")) dest = `${window.location.protocol}${dest}`;\n\t\t\t\tconst hasScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(dest);\n\t\t\t\tif (hasScheme) {\n\t\t\t\t\tif (dest.startsWith(\"http://\") || dest.startsWith(\"https://\")) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst url = new URL(dest);\n\t\t\t\t\t\t\tif (url.origin === window.location.origin) {\n\t\t\t\t\t\t\t\tconst internal = `${url.pathname}${url.search}${url.hash}`;\n\t\t\t\t\t\t\t\tthis.#frameworkNavigate(internal, { replace });\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (replace) window.location.replace(dest);\n\t\t\t\t\t\t\t\telse window.location.assign(dest);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tif (replace) window.location.replace(dest);\n\t\t\t\t\t\t\telse window.location.assign(dest);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// mailto:, tel:, data:, etc.\n\t\t\t\t\t\tif (replace) window.location.replace(dest);\n\t\t\t\t\t\telse window.location.assign(dest);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Relative or root-relative path → SPA navigate\n\t\t\t\t\tthis.#frameworkNavigate(dest, { replace });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"channel_message\": {\n\t\t\t\tthis.#routeChannelMessage(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconsole.error(\"Unexpected message:\", message);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync #performApiCall(msg: ServerApiCallMessage) {\n\t\ttry {\n\t\t\tconst res = await fetch(msg.url, {\n\t\t\t\tmethod: msg.method || \"GET\",\n\t\t\t\theaders: {\n\t\t\t\t\t...(msg.headers || {}),\n\t\t\t\t\t...(msg.body != null && !(\"content-type\" in (msg.headers || {}))\n\t\t\t\t\t\t? { \"content-type\": \"application/json\" }\n\t\t\t\t\t\t: {}),\n\t\t\t\t},\n\t\t\t\tbody:\n\t\t\t\t\tmsg.body != null\n\t\t\t\t\t\t? typeof msg.body === \"string\"\n\t\t\t\t\t\t\t? msg.body\n\t\t\t\t\t\t\t: JSON.stringify(msg.body)\n\t\t\t\t\t\t: undefined,\n\t\t\t\tcredentials: msg.credentials || \"include\",\n\t\t\t});\n\t\t\tconst headersObj: Record<string, string> = {};\n\t\t\tres.headers.forEach((v, k) => {\n\t\t\t\theadersObj[k] = v;\n\t\t\t});\n\t\t\tlet body: any = null;\n\t\t\tconst ct = res.headers.get(\"content-type\") || \"\";\n\t\t\tif (ct.includes(\"application/json\")) {\n\t\t\t\tbody = await res.json().catch(() => null);\n\t\t\t} else {\n\t\t\t\tbody = await res.text().catch(() => null);\n\t\t\t}\n\t\t\tconst reply: ClientApiResultMessage = {\n\t\t\t\ttype: \"api_result\",\n\t\t\t\tid: msg.id,\n\t\t\t\tok: res.ok,\n\t\t\t\tstatus: res.status,\n\t\t\t\theaders: headersObj,\n\t\t\t\tbody,\n\t\t\t};\n\t\t\tthis.sendMessage(reply);\n\t\t} catch (err) {\n\t\t\tconst reply: ClientApiResultMessage = {\n\t\t\t\ttype: \"api_result\",\n\t\t\t\tid: msg.id,\n\t\t\t\tok: false,\n\t\t\t\tstatus: 0,\n\t\t\t\theaders: {},\n\t\t\t\tbody: { error: String(err) },\n\t\t\t};\n\t\t\tthis.sendMessage(reply);\n\t\t}\n\t}\n\n\tpublic invokeCallback(path: string, callback: string, args: any[]) {\n\t\tthis.sendMessage({\n\t\t\ttype: \"callback\",\n\t\t\tpath,\n\t\t\tcallback,\n\t\t\targs: args.map(extractEvent),\n\t\t});\n\t}\n\n\tpublic acquireChannel(id: string): ChannelBridge {\n\t\tconst entry = this.#ensureChannelEntry(id);\n\t\tentry.refCount += 1;\n\t\treturn entry.bridge;\n\t}\n\n\tpublic releaseChannel(id: string): void {\n\t\tconst entry = this.#channels.get(id);\n\t\tif (!entry) {\n\t\t\treturn;\n\t\t}\n\t\tentry.refCount = Math.max(0, entry.refCount - 1);\n\t\tif (entry.refCount === 0) {\n\t\t\tentry.bridge.dispose(new PulseChannelResetError(\"Channel released\"));\n\t\t\tthis.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: id,\n\t\t\t\tevent: \"__close__\",\n\t\t\t\tpayload: { reason: \"refcount_zero\" },\n\t\t\t});\n\t\t\tthis.#channels.delete(id);\n\t\t}\n\t}\n\n\t#ensureChannelEntry(id: string): {\n\t\tbridge: ChannelBridge;\n\t\trefCount: number;\n\t} {\n\t\tlet entry = this.#channels.get(id);\n\t\tif (!entry) {\n\t\t\tentry = {\n\t\t\t\tbridge: createChannelBridge(this, id),\n\t\t\t\trefCount: 0,\n\t\t\t};\n\t\t\tthis.#channels.set(id, entry);\n\t\t}\n\t\treturn entry;\n\t}\n\n\t#routeChannelMessage(message: ServerChannelMessage): void {\n\t\tconst entry = this.#ensureChannelEntry(message.channel);\n\t\tconst closed = entry.bridge.handleServerMessage(message);\n\t\tif (closed && entry.refCount === 0) {\n\t\t\tthis.#channels.delete(message.channel);\n\t\t}\n\t}\n\n\t#handleTransportDisconnect(): void {\n\t\tfor (const entry of this.#channels.values()) {\n\t\t\tentry.bridge.handleDisconnect(new PulseChannelResetError(\"Connection lost\"));\n\t\t}\n\t}\n}\n","import type { ComponentType } from \"react\";\n\n// Special prefixes for reserved node types\nexport const FRAGMENT_TAG = \"$$fragment\";\nexport const MOUNT_POINT_PREFIX = \"$$\";\n\n// export type LazyComponent = () => Promise<{ default: ComponentType<any> }>;\nexport type RegistryEntry = ComponentType<any>;\nexport type ComponentRegistry = Record<string, ComponentType<any>>;\n\nexport interface VDOMElement {\n\ttag: string;\n\tprops?: Record<string, any>;\n\tchildren?: VDOMNode[];\n\tkey?: string;\n\tlazy?: boolean;\n}\n\n// Primitive nodes that can be rendered\nexport type PrimitiveNode = string | number | boolean;\n\n// VDOMNode is either a primitive (string, number, boolean) or an element node.\n// Booleans are valid children in React but do not render anything.\n// Mount points are just UIElementNodes with tags starting with $$ComponentKey\nexport type VDOMNode = PrimitiveNode | VDOMElement;\n\nexport type VDOM = VDOMNode;\n\nexport interface VDOMUpdateBase {\n\ttype: string;\n\tpath: string; // Dot-separated path to the node\n}\n\nexport interface ReplaceUpdate extends VDOMUpdateBase {\n\ttype: \"replace\";\n\tdata: VDOMNode; // The new node\n}\n\nexport interface UpdatePropsUpdate extends VDOMUpdateBase {\n\ttype: \"update_props\";\n\tdata: {\n\t\tset?: Record<string, any>;\n\t\tremove?: string[];\n\t};\n}\n\nexport interface ReconciliationUpdate {\n\ttype: \"reconciliation\";\n\tpath: string;\n\tN: number;\n\tnew: [number[], VDOM[]];\n\treuse: [number[], number[]];\n}\n\nexport interface PathDelta {\n\tadd?: string[];\n\tremove?: string[];\n}\n\nexport interface UpdateCallbacksUpdate extends VDOMUpdateBase {\n\ttype: \"update_callbacks\";\n\tdata: PathDelta;\n}\n\nexport interface UpdateRenderPropsUpdate extends VDOMUpdateBase {\n\ttype: \"update_render_props\";\n\tdata: PathDelta;\n}\n\nexport interface UpdateCssRefsUpdate extends VDOMUpdateBase {\n\ttype: \"update_css_refs\";\n\tdata: PathDelta;\n}\n\nexport type VDOMUpdate =\n\t| ReplaceUpdate\n\t| UpdatePropsUpdate\n\t| ReconciliationUpdate\n\t| UpdateCallbacksUpdate\n\t| UpdateRenderPropsUpdate\n\t| UpdateCssRefsUpdate;\n\nexport type UpdateType = VDOMUpdate[\"type\"];\n\n// Utility functions for working with the UI tree structure\nexport function isElementNode(node: VDOMNode): node is VDOMElement {\n\t// Matches all non-text nodes\n\treturn typeof node === \"object\" && node !== null;\n}\n\nexport function isMountPointNode(node: VDOMNode): node is VDOMElement {\n\treturn (\n\t\ttypeof node === \"object\" &&\n\t\tnode !== null &&\n\t\tnode.tag.startsWith(MOUNT_POINT_PREFIX) &&\n\t\tnode.tag !== FRAGMENT_TAG\n\t);\n}\n\nexport function isTextNode(node: VDOMNode): node is string {\n\treturn typeof node === \"string\";\n}\n\nexport function isFragment(node: VDOMNode): boolean {\n\treturn typeof node === \"object\" && node !== null && node.tag === FRAGMENT_TAG;\n}\n","import {\n\ttype ComponentType,\n\tcloneElement,\n\tcreateElement,\n\ttype FC,\n\tFragment,\n\tisValidElement,\n\tlazy,\n\ttype PropsWithChildren,\n\ttype ReactElement,\n\ttype ReactNode,\n\tSuspense,\n} from \"react\";\nimport type { PulseSocketIOClient } from \"./client\";\nimport type { PulsePrerenderView } from \"./pulse\";\nimport type { ComponentRegistry, PathDelta, VDOMNode, VDOMUpdate } from \"./vdom\";\nimport { FRAGMENT_TAG, isElementNode, isMountPointNode, MOUNT_POINT_PREFIX } from \"./vdom\";\n\nexport class VDOMRenderer {\n\t#callbacks: Set<string>;\n\t#callbackCache: Map<string, (...args: any) => void>;\n\t#renderPropKeys: Set<string>;\n\t#cssProps: Set<string>;\n\t#callbackList: string[];\n\t#client: PulseSocketIOClient;\n\t#path: string;\n\t#components: ComponentRegistry;\n\t#cssModules: Record<string, Record<string, string>>;\n\n\tconstructor(\n\t\tclient: PulseSocketIOClient,\n\t\tpath: string,\n\t\tcomponents: ComponentRegistry,\n\t\tcssModules: Record<string, Record<string, string>>,\n\t\tinitialCallbacks: string[] = [],\n\t\tinitialRenderProps: string[] = [],\n\t\tinitialCssRefs: string[] = [],\n\t) {\n\t\tthis.#client = client;\n\t\tthis.#path = path;\n\t\tthis.#components = components;\n\t\tthis.#cssModules = cssModules;\n\t\tthis.#callbacks = new Set(initialCallbacks);\n\t\tthis.#callbackCache = new Map();\n\t\tthis.#renderPropKeys = new Set(initialRenderProps);\n\t\tthis.#cssProps = new Set(initialCssRefs);\n\t\tthis.#callbackList = [...this.#callbacks].sort();\n\t}\n\n\t// Accessors used by update logic to determine which props need rebinding\n\thasCallbackPath(path: string) {\n\t\treturn this.#callbacks.has(path);\n\t}\n\n\thasRenderPropPath(path: string) {\n\t\treturn this.#renderPropKeys.has(path);\n\t}\n\n\thasAnyCallbackUnder(prefix: string): boolean {\n\t\tif (prefix === \"\") return this.#callbackList.length > 0;\n\t\tconst i = this.#lowerBound(this.#callbackList, prefix);\n\t\treturn i < this.#callbackList.length && this.#callbackList[i]!.startsWith(prefix);\n\t}\n\n\tapplyCallbackDelta(delta: PathDelta) {\n\t\t// Only update the internal callback path registry and cache. We rely on\n\t\t// accompanying update_props operations that contain the \"$cb\" placeholder\n\t\t// to trigger prop updates; transformValue will resolve to functions.\n\t\tif (delta.remove) {\n\t\t\tfor (const key of delta.remove) {\n\t\t\t\tthis.#callbacks.delete(key);\n\t\t\t\tthis.#callbackCache.delete(key);\n\t\t\t}\n\t\t}\n\t\tif (delta.add) {\n\t\t\tfor (const key of delta.add) {\n\t\t\t\tthis.#callbacks.add(key);\n\t\t\t}\n\t\t}\n\t\tthis.#callbackList = [...this.#callbacks].sort();\n\t}\n\n\tapplyRenderPropsDelta(delta: PathDelta) {\n\t\tif (delta.remove) {\n\t\t\tfor (const key of delta.remove) {\n\t\t\t\tthis.#renderPropKeys.delete(key);\n\t\t\t}\n\t\t}\n\t\tif (delta.add) {\n\t\t\tfor (const key of delta.add) {\n\t\t\t\tthis.#renderPropKeys.add(key);\n\t\t\t}\n\t\t}\n\t}\n\n\tapplyCssRefsDelta(delta: PathDelta) {\n\t\tif (delta.remove) {\n\t\t\tfor (const prop of delta.remove) {\n\t\t\t\tthis.#cssProps.delete(prop);\n\t\t\t}\n\t\t}\n\t\tif (delta.add) {\n\t\t\tfor (const prop of delta.add) {\n\t\t\t\tthis.#cssProps.add(prop);\n\t\t\t}\n\t\t}\n\t}\n\n\tgetCallback(path: string, prop: string) {\n\t\tconst key = this.#propPath(path, prop);\n\t\tlet fn = this.#callbackCache.get(key);\n\t\tif (!fn) {\n\t\t\tfn = (...args: any[]) => this.#client.invokeCallback(this.#path, key, args);\n\t\t\tthis.#callbackCache.set(key, fn);\n\t\t}\n\t\treturn fn;\n\t}\n\n\trenderNode(node: VDOMNode, currentPath = \"\"): ReactNode {\n\t\t// Handle primitives early\n\t\tif (\n\t\t\tnode == null || // catches both null and undefined\n\t\t\ttypeof node === \"boolean\" ||\n\t\t\ttypeof node === \"number\" ||\n\t\t\ttypeof node === \"string\"\n\t\t) {\n\t\t\treturn node;\n\t\t}\n\n\t\t// Element nodes\n\t\tif (isElementNode(node)) {\n\t\t\tconst { tag, props = {}, children = [] } = node;\n\n\t\t\tconst newProps: Record<string, any> = {};\n\t\t\tfor (const [propName, propValue] of Object.entries(props)) {\n\t\t\t\tnewProps[propName] = this.transformValue(currentPath, propName, propValue);\n\t\t\t}\n\n\t\t\tif (node.key) {\n\t\t\t\tnewProps.key = node.key;\n\t\t\t}\n\n\t\t\tconst renderedChildren = [];\n\t\t\tfor (let index = 0; index < children.length; index += 1) {\n\t\t\t\tconst child = children[index]!;\n\t\t\t\tconst childPath = currentPath ? `${currentPath}.${index}` : String(index);\n\t\t\t\trenderedChildren.push(this.renderNode(child, childPath));\n\t\t\t}\n\n\t\t\tif (isMountPointNode(node)) {\n\t\t\t\tconst componentKey = node.tag.slice(MOUNT_POINT_PREFIX.length);\n\t\t\t\tconst Component = this.#components[componentKey]!;\n\t\t\t\tif (!Component) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Could not find component ${componentKey}. This is a Pulse internal error.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn createElement(Component, newProps, ...renderedChildren);\n\t\t\t}\n\n\t\t\treturn createElement(tag === FRAGMENT_TAG ? Fragment : tag, newProps, ...renderedChildren);\n\t\t}\n\n\t\t// Fallback for unknown node types\n\t\tif (process.env.NODE_ENV !== \"production\") {\n\t\t\tconsole.error(\"Unknown VDOM node type:\", node);\n\t\t}\n\t\treturn null;\n\t}\n\n\t#propPath(path: string, prop: string) {\n\t\treturn path ? `${path}.${prop}` : prop;\n\t}\n\n\ttransformValue(path: string, key: string, value: any) {\n\t\tconst propPath = this.#propPath(path, key);\n\t\tif (this.#callbacks.has(propPath)) {\n\t\t\treturn this.getCallback(path, key);\n\t\t}\n\t\tif (this.#renderPropKeys.has(propPath)) {\n\t\t\treturn this.renderNode(value, propPath);\n\t\t}\n\t\tif (this.#cssProps.has(propPath)) {\n\t\t\treturn this.#resolveCssToken(value);\n\t\t}\n\t\treturn value;\n\t}\n\n\t#resolveCssToken(token: string): string {\n\t\tconst idx = token.indexOf(\":\");\n\t\tif (idx === -1) {\n\t\t\treturn token;\n\t\t}\n\t\tconst moduleId = token.slice(0, idx);\n\t\tconst className = token.slice(idx + 1);\n\t\tif (!moduleId || !className) {\n\t\t\treturn token;\n\t\t}\n\t\tconst mod = this.#cssModules[moduleId];\n\t\tif (!mod) {\n\t\t\tthrow new Error(`Received CSS reference for unknown module '${moduleId}'`);\n\t\t}\n\t\tconst resolved = mod[className];\n\t\tif (typeof resolved !== \"string\") {\n\t\t\tthrow new Error(\n\t\t\t\t`Received CSS reference for missing class '${className}' in module '${moduleId}'`,\n\t\t\t);\n\t\t}\n\t\treturn resolved;\n\t}\n\n\tinit(view: PulsePrerenderView): ReactNode {\n\t\t// Set callbacks\n\t\tthis.#callbacks = new Set(view.callbacks);\n\t\t// prune stale cached callbacks\n\t\tfor (const k of Array.from(this.#callbackCache.keys())) {\n\t\t\tif (!this.#callbacks.has(k)) this.#callbackCache.delete(k);\n\t\t}\n\t\tthis.#callbackList = [...this.#callbacks].sort();\n\n\t\t// Set render props\n\t\tthis.#renderPropKeys = new Set(view.render_props);\n\n\t\t// Set CSS refs\n\t\tthis.#cssProps = new Set(view.css_refs);\n\n\t\treturn this.renderNode(view.vdom);\n\t}\n\n\t#ensureChildrenArray(el: ReactElement): ReactNode[] {\n\t\tconst children = (el.props as any)?.children as ReactNode | undefined;\n\t\tif (children == null) return [];\n\t\treturn Array.isArray(children) ? children.slice() : [children];\n\t}\n\n\tapplyUpdates(initialTree: ReactNode, updates: VDOMUpdate[]): ReactNode {\n\t\tlet newTree: ReactNode = initialTree;\n\t\tfor (const update of updates) {\n\t\t\tif (update.type === \"update_callbacks\") {\n\t\t\t\tthis.applyCallbackDelta(update.data);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (update.type === \"update_css_refs\") {\n\t\t\t\tthis.applyCssRefsDelta(update.data);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (update.type === \"update_render_props\") {\n\t\t\t\tthis.applyRenderPropsDelta(update.data);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst parts = update.path.split(\".\").filter((s) => s.length > 0);\n\n\t\t\tconst descend = (node: ReactNode, depth: number, path: string): ReactNode => {\n\t\t\t\tif (depth < parts.length) {\n\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\tconst element = node as ReactElement<Record<string, any> | null>;\n\t\t\t\t\tconst childKey = parts[depth]!;\n\t\t\t\t\tconst childIdx = +childKey;\n\t\t\t\t\tconst childPath = path ? `${path}.${childKey}` : childKey;\n\t\t\t\t\tif (!Number.isNaN(childIdx)) {\n\t\t\t\t\t\t// Regular child traversal\n\t\t\t\t\t\tconst childrenArr = this.#ensureChildrenArray(element);\n\t\t\t\t\t\tconst child = childrenArr[childIdx];\n\t\t\t\t\t\tchildrenArr[childIdx] = descend(child, depth + 1, childPath) as any;\n\t\t\t\t\t\treturn cloneElement(element, undefined, ...childrenArr);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Render prop traversal\n\t\t\t\t\t\tconst baseProps = (element.props ?? {}) as Record<string, any>;\n\t\t\t\t\t\tconst child = baseProps[childKey];\n\t\t\t\t\t\tconst props = {\n\t\t\t\t\t\t\t...baseProps,\n\t\t\t\t\t\t\t[childKey]: descend(child, depth + 1, childPath),\n\t\t\t\t\t\t};\n\t\t\t\t\t\treturn cloneElement(element, props);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tswitch (update.type) {\n\t\t\t\t\tcase \"replace\": {\n\t\t\t\t\t\treturn this.renderNode(update.data, update.path);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"update_props\": {\n\t\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\t\tconst element = node as ReactElement;\n\t\t\t\t\t\tconst currentProps = (element.props ?? {}) as Record<string, any>;\n\t\t\t\t\t\tconst nextProps: Record<string, any> = { ...currentProps };\n\t\t\t\t\t\tconst delta = update.data;\n\t\t\t\t\t\tif (delta.remove && delta.remove.length > 0) {\n\t\t\t\t\t\t\tfor (const key of delta.remove) {\n\t\t\t\t\t\t\t\tif (key in nextProps) {\n\t\t\t\t\t\t\t\t\tdelete nextProps[key];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (delta.set) {\n\t\t\t\t\t\t\tfor (const [k, v] of Object.entries(delta.set)) {\n\t\t\t\t\t\t\t\tnextProps[k] = this.transformValue(path, k, v);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If some props were removed, use `createElement` to fully override\n\t\t\t\t\t\t// the props, as `cloneElement` shallowly merges the new props with\n\t\t\t\t\t\t// the old ones.\n\t\t\t\t\t\tconst removedSomething = (delta.remove?.length ?? 0) > 0;\n\t\t\t\t\t\tif (removedSomething) {\n\t\t\t\t\t\t\t// Preserve key + ref\n\t\t\t\t\t\t\tnextProps.key = element.key;\n\t\t\t\t\t\t\tnextProps.ref = (element as any).ref;\n\t\t\t\t\t\t\treturn createElement(element.type, nextProps, ...this.#ensureChildrenArray(element));\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Don't touch children. Key and ref are transferred by cloneElement.\n\t\t\t\t\t\t\treturn cloneElement(element, nextProps);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase \"reconciliation\": {\n\t\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\t\tconst element = node as ReactElement;\n\t\t\t\t\t\tconst prevChildren = this.#ensureChildrenArray(element);\n\t\t\t\t\t\tconst nextChildren = [];\n\n\t\t\t\t\t\tconst [newIndices, newContents] = update.new;\n\t\t\t\t\t\tconst [reuseIndices, reuseSources] = update.reuse;\n\n\t\t\t\t\t\tlet nextNew = -1,\n\t\t\t\t\t\t\tnextReuse = -1,\n\t\t\t\t\t\t\tnewIdx = -1,\n\t\t\t\t\t\t\treuseIdx = -1;\n\t\t\t\t\t\tif (newIndices.length > 0) {\n\t\t\t\t\t\t\tnextNew = newIndices[0];\n\t\t\t\t\t\t\tnewIdx = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (reuseIndices.length > 0) {\n\t\t\t\t\t\t\tnextReuse = reuseIndices[0];\n\t\t\t\t\t\t\treuseIdx = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (let i = 0; i < update.N; ++i) {\n\t\t\t\t\t\t\tif (i === nextNew) {\n\t\t\t\t\t\t\t\tconst contents = newContents[newIdx];\n\t\t\t\t\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\t\t\t\t\tnextChildren.push(this.renderNode(contents, childPath));\n\t\t\t\t\t\t\t\tnextNew = newIdx < newIndices.length - 1 ? newIndices[++newIdx] : -1;\n\t\t\t\t\t\t\t} else if (i === nextReuse) {\n\t\t\t\t\t\t\t\tconst srcIdx = reuseSources[reuseIdx];\n\t\t\t\t\t\t\t\tlet src = prevChildren[srcIdx];\n\t\t\t\t\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\t\t\t\t\t// The node may have callbacks that need to be updated for this new path\n\t\t\t\t\t\t\t\tif (this.hasAnyCallbackUnder(childPath)) {\n\t\t\t\t\t\t\t\t\tsrc = this.#rebindCallbacksInSubtree(src, childPath);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tnextChildren.push(src);\n\t\t\t\t\t\t\t\tnextReuse = reuseIdx < reuseIndices.length - 1 ? reuseIndices[++reuseIdx] : -1;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// No need to rebind callbacks, the node hasn't moved\n\t\t\t\t\t\t\t\tnextChildren.push(prevChildren[i]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Pass null to reuse previous props\n\t\t\t\t\t\treturn cloneElement(element, null!, ...nextChildren);\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`[Pulse renderer] Unknown update type: ${(update as any)?.type}`);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tnewTree = descend(newTree, 0, \"\");\n\t\t}\n\t\treturn newTree;\n\t}\n\n\t#assertIsElement(node: ReactNode, parts: string[], depth: number): node is ReactElement {\n\t\tif (process.env.NODE_ENV !== \"production\" && !isValidElement(node)) {\n\t\t\tconsole.error(\"Invalid node:\", node);\n\t\t\tthrow new Error(`Invalid node at path ${parts.slice(0, depth).join(\".\")}`);\n\t\t}\n\t\treturn true;\n\t}\n\n\t// Rebind callback function props within a subtree after a path-changing move\n\t#rebindCallbacksInSubtree(node: ReactNode, path: string): ReactNode {\n\t\tif (!isValidElement(node)) return node;\n\t\tconst element = node as ReactElement<Record<string, any> | null>;\n\t\tconst baseProps = (element.props ?? {}) as Record<string, any>;\n\t\tconst nextProps: Record<string, any> = { ...baseProps };\n\n\t\t// Rebind only callback props; CSS refs are path-agnostic and render-props\n\t\t// are handled by the server-side renderer via explicit updates\n\t\tfor (const key of Object.keys(baseProps)) {\n\t\t\tconst propPath = path ? `${path}.${key}` : key;\n\t\t\tif (this.hasCallbackPath(propPath)) {\n\t\t\t\tnextProps[key] = this.getCallback(path, key);\n\t\t\t}\n\t\t\tif (this.hasRenderPropPath(propPath) && this.hasAnyCallbackUnder(propPath)) {\n\t\t\t\tnextProps[key] = this.#rebindCallbacksInSubtree(baseProps[key], propPath);\n\t\t\t}\n\t\t}\n\n\t\tconst children = this.#ensureChildrenArray(element).map((child, idx) => {\n\t\t\tconst childPath = path ? `${path}.${idx}` : String(idx);\n\t\t\tif (this.hasAnyCallbackUnder(childPath)) {\n\t\t\t\treturn this.#rebindCallbacksInSubtree(child, childPath);\n\t\t\t} else {\n\t\t\t\treturn child;\n\t\t\t}\n\t\t});\n\n\t\treturn cloneElement(element, nextProps, ...children);\n\t}\n\n\t// Binary-search lower bound for prefix matching on sorted callback paths\n\t#lowerBound(arr: string[], target: string): number {\n\t\tlet lo = 0;\n\t\tlet hi = arr.length;\n\t\twhile (lo < hi) {\n\t\t\tconst mid = (lo + hi) >>> 1;\n\t\t\tif (arr[mid]! < target) {\n\t\t\t\tlo = mid + 1;\n\t\t\t} else {\n\t\t\t\thi = mid;\n\t\t\t}\n\t\t}\n\t\treturn lo;\n\t}\n}\n\n// The `component` prop should be something like `() =>\n// import('~/path/to/component') (we'll need to remap if we're importing a named export and not the default)\nexport function RenderLazy(\n\tcomponent: () => Promise<{ default: ComponentType<any> }>,\n\tfallback?: ReactNode,\n): FC<PropsWithChildren<unknown>> {\n\tconst Component = lazy(component);\n\treturn ({ children, ...props }: PropsWithChildren<unknown>) => {\n\t\treturn (\n\t\t\t<Suspense fallback={fallback}>\n\t\t\t\t<Component {...props}>{children}</Component>\n\t\t\t</Suspense>\n\t\t);\n\t};\n}\n","import {\n\tcreateContext,\n\ttype ReactNode,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { useLocation, useNavigate, useParams } from \"react-router\";\nimport { type Directives, PulseSocketIOClient } from \"./client\";\nimport type { RouteInfo } from \"./helpers\";\nimport type { ServerErrorInfo } from \"./messages\";\nimport { VDOMRenderer } from \"./renderer\";\nimport type { ComponentRegistry, VDOM } from \"./vdom\";\n\n// =================================================================\n// Types\n// =================================================================\n\nexport interface PulseConfig {\n\tserverAddress: string;\n}\n\nexport type PulsePrerenderView = {\n\tvdom: VDOM;\n\tcallbacks: string[];\n\trender_props: string[];\n\tcss_refs: string[];\n};\n\nexport type PulsePrerender = {\n\tviews: Record<string, PulsePrerenderView>;\n\tdirectives: Directives;\n};\n// =================================================================\n// Context and Hooks\n// =================================================================\n\n// Context for the client, provided by PulseProvider\nconst PulseClientContext = createContext<PulseSocketIOClient | null>(null);\nconst PulsePrerenderContext = createContext<PulsePrerender | null>(null);\n\nexport const usePulseClient = () => {\n\tconst client = useContext(PulseClientContext);\n\tif (!client) {\n\t\tthrow new Error(\"usePulseClient must be used within a PulseProvider\");\n\t}\n\treturn client;\n};\n\nexport const usePulsePrerender = (path: string) => {\n\tconst ctx = useContext(PulsePrerenderContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"usePulsePrerender must be used within a PulseProvider\");\n\t}\n\tconst view = ctx.views[path];\n\tif (!view) {\n\t\tthrow new Error(`No prerender found for '${path}'`);\n\t}\n\treturn view;\n};\n\n// =================================================================\n// Provider\n// =================================================================\n\nexport interface PulseProviderProps {\n\tchildren: ReactNode;\n\tconfig: PulseConfig;\n\tprerender: PulsePrerender;\n}\n\nconst inBrowser = typeof window !== \"undefined\";\n\nexport function PulseProvider({ children, config, prerender }: PulseProviderProps) {\n\tconst [connected, setConnected] = useState(true);\n\tconst rrNavigate = useNavigate();\n\tconst { directives } = prerender;\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: another useEffect syncs the directives without recreating the client\n\tconst client = useMemo(() => {\n\t\treturn new PulseSocketIOClient(config.serverAddress, directives, rrNavigate);\n\t}, [config.serverAddress, rrNavigate]);\n\tuseEffect(() => client.setDirectives(directives), [client, directives]);\n\tuseEffect(() => client.onConnectionChange(setConnected), [client]);\n\tuseEffect(() => {\n\t\tif (inBrowser) {\n\t\t\tclient.connect();\n\t\t\treturn () => client.disconnect();\n\t\t}\n\t}, [client]);\n\n\treturn (\n\t\t<PulseClientContext.Provider value={client}>\n\t\t\t<PulsePrerenderContext.Provider value={prerender}>\n\t\t\t\t{!connected && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tposition: \"fixed\",\n\t\t\t\t\t\t\tbottom: \"20px\",\n\t\t\t\t\t\t\tright: \"20px\",\n\t\t\t\t\t\t\tbackgroundColor: \"red\",\n\t\t\t\t\t\t\tcolor: \"white\",\n\t\t\t\t\t\t\tpadding: \"10px\",\n\t\t\t\t\t\t\tborderRadius: \"5px\",\n\t\t\t\t\t\t\tzIndex: 1000,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tFailed to connect to the server.\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{children}\n\t\t\t</PulsePrerenderContext.Provider>\n\t\t</PulseClientContext.Provider>\n\t);\n}\n\n// =================================================================\n// View\n// =================================================================\n\nexport interface PulseViewProps {\n\texternalComponents: ComponentRegistry;\n\tpath: string;\n\tcssModules: Record<string, Record<string, string>>;\n}\n\nexport function PulseView({ externalComponents, path, cssModules }: PulseViewProps) {\n\tconst client = usePulseClient();\n\tconst initialView = usePulsePrerender(path);\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: We only want to lose the renderer on unmount. initialView will change on every navigation with our current setup, so we hack around it with another useEffect below. This is not ideal and will be fixed in the future.\n\tconst renderer = useMemo(\n\t\t() =>\n\t\t\tnew VDOMRenderer(\n\t\t\t\tclient,\n\t\t\t\tpath,\n\t\t\t\texternalComponents,\n\t\t\t\tcssModules,\n\t\t\t\tinitialView.callbacks,\n\t\t\t\tinitialView.render_props,\n\t\t\t\tinitialView.css_refs,\n\t\t\t),\n\t\t[client, path, externalComponents, cssModules],\n\t);\n\tconst [tree, setTree] = useState<ReactNode>(() => renderer.init(initialView));\n\tconst [serverError, setServerError] = useState<ServerErrorInfo | null>(null);\n\n\tconst location = useLocation();\n\tconst params = useParams();\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: using hacky deep equality for params\n\tconst routeInfo = useMemo(() => {\n\t\tconst { \"*\": catchall = \"\", ...pathParams } = params;\n\t\tconst queryParams = new URLSearchParams(location.search);\n\t\treturn {\n\t\t\thash: location.hash,\n\t\t\tpathname: location.pathname,\n\t\t\tquery: location.search,\n\t\t\tqueryParams: Object.fromEntries(queryParams.entries()),\n\t\t\tpathParams,\n\t\t\tcatchall: catchall.length > 0 ? catchall.split(\"/\") : [],\n\t\t} satisfies RouteInfo;\n\t}, [location.hash, location.pathname, location.search, JSON.stringify(params)]);\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: We don't want to unmount on navigation, so another useEffect sync the routeInfo on navigation.\n\tuseEffect(() => {\n\t\tif (inBrowser) {\n\t\t\tclient.mountView(path, {\n\t\t\t\trouteInfo,\n\t\t\t\tonInit: (view) => {\n\t\t\t\t\tsetTree(renderer.init(view));\n\t\t\t\t},\n\t\t\t\tonUpdate: (ops) => {\n\t\t\t\t\tsetTree((prev) => (prev == null ? prev : renderer.applyUpdates(prev, ops)));\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst offErr = client.onServerError((p, err) => {\n\t\t\t\tif (p === path) setServerError(err);\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\toffErr();\n\t\t\t\tclient.unmount(path);\n\t\t\t};\n\t\t}\n\t\t// routeInfo is NOT included here on purpose\n\t}, [client, renderer, path]);\n\n\tuseEffect(() => {\n\t\tif (inBrowser) {\n\t\t\tclient.navigate(path, routeInfo);\n\t\t}\n\t}, [client, path, routeInfo]);\n\t// Hack for our current prerendering setup on client-side navigation. Will be improved soon\n\tconst hasRendered = useRef(false);\n\tuseEffect(() => {\n\t\t// First rendering pass, no need to update the tree\n\t\tif (!hasRendered.current) {\n\t\t\thasRendered.current = true;\n\t\t}\n\t\t// 2nd+ rendering pass. Happens when a route stays mounted on navigation.\n\t\telse {\n\t\t\tsetTree(renderer.init(initialView));\n\t\t}\n\t\treturn () => {\n\t\t\thasRendered.current = false;\n\t\t};\n\t}, [initialView, renderer]);\n\n\tif (serverError) {\n\t\treturn <ServerError error={serverError} />;\n\t}\n\n\treturn tree;\n}\n\nfunction ServerError({ error }: { error: ServerErrorInfo }) {\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tpadding: 16,\n\t\t\t\tborder: \"1px solid #e00\",\n\t\t\t\tbackground: \"#fff5f5\",\n\t\t\t\tcolor: \"#900\",\n\t\t\t\tfontFamily:\n\t\t\t\t\t'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n\t\t\t\twhiteSpace: \"pre-wrap\",\n\t\t\t}}\n\t\t>\n\t\t\t<div style={{ fontWeight: 700, marginBottom: 8 }}>Server Error during {error.phase}</div>\n\t\t\t{error.message && <div>{error.message}</div>}\n\t\t\t{error.stack && (\n\t\t\t\t<details open style={{ marginTop: 8 }}>\n\t\t\t\t\t<summary>Stack trace</summary>\n\t\t\t\t\t<pre style={{ margin: 0 }}>{error.stack}</pre>\n\t\t\t\t</details>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { useEffect, useMemo } from \"react\";\nimport type { ChannelBridge } from \"./channel\";\nimport { usePulseClient } from \"./pulse\";\n\nexport function usePulseChannel(channelId: string): ChannelBridge {\n\tconst client = usePulseClient();\n\tconst bridge = useMemo(() => {\n\t\tif (!channelId) {\n\t\t\tthrow new Error(\"usePulseChannel requires a non-empty channelId\");\n\t\t}\n\t\treturn client.acquireChannel(channelId);\n\t}, [client, channelId]);\n\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tclient.releaseChannel(channelId);\n\t\t};\n\t}, [client, channelId]);\n\n\treturn bridge;\n}\n"],"mappings":"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OACA,WACA,OACA,iBACA,OACA,CACoE,CAuB/D,GAAgB,EArBC,CACtB,MACA,SACA,WACA,OACA,OACA,WACA,OACA,SACA,WACA,WACA,OACA,WACA,MACA,SACA,QACA,SACA,WACA,OACA,iBACA,CAC8D,CAwBzD,EAAiB,EAtBC,CACvB,WACA,WACA,cACA,aACA,cACA,eACA,sBACA,WACA,QACA,OACA,QACA,eACA,SACA,eACA,UACA,aACA,UACA,MACA,SACA,iBACA,CACiE,CAE5D,GAAkB,GAA0B,EAAe,EAAI,CAc/D,GAAkB,EAZC,CACxB,WACA,OACA,OACA,QACA,aACA,cACA,aACA,iBACA,aACA,sBACA,CACoE,CAG/D,GAAgB,EADC,CAAC,QAAQ,CAC+B,CAUzD,GAAiB,EARC,CACvB,SACA,MACA,OACA,QACA,QACA,OACA,CACiE,CAS5D,GAAoB,EAPC,CAC1B,WACA,OACA,OACA,oBACA,eACA,CAC0E,CAerEC,GAAgB,EAbC,CACtB,gBACA,SACA,eACA,WACA,UACA,SACA,SACA,OACA,aACA,SACA,MACA,CAC8D,CAmBzD,GAAkB,EAjBC,CACxB,QACA,kBACA,SACA,OACA,iBACA,MACA,SACA,QACA,QACA,cACA,WACA,eACA,cACA,YACA,UACA,CACoE,CA6B/D,GAAiB,EA3BC,CACvB,MACA,cACA,WACA,SACA,QACA,UACA,gBACA,eACA,iBACA,QACA,MACA,SACA,SACA,QACA,QACA,SACA,WACA,SACA,WACA,SACA,OACA,SACA,IACA,IACA,gBACA,CACiE,CA6C5D,GAAiB,EA3CC,8ZA0CvB,CACiE,CAG5D,GAAiB,EADC,CAAC,UAAU,CAC+B,CAG5D,GAAc,EADC,CAAC,QAAS,OAAO,CACmB,CAqBnD,GAAgB,EAnBC,CACtB,KACA,cACA,WACA,gBACA,OACA,WACA,aACA,cACA,YACA,QACA,iBACA,MACA,OACA,UACA,MACA,SACA,QACA,CAC8D,CAGzD,GAAe,EADC,CAAC,OAAO,CAC8B,CAUtD,GAAiB,EARC,CACvB,OACA,MACA,MACA,MACA,UACA,QACA,CACiE,CAG5D,EAAe,EADC,CAAC,OAAQ,WAAW,CACkB,CAQtD,GAAiB,EANF,CACpB,WACA,QACA,OACA,UACA,CAC8D,CAsBzD,GAAkB,EApBC,CACxB,OACA,SACA,OACA,OACA,SACA,QACA,oBACA,eACA,QACA,UACA,SACA,OACA,WACA,WACA,UACA,SACA,UACA,SACA,CACoE,CAM/D,GAAoB,EAJC,CAC1B,WACA,QACA,CAC0E,CAWrE,GAAkB,EATC,CACxB,kBACA,WACA,QACA,QACA,WACA,OACA,QACA,CACoE,CAW/D,GAAkB,EATC,CACxB,eACA,OACA,OACA,QACA,UACA,oBACA,eACA,CACoE,CAO/D,GAAoB,EALC,CAC1B,MACA,WACA,QACA,CAC0E,CAGrE,EAAiB,EADC,CAAC,OAAO,CACkC,CAE5D,GAAiB,GAAqB,EAAuB,EAAI,CAejE,GAAwB,GAAoC,CAbzC,CACxB,QACA,cACA,QACA,gBACA,YACA,WACA,iBACA,MACA,OACA,OACA,UACA,CACoF,CACpF,MAAQ,GAAO,EAAU,MACzB,QAAU,GAAO,EAAU,QAC3B,CAAC,CACI,GAAmB,IAA4B,CACpD,GAAG,EAAuB,EAAI,CAC9B,GAAG,GAAsB,EAAI,CAC7B,EAgBK,GAAkB,EAdC,CACxB,eACA,WACA,SACA,WACA,OACA,WACA,gBACA,OACA,OACA,QACA,oBACA,eACA,CACoE,CAG/D,GAAgB,EADC,CAAC,OAAO,CACgC,CAWzD,GAAkB,EATC,CACxB,SACA,QACA,QACA,MACA,SACA,OACA,QACA,CACoE,CAK/D,GAAwB,EAHE,CAC/B,QACA,CACuF,CAmBlF,EAAqB,EAjBE,CAC5B,OACA,YACA,UACA,UACA,UACA,QACA,QACA,OACA,UACA,KACA,QACA,SACA,SACA,SACA,QACA,CAC8E,CAUzE,EAAoB,EARE,CAC3B,OACA,QACA,KACA,QACA,SACA,QACA,CAC2E,CAatE,GAAiB,EAXC,CACvB,QACA,UACA,SACA,cACA,cACA,QACA,QACA,UACA,QACA,CACiE,CAW5D,GAAoB,EATL,CACpB,WACA,kBACA,QACA,UACA,KACA,QACA,SACA,CACoE,CAQ/D,EAAwB,EANH,CAC1B,QACA,KACA,QACA,SACA,CACkF,CAE7E,GAAqB,GAA6B,EAAuB,EAAI,CAwB7E,GAAoB,EAtBC,CAC1B,eACA,OACA,eACA,UACA,WACA,YACA,YACA,OACA,cACA,WACA,WACA,OACA,qBACA,eACA,iBACA,QACA,OACA,aACA,oBACA,eACA,CAC0E,CAGrE,GAAgB,EADC,CAAC,WAAW,CAC4B,CAUzD,GAAiB,EARC,CACvB,UACA,OACA,QACA,aACA,MACA,UACA,CACiE,CAU5D,GAAuB,GAAmC,CARxC,CACvB,SACA,SACA,cACA,aACA,QACA,cACA,CACgF,CAC3E,GAAkB,IAA2B,CAClD,GAAG,EAAe,EAAI,CACtB,GAAG,GAAqB,EAAI,CAC5B,EAGK,GAAc,EADC,CAAC,QAAQ,CAC2B,CAGnD,GAAgB,EADC,CAAC,OAAQ,SAAS,CACsB,CAUzD,GAAgB,EARC,CACtB,QACA,aACA,UACA,OACA,OACA,QACA,CAC8D,CAGzD,GAAiB,EADC,CAAC,UAAU,CAC+B,CAG5D,GAAmB,EADC,CAAC,OAAO,CACsC,CAMlE,GAAkB,EAJC,CACxB,OACA,cACA,CACoE,CAG/D,GAAe,EADC,CAAC,QAAQ,CAC6B,CAEtD,GAAiB,GAAyB,EAAuB,EAAI,CAGrE,EAAmB,EADC,CAAC,QAAQ,CACqC,CASlE,GAAc,EAPC,CACpB,QACA,QACA,UACA,OACA,QACA,CACwD,CAGnD,GAAgB,EADC,CAAC,UAAU,CAC6B,CAEzD,GAAiB,GAAyB,EAAuB,EAAI,CAQrE,GAAgB,EANC,CACtB,UACA,YACA,OACA,SACA,CAC8D,CAGzD,GAAqB,EADP,CAAC,QAAQ,CACyC,CAEhE,GAAoB,GAA4B,EAAuB,EAAI,CAG3E,GAAe,EADC,CAAC,QAAQ,CAC6B,CAEtD,GAAiB,GAAyB,EAAuB,EAAI,CAOrE,GAAiB,EALC,CACvB,QACA,OACA,WACA,CACiE,CAG5D,GAAiB,EADC,CAAC,OAAO,CACkC,CAG5D,GAAiB,EADF,CAAC,UAAW,OAAO,CACuB,CAG/D,SAAS,EAAsB,EAAiB,CAC/C,MAAO,CACN,GAAG,EAAmB,EAAI,CAC1B,GAAG,EAAwB,EAAwB,CACnD,CAIF,SAAS,EACR,EACA,EACC,CACD,IAAM,EAAO,GAAoB,CAAC,EAAM,EAAgB,CACxD,MAAQ,KAAY,CAAE,GAAG,EAAsB,EAAI,CAAE,GAAG,EAAK,EAAI,CAAE,EAsJpE,MAAMC,EAA0D,CAC/D,EAAG,GACH,KAAM,GACN,MAAO,GACP,KAAM,GACN,WAAY,EACZ,EAAG,EACH,KAAM,GACN,GAAI,GACJ,OAAQ,GACR,OAAQ,EACR,QAAS,GACT,KAAM,GACN,IAAK,EACL,SAAU,EACV,KAAM,GACN,QAAS,GACT,OAAQ,GACR,IAAK,GACL,GAAI,GACJ,MAAO,GACP,SAAU,GACV,KAAMD,GACN,GAAI,EACJ,GAAI,EACJ,GAAI,EACJ,GAAI,EACJ,GAAI,EACJ,GAAI,EACJ,KAAM,GACN,GAAI,GACJ,KAAM,GACN,OAAQ,GACR,IAAK,GACL,MAAO,GACP,MAAO,GACP,GAAI,GACJ,KAAM,GACN,IAAK,GACL,KAAM,GACN,KAAM,GACN,MAAO,GACP,IAAK,EACL,IAAK,EACL,OAAQ,GACR,GAAI,GACJ,SAAU,GACV,OAAQ,GACR,OAAQ,GACR,EAAG,GACH,QAAS,GACT,IAAK,GACL,SAAU,GACV,OAAQ,GACR,OAAQ,GACR,KAAM,GACN,OAAQ,GACR,KAAM,GACN,MAAO,GACP,MAAO,GACP,MAAO,EACP,MAAO,EACP,MAAO,EACP,GAAI,EACJ,GAAI,EACJ,SAAU,GACV,SAAU,GACV,KAAM,GACN,MAAO,GACP,GAAI,GACJ,MAAO,GACP,GAAI,GACJ,MAAO,GAEP,IArNoB,EARA,CACpB,IACA,IACA,QACA,SACA,eACA,mBACA,CAC4D,CAsN5D,OAnNuB,EADA,CAAC,KAAM,KAAM,IAAI,CAC6B,CAoNrE,QA5MwB,EANA,CACxB,KACA,KACA,KACA,KACA,CACwE,CA6MxE,KA1MqB,EADA,CAAC,KAAM,KAAM,KAAM,KAAK,CACkB,CA2M/D,KAxMqB,EADA,CAAC,aAAa,CAC4B,CAyM/D,KA/LqB,EARA,CACrB,IACA,IACA,QACA,SACA,KACA,KACA,CAC+D,CAgM/D,QA7LwB,EADA,CAAC,SAAS,CACsC,CA8LxE,SA3LyB,EADA,CAAC,SAAS,CACwC,CA4L3E,KAjLqB,EATA,CACrB,IACA,IACA,KACA,KACA,SACA,aACA,eACA,CAC+D,CAkL/D,MAvKsB,EATA,CACtB,IACA,IACA,KACA,KACA,SACA,aACA,eACA,CACkE,CAwKlE,MA7JyB,EATH,CACtB,IACA,IACA,QACA,SACA,OACA,sBACA,cACA,CACqE,CA8JrE,IArJoB,EAPA,CACpB,IACA,IACA,QACA,SACA,OACA,CAC4D,CAsJ5D,KAnJqB,EADA,EAAE,CACwC,CAoJ/D,EAjJkB,EADI,EAAE,CACkC,CAkJ1D,eAvI+B,EATC,CAChC,KACA,KACA,KACA,KACA,gBACA,oBACA,eACA,CAC8F,CAwI9F,eA3H+B,EAXC,CAChC,KACA,KACA,IACA,KACA,KACA,KACA,gBACA,oBACA,eACA,CAC8F,CA4H9F,KAzHqB,EADA,CAAC,SAAS,CACgC,CA0H/D,QA7GwB,EAXA,CACxB,IACA,IACA,QACA,SACA,eACA,sBACA,mBACA,sBACA,OACA,CACwE,CA8GxE,SAzGyB,EAHC,CAC1B,gBACA,CAC4E,CA0G5E,KAhGqB,EARA,CACrB,IACA,IACA,QACA,SACA,YACA,mBACA,CAC+D,CAiG/D,CAED,SAAgB,GAAmB,EAA0B,CAG5D,IAAM,EAAY,EAFF,EAAI,QAAQ,aAAa,EAGzC,GAAI,EACH,OAAO,EAAU,EAAI,CAEtB,MAAU,MAAM,gCAAgC,EAAI,QAAQ,oCAAoC,CAGjG,SAAgB,GAAkB,EAAyB,CAG1D,IAAM,EAAY,EAFF,EAAI,QAAQ,aAAa,EAOzC,OAJI,EACI,EAAU,EAAI,CAGf,EAAsB,EAAI,CAGlC,SAAgB,EAAe,EAAsB,CAQpD,OAPI,aAAe,YACX,GAAmB,EAAI,CAE3B,aAAe,WACX,GAAkB,EAAI,CAGvB,EAAmB,EAAI,CC56B/B,MAAM,GAAa,GAAsC,EAAe,EAAE,OAAkB,CACtF,EAAc,GACnB,EAAE,cAAgB,EAAe,EAAE,cAAyB,CAAG,KAEhE,SAAS,EACR,EACA,EACC,CACD,OAAO,GAAsB,CAC5B,EACA,CACC,OAAQ,GACR,GAAI,GAAY,EAAE,CAClB,CACD,CAGF,MAAM,EAAiB,CACtB,SACA,UACA,aACA,mBACA,aACA,YACA,YACA,OACA,CAEK,EAAU,CAAC,GAAG,EAAgB,SAAS,CAEvC,EAAa,CAClB,GAAG,EACH,SACA,SACA,UACA,UACA,UACA,UACA,UACA,YACA,YACA,QACA,QACA,UACA,UACA,WACA,CAEK,GAAe,CACpB,GAAG,EACH,YACA,WACA,qBACA,QACA,QACA,QACA,QACA,SACA,cACA,YACA,CAEK,GAAqB,EAAc,EAAe,CAElD,GAAc,EAAc,EAAQ,CAEpC,GAAiB,EAAc,EAAY,CAAE,cAAe,EAAY,CAAC,CAEzE,GAAqB,EAAc,EAAgB,CACxD,cAAgB,GAAM,EAAoB,EAAE,cAAc,CAC1D,CAAC,CAEI,GAAuB,EAAc,CAAC,GAAG,EAAgB,OAAO,CAAU,CAE1E,GAAgB,EAAc,EAAY,CAC/C,cAAe,EACf,aAAe,GAAM,EAAoB,EAAE,aAAa,CACxD,CAAC,CAEI,GAAmB,EAAc,GAAc,CACpD,cAAe,EACf,CAAC,CAEI,GAAiB,EAAc,EAAgB,CACpD,cAAe,EACf,CAAC,CAEI,GAAgB,EAAc,EAAe,CAE7C,GAAmB,EAAc,EAAe,CAEhD,GAAkB,EAAc,EAAe,CAE/C,GAAoB,EAAc,CACvC,GAAG,EACH,SACA,UACA,OACA,MACA,SACA,WACA,UACA,SACA,WACA,CAAU,CAEL,GAAiB,EACtB,CACC,GAAG,EACH,SACA,UACA,UACA,WACA,iBACA,gBACA,UACA,CACD,CACC,eAAiB,GAAM,EAAa,EAAE,eAAe,CACrD,cAAgB,GAAM,EAAa,EAAE,cAAc,CACnD,QAAU,GAAM,EAAa,EAAE,QAAQ,CACvC,CACD,CAEK,GAAiB,EACtB,CAAC,GAAG,EAAY,YAAa,SAAU,SAAU,SAAS,CAC1D,CACC,cAAe,EACf,CACD,CAEK,GAAqB,EAAc,CACxC,GAAG,EACH,gBACA,cACA,gBACA,CAAU,CAEL,GAAkB,EAAc,CAAC,GAAG,EAAgB,WAAY,WAAW,CAAU,CAErF,GAAsB,EAAc,CACzC,GAAG,EACH,cACA,eACA,gBACA,CAAU,CAEX,SAAS,EAAa,EAAkB,CACvC,OAAO,MAAM,KAAK,EAAuB,CAAC,IAAK,IAAgB,CAC9D,OAAQ,EAAe,EAAM,OAAkB,CAC/C,WAAY,EAAM,WAClB,QAAS,EAAM,QACf,QAAS,EAAM,QACf,QAAS,EAAM,QACf,QAAS,EAAM,QACf,MAAO,EAAM,MACb,MAAO,EAAM,MACb,EAAE,CAIJ,SAAS,EAAoB,EAAwC,CACpE,GAAI,CAAC,EACJ,OAAO,KAER,IAAM,EAAQ,EAAE,CAChB,GAAI,EAAG,MACN,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,MAAM,OAAQ,IAAK,CACzC,IAAM,EAAO,EAAG,MAAM,GACtB,EAAM,KAAK,CACV,KAAM,EAAK,KACX,KAAM,EAAK,KACX,CAAC,CAGJ,MAAO,CACN,YAAa,EAAG,WAChB,eAAgB,EAAG,cACZ,QACP,MAAO,MAAM,KAAK,EAAG,OAAS,EAAE,CAAC,CACjC,CAGF,MAAME,EAA6D,EAAE,CAErE,SAAS,EAAI,EAA0B,EAA0B,EAAS,CACzE,IAAK,IAAM,KAAK,EAAO,EAAI,GAAK,EAGjC,EACC,EACA,CACC,cACA,cACA,YACA,gBACA,oBACA,qBACA,eACA,eACA,cACA,aACA,CACD,GACA,CAED,EACC,EACA,CACC,QACA,cACA,WACA,YACA,aACA,aACA,YACA,WACA,YACA,UACA,CACD,GACA,CAED,EACC,EACA,CAAC,OAAQ,UAAW,YAAa,WAAY,YAAa,WAAY,YAAa,OAAO,CAC1F,GACA,CAED,EAAI,EAAmB,CAAC,UAAW,WAAY,QAAQ,CAAE,GAAkB,CAC3E,EAAI,EAAmB,CAAC,QAAS,OAAO,CAAE,GAAe,CACzD,EAAI,EAAmB,CAAC,SAAU,QAAQ,CAAE,GAAgB,CAC5D,EAAI,EAAmB,CAAC,UAAU,CAAE,GAAiB,CACrD,EAAI,EAAmB,CAAC,QAAS,SAAS,CAAE,GAAc,CAC1D,EAAI,EAAmB,CAAC,OAAQ,MAAO,QAAQ,CAAE,GAAmB,CACpE,EACC,EACA,CAAC,iBAAkB,mBAAoB,oBAAoB,CAC3D,GACA,CACD,EAAI,EAAmB,CAAC,cAAe,WAAY,YAAa,aAAa,CAAE,GAAe,CAC9F,EAAI,EAAmB,CAAC,SAAS,CAAE,GAAY,CAC/C,EAAI,EAAmB,CAAC,QAAQ,CAAE,GAAe,CACjD,EACC,EACA,CAAC,iBAAkB,eAAgB,qBAAqB,CACxD,GACA,CACD,EAAI,EAAmB,CAAC,gBAAgB,CAAE,GAAoB,CAC9D,EAAI,EAAmB,CAAC,SAAS,CAAE,GAAgB,CAEnD,SAAgB,GAAa,EAAiB,CAG7C,GACC,GACA,OAAO,GAAU,UACjB,gBAAiB,GACjB,OAAO,EAAM,oBAAuB,WACnC,CACD,IAAM,EAAM,EAEZ,GAAI,OAAO,EAAI,MAAS,SACvB,OAAO,EAGR,IAAM,EAAY,EAAkB,EAAI,KAAK,aAAa,EAM1D,OALI,EACI,EAAU,EAAI,CAIf,GAAmB,EAAI,CAI/B,OAAO,ECnRR,SAAgB,EAAU,EAAgC,CACzD,IAAM,EAAO,IAAI,IACXC,EAAiB,EAAE,CACnBC,EAAkB,EAAE,CACpBC,EAAiB,EAAE,CACnBC,EAAiB,EAAE,CAGrB,EAAc,EAElB,SAASC,EAAQ,EAAgC,CAChD,GACC,GAAS,MACT,OAAO,GAAU,UACjB,OAAO,GAAU,UACjB,OAAO,GAAU,UAEjB,OAAO,EAGR,IAAM,EAAM,IACN,EAAU,EAAK,IAAI,EAAM,CAC/B,GAAI,IAAY,IAAA,GAGf,OADA,EAAK,KAAK,EAAI,CACP,EAKR,GAFA,EAAK,IAAI,EAAO,EAAI,CAEhB,aAAiB,KAEpB,OADA,EAAM,KAAK,EAAI,CACR,EAAM,SAAS,CAGvB,GAAI,MAAM,QAAQ,EAAM,CAAE,CACzB,IAAM,EAAS,EAAM,OACf,EAAa,MAAM,EAAO,CAChC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,IAC3B,EAAO,GAAKA,EAAQ,EAAM,GAAG,CAE9B,OAAO,EAGR,GAAI,aAAiB,IAAK,CACzB,EAAK,KAAK,EAAI,CACd,IAAMC,EAA2B,EAAE,CACnC,IAAK,GAAM,CAAC,EAAK,KAAU,EAAM,SAAS,CACzC,EAAI,OAAO,EAAI,EAAID,EAAQ,EAAM,CAElC,OAAO,EAGR,GAAI,aAAiB,IAAK,CACzB,EAAK,KAAK,EAAI,CACd,IAAM,EAAO,EAAM,KACb,EAAa,MAAM,EAAK,CAC1B,EAAI,EACR,IAAK,IAAM,KAAS,EACnB,EAAO,GAAKA,EAAQ,EAAM,CAC1B,GAAK,EAEN,OAAO,EAGR,GAAI,OAAO,GAAU,SAAU,CAC9B,IAAMC,EAA2B,EAAE,CAC7B,EAAO,OAAO,KAAK,EAAM,CAC/B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACrC,IAAM,EAAM,EAAK,GACjB,EAAI,GAAOD,EAAQ,EAAM,GAAK,CAE/B,OAAO,EAGR,MAAU,MAAM,uCAAuC,IAAQ,CAGhE,IAAM,EAAUA,EAAQ,EAAK,CAC7B,MAAO,CAAC,CAAC,EAAM,EAAO,EAAM,EAAK,CAAE,EAAQ,CAO5C,SAAgB,EACf,EACA,EACO,CACP,GAAM,CAAC,CAAC,EAAO,EAAQ,EAAO,GAAQ,GAAQ,EAExC,EAAO,IAAI,IAAI,EAAM,CACrB,EAAQ,IAAI,IAAI,EAAO,CACvB,EAAO,IAAI,IAAI,EAAM,CACrB,EAAO,IAAI,IAAI,EAAM,CAErBE,EAAsB,EAAE,CAE9B,SAAS,EAAY,EAAuB,CAC3C,IAAM,EAAM,EAAQ,OACpB,GAAI,EAAK,IAAI,EAAI,CAIhB,OADA,EAAQ,KAAK,KAAK,CACX,EAAQ,GAGhB,GAAI,EAAM,IAAI,EAAI,CAAE,CACnB,IAAM,EAAK,IAAI,KAAK,EAAgB,CAEpC,OADA,EAAQ,KAAK,EAAG,CACT,EAGR,GACC,GAAS,MACT,OAAO,GAAU,UACjB,OAAO,GAAU,UACjB,OAAO,GAAU,UAKjB,OAHI,GAAS,uBACL,GAAS,IAAA,GAEV,EAGR,GAAI,MAAM,QAAQ,EAAM,CAAE,CACzB,GAAI,EAAK,IAAI,EAAI,CAAE,CAClB,IAAM,EAAS,IAAI,IACnB,EAAQ,KAAK,EAAO,CACpB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IACjC,EAAO,IAAI,EAAY,EAAM,GAAG,CAAC,CAElC,OAAO,EAGR,IAAM,EAAS,EAAM,OACf,EAAU,MAAM,EAAO,CAC7B,EAAQ,KAAK,EAAI,CACjB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,IAC3B,EAAI,GAAK,EAAY,EAAM,GAAG,CAE/B,OAAO,EAGR,GAAI,OAAO,GAAU,SAAU,CAC9B,GAAI,EAAK,IAAI,EAAI,CAAE,CAClB,IAAMC,EAAS,IAAI,IACnB,EAAQ,KAAKA,EAAO,CACpB,IAAMC,EAAO,OAAO,KAAK,EAAM,CAC/B,IAAK,IAAI,EAAI,EAAG,EAAIA,EAAK,OAAQ,IAAK,CACrC,IAAM,EAAMA,EAAK,GACjB,EAAO,IAAI,EAAK,EAAY,EAAM,GAAK,CAAC,CAEzC,OAAOD,EAGR,IAAME,EAA8B,EAAE,CACtC,EAAQ,KAAK,EAAO,CACpB,IAAM,EAAO,OAAO,KAAK,EAAM,CAC/B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACrC,IAAM,EAAM,EAAK,GACjB,EAAO,GAAO,EAAY,EAAM,GAAK,CAEtC,OAAO,EAGR,MAAU,MAAM,yCAAyC,IAAQ,CAGlE,OAAO,EAAY,EAAK,CCjIzB,IAAa,EAAb,KAAiC,CAChC,aACA,QAAyB,KACzB,cACA,qBAAsD,IAAI,IAC1D,cAA8C,IAAI,IAClD,sBAAkD,IAAI,IACtD,UAAsE,IAAI,IAC1E,KACA,mBACA,YAEA,YAAY,EAAa,EAAwB,EAAqC,CAQrF,GAPA,MAAA,IAAY,EACZ,MAAA,WAAmB,EACnB,MAAA,kBAA0B,EAC1B,MAAA,OAAe,KACf,MAAA,YAAoB,IAAI,IACxB,MAAA,aAAqB,EAAE,CAEnB,OAAO,OAAW,KAAe,OAAO,eAAmB,IAAa,CAC3E,IAAM,EAAS,eAAe,QAAQ,qBAAqB,CAC3D,GAAI,EACH,GAAI,CACH,MAAA,WAAmB,KAAK,MAAM,EAAO,MAC9B,IAMX,cAAqB,EAAwB,CAC5C,MAAA,WAAmB,EAEpB,aAA8B,CAC7B,OAAO,MAAA,QAAc,WAAa,GAGnC,MAAa,SAAyB,CACjC,UAAA,OAGJ,OAAO,IAAI,SAAS,EAAS,IAAW,CACvC,IAAM,EAAS,EAAG,MAAA,IAAW,CAC5B,WAAY,CAAC,YAAa,eAAe,CACzC,KAAM,MAAA,WAAiB,UAAU,KACjC,aAAc,MAAA,WAAiB,UAAU,QACzC,CAAC,CACF,MAAA,OAAe,EAEf,EAAO,GAAG,cAAiB,CAC1B,QAAQ,IAAI,iCAAkC,MAAA,QAAc,GAAG,CAE/D,IAAK,GAAM,CAAC,EAAM,KAAU,MAAA,YAC3B,EAAO,KACN,UACA,EAAU,CACT,KAAM,QACA,OACN,UAAW,EAAM,UACjB,CAAC,CACF,CAGF,IAAK,IAAM,KAAW,MAAA,aAEjB,EAAQ,OAAS,SAAW,MAAA,YAAkB,IAAI,EAAQ,KAAK,EAI/D,EAAQ,OAAS,YAGrB,EAAO,KAAK,UAAW,EAAU,EAAQ,CAAC,CAE3C,MAAA,aAAqB,EAAE,CAEvB,KAAK,0BAA0B,GAAK,CACpC,GAAS,EACR,CAEF,EAAO,GAAG,gBAAkB,GAAQ,CACnC,QAAQ,MAAM,yCAA0C,EAAI,CAC5D,KAAK,0BAA0B,GAAM,CACrC,EAAO,EAAI,EACV,CAEF,EAAO,GAAG,iBAAoB,CAC7B,QAAQ,IAAI,mCAAmC,CAC/C,MAAA,2BAAiC,CACjC,KAAK,0BAA0B,GAAM,EACpC,CAGF,EAAO,GAAG,UAAY,GACrB,MAAA,oBAA0B,EAAY,EAAM,CAAE,uBAAwB,GAAM,CAAC,CAAC,CAC9E,EACA,CAGH,mBAAmB,EAAgD,CAOlE,OANA,MAAA,oBAA0B,IAAI,EAAS,CAGnC,MAAA,SAAiB,MACpB,EAAS,KAAK,aAAa,CAAC,KAEhB,CACZ,MAAA,oBAA0B,OAAO,EAAS,EAI5C,0BAAkC,EAA0B,CAC3D,IAAK,IAAM,KAAY,MAAA,oBACtB,EAAS,EAAU,CAIrB,cAAqB,EAA2C,CAC/D,MAAA,qBAA2B,IAAI,EAAS,CAExC,IAAK,GAAM,CAAC,EAAM,KAAQ,MAAA,aAAoB,EAAS,EAAM,EAAI,CACjE,UAAa,CACZ,MAAA,qBAA2B,OAAO,EAAS,EAI7C,kBAA0B,EAAc,EAA+B,CACtE,IAAK,IAAM,KAAY,MAAA,qBAA4B,EAAS,EAAM,EAAM,CAGzE,YAAmB,EAAwB,CACtC,KAAK,aAAa,CAErB,MAAA,OAAc,KAAK,UAAW,EAAU,EAAe,CAAC,CAGxD,MAAA,aAAmB,KAAK,EAAQ,CAIlC,UAAiB,EAAc,EAAmB,CACjD,GAAI,MAAA,YAAkB,IAAI,EAAK,CAC9B,MAAU,MAAM,QAAQ,EAAK,qBAAqB,CAEnD,MAAA,YAAkB,IAAI,EAAM,EAAK,CAC5B,KAAK,YAAY,CACrB,KAAM,QACN,OACA,UAAW,EAAK,UAChB,CAAC,CAGH,SAAgB,EAAc,EAAsB,CACnD,KAAK,YAAY,CAChB,KAAM,WACN,OACA,YACA,CAAC,CAGH,QAAe,EAAc,CACvB,KAAK,YAAY,CAAE,KAAM,UAAW,OAAM,CAAC,CAChD,MAAA,YAAkB,OAAO,EAAK,CAG/B,YAAoB,CACnB,MAAA,QAAc,YAAY,CAC1B,MAAA,OAAe,KACf,MAAA,aAAqB,EAAE,CACvB,MAAA,oBAA0B,OAAO,CACjC,MAAA,YAAkB,OAAO,CACzB,MAAA,aAAmB,OAAO,CAC1B,MAAA,qBAA2B,OAAO,CAClC,IAAK,GAAM,CAAE,YAAY,MAAA,SAAe,QAAQ,CAC/C,EAAO,QAAQ,IAAI,EAAuB,sBAAsB,CAAC,CAElE,MAAA,SAAe,OAAO,CAGvB,qBAAqB,EAAwB,CAE5C,OAAQ,EAAQ,KAAhB,CACC,IAAK,YAAa,CACjB,IAAM,EAAQ,MAAA,YAAkB,IAAI,EAAQ,KAAK,CAEjD,GAAI,CAAC,EAAO,OACR,GACH,EAAM,OAAO,EAAQ,CAGlB,MAAA,aAAmB,IAAI,EAAQ,KAAK,GACvC,MAAA,aAAmB,OAAO,EAAQ,KAAK,CACvC,KAAK,kBAAkB,EAAQ,KAAM,KAAK,EAE3C,MAED,IAAK,cAAe,CACnB,IAAM,EAAQ,MAAA,YAAkB,IAAI,EAAQ,KAAK,CACjD,GAAI,CAAC,EAAO,OACZ,EAAM,SAAS,EAAQ,IAAI,CAEvB,MAAA,aAAmB,IAAI,EAAQ,KAAK,GACvC,MAAA,aAAmB,OAAO,EAAQ,KAAK,CACvC,KAAK,kBAAkB,EAAQ,KAAM,KAAK,EAE3C,MAED,IAAK,eACJ,GAAI,CAAC,MAAA,YAAkB,IAAI,EAAQ,KAAK,CAAE,OAC1C,MAAA,aAAmB,IAAI,EAAQ,KAAM,EAAQ,MAAM,CACnD,KAAK,kBAAkB,EAAQ,KAAM,EAAQ,MAAM,CACnD,MAED,IAAK,WACC,MAAA,eAAqB,EAAQ,CAClC,MAED,IAAK,cAAe,CAEnB,IAAM,EAAU,CAAC,CAAC,EAAQ,QACtB,EAAO,EAAQ,MAAQ,GAI3B,GAFI,EAAK,WAAW,KAAK,GAAE,EAAO,GAAG,OAAO,SAAS,WAAW,KAC9C,4BAA4B,KAAK,EAAK,CAEvD,GAAI,EAAK,WAAW,UAAU,EAAI,EAAK,WAAW,WAAW,CAC5D,GAAI,CACH,IAAM,EAAM,IAAI,IAAI,EAAK,CACzB,GAAI,EAAI,SAAW,OAAO,SAAS,OAAQ,CAC1C,IAAM,EAAW,GAAG,EAAI,WAAW,EAAI,SAAS,EAAI,OACpD,MAAA,kBAAwB,EAAU,CAAE,UAAS,CAAC,MAE1C,EAAS,OAAO,SAAS,QAAQ,EAAK,CACrC,OAAO,SAAS,OAAO,EAAK,MAE3B,CACH,EAAS,OAAO,SAAS,QAAQ,EAAK,CACrC,OAAO,SAAS,OAAO,EAAK,MAI9B,EAAS,OAAO,SAAS,QAAQ,EAAK,CACrC,OAAO,SAAS,OAAO,EAAK,MAIlC,MAAA,kBAAwB,EAAM,CAAE,UAAS,CAAC,CAE3C,MAED,IAAK,kBACJ,MAAA,oBAA0B,EAAQ,CAClC,MAED,QACC,QAAQ,MAAM,sBAAuB,EAAQ,EAKhD,MAAA,eAAsB,EAA2B,CAChD,GAAI,CACH,IAAM,EAAM,MAAM,MAAM,EAAI,IAAK,CAChC,OAAQ,EAAI,QAAU,MACtB,QAAS,CACR,GAAI,EAAI,SAAW,EAAE,CACrB,GAAI,EAAI,MAAQ,MAAQ,EAAE,iBAAmB,EAAI,SAAW,EAAE,GAC3D,CAAE,eAAgB,mBAAoB,CACtC,EAAE,CACL,CACD,KACC,EAAI,MAAQ,KAIT,IAAA,GAHA,OAAO,EAAI,MAAS,SACnB,EAAI,KACJ,KAAK,UAAU,EAAI,KAAK,CAE7B,YAAa,EAAI,aAAe,UAChC,CAAC,CACIe,EAAqC,EAAE,CAC7C,EAAI,QAAQ,SAAS,EAAG,IAAM,CAC7B,EAAW,GAAK,GACf,CACF,IAAIC,EAAY,KAEhB,AAGC,GAJU,EAAI,QAAQ,IAAI,eAAe,EAAI,IACvC,SAAS,mBAAmB,CAC3B,MAAM,EAAI,MAAM,CAAC,UAAY,KAAK,CAElC,MAAM,EAAI,MAAM,CAAC,UAAY,KAAK,CAE1C,IAAMC,EAAgC,CACrC,KAAM,aACN,GAAI,EAAI,GACR,GAAI,EAAI,GACR,OAAQ,EAAI,OACZ,QAAS,EACT,OACA,CACD,KAAK,YAAY,EAAM,OACf,EAAK,CACb,IAAMA,EAAgC,CACrC,KAAM,aACN,GAAI,EAAI,GACR,GAAI,GACJ,OAAQ,EACR,QAAS,EAAE,CACX,KAAM,CAAE,MAAO,OAAO,EAAI,CAAE,CAC5B,CACD,KAAK,YAAY,EAAM,EAIzB,eAAsB,EAAc,EAAkB,EAAa,CAClE,KAAK,YAAY,CAChB,KAAM,WACN,OACA,WACA,KAAM,EAAK,IAAI,GAAa,CAC5B,CAAC,CAGH,eAAsB,EAA2B,CAChD,IAAM,EAAQ,MAAA,mBAAyB,EAAG,CAE1C,MADA,GAAM,UAAY,EACX,EAAM,OAGd,eAAsB,EAAkB,CACvC,IAAM,EAAQ,MAAA,SAAe,IAAI,EAAG,CAC/B,IAGL,EAAM,SAAW,KAAK,IAAI,EAAG,EAAM,SAAW,EAAE,CAC5C,EAAM,WAAa,IACtB,EAAM,OAAO,QAAQ,IAAI,EAAuB,mBAAmB,CAAC,CACpE,KAAK,YAAY,CAChB,KAAM,kBACN,QAAS,EACT,MAAO,YACP,QAAS,CAAE,OAAQ,gBAAiB,CACpC,CAAC,CACF,MAAA,SAAe,OAAO,EAAG,GAI3B,oBAAoB,EAGlB,CACD,IAAI,EAAQ,MAAA,SAAe,IAAI,EAAG,CAQlC,OAPK,IACJ,EAAQ,CACP,OAAQ,GAAoB,KAAM,EAAG,CACrC,SAAU,EACV,CACD,MAAA,SAAe,IAAI,EAAI,EAAM,EAEvB,EAGR,qBAAqB,EAAqC,CACzD,IAAM,EAAQ,MAAA,mBAAyB,EAAQ,QAAQ,CACxC,EAAM,OAAO,oBAAoB,EAAQ,EAC1C,EAAM,WAAa,GAChC,MAAA,SAAe,OAAO,EAAQ,QAAQ,CAIxC,4BAAmC,CAClC,IAAK,IAAM,KAAS,MAAA,SAAe,QAAQ,CAC1C,EAAM,OAAO,iBAAiB,IAAI,EAAuB,kBAAkB,CAAC,GC/Z/E,MAAa,EAAe,aAkF5B,SAAgB,GAAc,EAAqC,CAElE,OAAO,OAAO,GAAS,YAAY,EAGpC,SAAgB,GAAiB,EAAqC,CACrE,OACC,OAAO,GAAS,YAChB,GACA,EAAK,IAAI,WAAW,KAAmB,EACvC,EAAK,MAAQ,EC7Ef,IAAa,GAAb,KAA0B,CACzB,WACA,eACA,gBACA,UACA,cACA,QACA,MACA,YACA,YAEA,YACC,EACA,EACA,EACA,EACA,EAA6B,EAAE,CAC/B,EAA+B,EAAE,CACjC,EAA2B,EAAE,CAC5B,CACD,MAAA,OAAe,EACf,MAAA,KAAa,EACb,MAAA,WAAmB,EACnB,MAAA,WAAmB,EACnB,MAAA,UAAkB,IAAI,IAAI,EAAiB,CAC3C,MAAA,cAAsB,IAAI,IAC1B,MAAA,eAAuB,IAAI,IAAI,EAAmB,CAClD,MAAA,SAAiB,IAAI,IAAI,EAAe,CACxC,MAAA,aAAqB,CAAC,GAAG,MAAA,UAAgB,CAAC,MAAM,CAIjD,gBAAgB,EAAc,CAC7B,OAAO,MAAA,UAAgB,IAAI,EAAK,CAGjC,kBAAkB,EAAc,CAC/B,OAAO,MAAA,eAAqB,IAAI,EAAK,CAGtC,oBAAoB,EAAyB,CAC5C,GAAI,IAAW,GAAI,OAAO,MAAA,aAAmB,OAAS,EACtD,IAAM,EAAI,MAAA,WAAiB,MAAA,aAAoB,EAAO,CACtD,OAAO,EAAI,MAAA,aAAmB,QAAU,MAAA,aAAmB,GAAI,WAAW,EAAO,CAGlF,mBAAmB,EAAkB,CAIpC,GAAI,EAAM,OACT,IAAK,IAAM,KAAO,EAAM,OACvB,MAAA,UAAgB,OAAO,EAAI,CAC3B,MAAA,cAAoB,OAAO,EAAI,CAGjC,GAAI,EAAM,IACT,IAAK,IAAM,KAAO,EAAM,IACvB,MAAA,UAAgB,IAAI,EAAI,CAG1B,MAAA,aAAqB,CAAC,GAAG,MAAA,UAAgB,CAAC,MAAM,CAGjD,sBAAsB,EAAkB,CACvC,GAAI,EAAM,OACT,IAAK,IAAM,KAAO,EAAM,OACvB,MAAA,eAAqB,OAAO,EAAI,CAGlC,GAAI,EAAM,IACT,IAAK,IAAM,KAAO,EAAM,IACvB,MAAA,eAAqB,IAAI,EAAI,CAKhC,kBAAkB,EAAkB,CACnC,GAAI,EAAM,OACT,IAAK,IAAM,KAAQ,EAAM,OACxB,MAAA,SAAe,OAAO,EAAK,CAG7B,GAAI,EAAM,IACT,IAAK,IAAM,KAAQ,EAAM,IACxB,MAAA,SAAe,IAAI,EAAK,CAK3B,YAAY,EAAc,EAAc,CACvC,IAAM,EAAM,MAAA,SAAe,EAAM,EAAK,CAClC,EAAK,MAAA,cAAoB,IAAI,EAAI,CAKrC,OAJK,IACJ,GAAM,GAAG,IAAgB,MAAA,OAAa,eAAe,MAAA,KAAY,EAAK,EAAK,CAC3E,MAAA,cAAoB,IAAI,EAAK,EAAG,EAE1B,EAGR,WAAW,EAAgB,EAAc,GAAe,CAEvD,GACC,GAAQ,MACR,OAAO,GAAS,WAChB,OAAO,GAAS,UAChB,OAAO,GAAS,SAEhB,OAAO,EAIR,GAAI,GAAc,EAAK,CAAE,CACxB,GAAM,CAAE,MAAK,QAAQ,EAAE,CAAE,WAAW,EAAE,EAAK,EAErCa,EAAgC,EAAE,CACxC,IAAK,GAAM,CAAC,EAAU,KAAc,OAAO,QAAQ,EAAM,CACxD,EAAS,GAAY,KAAK,eAAe,EAAa,EAAU,EAAU,CAGvE,EAAK,MACR,EAAS,IAAM,EAAK,KAGrB,IAAM,EAAmB,EAAE,CAC3B,IAAK,IAAI,EAAQ,EAAG,EAAQ,EAAS,OAAQ,GAAS,EAAG,CACxD,IAAM,EAAQ,EAAS,GACjB,EAAY,EAAc,GAAG,EAAY,GAAG,IAAU,OAAO,EAAM,CACzE,EAAiB,KAAK,KAAK,WAAW,EAAO,EAAU,CAAC,CAGzD,GAAI,GAAiB,EAAK,CAAE,CAC3B,IAAM,EAAe,EAAK,IAAI,MAAM,EAA0B,CACxD,EAAY,MAAA,WAAiB,GACnC,GAAI,CAAC,EACJ,MAAU,MACT,4BAA4B,EAAa,mCACzC,CAEF,OAAO,EAAc,EAAW,EAAU,GAAG,EAAiB,CAG/D,OAAO,EAAc,IAAQ,EAAe,EAAW,EAAK,EAAU,GAAG,EAAiB,CAO3F,OAHI,QAAQ,IAAI,WAAa,cAC5B,QAAQ,MAAM,0BAA2B,EAAK,CAExC,KAGR,UAAU,EAAc,EAAc,CACrC,OAAO,EAAO,GAAG,EAAK,GAAG,IAAS,EAGnC,eAAe,EAAc,EAAa,EAAY,CACrD,IAAM,EAAW,MAAA,SAAe,EAAM,EAAI,CAU1C,OATI,MAAA,UAAgB,IAAI,EAAS,CACzB,KAAK,YAAY,EAAM,EAAI,CAE/B,MAAA,eAAqB,IAAI,EAAS,CAC9B,KAAK,WAAW,EAAO,EAAS,CAEpC,MAAA,SAAe,IAAI,EAAS,CACxB,MAAA,gBAAsB,EAAM,CAE7B,EAGR,iBAAiB,EAAuB,CACvC,IAAM,EAAM,EAAM,QAAQ,IAAI,CAC9B,GAAI,IAAQ,GACX,OAAO,EAER,IAAM,EAAW,EAAM,MAAM,EAAG,EAAI,CAC9B,EAAY,EAAM,MAAM,EAAM,EAAE,CACtC,GAAI,CAAC,GAAY,CAAC,EACjB,OAAO,EAER,IAAM,EAAM,MAAA,WAAiB,GAC7B,GAAI,CAAC,EACJ,MAAU,MAAM,8CAA8C,EAAS,GAAG,CAE3E,IAAM,EAAW,EAAI,GACrB,GAAI,OAAO,GAAa,SACvB,MAAU,MACT,6CAA6C,EAAU,eAAe,EAAS,GAC/E,CAEF,OAAO,EAGR,KAAK,EAAqC,CAEzC,MAAA,UAAkB,IAAI,IAAI,EAAK,UAAU,CAEzC,IAAK,IAAM,KAAK,MAAM,KAAK,MAAA,cAAoB,MAAM,CAAC,CAChD,MAAA,UAAgB,IAAI,EAAE,EAAE,MAAA,cAAoB,OAAO,EAAE,CAU3D,MARA,OAAA,aAAqB,CAAC,GAAG,MAAA,UAAgB,CAAC,MAAM,CAGhD,MAAA,eAAuB,IAAI,IAAI,EAAK,aAAa,CAGjD,MAAA,SAAiB,IAAI,IAAI,EAAK,SAAS,CAEhC,KAAK,WAAW,EAAK,KAAK,CAGlC,qBAAqB,EAA+B,CACnD,IAAM,EAAY,EAAG,OAAe,SAEpC,OADI,GAAY,KAAa,EAAE,CACxB,MAAM,QAAQ,EAAS,CAAG,EAAS,OAAO,CAAG,CAAC,EAAS,CAG/D,aAAa,EAAwB,EAAkC,CACtE,IAAIE,EAAqB,EACzB,IAAK,IAAM,KAAU,EAAS,CAC7B,GAAI,EAAO,OAAS,mBAAoB,CACvC,KAAK,mBAAmB,EAAO,KAAK,CACpC,SAED,GAAI,EAAO,OAAS,kBAAmB,CACtC,KAAK,kBAAkB,EAAO,KAAK,CACnC,SAED,GAAI,EAAO,OAAS,sBAAuB,CAC1C,KAAK,sBAAsB,EAAO,KAAK,CACvC,SAGD,IAAM,EAAQ,EAAO,KAAK,MAAM,IAAI,CAAC,OAAQ,GAAM,EAAE,OAAS,EAAE,CAE1D,GAAW,EAAiB,EAAe,IAA4B,CAC5E,GAAI,EAAQ,EAAM,OAAQ,CACzB,MAAA,gBAAsB,EAAM,EAAO,EAAM,CACzC,IAAM,EAAU,EACV,EAAW,EAAM,GACjB,EAAW,CAAC,EACZ,EAAY,EAAO,GAAG,EAAK,GAAG,IAAa,EACjD,GAAK,OAAO,MAAM,EAAS,CAMpB,CAEN,IAAM,EAAa,EAAQ,OAAS,EAAE,CAChC,EAAQ,EAAU,GAKxB,OAAO,EAAa,EAJN,CACb,GAAG,GACF,GAAW,EAAQ,EAAO,EAAQ,EAAG,EAAU,CAChD,CACkC,KAdP,CAE5B,IAAM,EAAc,MAAA,oBAA0B,EAAQ,CAChD,EAAQ,EAAY,GAE1B,MADA,GAAY,GAAY,EAAQ,EAAO,EAAQ,EAAG,EAAU,CACrD,EAAa,EAAS,IAAA,GAAW,GAAG,EAAY,EAYzD,OAAQ,EAAO,KAAf,CACC,IAAK,UACJ,OAAO,KAAK,WAAW,EAAO,KAAM,EAAO,KAAK,CAEjD,IAAK,eAAgB,CACpB,MAAA,gBAAsB,EAAM,EAAO,EAAM,CACzC,IAAM,EAAU,EAEVG,EAAiC,CAAE,GADnB,EAAQ,OAAS,EAAE,CACiB,CACpD,EAAQ,EAAO,KACrB,GAAI,EAAM,QAAU,EAAM,OAAO,OAAS,MACpC,IAAM,KAAO,EAAM,OACnB,KAAO,GACV,OAAO,EAAU,GAIpB,GAAI,EAAM,IACT,IAAK,GAAM,CAAC,EAAG,KAAM,OAAO,QAAQ,EAAM,IAAI,CAC7C,EAAU,GAAK,KAAK,eAAe,EAAM,EAAG,EAAE,CAe/C,OARyB,EAAM,QAAQ,QAAU,GAAK,GAGtD,EAAU,IAAM,EAAQ,IACxB,EAAU,IAAO,EAAgB,IAC1B,EAAc,EAAQ,KAAM,EAAW,GAAG,MAAA,oBAA0B,EAAQ,CAAC,EAG7E,EAAa,EAAS,EAAU,CAGzC,IAAK,iBAAkB,CACtB,MAAA,gBAAsB,EAAM,EAAO,EAAM,CACzC,IAAM,EAAU,EACV,EAAe,MAAA,oBAA0B,EAAQ,CACjD,EAAe,EAAE,CAEjB,CAAC,EAAY,GAAe,EAAO,IACnC,CAAC,EAAc,GAAgB,EAAO,MAExC,EAAU,GACb,EAAY,GACZ,EAAS,GACT,EAAW,GACR,EAAW,OAAS,IACvB,EAAU,EAAW,GACrB,EAAS,GAEN,EAAa,OAAS,IACzB,EAAY,EAAa,GACzB,EAAW,GAEZ,IAAK,IAAI,EAAI,EAAG,EAAI,EAAO,EAAG,EAAE,EAC/B,GAAI,IAAM,EAAS,CAClB,IAAM,EAAW,EAAY,GACvB,EAAY,EAAO,GAAG,EAAK,GAAG,IAAM,OAAO,EAAE,CACnD,EAAa,KAAK,KAAK,WAAW,EAAU,EAAU,CAAC,CACvD,EAAU,EAAS,EAAW,OAAS,EAAI,EAAW,EAAE,GAAU,WACxD,IAAM,EAAW,CAE3B,IAAI,EAAM,EADK,EAAa,IAEtB,EAAY,EAAO,GAAG,EAAK,GAAG,IAAM,OAAO,EAAE,CAE/C,KAAK,oBAAoB,EAAU,GACtC,EAAM,MAAA,yBAA+B,EAAK,EAAU,EAErD,EAAa,KAAK,EAAI,CACtB,EAAY,EAAW,EAAa,OAAS,EAAI,EAAa,EAAE,GAAY,QAG5E,EAAa,KAAK,EAAa,GAAG,CAIpC,OAAO,EAAa,EAAS,KAAO,GAAG,EAAa,CAErD,QACC,MAAU,MAAM,yCAA0C,GAAgB,OAAO,GAIpF,EAAU,EAAQ,EAAS,EAAG,GAAG,CAElC,OAAO,EAGR,iBAAiB,EAAiB,EAAiB,EAAqC,CACvF,GAAI,QAAQ,IAAI,WAAa,cAAgB,CAAC,EAAe,EAAK,CAEjE,MADA,QAAQ,MAAM,gBAAiB,EAAK,CAC1B,MAAM,wBAAwB,EAAM,MAAM,EAAG,EAAM,CAAC,KAAK,IAAI,GAAG,CAE3E,MAAO,GAIR,0BAA0B,EAAiB,EAAyB,CACnE,GAAI,CAAC,EAAe,EAAK,CAAE,OAAO,EAClC,IAAM,EAAU,EACV,EAAa,EAAQ,OAAS,EAAE,CAChCA,EAAiC,CAAE,GAAG,EAAW,CAIvD,IAAK,IAAM,KAAO,OAAO,KAAK,EAAU,CAAE,CACzC,IAAM,EAAW,EAAO,GAAG,EAAK,GAAG,IAAQ,EACvC,KAAK,gBAAgB,EAAS,GACjC,EAAU,GAAO,KAAK,YAAY,EAAM,EAAI,EAEzC,KAAK,kBAAkB,EAAS,EAAI,KAAK,oBAAoB,EAAS,GACzE,EAAU,GAAO,MAAA,yBAA+B,EAAU,GAAM,EAAS,EAa3E,OAAO,EAAa,EAAS,EAAW,GATvB,MAAA,oBAA0B,EAAQ,CAAC,KAAK,EAAO,IAAQ,CACvE,IAAM,EAAY,EAAO,GAAG,EAAK,GAAG,IAAQ,OAAO,EAAI,CAItD,OAHG,KAAK,oBAAoB,EAAU,CAC/B,MAAA,yBAA+B,EAAO,EAAU,CAEhD,GAEP,CAEkD,CAIrD,YAAY,EAAe,EAAwB,CAClD,IAAI,EAAK,EACL,EAAK,EAAI,OACb,KAAO,EAAK,GAAI,CACf,IAAM,EAAO,EAAK,IAAQ,EACtB,EAAI,GAAQ,EACf,EAAK,EAAM,EAEX,EAAK,EAGP,OAAO,IAMT,SAAgB,GACf,EACA,EACiC,CACjC,IAAM,EAAY,EAAK,EAAU,CACjC,OAAQ,CAAE,WAAU,GAAG,KAErB,EAAC,EAAA,CAAmB,oBACnB,EAAC,EAAA,CAAU,GAAI,EAAQ,YAAqB,EAClC,CC3Yd,MAAM,EAAqB,EAA0C,KAAK,CACpE,EAAwB,EAAqC,KAAK,CAE3D,MAAuB,CACnC,IAAM,EAAS,EAAW,EAAmB,CAC7C,GAAI,CAAC,EACJ,MAAU,MAAM,qDAAqD,CAEtE,OAAO,GAGK,GAAqB,GAAiB,CAClD,IAAM,EAAM,EAAW,EAAsB,CAC7C,GAAI,CAAC,EACJ,MAAU,MAAM,wDAAwD,CAEzE,IAAM,EAAO,EAAI,MAAM,GACvB,GAAI,CAAC,EACJ,MAAU,MAAM,2BAA2B,EAAK,GAAG,CAEpD,OAAO,GAaF,EAAY,OAAO,OAAW,IAEpC,SAAgB,GAAc,CAAE,WAAU,SAAQ,aAAiC,CAClF,GAAM,CAAC,EAAW,GAAgB,EAAS,GAAK,CAC1C,EAAa,GAAa,CAC1B,CAAE,cAAe,EAGjB,EAAS,MACP,IAAI,EAAoB,EAAO,cAAe,EAAY,EAAW,CAC1E,CAAC,EAAO,cAAe,EAAW,CAAC,CAUtC,OATA,MAAgB,EAAO,cAAc,EAAW,CAAE,CAAC,EAAQ,EAAW,CAAC,CACvE,MAAgB,EAAO,mBAAmB,EAAa,CAAE,CAAC,EAAO,CAAC,CAClE,MAAgB,CACf,GAAI,EAEH,OADA,EAAO,SAAS,KACH,EAAO,YAAY,EAE/B,CAAC,EAAO,CAAC,CAGX,EAAC,EAAmB,SAAA,CAAS,MAAO,WACnC,EAAC,EAAsB,SAAA,CAAS,MAAO,YACrC,CAAC,GACD,EAAC,MAAA,CACA,MAAO,CACN,SAAU,QACV,OAAQ,OACR,MAAO,OACP,gBAAiB,MACjB,MAAO,QACP,QAAS,OACT,aAAc,MACd,OAAQ,IACR,UACD,oCAEK,CAEN,EAAA,EAC+B,EACJ,CAchC,SAAgB,GAAU,CAAE,qBAAoB,OAAM,cAA8B,CACnF,IAAM,EAAS,GAAgB,CACzB,EAAc,GAAkB,EAAK,CAErC,EAAW,MAEf,IAAI,GACH,EACA,EACA,EACA,EACA,EAAY,UACZ,EAAY,aACZ,EAAY,SACZ,CACF,CAAC,EAAQ,EAAM,EAAoB,EAAW,CAC9C,CACK,CAAC,EAAM,GAAW,MAA0B,EAAS,KAAK,EAAY,CAAC,CACvE,CAAC,EAAa,GAAkB,EAAiC,KAAK,CAEtE,EAAW,IAAa,CACxB,EAAS,IAAW,CAGpB,EAAY,MAAc,CAC/B,GAAM,CAAE,IAAK,EAAW,GAAI,GAAG,GAAe,EACxC,EAAc,IAAI,gBAAgB,EAAS,OAAO,CACxD,MAAO,CACN,KAAM,EAAS,KACf,SAAU,EAAS,SACnB,MAAO,EAAS,OAChB,YAAa,OAAO,YAAY,EAAY,SAAS,CAAC,CACtD,aACA,SAAU,EAAS,OAAS,EAAI,EAAS,MAAM,IAAI,CAAG,EAAE,CACxD,EACC,CAAC,EAAS,KAAM,EAAS,SAAU,EAAS,OAAQ,KAAK,UAAU,EAAO,CAAC,CAAC,CAG/E,MAAgB,CACf,GAAI,EAAW,CACd,EAAO,UAAU,EAAM,CACtB,YACA,OAAS,GAAS,CACjB,EAAQ,EAAS,KAAK,EAAK,CAAC,EAE7B,SAAW,GAAQ,CAClB,EAAS,GAAU,GAAQ,KAAO,EAAO,EAAS,aAAa,EAAM,EAAI,CAAE,EAE5E,CAAC,CACF,IAAM,EAAS,EAAO,eAAe,EAAG,IAAQ,CAC3C,IAAM,GAAM,EAAe,EAAI,EAClC,CACF,UAAa,CACZ,GAAQ,CACR,EAAO,QAAQ,EAAK,IAIpB,CAAC,EAAQ,EAAU,EAAK,CAAC,CAE5B,MAAgB,CACX,GACH,EAAO,SAAS,EAAM,EAAU,EAE/B,CAAC,EAAQ,EAAM,EAAU,CAAC,CAE7B,IAAM,EAAc,EAAO,GAAM,CAmBjC,OAlBA,OAEM,EAAY,QAKhB,EAAQ,EAAS,KAAK,EAAY,CAAC,CAJnC,EAAY,QAAU,OAMV,CACZ,EAAY,QAAU,KAErB,CAAC,EAAa,EAAS,CAAC,CAEvB,EACI,EAAC,GAAA,CAAY,MAAO,EAAA,CAAe,CAGpC,EAGR,SAAS,GAAY,CAAE,SAAqC,CAC3D,OACC,EAAC,MAAA,CACA,MAAO,CACN,QAAS,GACT,OAAQ,iBACR,WAAY,UACZ,MAAO,OACP,WACC,qGACD,WAAY,WACZ,WAED,EAAC,MAAA,CAAI,MAAO,CAAE,WAAY,IAAK,aAAc,EAAG,WAAE,uBAAqB,EAAM,MAAA,EAAY,CACxF,EAAM,SAAW,EAAC,MAAA,CAAA,SAAK,EAAM,QAAA,CAAc,CAC3C,EAAM,OACN,EAAC,UAAA,CAAQ,KAAA,GAAK,MAAO,CAAE,UAAW,EAAG,WACpC,EAAC,UAAA,CAAA,SAAQ,cAAA,CAAqB,CAC9B,EAAC,MAAA,CAAI,MAAO,CAAE,OAAQ,EAAG,UAAG,EAAM,OAAY,CAAA,EACrC,GAEN,CCzOR,SAAgB,GAAgB,EAAkC,CACjE,IAAM,EAAS,GAAgB,CACzB,EAAS,MAAc,CAC5B,GAAI,CAAC,EACJ,MAAU,MAAM,iDAAiD,CAElE,OAAO,EAAO,eAAe,EAAU,EACrC,CAAC,EAAQ,EAAU,CAAC,CAQvB,OANA,UACc,CACZ,EAAO,eAAe,EAAU,EAE/B,CAAC,EAAQ,EAAU,CAAC,CAEhB"}
|