phlex-reactive 0.14.1 → 0.14.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da91cf678610a49eedda39afbad34c05d879bd4a37b30d6a722bb7400178291c
4
- data.tar.gz: ce7e5870c7e8a9e33d0f61a05b1b18da1e3adea553a7ed2c7402b72fbfda4110
3
+ metadata.gz: f4b8ab0285b176f4fab5221687a3d3364e2311eaa4c08c091eef07763cf22a8e
4
+ data.tar.gz: 9072c2d1b802438c7f39c694753308020d65e9a20e38c1ee4f730351b25de49d
5
5
  SHA512:
6
- metadata.gz: 36dd243fdc59218e08608ced77ec11aa152a476e483269408b5713c75f9c72c4386b2436143d10ba5d18f5c0456a01f9ee1275d9143678b1feb7c22123dc0b6e
7
- data.tar.gz: f0f0185d456b4d01db104731e93b56e60dafd8dc6bda77b4aec581290baa067297eb318b5004dfb3d30004d21afe2647f479574786829c98a9f2d0727a32f9a3
6
+ metadata.gz: fc1c7ffa6b616154f5ce897f256fbd6d8be501948dc63295163b831b0578c55908c9187e4ac461d00dc2dd4d7481090672c654b28d30f9894a1ec65f079579d2
7
+ data.tar.gz: f889193d4bc9bdb381446d93bfcf5ddf3ac7047b84250787a63f83c61844712ba1c511529792381511570740fff8f37e42c385d14fbecaad9809e52ad3064b35
data/CHANGELOG.md CHANGED
@@ -6,6 +6,30 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ### Added
10
+
11
+ - **`on_client(…, detail: { success: true })` — run ops only when the event's
12
+ payload qualifies (#346).** A binding can require top-level `event.detail`
13
+ keys to strictly equal JSON scalars, so `on_client("turbo:submit-end",
14
+ js.check_group("ids[]", false), detail: { success: true })` clears a bulk
15
+ selection after a successful submit and keeps it after a failed one. A
16
+ missing detail or key never matches; a miss runs no confirm and no
17
+ `preventDefault`. Each binding record carries its own filter, so two bindings
18
+ on one element can split success and failure. A non-scalar value, an empty
19
+ Hash, or `detail:` with `once:` raises at render. Records without `detail`
20
+ are byte-identical.
21
+
22
+ ### Fixed
23
+
24
+ - **A `checked:`-only `reactive_show_targets` entry hides at zero boxes
25
+ (#348).** `"#bulk-bar" => { if: { "ids[]" => { checked: 1.. } } }` was left
26
+ visible once the owning root held no box of the group (the last ticked row
27
+ stream-removed, or a morph that emptied the list), while
28
+ `reactive_group_targets` beside it wrote 0. A target made only of `checked_*`
29
+ terms is now always evaluated, as the in-root `reactive_show` and the server
30
+ first paint already were. A target with any value term keeps the skip when
31
+ none of its fields is owned.
32
+
9
33
  ## [0.14.1] - 2026-10-07
10
34
 
11
35
  ### Added
data/README.md CHANGED
@@ -677,7 +677,7 @@ Use in controllers: `render turbo_stream: Counter.replace(counter)`.
677
677
  | `on(:save, loading: { disable: true, class: "opacity-50", text: "…" })` | Full loading form: `disable:`, a loading `class:` (on the trigger or a `to:` target), a `text:` swap. Reverts on settle. |
678
678
  | `busy_on(:save)` | Mark any element so it carries `data-reactive-busy` **only while `save` is in flight** — a spinner styled with pure CSS, zero Ruby. See [Loading states](#declarative-loading-states-loading--disable_with). |
679
679
  | `on(:action, once: true)` | Fire at most once, then unbind (Stimulus's native `:once`). |
680
- | `on_client(:click, js.toggle("#menu"))` | **Client-only** trigger: applies declared DOM ops with ZERO round trip — no token, no POST, ever. Takes the same `window:`/`once:`/`outside:` modifiers. See [Client-only ops](#client-only-ops-on_client--js--zero-round-trips). |
680
+ | `on_client(:click, js.toggle("#menu"))` | **Client-only** trigger: applies declared DOM ops with ZERO round trip — no token, no POST, ever. Takes the same `window:`/`once:`/`outside:` modifiers, plus `detail:` (run only when `event.detail` carries the listed values). See [Client-only ops](#client-only-ops-on_client--js--zero-round-trips). |
681
681
  | `js` | The immutable op builder behind `on_client`: `show`/`hide`/`toggle` (the `hidden` attribute, with an optional `transition:` and `expanded:`), `add_class`/`remove_class`/`toggle_class`, `set_attr`/`remove_attr`/`toggle_attr` (allowlisted names; `toggle_attr` also flips between two values), `focus`/`focus_first`, `text` (set `textContent` — XSS-safe), `dispatch`, `submit` (requestSubmit the target's own form, optionally through a `submitter:`), `paste_into` (read the clipboard into a field, gesture-gated), `check_group` (tick or untick a checkbox group, then re-sync its bindings), and `persist_state`/`persist_clear` (the `reactive_persist` draft) — chainable. |
682
682
  | `reactive_field(:param, **attrs)` | The attribute hash that binds a control to an action param (no magic `name:`) — spread onto any control: `input(**reactive_field(:value, value: @record.name))`, `select(**reactive_field(:status)) { … }`. |
683
683
  | `reactive_text(:name, initial)` | Mirror a compute output (or a declared input) into a **text node** — a live preview heading, a character counter, `"Hello, {name}"` — via `textContent` (XSS-safe). The text sibling of `reactive_field`; carries no `name`, so it's never POSTed. See [Client-side computes](#client-side-computes-reactive_compute--reactive_text). |
@@ -1273,6 +1273,24 @@ button(**on_client(:click, js
1273
1273
  modifiers: the dropdown above closes on any click outside the component, and
1274
1274
  window-bound triggers never `preventDefault`, so links elsewhere keep working.
1275
1275
 
1276
+ **Gate on the event's payload with `detail:` (#346).** A Hash of top-level
1277
+ `event.detail` keys to the value each must strictly equal (`===`). Values are
1278
+ JSON scalars only (`true`/`false`, `nil`, a String, a number); anything else
1279
+ raises at render. A missing `event.detail` or key never matches, and a miss is
1280
+ a complete no-op: no `confirm:`, no `preventDefault`. A bulk form whose
1281
+ successful reply only swaps a flash clears its selection on success, and keeps
1282
+ it after a failed (4xx/5xx) submit for the retry:
1283
+
1284
+ ```ruby
1285
+ form(action: "/posts/bulk", method: "post",
1286
+ **on_client("turbo:submit-end", js.check_group("ids[]", false), detail: { success: true })) { … }
1287
+ ```
1288
+
1289
+ It is not Turbo-specific: an app's own `upload:done` event with `{ ok: true }`
1290
+ filters the same way. `detail:` does not combine with `once:` (raises): Stimulus
1291
+ removes a `:once` listener on its first event, so a first non-matching event
1292
+ would leave the binding dead.
1293
+
1276
1294
  **Several bindings on one element (#271).** Each `on_client` call emits one
1277
1295
  self-describing **binding record** — its descriptor, flags, `confirm:` and ops —
1278
1296
  so two calls compose through `mix`. The descriptors token-join; the records
@@ -1500,7 +1518,12 @@ reactive_show_targets(
1500
1518
  The fold is identical to an in-root `reactive_show` (each term reads its own
1501
1519
  field; a missing owned field reads as blank — fail-closed). Every referenced
1502
1520
  field must be owned by the declaring root; a target whose fields are all
1503
- unowned is left alone, like the single-field skip.
1521
+ unowned is left alone, like the single-field skip. A target made only of
1522
+ `checked:` terms is the exception: a group with no owned boxes counts 0, so
1523
+ `"#bulk-bar" => { if: { "ids[]" => { checked: 1.. } } }` hides once the last
1524
+ box is removed, as an in-root `reactive_show` does. A target that mixes a
1525
+ `checked:` term with a value field keeps the skip while none of its fields is
1526
+ owned.
1504
1527
 
1505
1528
  ### Bulk selection (`reactive_select_all`, `reactive_count`, `reactive_enable`)
1506
1529
 
@@ -1,4 +1,4 @@
1
- import{Controller as Ae}from"@hotwired/stimulus";import{confirmResolver as U}from"phlex/reactive/confirm";function Ee(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:visit"])return;e["reactive:visit"]=function(){let t=this.getAttribute("data-url");if(t)window.Turbo.visit(t,{action:"advance"})}}function Fe(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:token"])return;e["reactive:token"]=function(){let t=this.getAttribute("data-reactive-token-value"),r=this.getAttribute("target");if(!t||!r)return;let n=document.getElementById(r);if(n)n.setAttribute("data-reactive-token-value",t)}}function ke(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:js"])return;e["reactive:js"]=function(){let t=W(this.getAttribute("data-reactive-ops"));if(!t.length)return;let r=this.getAttribute("target"),n=this.getAttribute("data-reactive-verbose")==="true",i=r?document.getElementById(r):null;if(r&&!i){if(n)b("devtools",(o)=>o.missingRoot(r));return}q(t,(o)=>Qe(o,i),n?(o,a)=>b("devtools",(s)=>s.diagnoseStream(o,a,i)):void 0)}}function Le(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:defer"])return;e["reactive:defer"]=function(){b("defer",(t)=>t.streamAction(this))}}var J=!1,D=null;function Re(){if(J)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;J=!0,document.addEventListener("turbo:before-stream-render",(e)=>{if(D)D(e,m.get("effects"));else m.get("effects")?.wrap(e)})}function oe(e){D=e}var K=!1;function z(e){return e===document.activeElement&&(e.localName==="input"||e.localName==="textarea")&&!e.hasAttribute("data-reactive-morph-value")&&!!e.closest('[data-controller~="reactive"]')}function xe(){if(K)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;K=!0,document.addEventListener("turbo:before-morph-element",(e)=>{let t=e.target,r=e.detail?.newElement;if(!r||e.defaultPrevented||t.localName!=="input"||!z(t))return;let n=r.getAttribute("value");if(n==null)t.removeAttribute("value");else if(t.getAttribute("value")!==n)t.setAttribute("value",n)}),document.addEventListener("turbo:before-morph-attribute",(e)=>{if(e.detail?.attributeName==="value"&&z(e.target))e.preventDefault()})}var Pe="__materialize",H=!1;function Ie(){if(H)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;H=!0;let e=()=>{let t=document.documentElement;if(typeof t?.toggleAttribute!=="function")return;t.toggleAttribute("data-reactive-offline",globalThis.navigator?.onLine===!1)};e(),window.addEventListener("online",e),window.addEventListener("offline",e)}var Ne="phlex-reactive:latency";function ae(){return typeof sessionStorage<"u"&&Boolean(sessionStorage.getItem(Ne))}function B(){if(typeof document>"u")return;if(!m.has("devtools")&&!v.get("devtools")[1])return;let e=document.querySelector?.('meta[name="phlex-reactive-env"]')?.content==="development";if(e||ae())b("devtools",(t)=>e&&t.attach())}var ce="data-reactive-active",_=0;function ue(){if(_++,_===1)fe("reactive:busy")}function le(){if(_===0)return;if(_--,_===0)fe("reactive:idle")}function Et(){return _}function Ft(){_=0,(typeof document<"u"?document.documentElement:null)?.removeAttribute?.(ce)}function fe(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.toggleAttribute==="function")t.toggleAttribute(ce,_>0);if(typeof document.dispatchEvent==="function"&&typeof CustomEvent==="function")document.dispatchEvent(new CustomEvent(e,{detail:{count:_}}))}var de="data-reactive-requests";function he(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.setAttribute!=="function"||!Oe(t))return;let r=Me(t);r[e]=(Number(r[e])||0)+1,t.setAttribute(de,JSON.stringify(r))}function Oe(e){return e.hasAttribute?.("data-reactive-verbose")||!!document.querySelector?.('[data-reactive-verbose="true"]')}function Me(e){try{let t=JSON.parse(e.getAttribute(de));if(t&&typeof t==="object")return{action:0,defer:0,...t}}catch{}return{action:0,defer:0}}function G(){Ee(),Fe(),ke(),Le(),Re(),xe(),Ie(),B()}function Ce(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var me=Symbol.for("phlex-reactive.core");if(globalThis[me])console.error("[phlex-reactive] the client was loaded twice. Import EITHER phlex/reactive/reactive_controller (the default, "+"everything in one file) OR phlex/reactive/core (features on demand), not both — each carries its own state.");globalThis[me]=!0;var pe=!1;function De(){if(pe)return;if(typeof document>"u")return;let e=document.querySelectorAll('[data-controller~="reactive"]');if(!e||e.length===0)return;console.warn("[phlex-reactive] found "+e.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.')}if(typeof window<"u"&&typeof document<"u"){let e=()=>setTimeout(De,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",e,{once:!0});else e()}var qe=new Set(["href","src","srcdoc","action","formaction","xlink:href","style"]);function $e(e){let t=String(e).toLowerCase();return t.startsWith("on")||qe.has(t)}var I=new WeakMap;function Be(e,t,r){let[n,i,o]=t;I.get(e)?.(),e.classList.add(n,i),r();let a=!1,s=requestAnimationFrame(()=>{if(a)return;e.classList.remove(i),e.classList.add(o)}),c=(h)=>{if(a||h&&h.target!==e)return;a=!0,I.delete(e),clearTimeout(l),globalThis.cancelAnimationFrame?.(s),e.removeEventListener("animationend",c),e.removeEventListener("transitionend",c),e.classList.remove(n,i,o)};I.set(e,c),e.addEventListener("animationend",c),e.addEventListener("transitionend",c);let l=setTimeout(c,We(e))}function We(e){let t=0;try{let r=getComputedStyle(e);for(let n of["transition","animation"]){let[i,o]=["Duration","Delay"].map((s)=>String(r[n+s]).split(",").map((c)=>parseFloat(c)*(/ms/.test(c)?1:1000)||0)),a=String(r[n+"IterationCount"]).split(",").map((s)=>/inf/.test(s)?1/0:parseFloat(s)>=0?parseFloat(s):1);for(let s=0;s<i.length||s<o.length||s<a.length;s++){let c=i[s%i.length]*a[s%a.length]||0;t=Math.max(t,c+o[s%o.length])}}}catch{}return Math.min(Math.max(t+50,350),5000)}var je=":is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])",Ue=new Set(["lexxy-editor","trix-editor"]);function Je(e){return Ue.has(e.localName)?typeof e.value==="string":!0}var V=Object.freeze({show:(e,t,r)=>N(e,!1,t,r),hide:(e,t,r)=>N(e,!0,t,r),toggle:(e,t,r)=>N(e,!e.hidden,t,r),add_class:(e,t)=>e.classList.add(...t.classes??[]),remove_class:(e,t)=>e.classList.remove(...t.classes??[]),toggle_class:(e,t)=>(t.classes??[]).forEach((r)=>e.classList.toggle(r)),set_attr:(e,t)=>{if(O(t.name))e.setAttribute(t.name,t.value??"")},remove_attr:(e,t)=>{if(O(t.name))e.removeAttribute(t.name)},toggle_attr:(e,t)=>{if(!O(t.name))return;if(Array.isArray(t.values)){let[r,n]=t.values;e.setAttribute(t.name,e.getAttribute(t.name)===r?n:r)}else if(e.hasAttribute(t.name))e.removeAttribute(t.name);else e.setAttribute(t.name,"")},focus:(e)=>e.focus?.(),focus_first:(e)=>Ve(e)?.focus?.(),text:(e,t)=>{let r=String(t.value??"");if(e.textContent!==r)e.textContent=r},check_group:(e,t)=>{let r=t.global?document.querySelectorAll('[data-controller~="reactive"]'):[e];for(let n of r)b("bindings",(i)=>i.checkGroup(n,t.group,t.checked))},dispatch:(e,t)=>{e.dispatchEvent(new CustomEvent(t.name,{bubbles:!0,composed:!0,detail:t.detail??{}}))},submit:(e,t,r)=>{let n=Ke(e);if(!n)return;let i=null;if(t?.submitter!=null&&typeof r==="function"){if(i=r({...t,to:t.submitter})[0]??null,!(i?.form===n&&(i.type==="submit"||i.type==="image")))console.warn(`[phlex-reactive] submitter ${t.submitter} is not a submit control of the form — ignored`),i=null}i?n.requestSubmit?.(i):n.requestSubmit?.()},paste_into:(e)=>ze(e),persist_state:(e,t)=>b("persist",(r)=>r.writeState(e,t.state)),persist_clear:(e)=>b("persist",(t)=>t.clearRoot(e))});function Ke(e){if(e?.tagName==="FORM")return e;return e?.form??e?.closest?.("form")??null}function ze(e){let t=globalThis.navigator?.clipboard;if(typeof t?.readText!=="function")return;t.readText().then((r)=>{if(!r)return;if(e.value=r,typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}));e.focus?.()}).catch(()=>{})}function He(e,t,r){if(r?.transition)Be(e,r.transition,()=>e.hidden=t);else e.hidden=t}function N(e,t,r,n){if(He(e,t,r),r?.expanded==null||typeof n!=="function")return;for(let i of n({...r,to:r.expanded}))i.setAttribute?.("aria-expanded",String(!t))}function O(e){if(!$e(e))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(e)} — skipped`),!1}var Ge='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Ve(e){return e.querySelectorAll?.(Ge)?.[0]??null}function W(e){if(Array.isArray(e))return e;if(typeof e!=="string")return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}var Y=Object.freeze({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"}),X=Object.freeze(["meta","ctrl","alt","shift"]);function j(e,t,r){let n=e.split("+");for(let a of X)if(n.includes(a)!==Boolean(t[`${a}Key`]))return!1;let i=n.find((a)=>!X.includes(a));if(i===void 0||typeof t.key!=="string")return!0;let o=r&&Object.hasOwn(r,i)?r[i]:Object.hasOwn(Y,i)?Y[i]:/^[a-z0-9]$/.test(i)?i:null;return typeof o==="string"&&o.toLowerCase()===t.key.toLowerCase()}function Ye(e){if(Array.isArray(e))return[{ops:e,legacy:!0}];if(e&&typeof e==="object")return[e];if(typeof e!=="string")return[];let t=e.trim();if(t.startsWith("["))return[{ops:W(t),legacy:!0}];let r=[];for(let n of t.split(" ")){if(n==="")continue;let i=null;try{i=JSON.parse(n)}catch{i=null}if(i&&typeof i==="object"&&!Array.isArray(i))r.push(i);else console.warn(`[phlex-reactive] malformed on_client binding record ${JSON.stringify(n)} — skipped`)}return r}function Z(e,t,r){if(e.legacy)return!0;let n=e.on;if(typeof n!=="string"||n==="")return!1;let i=n.indexOf(".");if(t.type!==(i<0?n:n.slice(0,i)))return!1;if(Boolean(e.window)!==_e(t.currentTarget))return!1;return i<0||r===null||j(n.slice(i+1),t,r)}var Q=new WeakMap;function Xe(e,t,r){if(!r.once)return!1;let n=t.currentTarget??e.element,i=Q.get(e);if(!i)i=new WeakMap,Q.set(e,i);let o=i.get(n);if(!o)o=new Set,i.set(n,o);let a=t.params?.ops,c=(n===globalThis.window?`${typeof a==="string"?a:JSON.stringify(a??null)}|`:"")+JSON.stringify(r);if(o.has(c))return!0;return o.add(c),!1}var ee=new WeakMap;function Ze(e,t){if(e===null||typeof e!=="object")return!1;let r=e.params?.ops,n=typeof r==="string"?r:JSON.stringify(r??null),i=ee.get(e);if(!i)i=new WeakMap,ee.set(e,i);let o=i.get(t);if(!o)o=new Map,i.set(t,o);let a=o.get(e.currentTarget);if(!a)a=new Set,o.set(e.currentTarget,a);if(a.has(n))return!0;return a.add(n),!1}function q(e,t,r){for(let n of e){if(!Array.isArray(n))continue;let[i,o={}]=n;if(!Object.hasOwn(V,i)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(i)} — skipped`);continue}let a=t(o);if(a.length===0&&r)r(i,o);for(let s of a)V[i](s,o,t)}}function Qe(e,t){let r=e.to;if(t){if(r==="@root")return[t];if(typeof r!=="string"||r==="")return[];if(e.global)return[...document.querySelectorAll(r)];return[...t.querySelectorAll(r)]}if(typeof r!=="string"||r===""||r==="@root")return[];return[...document.querySelectorAll(r)]}function et(e){let t=e.getAttribute?.("data-reactive-persist");return Boolean(t)&&t!=="off"}function ge(e){return["defer-token","defer-src","lazy-on","lazy-visible"].some((t)=>e.getAttribute?.(`data-reactive-${t}`)!=null)}function tt(e){return(e.getAttribute?.("data-action")??"").includes("reactive#trackDirty")||e.getAttribute?.("data-reactive-clipboard")!=null||e.querySelector?.('[data-action*="reactive#trackDirty"],[data-reactive-clipboard]')!=null}function rt(e){return["show-targets","group-targets","on-complete","filter-input","tags-field"].some((t)=>e.getAttribute?.(`data-reactive-${t}`)!=null)||(e.querySelectorAll?.("[data-reactive-show-field], [data-reactive-show]")??[]).length>0||e.querySelector?.("[data-reactive-nested-json], [data-reactive-nested-list], [data-reactive-confirm-when-param], [data-reactive-enable], [data-reactive-select-all], [data-reactive-count]")!=null}function nt(e){return e.getAttribute?.("data-reactive-compute-inputs-param")!=null}var it=[["persist",[et,null,null,!0]],["defer",[ge,null]],["form",[tt,null]],["bindings",[rt,null,null,!0]],["compute",[nt,null,null,!0]],["effects",[(e)=>["enter","update","exit"].some((t)=>e.getAttribute?.(`data-reactive-effect-${t}`)!=null),null]],["hints",[(e)=>e.querySelector?.("[data-reactive-optimistic-param], [data-reactive-busy-param], [data-reactive-loading-param]")!=null,null]],["devtools",[(e)=>e.getAttribute?.("data-reactive-debug")==="true",null]]],v=new Map(it),te=new Map,m=new Map,st=new Map;function w(e,t,r){ye.set(e,[t,r]),ot(e)}var ye=new Map;function ot(e){let t=v.get(e),[r,n]=ye.get(e);t[1]=r,t[2]=n}function kt(e,t){t.install?.(F),m.set(e,t),st.set(e,t)}function be(e){let t=[];for(let[r,[n]]of v){if(!n||m.has(r))continue;try{if(e.some((i)=>n(i)))t.push(r)}catch{}}return t}function ve(e){return E(e).catch((t)=>R(e,"load",t))}function E(e){let t=te.get(e);if(!t)t=(v.get(e)[1]??(()=>Promise.reject(Error("this entry has no way to import it"))))().then((n)=>(n.install?.(F),m.set(e,n),n)),te.set(e,t);return t}var re=new Set;function R(e,t,r){let n=e+t;if(re.has(n))return;re.add(n),console.error(`[phlex-reactive] the "${e}" feature module (phlex/reactive/features/${e}) is unavailable: ${t}. If you bundle or vendor the client, alias or pin phlex/reactive/features/* (README: esbuild / webpack / bun).`,r)}function b(e,t){let r=m.get(e);if(r)return t(r);E(e).then(t,(n)=>R(e,"load",n))}var at=1e4;function M(){let e=Number(globalThis.document?.head?.querySelector?.('meta[name="phlex-reactive-feature-timeout"]')?.content);return Number.isFinite(e)&&e>0?e:at}function Lt(){return[...v.keys()]}var ne=Promise.resolve();function ie(e,t,r){let n=F.waiting.get(e);if(n&&n[t]===r)delete n[t]}var F={enter:ue,exit:le,count:he,waiting:new WeakMap};var k=Symbol.for("phlex-reactive.early"),ct=1e4,ut=1500,_e=(e)=>e!=null&&(e===globalThis.window||e.window===e);function C(){return globalThis[k]??={queue:[],connected:new WeakSet},globalThis[k]}function lt(){let e=Number(globalThis.document?.querySelector?.('meta[name="phlex-reactive-early-ttl"]')?.content);return Number.isFinite(e)&&e>0?e:ct}function ft(e){let t={};for(let{name:r,value:n}of Array.from(e.attributes??[])){let i=/^data-reactive-(.+)-param$/i.exec(r);if(!i)continue;let o;try{o=JSON.parse(n)}catch{o=n}t[i[1].replace(/[-_]([a-z0-9])/g,(a,s)=>s.toUpperCase())]=o}return t}function dt(e,t,r){return{[k]:!0,type:e.type,detail:e.detail,target:e.target,currentTarget:r?t.ownerDocument.defaultView:t,params:ft(t),key:e.key,code:e.code,metaKey:e.metaKey,ctrlKey:e.ctrlKey,altKey:e.altKey,shiftKey:e.shiftKey,button:e.button,submitter:e.submitter,bubbles:e.bubbles,timeStamp:e.timeStamp,defaultPrevented:e.defaultPrevented,preventDefault(){},stopPropagation(){},stopImmediatePropagation(){}}}var x=new WeakMap;function ht(e,{token:t,type:r,method:n,filter:i,win:o},a){let s=x.get(e);if(!s)x.set(e,s=new Map);let c=o?`${t} ${a}`:t;if(s.has(c))return!1;return s.set(c,{type:r,method:n,filter:i,win:o,params:a,armed:!0}),!0}function se(e,t,r,n){if(e?.[k])return!1;let i=_e(e?.currentTarget),o=i?n:e?.currentTarget,a=pt(e,o,i?`@${t}`:t),s=x.get(o),c=i&&JSON.stringify(e.params);for(let l of s?.values()??[]){if(!l.armed||l.method!==t||l.type!==e.type||Boolean(l.win)!==i)continue;if(i&&l.params!==c)continue;if(l.filter&&!j(l.filter,e,r))continue;return l.armed=!1,!0}return a}var L=new WeakMap;function mt(e,t,r){let n=L.get(e);if(!n)L.set(e,n=new Map),setTimeout(()=>L.delete(e));let i=n.get(t)??{};n.set(t,i),i[r]=(i[r]??0)+1}function pt(e,t,r){let n=e&&L.get(e)?.get(t);if(!n?.[r])return!1;return n[r]-=1,!0}class we extends Ae{static values={token:String};#v;#_=new Map;#u=new Map;#Q;#L;#j;#R=0;#l=new Map;#x=new WeakMap;#w;featuresReady=ne;#t=new Map;#P=new Set;#f=!1;#r=null;#d=new Map;#S=new Map;#h=new Map;#m=0;#U;#Ne=0;#Oe=0;connect(){if(pe=!0,C().connected.add(this.element),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-token-value")!=null||ge(this.element))this.#w=(e)=>{if(e.target!==this.element)return;this.#J(!0)},this.element.addEventListener?.("turbo:morph-element",this.#w);this.#m++,this.featuresReady=ne,this.#J(),this.#ie()}#Me(e){}#Ce(e,t,r,n){}#De(){}#qe(e,t){}#J(e){{let t=this.#m,r=[];for(let[o,[a]]of v){if(!a||this.#P.has(o))continue;let s=m.get(o);if(s&&!s.connect)continue;try{if(a(this.element))r.push(o)}catch(c){this.#p(o,"detect",c)}}if(r.length===0)return;for(let o of r)this.#P.add(o);if(!this.#f&&r.every((o)=>m.has(o))){for(let o of r)this.#I(t,o,m.get(o),e);return}for(let o of r){let a=this.#ee(t,o),s=[];for(let l of v.keys()){if(l===o)break;if(this.#h.has(l))s.push(this.#h.get(l))}let c=Promise.all(s).then(()=>a).then((l)=>l&&this.#I(t,o,l,e));if(this.#h.set(o,c),v.get(o)[3])this.#r=c}let n=this.#r;n?.then(()=>{if(this.#r===n)this.#r=null}),this.#f=!0;let i=Promise.all(this.#h.values()).then(()=>{if(this.featuresReady===i)this.#f=!1});this.featuresReady=i}}#ee(e,t){{let r=()=>e===this.#m;return this.#te(t),new Promise((n)=>{let i=!1,o=setTimeout(()=>{if(this.#d.delete(o),i=!0,r())this.#p(t,"timeout",Error(`not loaded after ${M()} ms`));n(null)},M());this.#d.set(o,n);let a=()=>{clearTimeout(o),this.#d.delete(o)};E(t).then((s)=>{if(a(),i)queueMicrotask(()=>this.#I(e,t,s));else n(s)},(s)=>{if(a(),r())this.#p(t,"load",s);n(null)})})}}#te(e){{let t=v.get(e)[2];if(!t)return;let r={};try{this.#S.set(e,[t(this.element,r),r]),F.waiting.set(this.element,{...F.waiting.get(this.element),[e]:r})}catch(n){this.#p(e,"detect",n)}}}#K(e,t){{let[r,n]=this.#S.get(e)??[];if(this.#S.delete(e),!t)ie(this.element,e,n);try{r?.()}catch(i){console.error(`[phlex-reactive] the "${e}" feature module failed to stop waiting`,i)}return n}}#I(e,t,r,n){{if(e!==this.#m)return;let i=this.#K(t);try{r.connect?.(this,this.#e(),n,i),this.#t.set(t,r)}catch(o){this.#p(t,"connect",o)}}}#e(){return this.#U??={emit:(e,t,r)=>this.#i(e,t,r),reseed:()=>this.#re(),proceed:(e,t,r)=>this.#O(e,t,r),forgetToken:()=>{this.#v=void 0},owns:(e)=>this.#F(e),ownership:()=>this.#D(),opTargets:(e)=>this.#W(e),diagnose:(e,t)=>this.#B(e,t),applyOps:(e,t)=>q(e,(r)=>this.#W(t!=null&&r.to==null?{...r,to:t}:r),(r,n)=>this.#B(`client op "${r}"`,n)),listnavOptions:(e)=>this.#y(e),collectFields:()=>this.#Y(),confirm:(e,t)=>Promise.resolve().then(()=>U(e,t)).catch(()=>!1)},this.#U}#re(){this.#t.get("form")?.scan(this,this.#e()),this.#t.get("bindings")?.reseed(this),this.#t.get("compute")?.seed(this)}#p(e,t,r){if(R(e,t,r),this.#n("feature"),t==="load"&&this.element.getAttribute?.("data-reactive-defer-pending"))this.element.removeAttribute("data-reactive-defer-pending"),this.element.removeAttribute("aria-busy");this.#i("reactive:error",{kind:"feature",feature:e,phase:t,error:r})}#ne(){{this.#m++;for(let[t,r]of this.#d)clearTimeout(t),r(null);this.#d.clear();for(let t of[...this.#S.keys()]){let r=this.#K(t,!0),n=this.element;b(t,(i)=>{i.abandon?.(n,r),ie(n,t,r)})}this.#P.clear(),this.#h.clear(),this.#f=!1,this.#r=null;let e=[...this.#t];this.#t.clear();for(let[t,r]of e)try{r.disconnect?.(this,this.#e())}catch(n){console.error(`[phlex-reactive] the "${t}" feature module failed to disconnect`,n)}}}#ie(){if(this.element.setAttribute?.("data-reactive-connected",""),this.element.isConnected)this.element.dispatchEvent?.(new CustomEvent("reactive:connect",{bubbles:!0,composed:!0,detail:{id:this.element.id}}));this.#se()}#N=new Set;#se(){let{queue:e}=C();if(e.length===0)return;let t=[];for(let i=e.length-1;i>=0;i--){let{root:o}=e[i];if(o===this.element||!o.isConnected)t.unshift(...e.splice(i,1))}let r=lt(),n=new Map;for(let i of t){let o=n.get(i.event)??[new Set,new Set];n.set(i.event,o);let a=o[+!!i.win];if(a.has(i.el))continue;a.add(i.el);let s=i.win?Math.min(ut,r):r,c=i.root!==this.element?"its root left the page before a controller connected":performance.now()-i.at>s?`it is older than the ${s} ms ${i.win?"window-trigger":"early-event"} TTL`:i.el.isConnected&&this.element.contains(i.el)?null:"its element left the root before the controller connected";if(c){if(this.#$())console.warn(`[phlex-reactive] dropped an early "${i.event.type}" trigger: ${c}`);continue}this.#oe(i)}}#oe({event:e,el:t,descs:r,win:n}){let i=dt(e,t,n),o=this.application?.schema?.keyMappings,a=(t.getAttribute("data-action")??"").split(/\s+/),s=n?this.element:t;for(let c of r){if(!a.includes(c.token))continue;if(c.filter&&!j(c.filter,e,o))continue;if(/#\w+.*:once\b/.test(c.token)){if(!ht(s,c,n&&JSON.stringify(i.params)))continue;this.#N.add(s)}if(mt(e,s,n?`@${c.method}`:c.method),c.method==="runOps")this.runOps(i);else this.dispatch(i)}}disconnect(){if(this.#ne(),this.#fe(),this.#he(),this.#w)this.element.removeEventListener?.("turbo:morph-element",this.#w);C().connected.delete(this.element),this.element.removeAttribute?.("data-reactive-connected");for(let e of this.#N)x.delete(e);this.#N.clear()}dispatch(e){if(se(e,"dispatch",this.application?.schema?.keyMappings,this.element))return;let{action:t,params:r,debounce:n,throttle:i,confirm:o,confirmWhen:a,outside:s,window:c,optimistic:l}=e.params;if(!t)return;let h=e.params.busy??e.params.loading;if(s&&this.element.contains(e.target))return;let d=e.currentTarget??e.target;if(!c&&!this.#Ee(l,d))e.preventDefault();if(t===Pe){let y=()=>{{let T=this.#t.get("defer");if(T)return T.materialize(this)}if(this.tokenValue)return this.#O(d,t,"{}")};return this.#f?this.featuresReady.then(y):y()}let f=this.#z(o,a),g=()=>this.#O(d,t,r,n,i,l,h);if(!f)return g();if(f instanceof Promise)return f.then((y)=>y?this.#T(y,d,g):g());this.#T(f,d,g)}#T(e,t,r){return Promise.resolve().then(()=>U(e,{el:t})).catch(()=>!1).then((n)=>{if(n)r()})}#z(e,t){if(e)return e;if(!t)return null;{let r=m.get("bindings");if(r)return r.confirmMessage(this,this.#e(),t);return this.#H("bindings").then((n)=>n&&n.confirmMessage(this,this.#e(),t))}}#H(e){{let t;return Promise.race([E(e).catch((r)=>(R(e,"load",r),null)),new Promise((r)=>t=setTimeout(()=>r(null),M()))]).finally(()=>clearTimeout(t))}}runOps(e){if(se(e,"runOps",this.application?.schema?.keyMappings,this.element))return;if(Ze(e,this))return;let t=e.params??{},r=e.currentTarget??e.target,n=Ye(t.ops),i=n.filter((a)=>Z(a,e,null)),o=i.length<=1?i:i.filter((a)=>Z(a,e,this.application?.schema?.keyMappings));if(o.length===0&&n.length>0){if(this.#$())this.#b((a)=>a.noBinding(this,e));return}for(let a of o){if(a.outside&&e[k])continue;if(Xe(this,e,a))continue;this.#ae(a.legacy?{...t,ops:a.ops}:a,e,r)}}#ae({ops:e,confirm:t,confirmWhen:r,outside:n,window:i},o,a){if(n&&this.element.contains(o.target))return;if(!i)o.preventDefault();let s=this.#z(t,r),c=()=>this.#Ae(this.#Te(e));if(!s)return c();if(s instanceof Promise)return s.then((l)=>l?this.#T(l,a,c):c());this.#T(s,a,c)}recompute(e){return m.get("compute")?.recompute(this,this.#e(),e)}tagsAdd(e){if(e?.defaultPrevented)return;if(this.#y(e).some((t)=>t.hasAttribute?.("data-reactive-highlighted")))return;return this.#g("tagsAdd",e)}tagsPick(e){return this.#g("tagsPick",e)}tagsRemove(e){return this.#g("tagsRemove",e)}nestedAdd(e){return this.#g("nestedAdd",e)}nestedRemove(e){return this.#g("nestedRemove",e)}syncNestedJson(e){return m.get("bindings")?.syncNestedJson(this,this.#e(),e)}#g(e,t){{let r=m.get("bindings");if(r)return r[e](this,this.#e(),t);t?.preventDefault?.();let n={currentTarget:t?.currentTarget??null,target:t?.target??null,preventDefault(){}};return b("bindings",(i)=>i[e](this,this.#e(),n))}}trackDirty(){(this.#t.get("form")??m.get("form"))?.scan(this,this.#e())}listnavNext(e){this.#A(e,(t,r)=>t<0?0:(t+1)%r)}listnavPrev(e){this.#A(e,(t,r)=>t<0?r-1:(t-1+r)%r)}listnavFirst(e){this.#A(e,()=>0)}listnavLast(e){this.#A(e,(t,r)=>r-1)}listnavPick(e){let t=this.#y(e),r=t.findIndex((n)=>n.hasAttribute("data-reactive-highlighted"));if(r<0)return;e.preventDefault(),t[r].click()}listnavClose(e){for(let t of this.#y(e))t.removeAttribute("data-reactive-highlighted")}#A(e,t){let r=this.#y(e);if(!r.length)return;e.preventDefault();let n=this.#ce(e),i=globalThis.document?.activeElement,o=n?r.findIndex((s)=>s===i||i!=null&&s.contains?.(i)):r.findIndex((s)=>s.hasAttribute("data-reactive-highlighted")),a=r[t(o,r.length)];if(n)a.focus?.();else{for(let s of r)s.removeAttribute("data-reactive-highlighted");a.setAttribute("data-reactive-highlighted","true")}a.scrollIntoView?.({block:"nearest"})}#ce(e){return(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-focus-param")==="true"}#y(e){let r=(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-option-param")??this.element.getAttribute("data-reactive-listnav-option-param");if(!r)return[];let n=this.#D();return Array.from(this.element.querySelectorAll(r)).filter((i)=>!i.hidden&&n(i))}#O(e,t,r,n,i,o,a){if(this.#i("reactive:before-dispatch",{action:t,params:this.#X(r),element:this.element},{cancelable:!0}).defaultPrevented)return;let c=Number(n)||0;if(c>0)return this.#le(e,c,t,r,o,a);let l=Number(i)||0;if(l>0)return this.#de(e,l,t,r,o,a);return this.#E(t,r,o,e,a)}#E(e,t,r,n,i){let o={inverse:null,undo:[],resurrect:null},a=this.#Fe(e,n,o),s=Boolean(r||i),c=(f)=>{if(!s||!f)return;let g=this.#e();if(o.inverse=f.optimistic(this,g,r,n),o.undo.push(...f.busy(this,g,i,n)),this.#C())o.resurrect=f.resurrection(this,g,r,n)},l=m.get("hints");if(!s||l)c(l);let h=()=>this.#ye(e,t,o,a),d=()=>this.#r?this.#r.then(h):h();return this.queue=(this.queue??Promise.resolve()).then(()=>s&&!l?this.#ue().then(c).then(d):d()),this.queue}#ue(){return this.#H("hints")}#le(e,t,r,n,i,o){this.#M(e);let a=()=>{this.#M(e),this.#E(r,n,i,e,o)},s=setTimeout(a,t);e?.addEventListener?.("blur",a,{once:!0}),this.#_.set(e,{timer:s,flush:a})}#M(e){let t=this.#_.get(e);if(!t)return;clearTimeout(t.timer),e?.removeEventListener?.("blur",t.flush),this.#_.delete(e)}#fe(){for(let e of[...this.#_.keys()])this.#M(e)}#de(e,t,r,n,i,o){let a=this.#u.get(e)??new Map;if(a.has(r))return;let s=setTimeout(()=>{if(a.delete(r),a.size===0)this.#u.delete(e)},t);return a.set(r,s),this.#u.set(e,a),this.#E(r,n,i,e,o)}#he(){for(let e of this.#u.values())for(let t of e.values())clearTimeout(t);this.#u.clear()}#i(e,t,{cancelable:r=!1}={}){let n=new CustomEvent(e,{bubbles:!0,composed:!0,cancelable:r,detail:t});return(this.element.isConnected?this.element:document).dispatchEvent(n),n}#s(e,t,r,n){let i=()=>{if(!this.element.isConnected){console.warn("[phlex-reactive] retry() ignored — the reactive root left the DOM");return}return this.#E(e,t)};this.#i("reactive:error",{action:e,params:r,...n,retry:i})}#n(e){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",e)}#me(){this.element?.removeAttribute?.("data-reactive-error")}#pe(){let e=document.querySelector("[data-reactive-error-flash]");if(!e?.content)return;let t=e.getAttribute("data-reactive-error-flash")||"flash",r=document.getElementById(t);if(!r)return;r.appendChild(e.content.cloneNode(!0))}#ge(){{let e=m.get("devtools");if(e)return e.delay();if(ae())return E("devtools").then((t)=>t.delay(),()=>{})}}#C(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#G(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}async#ye(e,t,r,n){let{fields:i,files:o}=this.#Y(),a=this.#X(t),s={...i,...a},c=this.#o,l=o.length>0,h=l?this.#we(c,e,s,o):JSON.stringify({token:c,act:e,params:s}),d=this.#C()?{action:e,paramNames:Object.keys(a),fieldNames:Object.keys(i),encoding:l?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#G()}:null;await this.#ge();try{if(navigator.onLine===!1){this.#a(r.inverse),this.#n("offline"),this.#s(e,t,s,{kind:"offline"});return}let f;try{let p={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#Pe()};if(!l)p["Content-Type"]="application/json";let A=this.#Ie();if(A)p["X-Pgbus-Connection"]=A;he("action"),f=await fetch(this.#Re(),{method:"POST",headers:p,body:h,credentials:"same-origin",signal:AbortSignal.timeout(this.#xe())})}catch(p){if(console.error("[phlex-reactive] action error",p),this.#a(r.inverse),p?.name==="TimeoutError"||p?.name==="AbortError"){this.#n("timeout"),this.#s(e,t,s,{kind:"timeout"});return}this.#pe(),this.#n("network"),this.#s(e,t,s,{kind:"network"});return}if(d)d.status=f.status;if(f.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#a(r.inverse),this.#n("redirected"),this.#s(e,t,s,{kind:"redirected",status:f.status});return}if(!f.ok){let p=await f.text();if(console.error(`[phlex-reactive] action failed: HTTP ${f.status}`,p),this.#a(r.inverse),(f.headers.get("Content-Type")||"").includes("turbo-stream")){let A=this.#V(p);if(this.#o=A??this.#o,d)this.#b((Te)=>Te.recordBody(d,p,A));window.Turbo.renderStreamMessage(p)}this.#n("http"),this.#s(e,t,s,{kind:"http",status:f.status,body:p});return}let g=f.headers.get("Content-Type")||"";if(!g.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${g}" — no update applied`),this.#a(r.inverse),this.#n("content-type"),this.#s(e,t,s,{kind:"content-type",status:f.status});return}let y=await f.text(),T=this.#V(y);if(this.#o=T??this.#o,d)this.#b((p)=>p.recordBody(d,y,T));if(window.Turbo.renderStreamMessage(y),r.resurrect)queueMicrotask(r.resurrect);this.#me(),this.#i("reactive:applied",{action:e,params:s,html:y})}catch(f){console.error("[phlex-reactive] action error",f),this.#a(r.inverse),this.#i("reactive:error",{action:e,params:s,kind:"apply"})}finally{if(n?.(),d)this.#b((f)=>f.trace(this,{...d,ms:this.#G()-d.started}))}}get#o(){return this.#v??this.tokenValue}set#o(e){this.#v=e}tokenValueChanged(){this.#v=void 0}#V(e){let t=this.element.id;if(!t)return e.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:r,self:n}=this.#be(t),i=e.match(r);if(i)return i[1];let o=e.match(n);if(o)return o[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#be(e){let t=this.#j;if(t&&t.id===e)return t;let r=Ce(e);return this.#j={id:e,token:new RegExp(`<turbo-stream\\b[^>]*\\baction="reactive:token"[^>]*\\btarget="${r}"[^>]*\\bdata-reactive-token-value="([^"]+)"`),self:new RegExp(`<turbo-stream\\b[^>]*\\baction="(?:replace|update)"[^>]*\\btarget="${r}"[^>]*>([\\s\\S]*?)</turbo-stream>`)}}#F(e){return e.closest('[data-controller~="reactive"]')===this.element}#D(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(t)=>this.#F(t)}#Y(){let e={},t=[],r=this.#D(),n=[];this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((s)=>{if(!r(s))return;if(s.type==="file")for(let c of s.files??[])t.push({name:s.name,file:c,multiple:s.multiple});else n.push(s)});let i=[];this.element.querySelectorAll(`[name]${je}`).forEach((s)=>{if(r(s))i.push(s)});let o=this.#ve(n),a=this.#_e(n);for(let s of n)if(o.has(s.name)){let c=e[s.name]??(e[s.name]=[]);if(s.type==="checkbox"||s.type==="radio"){if(s.checked)c.push(s.value)}else if(s.type==="hidden"){if(!a.has(s.name))c.push(s.value)}else if(s.multiple&&s.options){for(let l of s.options)if(l.selected)c.push(l.value)}else c.push(s.value)}else if(s.type==="checkbox")e[s.name]=s.checked;else if(s.type==="radio"){if(s.checked)e[s.name]=s.value}else e[s.name]=s.value;return i.forEach((s)=>{let c=s.getAttribute("name");if(!c)return;let l=s.value??s.textContent??s.innerHTML??"",h=e[c];if(String(c).endsWith("[]")&&!Je(s))return;if(String(c).endsWith("[]")&&(h===void 0||Array.isArray(h))){(Array.isArray(h)?h:e[c]=[]).push(l);return}if(h==null||h==="")e[c]=l}),{fields:e,files:t}}#ve(e){let t=new Set;for(let r of e){if(r.type==="radio")continue;if(String(r.name).endsWith("[]"))t.add(r.name)}return t}#_e(e){let t=new Set;for(let r of e)if(r.type==="checkbox")t.add(r.name);return t}#we(e,t,r,n){let i=new FormData;i.append("token",e),i.append("act",t);let o=[];for(let[s,c]of Object.entries(r))if(Array.isArray(c)&&String(s).endsWith("[]"))if(c.length===0)o.push(String(s).slice(0,-2));else{let l=`${this.#k(s)}[]`;for(let h of c)i.append(l,String(h))}else this.#q(i,this.#k(s),c);for(let s of o)i.append("empty_groups[]",s);let a=this.#Se(n);for(let{name:s,file:c,multiple:l}of n){let d=l||a.has(s)?`${this.#k(s)}[]`:this.#k(s);i.append(d,c,c.name)}return i}#k(e){let t=String(e),r=t.indexOf("[");if(r===-1)return`params[${t}]`;return`params${[t.slice(0,r),...t.slice(r).match(/[^\[\]]+/g)??[]].map((i)=>`[${i}]`).join("")}`}#q(e,t,r){if(r==null)e.append(t,"");else if(Array.isArray(r))r.forEach((n,i)=>this.#q(e,`${t}[${i}]`,n));else if(typeof r==="object")for(let[n,i]of Object.entries(r))this.#q(e,`${t}[${n}]`,i);else e.append(t,String(r))}#Se(e){let t=new Map;for(let{name:r}of e)t.set(r,(t.get(r)??0)+1);return new Set([...t].filter(([,r])=>r>1).map(([r])=>r))}#X(e){if(!e)return{};try{return typeof e==="string"?JSON.parse(e):e}catch{return{}}}#Te(e){return W(e)}#Ae(e){q(e,(t)=>this.#W(t),(t,r)=>this.#B(`client op "${t}"`,r))}#$(){return this.element?.getAttribute?.("data-reactive-verbose")==="true"||this.#C()}#B(e,t){if(!this.#$())return;this.#b((r)=>r.diagnose(this,e,t))}#b(e){b("devtools",e)}#W(e){let t=e.to;if(t==="@root")return[this.element];if(typeof t!=="string"||t==="")return[];if(e.global)return[...document.querySelectorAll(t)];return[...this.element.querySelectorAll(t)].filter((r)=>this.#F(r))}#Ee(e,t){if(e?.checked!=="keep")return!1;let r=t?.type;return r==="checkbox"||r==="radio"}#a(e){if(!e)return;if(!this.element.isConnected)return;for(let t of e)t()}#Fe(e,t,r){this.#ke(e,t),ue();let n=!1;return()=>{if(n)return;n=!0,this.#Le(e,t),le();for(let i of r.undo)i()}}#ke(e,t){if(this.#c(t,e,1),this.#c(this.element,e,1),this.#l.set(e,(this.#l.get(e)??0)+1),this.#R++===0)this.element.setAttribute("aria-busy","true");for(let r of this.#Z(e))this.#c(r,e,1)}#Le(e,t){this.#c(t,e,-1),this.#c(this.element,e,-1);let r=(this.#l.get(e)??1)-1;if(r<=0)this.#l.delete(e);else this.#l.set(e,r);if(--this.#R<=0)this.#R=0,this.element.removeAttribute("aria-busy");for(let n of this.#Z(e))this.#c(n,e,-1)}#c(e,t,r){if(!e||typeof e.getAttribute!=="function")return;let n=this.#x.get(e)??new Map,i=(n.get(t)??0)+r;if(i<=0)n.delete(t);else n.set(t,i);if(n.size===0){this.#x.delete(e),e.removeAttribute("data-reactive-busy");return}this.#x.set(e,n),e.setAttribute("data-reactive-busy",[...n.keys()].join(" "))}#Z(e){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((r)=>r.getAttribute("data-reactive-busy-on")===e&&this.#F(r))}#Re(){return this.#Q??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#xe(){if(this.#L!=null)return this.#L;let e=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,t=Number(e);return this.#L=Number.isFinite(t)&&t>0?t:30000}#Pe(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#Ie(){return document.querySelector("pgbus-stream-source[connection-id]")?.getAttribute("connection-id")||document.querySelector('meta[name="pgbus-connection-id"]')?.content||null}}if(typeof window<"u")if(window.Turbo)G();else document.addEventListener("turbo:load",G,{once:!0});w("persist",()=>import("phlex/reactive/features/persist"),gt);w("defer",()=>import("phlex/reactive/features/defer"));w("form",()=>import("phlex/reactive/features/form"));w("bindings",()=>import("phlex/reactive/features/bindings"));w("compute",()=>import("phlex/reactive/features/compute"),yt);w("effects",()=>import("phlex/reactive/features/effects"));w("hints",()=>import("phlex/reactive/features/hints"));w("devtools",()=>import("phlex/reactive/features/devtools"));B();function gt(e,t){let r=()=>{t.edited=!0},n=(o)=>{let a=o.target;if(o.detail?.success&&a?.tagName==="FORM"&&a.contains?.(e))t.submitted=!0},i=["input","change","lexxy:change","trix-change"];for(let o of i)e.addEventListener?.(o,r);return document.addEventListener("turbo:submit-end",n),()=>{for(let o of i)e.removeEventListener?.(o,r);document.removeEventListener("turbo:submit-end",n)}}function yt(e,t){let r=()=>{t.edited=!0};return e.addEventListener?.("input",r),e.addEventListener?.("change",r),()=>{e.removeEventListener?.("input",r),e.removeEventListener?.("change",r)}}var bt=1000,S=null,Se,P=new Set;function vt(e){return ve(e).then((t)=>{if(e!=="effects")return;Se=t,t?.sweep()})}oe((e,t)=>{let r=e.detail,n=r?.render;if(typeof n!=="function")return;let i=r.newStream??e.target,o=be(_t(i)).filter((s)=>!P.has(s));if(!t&&!P.has("effects")&&wt(i))o.push("effects");if(o.length===0&&!S)return t?.wrap(e);if(o.length>0){for(let c of o)P.add(c);let s=S=Promise.race([Promise.all([S,...o.map(vt)]),new Promise((c)=>setTimeout(c,bt))]).then(()=>{if(S!==s)return;S=null,P.clear()})}let a=S;r.render=async(s)=>{await a;let c={target:e.target,detail:{newStream:r.newStream,render:n}};(t??Se)?.wrap(c),await c.detail.render(s)}});function _t(e){let t=e?.querySelector?.("template")?.content;if(!t)return[];let r=[...t.querySelectorAll?.('[data-controller~="reactive"]')??[]];for(let n of t.children??[])if(n.matches?.('[data-controller~="reactive"]')&&!r.includes(n))r.unshift(n);return r}function wt(e){return Boolean(e?.hasAttribute?.("data-reactive-effect")||document.getElementById?.(e?.getAttribute?.("target"))?.matches?.("[data-reactive-effect-update],[data-reactive-effect-exit]")||e?.querySelector?.("template")?.content?.querySelector?.("[data-reactive-effect-enter],[data-reactive-dismiss-after]")||document.querySelector?.("[data-reactive-dismiss-after]:not([data-reactive-dismiss-scheduled])"))}var Ot=we;export{ce as ACTIVE_ATTR,je as EDITOR_SELECTOR,Ue as EDITOR_TAGS,de as REQUESTS_ATTR,De as checkReactiveRegistration,he as countReactiveRequest,Ot as default,ue as enterReactiveActivity,Ce as escapeRegExp,le as exitReactiveActivity,ve as loadReactiveFeature,oe as onReactiveStreamWithoutEffects,Et as reactiveActivityCount,Lt as reactiveFeatureNames,G as registerReactiveActions,Le as registerReactiveDefer,B as registerReactiveDev,Re as registerReactiveDismiss,Re as registerReactiveEffects,kt as registerReactiveFeature,w as registerReactiveFeatureLoader,ke as registerReactiveJs,xe as registerReactiveMorphFocus,Ie as registerReactiveOffline,Re as registerReactiveStreamRender,Fe as registerReactiveToken,Ee as registerReactiveVisit,Ft as resetReactiveActivity,be as unloadedFeaturesFor};
1
+ import{Controller as Ae}from"@hotwired/stimulus";import{confirmResolver as U}from"phlex/reactive/confirm";function Ee(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:visit"])return;e["reactive:visit"]=function(){let t=this.getAttribute("data-url");if(t)window.Turbo.visit(t,{action:"advance"})}}function Fe(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:token"])return;e["reactive:token"]=function(){let t=this.getAttribute("data-reactive-token-value"),r=this.getAttribute("target");if(!t||!r)return;let n=document.getElementById(r);if(n)n.setAttribute("data-reactive-token-value",t)}}function ke(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:js"])return;e["reactive:js"]=function(){let t=j(this.getAttribute("data-reactive-ops"));if(!t.length)return;let r=this.getAttribute("target"),n=this.getAttribute("data-reactive-verbose")==="true",i=r?document.getElementById(r):null;if(r&&!i){if(n)b("devtools",(o)=>o.missingRoot(r));return}q(t,(o)=>et(o,i),n?(o,a)=>b("devtools",(s)=>s.diagnoseStream(o,a,i)):void 0)}}function Le(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:defer"])return;e["reactive:defer"]=function(){b("defer",(t)=>t.streamAction(this))}}var J=!1,D=null;function Re(){if(J)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;J=!0,document.addEventListener("turbo:before-stream-render",(e)=>{if(D)D(e,m.get("effects"));else m.get("effects")?.wrap(e)})}function oe(e){D=e}var K=!1;function z(e){return e===document.activeElement&&(e.localName==="input"||e.localName==="textarea")&&!e.hasAttribute("data-reactive-morph-value")&&!!e.closest('[data-controller~="reactive"]')}function xe(){if(K)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;K=!0,document.addEventListener("turbo:before-morph-element",(e)=>{let t=e.target,r=e.detail?.newElement;if(!r||e.defaultPrevented||t.localName!=="input"||!z(t))return;let n=r.getAttribute("value");if(n==null)t.removeAttribute("value");else if(t.getAttribute("value")!==n)t.setAttribute("value",n)}),document.addEventListener("turbo:before-morph-attribute",(e)=>{if(e.detail?.attributeName==="value"&&z(e.target))e.preventDefault()})}var Pe="__materialize",H=!1;function Ie(){if(H)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;H=!0;let e=()=>{let t=document.documentElement;if(typeof t?.toggleAttribute!=="function")return;t.toggleAttribute("data-reactive-offline",globalThis.navigator?.onLine===!1)};e(),window.addEventListener("online",e),window.addEventListener("offline",e)}var Ne="phlex-reactive:latency";function ae(){return typeof sessionStorage<"u"&&Boolean(sessionStorage.getItem(Ne))}function B(){if(typeof document>"u")return;if(!m.has("devtools")&&!v.get("devtools")[1])return;let e=document.querySelector?.('meta[name="phlex-reactive-env"]')?.content==="development";if(e||ae())b("devtools",(t)=>e&&t.attach())}var ce="data-reactive-active",_=0;function ue(){if(_++,_===1)fe("reactive:busy")}function le(){if(_===0)return;if(_--,_===0)fe("reactive:idle")}function Ft(){return _}function kt(){_=0,(typeof document<"u"?document.documentElement:null)?.removeAttribute?.(ce)}function fe(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.toggleAttribute==="function")t.toggleAttribute(ce,_>0);if(typeof document.dispatchEvent==="function"&&typeof CustomEvent==="function")document.dispatchEvent(new CustomEvent(e,{detail:{count:_}}))}var de="data-reactive-requests";function he(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.setAttribute!=="function"||!Oe(t))return;let r=Me(t);r[e]=(Number(r[e])||0)+1,t.setAttribute(de,JSON.stringify(r))}function Oe(e){return e.hasAttribute?.("data-reactive-verbose")||!!document.querySelector?.('[data-reactive-verbose="true"]')}function Me(e){try{let t=JSON.parse(e.getAttribute(de));if(t&&typeof t==="object")return{action:0,defer:0,...t}}catch{}return{action:0,defer:0}}function G(){Ee(),Fe(),ke(),Le(),Re(),xe(),Ie(),B()}function Ce(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var me=Symbol.for("phlex-reactive.core");if(globalThis[me])console.error("[phlex-reactive] the client was loaded twice. Import EITHER phlex/reactive/reactive_controller (the default, "+"everything in one file) OR phlex/reactive/core (features on demand), not both — each carries its own state.");globalThis[me]=!0;var pe=!1;function De(){if(pe)return;if(typeof document>"u")return;let e=document.querySelectorAll('[data-controller~="reactive"]');if(!e||e.length===0)return;console.warn("[phlex-reactive] found "+e.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.')}if(typeof window<"u"&&typeof document<"u"){let e=()=>setTimeout(De,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",e,{once:!0});else e()}var qe=new Set(["href","src","srcdoc","action","formaction","xlink:href","style"]);function $e(e){let t=String(e).toLowerCase();return t.startsWith("on")||qe.has(t)}var I=new WeakMap;function Be(e,t,r){let[n,i,o]=t;I.get(e)?.(),e.classList.add(n,i),r();let a=!1,s=requestAnimationFrame(()=>{if(a)return;e.classList.remove(i),e.classList.add(o)}),c=(h)=>{if(a||h&&h.target!==e)return;a=!0,I.delete(e),clearTimeout(l),globalThis.cancelAnimationFrame?.(s),e.removeEventListener("animationend",c),e.removeEventListener("transitionend",c),e.classList.remove(n,i,o)};I.set(e,c),e.addEventListener("animationend",c),e.addEventListener("transitionend",c);let l=setTimeout(c,je(e))}function je(e){let t=0;try{let r=getComputedStyle(e);for(let n of["transition","animation"]){let[i,o]=["Duration","Delay"].map((s)=>String(r[n+s]).split(",").map((c)=>parseFloat(c)*(/ms/.test(c)?1:1000)||0)),a=String(r[n+"IterationCount"]).split(",").map((s)=>/inf/.test(s)?1/0:parseFloat(s)>=0?parseFloat(s):1);for(let s=0;s<i.length||s<o.length||s<a.length;s++){let c=i[s%i.length]*a[s%a.length]||0;t=Math.max(t,c+o[s%o.length])}}}catch{}return Math.min(Math.max(t+50,350),5000)}var We=":is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])",Ue=new Set(["lexxy-editor","trix-editor"]);function Je(e){return Ue.has(e.localName)?typeof e.value==="string":!0}var V=Object.freeze({show:(e,t,r)=>N(e,!1,t,r),hide:(e,t,r)=>N(e,!0,t,r),toggle:(e,t,r)=>N(e,!e.hidden,t,r),add_class:(e,t)=>e.classList.add(...t.classes??[]),remove_class:(e,t)=>e.classList.remove(...t.classes??[]),toggle_class:(e,t)=>(t.classes??[]).forEach((r)=>e.classList.toggle(r)),set_attr:(e,t)=>{if(O(t.name))e.setAttribute(t.name,t.value??"")},remove_attr:(e,t)=>{if(O(t.name))e.removeAttribute(t.name)},toggle_attr:(e,t)=>{if(!O(t.name))return;if(Array.isArray(t.values)){let[r,n]=t.values;e.setAttribute(t.name,e.getAttribute(t.name)===r?n:r)}else if(e.hasAttribute(t.name))e.removeAttribute(t.name);else e.setAttribute(t.name,"")},focus:(e)=>e.focus?.(),focus_first:(e)=>Ve(e)?.focus?.(),text:(e,t)=>{let r=String(t.value??"");if(e.textContent!==r)e.textContent=r},check_group:(e,t)=>{let r=t.global?document.querySelectorAll('[data-controller~="reactive"]'):[e];for(let n of r)b("bindings",(i)=>i.checkGroup(n,t.group,t.checked))},dispatch:(e,t)=>{e.dispatchEvent(new CustomEvent(t.name,{bubbles:!0,composed:!0,detail:t.detail??{}}))},submit:(e,t,r)=>{let n=Ke(e);if(!n)return;let i=null;if(t?.submitter!=null&&typeof r==="function"){if(i=r({...t,to:t.submitter})[0]??null,!(i?.form===n&&(i.type==="submit"||i.type==="image")))console.warn(`[phlex-reactive] submitter ${t.submitter} is not a submit control of the form — ignored`),i=null}i?n.requestSubmit?.(i):n.requestSubmit?.()},paste_into:(e)=>ze(e),persist_state:(e,t)=>b("persist",(r)=>r.writeState(e,t.state)),persist_clear:(e)=>b("persist",(t)=>t.clearRoot(e))});function Ke(e){if(e?.tagName==="FORM")return e;return e?.form??e?.closest?.("form")??null}function ze(e){let t=globalThis.navigator?.clipboard;if(typeof t?.readText!=="function")return;t.readText().then((r)=>{if(!r)return;if(e.value=r,typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}));e.focus?.()}).catch(()=>{})}function He(e,t,r){if(r?.transition)Be(e,r.transition,()=>e.hidden=t);else e.hidden=t}function N(e,t,r,n){if(He(e,t,r),r?.expanded==null||typeof n!=="function")return;for(let i of n({...r,to:r.expanded}))i.setAttribute?.("aria-expanded",String(!t))}function O(e){if(!$e(e))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(e)} — skipped`),!1}var Ge='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Ve(e){return e.querySelectorAll?.(Ge)?.[0]??null}function j(e){if(Array.isArray(e))return e;if(typeof e!=="string")return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}var Y=Object.freeze({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"}),X=Object.freeze(["meta","ctrl","alt","shift"]);function W(e,t,r){let n=e.split("+");for(let a of X)if(n.includes(a)!==Boolean(t[`${a}Key`]))return!1;let i=n.find((a)=>!X.includes(a));if(i===void 0||typeof t.key!=="string")return!0;let o=r&&Object.hasOwn(r,i)?r[i]:Object.hasOwn(Y,i)?Y[i]:/^[a-z0-9]$/.test(i)?i:null;return typeof o==="string"&&o.toLowerCase()===t.key.toLowerCase()}function Ye(e){if(Array.isArray(e))return[{ops:e,legacy:!0}];if(e&&typeof e==="object")return[e];if(typeof e!=="string")return[];let t=e.trim();if(t.startsWith("["))return[{ops:j(t),legacy:!0}];let r=[];for(let n of t.split(" ")){if(n==="")continue;let i=null;try{i=JSON.parse(n)}catch{i=null}if(i&&typeof i==="object"&&!Array.isArray(i))r.push(i);else console.warn(`[phlex-reactive] malformed on_client binding record ${JSON.stringify(n)} — skipped`)}return r}function Z(e,t,r){if(e.legacy)return!0;let n=e.on;if(typeof n!=="string"||n==="")return!1;let i=n.indexOf(".");if(t.type!==(i<0?n:n.slice(0,i)))return!1;if(Boolean(e.window)!==_e(t.currentTarget))return!1;return i<0||r===null||W(n.slice(i+1),t,r)}function Xe(e,t){let r=e.detail;if(r===void 0)return!0;if(r===null||typeof r!=="object"||Array.isArray(r))return!1;let n=t.detail;if(n===null||typeof n!=="object")return!1;return Object.keys(r).every((i)=>n[i]===r[i])}var Q=new WeakMap;function Ze(e,t,r){if(!r.once)return!1;let n=t.currentTarget??e.element,i=Q.get(e);if(!i)i=new WeakMap,Q.set(e,i);let o=i.get(n);if(!o)o=new Set,i.set(n,o);let a=t.params?.ops,c=(n===globalThis.window?`${typeof a==="string"?a:JSON.stringify(a??null)}|`:"")+JSON.stringify(r);if(o.has(c))return!0;return o.add(c),!1}var ee=new WeakMap;function Qe(e,t){if(e===null||typeof e!=="object")return!1;let r=e.params?.ops,n=typeof r==="string"?r:JSON.stringify(r??null),i=ee.get(e);if(!i)i=new WeakMap,ee.set(e,i);let o=i.get(t);if(!o)o=new Map,i.set(t,o);let a=o.get(e.currentTarget);if(!a)a=new Set,o.set(e.currentTarget,a);if(a.has(n))return!0;return a.add(n),!1}function q(e,t,r){for(let n of e){if(!Array.isArray(n))continue;let[i,o={}]=n;if(!Object.hasOwn(V,i)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(i)} — skipped`);continue}let a=t(o);if(a.length===0&&r)r(i,o);for(let s of a)V[i](s,o,t)}}function et(e,t){let r=e.to;if(t){if(r==="@root")return[t];if(typeof r!=="string"||r==="")return[];if(e.global)return[...document.querySelectorAll(r)];return[...t.querySelectorAll(r)]}if(typeof r!=="string"||r===""||r==="@root")return[];return[...document.querySelectorAll(r)]}function tt(e){let t=e.getAttribute?.("data-reactive-persist");return Boolean(t)&&t!=="off"}function ge(e){return["defer-token","defer-src","lazy-on","lazy-visible"].some((t)=>e.getAttribute?.(`data-reactive-${t}`)!=null)}function rt(e){return(e.getAttribute?.("data-action")??"").includes("reactive#trackDirty")||e.getAttribute?.("data-reactive-clipboard")!=null||e.querySelector?.('[data-action*="reactive#trackDirty"],[data-reactive-clipboard]')!=null}function nt(e){return["show-targets","group-targets","on-complete","filter-input","tags-field"].some((t)=>e.getAttribute?.(`data-reactive-${t}`)!=null)||(e.querySelectorAll?.("[data-reactive-show-field], [data-reactive-show]")??[]).length>0||e.querySelector?.("[data-reactive-nested-json], [data-reactive-nested-list], [data-reactive-confirm-when-param], [data-reactive-enable], [data-reactive-select-all], [data-reactive-count]")!=null}function it(e){return e.getAttribute?.("data-reactive-compute-inputs-param")!=null}var st=[["persist",[tt,null,null,!0]],["defer",[ge,null]],["form",[rt,null]],["bindings",[nt,null,null,!0]],["compute",[it,null,null,!0]],["effects",[(e)=>["enter","update","exit"].some((t)=>e.getAttribute?.(`data-reactive-effect-${t}`)!=null),null]],["hints",[(e)=>e.querySelector?.("[data-reactive-optimistic-param], [data-reactive-busy-param], [data-reactive-loading-param]")!=null,null]],["devtools",[(e)=>e.getAttribute?.("data-reactive-debug")==="true",null]]],v=new Map(st),te=new Map,m=new Map,ot=new Map;function w(e,t,r){ye.set(e,[t,r]),at(e)}var ye=new Map;function at(e){let t=v.get(e),[r,n]=ye.get(e);t[1]=r,t[2]=n}function Lt(e,t){t.install?.(F),m.set(e,t),ot.set(e,t)}function be(e){let t=[];for(let[r,[n]]of v){if(!n||m.has(r))continue;try{if(e.some((i)=>n(i)))t.push(r)}catch{}}return t}function ve(e){return E(e).catch((t)=>R(e,"load",t))}function E(e){let t=te.get(e);if(!t)t=(v.get(e)[1]??(()=>Promise.reject(Error("this entry has no way to import it"))))().then((n)=>(n.install?.(F),m.set(e,n),n)),te.set(e,t);return t}var re=new Set;function R(e,t,r){let n=e+t;if(re.has(n))return;re.add(n),console.error(`[phlex-reactive] the "${e}" feature module (phlex/reactive/features/${e}) is unavailable: ${t}. If you bundle or vendor the client, alias or pin phlex/reactive/features/* (README: esbuild / webpack / bun).`,r)}function b(e,t){let r=m.get(e);if(r)return t(r);E(e).then(t,(n)=>R(e,"load",n))}var ct=1e4;function M(){let e=Number(globalThis.document?.head?.querySelector?.('meta[name="phlex-reactive-feature-timeout"]')?.content);return Number.isFinite(e)&&e>0?e:ct}function Rt(){return[...v.keys()]}var ne=Promise.resolve();function ie(e,t,r){let n=F.waiting.get(e);if(n&&n[t]===r)delete n[t]}var F={enter:ue,exit:le,count:he,waiting:new WeakMap};var k=Symbol.for("phlex-reactive.early"),ut=1e4,lt=1500,_e=(e)=>e!=null&&(e===globalThis.window||e.window===e);function C(){return globalThis[k]??={queue:[],connected:new WeakSet},globalThis[k]}function ft(){let e=Number(globalThis.document?.querySelector?.('meta[name="phlex-reactive-early-ttl"]')?.content);return Number.isFinite(e)&&e>0?e:ut}function dt(e){let t={};for(let{name:r,value:n}of Array.from(e.attributes??[])){let i=/^data-reactive-(.+)-param$/i.exec(r);if(!i)continue;let o;try{o=JSON.parse(n)}catch{o=n}t[i[1].replace(/[-_]([a-z0-9])/g,(a,s)=>s.toUpperCase())]=o}return t}function ht(e,t,r){return{[k]:!0,type:e.type,detail:e.detail,target:e.target,currentTarget:r?t.ownerDocument.defaultView:t,params:dt(t),key:e.key,code:e.code,metaKey:e.metaKey,ctrlKey:e.ctrlKey,altKey:e.altKey,shiftKey:e.shiftKey,button:e.button,submitter:e.submitter,bubbles:e.bubbles,timeStamp:e.timeStamp,defaultPrevented:e.defaultPrevented,preventDefault(){},stopPropagation(){},stopImmediatePropagation(){}}}var x=new WeakMap;function mt(e,{token:t,type:r,method:n,filter:i,win:o},a){let s=x.get(e);if(!s)x.set(e,s=new Map);let c=o?`${t} ${a}`:t;if(s.has(c))return!1;return s.set(c,{type:r,method:n,filter:i,win:o,params:a,armed:!0}),!0}function se(e,t,r,n){if(e?.[k])return!1;let i=_e(e?.currentTarget),o=i?n:e?.currentTarget,a=gt(e,o,i?`@${t}`:t),s=x.get(o),c=i&&JSON.stringify(e.params);for(let l of s?.values()??[]){if(!l.armed||l.method!==t||l.type!==e.type||Boolean(l.win)!==i)continue;if(i&&l.params!==c)continue;if(l.filter&&!W(l.filter,e,r))continue;return l.armed=!1,!0}return a}var L=new WeakMap;function pt(e,t,r){let n=L.get(e);if(!n)L.set(e,n=new Map),setTimeout(()=>L.delete(e));let i=n.get(t)??{};n.set(t,i),i[r]=(i[r]??0)+1}function gt(e,t,r){let n=e&&L.get(e)?.get(t);if(!n?.[r])return!1;return n[r]-=1,!0}class we extends Ae{static values={token:String};#v;#_=new Map;#u=new Map;#Q;#L;#W;#R=0;#l=new Map;#x=new WeakMap;#w;featuresReady=ne;#t=new Map;#P=new Set;#f=!1;#r=null;#d=new Map;#S=new Map;#h=new Map;#m=0;#U;#Ne=0;#Oe=0;connect(){if(pe=!0,C().connected.add(this.element),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-token-value")!=null||ge(this.element))this.#w=(e)=>{if(e.target!==this.element)return;this.#J(!0)},this.element.addEventListener?.("turbo:morph-element",this.#w);this.#m++,this.featuresReady=ne,this.#J(),this.#ie()}#Me(e){}#Ce(e,t,r,n){}#De(){}#qe(e,t){}#J(e){{let t=this.#m,r=[];for(let[o,[a]]of v){if(!a||this.#P.has(o))continue;let s=m.get(o);if(s&&!s.connect)continue;try{if(a(this.element))r.push(o)}catch(c){this.#p(o,"detect",c)}}if(r.length===0)return;for(let o of r)this.#P.add(o);if(!this.#f&&r.every((o)=>m.has(o))){for(let o of r)this.#I(t,o,m.get(o),e);return}for(let o of r){let a=this.#ee(t,o),s=[];for(let l of v.keys()){if(l===o)break;if(this.#h.has(l))s.push(this.#h.get(l))}let c=Promise.all(s).then(()=>a).then((l)=>l&&this.#I(t,o,l,e));if(this.#h.set(o,c),v.get(o)[3])this.#r=c}let n=this.#r;n?.then(()=>{if(this.#r===n)this.#r=null}),this.#f=!0;let i=Promise.all(this.#h.values()).then(()=>{if(this.featuresReady===i)this.#f=!1});this.featuresReady=i}}#ee(e,t){{let r=()=>e===this.#m;return this.#te(t),new Promise((n)=>{let i=!1,o=setTimeout(()=>{if(this.#d.delete(o),i=!0,r())this.#p(t,"timeout",Error(`not loaded after ${M()} ms`));n(null)},M());this.#d.set(o,n);let a=()=>{clearTimeout(o),this.#d.delete(o)};E(t).then((s)=>{if(a(),i)queueMicrotask(()=>this.#I(e,t,s));else n(s)},(s)=>{if(a(),r())this.#p(t,"load",s);n(null)})})}}#te(e){{let t=v.get(e)[2];if(!t)return;let r={};try{this.#S.set(e,[t(this.element,r),r]),F.waiting.set(this.element,{...F.waiting.get(this.element),[e]:r})}catch(n){this.#p(e,"detect",n)}}}#K(e,t){{let[r,n]=this.#S.get(e)??[];if(this.#S.delete(e),!t)ie(this.element,e,n);try{r?.()}catch(i){console.error(`[phlex-reactive] the "${e}" feature module failed to stop waiting`,i)}return n}}#I(e,t,r,n){{if(e!==this.#m)return;let i=this.#K(t);try{r.connect?.(this,this.#e(),n,i),this.#t.set(t,r)}catch(o){this.#p(t,"connect",o)}}}#e(){return this.#U??={emit:(e,t,r)=>this.#i(e,t,r),reseed:()=>this.#re(),proceed:(e,t,r)=>this.#O(e,t,r),forgetToken:()=>{this.#v=void 0},owns:(e)=>this.#F(e),ownership:()=>this.#D(),opTargets:(e)=>this.#j(e),diagnose:(e,t)=>this.#B(e,t),applyOps:(e,t)=>q(e,(r)=>this.#j(t!=null&&r.to==null?{...r,to:t}:r),(r,n)=>this.#B(`client op "${r}"`,n)),listnavOptions:(e)=>this.#y(e),collectFields:()=>this.#Y(),confirm:(e,t)=>Promise.resolve().then(()=>U(e,t)).catch(()=>!1)},this.#U}#re(){this.#t.get("form")?.scan(this,this.#e()),this.#t.get("bindings")?.reseed(this),this.#t.get("compute")?.seed(this)}#p(e,t,r){if(R(e,t,r),this.#n("feature"),t==="load"&&this.element.getAttribute?.("data-reactive-defer-pending"))this.element.removeAttribute("data-reactive-defer-pending"),this.element.removeAttribute("aria-busy");this.#i("reactive:error",{kind:"feature",feature:e,phase:t,error:r})}#ne(){{this.#m++;for(let[t,r]of this.#d)clearTimeout(t),r(null);this.#d.clear();for(let t of[...this.#S.keys()]){let r=this.#K(t,!0),n=this.element;b(t,(i)=>{i.abandon?.(n,r),ie(n,t,r)})}this.#P.clear(),this.#h.clear(),this.#f=!1,this.#r=null;let e=[...this.#t];this.#t.clear();for(let[t,r]of e)try{r.disconnect?.(this,this.#e())}catch(n){console.error(`[phlex-reactive] the "${t}" feature module failed to disconnect`,n)}}}#ie(){if(this.element.setAttribute?.("data-reactive-connected",""),this.element.isConnected)this.element.dispatchEvent?.(new CustomEvent("reactive:connect",{bubbles:!0,composed:!0,detail:{id:this.element.id}}));this.#se()}#N=new Set;#se(){let{queue:e}=C();if(e.length===0)return;let t=[];for(let i=e.length-1;i>=0;i--){let{root:o}=e[i];if(o===this.element||!o.isConnected)t.unshift(...e.splice(i,1))}let r=ft(),n=new Map;for(let i of t){let o=n.get(i.event)??[new Set,new Set];n.set(i.event,o);let a=o[+!!i.win];if(a.has(i.el))continue;a.add(i.el);let s=i.win?Math.min(lt,r):r,c=i.root!==this.element?"its root left the page before a controller connected":performance.now()-i.at>s?`it is older than the ${s} ms ${i.win?"window-trigger":"early-event"} TTL`:i.el.isConnected&&this.element.contains(i.el)?null:"its element left the root before the controller connected";if(c){if(this.#$())console.warn(`[phlex-reactive] dropped an early "${i.event.type}" trigger: ${c}`);continue}this.#oe(i)}}#oe({event:e,el:t,descs:r,win:n}){let i=ht(e,t,n),o=this.application?.schema?.keyMappings,a=(t.getAttribute("data-action")??"").split(/\s+/),s=n?this.element:t;for(let c of r){if(!a.includes(c.token))continue;if(c.filter&&!W(c.filter,e,o))continue;if(/#\w+.*:once\b/.test(c.token)){if(!mt(s,c,n&&JSON.stringify(i.params)))continue;this.#N.add(s)}if(pt(e,s,n?`@${c.method}`:c.method),c.method==="runOps")this.runOps(i);else this.dispatch(i)}}disconnect(){if(this.#ne(),this.#fe(),this.#he(),this.#w)this.element.removeEventListener?.("turbo:morph-element",this.#w);C().connected.delete(this.element),this.element.removeAttribute?.("data-reactive-connected");for(let e of this.#N)x.delete(e);this.#N.clear()}dispatch(e){if(se(e,"dispatch",this.application?.schema?.keyMappings,this.element))return;let{action:t,params:r,debounce:n,throttle:i,confirm:o,confirmWhen:a,outside:s,window:c,optimistic:l}=e.params;if(!t)return;let h=e.params.busy??e.params.loading;if(s&&this.element.contains(e.target))return;let d=e.currentTarget??e.target;if(!c&&!this.#Ee(l,d))e.preventDefault();if(t===Pe){let y=()=>{{let T=this.#t.get("defer");if(T)return T.materialize(this)}if(this.tokenValue)return this.#O(d,t,"{}")};return this.#f?this.featuresReady.then(y):y()}let f=this.#z(o,a),g=()=>this.#O(d,t,r,n,i,l,h);if(!f)return g();if(f instanceof Promise)return f.then((y)=>y?this.#T(y,d,g):g());this.#T(f,d,g)}#T(e,t,r){return Promise.resolve().then(()=>U(e,{el:t})).catch(()=>!1).then((n)=>{if(n)r()})}#z(e,t){if(e)return e;if(!t)return null;{let r=m.get("bindings");if(r)return r.confirmMessage(this,this.#e(),t);return this.#H("bindings").then((n)=>n&&n.confirmMessage(this,this.#e(),t))}}#H(e){{let t;return Promise.race([E(e).catch((r)=>(R(e,"load",r),null)),new Promise((r)=>t=setTimeout(()=>r(null),M()))]).finally(()=>clearTimeout(t))}}runOps(e){if(se(e,"runOps",this.application?.schema?.keyMappings,this.element))return;if(Qe(e,this))return;let t=e.params??{},r=e.currentTarget??e.target,n=Ye(t.ops),i=n.filter((a)=>Z(a,e,null)),o=i.length<=1?i:i.filter((a)=>Z(a,e,this.application?.schema?.keyMappings));if(o.length===0&&n.length>0){if(this.#$())this.#b((a)=>a.noBinding(this,e));return}for(let a of o){if(a.outside&&e[k])continue;if(!Xe(a,e))continue;if(Ze(this,e,a))continue;this.#ae(a.legacy?{...t,ops:a.ops}:a,e,r)}}#ae({ops:e,confirm:t,confirmWhen:r,outside:n,window:i},o,a){if(n&&this.element.contains(o.target))return;if(!i)o.preventDefault();let s=this.#z(t,r),c=()=>this.#Ae(this.#Te(e));if(!s)return c();if(s instanceof Promise)return s.then((l)=>l?this.#T(l,a,c):c());this.#T(s,a,c)}recompute(e){return m.get("compute")?.recompute(this,this.#e(),e)}tagsAdd(e){if(e?.defaultPrevented)return;if(this.#y(e).some((t)=>t.hasAttribute?.("data-reactive-highlighted")))return;return this.#g("tagsAdd",e)}tagsPick(e){return this.#g("tagsPick",e)}tagsRemove(e){return this.#g("tagsRemove",e)}nestedAdd(e){return this.#g("nestedAdd",e)}nestedRemove(e){return this.#g("nestedRemove",e)}syncNestedJson(e){return m.get("bindings")?.syncNestedJson(this,this.#e(),e)}#g(e,t){{let r=m.get("bindings");if(r)return r[e](this,this.#e(),t);t?.preventDefault?.();let n={currentTarget:t?.currentTarget??null,target:t?.target??null,preventDefault(){}};return b("bindings",(i)=>i[e](this,this.#e(),n))}}trackDirty(){(this.#t.get("form")??m.get("form"))?.scan(this,this.#e())}listnavNext(e){this.#A(e,(t,r)=>t<0?0:(t+1)%r)}listnavPrev(e){this.#A(e,(t,r)=>t<0?r-1:(t-1+r)%r)}listnavFirst(e){this.#A(e,()=>0)}listnavLast(e){this.#A(e,(t,r)=>r-1)}listnavPick(e){let t=this.#y(e),r=t.findIndex((n)=>n.hasAttribute("data-reactive-highlighted"));if(r<0)return;e.preventDefault(),t[r].click()}listnavClose(e){for(let t of this.#y(e))t.removeAttribute("data-reactive-highlighted")}#A(e,t){let r=this.#y(e);if(!r.length)return;e.preventDefault();let n=this.#ce(e),i=globalThis.document?.activeElement,o=n?r.findIndex((s)=>s===i||i!=null&&s.contains?.(i)):r.findIndex((s)=>s.hasAttribute("data-reactive-highlighted")),a=r[t(o,r.length)];if(n)a.focus?.();else{for(let s of r)s.removeAttribute("data-reactive-highlighted");a.setAttribute("data-reactive-highlighted","true")}a.scrollIntoView?.({block:"nearest"})}#ce(e){return(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-focus-param")==="true"}#y(e){let r=(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-option-param")??this.element.getAttribute("data-reactive-listnav-option-param");if(!r)return[];let n=this.#D();return Array.from(this.element.querySelectorAll(r)).filter((i)=>!i.hidden&&n(i))}#O(e,t,r,n,i,o,a){if(this.#i("reactive:before-dispatch",{action:t,params:this.#X(r),element:this.element},{cancelable:!0}).defaultPrevented)return;let c=Number(n)||0;if(c>0)return this.#le(e,c,t,r,o,a);let l=Number(i)||0;if(l>0)return this.#de(e,l,t,r,o,a);return this.#E(t,r,o,e,a)}#E(e,t,r,n,i){let o={inverse:null,undo:[],resurrect:null},a=this.#Fe(e,n,o),s=Boolean(r||i),c=(f)=>{if(!s||!f)return;let g=this.#e();if(o.inverse=f.optimistic(this,g,r,n),o.undo.push(...f.busy(this,g,i,n)),this.#C())o.resurrect=f.resurrection(this,g,r,n)},l=m.get("hints");if(!s||l)c(l);let h=()=>this.#ye(e,t,o,a),d=()=>this.#r?this.#r.then(h):h();return this.queue=(this.queue??Promise.resolve()).then(()=>s&&!l?this.#ue().then(c).then(d):d()),this.queue}#ue(){return this.#H("hints")}#le(e,t,r,n,i,o){this.#M(e);let a=()=>{this.#M(e),this.#E(r,n,i,e,o)},s=setTimeout(a,t);e?.addEventListener?.("blur",a,{once:!0}),this.#_.set(e,{timer:s,flush:a})}#M(e){let t=this.#_.get(e);if(!t)return;clearTimeout(t.timer),e?.removeEventListener?.("blur",t.flush),this.#_.delete(e)}#fe(){for(let e of[...this.#_.keys()])this.#M(e)}#de(e,t,r,n,i,o){let a=this.#u.get(e)??new Map;if(a.has(r))return;let s=setTimeout(()=>{if(a.delete(r),a.size===0)this.#u.delete(e)},t);return a.set(r,s),this.#u.set(e,a),this.#E(r,n,i,e,o)}#he(){for(let e of this.#u.values())for(let t of e.values())clearTimeout(t);this.#u.clear()}#i(e,t,{cancelable:r=!1}={}){let n=new CustomEvent(e,{bubbles:!0,composed:!0,cancelable:r,detail:t});return(this.element.isConnected?this.element:document).dispatchEvent(n),n}#s(e,t,r,n){let i=()=>{if(!this.element.isConnected){console.warn("[phlex-reactive] retry() ignored — the reactive root left the DOM");return}return this.#E(e,t)};this.#i("reactive:error",{action:e,params:r,...n,retry:i})}#n(e){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",e)}#me(){this.element?.removeAttribute?.("data-reactive-error")}#pe(){let e=document.querySelector("[data-reactive-error-flash]");if(!e?.content)return;let t=e.getAttribute("data-reactive-error-flash")||"flash",r=document.getElementById(t);if(!r)return;r.appendChild(e.content.cloneNode(!0))}#ge(){{let e=m.get("devtools");if(e)return e.delay();if(ae())return E("devtools").then((t)=>t.delay(),()=>{})}}#C(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#G(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}async#ye(e,t,r,n){let{fields:i,files:o}=this.#Y(),a=this.#X(t),s={...i,...a},c=this.#o,l=o.length>0,h=l?this.#we(c,e,s,o):JSON.stringify({token:c,act:e,params:s}),d=this.#C()?{action:e,paramNames:Object.keys(a),fieldNames:Object.keys(i),encoding:l?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#G()}:null;await this.#ge();try{if(navigator.onLine===!1){this.#a(r.inverse),this.#n("offline"),this.#s(e,t,s,{kind:"offline"});return}let f;try{let p={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#Pe()};if(!l)p["Content-Type"]="application/json";let A=this.#Ie();if(A)p["X-Pgbus-Connection"]=A;he("action"),f=await fetch(this.#Re(),{method:"POST",headers:p,body:h,credentials:"same-origin",signal:AbortSignal.timeout(this.#xe())})}catch(p){if(console.error("[phlex-reactive] action error",p),this.#a(r.inverse),p?.name==="TimeoutError"||p?.name==="AbortError"){this.#n("timeout"),this.#s(e,t,s,{kind:"timeout"});return}this.#pe(),this.#n("network"),this.#s(e,t,s,{kind:"network"});return}if(d)d.status=f.status;if(f.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#a(r.inverse),this.#n("redirected"),this.#s(e,t,s,{kind:"redirected",status:f.status});return}if(!f.ok){let p=await f.text();if(console.error(`[phlex-reactive] action failed: HTTP ${f.status}`,p),this.#a(r.inverse),(f.headers.get("Content-Type")||"").includes("turbo-stream")){let A=this.#V(p);if(this.#o=A??this.#o,d)this.#b((Te)=>Te.recordBody(d,p,A));window.Turbo.renderStreamMessage(p)}this.#n("http"),this.#s(e,t,s,{kind:"http",status:f.status,body:p});return}let g=f.headers.get("Content-Type")||"";if(!g.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${g}" — no update applied`),this.#a(r.inverse),this.#n("content-type"),this.#s(e,t,s,{kind:"content-type",status:f.status});return}let y=await f.text(),T=this.#V(y);if(this.#o=T??this.#o,d)this.#b((p)=>p.recordBody(d,y,T));if(window.Turbo.renderStreamMessage(y),r.resurrect)queueMicrotask(r.resurrect);this.#me(),this.#i("reactive:applied",{action:e,params:s,html:y})}catch(f){console.error("[phlex-reactive] action error",f),this.#a(r.inverse),this.#i("reactive:error",{action:e,params:s,kind:"apply"})}finally{if(n?.(),d)this.#b((f)=>f.trace(this,{...d,ms:this.#G()-d.started}))}}get#o(){return this.#v??this.tokenValue}set#o(e){this.#v=e}tokenValueChanged(){this.#v=void 0}#V(e){let t=this.element.id;if(!t)return e.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:r,self:n}=this.#be(t),i=e.match(r);if(i)return i[1];let o=e.match(n);if(o)return o[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#be(e){let t=this.#W;if(t&&t.id===e)return t;let r=Ce(e);return this.#W={id:e,token:new RegExp(`<turbo-stream\\b[^>]*\\baction="reactive:token"[^>]*\\btarget="${r}"[^>]*\\bdata-reactive-token-value="([^"]+)"`),self:new RegExp(`<turbo-stream\\b[^>]*\\baction="(?:replace|update)"[^>]*\\btarget="${r}"[^>]*>([\\s\\S]*?)</turbo-stream>`)}}#F(e){return e.closest('[data-controller~="reactive"]')===this.element}#D(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(t)=>this.#F(t)}#Y(){let e={},t=[],r=this.#D(),n=[];this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((s)=>{if(!r(s))return;if(s.type==="file")for(let c of s.files??[])t.push({name:s.name,file:c,multiple:s.multiple});else n.push(s)});let i=[];this.element.querySelectorAll(`[name]${We}`).forEach((s)=>{if(r(s))i.push(s)});let o=this.#ve(n),a=this.#_e(n);for(let s of n)if(o.has(s.name)){let c=e[s.name]??(e[s.name]=[]);if(s.type==="checkbox"||s.type==="radio"){if(s.checked)c.push(s.value)}else if(s.type==="hidden"){if(!a.has(s.name))c.push(s.value)}else if(s.multiple&&s.options){for(let l of s.options)if(l.selected)c.push(l.value)}else c.push(s.value)}else if(s.type==="checkbox")e[s.name]=s.checked;else if(s.type==="radio"){if(s.checked)e[s.name]=s.value}else e[s.name]=s.value;return i.forEach((s)=>{let c=s.getAttribute("name");if(!c)return;let l=s.value??s.textContent??s.innerHTML??"",h=e[c];if(String(c).endsWith("[]")&&!Je(s))return;if(String(c).endsWith("[]")&&(h===void 0||Array.isArray(h))){(Array.isArray(h)?h:e[c]=[]).push(l);return}if(h==null||h==="")e[c]=l}),{fields:e,files:t}}#ve(e){let t=new Set;for(let r of e){if(r.type==="radio")continue;if(String(r.name).endsWith("[]"))t.add(r.name)}return t}#_e(e){let t=new Set;for(let r of e)if(r.type==="checkbox")t.add(r.name);return t}#we(e,t,r,n){let i=new FormData;i.append("token",e),i.append("act",t);let o=[];for(let[s,c]of Object.entries(r))if(Array.isArray(c)&&String(s).endsWith("[]"))if(c.length===0)o.push(String(s).slice(0,-2));else{let l=`${this.#k(s)}[]`;for(let h of c)i.append(l,String(h))}else this.#q(i,this.#k(s),c);for(let s of o)i.append("empty_groups[]",s);let a=this.#Se(n);for(let{name:s,file:c,multiple:l}of n){let d=l||a.has(s)?`${this.#k(s)}[]`:this.#k(s);i.append(d,c,c.name)}return i}#k(e){let t=String(e),r=t.indexOf("[");if(r===-1)return`params[${t}]`;return`params${[t.slice(0,r),...t.slice(r).match(/[^\[\]]+/g)??[]].map((i)=>`[${i}]`).join("")}`}#q(e,t,r){if(r==null)e.append(t,"");else if(Array.isArray(r))r.forEach((n,i)=>this.#q(e,`${t}[${i}]`,n));else if(typeof r==="object")for(let[n,i]of Object.entries(r))this.#q(e,`${t}[${n}]`,i);else e.append(t,String(r))}#Se(e){let t=new Map;for(let{name:r}of e)t.set(r,(t.get(r)??0)+1);return new Set([...t].filter(([,r])=>r>1).map(([r])=>r))}#X(e){if(!e)return{};try{return typeof e==="string"?JSON.parse(e):e}catch{return{}}}#Te(e){return j(e)}#Ae(e){q(e,(t)=>this.#j(t),(t,r)=>this.#B(`client op "${t}"`,r))}#$(){return this.element?.getAttribute?.("data-reactive-verbose")==="true"||this.#C()}#B(e,t){if(!this.#$())return;this.#b((r)=>r.diagnose(this,e,t))}#b(e){b("devtools",e)}#j(e){let t=e.to;if(t==="@root")return[this.element];if(typeof t!=="string"||t==="")return[];if(e.global)return[...document.querySelectorAll(t)];return[...this.element.querySelectorAll(t)].filter((r)=>this.#F(r))}#Ee(e,t){if(e?.checked!=="keep")return!1;let r=t?.type;return r==="checkbox"||r==="radio"}#a(e){if(!e)return;if(!this.element.isConnected)return;for(let t of e)t()}#Fe(e,t,r){this.#ke(e,t),ue();let n=!1;return()=>{if(n)return;n=!0,this.#Le(e,t),le();for(let i of r.undo)i()}}#ke(e,t){if(this.#c(t,e,1),this.#c(this.element,e,1),this.#l.set(e,(this.#l.get(e)??0)+1),this.#R++===0)this.element.setAttribute("aria-busy","true");for(let r of this.#Z(e))this.#c(r,e,1)}#Le(e,t){this.#c(t,e,-1),this.#c(this.element,e,-1);let r=(this.#l.get(e)??1)-1;if(r<=0)this.#l.delete(e);else this.#l.set(e,r);if(--this.#R<=0)this.#R=0,this.element.removeAttribute("aria-busy");for(let n of this.#Z(e))this.#c(n,e,-1)}#c(e,t,r){if(!e||typeof e.getAttribute!=="function")return;let n=this.#x.get(e)??new Map,i=(n.get(t)??0)+r;if(i<=0)n.delete(t);else n.set(t,i);if(n.size===0){this.#x.delete(e),e.removeAttribute("data-reactive-busy");return}this.#x.set(e,n),e.setAttribute("data-reactive-busy",[...n.keys()].join(" "))}#Z(e){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((r)=>r.getAttribute("data-reactive-busy-on")===e&&this.#F(r))}#Re(){return this.#Q??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#xe(){if(this.#L!=null)return this.#L;let e=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,t=Number(e);return this.#L=Number.isFinite(t)&&t>0?t:30000}#Pe(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#Ie(){return document.querySelector("pgbus-stream-source[connection-id]")?.getAttribute("connection-id")||document.querySelector('meta[name="pgbus-connection-id"]')?.content||null}}if(typeof window<"u")if(window.Turbo)G();else document.addEventListener("turbo:load",G,{once:!0});w("persist",()=>import("phlex/reactive/features/persist"),yt);w("defer",()=>import("phlex/reactive/features/defer"));w("form",()=>import("phlex/reactive/features/form"));w("bindings",()=>import("phlex/reactive/features/bindings"));w("compute",()=>import("phlex/reactive/features/compute"),bt);w("effects",()=>import("phlex/reactive/features/effects"));w("hints",()=>import("phlex/reactive/features/hints"));w("devtools",()=>import("phlex/reactive/features/devtools"));B();function yt(e,t){let r=()=>{t.edited=!0},n=(o)=>{let a=o.target;if(o.detail?.success&&a?.tagName==="FORM"&&a.contains?.(e))t.submitted=!0},i=["input","change","lexxy:change","trix-change"];for(let o of i)e.addEventListener?.(o,r);return document.addEventListener("turbo:submit-end",n),()=>{for(let o of i)e.removeEventListener?.(o,r);document.removeEventListener("turbo:submit-end",n)}}function bt(e,t){let r=()=>{t.edited=!0};return e.addEventListener?.("input",r),e.addEventListener?.("change",r),()=>{e.removeEventListener?.("input",r),e.removeEventListener?.("change",r)}}var vt=1000,S=null,Se,P=new Set;function _t(e){return ve(e).then((t)=>{if(e!=="effects")return;Se=t,t?.sweep()})}oe((e,t)=>{let r=e.detail,n=r?.render;if(typeof n!=="function")return;let i=r.newStream??e.target,o=be(wt(i)).filter((s)=>!P.has(s));if(!t&&!P.has("effects")&&St(i))o.push("effects");if(o.length===0&&!S)return t?.wrap(e);if(o.length>0){for(let c of o)P.add(c);let s=S=Promise.race([Promise.all([S,...o.map(_t)]),new Promise((c)=>setTimeout(c,vt))]).then(()=>{if(S!==s)return;S=null,P.clear()})}let a=S;r.render=async(s)=>{await a;let c={target:e.target,detail:{newStream:r.newStream,render:n}};(t??Se)?.wrap(c),await c.detail.render(s)}});function wt(e){let t=e?.querySelector?.("template")?.content;if(!t)return[];let r=[...t.querySelectorAll?.('[data-controller~="reactive"]')??[]];for(let n of t.children??[])if(n.matches?.('[data-controller~="reactive"]')&&!r.includes(n))r.unshift(n);return r}function St(e){return Boolean(e?.hasAttribute?.("data-reactive-effect")||document.getElementById?.(e?.getAttribute?.("target"))?.matches?.("[data-reactive-effect-update],[data-reactive-effect-exit]")||e?.querySelector?.("template")?.content?.querySelector?.("[data-reactive-effect-enter],[data-reactive-dismiss-after]")||document.querySelector?.("[data-reactive-dismiss-after]:not([data-reactive-dismiss-scheduled])"))}var Mt=we;export{ce as ACTIVE_ATTR,We as EDITOR_SELECTOR,Ue as EDITOR_TAGS,de as REQUESTS_ATTR,De as checkReactiveRegistration,he as countReactiveRequest,Mt as default,ue as enterReactiveActivity,Ce as escapeRegExp,le as exitReactiveActivity,ve as loadReactiveFeature,oe as onReactiveStreamWithoutEffects,Ft as reactiveActivityCount,Rt as reactiveFeatureNames,G as registerReactiveActions,Le as registerReactiveDefer,B as registerReactiveDev,Re as registerReactiveDismiss,Re as registerReactiveEffects,Lt as registerReactiveFeature,w as registerReactiveFeatureLoader,ke as registerReactiveJs,xe as registerReactiveMorphFocus,Ie as registerReactiveOffline,Re as registerReactiveStreamRender,Fe as registerReactiveToken,Ee as registerReactiveVisit,kt as resetReactiveActivity,be as unloadedFeaturesFor};
2
2
 
3
- //# debugId=9AF39057384FC9A664756E2164756E21
3
+ //# debugId=A64326901A33E83A64756E2164756E21
4
4
  //# sourceMappingURL=core.min.js.map