phlex-reactive 0.16.8 → 0.16.10
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 +66 -1
- data/README.md +61 -6
- data/app/javascript/phlex/reactive/core.min.js +4 -4
- data/app/javascript/phlex/reactive/core.min.js.map +3 -3
- data/app/javascript/phlex/reactive/early.js +28 -1
- data/app/javascript/phlex/reactive/early.min.js +2 -2
- data/app/javascript/phlex/reactive/early.min.js.map +3 -3
- data/app/javascript/phlex/reactive/features/devtools.js +15 -5
- data/app/javascript/phlex/reactive/features/devtools.min.js +2 -2
- data/app/javascript/phlex/reactive/features/devtools.min.js.map +3 -3
- data/app/javascript/phlex/reactive/reactive_controller.min.js +4 -4
- data/app/javascript/phlex/reactive/reactive_controller.min.js.map +4 -4
- data/app/javascript/phlex/reactive/runtime.js +116 -17
- data/lib/phlex/reactive/component/dsl.rb +2 -0
- data/lib/phlex/reactive/component/helpers.rb +50 -4
- data/lib/phlex/reactive/js.rb +211 -41
- data/lib/phlex/reactive/response.rb +4 -0
- 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: fe73d6104157ba5f7134664ab8c7b3c6f168b36b2ac3ea10ede454469f442e85
|
|
4
|
+
data.tar.gz: 100e377a09a2a80e48af02a91808f3b8ce5d29c7b89aa2e6616dd880b6719460
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e9007ecf1e1e4628a4183a03b2d66152a85a004e00b90a2b65ac6c1395f248643a7a2e6067e11dbfb7cfa8619f38d836c871a97f84f7da96a87b2ae2032a12cd
|
|
7
|
+
data.tar.gz: 1cafa86d8dc5f8399f61856969ef2d8fc2668aaa74ce906382b0bb670f5e25b51923b7a4bc886fc0e005145958c13553ff06ec5f7b0e158855a3ca868e9faca1
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,68 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.16.10] - 2026-10-19
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **`reactive_image_fallback` marks an `img` that failed before Turbo
|
|
14
|
+
inserted it (#452).** Turbo's frame render imports the fetched frame into
|
|
15
|
+
the document and inserts it a few awaits later; an `img` starts loading as
|
|
16
|
+
soon as it is imported, so one whose request failed in that gap fired
|
|
17
|
+
`error` on a detached node, where the client's document listener could not
|
|
18
|
+
hear it, and stayed on screen as a broken image. Once Turbo has inserted
|
|
19
|
+
new content (`turbo:frame-render` for the frame, `turbo:render` for the
|
|
20
|
+
page, and after a stream whose content holds a marked `img` has rendered),
|
|
21
|
+
the client now reads the result off every `img[data-reactive-image-fallback]`
|
|
22
|
+
that has no `data-reactive-image-state` yet and has finished: a
|
|
23
|
+
`naturalWidth` means `loaded`, otherwise `decode()` decides, as the scan at
|
|
24
|
+
registration already did. An `img` already marked is not touched, one still
|
|
25
|
+
loading is left to its own event, and nothing is fetched again.
|
|
26
|
+
|
|
27
|
+
## [0.16.9] - 2026-10-19
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- **One client binding for a whole list: `:trigger`, `from:`/`attr:` reads and
|
|
32
|
+
`on_client(…, within:)` (#442).** Every client-op argument was a literal baked
|
|
33
|
+
at render, so a pickable list whose rows each write their own value and label
|
|
34
|
+
carried a full op chain on every row, differing in two or three literals.
|
|
35
|
+
Three parts now let the list bind once:
|
|
36
|
+
- **`:trigger`** (wire `"@trigger"`) targets the element whose `on_client`
|
|
37
|
+
binding fired, wherever an op takes a target (`to`, `expanded:`,
|
|
38
|
+
`submit(submitter:)`, `copy_media(from:)`). `set_value`, `paste_into` and
|
|
39
|
+
`preview_file` refuse it as their field. `JS.normalize_target` (pending
|
|
40
|
+
hints, `reactive_css_vars`) still refuses it.
|
|
41
|
+
- **`from:` + `attr:`** on `set_value`, `text` and `set_attr` read the value in
|
|
42
|
+
the browser off an element instead of a literal:
|
|
43
|
+
`js.set_value("#item-value", from: :trigger, attr: "data-value")`. `from:` is
|
|
44
|
+
`:trigger`, `:root` or a selector (the op's own scoping, `global:` included,
|
|
45
|
+
first match); `attr:` is a `data-*` attribute or `:text` (textContent),
|
|
46
|
+
enforced at render and again in the client. A missing attribute reads `""`;
|
|
47
|
+
a `from:` matching nothing skips the op. Exactly one of the value or `from:`.
|
|
48
|
+
**`dispatch(…, detail_from: { id: "data-id" })`** builds the event detail off
|
|
49
|
+
the trigger the same way, merged over `detail:` (a key in both raises).
|
|
50
|
+
- **`on_client(:click, ops, within: "[role=option]")`** runs the record only
|
|
51
|
+
for an event from inside an element matching the selector, under the bound
|
|
52
|
+
element and owned by this root; that element is the ops' `:trigger`.
|
|
53
|
+
Anywhere else is a complete no-op (no `preventDefault`, no confirm, no ops).
|
|
54
|
+
Keyboard picking through `reactive_listnav` and a click before the root
|
|
55
|
+
connects reach the same binding; before connect, `phlex/reactive/early`
|
|
56
|
+
leaves a click outside every row alone (a link in the list navigates). A
|
|
57
|
+
`within:` selector that does not parse runs nothing (verbose: warned). The bound element is not forced to
|
|
58
|
+
`type="button"`. `within:` raises with `window:`, `outside:`, `shortcut:` and
|
|
59
|
+
`once:` (Stimulus would drop a `:once` listener on its first event, a miss
|
|
60
|
+
included).
|
|
61
|
+
|
|
62
|
+
A server-pushed op has no trigger: `reply.js`, `broadcast_to(js:)` and
|
|
63
|
+
`reactive_on_complete` refuse `@trigger` and `detail_from:` (a chain or a raw
|
|
64
|
+
list). In the browser a stream op naming `@trigger`, or one in a window-bound
|
|
65
|
+
binding, resolves to nothing (verbose: warned). Every record that
|
|
66
|
+
asks for none of this is byte-identical. Client: the core gains 314 B
|
|
67
|
+
gzipped, the default bundle 364 B, `phlex/reactive/early` 129 B.
|
|
68
|
+
|
|
69
|
+
## [0.16.8] - 2026-10-19
|
|
70
|
+
|
|
9
71
|
### Changed
|
|
10
72
|
|
|
11
73
|
- **A `reactive_shared_field` drives its host's client bindings too (#440).**
|
|
@@ -4364,7 +4426,10 @@ room for dogfood fixes.
|
|
|
4364
4426
|
scaffolds a reactive component (and an RSpec spec when the app uses RSpec),
|
|
4365
4427
|
state-backed by default or record-backed with `--record`.
|
|
4366
4428
|
|
|
4367
|
-
[Unreleased]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.
|
|
4429
|
+
[Unreleased]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.10...HEAD
|
|
4430
|
+
[0.16.10]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.9...v0.16.10
|
|
4431
|
+
[0.16.9]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.8...v0.16.9
|
|
4432
|
+
[0.16.8]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.7...v0.16.8
|
|
4368
4433
|
[0.16.7]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.6...v0.16.7
|
|
4369
4434
|
[0.16.6]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.5...v0.16.6
|
|
4370
4435
|
[0.16.5]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.4...v0.16.5
|
data/README.md
CHANGED
|
@@ -696,7 +696,7 @@ Use in controllers: `render turbo_stream: Counter.replace(counter)`.
|
|
|
696
696
|
| `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). |
|
|
697
697
|
| `reactive_show(if:/if_any:/unless:)` | **Value-conditional visibility** (the `x-show`/`data-show` case): spread onto the element to show/hide — it toggles `hidden` from the fields' **current values**, client-only, zero round trip. One conditions language: a **Hash is an AND**, an **Array is membership**, a **Range is a threshold**, `if_any:` is OR-of-AND, `unless:` negates. `reactive_values` computes first paint; `disable:` disables a hidden section's controls; `{ same: :email }` compares two fields, `{ digits: 10 }` checks a digit format, `after: :blur` waits for the field's first blur, and `clear:`/`focus:`/`scroll:` run when the section changes visibility. See [Value-conditional visibility](#value-conditional-visibility-reactive_show). |
|
|
698
698
|
| `reactive_media(from:, pool:, take:, match:, when:, pending:, label:, blank_label:)` | A preview `<img>` that **follows a field** (#373): the field's value (its first `take:` characters, or all of it) is a key into `pool`, whose values are **selectors** for `<img>` elements the server rendered — never URLs. A hit copies that image's `src`/`srcset`/`alt` like `js.copy_media` (a pool `<img>` with an `alt` and no `src` is a hit without an image, #381); a miss clears the preview. `label:` gets the `alt` (or `blank_label`) as `textContent`. Below `take:` characters, or while `match:` (a JavaScript-compatible Regexp over the whole key) rejects the key, the binding is **pending** (#380) — never `blank_label` (Regexp options or Ruby-only syntax raise at render); `when:` (same rules) tests the **whole field** before the pool lookup while the key stays the prefix, so `take: 3, when: /\A\d{3,24}\z/` keeps `007bad` pending (#390); `pending: :clear` (default) clears the preview and label, `:keep` leaves them. The preview's `data-reactive-media-state` reads `pending`/`hit`/`miss`, so CSS can hide its row. See [Media previews](https://phlex-reactive.zoolutions.llc/docs/example-client-ops). |
|
|
699
|
-
| `reactive_image_fallback(hide: true, show_alt: nil, wrap: nil)` | An `<img>` that **falls back and recovers** (#383): on `error` it gets `data-reactive-image-state="error"`; `hide:` (default `true`) also hides it, and `show_alt:`, independently, writes its `alt` into that node and shows it; `wrap:` (#392) hides the box around it (marked `data-reactive-wrap-hidden`, shown again only when it carries that mark, its text never written); `load` sets `"loaded"`. A later `src` (from `copy_media`, `reactive_media`, `preview_file`, a morph, or any `src` that loads) shows it again; removing the `src` is not an error. Composes with `reactive_media(…, **reactive_image_fallback)`. See [Client-only ops](https://phlex-reactive.zoolutions.llc/docs/example-client-ops). |
|
|
699
|
+
| `reactive_image_fallback(hide: true, show_alt: nil, wrap: nil)` | An `<img>` that **falls back and recovers** (#383): on `error` it gets `data-reactive-image-state="error"`; `hide:` (default `true`) also hides it, and `show_alt:`, independently, writes its `alt` into that node and shows it; `wrap:` (#392) hides the box around it (marked `data-reactive-wrap-hidden`, shown again only when it carries that mark, its text never written); `load` sets `"loaded"`. An `img` that finished before Turbo inserted it (a frame, a page or a stream render, #452) is marked once it is in. A later `src` (from `copy_media`, `reactive_media`, `preview_file`, a morph, or any `src` that loads) shows it again; removing the `src` is not an error. Composes with `reactive_media(…, **reactive_image_fallback)`. See [Client-only ops](https://phlex-reactive.zoolutions.llc/docs/example-client-ops). |
|
|
700
700
|
| `reactive_countdown(until:, format: :ms, waiting:, done:)` | A server **deadline counted down** on the client (#400): `until:` is an ISO8601 date-time with a zone (or a `Time`); the text is the time left from `Date.now` (`1:30`), as `textContent`, once a second and again when a hidden tab is shown. At zero (or already past on connect) it reads `0:00`, `data-reactive-countdown-state="done"`, `waiting:` hides, `done:` shows and `reactive:countdown-done` fires **once per deadline** (a morph that keeps `until:` does not fire again; a new `until:` restarts). The server renders the first text and visibility. No request, no frame reload. See [Client-only ops](https://phlex-reactive.zoolutions.llc/docs/example-client-ops). |
|
|
701
701
|
| `reactive_css_vars(to:, vars:, global: false)` | Fields that **feed CSS custom properties** on an element (#417), for a preview that follows a control with no request: `vars: { "--light" => "light", "--turn" => { field: "turn", unit: "deg" } }`. Each field is read as `reactive_show` reads one (a checkbox gives `1`/`0`, a radio group its checked value) and parsed as a **finite number**; the client writes `number + unit` with `style.setProperty`, and anything else (empty, text) removes the property so the `var()` fallback applies. No text from a field reaches CSS. Units: `""`, `px`, `%`, `deg`, `turn`, `ms`, `s`, `em`, `rem`, `fr`; names match `--[a-zA-Z0-9-]+`; a bad name or unit or a blank field raises at render. Runs on connect, on `input`/`change` and after a morph. `to:` resolves like a client op's (`:root`, inside the root, `global: true`, an Array). Render the same properties inline for the first paint. See [Client-only ops](https://phlex-reactive.zoolutions.llc/docs/example-client-ops). |
|
|
702
702
|
| `reactive_enable(if:/if_any:/unless:)` | The sibling of `reactive_show` that flips the element's **own `disabled`** (a button, a fieldset) instead of `hidden` — same conditions, same `reactive_values` first paint. `button(**reactive_enable(if: { "ids[]" => { checked: 1.. } }))`. See [Bulk selection](#bulk-selection-reactive_select_all-reactive_count-reactive_enable). |
|
|
@@ -1357,9 +1357,64 @@ vocabulary is a fixed whitelist mirrored by the client: `show`/`hide`/`toggle`
|
|
|
1357
1357
|
flip the `hidden` attribute; `add_class`/`remove_class`/`toggle_class` take one
|
|
1358
1358
|
or more classes. Targets are CSS selectors resolved **within the component's
|
|
1359
1359
|
root** (nested reactive components are never touched — same ownership rule as
|
|
1360
|
-
field collection); `:root` targets the root element itself; `
|
|
1361
|
-
|
|
1362
|
-
|
|
1360
|
+
field collection); `:root` targets the root element itself; `:trigger` (#442)
|
|
1361
|
+
targets the element whose `on_client` binding fired (see "One binding for a
|
|
1362
|
+
list" below); `global: true` on an op escapes to the whole document. An op name
|
|
1363
|
+
the client doesn't recognize logs a warning and is skipped — the rest of the
|
|
1364
|
+
chain still applies.
|
|
1365
|
+
|
|
1366
|
+
**One binding for a list (#442).** A list whose rows each write their own value
|
|
1367
|
+
binds **once**: `within:` delegates the record to the rows, `:trigger` is the
|
|
1368
|
+
row that was picked, and `from:` + `attr:` read the row's value off it instead
|
|
1369
|
+
of baking a literal into every row:
|
|
1370
|
+
|
|
1371
|
+
```ruby
|
|
1372
|
+
ul(id: "menu", role: "listbox", **on_client(:click, js
|
|
1373
|
+
.set_value("#item-value", from: :trigger, attr: "data-value")
|
|
1374
|
+
.text("#item-label", from: :trigger, attr: "data-label")
|
|
1375
|
+
.remove_attr("[role=option]", "aria-selected")
|
|
1376
|
+
.set_attr(:trigger, "aria-selected", "true")
|
|
1377
|
+
.dispatch("app:item-picked", detail_from: { id: "data-id", text: :text }),
|
|
1378
|
+
within: "[role=option]")) do
|
|
1379
|
+
@items.each do |item|
|
|
1380
|
+
li { button(role: "option", data: { id: item.id, value: item.value, label: item.label }) { item.label } }
|
|
1381
|
+
end
|
|
1382
|
+
end
|
|
1383
|
+
```
|
|
1384
|
+
|
|
1385
|
+
- **`within: "[role=option]"`** runs the record only for an event from inside an
|
|
1386
|
+
element matching the selector, under the bound element and owned by this root
|
|
1387
|
+
(a row of a nested reactive root is that root's). That element is the ops'
|
|
1388
|
+
`:trigger`. Anywhere else (the list's padding, a heading) is a complete no-op:
|
|
1389
|
+
no `preventDefault`, no confirm, no ops. Keyboard picking needs
|
|
1390
|
+
`reactive_listnav` on the search input (not on the rows): Enter on the row it
|
|
1391
|
+
highlights clicks that row, which goes through the same binding, and so does a click before the
|
|
1392
|
+
root connects (`phlex/reactive/early` queues a row's click and leaves a click
|
|
1393
|
+
outside every row alone, so a link in the list still navigates; a row inside
|
|
1394
|
+
a nested reactive root is held too, and its replay is a miss). A `within:`
|
|
1395
|
+
selector that does not parse runs nothing, warned under `verbose_errors`. The
|
|
1396
|
+
list is not forced to `type="button"`. It raises with
|
|
1397
|
+
`window:`, `outside:`, `shortcut:` and `once:` (Stimulus drops a `:once`
|
|
1398
|
+
listener on its first event, a miss included).
|
|
1399
|
+
- **`:trigger`** is accepted wherever an op takes a target, and by `expanded:`,
|
|
1400
|
+
`submit(submitter:)` and `copy_media(from:)`. Without `within:` it is the
|
|
1401
|
+
element the binding is on. `set_value`, `paste_into` and `preview_file` refuse
|
|
1402
|
+
it as the field they write.
|
|
1403
|
+
- **`from:` + `attr:`** on `set_value`, `text` and `set_attr` replace the literal
|
|
1404
|
+
value: `from:` is `:trigger`, `:root` or a selector (the op's own scoping,
|
|
1405
|
+
`global:` included, first match); `attr:` is a `data-*` attribute or `:text`
|
|
1406
|
+
(the element's `textContent`) — nothing else, at render and again in the
|
|
1407
|
+
client. A missing attribute reads `""` (it clears); a `from:` that matches
|
|
1408
|
+
nothing skips the op. The write side keeps its own rules (`set_attr`'s name
|
|
1409
|
+
allowlist, `text`'s `textContent`, `set_value`'s `.value`).
|
|
1410
|
+
- **`dispatch(…, detail_from: { key => attr })`** builds the event's detail off
|
|
1411
|
+
the trigger, every value a String, merged over `detail:` (a key in both
|
|
1412
|
+
raises).
|
|
1413
|
+
- A server-pushed op has no trigger: `reply.js`, `broadcast_to(js:)` and
|
|
1414
|
+
`reactive_on_complete` raise on `:trigger`, `from: :trigger` and
|
|
1415
|
+
`detail_from:`. Nor does a window-bound `on_client` (`window:`, `outside:`,
|
|
1416
|
+
`shortcut:`): its `:trigger` ops resolve to nothing, warned under
|
|
1417
|
+
`verbose_errors`.
|
|
1363
1418
|
|
|
1364
1419
|
In development and test (`verbose_errors`), an op whose selector resolves to
|
|
1365
1420
|
**zero elements** also warns once per unique (op, selector, scope) — with a
|
|
@@ -1421,10 +1476,10 @@ button(**on_client(:click, js
|
|
|
1421
1476
|
powerful than `set_attr`. With `global: true` it is the **cross-root text
|
|
1422
1477
|
escape**: paint a value into a recap node outside the component's root
|
|
1423
1478
|
(`js.text("#sum_total", total, global: true)`).
|
|
1424
|
-
- **`dispatch(name, to: nil, detail: {})`** emits a **bubbling `CustomEvent`** so
|
|
1479
|
+
- **`dispatch(name, to: nil, detail: {}, detail_from: {})`** emits a **bubbling `CustomEvent`** so
|
|
1425
1480
|
another component or a plain Stimulus controller can react to a client-only
|
|
1426
1481
|
interaction — `to:` picks the element (default: the component root), `detail:`
|
|
1427
|
-
is the payload.
|
|
1482
|
+
is the payload, and `detail_from:` (#442) adds values read off the trigger.
|
|
1428
1483
|
- **`submit(to = :root)`** commits the **target's own form** via
|
|
1429
1484
|
`requestSubmit()`: the target itself when it *is* a form, its form owner for a
|
|
1430
1485
|
control (`input.form`, honoring a `form=` attribute), else the nearest ancestor
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{Controller as Rt}from"@hotwired/stimulus";import{confirmResolver as Re}from"phlex/reactive/confirm";function Nt(){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 Ot(){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)}}var It=["focus","focus_first","blur"];function Pt(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:js"])return;e["reactive:js"]=function(){let t=Te(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)y("devtools",(o)=>o.missingRoot(r));return}let s=(o)=>me(o,(c)=>Ar(c,i),n?(c,u)=>y("devtools",(d)=>d.diagnoseStream(c,u,i)):void 0),a=t.findIndex((o)=>It.includes(o?.[0]));if(a<0||typeof requestAnimationFrame!=="function")return s(t);s(t.slice(0,a)),requestAnimationFrame(()=>s(t.slice(a)))}}function Mt(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:defer"])return;e["reactive:defer"]=function(){y("defer",(t)=>t.streamAction(this))}}var Ne=!1,le=null;function Ct(){if(Ne)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Ne=!0,document.addEventListener("turbo:before-stream-render",(e)=>{if(Vt(e),Dt(e),qt(e),le)le(e,g.get("effects"));else g.get("effects")?.wrap(e)})}var U="reactive:streamed";function Dt(e){let t=e.detail,r=t?.render,n=t?.newStream??e.target,i=n?.getAttribute?.("action"),s=/^(append|prepend|update)$/.test(i);if(typeof r!=="function"||!(s||/^(before|after|replace)$/.test(i)))return;let a=n.getAttribute("target"),o=n.getAttribute("targets"),c=new Set;for(let u of a?[document.getElementById(a)]:o?document.querySelectorAll(o):[]){let d=(s?u:u?.parentElement)?.closest?.('[data-controller~="reactive"]');if(d)c.add(d)}if(c.size===0)return;t.render=async(u)=>{await r(u);for(let d of c)if(d.isConnected)d.dispatchEvent(new Event(U))}}function ge(e){return e?.tagName==="DIALOG"&&typeof e.showModal==="function"}function be(e){try{return e.matches(":modal")}catch{return!1}}function et(e){if(!ge(e)){if(e?.closest?.('[data-reactive-verbose="true"], [data-reactive-debug="true"]'))console.warn(`[phlex-reactive] show_modal targets a <dialog>, not <${e.localName}> — skipped`);return}if(!e.isConnected||be(e))return;if(e.open)e.close();e.showModal()}function $t(e){if(ge(e)&&e.open)e.close()}function V(e){let r=[...e?.querySelectorAll?.("dialog[data-reactive-modal]")??[]];if(e?.matches?.("dialog[data-reactive-modal]"))r.push(e);for(let n of r)if(n.open&&!be(n))et(n)}function qt(e){let t=e.detail,r=t?.render,n=t?.newStream??e.target;if(typeof r!=="function"||!n?.querySelector?.("template")?.content?.querySelector?.("dialog"))return;t.render=async(i)=>{await r(i),V(document)}}var Oe=!1;function Wt(){if(Oe)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Oe=!0,document.addEventListener("turbo:morph-element",(t)=>{if(t.target?.matches?.('[data-controller~="reactive"]'))V(t.target)}),document.addEventListener("turbo:morph",()=>V(document));let e=new WeakSet;document.addEventListener("turbo:before-morph-element",(t)=>{let r=t.target,n=t.detail?.newElement;if(!ge(r)||!n)return;if(n.hasAttribute?.("open"))e.delete(r);else e.add(r)}),document.addEventListener("turbo:before-morph-attribute",(t)=>{let{target:r,detail:n}=t;if(n?.attributeName!=="open"||n.mutationType!=="remove")return;if(!e.has(r)||!r.open||!be(r))return;e.delete(r),t.preventDefault(),r.close()})}var de=new WeakMap;function tt(e,t,r,n){let i=de.get(e)??new Map;de.set(e,i);let s=(a,o)=>{i.delete(a),i.set(a,o)};if(t.endsWith("_class"))for(let a of r.classes??[])s(`.${a}`,e.classList.contains(a));else if(t.endsWith("_attr"))vt(r.name)||s(r.name,e.getAttribute(r.name));else if(t==="show"||t==="hide"||t==="toggle"){if(s("hidden",e.getAttribute("hidden")),r.expanded!=null)for(let a of n({...r,to:r.expanded}))tt(a,"set_attr",{name:"aria-expanded"})}}var Ie=!1;function Bt(){if(Ie)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Ie=!0,document.addEventListener("turbo:morph-element",(e)=>{let t=e.target;for(let[r,n]of de.get(t)??[])if(r[0]===".")t.classList.toggle(r.slice(1),n);else if(n==null)t.removeAttribute(r);else if(t.getAttribute(r)!==n)t.setAttribute(r,n)})}var rt="data-reactive-image-fallback",R="data-reactive-image-state",fe="data-reactive-image-hidden",ne=null,he="data-reactive-wrap-hidden";function nt(e){if(e.hasAttribute("hidden"))return;e.setAttribute("hidden",""),e.setAttribute(he,"")}function it(e){if(!e.hasAttribute(he))return;e.removeAttribute("hidden"),e.removeAttribute(he)}function N(e){if(e?.localName!=="img")return null;let t=e.getAttribute(rt);if(t==null)return null;try{return JSON.parse(t)||{}}catch{return{}}}var ot=(e)=>e.getAttribute("src")||e.getAttribute("srcset");function ye(e,t){if(typeof t!=="string"||!t)return null;try{return e.closest('[data-controller~="reactive"]')?.querySelector(t)??null}catch{return null}}function st(e,t){let r=ye(e,t.alt);return r&&!r.contains(e)?r:null}function Y(e,t,r){if(r==="error"){if(t.hide&&!e.hasAttribute("hidden"))e.setAttribute("hidden",""),e.setAttribute(fe,"");if(t.wrap){let i=ye(e,t.wrap);if(i)nt(i);else console.warn(`[phlex-reactive] reactive_image_fallback wrap: ${JSON.stringify(t.wrap)} is not in the root — skipped`)}let n=st(e,t);if(n)n.textContent=e.getAttribute("alt")??"",n.hidden=!1}else ee(e,t);e.setAttribute(R,r)}function ee(e,t=N(e)){if(!t||e.getAttribute(R)==null)return;if(e.getAttribute(R)==="error"){if(e.hasAttribute(fe))e.removeAttribute("hidden");let r=ye(e,t.wrap);if(r)it(r);let n=st(e,t);if(n)n.hidden=!0}e.removeAttribute(R),e.removeAttribute(fe)}function Pe(e){let t=e.target,r=N(t);if(!r)return;if(e.type==="load")Y(t,r,"loaded");else if(ot(t))Y(t,r,"error");else ee(t,r)}function jt(){if(ne)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;let e=new WeakMap;ne={error:Pe,load:Pe,"turbo:before-morph-element":(t)=>{let r=t.target,n=t.detail?.newElement,i=r?.getAttribute?.(R);if(i==null||!n||!N(r))return;let s=(a)=>r.getAttribute(a)===n.getAttribute?.(a);if(s("src")&&s("srcset"))e.set(r,i)},"turbo:morph-element":(t)=>{let r=t.target,n=e.get(r);if(n===void 0)return;e.delete(r),queueMicrotask(()=>{let i=N(r);if(i)Y(r,i,n)})}};for(let[t,r]of Object.entries(ne))document.addEventListener(t,r,!0);for(let t of document.querySelectorAll?.(`img[${rt}]`)??[]){if(!t.complete||!ot(t))continue;let r=`${t.getAttribute("src")} ${t.getAttribute("srcset")}`,n=(i)=>`${t.getAttribute("src")} ${t.getAttribute("srcset")}`===r&&Y(t,N(t)??{},i);if(t.naturalWidth>0)n("loaded");else if(typeof t.decode==="function")t.decode().then(()=>n("loaded"),()=>n("error"));else n("error")}}function at(e){le=e}var q,ie=null,Me="[data-reactive-editable][contenteditable=plaintext-only]";function ct(){if(q===void 0)try{let e=document.createElement("div");e.contentEditable="plaintext-only",q=e.contentEditable==="plaintext-only"}catch{q=!1}return q}function J(e){if(e.matches?.(Me))e.setAttribute("contenteditable","true");e.querySelectorAll?.(Me).forEach(J)}function Ut(){if(ie||typeof document>"u"||typeof document.createElement!=="function")return;if(ct())return;J(document),ie=new MutationObserver((e)=>{for(let t of e)if(t.type==="attributes")J(t.target);else t.addedNodes.forEach(J)}),ie.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["contenteditable","data-reactive-editable"]})}var Ce=!1;function De(e){return e===document.activeElement&&(e.localName==="input"||e.localName==="textarea"||e.hasAttribute("data-reactive-editable"))&&!e.hasAttribute("data-reactive-morph-value")&&!!e.closest('[data-controller~="reactive"]')}function Jt(){if(Ce)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Ce=!0,document.addEventListener("turbo:before-morph-element",(e)=>{let t=e.target,r=e.detail?.newElement;if(!r||e.defaultPrevented)return;let n=De(t);if(n)zt(t,r);if(t.hasAttribute?.("data-reactive-editable")){if(X.set(t,T(r)),!n)return;for(let{name:s}of[...t.attributes])if(!r.hasAttribute(s)&&s!=="contenteditable"&&s!==_)t.removeAttribute(s);for(let{name:s,value:a}of r.attributes)if(s!=="contenteditable"&&t.getAttribute(s)!==a)t.setAttribute(s,a);return e.preventDefault()}if(t.localName!=="input"||!n)return;let i=r.getAttribute("value");if(i==null)t.removeAttribute("value");else if(t.getAttribute("value")!==i)t.setAttribute("value",i)}),document.addEventListener("focusin",(e)=>Se(e.target)),document.addEventListener("turbo:before-morph-attribute",(e)=>{let t=e.detail?.attributeName;if((t==="value"||t===_)&&De(e.target))e.preventDefault()}),document.addEventListener("input",(e)=>{let t=e.target;if(t?.hasAttribute?.(_)&&_e(t)===we(t))t.removeAttribute(_)})}var _="data-reactive-held",ve='[data-controller~="reactive"]',H=null,k=new Map;function _e(e){return e.hasAttribute("data-reactive-editable")?T(e):e.value}function we(e){return e.hasAttribute("data-reactive-editable")?Ee(e):e.defaultValue}function Ht(e){if(e.hasAttribute("data-reactive-editable"))return T(e);return e.localName==="textarea"?e.textContent:e.getAttribute("value")??""}function zt(e,t){let r=e.getAttribute("name");if(!r||/^(checkbox|radio)$/.test(e.type)||k.has(e.closest(ve)))return;let n=Ht(t);if(n===_e(e))return e.removeAttribute(_);if(n===we(e))return;e.setAttribute(_,""),e.dispatchEvent(new CustomEvent("reactive:held",{bubbles:!0,detail:{name:r,theirs:n}}))}function Kt(e){let t=[];for(let r of e.querySelectorAll(`[${_}]`)){if(r.closest(ve)!==e)continue;let n=r.getAttribute("name");if(_e(r)===we(r))r.removeAttribute(_);else if(n&&!t.includes(n))t.push(n)}if(t.length===0)return null;return JSON.stringify(t).replace(/[\u007f-]/g,(r)=>`\\u${r.charCodeAt(0).toString(16).padStart(4,"0")}`)}function ut(e,t){if(t===!0)return;for(let r of e.querySelectorAll(`[${_}]`))if(r.closest(ve)===e&&!t?.includes(r.getAttribute("name")))r.removeAttribute(_)}function Gt(e){let t=e.headers.get("X-Reactive-Refused");if(t==="*")return!0;try{let r=JSON.parse(t);return Array.isArray(r)?r:null}catch{return null}}function $e(e,t,r=null){let n={root:e,streams:0,keep:r},i=H;H=n;try{window.Turbo.renderStreamMessage(t)}finally{H=i}if(n.streams===0)ut(e,r)}function Vt(e){let t=H,r=e.detail,n=r?.render;if(!t||typeof n!=="function")return;t.streams++,r.render=async(i)=>{k.set(t.root,(k.get(t.root)||0)+1);try{return await n(i)}finally{let s=k.get(t.root)-1;if(s)k.set(t.root,s);else k.delete(t.root);ut(t.root,t.keep)}}}var qe="__materialize",We=!1;function Yt(){if(We)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;We=!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 Xt="phlex-reactive:latency";function lt(){return typeof sessionStorage<"u"&&Boolean(sessionStorage.getItem(Xt))}function Ae(){if(typeof document>"u")return;if(!g.has("devtools")&&!w.get("devtools")[1])return;let e=document.querySelector?.('meta[name="phlex-reactive-env"]')?.content==="development";if(e||lt())y("devtools",(t)=>e&&t.attach())}var dt="data-reactive-active",A=0;function ft(){if(A++,A===1)mt("reactive:busy")}function ht(){if(A===0)return;if(A--,A===0)mt("reactive:idle")}function Qr(){return A}function en(){A=0,(typeof document<"u"?document.documentElement:null)?.removeAttribute?.(dt)}function mt(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.toggleAttribute==="function")t.toggleAttribute(dt,A>0);if(typeof document.dispatchEvent==="function"&&typeof CustomEvent==="function")document.dispatchEvent(new CustomEvent(e,{detail:{count:A}}))}var pt="data-reactive-requests";function gt(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.setAttribute!=="function"||!Zt(t))return;let r=Qt(t);r[e]=(Number(r[e])||0)+1,t.setAttribute(pt,JSON.stringify(r))}function Zt(e){return e.hasAttribute?.("data-reactive-verbose")||!!document.querySelector?.('[data-reactive-verbose="true"]')}function Qt(e){try{let t=JSON.parse(e.getAttribute(pt));if(t&&typeof t==="object")return{action:0,defer:0,...t}}catch{}return{action:0,defer:0}}function Be(){Nt(),Ot(),Pt(),Mt(),Ct(),Jt(),Wt(),Bt(),jt(),Ut(),Yt(),Ae()}function er(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var bt=Symbol.for("phlex-reactive.core");if(globalThis[bt])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[bt]=!0;var yt=!1;function tr(){if(yt)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(tr,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",e,{once:!0});else e()}var rr=new Set(["href","src","srcset","srcdoc","action","formaction","xlink:href","style"]);function vt(e){let t=String(e).toLowerCase();return t.startsWith("on")||rr.has(t)}var oe=new WeakMap;function nr(e,t,r){let[n,i,s]=t;oe.get(e)?.(),e.classList.add(n,i),r();let a=!1,o=requestAnimationFrame(()=>{if(a)return;e.classList.remove(i),e.classList.add(s)}),c=(d)=>{if(a||d&&d.target!==e)return;a=!0,oe.delete(e),clearTimeout(u),globalThis.cancelAnimationFrame?.(o),e.removeEventListener("animationend",c),e.removeEventListener("transitionend",c),e.classList.remove(n,i,s)};oe.set(e,c),e.addEventListener("animationend",c),e.addEventListener("transitionend",c);let u=setTimeout(c,ir(e))}function ir(e){let t=0;try{let r=getComputedStyle(e);for(let n of["transition","animation"]){let[i,s]=["Duration","Delay"].map((o)=>String(r[n+o]).split(",").map((c)=>parseFloat(c)*(/ms/.test(c)?1:1000)||0)),a=String(r[n+"IterationCount"]).split(",").map((o)=>/inf/.test(o)?1/0:parseFloat(o)>=0?parseFloat(o):1);for(let o=0;o<i.length||o<s.length||o<a.length;o++){let c=i[o%i.length]*a[o%a.length]||0;t=Math.max(t,c+s[o%s.length])}}}catch{}return Math.min(Math.max(t+50,350),5000)}var or=":is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])",sr=new Set(["lexxy-editor","trix-editor"]);function T(e){let t="",r=!1,n=(s)=>{if(r&&t&&!t.endsWith(`
|
|
1
|
+
import{Controller as Nt}from"@hotwired/stimulus";import{confirmResolver as Oe}from"phlex/reactive/confirm";function Ot(){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 It(){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)}}var Pt=["focus","focus_first","blur"];function Mt(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:js"])return;e["reactive:js"]=function(){let t=ke(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)v("devtools",(o)=>o.missingRoot(r));return}let s=(o)=>pe(o,(c)=>Fr(c,i),n?(c,u)=>v("devtools",(d)=>d.diagnoseStream(c,u,i)):void 0),a=t.findIndex((o)=>Pt.includes(o?.[0]));if(a<0||typeof requestAnimationFrame!=="function")return s(t);s(t.slice(0,a)),requestAnimationFrame(()=>s(t.slice(a)))}}function Ct(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:defer"])return;e["reactive:defer"]=function(){v("defer",(t)=>t.streamAction(this))}}var Ie=!1,de=null;function Dt(){if(Ie)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Ie=!0,document.addEventListener("turbo:before-stream-render",(e)=>{if(Yt(e),$t(e),Wt(e),de)de(e,g.get("effects"));else g.get("effects")?.wrap(e)})}var J="reactive:streamed";function $t(e){let t=e.detail,r=t?.render,n=t?.newStream??e.target,i=n?.getAttribute?.("action"),s=/^(append|prepend|update)$/.test(i);if(typeof r!=="function"||!(s||/^(before|after|replace)$/.test(i)))return;let a=n.getAttribute("target"),o=n.getAttribute("targets"),c=new Set;for(let u of a?[document.getElementById(a)]:o?document.querySelectorAll(o):[]){let d=(s?u:u?.parentElement)?.closest?.('[data-controller~="reactive"]');if(d)c.add(d)}if(c.size===0)return;t.render=async(u)=>{await r(u);for(let d of c)if(d.isConnected)d.dispatchEvent(new Event(J))}}function be(e){return e?.tagName==="DIALOG"&&typeof e.showModal==="function"}function ye(e){try{return e.matches(":modal")}catch{return!1}}function rt(e){if(!be(e)){if(e?.closest?.('[data-reactive-verbose="true"], [data-reactive-debug="true"]'))console.warn(`[phlex-reactive] show_modal targets a <dialog>, not <${e.localName}> — skipped`);return}if(!e.isConnected||ye(e))return;if(e.open)e.close();e.showModal()}function qt(e){if(be(e)&&e.open)e.close()}function Y(e){let r=[...e?.querySelectorAll?.("dialog[data-reactive-modal]")??[]];if(e?.matches?.("dialog[data-reactive-modal]"))r.push(e);for(let n of r)if(n.open&&!ye(n))rt(n)}function Wt(e){let t=e.detail,r=t?.render,n=t?.newStream??e.target;if(typeof r!=="function"||!n?.querySelector?.("template")?.content?.querySelector?.("dialog"))return;t.render=async(i)=>{await r(i),Y(document)}}var Pe=!1;function Bt(){if(Pe)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Pe=!0,document.addEventListener("turbo:morph-element",(t)=>{if(t.target?.matches?.('[data-controller~="reactive"]'))Y(t.target)}),document.addEventListener("turbo:morph",()=>Y(document));let e=new WeakSet;document.addEventListener("turbo:before-morph-element",(t)=>{let r=t.target,n=t.detail?.newElement;if(!be(r)||!n)return;if(n.hasAttribute?.("open"))e.delete(r);else e.add(r)}),document.addEventListener("turbo:before-morph-attribute",(t)=>{let{target:r,detail:n}=t;if(n?.attributeName!=="open"||n.mutationType!=="remove")return;if(!e.has(r)||!r.open||!ye(r))return;e.delete(r),t.preventDefault(),r.close()})}var fe=new WeakMap;function nt(e,t,r,n){let i=fe.get(e)??new Map;fe.set(e,i);let s=(a,o)=>{i.delete(a),i.set(a,o)};if(t.endsWith("_class"))for(let a of r.classes??[])s(`.${a}`,e.classList.contains(a));else if(t.endsWith("_attr"))_t(r.name)||s(r.name,e.getAttribute(r.name));else if(t==="show"||t==="hide"||t==="toggle"){if(s("hidden",e.getAttribute("hidden")),r.expanded!=null)for(let a of n({...r,to:r.expanded}))nt(a,"set_attr",{name:"aria-expanded"})}}var Me=!1;function jt(){if(Me)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Me=!0,document.addEventListener("turbo:morph-element",(e)=>{let t=e.target;for(let[r,n]of fe.get(t)??[])if(r[0]===".")t.classList.toggle(r.slice(1),n);else if(n==null)t.removeAttribute(r);else if(t.getAttribute(r)!==n)t.setAttribute(r,n)})}var ve="data-reactive-image-fallback",L="data-reactive-image-state",he="data-reactive-image-hidden",ie=null,me="data-reactive-wrap-hidden";function it(e){if(e.hasAttribute("hidden"))return;e.setAttribute("hidden",""),e.setAttribute(me,"")}function ot(e){if(!e.hasAttribute(me))return;e.removeAttribute("hidden"),e.removeAttribute(me)}function P(e){if(e?.localName!=="img")return null;let t=e.getAttribute(ve);if(t==null)return null;try{return JSON.parse(t)||{}}catch{return{}}}var st=(e)=>e.getAttribute("src")||e.getAttribute("srcset");function _e(e,t){if(typeof t!=="string"||!t)return null;try{return e.closest('[data-controller~="reactive"]')?.querySelector(t)??null}catch{return null}}function at(e,t){let r=_e(e,t.alt);return r&&!r.contains(e)?r:null}function X(e,t,r){if(r==="error"){if(t.hide&&!e.hasAttribute("hidden"))e.setAttribute("hidden",""),e.setAttribute(he,"");if(t.wrap){let i=_e(e,t.wrap);if(i)it(i);else console.warn(`[phlex-reactive] reactive_image_fallback wrap: ${JSON.stringify(t.wrap)} is not in the root — skipped`)}let n=at(e,t);if(n)n.textContent=e.getAttribute("alt")??"",n.hidden=!1}else te(e,t);e.setAttribute(L,r)}function te(e,t=P(e)){if(!t||e.getAttribute(L)==null)return;if(e.getAttribute(L)==="error"){if(e.hasAttribute(he))e.removeAttribute("hidden");let r=_e(e,t.wrap);if(r)ot(r);let n=at(e,t);if(n)n.hidden=!0}e.removeAttribute(L),e.removeAttribute(he)}function Ce(e){let t=e.target,r=P(t);if(!r)return;if(e.type==="load")X(t,r,"loaded");else if(st(t))X(t,r,"error");else te(t,r)}function Ut(){if(ie)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;let e=new WeakMap;ie={error:Ce,load:Ce,"turbo:before-morph-element":(t)=>{let r=t.target,n=t.detail?.newElement,i=r?.getAttribute?.(L);if(i==null||!n||!P(r))return;let s=(a)=>r.getAttribute(a)===n.getAttribute?.(a);if(s("src")&&s("srcset"))e.set(r,i)},"turbo:morph-element":(t)=>{let r=t.target,n=e.get(r);if(n===void 0)return;e.delete(r),queueMicrotask(()=>{let i=P(r);if(i)X(r,i,n)})},"turbo:frame-render":(t)=>q(t.target),"turbo:render":()=>q(document),"turbo:before-stream-render":(t)=>{let r=t.detail,n=r?.render,i=r?.newStream??t.target;if(typeof n!=="function"||!i?.querySelector?.("template")?.content?.querySelector?.(`img[${ve}]`))return;r.render=async(s)=>{await n(s),q(document)}}};for(let[t,r]of Object.entries(ie))document.addEventListener(t,r,!0);q(document)}function q(e){for(let t of e?.querySelectorAll?.(`img[${ve}]`)??[]){if(t.getAttribute(L)!=null||!t.complete||!st(t))continue;let r=`${t.getAttribute("src")} ${t.getAttribute("srcset")}`,n=(i)=>`${t.getAttribute("src")} ${t.getAttribute("srcset")}`===r&&X(t,P(t)??{},i);if(t.naturalWidth>0)n("loaded");else if(typeof t.decode==="function")t.decode().then(()=>n("loaded"),()=>n("error"));else n("error")}}function ct(e){de=e}var W,oe=null,De="[data-reactive-editable][contenteditable=plaintext-only]";function ut(){if(W===void 0)try{let e=document.createElement("div");e.contentEditable="plaintext-only",W=e.contentEditable==="plaintext-only"}catch{W=!1}return W}function z(e){if(e.matches?.(De))e.setAttribute("contenteditable","true");e.querySelectorAll?.(De).forEach(z)}function Jt(){if(oe||typeof document>"u"||typeof document.createElement!=="function")return;if(ut())return;z(document),oe=new MutationObserver((e)=>{for(let t of e)if(t.type==="attributes")z(t.target);else t.addedNodes.forEach(z)}),oe.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["contenteditable","data-reactive-editable"]})}var $e=!1;function qe(e){return e===document.activeElement&&(e.localName==="input"||e.localName==="textarea"||e.hasAttribute("data-reactive-editable"))&&!e.hasAttribute("data-reactive-morph-value")&&!!e.closest('[data-controller~="reactive"]')}function zt(){if($e)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;$e=!0,document.addEventListener("turbo:before-morph-element",(e)=>{let t=e.target,r=e.detail?.newElement;if(!r||e.defaultPrevented)return;let n=qe(t);if(n)Kt(t,r);if(t.hasAttribute?.("data-reactive-editable")){if(Q.set(t,T(r)),!n)return;for(let{name:s}of[...t.attributes])if(!r.hasAttribute(s)&&s!=="contenteditable"&&s!==_)t.removeAttribute(s);for(let{name:s,value:a}of r.attributes)if(s!=="contenteditable"&&t.getAttribute(s)!==a)t.setAttribute(s,a);return e.preventDefault()}if(t.localName!=="input"||!n)return;let i=r.getAttribute("value");if(i==null)t.removeAttribute("value");else if(t.getAttribute("value")!==i)t.setAttribute("value",i)}),document.addEventListener("focusin",(e)=>Te(e.target)),document.addEventListener("turbo:before-morph-attribute",(e)=>{let t=e.detail?.attributeName;if((t==="value"||t===_)&&qe(e.target))e.preventDefault()}),document.addEventListener("input",(e)=>{let t=e.target;if(t?.hasAttribute?.(_)&&Ae(t)===Se(t))t.removeAttribute(_)})}var _="data-reactive-held",we='[data-controller~="reactive"]',H=null,k=new Map;function Ae(e){return e.hasAttribute("data-reactive-editable")?T(e):e.value}function Se(e){return e.hasAttribute("data-reactive-editable")?Fe(e):e.defaultValue}function Ht(e){if(e.hasAttribute("data-reactive-editable"))return T(e);return e.localName==="textarea"?e.textContent:e.getAttribute("value")??""}function Kt(e,t){let r=e.getAttribute("name");if(!r||/^(checkbox|radio)$/.test(e.type)||k.has(e.closest(we)))return;let n=Ht(t);if(n===Ae(e))return e.removeAttribute(_);if(n===Se(e))return;e.setAttribute(_,""),e.dispatchEvent(new CustomEvent("reactive:held",{bubbles:!0,detail:{name:r,theirs:n}}))}function Vt(e){let t=[];for(let r of e.querySelectorAll(`[${_}]`)){if(r.closest(we)!==e)continue;let n=r.getAttribute("name");if(Ae(r)===Se(r))r.removeAttribute(_);else if(n&&!t.includes(n))t.push(n)}if(t.length===0)return null;return JSON.stringify(t).replace(/[\u007f-]/g,(r)=>`\\u${r.charCodeAt(0).toString(16).padStart(4,"0")}`)}function lt(e,t){if(t===!0)return;for(let r of e.querySelectorAll(`[${_}]`))if(r.closest(we)===e&&!t?.includes(r.getAttribute("name")))r.removeAttribute(_)}function Gt(e){let t=e.headers.get("X-Reactive-Refused");if(t==="*")return!0;try{let r=JSON.parse(t);return Array.isArray(r)?r:null}catch{return null}}function We(e,t,r=null){let n={root:e,streams:0,keep:r},i=H;H=n;try{window.Turbo.renderStreamMessage(t)}finally{H=i}if(n.streams===0)lt(e,r)}function Yt(e){let t=H,r=e.detail,n=r?.render;if(!t||typeof n!=="function")return;t.streams++,r.render=async(i)=>{k.set(t.root,(k.get(t.root)||0)+1);try{return await n(i)}finally{let s=k.get(t.root)-1;if(s)k.set(t.root,s);else k.delete(t.root);lt(t.root,t.keep)}}}var Be="__materialize",je=!1;function Xt(){if(je)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;je=!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 Qt="phlex-reactive:latency";function dt(){return typeof sessionStorage<"u"&&Boolean(sessionStorage.getItem(Qt))}function Ee(){if(typeof document>"u")return;if(!g.has("devtools")&&!w.get("devtools")[1])return;let e=document.querySelector?.('meta[name="phlex-reactive-env"]')?.content==="development";if(e||dt())v("devtools",(t)=>e&&t.attach())}var ft="data-reactive-active",A=0;function ht(){if(A++,A===1)pt("reactive:busy")}function mt(){if(A===0)return;if(A--,A===0)pt("reactive:idle")}function nn(){return A}function on(){A=0,(typeof document<"u"?document.documentElement:null)?.removeAttribute?.(ft)}function pt(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.toggleAttribute==="function")t.toggleAttribute(ft,A>0);if(typeof document.dispatchEvent==="function"&&typeof CustomEvent==="function")document.dispatchEvent(new CustomEvent(e,{detail:{count:A}}))}var gt="data-reactive-requests";function bt(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.setAttribute!=="function"||!Zt(t))return;let r=er(t);r[e]=(Number(r[e])||0)+1,t.setAttribute(gt,JSON.stringify(r))}function Zt(e){return e.hasAttribute?.("data-reactive-verbose")||!!document.querySelector?.('[data-reactive-verbose="true"]')}function er(e){try{let t=JSON.parse(e.getAttribute(gt));if(t&&typeof t==="object")return{action:0,defer:0,...t}}catch{}return{action:0,defer:0}}function Ue(){Ot(),It(),Mt(),Ct(),Dt(),zt(),Bt(),jt(),Ut(),Jt(),Xt(),Ee()}function tr(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var yt=Symbol.for("phlex-reactive.core");if(globalThis[yt])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[yt]=!0;var vt=!1;function rr(){if(vt)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(rr,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",e,{once:!0});else e()}var nr=new Set(["href","src","srcset","srcdoc","action","formaction","xlink:href","style"]);function _t(e){let t=String(e).toLowerCase();return t.startsWith("on")||nr.has(t)}var se=new WeakMap;function ir(e,t,r){let[n,i,s]=t;se.get(e)?.(),e.classList.add(n,i),r();let a=!1,o=requestAnimationFrame(()=>{if(a)return;e.classList.remove(i),e.classList.add(s)}),c=(d)=>{if(a||d&&d.target!==e)return;a=!0,se.delete(e),clearTimeout(u),globalThis.cancelAnimationFrame?.(o),e.removeEventListener("animationend",c),e.removeEventListener("transitionend",c),e.classList.remove(n,i,s)};se.set(e,c),e.addEventListener("animationend",c),e.addEventListener("transitionend",c);let u=setTimeout(c,or(e))}function or(e){let t=0;try{let r=getComputedStyle(e);for(let n of["transition","animation"]){let[i,s]=["Duration","Delay"].map((o)=>String(r[n+o]).split(",").map((c)=>parseFloat(c)*(/ms/.test(c)?1:1000)||0)),a=String(r[n+"IterationCount"]).split(",").map((o)=>/inf/.test(o)?1/0:parseFloat(o)>=0?parseFloat(o):1);for(let o=0;o<i.length||o<s.length||o<a.length;o++){let c=i[o%i.length]*a[o%a.length]||0;t=Math.max(t,c+s[o%s.length])}}}catch{}return Math.min(Math.max(t+50,350),5000)}var sr=":is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])",ar=new Set(["lexxy-editor","trix-editor"]);function T(e){let t="",r=!1,n=(s)=>{if(r&&t&&!t.endsWith(`
|
|
2
2
|
`))t+=`
|
|
3
3
|
`;r=!1,t+=s},i=(s)=>{for(let a of s.childNodes){let o=/^(div|p|li)$/.test(a.localName);if(o)r=!0;if(a.nodeType===3)a.data&&n(a.data);else if(a.localName==="br")n(`
|
|
4
4
|
`);else if(a.nodeType===1)i(a);if(o)r=!0}};return i(e),t=t.replace(/\r\n?/g,`
|
|
5
|
-
`).replace(/\n$/,""),e.getAttribute("data-reactive-editable")==="multi"?t:t.replace(/\n/g," ")}var
|
|
6
|
-
`):e.value}function mr(e,t,r){if(r?.transition)nr(e,r.transition,()=>e.hidden=t);else e.hidden=t}function se(e,t,r,n){if(mr(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 ae(e){if(!vt(e))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(e)} — skipped`),!1}function St(e,t){if(e?.localName!=="img")return console.warn(`[phlex-reactive] copy_media targets an <img>, not <${e?.localName}> — skipped`),null;let r=t?.localName==="img"?t:null,n=r?.getAttribute("src"),i=!1;for(let a of["srcset","src"]){let o=n?r.getAttribute(a):null;if(o==null){if(e.hasAttribute(a))i=e.removeAttribute(a)??!0}else if(e.getAttribute(a)!==o)i=e.setAttribute(a,o)??!0}if(i)ee(e);let s=r?.getAttribute("alt")??"";if(e.getAttribute("alt")!==s)e.setAttribute("alt",s);return r?s:!1}var pr='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function gr(e){return e.querySelectorAll?.(pr)?.[0]??null}function Te(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 Je=Object.freeze({backspace:"Backspace",delete:"Delete",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"}),He=Object.freeze(["meta","ctrl","alt","shift"]);function te(e,t,r){let n=e.split("+");for(let a of He)if(n.includes(a)!==Boolean(t[`${a}Key`]))return!1;let i=n.find((a)=>!He.includes(a));if(i===void 0||typeof t.key!=="string")return!0;let s=r&&Object.hasOwn(r,i)?r[i]:Object.hasOwn(Je,i)?Je[i]:/^[a-z0-9]$/.test(i)?i:null;return typeof s==="string"&&s.toLowerCase()===t.key.toLowerCase()}var br=(e)=>e&&typeof e==="object"?e.keys:String(e),Fe=()=>K().prevented??=new WeakSet;function ce(e,t){if(t!=null&&!e.defaultPrevented)Fe().add(e);e.preventDefault()}function W(e,t,r){if(t.defaultPrevented&&e?.handled!==!0&&!Fe().has(t))return!1;let n=t.target;if(e?.inEditable!==!0&&(n?.isContentEditable||/^(input|textarea|select)$/.test(n?.localName)))return!1;let i=/[Mm]ac|iP/.test(navigator.userAgentData?.platform??navigator.platform)?"meta":"ctrl";return te(br(e).replace(/^mod\+/,`${i}+`),t,r)}function yr(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:Te(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 ze(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)!==Le(t.currentTarget))return!1;return i<0||r===null||te(n.slice(i+1),t,r)}function vr(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 Ke=new WeakMap;function _r(e,t,r){if(!r.once)return!1;let n=t.currentTarget??e.element,i=Ke.get(e);if(!i)i=new WeakMap,Ke.set(e,i);let s=i.get(n);if(!s)s=new Set,i.set(n,s);let a=t.params?.ops,c=(n===globalThis.window?`${typeof a==="string"?a:JSON.stringify(a??null)}|`:"")+JSON.stringify(r);if(s.has(c))return!0;return s.add(c),!1}var Ge=new WeakMap;function wr(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=Ge.get(e);if(!i)i=new WeakMap,Ge.set(e,i);let s=i.get(t);if(!s)s=new Map,i.set(t,s);let a=s.get(e.currentTarget);if(!a)a=new Set,s.set(e.currentTarget,a);if(a.has(n))return!0;return a.add(n),!1}function me(e,t,r){for(let n of e){if(!Array.isArray(n))continue;let[i,s={}]=n;if(!Object.hasOwn(je,i)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(i)} — skipped`);continue}let a=t(s);if(a.length===0&&r)r(i,s);for(let o of a)if(je[i](o,s,t),s?.keep===!0)tt(o,i,s,t)}}function Ar(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 Sr(e){let t=e.getAttribute?.("data-reactive-persist");return Boolean(t)&&t!=="off"}function ke(e){return["defer-token","defer-src","lazy-on","lazy-visible"].some((t)=>e.getAttribute?.(`data-reactive-${t}`)!=null)}var F='[data-controller~="reactive"]',Er='[data-controller~="reactive"],[data-reactive-dormant~="reactive"]',pe=(e)=>e.getAttribute?.("data-reactive-token-value")==null&&!ke(e);function x(e,t,r){let n=e?.closest?.(t);while(n&&n!==r&&pe(n))n=n.parentElement?.closest?.(t);return n??null}var B=new WeakMap,j=new WeakMap;function Tr(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 Fr(e){return["show-targets","group-targets","on-complete","filter-input","tags-field","css-vars"].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], [data-reactive-editable], [data-reactive-media], [data-reactive-css-vars]")!=null}function kr(e){return e.getAttribute?.("data-reactive-compute-inputs-param")!=null}function Lr(e){return Boolean(e.matches?.("[data-reactive-sortable],[data-reactive-sortable-source]")||e.querySelector?.("[data-reactive-sortable],[data-reactive-sortable-source]"))}function xr(e){return Boolean(e.matches?.("[data-reactive-frame],[data-reactive-box],[data-reactive-point]")||e.querySelector?.("[data-reactive-frame],[data-reactive-box],[data-reactive-point]"))}function Et(e){return e.getAttribute?.("data-reactive-presence")!=null}function Rr(e){return Boolean(e.matches?.("[data-reactive-countdown]")||e.querySelector?.("[data-reactive-countdown]"))}var Nr=[["persist",[Sr,null,null,!0]],["defer",[ke,null]],["form",[Tr,null]],["bindings",[Fr,null,null,!0]],["compute",[kr,null,null,!0]],["sortable",[Lr,null]],["drag",[xr,null]],["presence",[Et,null]],["countdown",[Rr,null]],["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]]],w=new Map(Nr),Ve=new Map,g=new Map,Or=new Map;function b(e,t,r){Tt.set(e,[t,r]),Ir(e)}var Tt=new Map;function Ir(e){let t=w.get(e),[r,n]=Tt.get(e);t[1]=r,t[2]=n}function tn(e,t){t.install?.(M),g.set(e,t),Or.set(e,t)}function Ft(e){let t=[];for(let[r,[n]]of w){if(!n||g.has(r))continue;try{if(e.some((i)=>n(i)))t.push(r)}catch{}}return t}function kt(e){return P(e).catch((t)=>Z(e,"load",t))}function P(e){let t=Ve.get(e);if(!t)t=(w.get(e)[1]??(()=>Promise.reject(Error("this entry has no way to import it"))))().then((n)=>(n.install?.(M),g.set(e,n),n)),Ve.set(e,t);return t}var Ye=new Set;function Z(e,t,r){let n=e+t;if(Ye.has(n))return;Ye.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 y(e,t){let r=g.get(e);if(r)return t(r);P(e).then(t,(n)=>Z(e,"load",n))}var Pr=1e4;function ue(){let e=Number(globalThis.document?.head?.querySelector?.('meta[name="phlex-reactive-feature-timeout"]')?.content);return Number.isFinite(e)&&e>0?e:Pr}function rn(){return[...w.keys()]}var Xe=Promise.resolve();function Ze(e,t,r){let n=M.waiting.get(e);if(n&&n[t]===r)delete n[t]}var M={enter:ft,exit:ht,count:gt,text:T,served:Ee,waiting:new WeakMap};var C=Symbol.for("phlex-reactive.early"),Mr=1e4,Cr=1500,Le=(e)=>e!=null&&(e===globalThis.window||e.window===e),Dr="dispatch";function K(){return globalThis[C]??={queue:[],connected:new WeakSet},globalThis[C]}function $r(){let e=Number(globalThis.document?.querySelector?.('meta[name="phlex-reactive-early-ttl"]')?.content);return Number.isFinite(e)&&e>0?e:Mr}function qr(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 s;try{s=JSON.parse(n)}catch{s=n}t[i[1].replace(/[-_]([a-z0-9])/g,(a,o)=>o.toUpperCase())]=s}return t}function Wr(e,t,r){return{[C]:!0,type:e.type,detail:e.detail,target:e.target,currentTarget:r?t.ownerDocument.defaultView:t,params:qr(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&&!Fe().has(e),preventDefault(){},stopPropagation(){},stopImmediatePropagation(){}}}var Q=new WeakMap;function Br(e,{token:t,type:r,method:n,filter:i,win:s},a){let o=Q.get(e);if(!o)Q.set(e,o=new Map);let c=s?`${t} ${a}`:t;if(o.has(c))return!1;return o.set(c,{type:r,method:n,filter:i,win:s,params:a,armed:!0}),!0}function Qe(e,t,r,n){if(e?.[C])return!1;let i=Le(e?.currentTarget),s=i?n:e?.currentTarget,a=Ur(e,s,i?`@${t}`:t),o=Q.get(s),c=i&&JSON.stringify(e.params);for(let u of o?.values()??[]){if(!u.armed||u.method!==t||u.type!==e.type||Boolean(u.win)!==i)continue;if(i&&u.params!==c)continue;if(u.filter&&!te(u.filter,e,r))continue;return u.armed=!1,!0}return a}var G=new WeakMap;function jr(e,t,r){let n=G.get(e);if(!n)G.set(e,n=new Map),setTimeout(()=>G.delete(e));let i=n.get(t)??{};n.set(t,i),i[r]=(i[r]??0)+1}function Ur(e,t,r){let n=e&&G.get(e)?.get(t);if(!n?.[r])return!1;return n[r]-=1,!0}class Lt extends Rt{static values={token:String};#A;#l=new Map;#d=new Map;#ie;#L;#B;#x=0;#f=new Map;#R=new WeakMap;#t;featuresReady=Xe;#r=new Map;#N=new Set;#h=!1;#n=null;#m=new Map;#S=new Map;#p=new Map;#g=0;#j;#Be=0;#je=0;connect(){if(yt=!0,K().connected.add(this.element),B.set(this.element,this),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||ke(this.element))this.#t=(e)=>{if(e.type==="focusin"?!e.target.hasAttribute?.("data-reactive-editable"):e.target!==this.element)return;if(e.type===U)this.#H();this.#U(!0)},this.element.addEventListener?.("turbo:morph-element",this.#t),this.element.addEventListener?.("focusin",this.#t),this.element.addEventListener?.(U,this.#t);this.element.querySelectorAll?.("[data-reactive-editable]").forEach(Se),this.#g++,this.featuresReady=Xe,this.#U(),V(this.element),this.#ce()}#Ue(e){}#Je(e,t,r,n){}#He(){}#ze(e,t){}#U(e){{let t=this.#g,r=[];for(let[s,[a]]of w){if(!a||this.#N.has(s))continue;let o=g.get(s);if(o&&!o.connect)continue;try{if(a(this.element))r.push(s)}catch(c){this.#b(s,"detect",c)}}if(r.length===0)return;for(let s of r)this.#N.add(s);if(!this.#h&&r.every((s)=>g.has(s))){for(let s of r)this.#O(t,s,g.get(s),e);return}for(let s of r){let a=this.#oe(t,s),o=[];for(let u of w.keys()){if(u===s)break;if(this.#p.has(u))o.push(this.#p.get(u))}let c=Promise.all(o).then(()=>a).then((u)=>u&&this.#O(t,s,u,e));if(this.#p.set(s,c),w.get(s)[3])this.#n=c}let n=this.#n;n?.then(()=>{if(this.#n===n)this.#n=null}),this.#h=!0;let i=Promise.all(this.#p.values()).then(()=>{if(this.featuresReady===i)this.#h=!1});this.featuresReady=i}}#oe(e,t){{let r=()=>e===this.#g;return this.#se(t),new Promise((n)=>{let i=!1,s=setTimeout(()=>{if(this.#m.delete(s),i=!0,r())this.#b(t,"timeout",Error(`not loaded after ${ue()} ms`));n(null)},ue());this.#m.set(s,n);let a=()=>{clearTimeout(s),this.#m.delete(s)};P(t).then((o)=>{if(a(),i)queueMicrotask(()=>this.#O(e,t,o));else n(o)},(o)=>{if(a(),r())this.#b(t,"load",o);n(null)})})}}#se(e){{let t=w.get(e)[2];if(!t)return;let r={};try{this.#S.set(e,[t(this.element,r),r]),M.waiting.set(this.element,{...M.waiting.get(this.element),[e]:r})}catch(n){this.#b(e,"detect",n)}}}#J(e,t){{let[r,n]=this.#S.get(e)??[];if(this.#S.delete(e),!t)Ze(this.element,e,n);try{r?.()}catch(i){console.error(`[phlex-reactive] the "${e}" feature module failed to stop waiting`,i)}return n}}#O(e,t,r,n){{if(e!==this.#g)return;let i=this.#J(t);try{r.connect?.(this,this.#e(),n,i),this.#r.set(t,r)}catch(s){this.#b(t,"connect",s)}}}#e(){return this.#j??={emit:(e,t,r)=>this.#o(e,t,r),reseed:()=>this.#H(),proceed:(e,t,r,n)=>this.#P(e,t,r,0,0,null,n),forgetToken:()=>{this.#A=void 0},owns:(e)=>this.#_(e),ownership:()=>this.#Z(),bindingOwns:(e)=>this.#Q(e),bindingOwnership:()=>this.#ke(),opTargets:(e)=>this.#W(e),diagnose:(e,t)=>this.#q(e,t),applyOps:(e,t)=>me(e,(r)=>this.#W(t!=null&&r.to==null?{...r,to:t}:r),(r,n)=>this.#q(`client op "${r}"`,n)),listnavOptions:(e)=>this.#v(e),collectFields:()=>this.#ee(),plain:ct,text:T,served:Ee,copyMedia:St,setValue:At,confirm:(e,t)=>Promise.resolve().then(()=>Re(e,t)).catch(()=>!1)},this.#j}#H(){this.#r.get("form")?.reseed(this),this.#r.get("bindings")?.reseed(this),this.#r.get("compute")?.seed(this)}#b(e,t,r){if(Z(e,t,r),this.#i("feature"),t==="load"&&this.element.getAttribute?.("data-reactive-defer-pending"))this.element.removeAttribute("data-reactive-defer-pending"),this.element.removeAttribute("aria-busy");this.#o("reactive:error",{kind:"feature",feature:e,phase:t,error:r})}#ae(){{this.#g++;for(let[t,r]of this.#m)clearTimeout(t),r(null);this.#m.clear();for(let t of[...this.#S.keys()]){let r=this.#J(t,!0),n=this.element;y(t,(i)=>{i.abandon?.(n,r),Ze(n,t,r)})}this.#N.clear(),this.#p.clear(),this.#h=!1,this.#n=null;let e=[...this.#r];this.#r.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)}}}#ce(){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.#ue();for(let[e,t]of j.get(this.element)??[]){if(e.currentTarget!==t)Object.defineProperty(e,"currentTarget",{value:t,configurable:!0});this.dispatch(e)}j.delete(this.element)}#I=new Set;#ue(){let{queue:e}=K();if(e.length===0)return;let t=[];for(let i=e.length-1;i>=0;i--){let{root:s}=e[i];if(s===this.element||!s.isConnected)t.unshift(...e.splice(i,1))}let r=$r(),n=new Map;for(let i of t){let s=n.get(i.event)??[new Set,new Set];n.set(i.event,s);let a=s[+!!i.win];if(a.has(i.el))continue;a.add(i.el);let o=i.win?Math.min(Cr,r):r,c=i.root!==this.element?"its root left the page before a controller connected":performance.now()-i.at>o?`it is older than the ${o} 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.#le(i)}}#le({event:e,el:t,descs:r,win:n}){let i=Wr(e,t,n),s=this.application?.schema?.keyMappings,a=(t.getAttribute("data-action")??"").split(/\s+/),o=n?this.element:t;for(let c of r){if(!a.includes(c.token))continue;if(c.filter&&!te(c.filter,e,s))continue;if(/#\w+.*:once\b/.test(c.token)){if(!Br(o,c,n&&JSON.stringify(i.params)))continue;this.#I.add(o)}if(jr(e,o,n?`@${c.method}`:c.method),c.method==="runOps")this.runOps(i);else this.dispatch(i)}}disconnect(){if(this.#ae(),this.#ye(),this.#_e(),this.#t)this.element.removeEventListener?.("turbo:morph-element",this.#t),this.element.removeEventListener?.("focusin",this.#t),this.element.removeEventListener?.(U,this.#t);if(K().connected.delete(this.element),B.get(this.element)===this)B.delete(this.element);this.element.removeAttribute?.("data-reactive-connected");for(let e of this.#I)Q.delete(e);this.#I.clear()}dispatch(e){if(e.params?.action&&e.params.action!==qe&&this.#de())return this.#fe(e);let t=e.params?.shortcut;if(t!=null&&!W(t,e,this.application?.schema?.keyMappings))return;if(Qe(e,"dispatch",this.application?.schema?.keyMappings,this.element))return;let{action:r,params:n,debounce:i,throttle:s,confirm:a,confirmWhen:o,outside:c,window:u,optimistic:d,prevent:f}=e.params;if(!r)return;let h=e.params.busy??e.params.loading;if(c&&this.element.contains(e.target))return;let p=e.currentTarget??e.target;if((t!=null||!u&&f!==!1)&&!this.#re(d,p))ce(e,t);if(r===qe){let m=()=>{{let S=this.#r.get("defer");if(S)return S.materialize(this)}if(this.tokenValue)return this.#P(p,r,"{}")};return this.#h?this.featuresReady.then(m):m()}let v=this.#z(a,o),E=()=>this.#P(p,r,n,i,s,d,h);if(!v)return E();if(v instanceof Promise)return v.then((m)=>m?this.#E(m,p,E):E());this.#E(v,p,E)}#E(e,t,r){return Promise.resolve().then(()=>Re(e,{el:t})).catch(()=>!1).then((n)=>{if(n)r()})}#z(e,t){if(e)return e;if(!t)return null;{let r=g.get("bindings");if(r)return r.confirmMessage(this,this.#e(),t);return this.#K("bindings").then((n)=>n&&n.confirmMessage(this,this.#e(),t))}}#K(e){{let t;return Promise.race([P(e).catch((r)=>(Z(e,"load",r),null)),new Promise((r)=>t=setTimeout(()=>r(null),ue()))]).finally(()=>clearTimeout(t))}}#de(){return!this.tokenValue&&pe(this.element)}#fe(e){let t=x(this.element.parentElement,Er);if(!t){if(this.element.closest?.('[data-reactive-verbose="true"], [data-reactive-debug="true"]'))console.warn(`[phlex-reactive] "${e.params.action}": no token on this root or above, nothing sent`);return}let r=B.get(t);if(r)return r.dispatch(e);let{shortcut:n,window:i,optimistic:s,prevent:a}=e.params;if(n!=null&&!W(n,e,this.application?.schema?.keyMappings))return;let o=e.currentTarget??e.target;if((n!=null||!i&&a!==!1)&&!this.#re(s,o))ce(e,n);j.set(t,[...j.get(t)??[],[e,o]]);let c=t.dataset;if(c.reactiveDormant)c.controller=`${c.controller??""} ${c.reactiveDormant}`.trim(),delete c.reactiveDormant}runOps(e){let t=e.params?.ops;if(t?.shortcut!=null&&!W(t.shortcut,e,this.application?.schema?.keyMappings))return;if(Qe(e,"runOps",this.application?.schema?.keyMappings,this.element))return;if(wr(e,this))return;let r=e.params??{},n=e.currentTarget??e.target,i=yr(r.ops),s=i.filter((o)=>ze(o,e,null)),a=s.length<=1?s:s.filter((o)=>ze(o,e,this.application?.schema?.keyMappings));if(a.length===0&&i.length>0){if(this.#$())this.#w((o)=>o.noBinding(this,e));return}for(let o of a){if(o.outside&&e[C])continue;if(!vr(o,e))continue;if(o.shortcut!=null&&!W(o.shortcut,e,this.application?.schema?.keyMappings))continue;if(_r(this,e,o))continue;this.#he(o.legacy?{...r,ops:o.ops,debounce:void 0,throttle:void 0,prevent:void 0}:o,e,n,i.indexOf(o))}}#he(e,t,r,n){let{ops:i,confirm:s,confirmWhen:a,outside:o,window:c,shortcut:u,prevent:d}=e;if(o&&this.element.contains(t.target))return;if(u!=null||!c&&d!==!1)ce(t,u);let f=this.#z(s,a),h=this.#me(e,n,r,()=>this.#Ie(this.#Oe(i)));if(!f)return h();if(f instanceof Promise)return f.then((p)=>p?this.#E(p,r,h):h());this.#E(f,r,h)}#me(e,t,r,n){let i=Number(e.debounce)||0,s=Number(e.throttle)||0;if(i<=0&&s<=0)return n;let a=JSON.stringify([t,e]);if(i>0)return()=>this.#G(r,a,i,n);return()=>this.#V(r,a,s,n)}recompute(e){return g.get("compute")?.recompute(this,this.#e(),e)}tagsAdd(e){if(e?.defaultPrevented)return;if(this.#v(e).some((t)=>t.hasAttribute?.("data-reactive-highlighted")))return;return this.#y("tagsAdd",e)}tagsPick(e){return this.#y("tagsPick",e)}tagsRemove(e){return this.#y("tagsRemove",e)}nestedAdd(e){return this.#y("nestedAdd",e)}nestedRemove(e){return this.#y("nestedRemove",e)}syncNestedJson(e){return g.get("bindings")?.syncNestedJson(this,this.#e(),e)}#y(e,t){{let r=g.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 y("bindings",(i)=>i[e](this,this.#e(),n))}}trackDirty(){(this.#r.get("form")??g.get("form"))?.scan(this,this.#e())}listnavNext(e){this.#T(e,(t,r)=>t<0?0:(t+1)%r)}listnavPrev(e){this.#T(e,(t,r)=>t<0?r-1:(t-1+r)%r)}listnavFirst(e){this.#T(e,()=>0)}listnavLast(e){this.#T(e,(t,r)=>r-1)}listnavPick(e){let t=this.#v(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.#v(e))t.removeAttribute("data-reactive-highlighted")}#T(e,t){let r=this.#v(e);if(!r.length)return;e.preventDefault();let n=this.#pe(e),i=globalThis.document?.activeElement,s=n?r.findIndex((o)=>o===i||i!=null&&o.contains?.(i)):r.findIndex((o)=>o.hasAttribute("data-reactive-highlighted")),a=r[t(s,r.length)];if(n)a.focus?.();else{for(let o of r)o.removeAttribute("data-reactive-highlighted");a.setAttribute("data-reactive-highlighted","true")}a.scrollIntoView?.({block:"nearest"})}#pe(e){return(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-focus-param")==="true"}#v(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.#Z();return Array.from(this.element.querySelectorAll(r)).filter((i)=>!i.hidden&&n(i))}#P(e,t,r,n,i,s,a){if(this.#o("reactive:before-dispatch",{action:t,params:this.#te(r),element:this.element},{cancelable:!0}).defaultPrevented)return;let c=Number(n)||0;if(c>0)return this.#be(e,c,t,r,s,a);let u=Number(i)||0;if(u>0)return this.#ve(e,u,t,r,s,a);return this.#F(t,r,s,e,a)}#F(e,t,r,n,i){let s={inverse:null,undo:[],resurrect:null},a=this.#Pe(e,n,s),o=Boolean(r||i),c=(h)=>{if(!o||!h)return;let p=this.#e();if(s.inverse=h.optimistic(this,p,r,n),s.undo.push(...h.busy(this,p,i,n)),this.#C())s.resurrect=h.resurrection(this,p,r,n)},u=g.get("hints");if(!o||u)c(u);let d=()=>this.#Ee(e,t,s,a),f=()=>this.#n?this.#n.then(d):d();return this.queue=(this.queue??Promise.resolve()).then(()=>o&&!u?this.#ge().then(c).then(f):f()),this.queue}#ge(){return this.#K("hints")}#be(e,t,r,n,i,s){this.#G(e,Dr,t,()=>this.#F(r,n,i,e,s))}#G(e,t,r,n){this.#M(e,t);let i=()=>{this.#M(e,t),n()},s=setTimeout(i,r);if(!Le(e))e?.addEventListener?.("blur",i,{once:!0});let a=this.#l.get(e);if(!a)this.#l.set(e,a=new Map);a.set(t,{timer:s,flush:i})}#M(e,t){let r=this.#l.get(e),n=r?.get(t);if(!n)return;if(clearTimeout(n.timer),e?.removeEventListener?.("blur",n.flush),r.delete(t),r.size===0)this.#l.delete(e)}#ye(){for(let[e,t]of[...this.#l])for(let r of[...t.keys()])this.#M(e,r)}#ve(e,t,r,n,i,s){return this.#V(e,r,t,()=>this.#F(r,n,i,e,s))}#V(e,t,r,n){let i=this.#d.get(e)??new Map;if(i.has(t))return;let s=setTimeout(()=>{if(i.delete(t),i.size===0)this.#d.delete(e)},r);return i.set(t,s),this.#d.set(e,i),n()}#_e(){for(let e of this.#d.values())for(let t of e.values())clearTimeout(t);this.#d.clear()}#o(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.#F(e,t)};this.#o("reactive:error",{action:e,params:r,...n,retry:i})}#i(e){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",e)}#we(){this.element?.removeAttribute?.("data-reactive-error")}#Ae(){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))}#Se(){{let e=g.get("devtools");if(e)return e.delay();if(lt())return P("devtools").then((t)=>t.delay(),()=>{})}}#C(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#Y(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}async#Ee(e,t,r,n){let{fields:i,files:s}=this.#ee(),a=this.#te(t),o={...i,...a},c=this.#a,u=s.length>0,d=u?this.#Re(c,e,o,s):JSON.stringify({token:c,act:e,params:o}),f=this.#C()?{action:e,paramNames:Object.keys(a),fieldNames:Object.keys(i),encoding:u?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#Y()}:null;await this.#Se();try{if(navigator.onLine===!1){this.#c(r.inverse),this.#i("offline"),this.#s(e,t,o,{kind:"offline"});return}let h;try{let m={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#qe()};if(!u)m["Content-Type"]="application/json";let S=this.#We();if(S)m["X-Pgbus-Connection"]=S;let D=Et(this.element)&&document.getElementById(`reactive-presence-src-${this.element.id}`)?.getAttribute("connection-id");if(D)m["X-Reactive-Presence"]=D;let xe=Kt(this.element);if(xe)m["X-Reactive-Held"]=xe;gt("action"),h=await fetch(this.#De(),{method:"POST",headers:m,body:d,credentials:"same-origin",signal:AbortSignal.timeout(this.#$e())})}catch(m){if(console.error("[phlex-reactive] action error",m),this.#c(r.inverse),m?.name==="TimeoutError"||m?.name==="AbortError"){this.#i("timeout"),this.#s(e,t,o,{kind:"timeout"});return}this.#Ae(),this.#i("network"),this.#s(e,t,o,{kind:"network"});return}if(f)f.status=h.status;if(h.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#c(r.inverse),this.#i("redirected"),this.#s(e,t,o,{kind:"redirected",status:h.status});return}if(!h.ok){let m=await h.text();if(console.error(`[phlex-reactive] action failed: HTTP ${h.status}`,m),this.#c(r.inverse),(h.headers.get("Content-Type")||"").includes("turbo-stream")){let S=this.#X(m);if(this.#a=S??this.#a,f)this.#w((D)=>D.recordBody(f,m,S));$e(this.element,m,!0)}this.#i("http"),this.#s(e,t,o,{kind:"http",status:h.status,body:m});return}let p=h.headers.get("Content-Type")||"";if(!p.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${p}" — no update applied`),this.#c(r.inverse),this.#i("content-type"),this.#s(e,t,o,{kind:"content-type",status:h.status});return}let v=await h.text(),E=this.#X(v);if(this.#a=E??this.#a,f)this.#w((m)=>m.recordBody(f,v,E));if($e(this.element,v,Gt(h)),r.resurrect)queueMicrotask(r.resurrect);return this.#we(),this.#o("reactive:applied",{action:e,params:o,html:v}),v}catch(h){console.error("[phlex-reactive] action error",h),this.#c(r.inverse),this.#o("reactive:error",{action:e,params:o,kind:"apply"})}finally{if(n?.(),f)this.#w((h)=>h.trace(this,{...f,ms:this.#Y()-f.started}))}}get#a(){return this.#A??this.tokenValue}set#a(e){this.#A=e}tokenValueChanged(){this.#A=void 0}#X(e){let t=this.element.id;if(!t)return e.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:r,self:n}=this.#Te(t),i=e.match(r);if(i)return i[1];let s=e.match(n);if(s)return s[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#Te(e){let t=this.#B;if(t&&t.id===e)return t;let r=er(e);return this.#B={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>`)}}#_(e){return e.closest('[data-controller~="reactive"]')===this.element}#Z(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(t)=>this.#_(t)}#Fe(){let e=this.element.querySelectorAll(F);if(e.length===0||[...e].every(pe))return()=>!0;return(t)=>{let r=x(t,F,this.element);if(r===this.element)return!0;return t.getAttribute("data-reactive-shared-field")!=null&&x(r.parentElement,F,this.element)===this.element}}#Q(e){if(this.#_(e))return!0;if(e.getAttribute?.("data-reactive-shared-field")==null)return!1;let t=x(e,F,this.element);return t===this.element||x(t?.parentElement,F,this.element)===this.element}#ke(){if(this.element.querySelectorAll(F).length===0)return()=>!0;return(e)=>this.#Q(e)}#ee(){let e={},t=[],r=this.#Fe(),n=[];this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((o)=>{if(!r(o))return;if(o.type==="file")for(let c of o.files??[])t.push({name:o.name,file:c,multiple:o.multiple});else n.push(o)});let i=[];this.element.querySelectorAll(`[name]${or}`).forEach((o)=>{if(r(o))i.push(o)});let s=this.#Le(n),a=this.#xe(n);for(let o of n)if(s.has(o.name)){let c=e[o.name]??(e[o.name]=[]);if(o.type==="checkbox"||o.type==="radio"){if(o.checked)c.push(o.value)}else if(o.type==="hidden"){if(!a.has(o.name))c.push(o.value)}else if(o.multiple&&o.options){for(let u of o.options)if(u.selected)c.push(u.value)}else c.push(o.value)}else if(o.type==="checkbox")e[o.name]=o.checked;else if(o.type==="radio"){if(o.checked)e[o.name]=o.value}else e[o.name]=o.value;return i.forEach((o)=>{let c=o.getAttribute("name");if(!c)return;let u=o.getAttribute("data-reactive-editable")!=null?T(o):o.value??o.textContent??o.innerHTML??"",d=e[c];if(String(c).endsWith("[]")&&!ar(o))return;if(String(c).endsWith("[]")&&(d===void 0||Array.isArray(d))){(Array.isArray(d)?d:e[c]=[]).push(u);return}if(d==null||d==="")e[c]=u}),{fields:e,files:t}}#Le(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}#xe(e){let t=new Set;for(let r of e)if(r.type==="checkbox")t.add(r.name);return t}#Re(e,t,r,n){let i=new FormData;i.append("token",e),i.append("act",t);let s=[];for(let[o,c]of Object.entries(r))if(Array.isArray(c)&&String(o).endsWith("[]"))if(c.length===0)s.push(String(o).slice(0,-2));else{let u=`${this.#k(o)}[]`;for(let d of c)i.append(u,String(d))}else this.#D(i,this.#k(o),c);for(let o of s)i.append("empty_groups[]",o);let a=this.#Ne(n);for(let{name:o,file:c,multiple:u}of n){let f=u||a.has(o)?`${this.#k(o)}[]`:this.#k(o);i.append(f,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("")}`}#D(e,t,r){if(r==null)e.append(t,"");else if(Array.isArray(r))r.forEach((n,i)=>this.#D(e,`${t}[${i}]`,n));else if(typeof r==="object")for(let[n,i]of Object.entries(r))this.#D(e,`${t}[${n}]`,i);else e.append(t,String(r))}#Ne(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))}#te(e){if(!e)return{};try{return typeof e==="string"?JSON.parse(e):e}catch{return{}}}#Oe(e){return Te(e)}#Ie(e){me(e,(t)=>this.#W(t),(t,r)=>this.#q(`client op "${t}"`,r))}#$(){return this.element?.getAttribute?.("data-reactive-verbose")==="true"||this.#C()}#q(e,t){if(!this.#$())return;this.#w((r)=>r.diagnose(this,e,t))}#w(e){y("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.#_(r))}#re(e,t){if(e?.checked!=="keep")return!1;let r=t?.type;return r==="checkbox"||r==="radio"}#c(e){if(!e)return;if(!this.element.isConnected)return;for(let t of e)t()}#Pe(e,t,r){this.#Me(e,t),ft();let n=!1;return()=>{if(n)return;n=!0,this.#Ce(e,t),ht();for(let i of r.undo)i()}}#Me(e,t){if(this.#u(t,e,1),this.#u(this.element,e,1),this.#f.set(e,(this.#f.get(e)??0)+1),this.#x++===0)this.element.setAttribute("aria-busy","true");for(let r of this.#ne(e))this.#u(r,e,1)}#Ce(e,t){this.#u(t,e,-1),this.#u(this.element,e,-1);let r=(this.#f.get(e)??1)-1;if(r<=0)this.#f.delete(e);else this.#f.set(e,r);if(--this.#x<=0)this.#x=0,this.element.removeAttribute("aria-busy");for(let n of this.#ne(e))this.#u(n,e,-1)}#u(e,t,r){if(!e||typeof e.getAttribute!=="function")return;let n=this.#R.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.#R.delete(e),e.removeAttribute("data-reactive-busy");return}this.#R.set(e,n),e.setAttribute("data-reactive-busy",[...n.keys()].join(" "))}#ne(e){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((r)=>r.getAttribute("data-reactive-busy-on")===e&&this.#_(r))}#De(){return this.#ie??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#$e(){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}#qe(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#We(){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)Be();else document.addEventListener("turbo:load",Be,{once:!0});b("persist",()=>import("phlex/reactive/features/persist"),Jr);b("defer",()=>import("phlex/reactive/features/defer"));b("form",()=>import("phlex/reactive/features/form"));b("bindings",()=>import("phlex/reactive/features/bindings"));b("compute",()=>import("phlex/reactive/features/compute"),Hr);b("sortable",()=>import("phlex/reactive/features/sortable"));b("drag",()=>import("phlex/reactive/features/drag"));b("presence",()=>import("phlex/reactive/features/presence"));b("countdown",()=>import("phlex/reactive/features/countdown"));b("effects",()=>import("phlex/reactive/features/effects"));b("hints",()=>import("phlex/reactive/features/hints"));b("devtools",()=>import("phlex/reactive/features/devtools"));Ae();function Jr(e,t){let r=()=>{t.edited=!0},n=(s)=>{let a=s.target;if(s.detail?.success&&a?.tagName==="FORM"&&a.contains?.(e))t.submitted=!0},i=["input","change","lexxy:change","trix-change"];for(let s of i)e.addEventListener?.(s,r);return document.addEventListener("turbo:submit-end",n),()=>{for(let s of i)e.removeEventListener?.(s,r);document.removeEventListener("turbo:submit-end",n)}}function Hr(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 zr=1000,L=null,xt,re=new Set;function Kr(e){return kt(e).then((t)=>{if(e!=="effects")return;xt=t,t?.sweep()})}at((e,t)=>{let r=e.detail,n=r?.render;if(typeof n!=="function")return;let i=r.newStream??e.target,s=Ft(Gr(i)).filter((o)=>!re.has(o));if(!t&&!re.has("effects")&&Vr(i))s.push("effects");if(s.length===0&&!L)return t?.wrap(e);if(s.length>0){for(let c of s)re.add(c);let o=L=Promise.race([Promise.all([L,...s.map(Kr)]),new Promise((c)=>setTimeout(c,zr))]).then(()=>{if(L!==o)return;L=null,re.clear()})}let a=L;r.render=async(o)=>{await a;let c={target:e.target,detail:{newStream:r.newStream,render:n}};(t??xt)?.wrap(c),await c.detail.render(o)}});function Gr(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.push(t),r}function Vr(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 un=Lt;export{dt as ACTIVE_ATTR,or as EDITOR_SELECTOR,sr as EDITOR_TAGS,pt as REQUESTS_ATTR,tr as checkReactiveRegistration,gt as countReactiveRequest,un as default,T as editableValue,ft as enterReactiveActivity,er as escapeRegExp,ht as exitReactiveActivity,kt as loadReactiveFeature,at as onReactiveStreamWithoutEffects,Qr as reactiveActivityCount,rn as reactiveFeatureNames,Be as registerReactiveActions,Mt as registerReactiveDefer,Ae as registerReactiveDev,Ct as registerReactiveDismiss,Ct as registerReactiveEffects,tn as registerReactiveFeature,b as registerReactiveFeatureLoader,jt as registerReactiveImageFallback,Pt as registerReactiveJs,Bt as registerReactiveKeep,Wt as registerReactiveModals,Jt as registerReactiveMorphFocus,Yt as registerReactiveOffline,Ut as registerReactivePlaintext,Ct as registerReactiveStreamRender,Ot as registerReactiveToken,Nt as registerReactiveVisit,en as resetReactiveActivity,Ee as serverText,Ft as unloadedFeaturesFor};
|
|
5
|
+
`).replace(/\n$/,""),e.getAttribute("data-reactive-editable")==="multi"?t:t.replace(/\n/g," ")}var Q=new WeakMap;function Te(e){if(e?.hasAttribute?.("data-reactive-editable")&&!Q.has(e))Q.set(e,T(e))}function Fe(e){return Te(e),Q.get(e)}function cr(e){return ar.has(e.localName)?typeof e.value==="string":!0}var Je=Object.freeze({show:(e,t,r)=>ae(e,!1,t,r),hide:(e,t,r)=>ae(e,!0,t,r),toggle:(e,t,r)=>ae(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(ce(t.name))e.setAttribute(t.name,t.value??"")},remove_attr:(e,t)=>{if(ce(t.name))e.removeAttribute(t.name)},toggle_attr:(e,t)=>{if(!ce(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)=>br(e)?.focus?.(),blur:(e)=>{let t=e.ownerDocument?.activeElement??globalThis.document?.activeElement;if(t&&(t===e||e.contains?.(t)))t.blur?.()},show_modal:(e)=>rt(e),close_dialog:(e)=>qt(e),text:(e,t)=>{let r=String(t.value??"");if(e.textContent!==r)e.textContent=r},copy_media:(e,t,r)=>{let n=null;try{n=r({...t,to:t.from})[0]??null}catch{}Et(e,n)},check_group:(e,t)=>{let r=t.global?document.querySelectorAll('[data-controller~="reactive"]'):[e];for(let n of r)v("bindings",(i)=>i.checkGroup(n,t.group,t.checked))},presence:(e,t)=>v("presence",(r)=>r.set(e,t.state)),dispatch:(e,t)=>{e.dispatchEvent(new CustomEvent(t.name,{bubbles:!0,composed:!0,detail:t.detail??{}}))},submit:(e,t,r)=>{let n=ur(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)=>lr(e),preview_file:(e,t,r)=>dr(e,t,r),set_value:(e,t)=>St(e,String(t.value??"")),persist_state:(e,t)=>v("persist",(r)=>r.writeState(e,t.state)),persist_clear:(e)=>v("persist",(t)=>t.clearRoot(e))});function ur(e){if(e?.tagName==="FORM")return e;return e?.form??e?.closest?.("form")??null}function lr(e){let t=globalThis.navigator?.clipboard;if(typeof t?.readText!=="function")return;t.readText().then((r)=>{if(!r)return;e.value=r,At(e),e.focus?.()}).catch(()=>{})}var N=new Map,O=null;function dr(e,t,r){if(e?.tagName!=="INPUT"||e.type!=="file")return K(`reads an input[type=file], not <${e?.localName}>`);let n=typeof r==="function"?r({...t,to:t.into})[0]:null;if(n?.tagName!=="IMG")return K(`paints an <img>, and ${JSON.stringify(t.into)} is ${n?`a <${n.localName}>`:"not on the page"}`);let i=[...t.valid===!0&&e.validity?.valid===!1?[]:e.files??[]],s=hr(e,t.accept),a=(u)=>Number.isInteger(t.max_bytes)&&u.size>t.max_bytes,o=[],c;if(t.per_file===!0&&e.multiple){let u=i.filter((f,h)=>{let p=typeof f?.type==="string"&&s(f)?a(f)&&"size":"type";if(p)o.push({reason:p,file:f,index:h});return!p}),d=o.length>0&&!fr(e,u)?i.length:u.length;for(let f of o)f.remaining=d;c=u.find((f)=>f.type.startsWith("image/"))}else{let u=i.filter((f)=>typeof f?.type==="string"&&s(f));c=u.find((f)=>f.type.startsWith("image/"));let d=i.length>0&&u.length===0?"type":null;if(c&&a(c))d="size";if(d)o.push({reason:d,file:d==="size"?c:i[0]}),c=null}if(wt(n),c){let u=URL.createObjectURL(c);N.set(n,u),n.setAttribute("src",u),mr()}else n.removeAttribute("src");if(te(n),t.wrap!=null){let u=r({...t,to:t.wrap});if(u.length===0)K(`wrap: ${JSON.stringify(t.wrap)} is not on the page`);for(let d of u)c?ot(d):it(d)}if(t.name!=null)for(let u of r({...t,to:t.name}))u.textContent=c?c.name:"";for(let u of o)e.dispatchEvent(new CustomEvent("reactive:file-rejected",{bubbles:!0,detail:u}))}function fr(e,t){if(typeof DataTransfer!=="function"){if(e.closest?.('[data-reactive-verbose="true"], [data-reactive-debug="true"]'))K("per_file: has no DataTransfer to drop the refused files from the input");return!1}let r=new DataTransfer;for(let n of t)r.items.add(n);return e.files=r.files,!0}function hr(e,t){let r=String((t===!0?e.getAttribute("accept"):typeof t==="string"&&t)||"").toLowerCase().split(",").map((n)=>n.trim()).filter(Boolean);if(r.length===0)return(n)=>n.type.startsWith("image/");return(n)=>{let i=n.type.toLowerCase();return r.some((s)=>s[0]==="."?String(n.name).toLowerCase().endsWith(s):s.endsWith("/*")?i.startsWith(s.slice(0,-1)):i===s)}}function K(e){console.warn(`[phlex-reactive] preview_file ${e} — skipped`)}function wt(e){let t=N.get(e);if(t===void 0)return;if(N.delete(e),URL.revokeObjectURL(t),N.size===0)O?.disconnect(),O=null}function mr(){if(O||typeof MutationObserver!=="function"||!document?.documentElement)return;O=new MutationObserver(()=>{for(let[e,t]of N)if(!e.isConnected||e.getAttribute("src")!==t)wt(e)}),O.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["src"]})}function At(e){if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}function St(e,t){if(!/^(input|textarea|select)$/.test(e.localName)||e.type==="file"&&t!==""){console.warn("[phlex-reactive] set_value skipped: not a field it can write",e);return}let r=ze(e);if(e.value=t,ze(e)!==r)At(e)}function ze(e){return e.type==="select-multiple"?[...e.selectedOptions].map((t)=>t.value).join(`
|
|
6
|
+
`):e.value}function pr(e,t,r){if(r?.transition)ir(e,r.transition,()=>e.hidden=t);else e.hidden=t}function ae(e,t,r,n){if(pr(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 ce(e){if(!_t(e))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(e)} — skipped`),!1}function Et(e,t){if(e?.localName!=="img")return console.warn(`[phlex-reactive] copy_media targets an <img>, not <${e?.localName}> — skipped`),null;let r=t?.localName==="img"?t:null,n=r?.getAttribute("src"),i=!1;for(let a of["srcset","src"]){let o=n?r.getAttribute(a):null;if(o==null){if(e.hasAttribute(a))i=e.removeAttribute(a)??!0}else if(e.getAttribute(a)!==o)i=e.setAttribute(a,o)??!0}if(i)te(e);let s=r?.getAttribute("alt")??"";if(e.getAttribute("alt")!==s)e.setAttribute("alt",s);return r?s:!1}var gr='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function br(e){return e.querySelectorAll?.(gr)?.[0]??null}function ke(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 He=Object.freeze({backspace:"Backspace",delete:"Delete",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"}),Ke=Object.freeze(["meta","ctrl","alt","shift"]);function re(e,t,r){let n=e.split("+");for(let a of Ke)if(n.includes(a)!==Boolean(t[`${a}Key`]))return!1;let i=n.find((a)=>!Ke.includes(a));if(i===void 0||typeof t.key!=="string")return!0;let s=r&&Object.hasOwn(r,i)?r[i]:Object.hasOwn(He,i)?He[i]:/^[a-z0-9]$/.test(i)?i:null;return typeof s==="string"&&s.toLowerCase()===t.key.toLowerCase()}var yr=(e)=>e&&typeof e==="object"?e.keys:String(e),Le=()=>V().prevented??=new WeakSet;function ue(e,t){if(t!=null&&!e.defaultPrevented)Le().add(e);e.preventDefault()}function B(e,t,r){if(t.defaultPrevented&&e?.handled!==!0&&!Le().has(t))return!1;let n=t.target;if(e?.inEditable!==!0&&(n?.isContentEditable||/^(input|textarea|select)$/.test(n?.localName)))return!1;let i=/[Mm]ac|iP/.test(navigator.userAgentData?.platform??navigator.platform)?"meta":"ctrl";return re(yr(e).replace(/^mod\+/,`${i}+`),t,r)}function vr(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:ke(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 Ve(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)!==Re(t.currentTarget))return!1;return i<0||r===null||re(n.slice(i+1),t,r)}function _r(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 Ge=new WeakMap;function wr(e,t,r){if(!r.once)return!1;let n=t.currentTarget??e.element,i=Ge.get(e);if(!i)i=new WeakMap,Ge.set(e,i);let s=i.get(n);if(!s)s=new Set,i.set(n,s);let a=t.params?.ops,c=(n===globalThis.window?`${typeof a==="string"?a:JSON.stringify(a??null)}|`:"")+JSON.stringify(r);if(s.has(c))return!0;return s.add(c),!1}var Ye=new WeakMap;function Ar(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=Ye.get(e);if(!i)i=new WeakMap,Ye.set(e,i);let s=i.get(t);if(!s)s=new Map,i.set(t,s);let a=s.get(e.currentTarget);if(!a)a=new Set,s.set(e.currentTarget,a);if(a.has(n))return!0;return a.add(n),!1}function pe(e,t,r){for(let n of e){if(!Array.isArray(n))continue;let[i,s={}]=n;if(!Object.hasOwn(Je,i)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(i)} — skipped`);continue}let a=t(s);if(a.length===0&&r)r(i,s);if(a.length>0)s=Er(i,s,t,r);if(!s)continue;for(let o of a)if(Je[i](o,s,t),s?.keep===!0)nt(o,i,s,t)}}var Sr=new Set(["set_value","text","set_attr"]);function Er(e,t,r,n){let i=e==="dispatch",s=i?t.detail_from:Sr.has(e)&&t.from!=null&&{value:t.attr};if(!s)return t;let a=i?"@trigger":t.from,o;try{o=r({...t,to:a})[0]}catch{}if(!o)return n?.(e,{...t,to:a}),null;let c=i?{...t.detail}:{};for(let[u,d]of Object.entries(s)){let f=Tr(o,d);if(f==null)return null;c[u]=f}return i?{...t,detail:c}:{...t,...c}}function Tr(e,t){if(t==="@text")return e.textContent??"";if(typeof t==="string"&&/^data-[a-z][a-z0-9-]*$/i.test(t))return e.getAttribute(t)??"";return console.warn(`[phlex-reactive] refused client read of ${JSON.stringify(t)} — skipped`),null}function Fr(e,t){let r=e.to;if(r==="@trigger")return[];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 kr(e){let t=e.getAttribute?.("data-reactive-persist");return Boolean(t)&&t!=="off"}function xe(e){return["defer-token","defer-src","lazy-on","lazy-visible"].some((t)=>e.getAttribute?.(`data-reactive-${t}`)!=null)}var F='[data-controller~="reactive"]',Lr='[data-controller~="reactive"],[data-reactive-dormant~="reactive"]',ge=(e)=>e.getAttribute?.("data-reactive-token-value")==null&&!xe(e);function R(e,t,r){let n=e?.closest?.(t);while(n&&n!==r&&ge(n))n=n.parentElement?.closest?.(t);return n??null}var j=new WeakMap,U=new WeakMap;function xr(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 Rr(e){return["show-targets","group-targets","on-complete","filter-input","tags-field","css-vars"].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], [data-reactive-editable], [data-reactive-media], [data-reactive-css-vars]")!=null}function Nr(e){return e.getAttribute?.("data-reactive-compute-inputs-param")!=null}function Or(e){return Boolean(e.matches?.("[data-reactive-sortable],[data-reactive-sortable-source]")||e.querySelector?.("[data-reactive-sortable],[data-reactive-sortable-source]"))}function Ir(e){return Boolean(e.matches?.("[data-reactive-frame],[data-reactive-box],[data-reactive-point]")||e.querySelector?.("[data-reactive-frame],[data-reactive-box],[data-reactive-point]"))}function Tt(e){return e.getAttribute?.("data-reactive-presence")!=null}function Pr(e){return Boolean(e.matches?.("[data-reactive-countdown]")||e.querySelector?.("[data-reactive-countdown]"))}var Mr=[["persist",[kr,null,null,!0]],["defer",[xe,null]],["form",[xr,null]],["bindings",[Rr,null,null,!0]],["compute",[Nr,null,null,!0]],["sortable",[Or,null]],["drag",[Ir,null]],["presence",[Tt,null]],["countdown",[Pr,null]],["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]]],w=new Map(Mr),Xe=new Map,g=new Map,Cr=new Map;function y(e,t,r){Ft.set(e,[t,r]),Dr(e)}var Ft=new Map;function Dr(e){let t=w.get(e),[r,n]=Ft.get(e);t[1]=r,t[2]=n}function sn(e,t){t.install?.(M),g.set(e,t),Cr.set(e,t)}function kt(e){let t=[];for(let[r,[n]]of w){if(!n||g.has(r))continue;try{if(e.some((i)=>n(i)))t.push(r)}catch{}}return t}function Lt(e){return I(e).catch((t)=>Z(e,"load",t))}function I(e){let t=Xe.get(e);if(!t)t=(w.get(e)[1]??(()=>Promise.reject(Error("this entry has no way to import it"))))().then((n)=>(n.install?.(M),g.set(e,n),n)),Xe.set(e,t);return t}var Qe=new Set;function Z(e,t,r){let n=e+t;if(Qe.has(n))return;Qe.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 v(e,t){let r=g.get(e);if(r)return t(r);I(e).then(t,(n)=>Z(e,"load",n))}var $r=1e4;function le(){let e=Number(globalThis.document?.head?.querySelector?.('meta[name="phlex-reactive-feature-timeout"]')?.content);return Number.isFinite(e)&&e>0?e:$r}function an(){return[...w.keys()]}var Ze=Promise.resolve();function et(e,t,r){let n=M.waiting.get(e);if(n&&n[t]===r)delete n[t]}var M={enter:ht,exit:mt,count:bt,text:T,served:Fe,waiting:new WeakMap};var C=Symbol.for("phlex-reactive.early"),qr=1e4,Wr=1500,Re=(e)=>e!=null&&(e===globalThis.window||e.window===e),Br="dispatch";function V(){return globalThis[C]??={queue:[],connected:new WeakSet},globalThis[C]}function jr(){let e=Number(globalThis.document?.querySelector?.('meta[name="phlex-reactive-early-ttl"]')?.content);return Number.isFinite(e)&&e>0?e:qr}function Ur(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 s;try{s=JSON.parse(n)}catch{s=n}t[i[1].replace(/[-_]([a-z0-9])/g,(a,o)=>o.toUpperCase())]=s}return t}function Jr(e,t,r){return{[C]:!0,type:e.type,detail:e.detail,target:e.target,currentTarget:r?t.ownerDocument.defaultView:t,params:Ur(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&&!Le().has(e),preventDefault(){},stopPropagation(){},stopImmediatePropagation(){}}}var ee=new WeakMap;function zr(e,{token:t,type:r,method:n,filter:i,win:s},a){let o=ee.get(e);if(!o)ee.set(e,o=new Map);let c=s?`${t} ${a}`:t;if(o.has(c))return!1;return o.set(c,{type:r,method:n,filter:i,win:s,params:a,armed:!0}),!0}function tt(e,t,r,n){if(e?.[C])return!1;let i=Re(e?.currentTarget),s=i?n:e?.currentTarget,a=Kr(e,s,i?`@${t}`:t),o=ee.get(s),c=i&&JSON.stringify(e.params);for(let u of o?.values()??[]){if(!u.armed||u.method!==t||u.type!==e.type||Boolean(u.win)!==i)continue;if(i&&u.params!==c)continue;if(u.filter&&!re(u.filter,e,r))continue;return u.armed=!1,!0}return a}var G=new WeakMap;function Hr(e,t,r){let n=G.get(e);if(!n)G.set(e,n=new Map),setTimeout(()=>G.delete(e));let i=n.get(t)??{};n.set(t,i),i[r]=(i[r]??0)+1}function Kr(e,t,r){let n=e&&G.get(e)?.get(t);if(!n?.[r])return!1;return n[r]-=1,!0}class xt extends Nt{static values={token:String};#A;#d=new Map;#f=new Map;#ie;#x;#B;#R=0;#h=new Map;#N=new WeakMap;#t;featuresReady=Ze;#r=new Map;#O=new Set;#m=!1;#n=null;#p=new Map;#S=new Map;#g=new Map;#b=0;#j;#je=0;#Ue=0;connect(){if(vt=!0,V().connected.add(this.element),j.set(this.element,this),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||xe(this.element))this.#t=(e)=>{if(e.type==="focusin"?!e.target.hasAttribute?.("data-reactive-editable"):e.target!==this.element)return;if(e.type===J)this.#z();this.#U(!0)},this.element.addEventListener?.("turbo:morph-element",this.#t),this.element.addEventListener?.("focusin",this.#t),this.element.addEventListener?.(J,this.#t);this.element.querySelectorAll?.("[data-reactive-editable]").forEach(Te),this.#b++,this.featuresReady=Ze,this.#U(),Y(this.element),this.#ce()}#Je(e){}#ze(e,t,r,n){}#He(){}#Ke(e,t){}#U(e){{let t=this.#b,r=[];for(let[s,[a]]of w){if(!a||this.#O.has(s))continue;let o=g.get(s);if(o&&!o.connect)continue;try{if(a(this.element))r.push(s)}catch(c){this.#y(s,"detect",c)}}if(r.length===0)return;for(let s of r)this.#O.add(s);if(!this.#m&&r.every((s)=>g.has(s))){for(let s of r)this.#I(t,s,g.get(s),e);return}for(let s of r){let a=this.#oe(t,s),o=[];for(let u of w.keys()){if(u===s)break;if(this.#g.has(u))o.push(this.#g.get(u))}let c=Promise.all(o).then(()=>a).then((u)=>u&&this.#I(t,s,u,e));if(this.#g.set(s,c),w.get(s)[3])this.#n=c}let n=this.#n;n?.then(()=>{if(this.#n===n)this.#n=null}),this.#m=!0;let i=Promise.all(this.#g.values()).then(()=>{if(this.featuresReady===i)this.#m=!1});this.featuresReady=i}}#oe(e,t){{let r=()=>e===this.#b;return this.#se(t),new Promise((n)=>{let i=!1,s=setTimeout(()=>{if(this.#p.delete(s),i=!0,r())this.#y(t,"timeout",Error(`not loaded after ${le()} ms`));n(null)},le());this.#p.set(s,n);let a=()=>{clearTimeout(s),this.#p.delete(s)};I(t).then((o)=>{if(a(),i)queueMicrotask(()=>this.#I(e,t,o));else n(o)},(o)=>{if(a(),r())this.#y(t,"load",o);n(null)})})}}#se(e){{let t=w.get(e)[2];if(!t)return;let r={};try{this.#S.set(e,[t(this.element,r),r]),M.waiting.set(this.element,{...M.waiting.get(this.element),[e]:r})}catch(n){this.#y(e,"detect",n)}}}#J(e,t){{let[r,n]=this.#S.get(e)??[];if(this.#S.delete(e),!t)et(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.#b)return;let i=this.#J(t);try{r.connect?.(this,this.#e(),n,i),this.#r.set(t,r)}catch(s){this.#y(t,"connect",s)}}}#e(){return this.#j??={emit:(e,t,r)=>this.#o(e,t,r),reseed:()=>this.#z(),proceed:(e,t,r,n)=>this.#M(e,t,r,0,0,null,n),forgetToken:()=>{this.#A=void 0},owns:(e)=>this.#c(e),ownership:()=>this.#Q(),bindingOwns:(e)=>this.#Z(e),bindingOwnership:()=>this.#Le(),opTargets:(e)=>this.#W(e),diagnose:(e,t)=>this.#q(e,t),applyOps:(e,t)=>pe(e,(r)=>this.#W(t!=null&&r.to==null?{...r,to:t}:r),(r,n)=>this.#q(`client op "${r}"`,n)),listnavOptions:(e)=>this.#_(e),collectFields:()=>this.#ee(),plain:ut,text:T,served:Fe,copyMedia:Et,setValue:St,confirm:(e,t)=>Promise.resolve().then(()=>Oe(e,t)).catch(()=>!1)},this.#j}#z(){this.#r.get("form")?.reseed(this),this.#r.get("bindings")?.reseed(this),this.#r.get("compute")?.seed(this)}#y(e,t,r){if(Z(e,t,r),this.#i("feature"),t==="load"&&this.element.getAttribute?.("data-reactive-defer-pending"))this.element.removeAttribute("data-reactive-defer-pending"),this.element.removeAttribute("aria-busy");this.#o("reactive:error",{kind:"feature",feature:e,phase:t,error:r})}#ae(){{this.#b++;for(let[t,r]of this.#p)clearTimeout(t),r(null);this.#p.clear();for(let t of[...this.#S.keys()]){let r=this.#J(t,!0),n=this.element;v(t,(i)=>{i.abandon?.(n,r),et(n,t,r)})}this.#O.clear(),this.#g.clear(),this.#m=!1,this.#n=null;let e=[...this.#r];this.#r.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)}}}#ce(){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.#ue();for(let[e,t]of U.get(this.element)??[]){if(e.currentTarget!==t)Object.defineProperty(e,"currentTarget",{value:t,configurable:!0});this.dispatch(e)}U.delete(this.element)}#P=new Set;#ue(){let{queue:e}=V();if(e.length===0)return;let t=[];for(let i=e.length-1;i>=0;i--){let{root:s}=e[i];if(s===this.element||!s.isConnected)t.unshift(...e.splice(i,1))}let r=jr(),n=new Map;for(let i of t){let s=n.get(i.event)??[new Set,new Set];n.set(i.event,s);let a=s[+!!i.win];if(a.has(i.el))continue;a.add(i.el);let o=i.win?Math.min(Wr,r):r,c=i.root!==this.element?"its root left the page before a controller connected":performance.now()-i.at>o?`it is older than the ${o} 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.#L())console.warn(`[phlex-reactive] dropped an early "${i.event.type}" trigger: ${c}`);continue}this.#le(i)}}#le({event:e,el:t,descs:r,win:n}){let i=Jr(e,t,n),s=this.application?.schema?.keyMappings,a=(t.getAttribute("data-action")??"").split(/\s+/),o=n?this.element:t;for(let c of r){if(!a.includes(c.token))continue;if(c.filter&&!re(c.filter,e,s))continue;if(/#\w+.*:once\b/.test(c.token)){if(!zr(o,c,n&&JSON.stringify(i.params)))continue;this.#P.add(o)}if(Hr(e,o,n?`@${c.method}`:c.method),c.method==="runOps")this.runOps(i);else this.dispatch(i)}}disconnect(){if(this.#ae(),this.#ve(),this.#we(),this.#t)this.element.removeEventListener?.("turbo:morph-element",this.#t),this.element.removeEventListener?.("focusin",this.#t),this.element.removeEventListener?.(J,this.#t);if(V().connected.delete(this.element),j.get(this.element)===this)j.delete(this.element);this.element.removeAttribute?.("data-reactive-connected");for(let e of this.#P)ee.delete(e);this.#P.clear()}dispatch(e){if(e.params?.action&&e.params.action!==Be&&this.#de())return this.#fe(e);let t=e.params?.shortcut;if(t!=null&&!B(t,e,this.application?.schema?.keyMappings))return;if(tt(e,"dispatch",this.application?.schema?.keyMappings,this.element))return;let{action:r,params:n,debounce:i,throttle:s,confirm:a,confirmWhen:o,outside:c,window:u,optimistic:d,prevent:f}=e.params;if(!r)return;let h=e.params.busy??e.params.loading;if(c&&this.element.contains(e.target))return;let p=e.currentTarget??e.target;if((t!=null||!u&&f!==!1)&&!this.#re(d,p))ue(e,t);if(r===Be){let m=()=>{{let S=this.#r.get("defer");if(S)return S.materialize(this)}if(this.tokenValue)return this.#M(p,r,"{}")};return this.#m?this.featuresReady.then(m):m()}let b=this.#H(a,o),E=()=>this.#M(p,r,n,i,s,d,h);if(!b)return E();if(b instanceof Promise)return b.then((m)=>m?this.#E(m,p,E):E());this.#E(b,p,E)}#E(e,t,r){return Promise.resolve().then(()=>Oe(e,{el:t})).catch(()=>!1).then((n)=>{if(n)r()})}#H(e,t){if(e)return e;if(!t)return null;{let r=g.get("bindings");if(r)return r.confirmMessage(this,this.#e(),t);return this.#K("bindings").then((n)=>n&&n.confirmMessage(this,this.#e(),t))}}#K(e){{let t;return Promise.race([I(e).catch((r)=>(Z(e,"load",r),null)),new Promise((r)=>t=setTimeout(()=>r(null),le()))]).finally(()=>clearTimeout(t))}}#de(){return!this.tokenValue&&ge(this.element)}#fe(e){let t=R(this.element.parentElement,Lr);if(!t){if(this.element.closest?.('[data-reactive-verbose="true"], [data-reactive-debug="true"]'))console.warn(`[phlex-reactive] "${e.params.action}": no token on this root or above, nothing sent`);return}let r=j.get(t);if(r)return r.dispatch(e);let{shortcut:n,window:i,optimistic:s,prevent:a}=e.params;if(n!=null&&!B(n,e,this.application?.schema?.keyMappings))return;let o=e.currentTarget??e.target;if((n!=null||!i&&a!==!1)&&!this.#re(s,o))ue(e,n);U.set(t,[...U.get(t)??[],[e,o]]);let c=t.dataset;if(c.reactiveDormant)c.controller=`${c.controller??""} ${c.reactiveDormant}`.trim(),delete c.reactiveDormant}runOps(e){let t=e.params?.ops;if(t?.shortcut!=null&&!B(t.shortcut,e,this.application?.schema?.keyMappings))return;if(tt(e,"runOps",this.application?.schema?.keyMappings,this.element))return;if(Ar(e,this))return;let r=e.params??{},n=e.currentTarget??e.target,i=vr(r.ops),s=i.filter((o)=>Ve(o,e,null)),a=s.length<=1?s:s.filter((o)=>Ve(o,e,this.application?.schema?.keyMappings));if(a.length===0&&i.length>0){if(this.#L())this.#w((o)=>o.noBinding(this,e));return}for(let o of a){if(o.outside&&e[C])continue;if(!_r(o,e))continue;let c=o.within==null?n:this.#he(o.within,e);if(o.within!=null&&!c)continue;if(o.shortcut!=null&&!B(o.shortcut,e,this.application?.schema?.keyMappings))continue;if(wr(this,e,o))continue;this.#me(o.legacy?{...r,ops:o.ops,debounce:void 0,throttle:void 0,prevent:void 0}:o,e,c,i.indexOf(o),n)}}#he(e,t){let r=t.currentTarget,n=null;try{n=t.target?.closest?.(e)}catch{if(this.#L())console.warn(`[phlex-reactive] on_client within: ${JSON.stringify(e)} is not a selector — nothing ran`)}return n&&n!==r&&r?.contains?.(n)&&this.#c(n)?n:null}#me(e,t,r,n,i=r){let{ops:s,confirm:a,confirmWhen:o,outside:c,window:u,shortcut:d,prevent:f}=e;if(c&&this.element.contains(t.target))return;if(d!=null||!u&&f!==!1)ue(t,d);let h=this.#H(a,o),p=this.#pe(e,n,i,()=>this.#Pe(this.#Ie(s),r));if(!h)return p();if(h instanceof Promise)return h.then((b)=>b?this.#E(b,r,p):p());this.#E(h,r,p)}#pe(e,t,r,n){let i=Number(e.debounce)||0,s=Number(e.throttle)||0;if(i<=0&&s<=0)return n;let a=JSON.stringify([t,e]);if(i>0)return()=>this.#V(r,a,i,n);return()=>this.#G(r,a,s,n)}recompute(e){return g.get("compute")?.recompute(this,this.#e(),e)}tagsAdd(e){if(e?.defaultPrevented)return;if(this.#_(e).some((t)=>t.hasAttribute?.("data-reactive-highlighted")))return;return this.#v("tagsAdd",e)}tagsPick(e){return this.#v("tagsPick",e)}tagsRemove(e){return this.#v("tagsRemove",e)}nestedAdd(e){return this.#v("nestedAdd",e)}nestedRemove(e){return this.#v("nestedRemove",e)}syncNestedJson(e){return g.get("bindings")?.syncNestedJson(this,this.#e(),e)}#v(e,t){{let r=g.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 v("bindings",(i)=>i[e](this,this.#e(),n))}}trackDirty(){(this.#r.get("form")??g.get("form"))?.scan(this,this.#e())}listnavNext(e){this.#T(e,(t,r)=>t<0?0:(t+1)%r)}listnavPrev(e){this.#T(e,(t,r)=>t<0?r-1:(t-1+r)%r)}listnavFirst(e){this.#T(e,()=>0)}listnavLast(e){this.#T(e,(t,r)=>r-1)}listnavPick(e){let t=this.#_(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.#_(e))t.removeAttribute("data-reactive-highlighted")}#T(e,t){let r=this.#_(e);if(!r.length)return;e.preventDefault();let n=this.#ge(e),i=globalThis.document?.activeElement,s=n?r.findIndex((o)=>o===i||i!=null&&o.contains?.(i)):r.findIndex((o)=>o.hasAttribute("data-reactive-highlighted")),a=r[t(s,r.length)];if(n)a.focus?.();else{for(let o of r)o.removeAttribute("data-reactive-highlighted");a.setAttribute("data-reactive-highlighted","true")}a.scrollIntoView?.({block:"nearest"})}#ge(e){return(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-focus-param")==="true"}#_(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.#Q();return Array.from(this.element.querySelectorAll(r)).filter((i)=>!i.hidden&&n(i))}#M(e,t,r,n,i,s,a){if(this.#o("reactive:before-dispatch",{action:t,params:this.#te(r),element:this.element},{cancelable:!0}).defaultPrevented)return;let c=Number(n)||0;if(c>0)return this.#ye(e,c,t,r,s,a);let u=Number(i)||0;if(u>0)return this.#_e(e,u,t,r,s,a);return this.#F(t,r,s,e,a)}#F(e,t,r,n,i){let s={inverse:null,undo:[],resurrect:null},a=this.#Me(e,n,s),o=Boolean(r||i),c=(h)=>{if(!o||!h)return;let p=this.#e();if(s.inverse=h.optimistic(this,p,r,n),s.undo.push(...h.busy(this,p,i,n)),this.#D())s.resurrect=h.resurrection(this,p,r,n)},u=g.get("hints");if(!o||u)c(u);let d=()=>this.#Te(e,t,s,a),f=()=>this.#n?this.#n.then(d):d();return this.queue=(this.queue??Promise.resolve()).then(()=>o&&!u?this.#be().then(c).then(f):f()),this.queue}#be(){return this.#K("hints")}#ye(e,t,r,n,i,s){this.#V(e,Br,t,()=>this.#F(r,n,i,e,s))}#V(e,t,r,n){this.#C(e,t);let i=()=>{this.#C(e,t),n()},s=setTimeout(i,r);if(!Re(e))e?.addEventListener?.("blur",i,{once:!0});let a=this.#d.get(e);if(!a)this.#d.set(e,a=new Map);a.set(t,{timer:s,flush:i})}#C(e,t){let r=this.#d.get(e),n=r?.get(t);if(!n)return;if(clearTimeout(n.timer),e?.removeEventListener?.("blur",n.flush),r.delete(t),r.size===0)this.#d.delete(e)}#ve(){for(let[e,t]of[...this.#d])for(let r of[...t.keys()])this.#C(e,r)}#_e(e,t,r,n,i,s){return this.#G(e,r,t,()=>this.#F(r,n,i,e,s))}#G(e,t,r,n){let i=this.#f.get(e)??new Map;if(i.has(t))return;let s=setTimeout(()=>{if(i.delete(t),i.size===0)this.#f.delete(e)},r);return i.set(t,s),this.#f.set(e,i),n()}#we(){for(let e of this.#f.values())for(let t of e.values())clearTimeout(t);this.#f.clear()}#o(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.#F(e,t)};this.#o("reactive:error",{action:e,params:r,...n,retry:i})}#i(e){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",e)}#Ae(){this.element?.removeAttribute?.("data-reactive-error")}#Se(){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))}#Ee(){{let e=g.get("devtools");if(e)return e.delay();if(dt())return I("devtools").then((t)=>t.delay(),()=>{})}}#D(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#Y(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}async#Te(e,t,r,n){let{fields:i,files:s}=this.#ee(),a=this.#te(t),o={...i,...a},c=this.#a,u=s.length>0,d=u?this.#Ne(c,e,o,s):JSON.stringify({token:c,act:e,params:o}),f=this.#D()?{action:e,paramNames:Object.keys(a),fieldNames:Object.keys(i),encoding:u?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#Y()}:null;await this.#Ee();try{if(navigator.onLine===!1){this.#u(r.inverse),this.#i("offline"),this.#s(e,t,o,{kind:"offline"});return}let h;try{let m={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#We()};if(!u)m["Content-Type"]="application/json";let S=this.#Be();if(S)m["X-Pgbus-Connection"]=S;let D=Tt(this.element)&&document.getElementById(`reactive-presence-src-${this.element.id}`)?.getAttribute("connection-id");if(D)m["X-Reactive-Presence"]=D;let Ne=Vt(this.element);if(Ne)m["X-Reactive-Held"]=Ne;bt("action"),h=await fetch(this.#$e(),{method:"POST",headers:m,body:d,credentials:"same-origin",signal:AbortSignal.timeout(this.#qe())})}catch(m){if(console.error("[phlex-reactive] action error",m),this.#u(r.inverse),m?.name==="TimeoutError"||m?.name==="AbortError"){this.#i("timeout"),this.#s(e,t,o,{kind:"timeout"});return}this.#Se(),this.#i("network"),this.#s(e,t,o,{kind:"network"});return}if(f)f.status=h.status;if(h.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#u(r.inverse),this.#i("redirected"),this.#s(e,t,o,{kind:"redirected",status:h.status});return}if(!h.ok){let m=await h.text();if(console.error(`[phlex-reactive] action failed: HTTP ${h.status}`,m),this.#u(r.inverse),(h.headers.get("Content-Type")||"").includes("turbo-stream")){let S=this.#X(m);if(this.#a=S??this.#a,f)this.#w((D)=>D.recordBody(f,m,S));We(this.element,m,!0)}this.#i("http"),this.#s(e,t,o,{kind:"http",status:h.status,body:m});return}let p=h.headers.get("Content-Type")||"";if(!p.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${p}" — no update applied`),this.#u(r.inverse),this.#i("content-type"),this.#s(e,t,o,{kind:"content-type",status:h.status});return}let b=await h.text(),E=this.#X(b);if(this.#a=E??this.#a,f)this.#w((m)=>m.recordBody(f,b,E));if(We(this.element,b,Gt(h)),r.resurrect)queueMicrotask(r.resurrect);return this.#Ae(),this.#o("reactive:applied",{action:e,params:o,html:b}),b}catch(h){console.error("[phlex-reactive] action error",h),this.#u(r.inverse),this.#o("reactive:error",{action:e,params:o,kind:"apply"})}finally{if(n?.(),f)this.#w((h)=>h.trace(this,{...f,ms:this.#Y()-f.started}))}}get#a(){return this.#A??this.tokenValue}set#a(e){this.#A=e}tokenValueChanged(){this.#A=void 0}#X(e){let t=this.element.id;if(!t)return e.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:r,self:n}=this.#Fe(t),i=e.match(r);if(i)return i[1];let s=e.match(n);if(s)return s[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#Fe(e){let t=this.#B;if(t&&t.id===e)return t;let r=tr(e);return this.#B={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>`)}}#c(e){return e.closest('[data-controller~="reactive"]')===this.element}#Q(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(t)=>this.#c(t)}#ke(){let e=this.element.querySelectorAll(F);if(e.length===0||[...e].every(ge))return()=>!0;return(t)=>{let r=R(t,F,this.element);if(r===this.element)return!0;return t.getAttribute("data-reactive-shared-field")!=null&&R(r.parentElement,F,this.element)===this.element}}#Z(e){if(this.#c(e))return!0;if(e.getAttribute?.("data-reactive-shared-field")==null)return!1;let t=R(e,F,this.element);return t===this.element||R(t?.parentElement,F,this.element)===this.element}#Le(){if(this.element.querySelectorAll(F).length===0)return()=>!0;return(e)=>this.#Z(e)}#ee(){let e={},t=[],r=this.#ke(),n=[];this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((o)=>{if(!r(o))return;if(o.type==="file")for(let c of o.files??[])t.push({name:o.name,file:c,multiple:o.multiple});else n.push(o)});let i=[];this.element.querySelectorAll(`[name]${sr}`).forEach((o)=>{if(r(o))i.push(o)});let s=this.#xe(n),a=this.#Re(n);for(let o of n)if(s.has(o.name)){let c=e[o.name]??(e[o.name]=[]);if(o.type==="checkbox"||o.type==="radio"){if(o.checked)c.push(o.value)}else if(o.type==="hidden"){if(!a.has(o.name))c.push(o.value)}else if(o.multiple&&o.options){for(let u of o.options)if(u.selected)c.push(u.value)}else c.push(o.value)}else if(o.type==="checkbox")e[o.name]=o.checked;else if(o.type==="radio"){if(o.checked)e[o.name]=o.value}else e[o.name]=o.value;return i.forEach((o)=>{let c=o.getAttribute("name");if(!c)return;let u=o.getAttribute("data-reactive-editable")!=null?T(o):o.value??o.textContent??o.innerHTML??"",d=e[c];if(String(c).endsWith("[]")&&!cr(o))return;if(String(c).endsWith("[]")&&(d===void 0||Array.isArray(d))){(Array.isArray(d)?d:e[c]=[]).push(u);return}if(d==null||d==="")e[c]=u}),{fields:e,files:t}}#xe(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}#Re(e){let t=new Set;for(let r of e)if(r.type==="checkbox")t.add(r.name);return t}#Ne(e,t,r,n){let i=new FormData;i.append("token",e),i.append("act",t);let s=[];for(let[o,c]of Object.entries(r))if(Array.isArray(c)&&String(o).endsWith("[]"))if(c.length===0)s.push(String(o).slice(0,-2));else{let u=`${this.#k(o)}[]`;for(let d of c)i.append(u,String(d))}else this.#$(i,this.#k(o),c);for(let o of s)i.append("empty_groups[]",o);let a=this.#Oe(n);for(let{name:o,file:c,multiple:u}of n){let f=u||a.has(o)?`${this.#k(o)}[]`:this.#k(o);i.append(f,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("")}`}#$(e,t,r){if(r==null)e.append(t,"");else if(Array.isArray(r))r.forEach((n,i)=>this.#$(e,`${t}[${i}]`,n));else if(typeof r==="object")for(let[n,i]of Object.entries(r))this.#$(e,`${t}[${n}]`,i);else e.append(t,String(r))}#Oe(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))}#te(e){if(!e)return{};try{return typeof e==="string"?JSON.parse(e):e}catch{return{}}}#Ie(e){return ke(e)}#Pe(e,t){pe(e,(r)=>this.#W(r,t),(r,n)=>this.#q(`client op "${r}"`,n))}#L(){return this.element?.getAttribute?.("data-reactive-verbose")==="true"||this.#D()}#q(e,t){if(!this.#L())return;this.#w((r)=>r.diagnose(this,e,t))}#w(e){v("devtools",e)}#W(e,t){let r=e.to;if(r==="@root")return[this.element];if(r==="@trigger")return t?.nodeType===1?[t]:[];if(typeof r!=="string"||r==="")return[];if(e.global)return[...document.querySelectorAll(r)];return[...this.element.querySelectorAll(r)].filter((n)=>this.#c(n))}#re(e,t){if(e?.checked!=="keep")return!1;let r=t?.type;return r==="checkbox"||r==="radio"}#u(e){if(!e)return;if(!this.element.isConnected)return;for(let t of e)t()}#Me(e,t,r){this.#Ce(e,t),ht();let n=!1;return()=>{if(n)return;n=!0,this.#De(e,t),mt();for(let i of r.undo)i()}}#Ce(e,t){if(this.#l(t,e,1),this.#l(this.element,e,1),this.#h.set(e,(this.#h.get(e)??0)+1),this.#R++===0)this.element.setAttribute("aria-busy","true");for(let r of this.#ne(e))this.#l(r,e,1)}#De(e,t){this.#l(t,e,-1),this.#l(this.element,e,-1);let r=(this.#h.get(e)??1)-1;if(r<=0)this.#h.delete(e);else this.#h.set(e,r);if(--this.#R<=0)this.#R=0,this.element.removeAttribute("aria-busy");for(let n of this.#ne(e))this.#l(n,e,-1)}#l(e,t,r){if(!e||typeof e.getAttribute!=="function")return;let n=this.#N.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.#N.delete(e),e.removeAttribute("data-reactive-busy");return}this.#N.set(e,n),e.setAttribute("data-reactive-busy",[...n.keys()].join(" "))}#ne(e){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((r)=>r.getAttribute("data-reactive-busy-on")===e&&this.#c(r))}#$e(){return this.#ie??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#qe(){if(this.#x!=null)return this.#x;let e=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,t=Number(e);return this.#x=Number.isFinite(t)&&t>0?t:30000}#We(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#Be(){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)Ue();else document.addEventListener("turbo:load",Ue,{once:!0});y("persist",()=>import("phlex/reactive/features/persist"),Vr);y("defer",()=>import("phlex/reactive/features/defer"));y("form",()=>import("phlex/reactive/features/form"));y("bindings",()=>import("phlex/reactive/features/bindings"));y("compute",()=>import("phlex/reactive/features/compute"),Gr);y("sortable",()=>import("phlex/reactive/features/sortable"));y("drag",()=>import("phlex/reactive/features/drag"));y("presence",()=>import("phlex/reactive/features/presence"));y("countdown",()=>import("phlex/reactive/features/countdown"));y("effects",()=>import("phlex/reactive/features/effects"));y("hints",()=>import("phlex/reactive/features/hints"));y("devtools",()=>import("phlex/reactive/features/devtools"));Ee();function Vr(e,t){let r=()=>{t.edited=!0},n=(s)=>{let a=s.target;if(s.detail?.success&&a?.tagName==="FORM"&&a.contains?.(e))t.submitted=!0},i=["input","change","lexxy:change","trix-change"];for(let s of i)e.addEventListener?.(s,r);return document.addEventListener("turbo:submit-end",n),()=>{for(let s of i)e.removeEventListener?.(s,r);document.removeEventListener("turbo:submit-end",n)}}function Gr(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 Yr=1000,x=null,Rt,ne=new Set;function Xr(e){return Lt(e).then((t)=>{if(e!=="effects")return;Rt=t,t?.sweep()})}ct((e,t)=>{let r=e.detail,n=r?.render;if(typeof n!=="function")return;let i=r.newStream??e.target,s=kt(Qr(i)).filter((o)=>!ne.has(o));if(!t&&!ne.has("effects")&&Zr(i))s.push("effects");if(s.length===0&&!x)return t?.wrap(e);if(s.length>0){for(let c of s)ne.add(c);let o=x=Promise.race([Promise.all([x,...s.map(Xr)]),new Promise((c)=>setTimeout(c,Yr))]).then(()=>{if(x!==o)return;x=null,ne.clear()})}let a=x;r.render=async(o)=>{await a;let c={target:e.target,detail:{newStream:r.newStream,render:n}};(t??Rt)?.wrap(c),await c.detail.render(o)}});function Qr(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.push(t),r}function Zr(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 hn=xt;export{ft as ACTIVE_ATTR,sr as EDITOR_SELECTOR,ar as EDITOR_TAGS,gt as REQUESTS_ATTR,rr as checkReactiveRegistration,bt as countReactiveRequest,hn as default,T as editableValue,ht as enterReactiveActivity,tr as escapeRegExp,mt as exitReactiveActivity,Lt as loadReactiveFeature,ct as onReactiveStreamWithoutEffects,nn as reactiveActivityCount,an as reactiveFeatureNames,Ue as registerReactiveActions,Ct as registerReactiveDefer,Ee as registerReactiveDev,Dt as registerReactiveDismiss,Dt as registerReactiveEffects,sn as registerReactiveFeature,y as registerReactiveFeatureLoader,Ut as registerReactiveImageFallback,Mt as registerReactiveJs,jt as registerReactiveKeep,Bt as registerReactiveModals,zt as registerReactiveMorphFocus,Xt as registerReactiveOffline,Jt as registerReactivePlaintext,Dt as registerReactiveStreamRender,It as registerReactiveToken,Ot as registerReactiveVisit,on as resetReactiveActivity,Fe as serverText,kt as unloadedFeaturesFor};
|
|
7
7
|
|
|
8
|
-
//# debugId=
|
|
8
|
+
//# debugId=657C41040377349A64756E2164756E21
|
|
9
9
|
//# sourceMappingURL=core.min.js.map
|