phlex-reactive 0.16.6 → 0.16.8

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.
@@ -68,6 +68,7 @@ export function connect(controller, core) {
68
68
  // here, and again from reseed() — a stream can render a root's first show
69
69
  // target, filter or nested list into it after connect (issue #356).
70
70
  let resetting
71
+ let sharing
71
72
  let filtering
72
73
  let tagging
73
74
  let serializing
@@ -105,10 +106,11 @@ export function connect(controller, core) {
105
106
  listen(c, "input change", c.show)
106
107
  // The after: gate (issue #396): an owned field's first blur marks its
107
108
  // name touched for this controller (a morph keeps it, a new one starts
108
- // without), and re-syncs once if a binding waits on a blur.
109
+ // without), and re-syncs once if a binding waits on a blur. A shared
110
+ // field just below counts as owned here (issue #440).
109
111
  listen(c, "focusout", (event) => {
110
112
  const name = event.target?.getAttribute?.("name")
111
- if (!name || c.touched?.has(name) || !c.core.owns(event.target)) return
113
+ if (!name || c.touched?.has(name) || !c.core.bindingOwns(event.target)) return
112
114
  ;(c.touched ??= new Set()).add(name)
113
115
  if (c.root.querySelector?.("[data-reactive-show-after]")) syncShow(c)
114
116
  })
@@ -151,6 +153,21 @@ export function connect(controller, core) {
151
153
  )
152
154
  }
153
155
 
156
+ // Issue #440: a nested root that comes back through a plain replace (a
157
+ // morph already bubbles turbo:morph-element here) brings a fresh shared
158
+ // field: a hidden disable: true group must disable it again, and the
159
+ // bindings read its new value. So does one whose draft restore wrote its
160
+ // fields without an input event. Each announces itself with a bubbling
161
+ // event; only a root holding a shared field this root reads (one level,
162
+ // core.bindingOwns) re-syncs it.
163
+ if (!sharing && (sharing = c.show || c.arm)) {
164
+ listen(c, "reactive:connect reactive:persist-restored", (event) => {
165
+ if (event.target === c.root || !sharedWith(c, event.target)) return
166
+ c.show?.()
167
+ c.arm?.()
168
+ })
169
+ }
170
+
154
171
  // Option filtering (issue #163) — ONLY when the root declares the binding
155
172
  // (reactive_filter emits both attrs together), so a component without one
156
173
  // pays two attribute reads. ONE delegated input listener on the root — the
@@ -201,6 +218,11 @@ export function connect(controller, core) {
201
218
  listen(c, "input", (event) => editableEmptied(c, event))
202
219
  }
203
220
 
221
+ // Whether `root` holds a shared field this root's bindings read (issue #440).
222
+ function sharedWith(c, root) {
223
+ return [...(root.querySelectorAll?.("[data-reactive-shared-field]") ?? [])].some(c.core.bindingOwns)
224
+ }
225
+
204
226
  // Remove every listener connect() added, so a stray event after a Turbo
205
227
  // morph/navigation never re-evaluates against a detached root.
206
228
  export function disconnect(controller) {
@@ -423,7 +445,7 @@ function syncOnComplete(c, event) {
423
445
  const bindings = onCompleteBindings(c)
424
446
  if (!bindings.length) return
425
447
 
426
- const fieldValue = fieldResolver(c, c.core.ownership())
448
+ const fieldValue = fieldResolver(c, c.core.bindingOwnership())
427
449
  bindings.forEach((binding, i) => {
428
450
  const matches = anyOfAllsMatches(binding.any, fieldValue)
429
451
  if (matches === null) return
@@ -443,15 +465,21 @@ function syncOnComplete(c, event) {
443
465
  // pass). A binding whose field can't be resolved, or whose predicate is
444
466
  // malformed, leaves visibility ALONE — a bad binding must never break or
445
467
  // blank the page (client-side default-deny).
468
+ //
469
+ // Two predicates (issue #440): `owns` picks the binding ELEMENTS this root
470
+ // evaluates (a nested root's are its own); `reads` picks the FIELDS they read,
471
+ // and the controls disable:/clear: may write: this root's own, plus a control
472
+ // marked data-reactive-shared-field just below (core.bindingOwnership).
446
473
  function syncShow(c) {
447
474
  if (typeof c.root?.querySelectorAll !== "function") return
448
475
 
449
476
  const owns = c.core.ownership()
477
+ const reads = c.core.bindingOwnership()
450
478
  const scope = c.root.getAttribute?.("data-reactive-scope") || null
451
479
  // A memoized resolver shared by every binding in this pass — a field driving
452
480
  // several bindings (and several DNF terms) reads exactly once. Scope-aware:
453
481
  // a bare field `director` resolves as `[name="scope[director]"]` (issue #180).
454
- const fieldValue = fieldResolver(c, owns)
482
+ const fieldValue = fieldResolver(c, reads)
455
483
  // Bindings whose visibility flipped this pass and that declare transition
456
484
  // work (issue #394) — run after the pass, so the `input` a clear dispatches
457
485
  // re-syncs from fresh values instead of this pass's memo.
@@ -469,7 +497,7 @@ function syncShow(c) {
469
497
  // after: (issue #396) keeps it hidden until its field has blurred once.
470
498
  const after = el.getAttribute("data-reactive-show-after")
471
499
  const visible = match && (after == null || !!c.touched?.has(wireName(after, scope)))
472
- applyShowVisibility(el, visible, owns, scope)
500
+ applyShowVisibility(el, visible, reads)
473
501
  // The previous visibility lives on this controller (absent on connect,
474
502
  // kept by a morph), so first paint never counts as a change.
475
503
  // Tracked for every binding, so a morph that drops the transition attrs
@@ -488,17 +516,17 @@ function syncShow(c) {
488
516
  if (value === null) continue // no owned field with that name — leave it be
489
517
  const match = showBindingMatches(el, value)
490
518
  if (match === null) continue // malformed predicate — warned + skipped
491
- applyShowVisibility(el, match, owns, scope)
519
+ applyShowVisibility(el, match, reads)
492
520
  }
493
521
 
494
522
  // The group bindings (issue #319) and the cross-root pass (issue #164)
495
523
  // share the same owned-field memo, so a field driving several reads once.
496
524
  if (c.groups) syncGroups(c, fieldValue, owns, scope)
497
525
  syncMedia(c, fieldValue, owns)
498
- syncCssVars(c, fieldValue, owns, scope)
526
+ syncCssVars(c, fieldValue, owns, scope, reads)
499
527
  syncShowTargets(c, fieldValue)
500
528
  syncGroupTargets(c, fieldValue)
501
- for (const el of moved) showMoved(c, el, owns, scope)
529
+ for (const el of moved) showMoved(c, el, reads, scope)
502
530
  }
503
531
 
504
532
  // The transition attrs a show binding may declare (issue #394).
@@ -542,8 +570,9 @@ function showMoved(c, el, owns, scope) {
542
570
  // the `disabled` of every owned named control inside it) from a match result
543
571
  // (issue #180). Disabling a hidden section's controls stops them submitting —
544
572
  // the stale-value fix. A visible section re-enables them. Controls a nested
545
- // reactive root owns are left alone (#15 ownership).
546
- function applyShowVisibility(el, match, owns, scope) {
573
+ // reactive root owns are left alone (#15 ownership), except one marked
574
+ // data-reactive-shared-field: it declared itself the host's too (issue #440).
575
+ function applyShowVisibility(el, match, owns) {
547
576
  el.hidden = !match
548
577
  if (el.getAttribute("data-reactive-show-disable") !== "true") return
549
578
  if (typeof el.querySelectorAll !== "function") return
@@ -556,8 +585,9 @@ function applyShowVisibility(el, match, owns, scope) {
556
585
 
557
586
  // Apply the declared cross-root show targets (issue #164) — the visibility
558
587
  // parallel of #applyComputeMirrors. For each declared field: read the OWNED
559
- // field's current value (never a nested root's — you can only drive outside
560
- // visibility from a field this root owns), then for each "#id" → predicate
588
+ // field's current value (never a nested root's, except a shared field just
589
+ // below, issue #440 — you can only drive outside visibility from a field this
590
+ // root reads), then for each "#id" → predicate
561
591
  // entry: guard the selector id-only (warn-and-skip; the Ruby helper raised
562
592
  // at declare time — two-sided default-deny), resolve it DOCUMENT-WIDE, and
563
593
  // toggle `hidden`. A target id not on the page is silently skipped (an
@@ -694,7 +724,9 @@ function wireName(name, scope) {
694
724
  // The per-pass field resolver every DNF fold reads (show, enable, on-complete).
695
725
  // fieldValue(name) is the field's string value; fieldValue(name, true) is how
696
726
  // many owned boxes of that checkbox group are ticked (the checked_* terms,
697
- // issue #319). Memoized, so a field driving several bindings reads once.
727
+ // issue #319). `owns` is what the bindings read: core.bindingOwnership, so a
728
+ // shared field just below counts as owned (issue #440). Memoized, so a field
729
+ // driving several bindings reads once.
698
730
  function fieldResolver(c, owns) {
699
731
  const scope = c.root.getAttribute?.("data-reactive-scope") || null
700
732
  const values = new Map()
@@ -795,7 +827,7 @@ const CSS_VARS_SELECTOR = "[data-reactive-css-vars]"
795
827
  const CSS_VAR_NAME = /^--[a-z0-9-]+$/i
796
828
  const CSS_VAR_UNITS = ["", "px", "%", "deg", "turn", "ms", "s", "em", "rem", "fr"]
797
829
 
798
- function syncCssVars(c, fieldValue, owns, scope) {
830
+ function syncCssVars(c, fieldValue, owns, scope, reads) {
799
831
  const nodes = [...c.root.querySelectorAll(CSS_VARS_SELECTOR)].filter(owns)
800
832
  if (c.root.hasAttribute("data-reactive-css-vars")) nodes.unshift(c.root)
801
833
  for (const el of nodes) {
@@ -825,7 +857,7 @@ function syncCssVars(c, fieldValue, owns, scope) {
825
857
  console.warn(`[phlex-reactive] refused reactive_css_vars entry ${JSON.stringify(name)} — skipped`)
826
858
  continue
827
859
  }
828
- const number = cssVarNumber(c, fieldValue, spec.field, owns, scope)
860
+ const number = cssVarNumber(c, fieldValue, spec.field, reads, scope)
829
861
  if (number === undefined) continue
830
862
  const value = number === null ? "" : `${number}${unit}`
831
863
  for (const target of targets) {
@@ -872,7 +904,9 @@ function hasGroups(c) {
872
904
  }
873
905
 
874
906
  // The owned checkboxes of a group (a nested root's boxes are its own, #15).
875
- // With `under` (a nested header, issue #398) only the boxes whose
907
+ // `owns` decides which: strict for a select-all header and the boxes it
908
+ // ticks; core.bindingOwnership for a count, which takes a shared box just
909
+ // below too (issue #440). With `under` (a nested header, issue #398) only the boxes whose
876
910
  // data-reactive-group is that path or below it, on whole segments.
877
911
  function groupBoxes(c, name, owns, scope, under) {
878
912
  return [...c.root.querySelectorAll(namedSelector(name, scope))].filter(
@@ -957,7 +991,8 @@ function syncGroups(c, fieldValue, owns, scope) {
957
991
  // The declared cross-root group targets (issue #343) — the count and enable
958
992
  // parallel of syncShowTargets, declared on the root that OWNS the group:
959
993
  // { group: { count: ["#id", …], enable: { "#id": { any: … } } } }. The count
960
- // is this root's owned ticked boxes (a nested root's are its own, #15), the
994
+ // is this root's owned ticked boxes (a nested root's are its own, #15, except
995
+ // a shared box just below, issue #440), the
961
996
  // enable folds its DNF payload with the same owned-field memo as every other
962
997
  // binding. Targets are id-only (warn-skip — the Ruby helper raised at
963
998
  // declare time) and resolved document-wide; a missing one is skipped.
@@ -1,4 +1,4 @@
1
- import{confirmPredicate as de}from"phlex/reactive/confirm_predicate";var v=new WeakMap,k=new WeakMap;function h(e,r){let t=v.get(e);if(!t){if(v.set(e,t={root:e.element,core:r,nestedIndex:0}),t.root)k.set(t.root,t)}return t}function g(e,r,t){for(let n of r.split(" "))e.root.addEventListener?.(n,t),e.offs.push(()=>e.root.removeEventListener?.(n,t))}function b(e,r){g(e,"turbo:morph-element",r),e.seeds.push(r),r()}function ot(e,r){let t=h(e,r);t.offs=[],t.seeds=[];let n,o,i,a;(t.wire=()=>{if(!t.show&&ve(t))t.show=(s)=>{if(t.flipping)return;if(s?.type==="input"||s?.type==="change")Re(t,s.target);else t.groups=Ee(t),F(t);L(t)},g(t,"input change",t.show),g(t,"focusout",(s)=>{let c=s.target?.getAttribute?.("name");if(!c||t.touched?.has(c)||!t.core.owns(s.target))return;if((t.touched??=new Set).add(c),t.root.querySelector?.("[data-reactive-show-after]"))L(t)}),b(t,t.show);if(!t.arm&&me(t))g(t,"input change",(s)=>D(t,s)),b(t,t.arm=()=>{D(t,null),F(t)});if(!n&&(n=t.show||t.arm))g(t,"reset",()=>setTimeout(()=>{if(v.get(e)!==t)return;t.show?.(),t.arm?.()},0));if(!o&&(o=x(t)))g(t,"input",(s)=>Te(t,s)&&A(t)),b(t,()=>A(t));if(!i&&(i=N(t)))b(t,()=>te(t));if(!a&&(a=De(t)))g(t,"input change",(s)=>ie(t,s)),b(t,()=>T(t))})(),g(t,"keydown",(s)=>et(t,s)),g(t,"paste drop",(s)=>tt(t,s)),g(t,"input",(s)=>rt(t,s))}function it(e){let r=v.get(e);if(!r)return;v.delete(e),k.delete(r.root);for(let t of r.offs??[])t();r.groupObserver?.disconnect()}function st(e){let r=v.get(e);if(!r)return;for(let t of r.seeds)t();r.wire()}function y(e){if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}function at(e,r,t){return ie(h(e,r),t)}function ct(e,r,t){return ue(h(e,r),t)}var pe=/^#[A-Za-z_][\w-]*$/,K="[data-reactive-show-field], [data-reactive-show]";function ge(e,r){let t=e.getAttribute("data-reactive-show-equals");if(t!==null)return r===t;let n=e.getAttribute("data-reactive-show-not");if(n!==null)return r!==n;let o=e.getAttribute("data-reactive-show-in");if(o!==null){try{let i=JSON.parse(o);if(Array.isArray(i))return i.includes(r)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify(o)} — skipped`),null}for(let i of se){let a=e.getAttribute(`data-reactive-show-${i}`);if(a!==null)return ce(i,a,r)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}function H(e){try{let r=JSON.parse(e);if(r&&typeof r==="object"&&!Array.isArray(r))return r}catch{}return console.warn(`[phlex-reactive] malformed compound reactive_show payload ${JSON.stringify(e)} — skipped`),null}function he(e){try{let r=JSON.parse(e);if(Array.isArray(r)&&r.every((t)=>t&&typeof t==="object"&&Array.isArray(t.any)&&Array.isArray(t.ops)))return r}catch{}return console.warn(`[phlex-reactive] malformed reactive_on_complete payload ${JSON.stringify(e)} — skipped`),[]}function V(e,r){if(!e||typeof e!=="object")return null;let t=e.any;if(Array.isArray(t)&&(t.length===0||Array.isArray(t[0])))return w(t,r);return ye(e,r)}function ye(e,r){let t=Array.isArray(e.all)?"all":Array.isArray(e.any)?"any":null;if(!t)return null;let n=e[t];if(n.length===0)return null;let o=n.map((i)=>J(i,r));return t==="all"?o.every(Boolean):o.some(Boolean)}function S(e,r="show"){if(typeof e==="string"&&pe.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root ${r} target ${JSON.stringify(e)} — skipped`),!1}function ve(e){if(e.root.getAttribute?.("data-reactive-show-targets"))return!0;if(e.root.getAttribute?.("data-reactive-group-targets"))return!0;let r=e.root.querySelectorAll?.(K)??[];for(let t of r)if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(_)??[])if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(`${U}, ${Z}`)??[])if(e.core.owns(t))return!0;return e.root.hasAttribute?.("data-reactive-css-vars")??!1}function me(e){return!!e.root.getAttribute?.("data-reactive-on-complete")}function be(e){let r=e.root.getAttribute?.("data-reactive-on-complete")??null;if(r!==e.onCompleteRaw)e.onCompleteRaw=r,e.onCompleteParsed=r==null?[]:he(r),e.onCompleteStates=e.onCompleteParsed.map(()=>!1);return e.onCompleteParsed}function D(e,r){let t=be(e);if(!t.length)return;let n=Y(e,e.core.ownership());t.forEach((o,i)=>{let a=w(o.any,n);if(a===null)return;let s=a&&!e.onCompleteStates[i]&&Boolean(r);if(e.onCompleteStates[i]=a,s)e.core.applyOps(o.ops,"@root")})}function L(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.core.ownership(),t=e.root.getAttribute?.("data-reactive-scope")||null,n=Y(e,r),o=[];for(let i of e.root.querySelectorAll(K)){if(!r(i))continue;let a=i.getAttribute("data-reactive-show");if(a!==null){let u=V(H(a),n);if(u===null)continue;let d=i.getAttribute("data-reactive-show-after"),f=u&&(d==null||!!e.touched?.has(E(d,t)));W(i,f,r,t);let p=(e.shown??=new WeakMap).get(i);if(e.shown.set(i,f),Ae.some((fe)=>i.hasAttribute(`data-reactive-show-${fe}`))&&p!==void 0&&p!==f)o.push(i);continue}let s=i.getAttribute("data-reactive-show-field");if(!s)continue;let c=n(s);if(c===null)continue;let l=ge(i,c);if(l===null)continue;W(i,l,r,t)}if(e.groups)je(e,n,r,t);Ne(e,n,r),ke(e,n,r,t),Se(e,n),Me(e,n);for(let i of o)we(e,i,r,t)}var Ae=["clear","focus","scroll"];function we(e,r,t,n){if(r.hidden){let s=[];try{s=JSON.parse(r.getAttribute("data-reactive-show-clear")??"[]")}catch{}let c=new Set((Array.isArray(s)?s:[]).map((l)=>E(String(l),n)));for(let l of c.size?e.root.querySelectorAll("[name]"):[]){if(!c.has(l.getAttribute("name"))||!t(l)||l.type==="file")continue;if(l.type==="checkbox"||l.type==="radio"){if(l.checked)l.checked=!1,y(l)}else e.core.setValue(l,"")}return}let o=r.getAttribute("data-reactive-show-scroll")==="true";if(o)r.scrollIntoView?.({block:"nearest"});let i=r.getAttribute("data-reactive-show-focus"),a=null;try{a=i?e.root.querySelector(i):null}catch{}a?.focus?.(o?{preventScroll:!0}:void 0)}function W(e,r,t,n){if(e.hidden=!r,e.getAttribute("data-reactive-show-disable")!=="true")return;if(typeof e.querySelectorAll!=="function")return;for(let o of e.querySelectorAll("input[name], select[name], textarea[name]"))if(t(o))o.disabled=!r;if(e.name&&t(e))e.disabled=!r}function Se(e,r){let t=z(e);for(let[n,o]of Object.entries(t)){if(n.startsWith("#")){xe(n,o,r);continue}if(!o||typeof o!=="object"||Array.isArray(o))continue;let i=r(n);if(i===null)continue;let a=(s,c)=>c?r(n,!0):i;for(let[s,c]of Object.entries(o)){if(!S(s))continue;let l;if(Array.isArray(c)){if(c.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${s} — skipped`);continue}l=c.every((u)=>J(u,a))}else{let u=le(c,i);if(u===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${s} — skipped`);continue}l=u}for(let u of document.querySelectorAll(s))u.hidden=!l}}}function xe(e,r,t){if(!S(e))return;let n=r&&typeof r==="object"&&!Array.isArray(r)?r.any:null,o=Qe(n);if(o===null){console.warn(`[phlex-reactive] malformed reactive_show_targets conditions for ${e} — skipped`);return}if(o.every((a)=>t(a)===null)&&!Xe(n))return;let i=w(n,t);if(i===null)return;for(let a of document.querySelectorAll(e))a.hidden=!i}function z(e,r="show",t="mode: { ... }, kind: { ... }"){let n=e.root.getAttribute?.(`data-reactive-${r}-targets`);if(!n)return{};try{let o=JSON.parse(n);if(o&&typeof o==="object"&&!Array.isArray(o))return o}catch{}return console.warn(`[phlex-reactive] malformed data-reactive-${r}-targets — ignored. `+`Did two reactive_${r}_targets calls collide on one root? Declare every entry in ONE call: reactive_${r}_targets(${t})`),{}}function _e(e,r,t,n){let o=!1,i=null;for(let a of e.root.querySelectorAll(q(r,n))){if(!t(a))continue;if(a.type==="checkbox")return a.checked?"true":"false";if(a.type==="radio"){if(a.checked)return a.value??"";o=!0;continue}i??=a}if(i)return i.value??"";return o?"":null}function q(e,r){return`[name="${E(e,r)}"]`}function E(e,r){return r&&!e.includes("[")?`${r}[${e}]`:e}function Y(e,r){let t=e.root.getAttribute?.("data-reactive-scope")||null,n=new Map;return(o,i)=>{let a=i?`#${o}`:o;if(!n.has(a))n.set(a,i?R(e,o,r,t).filter((s)=>s.checked).length:_e(e,o,r,t));return n.get(a)}}var U="[data-reactive-media]";function Ne(e,r,t){for(let n of e.root.querySelectorAll(U)){if(!t(n))continue;let o,i,a;try{if(o=JSON.parse(n.getAttribute("data-reactive-media")),o?.match!=null)i=new RegExp(`^(?:${o.match})$`);if(o?.when!=null)a=new RegExp(`^(?:${o.when})$`)}catch{}if(typeof o?.field!=="string"||!o.pool||typeof o.pool!=="object"||o.match!=null&&!i||o.when!=null&&!a){console.warn("[phlex-reactive] malformed data-reactive-media — skipped");continue}let s=r(o.field);if(s===null)continue;let c=o.take>0?[...s]:null,l=c?c.slice(0,o.take).join(""):s,u=c?.length<o.take||i?.test(l)===!1||a?.test(s)===!1;if(u&&o.pending==="keep"){P(n,"pending");continue}let d=!u&&Object.hasOwn(o.pool,l)?G(e,o.pool[l])[0]:null,f=e.core.copyMedia(n,d??null);if(f===null)continue;if(P(n,u?"pending":f===!1?"miss":"hit"),typeof o.label!=="string")continue;let p=u?"":f===!1?String(o.blank??""):f;for(let m of G(e,o.label))if(m.textContent!==p)m.textContent=p}}function P(e,r){if(e.getAttribute("data-reactive-media-state")!==r)e.setAttribute("data-reactive-media-state",r)}function G(e,r){try{return r==="@root"?[]:e.core.opTargets({to:r})}catch{return[]}}var Z="[data-reactive-css-vars]",Ce=/^--[a-z0-9-]+$/i,Oe=["","px","%","deg","turn","ms","s","em","rem","fr"];function ke(e,r,t,n){let o=[...e.root.querySelectorAll(Z)].filter(t);if(e.root.hasAttribute("data-reactive-css-vars"))o.unshift(e.root);for(let i of o){let a;try{a=JSON.parse(i.getAttribute("data-reactive-css-vars"))}catch{}if(!Array.isArray(a?.to)||!a.vars||typeof a.vars!=="object"){console.warn("[phlex-reactive] malformed data-reactive-css-vars — skipped (two reactive_css_vars on one element?)");continue}let s=a.to.flatMap((c)=>{let l={to:c,global:a.global===!0},u=[];try{u=e.core.opTargets(l)}catch{}if(!u.length)e.core.diagnose("reactive_css_vars",l);return u});for(let[c,l]of Object.entries(a.vars)){let u=l?.unit??"";if(!Ce.test(c)||!Oe.includes(u)||typeof l?.field!=="string"){console.warn(`[phlex-reactive] refused reactive_css_vars entry ${JSON.stringify(c)} — skipped`);continue}let d=qe(e,r,l.field,t,n);if(d===void 0)continue;let f=d===null?"":`${d}${u}`;for(let p of s){if(p.style.getPropertyValue(c)===f)continue;if(f)p.style.setProperty(c,f);else p.style.removeProperty(c)}}}}function qe(e,r,t,n,o){let i=r(t);if(i===null)return;if((i==="true"||i==="false")&&[...e.root.querySelectorAll(q(t,o))].some((s)=>n(s)&&s.type==="checkbox"))return i==="true"?1:0;let a=i.trim()?Number(i):NaN;return Number.isFinite(a)?a:null}var _="[data-reactive-enable], [data-reactive-select-all], [data-reactive-count]";function Ee(e){return!!e.root.querySelector?.(_)}function R(e,r,t,n,o){return[...e.root.querySelectorAll(q(r,n))].filter((i)=>i.type==="checkbox"&&t(i)&&(!o||$e(i.getAttribute("data-reactive-group"),o)))}function $e(e,r){return e===r||!!e?.startsWith(`${r}.`)}function Re(e,r){let t=r?.getAttribute?.("data-reactive-select-all");if(t&&e.core.owns(r))Q(e,t,r.checked,r,r.getAttribute("data-reactive-select-all-under"))}function lt(e,r,t){if(!r)return;let n=k.get(e)??{root:e,core:{ownership:()=>(o)=>o.closest('[data-controller~="reactive"]')===e}};Q(n,r,t!==!1),n.show?.()}function Q(e,r,t,n,o){let i=e.root.getAttribute?.("data-reactive-scope")||null,a=R(e,r,e.core.ownership(),i,o).filter((s)=>s!==n&&s.checked!==t);for(let s of a)s.checked=t;e.flipping=!0;try{for(let s of a)for(let c of["input","change"])s.dispatchEvent?.(new Event(c,{bubbles:!0}))}finally{e.flipping=!1}}function je(e,r,t,n){for(let o of e.root.querySelectorAll(_)){if(!t(o))continue;let i=o.getAttribute("data-reactive-enable");if(i!==null){let c=V(H(i),r);if(c!==null)o.disabled=!c}let a=o.getAttribute("data-reactive-count");if(a){let c=String(r(a,!0));if(o.textContent!==c)o.textContent=c}let s=o.getAttribute("data-reactive-select-all");if(s){let c=o.getAttribute("data-reactive-select-all-under"),l=R(e,s,t,n,c).filter((d)=>d!==o),u=l.filter((d)=>d.checked).length;o.checked=u>0&&u===l.length,o.indeterminate=u>0&&u<l.length}}}function Me(e,r){for(let[t,n]of Object.entries(z(e,"group",'"ids[]" => { ... }, "tags[]" => { ... }'))){if(!n||typeof n!=="object"||Array.isArray(n))continue;let o=String(r(t,!0));for(let a of Array.isArray(n.count)?n.count:[]){if(!S(a,"group"))continue;for(let s of document.querySelectorAll(a))if(s.textContent!==o)s.textContent=o}let i=n.enable&&typeof n.enable==="object"?n.enable:{};for(let[a,s]of Object.entries(i)){if(!S(a,"group"))continue;let c=w(s?.any,r);if(c===null){console.warn(`[phlex-reactive] malformed reactive_group_targets enable for ${a} — skipped`);continue}for(let l of document.querySelectorAll(a))l.disabled=!c}}}function F(e){if(e.groupObserver||typeof MutationObserver!=="function")return;let r=(o)=>e.root.getAttribute?.(`data-reactive-${o}`)?.includes("checked_");if(!e.root.getAttribute?.("data-reactive-group-targets")&&!e.root.querySelector?.(`${_}, [data-reactive-show*=checked_]`)&&!r("show-targets")&&!r("on-complete"))return;let n=(o)=>o.nodeType===1&&(o.matches('input[type="checkbox"]')||!!o.querySelector('input[type="checkbox"]'));e.groupObserver=new MutationObserver((o)=>{if(!o.some((i)=>[...i.addedNodes,...i.removedNodes].some(n)))return;e.show?.(),e.arm?.()}),e.groupObserver.observe(e.root,{childList:!0,subtree:!0})}function x(e){return!!(e.root.getAttribute?.("data-reactive-filter-input")&&e.root.getAttribute?.("data-reactive-filter-option"))}function Te(e,r){let t=e.root.getAttribute("data-reactive-filter-input");return!!t&&typeof r.target?.matches==="function"&&r.target.matches(t)}var Je=/[\s\-'(),./]/;function Ie(e,r,t){if(e==="prefix")return r.startsWith(t);if(e!=="word_start")return r.includes(t);for(let n=r.indexOf(t);n!==-1;n=r.indexOf(t,n+1))if(n===0||Je.test(r[n-1]))return!0;return!1}function A(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.root.getAttribute("data-reactive-filter-input"),t=e.root.getAttribute("data-reactive-filter-option");if(!r||!t)return;let n=e.core.ownership(),o=[...e.root.querySelectorAll(r)].find(n);if(!o)return;let i=e.root.getAttribute("data-reactive-filter-match"),a=e.root.hasAttribute?.("data-reactive-filter-fold"),s=(f)=>{let p=(f??"").toLowerCase().trim();return a?p.normalize("NFD").replace(/\p{M}/gu,""):p},c=s(o.value),l=0;for(let f of e.root.querySelectorAll(t)){if(!n(f))continue;let p=f.hasAttribute?.("data-reactive-tags-selected")||c!==""&&!Ie(i,s(f.getAttribute("data-reactive-filter-text")??f.textContent),c);if(f.hidden=p,p)f.removeAttribute("data-reactive-highlighted");else l++}let u=e.root.getAttribute("data-reactive-filter-group");if(u)for(let f of e.root.querySelectorAll(u)){if(!n(f))continue;let p=[...f.querySelectorAll(t)].filter(n);if(p.length===0)continue;f.hidden=p.every((m)=>m.hidden)}let d=e.root.getAttribute("data-reactive-filter-empty");if(d){for(let f of e.root.querySelectorAll(d))if(n(f))f.hidden=l>0}}function N(e){return!!e.root.getAttribute?.("data-reactive-tags-field")}function De(e){if(typeof e.root?.querySelector!=="function")return!1;return!!e.root.querySelector("[data-reactive-nested-json]")}function j(e){if(typeof e.root?.querySelectorAll!=="function")return null;let r=e.root.getAttribute("data-reactive-tags-field");if(!r)return null;let t=e.core.ownership();return[...e.root.querySelectorAll(r)].find(t)??null}function M(e){let r=new Set,t=[];for(let n of String(e.value??"").split(",")){let o=n.trim();if(o===""||r.has(o.toLowerCase()))continue;r.add(o.toLowerCase()),t.push(o)}return t}function X(e,r){let t=j(e);if(!t)return!1;let n=M(t),o=new Set(n.map((a)=>a.toLowerCase())),i=!1;for(let a of r){let s=String(a??"").trim();if(s===""||o.has(s.toLowerCase()))continue;o.add(s.toLowerCase()),n.push(s),i=!0}if(i)ee(e,t,n);return i}function ee(e,r,t){r.value=t.join(","),y(r),te(e)}function Le(e){if(typeof e.root?.querySelectorAll!=="function")return null;let r=e.root.getAttribute("data-reactive-filter-input");if(!r)return null;let t=e.core.ownership();return[...e.root.querySelectorAll(r)].find(t)??null}function te(e){let r=j(e);if(!r)return;let t=M(r),n=e.core.ownership();We(e,t,n),Pe(e,t,n)}function We(e,r,t){let n=[...e.root.querySelectorAll("[data-reactive-tags-list]")].find(t);if(!n)return;let i=[...e.root.querySelectorAll("[data-reactive-tags-template]")].find(t)?.content?.firstElementChild;if(!i){if(!e.tagsWarnedTemplate)console.warn("[phlex-reactive] reactive_tags: no chip <template data-reactive-tags-template> found in this root — "+"chips will not render (the hidden field still updates). Add a template with a [data-reactive-tag-text] node and a reactive_tags_remove button."),e.tagsWarnedTemplate=!0;return}while(n.firstChild)n.removeChild(n.firstChild);for(let a of r){let s=i.cloneNode(!0);s.setAttribute?.("data-reactive-tag",a);let c=s.matches?.("[data-reactive-tag-text]")?s:(s.querySelectorAll?.("[data-reactive-tag-text]")??[])[0];if(c)c.textContent=a;let l=[...s.querySelectorAll?.('[data-action*="reactive#tagsRemove"]')??[]];if(s.matches?.('[data-action*="reactive#tagsRemove"]'))l.push(s);for(let u of l)u.setAttribute?.("data-reactive-tag-param",a);n.appendChild(s)}}function Pe(e,r,t){let n=new Set(r.map((o)=>o.toLowerCase()));for(let o of e.root.querySelectorAll("[role=option]")){if(!t(o))continue;let i=o.getAttribute?.("data-reactive-tag-param");if(!i)continue;if(n.has(i.toLowerCase()))o.setAttribute("data-reactive-tags-selected","true"),o.hidden=!0,o.removeAttribute?.("data-reactive-highlighted");else if(o.hasAttribute?.("data-reactive-tags-selected")){if(o.removeAttribute("data-reactive-tags-selected"),!x(e))o.hidden=!1}}if(x(e))A(e)}function Ge(e){return e.nestedIndex=Math.max(e.nestedIndex+1,Date.now()),e.nestedIndex}function Fe(e,r){let t=[e,...e.querySelectorAll?.("*")??[]];for(let n of t)for(let o of["name","id","for"]){let i=n.getAttribute?.(o);if(i&&i.includes("NEW_ROW"))n.setAttribute?.(o,i.replaceAll("NEW_ROW",String(r)))}}function Be(e,r){if(e.nestedWarned)return;console.warn(`[phlex-reactive] nested rows: no owned [data-reactive-nested-list="${r}"] container + <template data-reactive-nested-template="${r}"> pair found in this root — the add `+"trigger did nothing. Render both inside the same reactive root (reactive_nested_list / reactive_nested_template)."),e.nestedWarned=!0}function Ke(e,r,t,n){if(!t)return null;let o;try{o=JSON.parse(t)}catch{return null}if(!o||typeof o!=="object")return null;let i=e.core.ownership(),a=[...r.querySelectorAll?.("input, select, textarea")??[]],s=[];for(let[c,l]of Object.entries(o)){let u=[...e.root.querySelectorAll?.(l)??[]].find(i);if(!u)continue;let d=a.find((f)=>ne(f.getAttribute?.("name"))===c);if(!d)continue;He(d,u),s.push(u)}if(n)for(let c of s)Ve(c);return s[0]??null}function He(e,r){if(e.type==="checkbox")e.checked=r.type==="checkbox"?!!r.checked:C(r)!=="";else e.value=C(r);y(e)}function Ve(e){if(e.type==="checkbox")e.checked=!1;else e.value="";y(e)}function ze(e,r){if(!e.includes("%{"))return e;return e.replace(/%\{(\w+)\}/g,(t,n)=>Object.prototype.hasOwnProperty.call(r,n)?r[n]:t)}function B(e,r){let t=[...r.querySelectorAll?.('input[name$="[_destroy]"]')??[]][0];if(t)t.value="1",y(t),r.hidden=!0;else r.parentNode?.removeChild?.(r);T(e)}function T(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.core.ownership();for(let t of[...e.root.querySelectorAll("[data-reactive-nested-json]")].filter(r))oe(e,t.getAttribute("data-reactive-nested-json"))}function Ye(e,r){let t=r.getAttribute?.("data-reactive-nested-json-field");if(!t)return null;let n=e.core.ownership();return[...e.root.querySelectorAll(t)].find(n)??null}function re(e,r){let t={},n=e.core.ownership();for(let o of[...r.querySelectorAll?.("input, select, textarea")??[]]){if(o.matches(":disabled")||o.type==="radio"&&!o.checked||!n(o))continue;let i=ne(o.getAttribute?.("name"));if(i===null||i==="_destroy")continue;t[i]=C(o)}return t}function ne(e){if(!e)return null;let r=e.match(/\[([^\][]+)\]$/);return r?r[1]:e}function C(e){if(e.type==="checkbox")return e.checked?e.value||"on":"";return e.value??""}function oe(e,r){let t=e.core.ownership(),n=[...e.root.querySelectorAll(`[data-reactive-nested-list="${r}"]`)].find(t);if(!n)return;let o=Ye(e,n);if(!o)return;let i=[];for(let s of[...n.querySelectorAll?.("[data-reactive-nested-row]")??[]]){if(!t(s)||s.hidden)continue;i.push(re(e,s))}let a=JSON.stringify(i);if(o.value===a)return;o.value=a,y(o)}function ut(e,r,t){let n=h(e,r);if(!N(n))return;if(t?.defaultPrevented)return;if(n.core.listnavOptions(t).some((a)=>a.hasAttribute?.("data-reactive-highlighted")))return;t?.preventDefault?.();let o=t?.currentTarget??t?.target;if(!o)return;if(!X(n,String(o.value??"").split(",")))return;if(o.value="",x(n))A(n)}function ft(e,r,t){let n=h(e,r);if(!N(n))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;if(!X(n,[i]))return;let a=Le(n);if(!a)return;a.value="",A(n),a.focus?.()}function dt(e,r,t){let n=h(e,r);if(!N(n))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;let a=j(n);if(!a)return;let s=M(a),c=s.filter((l)=>l.toLowerCase()!==i.toLowerCase());if(c.length===s.length)return;ee(n,a,c)}function pt(e,r,t){let n=h(e,r);t?.preventDefault?.();let o=t?.currentTarget??t?.target,i=o?.getAttribute?.("data-reactive-association-param");if(!i)return;if(typeof n.root?.querySelectorAll!=="function")return;let a=n.core.ownership(),s=[...n.root.querySelectorAll(`[data-reactive-nested-list="${i}"]`)].find(a),l=[...n.root.querySelectorAll(`[data-reactive-nested-template="${i}"]`)].find(a)?.content?.firstElementChild;if(!s||!l){Be(n,i);return}let u=l.cloneNode(!0);Fe(u,Ge(n)),s.appendChild(u);let d=o?.getAttribute?.("data-reactive-nested-from-param"),f=o?.getAttribute?.("data-reactive-nested-clear-param")==="true",p=Ke(n,u,d,f);if(d)p?.focus?.();else[...u.querySelectorAll?.("input, select, textarea")??[]][0]?.focus?.();if(s.getAttribute?.("data-reactive-nested-json")===i)oe(n,i)}function gt(e,r,t){let n=h(e,r);t?.preventDefault?.();let o=t?.currentTarget??t?.target,i=o?.closest?.("[data-reactive-nested-row]");if(!i)return;if(i.closest?.('[data-controller~="reactive"]')!==n.root)return;let a=o?.getAttribute?.("data-reactive-confirm-param"),s=o?.getAttribute?.("data-reactive-confirm-when-param"),c=a||(s?ue(n,s):null);if(!c)return B(n,i);let l=re(n,i),u=ze(c,l);return n.core.confirm(u,{el:o,row:i,fields:l}).then((d)=>{if(d)B(n,i)})}function ie(e,r){let t=r?.target;if(!t||!e.core.owns(t))return;T(e)}var se=["gte","gt","lte","lt"],Ue=["len_eq","len_gte","len_gt","len_lte","len_lt"],ae=["checked_eq","checked_gte","checked_gt","checked_lte","checked_lt"],Ze=["digits_eq","digits_gte","digits_lt","digits_lte"];function O(e,r,t){if(!Number.isInteger(r))return console.warn(`[phlex-reactive] reactive_show ${e}: needs an integer literal, got ${JSON.stringify(r)} — skipped`),null;switch(e.slice(e.indexOf("_")+1)){case"eq":return t===r;case"gte":return t>=r;case"gt":return t>r;case"lte":return t<=r;case"lt":return t<r;default:return null}}function ce(e,r,t){let n=Number(r);if(Number.isNaN(n))return console.warn(`[phlex-reactive] reactive_show ${e}: needs a numeric literal, got ${JSON.stringify(r)} — skipped`),null;let o=t==null?"":String(t).trim(),i=o===""?NaN:Number(o);if(Number.isNaN(i))return!1;switch(e){case"gte":return i>=n;case"gt":return i>n;case"lte":return i<=n;case"lt":return i<n;default:return null}}function le(e,r){if(!e||typeof e!=="object")return null;if(typeof e.equals==="string")return r===e.equals;if(typeof e.not==="string")return r!==e.not;if(Array.isArray(e.in))return e.in.includes(r);for(let t of se)if(t in e)return ce(t,e[t],r);for(let t of Ue)if(t in e)return O(t,e[t],[...String(r??"")].length);return null}function J(e,r){if(!e||typeof e!=="object"||typeof e.field!=="string")return!1;let t=ae.find((i)=>(i in e));if(t){let i=r(e.field,!0);return O(t,e[t],Array.isArray(i)?i.length:Number(i)||0)===!0}if(typeof e.same==="string"){let i=(a)=>{let s=String(r(a)??"");return e.fold===!0?s.replace(/[A-Z]/g,(c)=>String.fromCharCode(c.charCodeAt(0)+32)):s};return i(e.field)===i(e.same)!==(e.negate===!0)}let n=Ze.filter((i)=>(i in e));if(n.length){let i=String(r(e.field)??"");if(!n.every((s)=>Number.isInteger(e[s]))||e.prefix!=null&&typeof e.prefix!=="string")return!1;return(/^[0-9]*$/.test(i)&&n.every((s)=>O(s,e[s],i.length))&&i.startsWith(e.prefix??""))!==(e.negate===!0)}let o=r(e.field)??"";return le(e,o)===!0}function w(e,r){if(!Array.isArray(e)||e.length===0)return null;return e.some((t)=>Array.isArray(t)&&t.length>0&&t.every((n)=>J(n,r)))}function Qe(e){if(!Array.isArray(e)||e.length===0)return null;let r=new Set;for(let t of e){if(!Array.isArray(t))continue;for(let n of t){if(n&&typeof n==="object"&&typeof n.field==="string")r.add(n.field);if(typeof n?.same==="string")r.add(n.same)}}return r.size>0?[...r]:null}function Xe(e){return e.flat().every((r)=>ae.some((t)=>(t in Object(r))))}function ue(e,r){let t=r;if(typeof r==="string")try{t=JSON.parse(r)}catch{return console.warn(`[phlex-reactive] malformed conditional confirm payload ${JSON.stringify(r)} — skipped`),null}if(!t||typeof t!=="object")return null;let{fields:n}=e.core.collectFields(),o=(a)=>n[a],i;if(typeof t.predicate==="string"){let a=de(t.predicate);if(!a)return console.warn(`[phlex-reactive] confirm predicate "${t.predicate}" is not registered — proceeding without a dialog (register it with setConfirmPredicate)`),null;i=!!a(n)}else i=w(t.groups?.any,o)===!0;return i?t.message:null}function I(e,r){let t=r.target?.closest?.("[data-reactive-editable]");return t&&e.core.owns(t)?t:null}function et(e,r){let t=I(e,r);if(!t||r.isComposing||r.keyCode===229)return;if(r.key==="Enter"){let n=t.getAttribute("data-reactive-editable-enter");if(t.getAttribute("data-reactive-editable")==="multi"&&(n==null||r.shiftKey))return;if(r.preventDefault(),n==="submit")t.closest("form")?.requestSubmit();else if(n)e.core.applyOps(JSON.parse(n),"@root")}else if(r.key==="Escape"&&t.hasAttribute("data-reactive-editable-escape"))r.preventDefault(),t.textContent=e.core.served(t),y(t),t.blur()}function tt(e,r){let t=I(e,r),n=t?.getAttribute("data-reactive-editable")!=="multi",o=(r.clipboardData??r.dataTransfer)?.getData("text/plain");if(!t||o==null||e.core.plain()&&!(n&&/[\r\n]/.test(o)))return;if(r.preventDefault(),n)o=o.replace(/\r?\n|\r/g," ");t.focus(),document.execCommand("insertText",!1,o)}function rt(e,r){let t=I(e,r);if(t?.firstChild&&e.core.text(t)==="")t.replaceChildren()}export{lt as checkGroup,ct as confirmMessage,ot as connect,it as disconnect,pt as nestedAdd,gt as nestedRemove,st as reseed,at as syncNestedJson,ut as tagsAdd,ft as tagsPick,dt as tagsRemove};
1
+ import{confirmPredicate as de}from"phlex/reactive/confirm_predicate";var m=new WeakMap,k=new WeakMap;function y(e,r){let t=m.get(e);if(!t){if(m.set(e,t={root:e.element,core:r,nestedIndex:0}),t.root)k.set(t.root,t)}return t}function h(e,r,t){for(let n of r.split(" "))e.root.addEventListener?.(n,t),e.offs.push(()=>e.root.removeEventListener?.(n,t))}function b(e,r){h(e,"turbo:morph-element",r),e.seeds.push(r),r()}function st(e,r){let t=y(e,r);t.offs=[],t.seeds=[];let n,o,i,s,a;(t.wire=()=>{if(!t.show&&me(t))t.show=(c)=>{if(t.flipping)return;if(c?.type==="input"||c?.type==="change")je(t,c.target);else t.groups=$e(t),F(t);W(t)},h(t,"input change",t.show),h(t,"focusout",(c)=>{let l=c.target?.getAttribute?.("name");if(!l||t.touched?.has(l)||!t.core.bindingOwns(c.target))return;if((t.touched??=new Set).add(l),t.root.querySelector?.("[data-reactive-show-after]"))W(t)}),b(t,t.show);if(!t.arm&&be(t))h(t,"input change",(c)=>D(t,c)),b(t,t.arm=()=>{D(t,null),F(t)});if(!n&&(n=t.show||t.arm))h(t,"reset",()=>setTimeout(()=>{if(m.get(e)!==t)return;t.show?.(),t.arm?.()},0));if(!o&&(o=t.show||t.arm))h(t,"reactive:connect reactive:persist-restored",(c)=>{if(c.target===t.root||!pe(t,c.target))return;t.show?.(),t.arm?.()});if(!i&&(i=x(t)))h(t,"input",(c)=>Je(t,c)&&A(t)),b(t,()=>A(t));if(!s&&(s=O(t)))b(t,()=>te(t));if(!a&&(a=We(t)))h(t,"input change",(c)=>ie(t,c)),b(t,()=>T(t))})(),h(t,"keydown",(c)=>tt(t,c)),h(t,"paste drop",(c)=>rt(t,c)),h(t,"input",(c)=>nt(t,c))}function pe(e,r){return[...r.querySelectorAll?.("[data-reactive-shared-field]")??[]].some(e.core.bindingOwns)}function at(e){let r=m.get(e);if(!r)return;m.delete(e),k.delete(r.root);for(let t of r.offs??[])t();r.groupObserver?.disconnect()}function ct(e){let r=m.get(e);if(!r)return;for(let t of r.seeds)t();r.wire()}function v(e){if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}function lt(e,r,t){return ie(y(e,r),t)}function ut(e,r,t){return ue(y(e,r),t)}var ge=/^#[A-Za-z_][\w-]*$/,K="[data-reactive-show-field], [data-reactive-show]";function he(e,r){let t=e.getAttribute("data-reactive-show-equals");if(t!==null)return r===t;let n=e.getAttribute("data-reactive-show-not");if(n!==null)return r!==n;let o=e.getAttribute("data-reactive-show-in");if(o!==null){try{let i=JSON.parse(o);if(Array.isArray(i))return i.includes(r)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify(o)} — skipped`),null}for(let i of se){let s=e.getAttribute(`data-reactive-show-${i}`);if(s!==null)return ce(i,s,r)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}function H(e){try{let r=JSON.parse(e);if(r&&typeof r==="object"&&!Array.isArray(r))return r}catch{}return console.warn(`[phlex-reactive] malformed compound reactive_show payload ${JSON.stringify(e)} — skipped`),null}function ye(e){try{let r=JSON.parse(e);if(Array.isArray(r)&&r.every((t)=>t&&typeof t==="object"&&Array.isArray(t.any)&&Array.isArray(t.ops)))return r}catch{}return console.warn(`[phlex-reactive] malformed reactive_on_complete payload ${JSON.stringify(e)} — skipped`),[]}function V(e,r){if(!e||typeof e!=="object")return null;let t=e.any;if(Array.isArray(t)&&(t.length===0||Array.isArray(t[0])))return w(t,r);return ve(e,r)}function ve(e,r){let t=Array.isArray(e.all)?"all":Array.isArray(e.any)?"any":null;if(!t)return null;let n=e[t];if(n.length===0)return null;let o=n.map((i)=>J(i,r));return t==="all"?o.every(Boolean):o.some(Boolean)}function S(e,r="show"){if(typeof e==="string"&&ge.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root ${r} target ${JSON.stringify(e)} — skipped`),!1}function me(e){if(e.root.getAttribute?.("data-reactive-show-targets"))return!0;if(e.root.getAttribute?.("data-reactive-group-targets"))return!0;let r=e.root.querySelectorAll?.(K)??[];for(let t of r)if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(_)??[])if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(`${U}, ${Z}`)??[])if(e.core.owns(t))return!0;return e.root.hasAttribute?.("data-reactive-css-vars")??!1}function be(e){return!!e.root.getAttribute?.("data-reactive-on-complete")}function Ae(e){let r=e.root.getAttribute?.("data-reactive-on-complete")??null;if(r!==e.onCompleteRaw)e.onCompleteRaw=r,e.onCompleteParsed=r==null?[]:ye(r),e.onCompleteStates=e.onCompleteParsed.map(()=>!1);return e.onCompleteParsed}function D(e,r){let t=Ae(e);if(!t.length)return;let n=Y(e,e.core.bindingOwnership());t.forEach((o,i)=>{let s=w(o.any,n);if(s===null)return;let a=s&&!e.onCompleteStates[i]&&Boolean(r);if(e.onCompleteStates[i]=s,a)e.core.applyOps(o.ops,"@root")})}function W(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.core.ownership(),t=e.core.bindingOwnership(),n=e.root.getAttribute?.("data-reactive-scope")||null,o=Y(e,t),i=[];for(let s of e.root.querySelectorAll(K)){if(!r(s))continue;let a=s.getAttribute("data-reactive-show");if(a!==null){let d=V(H(a),o);if(d===null)continue;let f=s.getAttribute("data-reactive-show-after"),p=d&&(f==null||!!e.touched?.has(E(f,n)));L(s,p,t);let g=(e.shown??=new WeakMap).get(s);if(e.shown.set(s,p),we.some((fe)=>s.hasAttribute(`data-reactive-show-${fe}`))&&g!==void 0&&g!==p)i.push(s);continue}let c=s.getAttribute("data-reactive-show-field");if(!c)continue;let l=o(c);if(l===null)continue;let u=he(s,l);if(u===null)continue;L(s,u,t)}if(e.groups)Me(e,o,r,n);Ne(e,o,r),qe(e,o,r,n,t),xe(e,o),Te(e,o);for(let s of i)Se(e,s,t,n)}var we=["clear","focus","scroll"];function Se(e,r,t,n){if(r.hidden){let a=[];try{a=JSON.parse(r.getAttribute("data-reactive-show-clear")??"[]")}catch{}let c=new Set((Array.isArray(a)?a:[]).map((l)=>E(String(l),n)));for(let l of c.size?e.root.querySelectorAll("[name]"):[]){if(!c.has(l.getAttribute("name"))||!t(l)||l.type==="file")continue;if(l.type==="checkbox"||l.type==="radio"){if(l.checked)l.checked=!1,v(l)}else e.core.setValue(l,"")}return}let o=r.getAttribute("data-reactive-show-scroll")==="true";if(o)r.scrollIntoView?.({block:"nearest"});let i=r.getAttribute("data-reactive-show-focus"),s=null;try{s=i?e.root.querySelector(i):null}catch{}s?.focus?.(o?{preventScroll:!0}:void 0)}function L(e,r,t){if(e.hidden=!r,e.getAttribute("data-reactive-show-disable")!=="true")return;if(typeof e.querySelectorAll!=="function")return;for(let n of e.querySelectorAll("input[name], select[name], textarea[name]"))if(t(n))n.disabled=!r;if(e.name&&t(e))e.disabled=!r}function xe(e,r){let t=z(e);for(let[n,o]of Object.entries(t)){if(n.startsWith("#")){_e(n,o,r);continue}if(!o||typeof o!=="object"||Array.isArray(o))continue;let i=r(n);if(i===null)continue;let s=(a,c)=>c?r(n,!0):i;for(let[a,c]of Object.entries(o)){if(!S(a))continue;let l;if(Array.isArray(c)){if(c.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${a} — skipped`);continue}l=c.every((u)=>J(u,s))}else{let u=le(c,i);if(u===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${a} — skipped`);continue}l=u}for(let u of document.querySelectorAll(a))u.hidden=!l}}}function _e(e,r,t){if(!S(e))return;let n=r&&typeof r==="object"&&!Array.isArray(r)?r.any:null,o=Xe(n);if(o===null){console.warn(`[phlex-reactive] malformed reactive_show_targets conditions for ${e} — skipped`);return}if(o.every((s)=>t(s)===null)&&!et(n))return;let i=w(n,t);if(i===null)return;for(let s of document.querySelectorAll(e))s.hidden=!i}function z(e,r="show",t="mode: { ... }, kind: { ... }"){let n=e.root.getAttribute?.(`data-reactive-${r}-targets`);if(!n)return{};try{let o=JSON.parse(n);if(o&&typeof o==="object"&&!Array.isArray(o))return o}catch{}return console.warn(`[phlex-reactive] malformed data-reactive-${r}-targets — ignored. `+`Did two reactive_${r}_targets calls collide on one root? Declare every entry in ONE call: reactive_${r}_targets(${t})`),{}}function Oe(e,r,t,n){let o=!1,i=null;for(let s of e.root.querySelectorAll(q(r,n))){if(!t(s))continue;if(s.type==="checkbox")return s.checked?"true":"false";if(s.type==="radio"){if(s.checked)return s.value??"";o=!0;continue}i??=s}if(i)return i.value??"";return o?"":null}function q(e,r){return`[name="${E(e,r)}"]`}function E(e,r){return r&&!e.includes("[")?`${r}[${e}]`:e}function Y(e,r){let t=e.root.getAttribute?.("data-reactive-scope")||null,n=new Map;return(o,i)=>{let s=i?`#${o}`:o;if(!n.has(s))n.set(s,i?R(e,o,r,t).filter((a)=>a.checked).length:Oe(e,o,r,t));return n.get(s)}}var U="[data-reactive-media]";function Ne(e,r,t){for(let n of e.root.querySelectorAll(U)){if(!t(n))continue;let o,i,s;try{if(o=JSON.parse(n.getAttribute("data-reactive-media")),o?.match!=null)i=new RegExp(`^(?:${o.match})$`);if(o?.when!=null)s=new RegExp(`^(?:${o.when})$`)}catch{}if(typeof o?.field!=="string"||!o.pool||typeof o.pool!=="object"||o.match!=null&&!i||o.when!=null&&!s){console.warn("[phlex-reactive] malformed data-reactive-media — skipped");continue}let a=r(o.field);if(a===null)continue;let c=o.take>0?[...a]:null,l=c?c.slice(0,o.take).join(""):a,u=c?.length<o.take||i?.test(l)===!1||s?.test(a)===!1;if(u&&o.pending==="keep"){P(n,"pending");continue}let d=!u&&Object.hasOwn(o.pool,l)?G(e,o.pool[l])[0]:null,f=e.core.copyMedia(n,d??null);if(f===null)continue;if(P(n,u?"pending":f===!1?"miss":"hit"),typeof o.label!=="string")continue;let p=u?"":f===!1?String(o.blank??""):f;for(let g of G(e,o.label))if(g.textContent!==p)g.textContent=p}}function P(e,r){if(e.getAttribute("data-reactive-media-state")!==r)e.setAttribute("data-reactive-media-state",r)}function G(e,r){try{return r==="@root"?[]:e.core.opTargets({to:r})}catch{return[]}}var Z="[data-reactive-css-vars]",Ce=/^--[a-z0-9-]+$/i,ke=["","px","%","deg","turn","ms","s","em","rem","fr"];function qe(e,r,t,n,o){let i=[...e.root.querySelectorAll(Z)].filter(t);if(e.root.hasAttribute("data-reactive-css-vars"))i.unshift(e.root);for(let s of i){let a;try{a=JSON.parse(s.getAttribute("data-reactive-css-vars"))}catch{}if(!Array.isArray(a?.to)||!a.vars||typeof a.vars!=="object"){console.warn("[phlex-reactive] malformed data-reactive-css-vars — skipped (two reactive_css_vars on one element?)");continue}let c=a.to.flatMap((l)=>{let u={to:l,global:a.global===!0},d=[];try{d=e.core.opTargets(u)}catch{}if(!d.length)e.core.diagnose("reactive_css_vars",u);return d});for(let[l,u]of Object.entries(a.vars)){let d=u?.unit??"";if(!Ce.test(l)||!ke.includes(d)||typeof u?.field!=="string"){console.warn(`[phlex-reactive] refused reactive_css_vars entry ${JSON.stringify(l)} — skipped`);continue}let f=Ee(e,r,u.field,o,n);if(f===void 0)continue;let p=f===null?"":`${f}${d}`;for(let g of c){if(g.style.getPropertyValue(l)===p)continue;if(p)g.style.setProperty(l,p);else g.style.removeProperty(l)}}}}function Ee(e,r,t,n,o){let i=r(t);if(i===null)return;if((i==="true"||i==="false")&&[...e.root.querySelectorAll(q(t,o))].some((a)=>n(a)&&a.type==="checkbox"))return i==="true"?1:0;let s=i.trim()?Number(i):NaN;return Number.isFinite(s)?s:null}var _="[data-reactive-enable], [data-reactive-select-all], [data-reactive-count]";function $e(e){return!!e.root.querySelector?.(_)}function R(e,r,t,n,o){return[...e.root.querySelectorAll(q(r,n))].filter((i)=>i.type==="checkbox"&&t(i)&&(!o||Re(i.getAttribute("data-reactive-group"),o)))}function Re(e,r){return e===r||!!e?.startsWith(`${r}.`)}function je(e,r){let t=r?.getAttribute?.("data-reactive-select-all");if(t&&e.core.owns(r))Q(e,t,r.checked,r,r.getAttribute("data-reactive-select-all-under"))}function ft(e,r,t){if(!r)return;let n=k.get(e)??{root:e,core:{ownership:()=>(o)=>o.closest('[data-controller~="reactive"]')===e}};Q(n,r,t!==!1),n.show?.()}function Q(e,r,t,n,o){let i=e.root.getAttribute?.("data-reactive-scope")||null,s=R(e,r,e.core.ownership(),i,o).filter((a)=>a!==n&&a.checked!==t);for(let a of s)a.checked=t;e.flipping=!0;try{for(let a of s)for(let c of["input","change"])a.dispatchEvent?.(new Event(c,{bubbles:!0}))}finally{e.flipping=!1}}function Me(e,r,t,n){for(let o of e.root.querySelectorAll(_)){if(!t(o))continue;let i=o.getAttribute("data-reactive-enable");if(i!==null){let c=V(H(i),r);if(c!==null)o.disabled=!c}let s=o.getAttribute("data-reactive-count");if(s){let c=String(r(s,!0));if(o.textContent!==c)o.textContent=c}let a=o.getAttribute("data-reactive-select-all");if(a){let c=o.getAttribute("data-reactive-select-all-under"),l=R(e,a,t,n,c).filter((d)=>d!==o),u=l.filter((d)=>d.checked).length;o.checked=u>0&&u===l.length,o.indeterminate=u>0&&u<l.length}}}function Te(e,r){for(let[t,n]of Object.entries(z(e,"group",'"ids[]" => { ... }, "tags[]" => { ... }'))){if(!n||typeof n!=="object"||Array.isArray(n))continue;let o=String(r(t,!0));for(let s of Array.isArray(n.count)?n.count:[]){if(!S(s,"group"))continue;for(let a of document.querySelectorAll(s))if(a.textContent!==o)a.textContent=o}let i=n.enable&&typeof n.enable==="object"?n.enable:{};for(let[s,a]of Object.entries(i)){if(!S(s,"group"))continue;let c=w(a?.any,r);if(c===null){console.warn(`[phlex-reactive] malformed reactive_group_targets enable for ${s} — skipped`);continue}for(let l of document.querySelectorAll(s))l.disabled=!c}}}function F(e){if(e.groupObserver||typeof MutationObserver!=="function")return;let r=(o)=>e.root.getAttribute?.(`data-reactive-${o}`)?.includes("checked_");if(!e.root.getAttribute?.("data-reactive-group-targets")&&!e.root.querySelector?.(`${_}, [data-reactive-show*=checked_]`)&&!r("show-targets")&&!r("on-complete"))return;let n=(o)=>o.nodeType===1&&(o.matches('input[type="checkbox"]')||!!o.querySelector('input[type="checkbox"]'));e.groupObserver=new MutationObserver((o)=>{if(!o.some((i)=>[...i.addedNodes,...i.removedNodes].some(n)))return;e.show?.(),e.arm?.()}),e.groupObserver.observe(e.root,{childList:!0,subtree:!0})}function x(e){return!!(e.root.getAttribute?.("data-reactive-filter-input")&&e.root.getAttribute?.("data-reactive-filter-option"))}function Je(e,r){let t=e.root.getAttribute("data-reactive-filter-input");return!!t&&typeof r.target?.matches==="function"&&r.target.matches(t)}var Ie=/[\s\-'(),./]/;function De(e,r,t){if(e==="prefix")return r.startsWith(t);if(e!=="word_start")return r.includes(t);for(let n=r.indexOf(t);n!==-1;n=r.indexOf(t,n+1))if(n===0||Ie.test(r[n-1]))return!0;return!1}function A(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.root.getAttribute("data-reactive-filter-input"),t=e.root.getAttribute("data-reactive-filter-option");if(!r||!t)return;let n=e.core.ownership(),o=[...e.root.querySelectorAll(r)].find(n);if(!o)return;let i=e.root.getAttribute("data-reactive-filter-match"),s=e.root.hasAttribute?.("data-reactive-filter-fold"),a=(f)=>{let p=(f??"").toLowerCase().trim();return s?p.normalize("NFD").replace(/\p{M}/gu,""):p},c=a(o.value),l=0;for(let f of e.root.querySelectorAll(t)){if(!n(f))continue;let p=f.hasAttribute?.("data-reactive-tags-selected")||c!==""&&!De(i,a(f.getAttribute("data-reactive-filter-text")??f.textContent),c);if(f.hidden=p,p)f.removeAttribute("data-reactive-highlighted");else l++}let u=e.root.getAttribute("data-reactive-filter-group");if(u)for(let f of e.root.querySelectorAll(u)){if(!n(f))continue;let p=[...f.querySelectorAll(t)].filter(n);if(p.length===0)continue;f.hidden=p.every((g)=>g.hidden)}let d=e.root.getAttribute("data-reactive-filter-empty");if(d){for(let f of e.root.querySelectorAll(d))if(n(f))f.hidden=l>0}}function O(e){return!!e.root.getAttribute?.("data-reactive-tags-field")}function We(e){if(typeof e.root?.querySelector!=="function")return!1;return!!e.root.querySelector("[data-reactive-nested-json]")}function j(e){if(typeof e.root?.querySelectorAll!=="function")return null;let r=e.root.getAttribute("data-reactive-tags-field");if(!r)return null;let t=e.core.ownership();return[...e.root.querySelectorAll(r)].find(t)??null}function M(e){let r=new Set,t=[];for(let n of String(e.value??"").split(",")){let o=n.trim();if(o===""||r.has(o.toLowerCase()))continue;r.add(o.toLowerCase()),t.push(o)}return t}function X(e,r){let t=j(e);if(!t)return!1;let n=M(t),o=new Set(n.map((s)=>s.toLowerCase())),i=!1;for(let s of r){let a=String(s??"").trim();if(a===""||o.has(a.toLowerCase()))continue;o.add(a.toLowerCase()),n.push(a),i=!0}if(i)ee(e,t,n);return i}function ee(e,r,t){r.value=t.join(","),v(r),te(e)}function Le(e){if(typeof e.root?.querySelectorAll!=="function")return null;let r=e.root.getAttribute("data-reactive-filter-input");if(!r)return null;let t=e.core.ownership();return[...e.root.querySelectorAll(r)].find(t)??null}function te(e){let r=j(e);if(!r)return;let t=M(r),n=e.core.ownership();Pe(e,t,n),Ge(e,t,n)}function Pe(e,r,t){let n=[...e.root.querySelectorAll("[data-reactive-tags-list]")].find(t);if(!n)return;let i=[...e.root.querySelectorAll("[data-reactive-tags-template]")].find(t)?.content?.firstElementChild;if(!i){if(!e.tagsWarnedTemplate)console.warn("[phlex-reactive] reactive_tags: no chip <template data-reactive-tags-template> found in this root — "+"chips will not render (the hidden field still updates). Add a template with a [data-reactive-tag-text] node and a reactive_tags_remove button."),e.tagsWarnedTemplate=!0;return}while(n.firstChild)n.removeChild(n.firstChild);for(let s of r){let a=i.cloneNode(!0);a.setAttribute?.("data-reactive-tag",s);let c=a.matches?.("[data-reactive-tag-text]")?a:(a.querySelectorAll?.("[data-reactive-tag-text]")??[])[0];if(c)c.textContent=s;let l=[...a.querySelectorAll?.('[data-action*="reactive#tagsRemove"]')??[]];if(a.matches?.('[data-action*="reactive#tagsRemove"]'))l.push(a);for(let u of l)u.setAttribute?.("data-reactive-tag-param",s);n.appendChild(a)}}function Ge(e,r,t){let n=new Set(r.map((o)=>o.toLowerCase()));for(let o of e.root.querySelectorAll("[role=option]")){if(!t(o))continue;let i=o.getAttribute?.("data-reactive-tag-param");if(!i)continue;if(n.has(i.toLowerCase()))o.setAttribute("data-reactive-tags-selected","true"),o.hidden=!0,o.removeAttribute?.("data-reactive-highlighted");else if(o.hasAttribute?.("data-reactive-tags-selected")){if(o.removeAttribute("data-reactive-tags-selected"),!x(e))o.hidden=!1}}if(x(e))A(e)}function Fe(e){return e.nestedIndex=Math.max(e.nestedIndex+1,Date.now()),e.nestedIndex}function Be(e,r){let t=[e,...e.querySelectorAll?.("*")??[]];for(let n of t)for(let o of["name","id","for"]){let i=n.getAttribute?.(o);if(i&&i.includes("NEW_ROW"))n.setAttribute?.(o,i.replaceAll("NEW_ROW",String(r)))}}function Ke(e,r){if(e.nestedWarned)return;console.warn(`[phlex-reactive] nested rows: no owned [data-reactive-nested-list="${r}"] container + <template data-reactive-nested-template="${r}"> pair found in this root — the add `+"trigger did nothing. Render both inside the same reactive root (reactive_nested_list / reactive_nested_template)."),e.nestedWarned=!0}function He(e,r,t,n){if(!t)return null;let o;try{o=JSON.parse(t)}catch{return null}if(!o||typeof o!=="object")return null;let i=e.core.ownership(),s=[...r.querySelectorAll?.("input, select, textarea")??[]],a=[];for(let[c,l]of Object.entries(o)){let u=[...e.root.querySelectorAll?.(l)??[]].find(i);if(!u)continue;let d=s.find((f)=>ne(f.getAttribute?.("name"))===c);if(!d)continue;Ve(d,u),a.push(u)}if(n)for(let c of a)ze(c);return a[0]??null}function Ve(e,r){if(e.type==="checkbox")e.checked=r.type==="checkbox"?!!r.checked:N(r)!=="";else e.value=N(r);v(e)}function ze(e){if(e.type==="checkbox")e.checked=!1;else e.value="";v(e)}function Ye(e,r){if(!e.includes("%{"))return e;return e.replace(/%\{(\w+)\}/g,(t,n)=>Object.prototype.hasOwnProperty.call(r,n)?r[n]:t)}function B(e,r){let t=[...r.querySelectorAll?.('input[name$="[_destroy]"]')??[]][0];if(t)t.value="1",v(t),r.hidden=!0;else r.parentNode?.removeChild?.(r);T(e)}function T(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.core.ownership();for(let t of[...e.root.querySelectorAll("[data-reactive-nested-json]")].filter(r))oe(e,t.getAttribute("data-reactive-nested-json"))}function Ue(e,r){let t=r.getAttribute?.("data-reactive-nested-json-field");if(!t)return null;let n=e.core.ownership();return[...e.root.querySelectorAll(t)].find(n)??null}function re(e,r){let t={},n=e.core.ownership();for(let o of[...r.querySelectorAll?.("input, select, textarea")??[]]){if(o.matches(":disabled")||o.type==="radio"&&!o.checked||!n(o))continue;let i=ne(o.getAttribute?.("name"));if(i===null||i==="_destroy")continue;t[i]=N(o)}return t}function ne(e){if(!e)return null;let r=e.match(/\[([^\][]+)\]$/);return r?r[1]:e}function N(e){if(e.type==="checkbox")return e.checked?e.value||"on":"";return e.value??""}function oe(e,r){let t=e.core.ownership(),n=[...e.root.querySelectorAll(`[data-reactive-nested-list="${r}"]`)].find(t);if(!n)return;let o=Ue(e,n);if(!o)return;let i=[];for(let a of[...n.querySelectorAll?.("[data-reactive-nested-row]")??[]]){if(!t(a)||a.hidden)continue;i.push(re(e,a))}let s=JSON.stringify(i);if(o.value===s)return;o.value=s,v(o)}function dt(e,r,t){let n=y(e,r);if(!O(n))return;if(t?.defaultPrevented)return;if(n.core.listnavOptions(t).some((s)=>s.hasAttribute?.("data-reactive-highlighted")))return;t?.preventDefault?.();let o=t?.currentTarget??t?.target;if(!o)return;if(!X(n,String(o.value??"").split(",")))return;if(o.value="",x(n))A(n)}function pt(e,r,t){let n=y(e,r);if(!O(n))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;if(!X(n,[i]))return;let s=Le(n);if(!s)return;s.value="",A(n),s.focus?.()}function gt(e,r,t){let n=y(e,r);if(!O(n))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;let s=j(n);if(!s)return;let a=M(s),c=a.filter((l)=>l.toLowerCase()!==i.toLowerCase());if(c.length===a.length)return;ee(n,s,c)}function ht(e,r,t){let n=y(e,r);t?.preventDefault?.();let o=t?.currentTarget??t?.target,i=o?.getAttribute?.("data-reactive-association-param");if(!i)return;if(typeof n.root?.querySelectorAll!=="function")return;let s=n.core.ownership(),a=[...n.root.querySelectorAll(`[data-reactive-nested-list="${i}"]`)].find(s),l=[...n.root.querySelectorAll(`[data-reactive-nested-template="${i}"]`)].find(s)?.content?.firstElementChild;if(!a||!l){Ke(n,i);return}let u=l.cloneNode(!0);Be(u,Fe(n)),a.appendChild(u);let d=o?.getAttribute?.("data-reactive-nested-from-param"),f=o?.getAttribute?.("data-reactive-nested-clear-param")==="true",p=He(n,u,d,f);if(d)p?.focus?.();else[...u.querySelectorAll?.("input, select, textarea")??[]][0]?.focus?.();if(a.getAttribute?.("data-reactive-nested-json")===i)oe(n,i)}function yt(e,r,t){let n=y(e,r);t?.preventDefault?.();let o=t?.currentTarget??t?.target,i=o?.closest?.("[data-reactive-nested-row]");if(!i)return;if(i.closest?.('[data-controller~="reactive"]')!==n.root)return;let s=o?.getAttribute?.("data-reactive-confirm-param"),a=o?.getAttribute?.("data-reactive-confirm-when-param"),c=s||(a?ue(n,a):null);if(!c)return B(n,i);let l=re(n,i),u=Ye(c,l);return n.core.confirm(u,{el:o,row:i,fields:l}).then((d)=>{if(d)B(n,i)})}function ie(e,r){let t=r?.target;if(!t||!e.core.owns(t))return;T(e)}var se=["gte","gt","lte","lt"],Ze=["len_eq","len_gte","len_gt","len_lte","len_lt"],ae=["checked_eq","checked_gte","checked_gt","checked_lte","checked_lt"],Qe=["digits_eq","digits_gte","digits_lt","digits_lte"];function C(e,r,t){if(!Number.isInteger(r))return console.warn(`[phlex-reactive] reactive_show ${e}: needs an integer literal, got ${JSON.stringify(r)} — skipped`),null;switch(e.slice(e.indexOf("_")+1)){case"eq":return t===r;case"gte":return t>=r;case"gt":return t>r;case"lte":return t<=r;case"lt":return t<r;default:return null}}function ce(e,r,t){let n=Number(r);if(Number.isNaN(n))return console.warn(`[phlex-reactive] reactive_show ${e}: needs a numeric literal, got ${JSON.stringify(r)} — skipped`),null;let o=t==null?"":String(t).trim(),i=o===""?NaN:Number(o);if(Number.isNaN(i))return!1;switch(e){case"gte":return i>=n;case"gt":return i>n;case"lte":return i<=n;case"lt":return i<n;default:return null}}function le(e,r){if(!e||typeof e!=="object")return null;if(typeof e.equals==="string")return r===e.equals;if(typeof e.not==="string")return r!==e.not;if(Array.isArray(e.in))return e.in.includes(r);for(let t of se)if(t in e)return ce(t,e[t],r);for(let t of Ze)if(t in e)return C(t,e[t],[...String(r??"")].length);return null}function J(e,r){if(!e||typeof e!=="object"||typeof e.field!=="string")return!1;let t=ae.find((i)=>(i in e));if(t){let i=r(e.field,!0);return C(t,e[t],Array.isArray(i)?i.length:Number(i)||0)===!0}if(typeof e.same==="string"){let i=(s)=>{let a=String(r(s)??"");return e.fold===!0?a.replace(/[A-Z]/g,(c)=>String.fromCharCode(c.charCodeAt(0)+32)):a};return i(e.field)===i(e.same)!==(e.negate===!0)}let n=Qe.filter((i)=>(i in e));if(n.length){let i=String(r(e.field)??"");if(!n.every((a)=>Number.isInteger(e[a]))||e.prefix!=null&&typeof e.prefix!=="string")return!1;return(/^[0-9]*$/.test(i)&&n.every((a)=>C(a,e[a],i.length))&&i.startsWith(e.prefix??""))!==(e.negate===!0)}let o=r(e.field)??"";return le(e,o)===!0}function w(e,r){if(!Array.isArray(e)||e.length===0)return null;return e.some((t)=>Array.isArray(t)&&t.length>0&&t.every((n)=>J(n,r)))}function Xe(e){if(!Array.isArray(e)||e.length===0)return null;let r=new Set;for(let t of e){if(!Array.isArray(t))continue;for(let n of t){if(n&&typeof n==="object"&&typeof n.field==="string")r.add(n.field);if(typeof n?.same==="string")r.add(n.same)}}return r.size>0?[...r]:null}function et(e){return e.flat().every((r)=>ae.some((t)=>(t in Object(r))))}function ue(e,r){let t=r;if(typeof r==="string")try{t=JSON.parse(r)}catch{return console.warn(`[phlex-reactive] malformed conditional confirm payload ${JSON.stringify(r)} — skipped`),null}if(!t||typeof t!=="object")return null;let{fields:n}=e.core.collectFields(),o=(s)=>n[s],i;if(typeof t.predicate==="string"){let s=de(t.predicate);if(!s)return console.warn(`[phlex-reactive] confirm predicate "${t.predicate}" is not registered — proceeding without a dialog (register it with setConfirmPredicate)`),null;i=!!s(n)}else i=w(t.groups?.any,o)===!0;return i?t.message:null}function I(e,r){let t=r.target?.closest?.("[data-reactive-editable]");return t&&e.core.owns(t)?t:null}function tt(e,r){let t=I(e,r);if(!t||r.isComposing||r.keyCode===229)return;if(r.key==="Enter"){let n=t.getAttribute("data-reactive-editable-enter");if(t.getAttribute("data-reactive-editable")==="multi"&&(n==null||r.shiftKey))return;if(r.preventDefault(),n==="submit")t.closest("form")?.requestSubmit();else if(n)e.core.applyOps(JSON.parse(n),"@root")}else if(r.key==="Escape"&&t.hasAttribute("data-reactive-editable-escape"))r.preventDefault(),t.textContent=e.core.served(t),v(t),t.blur()}function rt(e,r){let t=I(e,r),n=t?.getAttribute("data-reactive-editable")!=="multi",o=(r.clipboardData??r.dataTransfer)?.getData("text/plain");if(!t||o==null||e.core.plain()&&!(n&&/[\r\n]/.test(o)))return;if(r.preventDefault(),n)o=o.replace(/\r?\n|\r/g," ");t.focus(),document.execCommand("insertText",!1,o)}function nt(e,r){let t=I(e,r);if(t?.firstChild&&e.core.text(t)==="")t.replaceChildren()}export{ft as checkGroup,ut as confirmMessage,st as connect,at as disconnect,ht as nestedAdd,yt as nestedRemove,ct as reseed,lt as syncNestedJson,dt as tagsAdd,pt as tagsPick,gt as tagsRemove};
2
2
 
3
- //# debugId=B45AD8F5762693AC64756E2164756E21
3
+ //# debugId=0E6A93F98751F98F64756E2164756E21
4
4
  //# sourceMappingURL=bindings.min.js.map