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 +4 -4
- data/CHANGELOG.md +24 -0
- data/README.md +25 -2
- data/app/javascript/phlex/reactive/core.min.js +2 -2
- data/app/javascript/phlex/reactive/core.min.js.map +3 -3
- data/app/javascript/phlex/reactive/features/bindings.js +10 -2
- data/app/javascript/phlex/reactive/features/bindings.min.js +2 -2
- data/app/javascript/phlex/reactive/features/bindings.min.js.map +3 -3
- data/app/javascript/phlex/reactive/reactive_controller.min.js +2 -2
- data/app/javascript/phlex/reactive/reactive_controller.min.js.map +4 -4
- data/app/javascript/phlex/reactive/runtime.js +20 -2
- data/lib/phlex/reactive/component/helpers.rb +52 -3
- data/lib/phlex/reactive/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f4b8ab0285b176f4fab5221687a3d3364e2311eaa4c08c091eef07763cf22a8e
|
|
4
|
+
data.tar.gz: 9072c2d1b802438c7f39c694753308020d65e9a20e38c1ee4f730351b25de49d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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=
|
|
3
|
+
//# debugId=A64326901A33E83A64756E2164756E21
|
|
4
4
|
//# sourceMappingURL=core.min.js.map
|