phlex-reactive 0.9.5 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import{Controller as d}from"@hotwired/stimulus";import{confirmResolver as l}from"phlex/reactive/confirm";import{computeReducer as s}from"phlex/reactive/compute";function o(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:visit"])return;j["reactive:visit"]=function(){let Q=this.getAttribute("data-url");if(Q)window.Turbo.visit(Q,{action:"advance"})}}function n(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:token"])return;j["reactive:token"]=function(){let Q=this.getAttribute("data-reactive-token-value"),X=this.getAttribute("target");if(!Q||!X)return;let Z=document.getElementById(X);if(Z)Z.setAttribute("data-reactive-token-value",Q)}}function i(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:js"])return;j["reactive:js"]=function(){let Q=c(this.getAttribute("data-reactive-ops"));if(!Q.length)return;let X=this.getAttribute("target"),Z=X?document.getElementById(X):null;if(X&&!Z)return;g(Q,($)=>Oj($,Z))}}var H=new Map;function Ej(){H.clear(),E=!1}function Fj(j){return H.get(j)?.via}var E=!1;function a(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:defer"])return;if(j["reactive:defer"]=function(){let Q=this.getAttribute("target");if(!Q)return;if(this.getAttribute("data-reactive-defer-via")==="stream"){t(Q,this);return}let X=this.getAttribute("data-reactive-defer-token");if(!X)return;L(Q,X)},!E&&typeof document<"u"&&document.addEventListener)E=!0,document.addEventListener("turbo:before-stream-render",r)}function r(j){let X=j.target?.getAttribute?.("target");if(!X)return;let Z=X.startsWith("reactive-defer-src-")?X.slice(19):X;if(H.get(Z)?.via==="stream")H.delete(Z)}function L(j,Q){let X=document.getElementById(j);if(!X){console.warn(`[phlex-reactive] reactive:defer target #${j} is not on the page — skipped`);return}h(j),y(X);let Z={via:"fetch",abort:new AbortController,timedOut:!1};H.set(j,Z),e(j,Z,Q)}function t(j,Q){let X=document.getElementById(j);if(!X){console.warn(`[phlex-reactive] reactive:defer target #${j} is not on the page — skipped`);return}let Z=Q.getAttribute("data-reactive-defer-src");if(!Z)return;if(!globalThis.customElements?.get?.("pgbus-stream-source")){let J=Q.getAttribute("data-reactive-defer-token");if(J){L(j,J);return}console.error("[phlex-reactive] reactive:defer via=stream but <pgbus-stream-source> is not registered "+"and no fallback token was provided — is the pgbus client loaded on this page?");return}h(j),y(X);let $=document.createElement("pgbus-stream-source");$.id=w(j),$.setAttribute("src",Z),$.setAttribute("since-id",Q.getAttribute("data-reactive-defer-since-id")??"0"),$.setAttribute("hidden",""),document.body.appendChild($),H.set(j,{via:"stream"})}function w(j){return`reactive-defer-src-${j}`}async function e(j,Q,X){let Z=setTimeout(()=>{Q.timedOut=!0,Q.abort.abort()},Xj()),$;try{$=await fetch(jj(),{method:"POST",headers:{Accept:"text/vnd.turbo-stream.html","Content-Type":"application/json","X-CSRF-Token":Qj()},body:JSON.stringify({token:X}),credentials:"same-origin",signal:Q.abort.signal})}catch(G){if(clearTimeout(Z),H.get(j)!==Q)return;console.error("[phlex-reactive] deferred render failed",G),O(j,X);return}if(H.get(j)!==Q){clearTimeout(Z);return}if($.status===204){clearTimeout(Z),I(j);return}if(!$.ok){clearTimeout(Z),console.error(`[phlex-reactive] deferred render failed: HTTP ${$.status}`),O(j,X,$.status);return}let J;try{J=await $.text()}catch(G){if(clearTimeout(Z),H.get(j)!==Q)return;console.error("[phlex-reactive] deferred render failed reading the body",G),O(j,X);return}if(clearTimeout(Z),H.get(j)!==Q)return;I(j),window.Turbo.renderStreamMessage(J)}function h(j){let Q=H.get(j);if(!Q)return;if(H.delete(j),Q.via==="fetch")Q.abort.abort();else document.getElementById(w(j))?.remove?.()}function y(j){j.setAttribute("data-reactive-defer-pending","true"),j.setAttribute("aria-busy","true")}function v(j){j.removeAttribute("data-reactive-defer-pending"),j.removeAttribute("aria-busy")}function I(j){H.delete(j);let Q=document.getElementById(j);if(!Q)return;v(Q),Q.removeAttribute("data-reactive-error")}function O(j,Q,X){H.delete(j);let Z=document.getElementById(j);if(!Z)return;v(Z),Z.setAttribute("data-reactive-error","defer");let $=()=>{let J=document.getElementById(j);if(!J){console.warn("[phlex-reactive] defer retry() ignored — the target left the DOM");return}J.removeAttribute("data-reactive-error"),L(j,Q)};Z.dispatchEvent(new CustomEvent("reactive:error",{bubbles:!0,composed:!0,detail:{kind:"defer",target:j,status:X,retry:$}}))}function jj(){return document.querySelector('meta[name="phlex-reactive-defer-path"]')?.content||"/reactive/defer"}function Qj(){return document.querySelector('meta[name="csrf-token"]')?.content??""}function Xj(){let j=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,Q=Number(j);return Number.isFinite(Q)&&Q>0?Q:30000}var F=!1;function Zj(){if(F)return;if(typeof document>"u"||!document.addEventListener)return;F=!0,document.addEventListener("turbo:before-stream-render",$j)}function $j(j){let Q=j.detail,X=Q?.render;if(typeof X!=="function"||X.__reactiveDismissWrapped){if(typeof requestAnimationFrame==="function")requestAnimationFrame(B);else setTimeout(B,0);return}let Z=async($)=>{await X($),B()};Z.__reactiveDismissWrapped=!0,Q.render=Z}function B(){let j=document.querySelectorAll("[data-reactive-dismiss-after]");for(let Q of j){if(Q.hasAttribute("data-reactive-dismiss-scheduled"))continue;let X=Number(Q.getAttribute("data-reactive-dismiss-after"));if(!Number.isFinite(X)||X<=0)continue;Q.setAttribute("data-reactive-dismiss-scheduled",""),setTimeout(()=>Q.remove(),X)}}function Rj(){F=!1}var R=!1;function Jj(){if(R)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;R=!0;let j=()=>{let Q=document.documentElement;if(typeof Q?.toggleAttribute!=="function")return;Q.toggleAttribute("data-reactive-offline",globalThis.navigator?.onLine===!1)};j(),window.addEventListener("online",j),window.addEventListener("offline",j)}function Dj(){R=!1}var D="phlex-reactive:latency",N=!1;function Gj(j){if(typeof sessionStorage>"u")return;sessionStorage.setItem(D,String(j))}function Wj(){if(typeof sessionStorage>"u")return;sessionStorage.removeItem(D),N=!1}function zj(){if(typeof window>"u"||typeof document>"u")return;if(document.querySelector?.('meta[name="phlex-reactive-env"]')?.content!=="development")return;window.PhlexReactive={enableLatencySim:Gj,disableLatencySim:Wj}}function Tj(){N=!1}function S(){o(),n(),i(),a(),Zj(),Jj(),zj()}function Kj(j){return j.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}if(typeof window<"u")if(window.Turbo)S();else document.addEventListener("turbo:load",S,{once:!0});var x=!1;function qj(){if(x)return;if(typeof document>"u")return;let j=document.querySelectorAll('[data-controller~="reactive"]');if(!j||j.length===0)return;console.warn("[phlex-reactive] found "+j.length+' element(s) with data-controller="reactive" '+"but the reactive controller never connected. It is loaded but not registered — "+'add `application.register("reactive", ReactiveController)` (importmap) or import it into app/javascript/controllers/ for lazyLoadControllersFrom apps. See the README.')}function Ij(){x=!1}function Sj(){x=!0}if(typeof window<"u"&&typeof document<"u"){let j=()=>setTimeout(qj,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",j,{once:!0});else j()}var Yj=new Set(["href","src","srcdoc","action","formaction","xlink:href","style"]);function Uj(j){let Q=String(j).toLowerCase();return Q.startsWith("on")||Yj.has(Q)}function Hj(j,Q,X){let[Z,$,J]=Q;j.classList.add(Z,$),X(),requestAnimationFrame(()=>{j.classList.remove($),j.classList.add(J)});let G=!1,W=()=>{if(G)return;G=!0,j.classList.remove(Z,J)};j.addEventListener("animationend",W,{once:!0}),setTimeout(W,350)}var k=Object.freeze({show:(j,Q)=>C(j,!1,Q),hide:(j,Q)=>C(j,!0,Q),toggle:(j,Q)=>C(j,!j.hidden,Q),add_class:(j,Q)=>j.classList.add(...Q.classes??[]),remove_class:(j,Q)=>j.classList.remove(...Q.classes??[]),toggle_class:(j,Q)=>(Q.classes??[]).forEach((X)=>j.classList.toggle(X)),set_attr:(j,Q)=>{if(P(Q.name))j.setAttribute(Q.name,Q.value??"")},remove_attr:(j,Q)=>{if(P(Q.name))j.removeAttribute(Q.name)},toggle_attr:(j,Q)=>{if(!P(Q.name))return;if(j.hasAttribute(Q.name))j.removeAttribute(Q.name);else j.setAttribute(Q.name,"")},focus:(j)=>j.focus?.(),focus_first:(j)=>xj(j)?.focus?.(),text:(j,Q)=>{let X=String(Q.value??"");if(j.textContent!==X)j.textContent=X},dispatch:(j,Q)=>{j.dispatchEvent(new CustomEvent(Q.name,{bubbles:!0,composed:!0,detail:Q.detail??{}}))}});function C(j,Q,X){if(X?.transition)Hj(j,X.transition,()=>j.hidden=Q);else j.hidden=Q}function P(j){if(!Uj(j))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(j)} — skipped`),!1}var f=/^#[A-Za-z_][\w-]*$/;function Vj(j){if(typeof j==="string"&&f.test(j))return!0;return console.warn(`[phlex-reactive] refused cross-root mirror target ${JSON.stringify(j)} — skipped`),!1}function Aj(j,Q){let X=j.getAttribute("data-reactive-show-equals");if(X!==null)return Q===X;let Z=j.getAttribute("data-reactive-show-not");if(Z!==null)return Q!==Z;let $=j.getAttribute("data-reactive-show-in");if($!==null){try{let J=JSON.parse($);if(Array.isArray(J))return J.includes(Q)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify($)} — skipped`),null}for(let J of u){let G=j.getAttribute(`data-reactive-show-${J}`);if(G!==null)return p(J,G,Q)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}var u=["gte","gt","lte","lt"];function p(j,Q,X){let Z=Number(Q);if(Number.isNaN(Z))return console.warn(`[phlex-reactive] reactive_show ${j}: needs a numeric literal, got ${JSON.stringify(Q)} — skipped`),null;let $=X==null?"":String(X).trim(),J=$===""?NaN:Number($);if(Number.isNaN(J))return!1;switch(j){case"gte":return J>=Z;case"gt":return J>Z;case"lte":return J<=Z;case"lt":return J<Z;default:return null}}function m(j,Q){if(!j||typeof j!=="object")return null;if(typeof j.equals==="string")return Q===j.equals;if(typeof j.not==="string")return Q!==j.not;if(Array.isArray(j.in))return j.in.includes(Q);for(let X of u)if(X in j)return p(X,j[X],Q);return null}var b="[data-reactive-show-field], [data-reactive-show]";function _j(j){try{let Q=JSON.parse(j);if(Q&&typeof Q==="object"&&!Array.isArray(Q))return Q}catch{}return console.warn(`[phlex-reactive] malformed compound reactive_show payload ${JSON.stringify(j)} — skipped`),null}function Mj(j,Q){if(!j||typeof j!=="object")return null;let X=Array.isArray(j.all)?"all":Array.isArray(j.any)?"any":null;if(!X)return null;let Z=j[X];if(Z.length===0)return null;let $=Z.map((J)=>{if(!J||typeof J!=="object"||typeof J.field!=="string")return!1;let G=Q(J.field);if(G===null)return!1;return m(J,G)===!0});return X==="all"?$.every(Boolean):$.some(Boolean)}function Nj(j){if(typeof j==="string"&&f.test(j))return!0;return console.warn(`[phlex-reactive] refused cross-root show target ${JSON.stringify(j)} — skipped`),!1}var Lj='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function xj(j){return j.querySelectorAll?.(Lj)?.[0]??null}function c(j){if(Array.isArray(j))return j;if(typeof j!=="string")return[];try{let Q=JSON.parse(j);return Array.isArray(Q)?Q:[]}catch{return[]}}function g(j,Q){for(let X of j){if(!Array.isArray(X))continue;let[Z,$={}]=X;if(!Object.hasOwn(k,Z)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(Z)} — skipped`);continue}for(let J of Q($))k[Z](J,$)}}function Oj(j,Q){let X=j.to;if(Q){if(X==="@root")return[Q];if(typeof X!=="string"||X==="")return[];if(j.global)return[...document.querySelectorAll(X)];return[...Q.querySelectorAll(X)]}if(typeof X!=="string"||X===""||X==="@root")return[];return[...document.querySelectorAll(X)]}class kj extends d{static values={token:String};#R;#V=new Map;#z=new Map;#g;#L;#D;#x=0;#K=new Map;#O=new WeakMap;#A=new Map;#q;#Y;#U;#j;#X;#_;connect(){if(x=!0,this.element.id==="")console.warn("[phlex-reactive] a reactive root has no id; its next-action token can't self-match "+"and may fall back to the first token in the response → a silent HTTP 403 on the NEXT action. "+"Put id: on the SAME element as reactive_attrs — use div(**reactive_root) (emits id + token together), "+"or div(id:, **reactive_attrs). The id: must NOT be on a child. See the README.");if(this.element.getAttribute?.("data-reactive-defer-token"))this.#T(),this.#_=()=>this.#T(),this.element.addEventListener?.("turbo:morph-element",this.#_);if(this.#d()){if(this.#q=()=>this.#P(),this.element.addEventListener?.("turbo:morph-element",this.#q),this.#P(),this.element.getAttribute?.("data-reactive-warn-unsaved")==="true")this.#qj()}if(this.#Uj())this.#j=()=>this.#f(),this.element.addEventListener?.("input",this.#j),this.element.addEventListener?.("change",this.#j),this.element.addEventListener?.("turbo:morph-element",this.#j),this.#f();if(this.#_j())this.#X=(j)=>{if(j?.type==="input"&&!this.#Mj(j))return;this.#p()},this.element.addEventListener?.("input",this.#X),this.element.addEventListener?.("turbo:morph-element",this.#X),this.#p()}#d(){if((this.element.getAttribute?.("data-action")??"").includes("reactive#trackDirty"))return!0;let j=this.element.querySelectorAll?.('[data-action*="reactive#trackDirty"]')??[];for(let Q of j)if(this.#Q(Q))return!0;return!1}disconnect(){if(this.#r(),this.#e(),this.#Yj(),this.#Aj(),this.#Nj(),this.#_)this.element.removeEventListener?.("turbo:morph-element",this.#_)}#T(){let j=this.element;if(!j?.id)return;let Q=j.getAttribute?.("data-reactive-defer-token");if(!Q)return;if(j.getAttribute?.("data-reactive-defer-pending")!=="true")return;L(j.id,Q)}dispatch(j){let{action:Q,params:X,debounce:Z,throttle:$,confirm:J,outside:G,window:W,optimistic:z,loading:Y}=j.params;if(!Q)return;if(G&&this.element.contains(j.target))return;let U=j.currentTarget??j.target;if(!W&&!this.#Cj(z,U))j.preventDefault();if(!J)return this.#b(U,Q,X,Z,$,z,Y);Promise.resolve().then(()=>l(J)).catch(()=>!1).then((K)=>{if(K)this.#b(U,Q,X,Z,$,z,Y)})}runOps(j){let{ops:Q,outside:X,window:Z}=j.params;if(X&&this.element.contains(j.target))return;if(!Z)j.preventDefault();this.#Bj(this.#Oj(Q))}trackDirty(){this.#P()}recompute(j){let Q=this.#s(),X=Q.map(([K])=>K),Z=this.#H(),$=new Map,J=(K)=>{if($.has(K))return $.get(K);let q=null;for(let A of this.element.querySelectorAll(`[name="${K}"]`))if(Z(A)){q=A;break}return $.set(K,q),q};for(let K of X)this.#S(K,J(K)?.value??"");let G=this.element.getAttribute("data-reactive-compute-reducer-param"),W=G?s(G):null;if(!W){this.#k({},J);return}let z=this.#l("data-reactive-compute-outputs-param"),Y={};for(let[K,q]of Q){let A=J(K);if(q==="string")Y[K]=A?.value??"";else{let _=Number(A?.value);Y[K]=Number.isFinite(_)?_:0}}let U=W(Y,{changed:this.#o(j,X)})||{};for(let K of z){if(!(K in U))continue;let q=J(K);if(q){if(String(U[K])===q.value)continue;q.value=U[K],q.dispatchEvent(new Event("input",{bubbles:!0}))}else this.#S(K,U[K])}this.#k(U,J)}listnavNext(j){this.#I(j,1)}listnavPrev(j){this.#I(j,-1)}listnavPick(j){let Q=this.#B(j),X=Q.findIndex((Z)=>Z.hasAttribute("data-reactive-highlighted"));if(X<0)return;j.preventDefault(),Q[X].click()}listnavClose(j){for(let Q of this.#B(j))Q.removeAttribute("data-reactive-highlighted")}#I(j,Q){let X=this.#B(j);if(!X.length)return;j.preventDefault();let Z=X.findIndex((G)=>G.hasAttribute("data-reactive-highlighted")),$=Z<0?Q>0?0:X.length-1:(Z+Q+X.length)%X.length;for(let G of X)G.removeAttribute("data-reactive-highlighted");let J=X[$];J.setAttribute("data-reactive-highlighted","true"),J.scrollIntoView?.({block:"nearest"})}#B(j){let X=(j?.currentTarget??j?.target??this.element).getAttribute?.("data-reactive-listnav-option-param")??this.element.getAttribute("data-reactive-listnav-option-param");if(!X)return[];let Z=this.#H();return Array.from(this.element.querySelectorAll(X)).filter(($)=>!$.hidden&&Z($))}#l(j){let Q=this.element.getAttribute(j);if(!Q)return[];try{let X=JSON.parse(Q);return Array.isArray(X)?X:[]}catch{return[]}}#s(){let j=this.element.getAttribute("data-reactive-compute-inputs-param");if(!j)return[];try{let Q=JSON.parse(j);if(Array.isArray(Q))return Q.map((X)=>[X,"number"]);if(Q&&typeof Q==="object")return Object.entries(Q);return[]}catch{return[]}}#o(j,Q){let X=j?.target;if(!X?.name||typeof X.closest!=="function")return null;if(!Q.includes(X.name))return null;return this.#Q(X)?X.name:null}#S(j,Q){let X=String(Q);for(let Z of this.#n(j)){if(Z.textContent===X)continue;Z.textContent=X}}#n(j){let Q=this.element.querySelectorAll(`[data-reactive-text="${j}"]`);return Array.from(Q).filter((X)=>this.#Q(X))}#k(j,Q){let X=this.#i();for(let[Z,$]of Object.entries(X)){let J=Z in j?j[Z]:Q(Z)?.value;if(J===void 0||J===null)continue;let G=String(J);for(let W of Array.isArray($)?$:[$]){if(!Vj(W))continue;for(let z of document.querySelectorAll(W)){if(z.textContent===G)continue;z.textContent=G}}}}#i(){let j=this.element.getAttribute("data-reactive-compute-mirror-param");if(!j)return{};try{let Q=JSON.parse(j);return Q&&typeof Q==="object"&&!Array.isArray(Q)?Q:{}}catch{return{}}}#b(j,Q,X,Z,$,J,G){if(this.#N("reactive:before-dispatch",{action:Q,params:this.#m(X),element:this.element},{cancelable:!0}).defaultPrevented)return;let z=Number(Z)||0;if(z>0)return this.#a(j,z,Q,X,J,G);let Y=Number($)||0;if(Y>0)return this.#t(j,Y,Q,X,J,G);return this.#M(Q,X,J,j,G)}#M(j,Q,X,Z,$){let J=this.#Pj(X,Z),G=this.#Fj(j,Z,$);return this.queue=(this.queue??Promise.resolve()).then(()=>this.#Gj(j,Q,J,G)),this.queue}#a(j,Q,X,Z,$,J){this.#C(j);let G=()=>{this.#C(j),this.#M(X,Z,$,j,J)},W=setTimeout(G,Q);j?.addEventListener?.("blur",G,{once:!0}),this.#V.set(j,{timer:W,flush:G})}#C(j){let Q=this.#V.get(j);if(!Q)return;clearTimeout(Q.timer),j?.removeEventListener?.("blur",Q.flush),this.#V.delete(j)}#r(){for(let j of[...this.#V.keys()])this.#C(j)}#t(j,Q,X,Z,$,J){let G=this.#z.get(j)??new Map;if(G.has(X))return;let W=setTimeout(()=>{if(G.delete(X),G.size===0)this.#z.delete(j)},Q);return G.set(X,W),this.#z.set(j,G),this.#M(X,Z,$,j,J)}#e(){for(let j of this.#z.values())for(let Q of j.values())clearTimeout(Q);this.#z.clear()}#N(j,Q,{cancelable:X=!1}={}){let Z=new CustomEvent(j,{bubbles:!0,composed:!0,cancelable:X,detail:Q});return(this.element.isConnected?this.element:document).dispatchEvent(Z),Z}#Z(j,Q,X,Z){let $=()=>{if(!this.element.isConnected){console.warn("[phlex-reactive] retry() ignored — the reactive root left the DOM");return}return this.#M(j,Q)};this.#N("reactive:error",{action:j,params:X,...Z,retry:$})}#$(j){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",j)}#jj(){this.element?.removeAttribute?.("data-reactive-error")}#Qj(){let j=document.querySelector("[data-reactive-error-flash]");if(!j?.content)return;let Q=j.getAttribute("data-reactive-error-flash")||"flash",X=document.getElementById(Q);if(!X)return;X.appendChild(j.content.cloneNode(!0))}#Xj(){if(typeof sessionStorage>"u")return Promise.resolve();let j=Number(sessionStorage.getItem(D));if(!Number.isFinite(j)||j<=0)return Promise.resolve();if(!N)N=!0,console.warn(`[phlex-reactive] latency simulator ACTIVE — every action is delayed by ${j}ms. Call PhlexReactive.disableLatencySim() (or clear sessionStorage) to turn it off.`);return new Promise((Q)=>setTimeout(Q,j))}#Zj(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#w(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}#$j(j){if(!j)return[];let Q=[],X=/<turbo-stream\b([^>]*)>/g,Z;while((Z=X.exec(j))!==null){let $=Z[1],J=$.match(/\baction="([^"]*)"/)?.[1]??"?",G=$.match(/\btarget="([^"]*)"/)?.[1];Q.push(G?`${J} → #${G}`:J)}return Q}#Jj(j){let{action:Q,status:X,ms:Z}=j,J=`reactive ${this.element?.id?`#${this.element.id} `:""}${Q} → ${X??"—"} (${Math.round(Z)}ms)`;if(console.groupCollapsed(J),console.log(`params: [${j.paramNames.join(", ")}] + collected: [${j.fieldNames.join(", ")}]`),console.log(`encoding: ${j.encoding}`),j.streams.length)console.log(`streams: ${j.streams.join(" ")}`);console.log(`token: ${j.tokenRefreshed?"refreshed ✓":"unchanged"}`),console.groupEnd()}async#Gj(j,Q,X,Z){let{fields:$,files:J}=this.#zj(),G=this.#m(Q),W={...$,...G},z=this.#J,Y=J.length>0,U=Y?this.#Lj(z,j,W,J):JSON.stringify({token:z,act:j,params:W}),K=this.#Zj()?{action:j,paramNames:Object.keys(G),fieldNames:Object.keys($),encoding:Y?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#w()}:null;await this.#Xj();try{if(navigator.onLine===!1){this.#G(X),this.#$("offline"),this.#Z(j,Q,W,{kind:"offline"});return}let q;try{let V={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#wj()};if(!Y)V["Content-Type"]="application/json";let M=this.#hj();if(M)V["X-Pgbus-Connection"]=M;q=await fetch(this.#kj(),{method:"POST",headers:V,body:U,credentials:"same-origin",signal:AbortSignal.timeout(this.#bj())})}catch(V){if(console.error("[phlex-reactive] action error",V),this.#G(X),V?.name==="TimeoutError"||V?.name==="AbortError"){this.#$("timeout"),this.#Z(j,Q,W,{kind:"timeout"});return}this.#Qj(),this.#$("network"),this.#Z(j,Q,W,{kind:"network"});return}if(K)K.status=q.status;if(q.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#G(X),this.#$("redirected"),this.#Z(j,Q,W,{kind:"redirected",status:q.status});return}if(!q.ok){let V=await q.text();if(console.error(`[phlex-reactive] action failed: HTTP ${q.status}`,V),this.#G(X),(q.headers.get("Content-Type")||"").includes("turbo-stream")){let M=this.#y(V);if(this.#J=M??this.#J,K)this.#h(K,V,M);window.Turbo.renderStreamMessage(V)}this.#$("http"),this.#Z(j,Q,W,{kind:"http",status:q.status,body:V});return}let A=q.headers.get("Content-Type")||"";if(!A.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${A}" — no update applied`),this.#G(X),this.#$("content-type"),this.#Z(j,Q,W,{kind:"content-type",status:q.status});return}let _=await q.text(),T=this.#y(_);if(this.#J=T??this.#J,K)this.#h(K,_,T);window.Turbo.renderStreamMessage(_),this.#jj(),this.#N("reactive:applied",{action:j,params:W,html:_})}catch(q){console.error("[phlex-reactive] action error",q),this.#G(X),this.#N("reactive:error",{action:j,params:W,kind:"apply"})}finally{if(Z?.(),K)this.#Jj({...K,ms:this.#w()-K.started})}}#h(j,Q,X){j.streams=this.#$j(Q),j.tokenRefreshed=X!=null}get#J(){return this.#R??this.tokenValue}set#J(j){this.#R=j}#y(j){let Q=this.element.id;if(!Q)return j.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:X,self:Z}=this.#Wj(Q),$=j.match(X);if($)return $[1];let J=j.match(Z);if(J)return J[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#Wj(j){let Q=this.#D;if(Q&&Q.id===j)return Q;let X=Kj(j);return this.#D={id:j,token:new RegExp(`<turbo-stream\\b[^>]*\\baction="reactive:token"[^>]*\\btarget="${X}"[^>]*\\bdata-reactive-token-value="([^"]+)"`),self:new RegExp(`<turbo-stream\\b[^>]*\\baction="(?:replace|update)"[^>]*\\btarget="${X}"[^>]*>([\\s\\S]*?)</turbo-stream>`)}}#Q(j){return j.closest('[data-controller~="reactive"]')===this.element}#H(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(Q)=>this.#Q(Q)}#zj(){let j={},Q=[],X=this.#H();return this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((Z)=>{if(!X(Z))return;if(Z.type==="file")for(let $ of Z.files??[])Q.push({name:Z.name,file:$,multiple:Z.multiple});else if(Z.type==="checkbox")j[Z.name]=Z.checked;else if(Z.type==="radio"){if(Z.checked)j[Z.name]=Z.value}else j[Z.name]=Z.value}),this.element.querySelectorAll("[name]:is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])").forEach((Z)=>{if(!X(Z))return;let $=Z.getAttribute("name");if(!$)return;let J=j[$];if(J==null||J==="")j[$]=Z.value??Z.textContent??Z.innerHTML??""}),{fields:j,files:Q}}#P(){if(typeof this.element?.querySelectorAll!=="function")return;let j=0;if(this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((Q)=>{if(!this.#Q(Q))return;if(Q.type==="file")return;if(this.#Kj(Q))Q.setAttribute("data-reactive-dirty","true"),j++;else Q.removeAttribute("data-reactive-dirty")}),j>0)this.element.setAttribute("data-reactive-dirty",String(j));else this.element.removeAttribute("data-reactive-dirty")}#Kj(j){if(j.type==="checkbox"||j.type==="radio")return j.checked!==j.defaultChecked;if(j.tag==="select"||j.options)return Array.from(j.options??[]).some((Q)=>Q.selected!==Q.defaultSelected);return j.value!==j.defaultValue}#v(){let j=this.element.getAttribute?.("data-reactive-dirty"),Q=Number(j);return Number.isFinite(Q)&&Q>0?Q:0}#qj(){if(typeof window>"u"||typeof window.addEventListener!=="function")return;this.#Y=(j)=>{if(this.#v()===0)return;return j.preventDefault(),j.returnValue="You have unsaved changes.",j.returnValue},this.#U=(j)=>{if(this.#v()===0)return;if(!(typeof window.confirm==="function"?window.confirm("You have unsaved changes. Leave anyway?"):!0))j.preventDefault?.()},window.addEventListener("beforeunload",this.#Y),window.addEventListener("turbo:before-visit",this.#U)}#Yj(){if(this.#q)this.element.removeEventListener?.("turbo:morph-element",this.#q),this.#q=void 0;if(typeof window<"u"&&typeof window.removeEventListener==="function"){if(this.#Y)window.removeEventListener("beforeunload",this.#Y);if(this.#U)window.removeEventListener("turbo:before-visit",this.#U)}this.#Y=void 0,this.#U=void 0}#Uj(){if(this.element.getAttribute?.("data-reactive-show-targets"))return!0;let j=this.element.querySelectorAll?.(b)??[];for(let Q of j)if(this.#Q(Q))return!0;return!1}#f(){if(typeof this.element?.querySelectorAll!=="function")return;let j=this.#H(),Q=new Map,X=(Z)=>{if(!Q.has(Z))Q.set(Z,this.#u(Z,j));return Q.get(Z)};for(let Z of this.element.querySelectorAll(b)){if(!j(Z))continue;let $=Z.getAttribute("data-reactive-show");if($!==null){let z=Mj(_j($),X);if(z!==null)Z.hidden=!z;continue}let J=Z.getAttribute("data-reactive-show-field");if(!J)continue;let G=X(J);if(G===null)continue;let W=Aj(Z,G);if(W===null)continue;Z.hidden=!W}this.#Hj(j,Q)}#Hj(j,Q){let X=this.#Vj();for(let[Z,$]of Object.entries(X)){if(!$||typeof $!=="object"||Array.isArray($))continue;if(!Q.has(Z))Q.set(Z,this.#u(Z,j));let J=Q.get(Z);if(J===null)continue;for(let[G,W]of Object.entries($)){if(!Nj(G))continue;let z=m(W,J);if(z===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${G} — skipped`);continue}for(let Y of document.querySelectorAll(G))Y.hidden=!z}}}#Vj(){let j=this.element.getAttribute?.("data-reactive-show-targets");if(!j)return{};try{let Q=JSON.parse(j);if(Q&&typeof Q==="object"&&!Array.isArray(Q))return Q}catch{}return console.warn("[phlex-reactive] malformed data-reactive-show-targets — ignored. "+"Did two reactive_show_targets calls collide on one root? Declare every field in ONE call: reactive_show_targets(mode: { ... }, kind: { ... })"),{}}#u(j,Q){let X=!1,Z=null;for(let $ of this.element.querySelectorAll(`[name="${j}"]`)){if(!Q($))continue;if($.type==="checkbox")return $.checked?"true":"false";if($.type==="radio"){if($.checked)return $.value??"";X=!0;continue}Z??=$}if(Z)return Z.value??"";return X?"":null}#Aj(){if(!this.#j)return;this.element.removeEventListener?.("input",this.#j),this.element.removeEventListener?.("change",this.#j),this.element.removeEventListener?.("turbo:morph-element",this.#j),this.#j=void 0}#_j(){return!!(this.element.getAttribute?.("data-reactive-filter-input")&&this.element.getAttribute?.("data-reactive-filter-option"))}#Mj(j){let Q=this.element.getAttribute("data-reactive-filter-input");return!!Q&&typeof j.target?.matches==="function"&&j.target.matches(Q)}#p(){if(typeof this.element?.querySelectorAll!=="function")return;let j=this.element.getAttribute("data-reactive-filter-input"),Q=this.element.getAttribute("data-reactive-filter-option");if(!j||!Q)return;let X=this.#H(),Z=[...this.element.querySelectorAll(j)].find(X);if(!Z)return;let $=(Z.value??"").trim().toLowerCase(),J=0;for(let z of this.element.querySelectorAll(Q)){if(!X(z))continue;let Y=(z.getAttribute("data-reactive-filter-text")??z.textContent??"").toLowerCase(),U=$!==""&&!Y.includes($);if(z.hidden=U,U)z.removeAttribute("data-reactive-highlighted");else J++}let G=this.element.getAttribute("data-reactive-filter-group");if(G)for(let z of this.element.querySelectorAll(G)){if(!X(z))continue;let Y=[...z.querySelectorAll(Q)].filter(X);if(Y.length===0)continue;z.hidden=Y.every((U)=>U.hidden)}let W=this.element.getAttribute("data-reactive-filter-empty");if(W){for(let z of this.element.querySelectorAll(W))if(X(z))z.hidden=J>0}}#Nj(){if(!this.#X)return;this.element.removeEventListener?.("input",this.#X),this.element.removeEventListener?.("turbo:morph-element",this.#X),this.#X=void 0}#Lj(j,Q,X,Z){let $=new FormData;$.append("token",j),$.append("act",Q);for(let[G,W]of Object.entries(X))this.#E($,`params[${G}]`,W);let J=this.#xj(Z);for(let{name:G,file:W,multiple:z}of Z){let U=z||J.has(G)?`params[${G}][]`:`params[${G}]`;$.append(U,W,W.name)}return $}#E(j,Q,X){if(X==null)j.append(Q,"");else if(Array.isArray(X))X.forEach((Z,$)=>this.#E(j,`${Q}[${$}]`,Z));else if(typeof X==="object")for(let[Z,$]of Object.entries(X))this.#E(j,`${Q}[${Z}]`,$);else j.append(Q,String(X))}#xj(j){let Q=new Map;for(let{name:X}of j)Q.set(X,(Q.get(X)??0)+1);return new Set([...Q].filter(([,X])=>X>1).map(([X])=>X))}#m(j){if(!j)return{};try{return typeof j==="string"?JSON.parse(j):j}catch{return{}}}#Oj(j){return c(j)}#Bj(j){g(j,(Q)=>this.#F(Q))}#F(j){let Q=j.to;if(Q==="@root")return[this.element];if(typeof Q!=="string"||Q==="")return[];if(j.global)return[...document.querySelectorAll(Q)];return[...this.element.querySelectorAll(Q)].filter((X)=>this.#Q(X))}#Cj(j,Q){if(j?.checked!=="keep")return!1;let X=Q?.type;return X==="checkbox"||X==="radio"}#Pj(j,Q){if(!j)return null;let X=this.#Ej(j,Q),Z=[];for(let $ of X){if(j.add_class){let J=j.add_class.filter((G)=>!$.classList.contains(G));if($.classList.add(...J),J.length)Z.push(()=>$.classList.remove(...J))}if(j.remove_class){let J=j.remove_class.filter((G)=>$.classList.contains(G));if($.classList.remove(...J),J.length)Z.push(()=>$.classList.add(...J))}if(j.toggle_class)j.toggle_class.forEach((J)=>$.classList.toggle(J)),Z.push(()=>j.toggle_class.forEach((J)=>$.classList.toggle(J)));if(j.hide)$.hidden=!0,Z.push(()=>$.hidden=!1)}if(j.checked==="keep"&&Q&&"checked"in Q){let $=Q.checked;Z.push(()=>Q.checked=!$)}return Z.length?Z:null}#G(j){if(!j)return;if(!this.element.isConnected)return;for(let Q of j)Q()}#Ej(j,Q){if(j.to==null)return Q?[Q]:[];return this.#F({to:j.to})}#Fj(j,Q,X){this.#Rj(j,Q);let Z=this.#Tj(j,Q,X),$=!1;return()=>{if($)return;$=!0,this.#Dj(j,Q),Z()}}#Rj(j,Q){if(this.#W(Q,j,1),this.#W(this.element,j,1),this.#K.set(j,(this.#K.get(j)??0)+1),this.#x++===0)this.element.setAttribute("aria-busy","true");for(let X of this.#c(j))this.#W(X,j,1)}#Dj(j,Q){this.#W(Q,j,-1),this.#W(this.element,j,-1);let X=(this.#K.get(j)??1)-1;if(X<=0)this.#K.delete(j);else this.#K.set(j,X);if(--this.#x<=0)this.#x=0,this.element.removeAttribute("aria-busy");for(let Z of this.#c(j))this.#W(Z,j,-1)}#W(j,Q,X){if(!j||typeof j.getAttribute!=="function")return;let Z=this.#O.get(j)??new Map,$=(Z.get(Q)??0)+X;if($<=0)Z.delete(Q);else Z.set(Q,$);if(Z.size===0){this.#O.delete(j),j.removeAttribute("data-reactive-busy");return}this.#O.set(j,Z),j.setAttribute("data-reactive-busy",[...Z.keys()].join(" "))}#c(j){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((X)=>X.getAttribute("data-reactive-busy-on")===j&&this.#Q(X))}#Tj(j,Q,X){if(!X||!Q)return()=>{};let Z=this.#Sj(X,Q),$=Array.isArray(X.class)?X.class:[],J=[];for(let W of Z){let z=$.filter((Y)=>!W.classList.contains(Y));if(W.classList.add(...z),z.length)J.push([W,z])}let G=this.#A.get(Q);if(G)G.count++;else if(X.disable||X.text!=null)this.#A.set(Q,{count:1,disabled:Q.disabled,text:Q.textContent,hadText:X.text!=null});if(X.disable)Q.disabled=!0;if(X.text!=null)Q.textContent=X.text;return()=>{for(let[W,z]of J)if(W.isConnected)W.classList.remove(...z);this.#Ij(Q,X)}}#Ij(j,Q){let X=this.#A.get(j);if(!X)return;if(--X.count>0)return;if(this.#A.delete(j),!j.isConnected)return;if(Q.disable)j.disabled=X.disabled;if(X.hadText&&j.textContent===Q.text)j.textContent=X.text}#Sj(j,Q){if(j.to==null)return Q?[Q]:[];return this.#F({to:j.to})}#kj(){return this.#g??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#bj(){if(this.#L!=null)return this.#L;let j=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,Q=Number(j);return this.#L=Number.isFinite(Q)&&Q>0?Q:30000}#wj(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#hj(){return document.querySelector("pgbus-stream-source[connection-id]")?.getAttribute("connection-id")||document.querySelector('meta[name="pgbus-connection-id"]')?.content||null}}export{Ej as resetReactiveDefers,o as registerReactiveVisit,n as registerReactiveToken,Jj as registerReactiveOffline,i as registerReactiveJs,Zj as registerReactiveDismiss,a as registerReactiveDefer,S as registerReactiveActions,Fj as pendingDeferVia,Kj as escapeRegExp,Gj as enableLatencySim,Wj as disableLatencySim,kj as default,qj as checkReactiveRegistration,Ij as __resetReactiveRegistrationForTest,Dj as __resetReactiveOfflineForTest,Tj as __resetReactiveLatencyForTest,Rj as __resetReactiveDismissForTest,Sj as __markReactiveConnectedForTest,D as LATENCY_KEY};
1
+ import{Controller as l}from"@hotwired/stimulus";import{confirmResolver as s}from"phlex/reactive/confirm";import{computeReducer as o}from"phlex/reactive/compute";function n(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:visit"])return;j["reactive:visit"]=function(){let Q=this.getAttribute("data-url");if(Q)window.Turbo.visit(Q,{action:"advance"})}}function i(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:token"])return;j["reactive:token"]=function(){let Q=this.getAttribute("data-reactive-token-value"),X=this.getAttribute("target");if(!Q||!X)return;let Z=document.getElementById(X);if(Z)Z.setAttribute("data-reactive-token-value",Q)}}function a(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:js"])return;j["reactive:js"]=function(){let Q=g(this.getAttribute("data-reactive-ops"));if(!Q.length)return;let X=this.getAttribute("target"),Z=X?document.getElementById(X):null;if(X&&!Z)return;d(Q,($)=>Pj($,Z))}}var H=new Map;function Dj(){H.clear(),E=!1}function Tj(j){return H.get(j)?.via}var E=!1;function r(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:defer"])return;if(j["reactive:defer"]=function(){let Q=this.getAttribute("target");if(!Q)return;if(this.getAttribute("data-reactive-defer-via")==="stream"){e(Q,this);return}let X=this.getAttribute("data-reactive-defer-token");if(!X)return;M(Q,X)},!E&&typeof document<"u"&&document.addEventListener)E=!0,document.addEventListener("turbo:before-stream-render",t)}function t(j){let X=j.target?.getAttribute?.("target");if(!X)return;let Z=X.startsWith("reactive-defer-src-")?X.slice(19):X;if(H.get(Z)?.via==="stream")H.delete(Z)}function M(j,Q){let X=document.getElementById(j);if(!X){console.warn(`[phlex-reactive] reactive:defer target #${j} is not on the page — skipped`);return}y(j),v(X);let Z={via:"fetch",abort:new AbortController,timedOut:!1};H.set(j,Z),jj(j,Z,Q)}function e(j,Q){let X=document.getElementById(j);if(!X){console.warn(`[phlex-reactive] reactive:defer target #${j} is not on the page — skipped`);return}let Z=Q.getAttribute("data-reactive-defer-src");if(!Z)return;if(!globalThis.customElements?.get?.("pgbus-stream-source")){let J=Q.getAttribute("data-reactive-defer-token");if(J){M(j,J);return}console.error("[phlex-reactive] reactive:defer via=stream but <pgbus-stream-source> is not registered "+"and no fallback token was provided — is the pgbus client loaded on this page?");return}y(j),v(X);let $=document.createElement("pgbus-stream-source");$.id=h(j),$.setAttribute("src",Z),$.setAttribute("since-id",Q.getAttribute("data-reactive-defer-since-id")??"0"),$.setAttribute("hidden",""),document.body.appendChild($),H.set(j,{via:"stream"})}function h(j){return`reactive-defer-src-${j}`}async function jj(j,Q,X){let Z=setTimeout(()=>{Q.timedOut=!0,Q.abort.abort()},Zj()),$;try{$=await fetch(Qj(),{method:"POST",headers:{Accept:"text/vnd.turbo-stream.html","Content-Type":"application/json","X-CSRF-Token":Xj()},body:JSON.stringify({token:X}),credentials:"same-origin",signal:Q.abort.signal})}catch(G){if(clearTimeout(Z),H.get(j)!==Q)return;console.error("[phlex-reactive] deferred render failed",G),O(j,X);return}if(H.get(j)!==Q){clearTimeout(Z);return}if($.status===204){clearTimeout(Z),S(j);return}if(!$.ok){clearTimeout(Z),console.error(`[phlex-reactive] deferred render failed: HTTP ${$.status}`),O(j,X,$.status);return}let J;try{J=await $.text()}catch(G){if(clearTimeout(Z),H.get(j)!==Q)return;console.error("[phlex-reactive] deferred render failed reading the body",G),O(j,X);return}if(clearTimeout(Z),H.get(j)!==Q)return;S(j),window.Turbo.renderStreamMessage(J)}function y(j){let Q=H.get(j);if(!Q)return;if(H.delete(j),Q.via==="fetch")Q.abort.abort();else document.getElementById(h(j))?.remove?.()}function v(j){j.setAttribute("data-reactive-defer-pending","true"),j.setAttribute("aria-busy","true")}function f(j){j.removeAttribute("data-reactive-defer-pending"),j.removeAttribute("aria-busy")}function S(j){H.delete(j);let Q=document.getElementById(j);if(!Q)return;f(Q),Q.removeAttribute("data-reactive-error")}function O(j,Q,X){H.delete(j);let Z=document.getElementById(j);if(!Z)return;f(Z),Z.setAttribute("data-reactive-error","defer");let $=()=>{let J=document.getElementById(j);if(!J){console.warn("[phlex-reactive] defer retry() ignored — the target left the DOM");return}J.removeAttribute("data-reactive-error"),M(j,Q)};Z.dispatchEvent(new CustomEvent("reactive:error",{bubbles:!0,composed:!0,detail:{kind:"defer",target:j,status:X,retry:$}}))}function Qj(){return document.querySelector('meta[name="phlex-reactive-defer-path"]')?.content||"/reactive/defer"}function Xj(){return document.querySelector('meta[name="csrf-token"]')?.content??""}function Zj(){let j=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,Q=Number(j);return Number.isFinite(Q)&&Q>0?Q:30000}var F=!1;function $j(){if(F)return;if(typeof document>"u"||!document.addEventListener)return;F=!0,document.addEventListener("turbo:before-stream-render",Jj)}function Jj(j){let Q=j.detail,X=Q?.render;if(typeof X!=="function"||X.__reactiveDismissWrapped){if(typeof requestAnimationFrame==="function")requestAnimationFrame(B);else setTimeout(B,0);return}let Z=async($)=>{await X($),B()};Z.__reactiveDismissWrapped=!0,Q.render=Z}function B(){let j=document.querySelectorAll("[data-reactive-dismiss-after]");for(let Q of j){if(Q.hasAttribute("data-reactive-dismiss-scheduled"))continue;let X=Number(Q.getAttribute("data-reactive-dismiss-after"));if(!Number.isFinite(X)||X<=0)continue;Q.setAttribute("data-reactive-dismiss-scheduled",""),setTimeout(()=>Q.remove(),X)}}function Ij(){F=!1}var R=!1;function Gj(){if(R)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;R=!0;let j=()=>{let Q=document.documentElement;if(typeof Q?.toggleAttribute!=="function")return;Q.toggleAttribute("data-reactive-offline",globalThis.navigator?.onLine===!1)};j(),window.addEventListener("online",j),window.addEventListener("offline",j)}function Sj(){R=!1}var D="phlex-reactive:latency",L=!1;function Wj(j){if(typeof sessionStorage>"u")return;sessionStorage.setItem(D,String(j))}function zj(){if(typeof sessionStorage>"u")return;sessionStorage.removeItem(D),L=!1}function Kj(){if(typeof window>"u"||typeof document>"u")return;if(document.querySelector?.('meta[name="phlex-reactive-env"]')?.content!=="development")return;window.PhlexReactive={enableLatencySim:Wj,disableLatencySim:zj}}function kj(){L=!1}function k(){n(),i(),a(),r(),$j(),Gj(),Kj()}function qj(j){return j.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}if(typeof window<"u")if(window.Turbo)k();else document.addEventListener("turbo:load",k,{once:!0});var x=!1;function Yj(){if(x)return;if(typeof document>"u")return;let j=document.querySelectorAll('[data-controller~="reactive"]');if(!j||j.length===0)return;console.warn("[phlex-reactive] found "+j.length+' element(s) with data-controller="reactive" '+"but the reactive controller never connected. It is loaded but not registered — "+'add `application.register("reactive", ReactiveController)` (importmap) or import it into app/javascript/controllers/ for lazyLoadControllersFrom apps. See the README.')}function bj(){x=!1}function wj(){x=!0}if(typeof window<"u"&&typeof document<"u"){let j=()=>setTimeout(Yj,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",j,{once:!0});else j()}var Uj=new Set(["href","src","srcdoc","action","formaction","xlink:href","style"]);function Hj(j){let Q=String(j).toLowerCase();return Q.startsWith("on")||Uj.has(Q)}function Aj(j,Q,X){let[Z,$,J]=Q;j.classList.add(Z,$),X(),requestAnimationFrame(()=>{j.classList.remove($),j.classList.add(J)});let G=!1,W=()=>{if(G)return;G=!0,j.classList.remove(Z,J)};j.addEventListener("animationend",W,{once:!0}),setTimeout(W,350)}var b=Object.freeze({show:(j,Q)=>C(j,!1,Q),hide:(j,Q)=>C(j,!0,Q),toggle:(j,Q)=>C(j,!j.hidden,Q),add_class:(j,Q)=>j.classList.add(...Q.classes??[]),remove_class:(j,Q)=>j.classList.remove(...Q.classes??[]),toggle_class:(j,Q)=>(Q.classes??[]).forEach((X)=>j.classList.toggle(X)),set_attr:(j,Q)=>{if(P(Q.name))j.setAttribute(Q.name,Q.value??"")},remove_attr:(j,Q)=>{if(P(Q.name))j.removeAttribute(Q.name)},toggle_attr:(j,Q)=>{if(!P(Q.name))return;if(j.hasAttribute(Q.name))j.removeAttribute(Q.name);else j.setAttribute(Q.name,"")},focus:(j)=>j.focus?.(),focus_first:(j)=>Cj(j)?.focus?.(),text:(j,Q)=>{let X=String(Q.value??"");if(j.textContent!==X)j.textContent=X},dispatch:(j,Q)=>{j.dispatchEvent(new CustomEvent(Q.name,{bubbles:!0,composed:!0,detail:Q.detail??{}}))}});function C(j,Q,X){if(X?.transition)Aj(j,X.transition,()=>j.hidden=Q);else j.hidden=Q}function P(j){if(!Hj(j))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(j)} — skipped`),!1}var u=/^#[A-Za-z_][\w-]*$/;function _j(j){if(typeof j==="string"&&u.test(j))return!0;return console.warn(`[phlex-reactive] refused cross-root mirror target ${JSON.stringify(j)} — skipped`),!1}function Nj(j,Q){let X=j.getAttribute("data-reactive-show-equals");if(X!==null)return Q===X;let Z=j.getAttribute("data-reactive-show-not");if(Z!==null)return Q!==Z;let $=j.getAttribute("data-reactive-show-in");if($!==null){try{let J=JSON.parse($);if(Array.isArray(J))return J.includes(Q)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify($)} — skipped`),null}for(let J of p){let G=j.getAttribute(`data-reactive-show-${J}`);if(G!==null)return m(J,G,Q)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}var p=["gte","gt","lte","lt"];function m(j,Q,X){let Z=Number(Q);if(Number.isNaN(Z))return console.warn(`[phlex-reactive] reactive_show ${j}: needs a numeric literal, got ${JSON.stringify(Q)} — skipped`),null;let $=X==null?"":String(X).trim(),J=$===""?NaN:Number($);if(Number.isNaN(J))return!1;switch(j){case"gte":return J>=Z;case"gt":return J>Z;case"lte":return J<=Z;case"lt":return J<Z;default:return null}}function c(j,Q){if(!j||typeof j!=="object")return null;if(typeof j.equals==="string")return Q===j.equals;if(typeof j.not==="string")return Q!==j.not;if(Array.isArray(j.in))return j.in.includes(Q);for(let X of p)if(X in j)return m(X,j[X],Q);return null}var w="[data-reactive-show-field], [data-reactive-show]";function Vj(j){try{let Q=JSON.parse(j);if(Q&&typeof Q==="object"&&!Array.isArray(Q))return Q}catch{}return console.warn(`[phlex-reactive] malformed compound reactive_show payload ${JSON.stringify(j)} — skipped`),null}function T(j,Q){if(!j||typeof j!=="object"||typeof j.field!=="string")return!1;let X=Q(j.field)??"";return c(j,X)===!0}function Lj(j,Q){if(!Array.isArray(j)||j.length===0)return null;return j.some((X)=>Array.isArray(X)&&X.length>0&&X.every((Z)=>T(Z,Q)))}function Mj(j,Q){if(!j||typeof j!=="object")return null;let X=j.any;if(Array.isArray(X)&&(X.length===0||Array.isArray(X[0])))return Lj(X,Q);return xj(j,Q)}function xj(j,Q){let X=Array.isArray(j.all)?"all":Array.isArray(j.any)?"any":null;if(!X)return null;let Z=j[X];if(Z.length===0)return null;let $=Z.map((J)=>T(J,Q));return X==="all"?$.every(Boolean):$.some(Boolean)}function Oj(j){if(typeof j==="string"&&u.test(j))return!0;return console.warn(`[phlex-reactive] refused cross-root show target ${JSON.stringify(j)} — skipped`),!1}var Bj='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Cj(j){return j.querySelectorAll?.(Bj)?.[0]??null}function g(j){if(Array.isArray(j))return j;if(typeof j!=="string")return[];try{let Q=JSON.parse(j);return Array.isArray(Q)?Q:[]}catch{return[]}}function d(j,Q){for(let X of j){if(!Array.isArray(X))continue;let[Z,$={}]=X;if(!Object.hasOwn(b,Z)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(Z)} — skipped`);continue}for(let J of Q($))b[Z](J,$)}}function Pj(j,Q){let X=j.to;if(Q){if(X==="@root")return[Q];if(typeof X!=="string"||X==="")return[];if(j.global)return[...document.querySelectorAll(X)];return[...Q.querySelectorAll(X)]}if(typeof X!=="string"||X===""||X==="@root")return[];return[...document.querySelectorAll(X)]}class hj extends l{static values={token:String};#R;#A=new Map;#z=new Map;#d;#M;#D;#x=0;#K=new Map;#O=new WeakMap;#_=new Map;#q;#Y;#U;#j;#X;#N;connect(){if(x=!0,this.element.id==="")console.warn("[phlex-reactive] a reactive root has no id; its next-action token can't self-match "+"and may fall back to the first token in the response → a silent HTTP 403 on the NEXT action. "+"Put id: on the SAME element as reactive_attrs — use div(**reactive_root) (emits id + token together), "+"or div(id:, **reactive_attrs). The id: must NOT be on a child. See the README.");if(this.element.getAttribute?.("data-reactive-defer-token"))this.#T(),this.#N=()=>this.#T(),this.element.addEventListener?.("turbo:morph-element",this.#N);if(this.#l()){if(this.#q=()=>this.#P(),this.element.addEventListener?.("turbo:morph-element",this.#q),this.#P(),this.element.getAttribute?.("data-reactive-warn-unsaved")==="true")this.#Yj()}if(this.#Hj())this.#j=()=>this.#f(),this.element.addEventListener?.("input",this.#j),this.element.addEventListener?.("change",this.#j),this.element.addEventListener?.("turbo:morph-element",this.#j),this.#f();if(this.#Vj())this.#X=(j)=>{if(j?.type==="input"&&!this.#Lj(j))return;this.#m()},this.element.addEventListener?.("input",this.#X),this.element.addEventListener?.("turbo:morph-element",this.#X),this.#m()}#l(){if((this.element.getAttribute?.("data-action")??"").includes("reactive#trackDirty"))return!0;let j=this.element.querySelectorAll?.('[data-action*="reactive#trackDirty"]')??[];for(let Q of j)if(this.#Q(Q))return!0;return!1}disconnect(){if(this.#t(),this.#jj(),this.#Uj(),this.#Nj(),this.#Mj(),this.#N)this.element.removeEventListener?.("turbo:morph-element",this.#N)}#T(){let j=this.element;if(!j?.id)return;let Q=j.getAttribute?.("data-reactive-defer-token");if(!Q)return;if(j.getAttribute?.("data-reactive-defer-pending")!=="true")return;M(j.id,Q)}dispatch(j){let{action:Q,params:X,debounce:Z,throttle:$,confirm:J,outside:G,window:W,optimistic:z,loading:q}=j.params;if(!Q)return;if(G&&this.element.contains(j.target))return;let U=j.currentTarget??j.target;if(!W&&!this.#Pj(z,U))j.preventDefault();if(!J)return this.#b(U,Q,X,Z,$,z,q);Promise.resolve().then(()=>s(J)).catch(()=>!1).then((K)=>{if(K)this.#b(U,Q,X,Z,$,z,q)})}runOps(j){let{ops:Q,outside:X,window:Z}=j.params;if(X&&this.element.contains(j.target))return;if(!Z)j.preventDefault();this.#Cj(this.#Bj(Q))}trackDirty(){this.#P()}recompute(j){let Q=this.#o(),X=Q.map(([K])=>K),Z=this.#H(),$=new Map,J=(K)=>{if($.has(K))return $.get(K);let Y=null;for(let _ of this.element.querySelectorAll(`[name="${K}"]`))if(Z(_)){Y=_;break}return $.set(K,Y),Y};for(let K of X)this.#S(K,J(K)?.value??"");let G=this.element.getAttribute("data-reactive-compute-reducer-param"),W=G?o(G):null;if(!W){this.#k({},J);return}let z=this.#s("data-reactive-compute-outputs-param"),q={};for(let[K,Y]of Q){let _=J(K);if(Y==="string")q[K]=_?.value??"";else{let N=Number(_?.value);q[K]=Number.isFinite(N)?N:0}}let U=W(q,{changed:this.#n(j,X)})||{};for(let K of z){if(!(K in U))continue;let Y=J(K);if(Y){if(String(U[K])===Y.value)continue;Y.value=U[K],Y.dispatchEvent(new Event("input",{bubbles:!0}))}else this.#S(K,U[K])}this.#k(U,J)}listnavNext(j){this.#I(j,1)}listnavPrev(j){this.#I(j,-1)}listnavPick(j){let Q=this.#B(j),X=Q.findIndex((Z)=>Z.hasAttribute("data-reactive-highlighted"));if(X<0)return;j.preventDefault(),Q[X].click()}listnavClose(j){for(let Q of this.#B(j))Q.removeAttribute("data-reactive-highlighted")}#I(j,Q){let X=this.#B(j);if(!X.length)return;j.preventDefault();let Z=X.findIndex((G)=>G.hasAttribute("data-reactive-highlighted")),$=Z<0?Q>0?0:X.length-1:(Z+Q+X.length)%X.length;for(let G of X)G.removeAttribute("data-reactive-highlighted");let J=X[$];J.setAttribute("data-reactive-highlighted","true"),J.scrollIntoView?.({block:"nearest"})}#B(j){let X=(j?.currentTarget??j?.target??this.element).getAttribute?.("data-reactive-listnav-option-param")??this.element.getAttribute("data-reactive-listnav-option-param");if(!X)return[];let Z=this.#H();return Array.from(this.element.querySelectorAll(X)).filter(($)=>!$.hidden&&Z($))}#s(j){let Q=this.element.getAttribute(j);if(!Q)return[];try{let X=JSON.parse(Q);return Array.isArray(X)?X:[]}catch{return[]}}#o(){let j=this.element.getAttribute("data-reactive-compute-inputs-param");if(!j)return[];try{let Q=JSON.parse(j);if(Array.isArray(Q))return Q.map((X)=>[X,"number"]);if(Q&&typeof Q==="object")return Object.entries(Q);return[]}catch{return[]}}#n(j,Q){let X=j?.target;if(!X?.name||typeof X.closest!=="function")return null;if(!Q.includes(X.name))return null;return this.#Q(X)?X.name:null}#S(j,Q){let X=String(Q);for(let Z of this.#i(j)){if(Z.textContent===X)continue;Z.textContent=X}}#i(j){let Q=this.element.querySelectorAll(`[data-reactive-text="${j}"]`);return Array.from(Q).filter((X)=>this.#Q(X))}#k(j,Q){let X=this.#a();for(let[Z,$]of Object.entries(X)){let J=Z in j?j[Z]:Q(Z)?.value;if(J===void 0||J===null)continue;let G=String(J);for(let W of Array.isArray($)?$:[$]){if(!_j(W))continue;for(let z of document.querySelectorAll(W)){if(z.textContent===G)continue;z.textContent=G}}}}#a(){let j=this.element.getAttribute("data-reactive-compute-mirror-param");if(!j)return{};try{let Q=JSON.parse(j);return Q&&typeof Q==="object"&&!Array.isArray(Q)?Q:{}}catch{return{}}}#b(j,Q,X,Z,$,J,G){if(this.#L("reactive:before-dispatch",{action:Q,params:this.#c(X),element:this.element},{cancelable:!0}).defaultPrevented)return;let z=Number(Z)||0;if(z>0)return this.#r(j,z,Q,X,J,G);let q=Number($)||0;if(q>0)return this.#e(j,q,Q,X,J,G);return this.#V(Q,X,J,j,G)}#V(j,Q,X,Z,$){let J=this.#Ej(X,Z),G=this.#Rj(j,Z,$);return this.queue=(this.queue??Promise.resolve()).then(()=>this.#Wj(j,Q,J,G)),this.queue}#r(j,Q,X,Z,$,J){this.#C(j);let G=()=>{this.#C(j),this.#V(X,Z,$,j,J)},W=setTimeout(G,Q);j?.addEventListener?.("blur",G,{once:!0}),this.#A.set(j,{timer:W,flush:G})}#C(j){let Q=this.#A.get(j);if(!Q)return;clearTimeout(Q.timer),j?.removeEventListener?.("blur",Q.flush),this.#A.delete(j)}#t(){for(let j of[...this.#A.keys()])this.#C(j)}#e(j,Q,X,Z,$,J){let G=this.#z.get(j)??new Map;if(G.has(X))return;let W=setTimeout(()=>{if(G.delete(X),G.size===0)this.#z.delete(j)},Q);return G.set(X,W),this.#z.set(j,G),this.#V(X,Z,$,j,J)}#jj(){for(let j of this.#z.values())for(let Q of j.values())clearTimeout(Q);this.#z.clear()}#L(j,Q,{cancelable:X=!1}={}){let Z=new CustomEvent(j,{bubbles:!0,composed:!0,cancelable:X,detail:Q});return(this.element.isConnected?this.element:document).dispatchEvent(Z),Z}#Z(j,Q,X,Z){let $=()=>{if(!this.element.isConnected){console.warn("[phlex-reactive] retry() ignored — the reactive root left the DOM");return}return this.#V(j,Q)};this.#L("reactive:error",{action:j,params:X,...Z,retry:$})}#$(j){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",j)}#Qj(){this.element?.removeAttribute?.("data-reactive-error")}#Xj(){let j=document.querySelector("[data-reactive-error-flash]");if(!j?.content)return;let Q=j.getAttribute("data-reactive-error-flash")||"flash",X=document.getElementById(Q);if(!X)return;X.appendChild(j.content.cloneNode(!0))}#Zj(){if(typeof sessionStorage>"u")return Promise.resolve();let j=Number(sessionStorage.getItem(D));if(!Number.isFinite(j)||j<=0)return Promise.resolve();if(!L)L=!0,console.warn(`[phlex-reactive] latency simulator ACTIVE — every action is delayed by ${j}ms. Call PhlexReactive.disableLatencySim() (or clear sessionStorage) to turn it off.`);return new Promise((Q)=>setTimeout(Q,j))}#$j(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#w(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}#Jj(j){if(!j)return[];let Q=[],X=/<turbo-stream\b([^>]*)>/g,Z;while((Z=X.exec(j))!==null){let $=Z[1],J=$.match(/\baction="([^"]*)"/)?.[1]??"?",G=$.match(/\btarget="([^"]*)"/)?.[1];Q.push(G?`${J} → #${G}`:J)}return Q}#Gj(j){let{action:Q,status:X,ms:Z}=j,J=`reactive ${this.element?.id?`#${this.element.id} `:""}${Q} → ${X??"—"} (${Math.round(Z)}ms)`;if(console.groupCollapsed(J),console.log(`params: [${j.paramNames.join(", ")}] + collected: [${j.fieldNames.join(", ")}]`),console.log(`encoding: ${j.encoding}`),j.streams.length)console.log(`streams: ${j.streams.join(" ")}`);console.log(`token: ${j.tokenRefreshed?"refreshed ✓":"unchanged"}`),console.groupEnd()}async#Wj(j,Q,X,Z){let{fields:$,files:J}=this.#Kj(),G=this.#c(Q),W={...$,...G},z=this.#J,q=J.length>0,U=q?this.#xj(z,j,W,J):JSON.stringify({token:z,act:j,params:W}),K=this.#$j()?{action:j,paramNames:Object.keys(G),fieldNames:Object.keys($),encoding:q?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#w()}:null;await this.#Zj();try{if(navigator.onLine===!1){this.#G(X),this.#$("offline"),this.#Z(j,Q,W,{kind:"offline"});return}let Y;try{let A={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#hj()};if(!q)A["Content-Type"]="application/json";let V=this.#yj();if(V)A["X-Pgbus-Connection"]=V;Y=await fetch(this.#bj(),{method:"POST",headers:A,body:U,credentials:"same-origin",signal:AbortSignal.timeout(this.#wj())})}catch(A){if(console.error("[phlex-reactive] action error",A),this.#G(X),A?.name==="TimeoutError"||A?.name==="AbortError"){this.#$("timeout"),this.#Z(j,Q,W,{kind:"timeout"});return}this.#Xj(),this.#$("network"),this.#Z(j,Q,W,{kind:"network"});return}if(K)K.status=Y.status;if(Y.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#G(X),this.#$("redirected"),this.#Z(j,Q,W,{kind:"redirected",status:Y.status});return}if(!Y.ok){let A=await Y.text();if(console.error(`[phlex-reactive] action failed: HTTP ${Y.status}`,A),this.#G(X),(Y.headers.get("Content-Type")||"").includes("turbo-stream")){let V=this.#y(A);if(this.#J=V??this.#J,K)this.#h(K,A,V);window.Turbo.renderStreamMessage(A)}this.#$("http"),this.#Z(j,Q,W,{kind:"http",status:Y.status,body:A});return}let _=Y.headers.get("Content-Type")||"";if(!_.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${_}" — no update applied`),this.#G(X),this.#$("content-type"),this.#Z(j,Q,W,{kind:"content-type",status:Y.status});return}let N=await Y.text(),I=this.#y(N);if(this.#J=I??this.#J,K)this.#h(K,N,I);window.Turbo.renderStreamMessage(N),this.#Qj(),this.#L("reactive:applied",{action:j,params:W,html:N})}catch(Y){console.error("[phlex-reactive] action error",Y),this.#G(X),this.#L("reactive:error",{action:j,params:W,kind:"apply"})}finally{if(Z?.(),K)this.#Gj({...K,ms:this.#w()-K.started})}}#h(j,Q,X){j.streams=this.#Jj(Q),j.tokenRefreshed=X!=null}get#J(){return this.#R??this.tokenValue}set#J(j){this.#R=j}#y(j){let Q=this.element.id;if(!Q)return j.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:X,self:Z}=this.#zj(Q),$=j.match(X);if($)return $[1];let J=j.match(Z);if(J)return J[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#zj(j){let Q=this.#D;if(Q&&Q.id===j)return Q;let X=qj(j);return this.#D={id:j,token:new RegExp(`<turbo-stream\\b[^>]*\\baction="reactive:token"[^>]*\\btarget="${X}"[^>]*\\bdata-reactive-token-value="([^"]+)"`),self:new RegExp(`<turbo-stream\\b[^>]*\\baction="(?:replace|update)"[^>]*\\btarget="${X}"[^>]*>([\\s\\S]*?)</turbo-stream>`)}}#Q(j){return j.closest('[data-controller~="reactive"]')===this.element}#H(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(Q)=>this.#Q(Q)}#Kj(){let j={},Q=[],X=this.#H();return this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((Z)=>{if(!X(Z))return;if(Z.type==="file")for(let $ of Z.files??[])Q.push({name:Z.name,file:$,multiple:Z.multiple});else if(Z.type==="checkbox")j[Z.name]=Z.checked;else if(Z.type==="radio"){if(Z.checked)j[Z.name]=Z.value}else j[Z.name]=Z.value}),this.element.querySelectorAll("[name]:is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])").forEach((Z)=>{if(!X(Z))return;let $=Z.getAttribute("name");if(!$)return;let J=j[$];if(J==null||J==="")j[$]=Z.value??Z.textContent??Z.innerHTML??""}),{fields:j,files:Q}}#P(){if(typeof this.element?.querySelectorAll!=="function")return;let j=0;if(this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((Q)=>{if(!this.#Q(Q))return;if(Q.type==="file")return;if(this.#qj(Q))Q.setAttribute("data-reactive-dirty","true"),j++;else Q.removeAttribute("data-reactive-dirty")}),j>0)this.element.setAttribute("data-reactive-dirty",String(j));else this.element.removeAttribute("data-reactive-dirty")}#qj(j){if(j.type==="checkbox"||j.type==="radio")return j.checked!==j.defaultChecked;if(j.tag==="select"||j.options)return Array.from(j.options??[]).some((Q)=>Q.selected!==Q.defaultSelected);return j.value!==j.defaultValue}#v(){let j=this.element.getAttribute?.("data-reactive-dirty"),Q=Number(j);return Number.isFinite(Q)&&Q>0?Q:0}#Yj(){if(typeof window>"u"||typeof window.addEventListener!=="function")return;this.#Y=(j)=>{if(this.#v()===0)return;return j.preventDefault(),j.returnValue="You have unsaved changes.",j.returnValue},this.#U=(j)=>{if(this.#v()===0)return;if(!(typeof window.confirm==="function"?window.confirm("You have unsaved changes. Leave anyway?"):!0))j.preventDefault?.()},window.addEventListener("beforeunload",this.#Y),window.addEventListener("turbo:before-visit",this.#U)}#Uj(){if(this.#q)this.element.removeEventListener?.("turbo:morph-element",this.#q),this.#q=void 0;if(typeof window<"u"&&typeof window.removeEventListener==="function"){if(this.#Y)window.removeEventListener("beforeunload",this.#Y);if(this.#U)window.removeEventListener("turbo:before-visit",this.#U)}this.#Y=void 0,this.#U=void 0}#Hj(){if(this.element.getAttribute?.("data-reactive-show-targets"))return!0;let j=this.element.querySelectorAll?.(w)??[];for(let Q of j)if(this.#Q(Q))return!0;return!1}#f(){if(typeof this.element?.querySelectorAll!=="function")return;let j=this.#H(),Q=this.element.getAttribute?.("data-reactive-scope")||null,X=new Map,Z=($)=>{if(!X.has($))X.set($,this.#p($,j,Q));return X.get($)};for(let $ of this.element.querySelectorAll(w)){if(!j($))continue;let J=$.getAttribute("data-reactive-show");if(J!==null){let q=Mj(Vj(J),Z);if(q!==null)this.#u($,q,j,Q);continue}let G=$.getAttribute("data-reactive-show-field");if(!G)continue;let W=Z(G);if(W===null)continue;let z=Nj($,W);if(z===null)continue;this.#u($,z,j,Q)}this.#Aj(j,X,Q)}#u(j,Q,X,Z){if(j.hidden=!Q,j.getAttribute("data-reactive-show-disable")!=="true")return;if(typeof j.querySelectorAll!=="function")return;for(let $ of j.querySelectorAll("input[name], select[name], textarea[name]"))if(X($))$.disabled=!Q;if(j.name&&X(j))j.disabled=!Q}#Aj(j,Q,X){let Z=this.#_j();for(let[$,J]of Object.entries(Z)){if(!J||typeof J!=="object"||Array.isArray(J))continue;if(!Q.has($))Q.set($,this.#p($,j,X));let G=Q.get($);if(G===null)continue;let W=()=>G;for(let[z,q]of Object.entries(J)){if(!Oj(z))continue;let U;if(Array.isArray(q)){if(q.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${z} — skipped`);continue}U=q.every((K)=>T(K,W))}else{let K=c(q,G);if(K===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${z} — skipped`);continue}U=K}for(let K of document.querySelectorAll(z))K.hidden=!U}}}#_j(){let j=this.element.getAttribute?.("data-reactive-show-targets");if(!j)return{};try{let Q=JSON.parse(j);if(Q&&typeof Q==="object"&&!Array.isArray(Q))return Q}catch{}return console.warn("[phlex-reactive] malformed data-reactive-show-targets — ignored. "+"Did two reactive_show_targets calls collide on one root? Declare every field in ONE call: reactive_show_targets(mode: { ... }, kind: { ... })"),{}}#p(j,Q,X){let Z=X&&!j.includes("[")?`${X}[${j}]`:j,$=!1,J=null;for(let G of this.element.querySelectorAll(`[name="${Z}"]`)){if(!Q(G))continue;if(G.type==="checkbox")return G.checked?"true":"false";if(G.type==="radio"){if(G.checked)return G.value??"";$=!0;continue}J??=G}if(J)return J.value??"";return $?"":null}#Nj(){if(!this.#j)return;this.element.removeEventListener?.("input",this.#j),this.element.removeEventListener?.("change",this.#j),this.element.removeEventListener?.("turbo:morph-element",this.#j),this.#j=void 0}#Vj(){return!!(this.element.getAttribute?.("data-reactive-filter-input")&&this.element.getAttribute?.("data-reactive-filter-option"))}#Lj(j){let Q=this.element.getAttribute("data-reactive-filter-input");return!!Q&&typeof j.target?.matches==="function"&&j.target.matches(Q)}#m(){if(typeof this.element?.querySelectorAll!=="function")return;let j=this.element.getAttribute("data-reactive-filter-input"),Q=this.element.getAttribute("data-reactive-filter-option");if(!j||!Q)return;let X=this.#H(),Z=[...this.element.querySelectorAll(j)].find(X);if(!Z)return;let $=(Z.value??"").trim().toLowerCase(),J=0;for(let z of this.element.querySelectorAll(Q)){if(!X(z))continue;let q=(z.getAttribute("data-reactive-filter-text")??z.textContent??"").toLowerCase(),U=$!==""&&!q.includes($);if(z.hidden=U,U)z.removeAttribute("data-reactive-highlighted");else J++}let G=this.element.getAttribute("data-reactive-filter-group");if(G)for(let z of this.element.querySelectorAll(G)){if(!X(z))continue;let q=[...z.querySelectorAll(Q)].filter(X);if(q.length===0)continue;z.hidden=q.every((U)=>U.hidden)}let W=this.element.getAttribute("data-reactive-filter-empty");if(W){for(let z of this.element.querySelectorAll(W))if(X(z))z.hidden=J>0}}#Mj(){if(!this.#X)return;this.element.removeEventListener?.("input",this.#X),this.element.removeEventListener?.("turbo:morph-element",this.#X),this.#X=void 0}#xj(j,Q,X,Z){let $=new FormData;$.append("token",j),$.append("act",Q);for(let[G,W]of Object.entries(X))this.#E($,`params[${G}]`,W);let J=this.#Oj(Z);for(let{name:G,file:W,multiple:z}of Z){let U=z||J.has(G)?`params[${G}][]`:`params[${G}]`;$.append(U,W,W.name)}return $}#E(j,Q,X){if(X==null)j.append(Q,"");else if(Array.isArray(X))X.forEach((Z,$)=>this.#E(j,`${Q}[${$}]`,Z));else if(typeof X==="object")for(let[Z,$]of Object.entries(X))this.#E(j,`${Q}[${Z}]`,$);else j.append(Q,String(X))}#Oj(j){let Q=new Map;for(let{name:X}of j)Q.set(X,(Q.get(X)??0)+1);return new Set([...Q].filter(([,X])=>X>1).map(([X])=>X))}#c(j){if(!j)return{};try{return typeof j==="string"?JSON.parse(j):j}catch{return{}}}#Bj(j){return g(j)}#Cj(j){d(j,(Q)=>this.#F(Q))}#F(j){let Q=j.to;if(Q==="@root")return[this.element];if(typeof Q!=="string"||Q==="")return[];if(j.global)return[...document.querySelectorAll(Q)];return[...this.element.querySelectorAll(Q)].filter((X)=>this.#Q(X))}#Pj(j,Q){if(j?.checked!=="keep")return!1;let X=Q?.type;return X==="checkbox"||X==="radio"}#Ej(j,Q){if(!j)return null;let X=this.#Fj(j,Q),Z=[];for(let $ of X){if(j.add_class){let J=j.add_class.filter((G)=>!$.classList.contains(G));if($.classList.add(...J),J.length)Z.push(()=>$.classList.remove(...J))}if(j.remove_class){let J=j.remove_class.filter((G)=>$.classList.contains(G));if($.classList.remove(...J),J.length)Z.push(()=>$.classList.add(...J))}if(j.toggle_class)j.toggle_class.forEach((J)=>$.classList.toggle(J)),Z.push(()=>j.toggle_class.forEach((J)=>$.classList.toggle(J)));if(j.hide)$.hidden=!0,Z.push(()=>$.hidden=!1)}if(j.checked==="keep"&&Q&&"checked"in Q){let $=Q.checked;Z.push(()=>Q.checked=!$)}return Z.length?Z:null}#G(j){if(!j)return;if(!this.element.isConnected)return;for(let Q of j)Q()}#Fj(j,Q){if(j.to==null)return Q?[Q]:[];return this.#F({to:j.to})}#Rj(j,Q,X){this.#Dj(j,Q);let Z=this.#Ij(j,Q,X),$=!1;return()=>{if($)return;$=!0,this.#Tj(j,Q),Z()}}#Dj(j,Q){if(this.#W(Q,j,1),this.#W(this.element,j,1),this.#K.set(j,(this.#K.get(j)??0)+1),this.#x++===0)this.element.setAttribute("aria-busy","true");for(let X of this.#g(j))this.#W(X,j,1)}#Tj(j,Q){this.#W(Q,j,-1),this.#W(this.element,j,-1);let X=(this.#K.get(j)??1)-1;if(X<=0)this.#K.delete(j);else this.#K.set(j,X);if(--this.#x<=0)this.#x=0,this.element.removeAttribute("aria-busy");for(let Z of this.#g(j))this.#W(Z,j,-1)}#W(j,Q,X){if(!j||typeof j.getAttribute!=="function")return;let Z=this.#O.get(j)??new Map,$=(Z.get(Q)??0)+X;if($<=0)Z.delete(Q);else Z.set(Q,$);if(Z.size===0){this.#O.delete(j),j.removeAttribute("data-reactive-busy");return}this.#O.set(j,Z),j.setAttribute("data-reactive-busy",[...Z.keys()].join(" "))}#g(j){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((X)=>X.getAttribute("data-reactive-busy-on")===j&&this.#Q(X))}#Ij(j,Q,X){if(!X||!Q)return()=>{};let Z=this.#kj(X,Q),$=Array.isArray(X.class)?X.class:[],J=[];for(let W of Z){let z=$.filter((q)=>!W.classList.contains(q));if(W.classList.add(...z),z.length)J.push([W,z])}let G=this.#_.get(Q);if(G)G.count++;else if(X.disable||X.text!=null)this.#_.set(Q,{count:1,disabled:Q.disabled,text:Q.textContent,hadText:X.text!=null});if(X.disable)Q.disabled=!0;if(X.text!=null)Q.textContent=X.text;return()=>{for(let[W,z]of J)if(W.isConnected)W.classList.remove(...z);this.#Sj(Q,X)}}#Sj(j,Q){let X=this.#_.get(j);if(!X)return;if(--X.count>0)return;if(this.#_.delete(j),!j.isConnected)return;if(Q.disable)j.disabled=X.disabled;if(X.hadText&&j.textContent===Q.text)j.textContent=X.text}#kj(j,Q){if(j.to==null)return Q?[Q]:[];return this.#F({to:j.to})}#bj(){return this.#d??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#wj(){if(this.#M!=null)return this.#M;let j=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,Q=Number(j);return this.#M=Number.isFinite(Q)&&Q>0?Q:30000}#hj(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#yj(){return document.querySelector("pgbus-stream-source[connection-id]")?.getAttribute("connection-id")||document.querySelector('meta[name="pgbus-connection-id"]')?.content||null}}export{Dj as resetReactiveDefers,n as registerReactiveVisit,i as registerReactiveToken,Gj as registerReactiveOffline,a as registerReactiveJs,$j as registerReactiveDismiss,r as registerReactiveDefer,k as registerReactiveActions,Tj as pendingDeferVia,qj as escapeRegExp,Wj as enableLatencySim,zj as disableLatencySim,hj as default,Yj as checkReactiveRegistration,bj as __resetReactiveRegistrationForTest,Sj as __resetReactiveOfflineForTest,kj as __resetReactiveLatencyForTest,Ij as __resetReactiveDismissForTest,wj as __markReactiveConnectedForTest,D as LATENCY_KEY};
2
2
 
3
- //# debugId=CA27DF71E8491EB164756E2164756E21
3
+ //# debugId=B4ECABAC7819655164756E2164756E21
4
4
  //# sourceMappingURL=reactive_controller.min.js.map