hotsheet 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +32 -35
  4. data/app/assets/hotsheet.css +1 -0
  5. data/app/assets/hotsheet.js +33 -0
  6. data/app/controllers/hotsheet/application_controller.rb +2 -4
  7. data/app/controllers/hotsheet/sheets_controller.rb +47 -0
  8. data/app/helpers/hotsheet/application_helper.rb +3 -3
  9. data/app/views/hotsheet/shared/_nav.html.erb +14 -0
  10. data/app/views/hotsheet/sheets/error.html.erb +1 -0
  11. data/app/views/hotsheet/sheets/index.html.erb +20 -0
  12. data/app/views/hotsheet/sheets/root.html.erb +1 -0
  13. data/app/views/layouts/hotsheet/application.html.erb +7 -7
  14. data/config/routes.rb +6 -5
  15. data/lib/generators/templates/hotsheet.rb +7 -4
  16. data/lib/hotsheet/column.rb +31 -0
  17. data/lib/hotsheet/config.rb +29 -0
  18. data/lib/hotsheet/engine.rb +5 -4
  19. data/lib/hotsheet/sheet.rb +44 -0
  20. data/lib/hotsheet/version.rb +1 -1
  21. data/lib/hotsheet.rb +38 -11
  22. metadata +17 -89
  23. data/CHANGELOG.md +0 -17
  24. data/app/assets/config/hotsheet.js +0 -2
  25. data/app/assets/javascripts/hotsheet/application.js +0 -1
  26. data/app/assets/javascripts/hotsheet/channels/consumer.js +0 -3
  27. data/app/assets/javascripts/hotsheet/channels/inline_edit_channel.js +0 -3
  28. data/app/assets/javascripts/hotsheet/controllers/application.js +0 -6
  29. data/app/assets/javascripts/hotsheet/controllers/editable_attribute_controller.js +0 -51
  30. data/app/assets/stylesheets/hotsheet/application.css +0 -86
  31. data/app/channels/application_cable/channel.rb +0 -6
  32. data/app/channels/application_cable/connection.rb +0 -6
  33. data/app/channels/inline_edit_channel.rb +0 -9
  34. data/app/controllers/hotsheet/pages_controller.rb +0 -43
  35. data/app/views/hotsheet/pages/_editable_attribute.html.erb +0 -24
  36. data/app/views/hotsheet/pages/index.html.erb +0 -27
  37. data/app/views/layouts/hotsheet/_flash.html.erb +0 -7
  38. data/app/views/layouts/hotsheet/_sidebar.html.erb +0 -11
  39. data/config/initializers/hotsheet/content_security_policy.rb +0 -14
  40. data/config/initializers/hotsheet/editable_attributes.rb +0 -43
  41. data/config/initializers/hotsheet/pagy.rb +0 -7
  42. data/config/locales/en.yml +0 -5
  43. data/lib/hotsheet/configuration.rb +0 -19
  44. data/vendor/assets/stylesheets/hotsheet/pagy.css +0 -37
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ebb74d345ffa27e7320c021ce0108b934414cc5e93fae4e58893a5e556e389b4
4
- data.tar.gz: c45e89321ccd3da4ad7354ae2d6695035d31451a2c38990a6c14f6cc4d793173
3
+ metadata.gz: 7a5cc231b679617e535c8fb71bc077fbf8c735935967149af191484baa07d5cb
4
+ data.tar.gz: 4a9f48ce2ed52a96b313bb691b0908f141b18aea5807c41385753bca97671cf5
5
5
  SHA512:
6
- metadata.gz: d7d422c0bfe713d39d3e2d4566b116e1e5cc75825bbca187bae4e9d73fb75ebd35a442020b8ad1b2f3e05796cd1726be86b9b7ff9f28838ef4bae6c86bfcefcc
7
- data.tar.gz: 82a933e5d47a1b60806dca93db6b5e041fc46a39fc2e0f57955c5bac3cf5dc45b7c3218bfd16a18e685faa1cbac4a2160daef3a30333ecafda78400d57737414
6
+ metadata.gz: df1ce187b96c8dde0699ac26cbef9d4c28c08d1835d591537e0329beb308e6fafd4b9b1fbc08d851d30aa4a137cb006109b95fd77202f1663d963a928427e901
7
+ data.tar.gz: 5eacbcbadf7cac7f8ff7cde1a058ff8233ecd9e2f962de90a792b5eaa51c48dc2d2d7ee6c2db1b03a7c9579bb137d363a3ebe0b8873357d45eef4301e742880c
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Renuo AG
3
+ Copyright (c) 2024-present Renuo AG
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,61 +1,58 @@
1
1
  # Hotsheet
2
2
 
3
- **Manage your database with a simple and familiar web interface**
3
+ **Manage your Rails database through a spreadsheet-like interface.**
4
4
 
5
- This gem allows you to mount a view to manage your database using a table view
6
- where you can edit database records inline.
5
+ - Look at and modify your DB within the app itself (no rails console required!).
6
+ - Give controlled DB access to your admin users without having to create CRUD views for each table.
7
+ - Lightweight and fast. We keep usage simple and configuration to the minimum.
8
+
9
+ <image width=450 alt=demo src=https://github.com/user-attachments/assets/d63544ff-0720-4839-9c14-b5c8cd084cd2>
7
10
 
8
11
  ## Installation
9
12
 
10
- Add this line to your application's Gemfile:
13
+ 1. Add `gem "hotsheet"` to your Gemfile.
14
+ 1. Run `bundle`.
15
+ 1. Run `bin/rails g hotsheet:install`.
11
16
 
12
- ```rb
13
- gem "hotsheet"
14
- ```
15
-
16
- And then execute:
17
+ ## Usage
17
18
 
18
- ```sh
19
- bundle
20
- bin/rails g hotsheet:install
21
- ```
19
+ After installing, you can directly go to `/hotsheet` within your app by default.
22
20
 
23
- ## Usage
21
+ ### Configuration
24
22
 
25
- You can configure which models this gem should manage, and specify which
26
- attributes (database columns) should be editable in the Hotsheet. This can be
23
+ You can configure which models ('sheets') this gem should manage, and specify which
24
+ database columns should be editable or viewable in the spreadsheet. This can be
27
25
  done by configuring the initializer file created by the install command:
28
26
 
29
27
  ```rb
30
28
  # config/initializers/hotsheet.rb
31
29
 
32
- Hotsheet.configure do |config|
33
- config.model :Author do |model|
34
- model.included_attributes = %i[name birthdate gender] # mutually exclusive with "excluded_attributes"
35
- # model.excluded_attributes = %i[created_at updated_at] # mutually exclusive with "included_attributes"
30
+ Hotsheet.configure do
31
+ sheet :User do
32
+ column :name
33
+ column :birthdate, editable: false
36
34
  end
37
35
  end
38
36
  ```
39
37
 
40
38
  ## Contributing
41
39
 
42
- See [Contributing Guide] for information on how to set up hotsheet locally.
40
+ See [Contributing Guide](https://github.com/renuo/hotsheet/blob/main/CONTRIBUTING.md) and please
41
+ follow the [Code of Conduct](https://github.com/renuo/hotsheet/blob/main/CODE_OF_CONDUCT.md).
43
42
 
44
- ## Roadmap / Planned Features
43
+ ## Roadmap
45
44
 
46
- - Fetch all models in the application by default
47
- - Support live updates (show when someone has the intention to edit a resource) via ActionCable
48
- - Conflict resolution strategy (locking / merging / latest change etc.)
49
- - Fine grained access / permissions (cancancan)
50
- - Type-specific input fields
51
- - Undo feature (or confirm / discard changes icons)
52
- - Configure visibility of non-editable (excluded) fields
53
- - Use importmap-rails for JS dependencies
45
+ This is a newly created gem, and we will firstly focus on:
54
46
 
55
- ## License
47
+ 1. Single-user experience (styles and usability)
48
+ 1. Configuration and access permissions
49
+ 1. Concurrent users (broadcasting, conflict resolution)
56
50
 
57
- Hotsheet is available as open source under the terms of the [MIT License].\
58
- Copyright © 2024 [Renuo AG](https://www.renuo.ch).
51
+ Feel free to look at our [planned enhancements](https://github.com/renuo/hotsheet/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement)
52
+ or add your own.
53
+
54
+ ## License
59
55
 
60
- [Contributing Guide]: https://github.com/renuo/hotsheet/blob/main/CONTRIBUTING.md
61
- [MIT License]: https://github.com/renuo/hotsheet/blob/main/LICENSE
56
+ Hotsheet is available as open source under the terms of the
57
+ [MIT License](https://github.com/renuo/hotsheet/blob/main/LICENSE).\
58
+ Copyright © 2024-present [Renuo AG](https://www.renuo.ch).
@@ -0,0 +1 @@
1
+ :root{--color-background:#000;--color-background-hover:#202020;--color-border:#404040;--color-foreground:#fff;--color-primary:#60ffff;--color-red:#ff6060;--border:var(--border-width)solid var(--color-border);--border-width:.0625rem;--border-radius:.25rem;--outline:var(--border-width)solid var(--color-primary);--margin:.25rem;--padding:.5rem;--height:1.75rem}@media (prefers-color-scheme:light){:root{--color-background:#fff;--color-background-hover:#e3e3e3;--color-border:#b6b6b6;--color-foreground:#000;--color-primary:#0070e4}}body,body *{all:unset;box-sizing:border-box;display:flex}body{background-color:var(--color-background);color:var(--color-foreground);font:400 1rem -apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,Arial,sans-serif}main{overflow-x:auto;padding:calc(var(--height)*2 + var(--padding)*2 + var(--margin) + var(--border-width) + var(--padding))var(--padding)var(--padding)var(--padding);width:100%;min-height:100vh}::selection{background-color:var(--color-primary);color:var(--color-background)}.flash{position:absolute;right:var(--padding);top:var(--padding);z-index:2}.flash .alert{background-color:var(--color-red);border-radius:var(--border-radius);color:#000;padding:var(--padding)}.nav{background-color:var(--color-background);border-bottom:var(--border);gap:var(--margin);padding:var(--padding);position:fixed;user-select:none;flex-direction:column;width:100%;top:0}.nav ul{gap:var(--margin);width:100%}.nav a{border-radius:var(--border-radius);border:var(--border);cursor:pointer;height:var(--height);white-space:nowrap;justify-content:center;align-items: center;width:100%;padding:0 .5rem}.nav a:focus-visible{border:var(--outline);z-index:1}.nav a:hover{background-color:var(--color-background-hover)}.nav a.active{background-color:var(--color-border)}.nav a.title{border-color:#0000;font-size:1.25rem}.nav .sheets{overflow-x:auto;scrollbar-width:none}.table{border:var(--border);border-radius:var(--border-radius);height:-moz-fit-content;height:fit-content}.column{flex-direction:column;max-width:20rem}.column:first-child .cell{border-left:none}.column:last-child .cell{border-right:none}.cell{border:calc(var(--border-width)/2)solid var(--color-border);height:var(--height);overflow:hidden;user-select:none;white-space:nowrap;align-items: center;padding:0 .5rem}.cell:hover{background-color:var(--color-background-hover)}.cell.readonly{background-color:var(--color-background-hover)}.cell:focus{background-color:var(--color-background);border-radius:var(--border-radius);outline:var(--outline);user-select:text;z-index:1}.cell:focus-within{background-color:var(--color-background);border-radius:var(--border-radius);outline:var(--outline);user-select:text;z-index:1}.cell:last-child{border-bottom:none}.cell:has(input){overflow:visible}.cell.header{background-color:var(--color-border);border-top:none}.cell input{overflow:hidden;width:100%;height:100%}
@@ -0,0 +1,33 @@
1
+ /*!
2
+ Turbo 8.0.13
3
+ Copyright © 2025 37signals LLC
4
+ */(function(H){if(typeof H.requestSubmit=="function")return;H.requestSubmit=function(X){if(X)J(X,this),X.click();else X=document.createElement("input"),X.type="submit",X.hidden=!0,this.appendChild(X),X.click(),this.removeChild(X)};function J(X,Y){X instanceof HTMLElement||Q(TypeError,"parameter 1 is not of type 'HTMLElement'"),X.type=="submit"||Q(TypeError,"The specified element is not a submit button"),X.form==Y||Q(DOMException,"The specified element is not owned by this form element","NotFoundError")}function Q(X,Y,Z){throw new X("Failed to execute 'requestSubmit' on 'HTMLFormElement': "+Y+".",Z)}})(HTMLFormElement.prototype);var eH=new WeakMap;function DJ(H){let J=H instanceof Element?H:H instanceof Node?H.parentElement:null,Q=J?J.closest("input, button"):null;return Q?.type=="submit"?Q:null}function OJ(H){let J=DJ(H.target);if(J&&J.form)eH.set(J.form,J)}(function(){if("submitter"in Event.prototype)return;let H=window.Event.prototype;if("SubmitEvent"in window){let J=window.SubmitEvent.prototype;if(/Apple Computer/.test(navigator.vendor)&&!("submitter"in J))H=J;else return}addEventListener("click",OJ,!0),Object.defineProperty(H,"submitter",{get(){if(this.type=="submit"&&this.target instanceof HTMLFormElement)return eH.get(this.target)}})})();var a={eager:"eager",lazy:"lazy"};class g extends HTMLElement{static delegateConstructor=void 0;loaded=Promise.resolve();static get observedAttributes(){return["disabled","loading","src"]}constructor(){super();this.delegate=new g.delegateConstructor(this)}connectedCallback(){this.delegate.connect()}disconnectedCallback(){this.delegate.disconnect()}reload(){return this.delegate.sourceURLReloaded()}attributeChangedCallback(H){if(H=="loading")this.delegate.loadingStyleChanged();else if(H=="src")this.delegate.sourceURLChanged();else if(H=="disabled")this.delegate.disabledChanged()}get src(){return this.getAttribute("src")}set src(H){if(H)this.setAttribute("src",H);else this.removeAttribute("src")}get refresh(){return this.getAttribute("refresh")}set refresh(H){if(H)this.setAttribute("refresh",H);else this.removeAttribute("refresh")}get shouldReloadWithMorph(){return this.src&&this.refresh==="morph"}get loading(){return xJ(this.getAttribute("loading")||"")}set loading(H){if(H)this.setAttribute("loading",H);else this.removeAttribute("loading")}get disabled(){return this.hasAttribute("disabled")}set disabled(H){if(H)this.setAttribute("disabled","");else this.removeAttribute("disabled")}get autoscroll(){return this.hasAttribute("autoscroll")}set autoscroll(H){if(H)this.setAttribute("autoscroll","");else this.removeAttribute("autoscroll")}get complete(){return!this.delegate.isLoading}get isActive(){return this.ownerDocument===document&&!this.isPreview}get isPreview(){return this.ownerDocument?.documentElement?.hasAttribute("data-turbo-preview")}}function xJ(H){switch(H.toLowerCase()){case"lazy":return a.lazy;default:return a.eager}}var hJ={enabled:!0,progressBarDelay:500,unvisitableExtensions:new Set([".7z",".aac",".apk",".avi",".bmp",".bz2",".css",".csv",".deb",".dmg",".doc",".docx",".exe",".gif",".gz",".heic",".heif",".ico",".iso",".jpeg",".jpg",".js",".json",".m4a",".mkv",".mov",".mp3",".mp4",".mpeg",".mpg",".msi",".ogg",".ogv",".pdf",".pkg",".png",".ppt",".pptx",".rar",".rtf",".svg",".tar",".tif",".tiff",".txt",".wav",".webm",".webp",".wma",".wmv",".xls",".xlsx",".xml",".zip"])};function JH(H){if(H.getAttribute("data-turbo-eval")=="false")return H;else{let J=document.createElement("script"),Q=Z1();if(Q)J.nonce=Q;return J.textContent=H.textContent,J.async=!1,gJ(J,H),J}}function gJ(H,J){for(let{name:Q,value:X}of J.attributes)H.setAttribute(Q,X)}function bJ(H){let J=document.createElement("template");return J.innerHTML=H,J.content}function C(H,{target:J,cancelable:Q,detail:X}={}){let Y=new CustomEvent(H,{cancelable:Q,bubbles:!0,composed:!0,detail:X});if(J&&J.isConnected)J.dispatchEvent(Y);else document.documentElement.dispatchEvent(Y);return Y}function mH(H){H.preventDefault(),H.stopImmediatePropagation()}function HH(){if(document.visibilityState==="hidden")return J1();else return H1()}function H1(){return new Promise((H)=>requestAnimationFrame(()=>H()))}function J1(){return new Promise((H)=>setTimeout(()=>H(),0))}function yJ(){return Promise.resolve()}function Q1(H=""){return new DOMParser().parseFromString(H,"text/html")}function X1(H,...J){let Q=kJ(H,J).replace(/^\n/,"").split(`
5
+ `),X=Q[0].match(/^\s+/),Y=X?X[0].length:0;return Q.map((Z)=>Z.slice(Y)).join(`
6
+ `)}function kJ(H,J){return H.reduce((Q,X,Y)=>{let Z=J[Y]==null?"":J[Y];return Q+X+Z},"")}function p(){return Array.from({length:36}).map((H,J)=>{if(J==8||J==13||J==18||J==23)return"-";else if(J==14)return"4";else if(J==19)return(Math.floor(Math.random()*4)+8).toString(16);else return Math.floor(Math.random()*15).toString(16)}).join("")}function WH(H,...J){for(let Q of J.map((X)=>X?.getAttribute(H)))if(typeof Q=="string")return Q;return null}function NJ(H,...J){return J.some((Q)=>Q&&Q.hasAttribute(H))}function AH(...H){for(let J of H){if(J.localName=="turbo-frame")J.setAttribute("busy","");J.setAttribute("aria-busy","true")}}function qH(...H){for(let J of H){if(J.localName=="turbo-frame")J.removeAttribute("busy");J.removeAttribute("aria-busy")}}function fJ(H,J=2000){return new Promise((Q)=>{let X=()=>{H.removeEventListener("error",X),H.removeEventListener("load",X),Q()};H.addEventListener("load",X,{once:!0}),H.addEventListener("error",X,{once:!0}),setTimeout(Q,J)})}function Y1(H){switch(H){case"replace":return history.replaceState;case"advance":case"restore":return history.pushState}}function vJ(H){return H=="advance"||H=="replace"||H=="restore"}function s(...H){let J=WH("data-turbo-action",...H);return vJ(J)?J:null}function CH(H){return document.querySelector(`meta[name="${H}"]`)}function UH(H){let J=CH(H);return J&&J.content}function Z1(){let H=CH("csp-nonce");if(H){let{nonce:J,content:Q}=H;return J==""?Q:J}}function pJ(H,J){let Q=CH(H);if(!Q)Q=document.createElement("meta"),Q.setAttribute("name",H),document.head.appendChild(Q);return Q.setAttribute("content",J),Q}function n(H,J){if(H instanceof Element)return H.closest(J)||n(H.assignedSlot||H.getRootNode()?.host,J)}function SH(H){return!!H&&H.closest("[inert], :disabled, [hidden], details:not([open]), dialog:not([open])")==null&&typeof H.focus=="function"}function $1(H){return Array.from(H.querySelectorAll("[autofocus]")).find(SH)}async function dJ(H,J){let Q=J();H(),await H1();let X=J();return[Q,X]}function G1(H){if(H==="_blank")return!1;else if(H){for(let J of document.getElementsByName(H))if(J instanceof HTMLIFrameElement)return!1;return!0}else return!0}function W1(H){return n(H,"a[href]:not([target^=_]):not([download])")}function A1(H){return V(H.getAttribute("href")||"")}function cJ(H,J){let Q=null;return(...X)=>{let Y=()=>H.apply(this,X);clearTimeout(Q),Q=setTimeout(Y,J)}}var uJ={"aria-disabled":{beforeSubmit:(H)=>{H.setAttribute("aria-disabled","true"),H.addEventListener("click",mH)},afterSubmit:(H)=>{H.removeAttribute("aria-disabled"),H.removeEventListener("click",mH)}},disabled:{beforeSubmit:(H)=>H.disabled=!0,afterSubmit:(H)=>H.disabled=!1}};class q1{#H=null;constructor(H){Object.assign(this,H)}get submitter(){return this.#H}set submitter(H){this.#H=uJ[H]||H}}var sJ=new q1({mode:"on",submitter:"disabled"}),T={drive:hJ,forms:sJ};function V(H){return new URL(H.toString(),document.baseURI)}function i(H){let J;if(H.hash)return H.hash.slice(1);else if(J=H.href.match(/#(.*)$/))return J[1]}function wH(H,J){let Q=J?.getAttribute("formaction")||H.getAttribute("action")||H.action;return V(Q)}function iJ(H){return(aJ(H).match(/\.[^.]*$/)||[])[0]||""}function mJ(H,J){let Q=lJ(J);return H.href===V(Q).href||H.href.startsWith(Q)}function v(H,J){return mJ(H,J)&&!T.drive.unvisitableExtensions.has(iJ(H))}function jH(H){let J=i(H);return J!=null?H.href.slice(0,-(J.length+1)):H.href}function $H(H){return jH(H)}function oJ(H,J){return V(H).href==V(J).href}function rJ(H){return H.pathname.split("/").slice(1)}function aJ(H){return rJ(H).slice(-1)[0]}function lJ(H){return nJ(H.origin+H.pathname)}function nJ(H){return H.endsWith("/")?H:H+"/"}class zH{constructor(H){this.response=H}get succeeded(){return this.response.ok}get failed(){return!this.succeeded}get clientError(){return this.statusCode>=400&&this.statusCode<=499}get serverError(){return this.statusCode>=500&&this.statusCode<=599}get redirected(){return this.response.redirected}get location(){return V(this.response.url)}get isHTML(){return this.contentType&&this.contentType.match(/^(?:text\/([^\s;,]+\b)?html|application\/xhtml\+xml)\b/)}get statusCode(){return this.response.status}get contentType(){return this.header("Content-Type")}get responseText(){return this.response.clone().text()}get responseHTML(){if(this.isHTML)return this.response.clone().text();else return Promise.resolve(void 0)}header(H){return this.response.headers.get(H)}}class U1 extends Set{constructor(H){super();this.maxSize=H}add(H){if(this.size>=this.maxSize){let Q=this.values().next().value;this.delete(Q)}super.add(H)}}var z1=new U1(20),tJ=window.fetch;function K1(H,J={}){let Q=new Headers(J.headers||{}),X=p();return z1.add(X),Q.append("X-Turbo-Request-Id",X),tJ(H,{...J,headers:Q})}function EH(H){switch(H.toLowerCase()){case"get":return O.get;case"post":return O.post;case"put":return O.put;case"patch":return O.patch;case"delete":return O.delete}}var O={get:"get",post:"post",put:"put",patch:"patch",delete:"delete"};function eJ(H){switch(H.toLowerCase()){case u.multipart:return u.multipart;case u.plain:return u.plain;default:return u.urlEncoded}}var u={urlEncoded:"application/x-www-form-urlencoded",multipart:"multipart/form-data",plain:"text/plain"};class e{abortController=new AbortController;#H=(H)=>{};constructor(H,J,Q,X=new URLSearchParams,Y=null,Z=u.urlEncoded){let[U,B]=oH(V(Q),J,X,Z);this.delegate=H,this.url=U,this.target=Y,this.fetchOptions={credentials:"same-origin",redirect:"follow",method:J.toUpperCase(),headers:{...this.defaultHeaders},body:B,signal:this.abortSignal,referrer:this.delegate.referrer?.href},this.enctype=Z}get method(){return this.fetchOptions.method}set method(H){let J=this.isSafe?this.url.searchParams:this.fetchOptions.body||new FormData,Q=EH(H)||O.get;this.url.search="";let[X,Y]=oH(this.url,Q,J,this.enctype);this.url=X,this.fetchOptions.body=Y,this.fetchOptions.method=Q.toUpperCase()}get headers(){return this.fetchOptions.headers}set headers(H){this.fetchOptions.headers=H}get body(){if(this.isSafe)return this.url.searchParams;else return this.fetchOptions.body}set body(H){this.fetchOptions.body=H}get location(){return this.url}get params(){return this.url.searchParams}get entries(){return this.body?Array.from(this.body.entries()):[]}cancel(){this.abortController.abort()}async perform(){let{fetchOptions:H}=this;this.delegate.prepareRequest(this);let J=await this.#J(H);try{if(this.delegate.requestStarted(this),J.detail.fetchRequest)this.response=J.detail.fetchRequest.response;else this.response=K1(this.url.href,H);let Q=await this.response;return await this.receive(Q)}catch(Q){if(Q.name!=="AbortError"){if(this.#Q(Q))this.delegate.requestErrored(this,Q);throw Q}}finally{this.delegate.requestFinished(this)}}async receive(H){let J=new zH(H);if(C("turbo:before-fetch-response",{cancelable:!0,detail:{fetchResponse:J},target:this.target}).defaultPrevented)this.delegate.requestPreventedHandlingResponse(this,J);else if(J.succeeded)this.delegate.requestSucceededWithResponse(this,J);else this.delegate.requestFailedWithResponse(this,J);return J}get defaultHeaders(){return{Accept:"text/html, application/xhtml+xml"}}get isSafe(){return RH(this.method)}get abortSignal(){return this.abortController.signal}acceptResponseType(H){this.headers.Accept=[H,this.headers.Accept].join(", ")}async#J(H){let J=new Promise((X)=>this.#H=X),Q=C("turbo:before-fetch-request",{cancelable:!0,detail:{fetchOptions:H,url:this.url,resume:this.#H},target:this.target});if(this.url=Q.detail.url,Q.defaultPrevented)await J;return Q}#Q(H){return!C("turbo:fetch-request-error",{target:this.target,cancelable:!0,detail:{request:this,error:H}}).defaultPrevented}}function RH(H){return EH(H)==O.get}function oH(H,J,Q,X){let Y=Array.from(Q).length>0?new URLSearchParams(B1(Q)):H.searchParams;if(RH(J))return[HQ(H,Y),null];else if(X==u.urlEncoded)return[H,Y];else return[H,Q]}function B1(H){let J=[];for(let[Q,X]of H)if(X instanceof File)continue;else J.push([Q,X]);return J}function HQ(H,J){let Q=new URLSearchParams(B1(J));return H.search=Q.toString(),H}class _1{started=!1;constructor(H,J){this.delegate=H,this.element=J,this.intersectionObserver=new IntersectionObserver(this.intersect)}start(){if(!this.started)this.started=!0,this.intersectionObserver.observe(this.element)}stop(){if(this.started)this.started=!1,this.intersectionObserver.unobserve(this.element)}intersect=(H)=>{if(H.slice(-1)[0]?.isIntersecting)this.delegate.elementAppearedInViewport(this.element)}}class m{static contentType="text/vnd.turbo-stream.html";static wrap(H){if(typeof H=="string")return new this(bJ(H));else return H}constructor(H){this.fragment=JQ(H)}}function JQ(H){for(let J of H.querySelectorAll("turbo-stream")){let Q=document.importNode(J,!0);for(let X of Q.templateElement.content.querySelectorAll("script"))X.replaceWith(JH(X));J.replaceWith(Q)}return H}var QQ=100;class I1{#H=null;#J=null;get(H){if(this.#J&&this.#J.url===H&&this.#J.expire>Date.now())return this.#J.request}setLater(H,J,Q){this.clear(),this.#H=setTimeout(()=>{J.perform(),this.set(H,J,Q),this.#H=null},QQ)}set(H,J,Q){this.#J={url:H,request:J,expire:new Date(new Date().getTime()+Q)}}clear(){if(this.#H)clearTimeout(this.#H);this.#J=null}}var XQ=1e4,l=new I1,r={initialized:"initialized",requesting:"requesting",waiting:"waiting",receiving:"receiving",stopping:"stopping",stopped:"stopped"};class KH{state=r.initialized;static confirmMethod(H){return Promise.resolve(confirm(H))}constructor(H,J,Q,X=!1){let Y=AQ(J,Q),Z=WQ(GQ(J,Q),Y),U=YQ(J,Q),B=qQ(J,Q);this.delegate=H,this.formElement=J,this.submitter=Q,this.fetchRequest=new e(this,Y,Z,U,J,B),this.mustRedirect=X}get method(){return this.fetchRequest.method}set method(H){this.fetchRequest.method=H}get action(){return this.fetchRequest.url.toString()}set action(H){this.fetchRequest.url=V(H)}get body(){return this.fetchRequest.body}get enctype(){return this.fetchRequest.enctype}get isSafe(){return this.fetchRequest.isSafe}get location(){return this.fetchRequest.url}async start(){let{initialized:H,requesting:J}=r,Q=WH("data-turbo-confirm",this.submitter,this.formElement);if(typeof Q==="string"){if(!await(typeof T.forms.confirm==="function"?T.forms.confirm:KH.confirmMethod)(Q,this.formElement,this.submitter))return}if(this.state==H)return this.state=J,this.fetchRequest.perform()}stop(){let{stopping:H,stopped:J}=r;if(this.state!=H&&this.state!=J)return this.state=H,this.fetchRequest.cancel(),!0}prepareRequest(H){if(!H.isSafe){let J=ZQ(UH("csrf-param"))||UH("csrf-token");if(J)H.headers["X-CSRF-Token"]=J}if(this.requestAcceptsTurboStreamResponse(H))H.acceptResponseType(m.contentType)}requestStarted(H){if(this.state=r.waiting,this.submitter)T.forms.submitter.beforeSubmit(this.submitter);this.setSubmitsWith(),AH(this.formElement),C("turbo:submit-start",{target:this.formElement,detail:{formSubmission:this}}),this.delegate.formSubmissionStarted(this)}requestPreventedHandlingResponse(H,J){l.clear(),this.result={success:J.succeeded,fetchResponse:J}}requestSucceededWithResponse(H,J){if(J.clientError||J.serverError){this.delegate.formSubmissionFailedWithResponse(this,J);return}if(l.clear(),this.requestMustRedirect(H)&&$Q(J)){let Q=new Error("Form responses must redirect to another location");this.delegate.formSubmissionErrored(this,Q)}else this.state=r.receiving,this.result={success:!0,fetchResponse:J},this.delegate.formSubmissionSucceededWithResponse(this,J)}requestFailedWithResponse(H,J){this.result={success:!1,fetchResponse:J},this.delegate.formSubmissionFailedWithResponse(this,J)}requestErrored(H,J){this.result={success:!1,error:J},this.delegate.formSubmissionErrored(this,J)}requestFinished(H){if(this.state=r.stopped,this.submitter)T.forms.submitter.afterSubmit(this.submitter);this.resetSubmitterText(),qH(this.formElement),C("turbo:submit-end",{target:this.formElement,detail:{formSubmission:this,...this.result}}),this.delegate.formSubmissionFinished(this)}setSubmitsWith(){if(!this.submitter||!this.submitsWith)return;if(this.submitter.matches("button"))this.originalSubmitText=this.submitter.innerHTML,this.submitter.innerHTML=this.submitsWith;else if(this.submitter.matches("input")){let H=this.submitter;this.originalSubmitText=H.value,H.value=this.submitsWith}}resetSubmitterText(){if(!this.submitter||!this.originalSubmitText)return;if(this.submitter.matches("button"))this.submitter.innerHTML=this.originalSubmitText;else if(this.submitter.matches("input")){let H=this.submitter;H.value=this.originalSubmitText}}requestMustRedirect(H){return!H.isSafe&&this.mustRedirect}requestAcceptsTurboStreamResponse(H){return!H.isSafe||NJ("data-turbo-stream",this.submitter,this.formElement)}get submitsWith(){return this.submitter?.getAttribute("data-turbo-submits-with")}}function YQ(H,J){let Q=new FormData(H),X=J?.getAttribute("name"),Y=J?.getAttribute("value");if(X)Q.append(X,Y||"");return Q}function ZQ(H){if(H!=null){let Q=(document.cookie?document.cookie.split("; "):[]).find((X)=>X.startsWith(H));if(Q){let X=Q.split("=").slice(1).join("=");return X?decodeURIComponent(X):void 0}}}function $Q(H){return H.statusCode==200&&!H.redirected}function GQ(H,J){let Q=typeof H.action==="string"?H.action:null;if(J?.hasAttribute("formaction"))return J.getAttribute("formaction")||"";else return H.getAttribute("action")||Q||""}function WQ(H,J){let Q=V(H);if(RH(J))Q.search="";return Q}function AQ(H,J){let Q=J?.getAttribute("formmethod")||H.getAttribute("method")||"";return EH(Q.toLowerCase())||O.get}function qQ(H,J){return eJ(J?.getAttribute("formenctype")||H.enctype)}class QH{constructor(H){this.element=H}get activeElement(){return this.element.ownerDocument.activeElement}get children(){return[...this.element.children]}hasAnchor(H){return this.getElementForAnchor(H)!=null}getElementForAnchor(H){return H?this.element.querySelector(`[id='${H}'], a[name='${H}']`):null}get isConnected(){return this.element.isConnected}get firstAutofocusableElement(){return $1(this.element)}get permanentElements(){return M1(this.element)}getPermanentElementById(H){return F1(this.element,H)}getPermanentElementMapForSnapshot(H){let J={};for(let Q of this.permanentElements){let{id:X}=Q,Y=H.getPermanentElementById(X);if(Y)J[X]=[Q,Y]}return J}}function F1(H,J){return H.querySelector(`#${J}[data-turbo-permanent]`)}function M1(H){return H.querySelectorAll("[id][data-turbo-permanent]")}class BH{started=!1;constructor(H,J){this.delegate=H,this.eventTarget=J}start(){if(!this.started)this.eventTarget.addEventListener("submit",this.submitCaptured,!0),this.started=!0}stop(){if(this.started)this.eventTarget.removeEventListener("submit",this.submitCaptured,!0),this.started=!1}submitCaptured=()=>{this.eventTarget.removeEventListener("submit",this.submitBubbled,!1),this.eventTarget.addEventListener("submit",this.submitBubbled,!1)};submitBubbled=(H)=>{if(!H.defaultPrevented){let J=H.target instanceof HTMLFormElement?H.target:void 0,Q=H.submitter||void 0;if(J&&UQ(J,Q)&&zQ(J,Q)&&this.delegate.willSubmitForm(J,Q))H.preventDefault(),H.stopImmediatePropagation(),this.delegate.formSubmitted(J,Q)}}}function UQ(H,J){return(J?.getAttribute("formmethod")||H.getAttribute("method"))!="dialog"}function zQ(H,J){let Q=J?.getAttribute("formtarget")||H.getAttribute("target");return G1(Q)}class TH{#H=(H)=>{};#J=(H)=>{};constructor(H,J){this.delegate=H,this.element=J}scrollToAnchor(H){let J=this.snapshot.getElementForAnchor(H);if(J)this.scrollToElement(J),this.focusElement(J);else this.scrollToPosition({x:0,y:0})}scrollToAnchorFromLocation(H){this.scrollToAnchor(i(H))}scrollToElement(H){H.scrollIntoView()}focusElement(H){if(H instanceof HTMLElement)if(H.hasAttribute("tabindex"))H.focus();else H.setAttribute("tabindex","-1"),H.focus(),H.removeAttribute("tabindex")}scrollToPosition({x:H,y:J}){this.scrollRoot.scrollTo(H,J)}scrollToTop(){this.scrollToPosition({x:0,y:0})}get scrollRoot(){return window}async render(H){let{isPreview:J,shouldRender:Q,willRender:X,newSnapshot:Y}=H,Z=X;if(Q)try{this.renderPromise=new Promise((R)=>this.#H=R),this.renderer=H,await this.prepareToRenderSnapshot(H);let U=new Promise((R)=>this.#J=R),B={resume:this.#J,render:this.renderer.renderElement,renderMethod:this.renderer.renderMethod};if(!this.delegate.allowsImmediateRender(Y,B))await U;await this.renderSnapshot(H),this.delegate.viewRenderedSnapshot(Y,J,this.renderer.renderMethod),this.delegate.preloadOnLoadLinksForView(this.element),this.finishRenderingSnapshot(H)}finally{delete this.renderer,this.#H(void 0),delete this.renderPromise}else if(Z)this.invalidate(H.reloadReason)}invalidate(H){this.delegate.viewInvalidated(H)}async prepareToRenderSnapshot(H){this.markAsPreview(H.isPreview),await H.prepareToRender()}markAsPreview(H){if(H)this.element.setAttribute("data-turbo-preview","");else this.element.removeAttribute("data-turbo-preview")}markVisitDirection(H){this.element.setAttribute("data-turbo-visit-direction",H)}unmarkVisitDirection(){this.element.removeAttribute("data-turbo-visit-direction")}async renderSnapshot(H){await H.render()}finishRenderingSnapshot(H){H.finishRendering()}}class P1 extends TH{missing(){this.element.innerHTML='<strong class="turbo-frame-error">Content missing</strong>'}get snapshot(){return new QH(this.element)}}class VH{constructor(H,J){this.delegate=H,this.element=J}start(){this.element.addEventListener("click",this.clickBubbled),document.addEventListener("turbo:click",this.linkClicked),document.addEventListener("turbo:before-visit",this.willVisit)}stop(){this.element.removeEventListener("click",this.clickBubbled),document.removeEventListener("turbo:click",this.linkClicked),document.removeEventListener("turbo:before-visit",this.willVisit)}clickBubbled=(H)=>{if(this.clickEventIsSignificant(H))this.clickEvent=H;else delete this.clickEvent};linkClicked=(H)=>{if(this.clickEvent&&this.clickEventIsSignificant(H)){if(this.delegate.shouldInterceptLinkClick(H.target,H.detail.url,H.detail.originalEvent))this.clickEvent.preventDefault(),H.preventDefault(),this.delegate.linkClickIntercepted(H.target,H.detail.url,H.detail.originalEvent)}delete this.clickEvent};willVisit=(H)=>{delete this.clickEvent};clickEventIsSignificant(H){let J=H.composed?H.target?.parentElement:H.target,Q=W1(J)||J;return Q instanceof Element&&Q.closest("turbo-frame, html")==this.element}}class DH{started=!1;constructor(H,J){this.delegate=H,this.eventTarget=J}start(){if(!this.started)this.eventTarget.addEventListener("click",this.clickCaptured,!0),this.started=!0}stop(){if(this.started)this.eventTarget.removeEventListener("click",this.clickCaptured,!0),this.started=!1}clickCaptured=()=>{this.eventTarget.removeEventListener("click",this.clickBubbled,!1),this.eventTarget.addEventListener("click",this.clickBubbled,!1)};clickBubbled=(H)=>{if(H instanceof MouseEvent&&this.clickEventIsSignificant(H)){let J=H.composedPath&&H.composedPath()[0]||H.target,Q=W1(J);if(Q&&G1(Q.target)){let X=A1(Q);if(this.delegate.willFollowLinkToLocation(Q,X,H))H.preventDefault(),this.delegate.followedLinkToLocation(Q,X)}}};clickEventIsSignificant(H){return!(H.target&&H.target.isContentEditable||H.defaultPrevented||H.which>1||H.altKey||H.ctrlKey||H.metaKey||H.shiftKey)}}class OH{constructor(H,J){this.delegate=H,this.linkInterceptor=new DH(this,J)}start(){this.linkInterceptor.start()}stop(){this.linkInterceptor.stop()}canPrefetchRequestToLocation(H,J){return!1}prefetchAndCacheRequestToLocation(H,J){return}willFollowLinkToLocation(H,J,Q){return this.delegate.willSubmitFormLinkToLocation(H,J,Q)&&(H.hasAttribute("data-turbo-method")||H.hasAttribute("data-turbo-stream"))}followedLinkToLocation(H,J){let Q=document.createElement("form"),X="hidden";for(let[b,y]of J.searchParams)Q.append(Object.assign(document.createElement("input"),{type:"hidden",name:b,value:y}));let Y=Object.assign(J,{search:""});Q.setAttribute("data-turbo","true"),Q.setAttribute("action",Y.href),Q.setAttribute("hidden","");let Z=H.getAttribute("data-turbo-method");if(Z)Q.setAttribute("method",Z);let U=H.getAttribute("data-turbo-frame");if(U)Q.setAttribute("data-turbo-frame",U);let B=s(H);if(B)Q.setAttribute("data-turbo-action",B);let D=H.getAttribute("data-turbo-confirm");if(D)Q.setAttribute("data-turbo-confirm",D);if(H.hasAttribute("data-turbo-stream"))Q.setAttribute("data-turbo-stream","");this.delegate.submittedFormLinkToLocation(H,J,Q),document.body.appendChild(Q),Q.addEventListener("turbo:submit-end",()=>Q.remove(),{once:!0}),requestAnimationFrame(()=>Q.requestSubmit())}}class xH{static async preservingPermanentElements(H,J,Q){let X=new this(H,J);X.enter(),await Q(),X.leave()}constructor(H,J){this.delegate=H,this.permanentElementMap=J}enter(){for(let H in this.permanentElementMap){let[J,Q]=this.permanentElementMap[H];this.delegate.enteringBardo(J,Q),this.replaceNewPermanentElementWithPlaceholder(Q)}}leave(){for(let H in this.permanentElementMap){let[J]=this.permanentElementMap[H];this.replaceCurrentPermanentElementWithClone(J),this.replacePlaceholderWithPermanentElement(J),this.delegate.leavingBardo(J)}}replaceNewPermanentElementWithPlaceholder(H){let J=KQ(H);H.replaceWith(J)}replaceCurrentPermanentElementWithClone(H){let J=H.cloneNode(!0);H.replaceWith(J)}replacePlaceholderWithPermanentElement(H){this.getPlaceholderById(H.id)?.replaceWith(H)}getPlaceholderById(H){return this.placeholders.find((J)=>J.content==H)}get placeholders(){return[...document.querySelectorAll("meta[name=turbo-permanent-placeholder][content]")]}}function KQ(H){let J=document.createElement("meta");return J.setAttribute("name","turbo-permanent-placeholder"),J.setAttribute("content",H.id),J}class _H{#H=null;static renderElement(H,J){}constructor(H,J,Q,X=!0){this.currentSnapshot=H,this.newSnapshot=J,this.isPreview=Q,this.willRender=X,this.renderElement=this.constructor.renderElement,this.promise=new Promise((Y,Z)=>this.resolvingFunctions={resolve:Y,reject:Z})}get shouldRender(){return!0}get shouldAutofocus(){return!0}get reloadReason(){return}prepareToRender(){return}render(){}finishRendering(){if(this.resolvingFunctions)this.resolvingFunctions.resolve(),delete this.resolvingFunctions}async preservingPermanentElements(H){await xH.preservingPermanentElements(this,this.permanentElementMap,H)}focusFirstAutofocusableElement(){if(this.shouldAutofocus){let H=this.connectedSnapshot.firstAutofocusableElement;if(H)H.focus()}}enteringBardo(H){if(this.#H)return;if(H.contains(this.currentSnapshot.activeElement))this.#H=this.currentSnapshot.activeElement}leavingBardo(H){if(H.contains(this.#H)&&this.#H instanceof HTMLElement)this.#H.focus(),this.#H=null}get connectedSnapshot(){return this.newSnapshot.isConnected?this.newSnapshot:this.currentSnapshot}get currentElement(){return this.currentSnapshot.element}get newElement(){return this.newSnapshot.element}get permanentElementMap(){return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot)}get renderMethod(){return"replace"}}class IH extends _H{static renderElement(H,J){let Q=document.createRange();Q.selectNodeContents(H),Q.deleteContents();let X=J,Y=X.ownerDocument?.createRange();if(Y)Y.selectNodeContents(X),H.appendChild(Y.extractContents())}constructor(H,J,Q,X,Y,Z=!0){super(J,Q,X,Y,Z);this.delegate=H}get shouldRender(){return!0}async render(){await HH(),this.preservingPermanentElements(()=>{this.loadFrameElement()}),this.scrollFrameIntoView(),await HH(),this.focusFirstAutofocusableElement(),await HH(),this.activateScriptElements()}loadFrameElement(){this.delegate.willRenderFrame(this.currentElement,this.newElement),this.renderElement(this.currentElement,this.newElement)}scrollFrameIntoView(){if(this.currentElement.autoscroll||this.newElement.autoscroll){let H=this.currentElement.firstElementChild,J=BQ(this.currentElement.getAttribute("data-autoscroll-block"),"end"),Q=_Q(this.currentElement.getAttribute("data-autoscroll-behavior"),"auto");if(H)return H.scrollIntoView({block:J,behavior:Q}),!0}return!1}activateScriptElements(){for(let H of this.newScriptElements){let J=JH(H);H.replaceWith(J)}}get newScriptElements(){return this.currentElement.querySelectorAll("script")}}function BQ(H,J){if(H=="end"||H=="start"||H=="center"||H=="nearest")return H;else return J}function _Q(H,J){if(H=="auto"||H=="smooth")return H;else return J}var IQ=function(){let H=()=>{},J={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:H,afterNodeAdded:H,beforeNodeMorphed:H,afterNodeMorphed:H,beforeNodeRemoved:H,afterNodeRemoved:H,beforeAttributeUpdated:H},head:{style:"merge",shouldPreserve:(I)=>I.getAttribute("im-preserve")==="true",shouldReAppend:(I)=>I.getAttribute("im-re-append")==="true",shouldRemove:H,afterHeadMorphed:H},restoreFocus:!0};function Q(I,j,M={}){I=b(I);let L=y(j),P=R(I,L,M),_=Y(P,()=>{return B(P,I,L,(W)=>{if(W.morphStyle==="innerHTML")return Z(W,I,L),Array.from(I.childNodes);else return X(W,I,L)})});return P.pantry.remove(),_}function X(I,j,M){let L=y(j),P=Array.from(L.childNodes),_=P.indexOf(j),W=P.length-(_+1);return Z(I,L,M,j,j.nextSibling),P=Array.from(L.childNodes),P.slice(_,P.length-W)}function Y(I,j){if(!I.config.restoreFocus)return j();let M=document.activeElement;if(!(M instanceof HTMLInputElement||M instanceof HTMLTextAreaElement))return j();let{id:L,selectionStart:P,selectionEnd:_}=M,W=j();if(L&&L!==document.activeElement?.id)M=I.target.querySelector(`#${L}`),M?.focus();if(M&&!M.selectionEnd&&_)M.setSelectionRange(P,_);return W}let Z=function(){function I($,G,K,q=null,z=null){if(G instanceof HTMLTemplateElement&&K instanceof HTMLTemplateElement)G=G.content,K=K.content;q||=G.firstChild;for(let F of K.childNodes){if(q&&q!=z){let S=M($,F,q,z);if(S){if(S!==q)P($,q,S);U(S,F,$),q=S.nextSibling;continue}}if(F instanceof Element&&$.persistentIds.has(F.id)){let S=_(G,F.id,q,$);U(S,F,$),q=S.nextSibling;continue}let w=j(G,F,q,$);if(w)q=w.nextSibling}while(q&&q!=z){let F=q;q=q.nextSibling,L($,F)}}function j($,G,K,q){if(q.callbacks.beforeNodeAdded(G)===!1)return null;if(q.idMap.has(G)){let z=document.createElement(G.tagName);return $.insertBefore(z,K),U(z,G,q),q.callbacks.afterNodeAdded(z),z}else{let z=document.importNode(G,!0);return $.insertBefore(z,K),q.callbacks.afterNodeAdded(z),z}}let M=function(){function $(q,z,F,w){let S=null,o=z.nextSibling,iH=0,x=F;while(x&&x!=w){if(K(x,z)){if(G(q,x,z))return x;if(S===null){if(!q.idMap.has(x))S=x}}if(S===null&&o&&K(x,o)){if(iH++,o=o.nextSibling,iH>=2)S=void 0}if(x.contains(document.activeElement))break;x=x.nextSibling}return S||null}function G(q,z,F){let w=q.idMap.get(z),S=q.idMap.get(F);if(!S||!w)return!1;for(let o of w)if(S.has(o))return!0;return!1}function K(q,z){let F=q,w=z;return F.nodeType===w.nodeType&&F.tagName===w.tagName&&(!F.id||F.id===w.id)}return $}();function L($,G){if($.idMap.has(G))A($.pantry,G,null);else{if($.callbacks.beforeNodeRemoved(G)===!1)return;G.parentNode?.removeChild(G),$.callbacks.afterNodeRemoved(G)}}function P($,G,K){let q=G;while(q&&q!==K){let z=q;q=q.nextSibling,L($,z)}return q}function _($,G,K,q){let z=q.target.querySelector(`#${G}`)||q.pantry.querySelector(`#${G}`);return W(z,q),A($,z,K),z}function W($,G){let K=$.id;while($=$.parentNode){let q=G.idMap.get($);if(q){if(q.delete(K),!q.size)G.idMap.delete($)}}}function A($,G,K){if($.moveBefore)try{$.moveBefore(G,K)}catch(q){$.insertBefore(G,K)}else $.insertBefore(G,K)}return I}(),U=function(){function I(W,A,$){if($.ignoreActive&&W===document.activeElement)return null;if($.callbacks.beforeNodeMorphed(W,A)===!1)return W;if(W instanceof HTMLHeadElement&&$.head.ignore);else if(W instanceof HTMLHeadElement&&$.head.style!=="morph")D(W,A,$);else if(j(W,A,$),!_(W,$))Z($,W,A);return $.callbacks.afterNodeMorphed(W,A),W}function j(W,A,$){let G=A.nodeType;if(G===1){let K=W,q=A,z=K.attributes,F=q.attributes;for(let w of F){if(P(w.name,K,"update",$))continue;if(K.getAttribute(w.name)!==w.value)K.setAttribute(w.name,w.value)}for(let w=z.length-1;0<=w;w--){let S=z[w];if(!S)continue;if(!q.hasAttribute(S.name)){if(P(S.name,K,"remove",$))continue;K.removeAttribute(S.name)}}if(!_(K,$))M(K,q,$)}if(G===8||G===3){if(W.nodeValue!==A.nodeValue)W.nodeValue=A.nodeValue}}function M(W,A,$){if(W instanceof HTMLInputElement&&A instanceof HTMLInputElement&&A.type!=="file"){let G=A.value,K=W.value;if(L(W,A,"checked",$),L(W,A,"disabled",$),!A.hasAttribute("value")){if(!P("value",W,"remove",$))W.value="",W.removeAttribute("value")}else if(K!==G){if(!P("value",W,"update",$))W.setAttribute("value",G),W.value=G}}else if(W instanceof HTMLOptionElement&&A instanceof HTMLOptionElement)L(W,A,"selected",$);else if(W instanceof HTMLTextAreaElement&&A instanceof HTMLTextAreaElement){let G=A.value,K=W.value;if(P("value",W,"update",$))return;if(G!==K)W.value=G;if(W.firstChild&&W.firstChild.nodeValue!==G)W.firstChild.nodeValue=G}}function L(W,A,$,G){let K=A[$],q=W[$];if(K!==q){let z=P($,W,"update",G);if(!z)W[$]=A[$];if(K){if(!z)W.setAttribute($,"")}else if(!P($,W,"remove",G))W.removeAttribute($)}}function P(W,A,$,G){if(W==="value"&&G.ignoreActiveValue&&A===document.activeElement)return!0;return G.callbacks.beforeAttributeUpdated(W,A,$)===!1}function _(W,A){return!!A.ignoreActiveValue&&W===document.activeElement&&W!==document.body}return I}();function B(I,j,M,L){if(I.head.block){let P=j.querySelector("head"),_=M.querySelector("head");if(P&&_){let W=D(P,_,I);return Promise.all(W).then(()=>{let A=Object.assign(I,{head:{block:!1,ignore:!0}});return L(A)})}}return L(I)}function D(I,j,M){let L=[],P=[],_=[],W=[],A=new Map;for(let G of j.children)A.set(G.outerHTML,G);for(let G of I.children){let K=A.has(G.outerHTML),q=M.head.shouldReAppend(G),z=M.head.shouldPreserve(G);if(K||z)if(q)P.push(G);else A.delete(G.outerHTML),_.push(G);else if(M.head.style==="append"){if(q)P.push(G),W.push(G)}else if(M.head.shouldRemove(G)!==!1)P.push(G)}W.push(...A.values());let $=[];for(let G of W){let K=document.createRange().createContextualFragment(G.outerHTML).firstChild;if(M.callbacks.beforeNodeAdded(K)!==!1){if("href"in K&&K.href||"src"in K&&K.src){let q,z=new Promise(function(F){q=F});K.addEventListener("load",function(){q()}),$.push(z)}I.appendChild(K),M.callbacks.afterNodeAdded(K),L.push(K)}}for(let G of P)if(M.callbacks.beforeNodeRemoved(G)!==!1)I.removeChild(G),M.callbacks.afterNodeRemoved(G);return M.head.afterHeadMorphed(I,{added:L,kept:_,removed:P}),$}let R=function(){function I(A,$,G){let{persistentIds:K,idMap:q}=_(A,$),z=j(G),F=z.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(F))throw`Do not understand how to morph style ${F}`;return{target:A,newContent:$,config:z,morphStyle:F,ignoreActive:z.ignoreActive,ignoreActiveValue:z.ignoreActiveValue,restoreFocus:z.restoreFocus,idMap:q,persistentIds:K,pantry:M(),callbacks:z.callbacks,head:z.head}}function j(A){let $=Object.assign({},J);return Object.assign($,A),$.callbacks=Object.assign({},J.callbacks,A.callbacks),$.head=Object.assign({},J.head,A.head),$}function M(){let A=document.createElement("div");return A.hidden=!0,document.body.insertAdjacentElement("afterend",A),A}function L(A){let $=Array.from(A.querySelectorAll("[id]"));if(A.id)$.push(A);return $}function P(A,$,G,K){for(let q of K)if($.has(q.id)){let z=q;while(z){let F=A.get(z);if(F==null)F=new Set,A.set(z,F);if(F.add(q.id),z===G)break;z=z.parentElement}}}function _(A,$){let G=L(A),K=L($),q=W(G,K),z=new Map;P(z,q,A,G);let F=$.__idiomorphRoot||$;return P(z,q,F,K),{persistentIds:q,idMap:z}}function W(A,$){let G=new Set,K=new Map;for(let{id:z,tagName:F}of A)if(K.has(z))G.add(z);else K.set(z,F);let q=new Set;for(let{id:z,tagName:F}of $)if(q.has(z))G.add(z);else if(K.get(z)===F)q.add(z);for(let z of G)q.delete(z);return q}return I}(),{normalizeElement:b,normalizeParent:y}=function(){let I=new WeakSet;function j(_){if(_ instanceof Document)return _.documentElement;else return _}function M(_){if(_==null)return document.createElement("div");else if(typeof _==="string")return M(P(_));else if(I.has(_))return _;else if(_ instanceof Node)if(_.parentNode)return L(_);else{let W=document.createElement("div");return W.append(_),W}else{let W=document.createElement("div");for(let A of[..._])W.append(A);return W}}function L(_){return{childNodes:[_],querySelectorAll:(W)=>{let A=_.querySelectorAll(W);return _.matches(W)?[_,...A]:A},insertBefore:(W,A)=>_.parentNode.insertBefore(W,A),moveBefore:(W,A)=>_.parentNode.moveBefore(W,A),get __idiomorphRoot(){return _}}}function P(_){let W=new DOMParser,A=_.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(A.match(/<\/html>/)||A.match(/<\/head>/)||A.match(/<\/body>/)){let $=W.parseFromString(_,"text/html");if(A.match(/<\/html>/))return I.add($),$;else{let G=$.firstChild;if(G)I.add(G);return G}}else{let G=W.parseFromString("<body><template>"+_+"</template></body>","text/html").body.querySelector("template").content;return I.add(G),G}}return{normalizeElement:j,normalizeParent:M}}();return{morph:Q,defaults:J}}();function hH(H,J,{callbacks:Q,...X}={}){IQ.morph(H,J,{...X,callbacks:new j1(Q)})}function L1(H,J){hH(H,J.childNodes,{morphStyle:"innerHTML"})}class j1{#H;constructor({beforeNodeMorphed:H}={}){this.#H=H||(()=>!0)}beforeNodeAdded=(H)=>{return!(H.id&&H.hasAttribute("data-turbo-permanent")&&document.getElementById(H.id))};beforeNodeMorphed=(H,J)=>{if(H instanceof Element)if(!H.hasAttribute("data-turbo-permanent")&&this.#H(H,J))return!C("turbo:before-morph-element",{cancelable:!0,target:H,detail:{currentElement:H,newElement:J}}).defaultPrevented;else return!1};beforeAttributeUpdated=(H,J,Q)=>{return!C("turbo:before-morph-attribute",{cancelable:!0,target:J,detail:{attributeName:H,mutationType:Q}}).defaultPrevented};beforeNodeRemoved=(H)=>{return this.beforeNodeMorphed(H)};afterNodeMorphed=(H,J)=>{if(H instanceof Element)C("turbo:morph-element",{target:H,detail:{currentElement:H,newElement:J}})}}class C1 extends IH{static renderElement(H,J){C("turbo:before-frame-morph",{target:H,detail:{currentElement:H,newElement:J}}),L1(H,J)}async preservingPermanentElements(H){return await H()}}class f{static animationDuration=300;static get defaultCSS(){return X1`
7
+ .turbo-progress-bar {
8
+ position: fixed;
9
+ display: block;
10
+ top: 0;
11
+ left: 0;
12
+ height: 3px;
13
+ background: #0076ff;
14
+ z-index: 2147483647;
15
+ transition:
16
+ width ${f.animationDuration}ms ease-out,
17
+ opacity ${f.animationDuration/2}ms ${f.animationDuration/2}ms ease-in;
18
+ transform: translate3d(0, 0, 0);
19
+ }
20
+ `}hiding=!1;value=0;visible=!1;constructor(){this.stylesheetElement=this.createStylesheetElement(),this.progressElement=this.createProgressElement(),this.installStylesheetElement(),this.setValue(0)}show(){if(!this.visible)this.visible=!0,this.installProgressElement(),this.startTrickling()}hide(){if(this.visible&&!this.hiding)this.hiding=!0,this.fadeProgressElement(()=>{this.uninstallProgressElement(),this.stopTrickling(),this.visible=!1,this.hiding=!1})}setValue(H){this.value=H,this.refresh()}installStylesheetElement(){document.head.insertBefore(this.stylesheetElement,document.head.firstChild)}installProgressElement(){this.progressElement.style.width="0",this.progressElement.style.opacity="1",document.documentElement.insertBefore(this.progressElement,document.body),this.refresh()}fadeProgressElement(H){this.progressElement.style.opacity="0",setTimeout(H,f.animationDuration*1.5)}uninstallProgressElement(){if(this.progressElement.parentNode)document.documentElement.removeChild(this.progressElement)}startTrickling(){if(!this.trickleInterval)this.trickleInterval=window.setInterval(this.trickle,f.animationDuration)}stopTrickling(){window.clearInterval(this.trickleInterval),delete this.trickleInterval}trickle=()=>{this.setValue(this.value+Math.random()/100)};refresh(){requestAnimationFrame(()=>{this.progressElement.style.width=`${10+this.value*90}%`})}createStylesheetElement(){let H=document.createElement("style");H.type="text/css",H.textContent=f.defaultCSS;let J=Z1();if(J)H.nonce=J;return H}createProgressElement(){let H=document.createElement("div");return H.className="turbo-progress-bar",H}}class S1 extends QH{detailsByOuterHTML=this.children.filter((H)=>!LQ(H)).map((H)=>SQ(H)).reduce((H,J)=>{let{outerHTML:Q}=J,X=Q in H?H[Q]:{type:FQ(J),tracked:MQ(J),elements:[]};return{...H,[Q]:{...X,elements:[...X.elements,J]}}},{});get trackedElementSignature(){return Object.keys(this.detailsByOuterHTML).filter((H)=>this.detailsByOuterHTML[H].tracked).join("")}getScriptElementsNotInSnapshot(H){return this.getElementsMatchingTypeNotInSnapshot("script",H)}getStylesheetElementsNotInSnapshot(H){return this.getElementsMatchingTypeNotInSnapshot("stylesheet",H)}getElementsMatchingTypeNotInSnapshot(H,J){return Object.keys(this.detailsByOuterHTML).filter((Q)=>!(Q in J.detailsByOuterHTML)).map((Q)=>this.detailsByOuterHTML[Q]).filter(({type:Q})=>Q==H).map(({elements:[Q]})=>Q)}get provisionalElements(){return Object.keys(this.detailsByOuterHTML).reduce((H,J)=>{let{type:Q,tracked:X,elements:Y}=this.detailsByOuterHTML[J];if(Q==null&&!X)return[...H,...Y];else if(Y.length>1)return[...H,...Y.slice(1)];else return H},[])}getMetaValue(H){let J=this.findMetaElementByName(H);return J?J.getAttribute("content"):null}findMetaElementByName(H){return Object.keys(this.detailsByOuterHTML).reduce((J,Q)=>{let{elements:[X]}=this.detailsByOuterHTML[Q];return CQ(X,H)?X:J},void 0|void 0)}}function FQ(H){if(PQ(H))return"script";else if(jQ(H))return"stylesheet"}function MQ(H){return H.getAttribute("data-turbo-track")=="reload"}function PQ(H){return H.localName=="script"}function LQ(H){return H.localName=="noscript"}function jQ(H){let J=H.localName;return J=="style"||J=="link"&&H.getAttribute("rel")=="stylesheet"}function CQ(H,J){return H.localName=="meta"&&H.getAttribute("name")==J}function SQ(H){if(H.hasAttribute("nonce"))H.setAttribute("nonce","");return H}class h extends QH{static fromHTMLString(H=""){return this.fromDocument(Q1(H))}static fromElement(H){return this.fromDocument(H.ownerDocument)}static fromDocument({documentElement:H,body:J,head:Q}){return new this(H,J,new S1(Q))}constructor(H,J,Q){super(J);this.documentElement=H,this.headSnapshot=Q}clone(){let H=this.element.cloneNode(!0),J=this.element.querySelectorAll("select"),Q=H.querySelectorAll("select");for(let[X,Y]of J.entries()){let Z=Q[X];for(let U of Z.selectedOptions)U.selected=!1;for(let U of Y.selectedOptions)Z.options[U.index].selected=!0}for(let X of H.querySelectorAll('input[type="password"]'))X.value="";return new h(this.documentElement,H,this.headSnapshot)}get lang(){return this.documentElement.getAttribute("lang")}get headElement(){return this.headSnapshot.element}get rootLocation(){let H=this.getSetting("root")??"/";return V(H)}get cacheControlValue(){return this.getSetting("cache-control")}get isPreviewable(){return this.cacheControlValue!="no-preview"}get isCacheable(){return this.cacheControlValue!="no-cache"}get isVisitable(){return this.getSetting("visit-control")!="reload"}get prefersViewTransitions(){return this.headSnapshot.getMetaValue("view-transition")==="same-origin"}get shouldMorphPage(){return this.getSetting("refresh-method")==="morph"}get shouldPreserveScrollPosition(){return this.getSetting("refresh-scroll")==="preserve"}getSetting(H){return this.headSnapshot.getMetaValue(`turbo-${H}`)}}class w1{#H=!1;#J=Promise.resolve();renderChange(H,J){if(H&&this.viewTransitionsAvailable&&!this.#H)this.#H=!0,this.#J=this.#J.then(async()=>{await document.startViewTransition(J).finished});else this.#J=this.#J.then(J);return this.#J}get viewTransitionsAvailable(){return document.startViewTransition}}var wQ={action:"advance",historyChanged:!1,visitCachedSnapshot:()=>{},willRender:!0,updateHistory:!0,shouldCacheSnapshot:!0,acceptsStreamResponse:!1},GH={visitStart:"visitStart",requestStart:"requestStart",requestEnd:"requestEnd",visitEnd:"visitEnd"},k={initialized:"initialized",started:"started",canceled:"canceled",failed:"failed",completed:"completed"},t={networkFailure:0,timeoutFailure:-1,contentTypeMismatch:-2},EQ={advance:"forward",restore:"back",replace:"none"};class E1{identifier=p();timingMetrics={};followedRedirect=!1;historyChanged=!1;scrolled=!1;shouldCacheSnapshot=!0;acceptsStreamResponse=!1;snapshotCached=!1;state=k.initialized;viewTransitioner=new w1;constructor(H,J,Q,X={}){this.delegate=H,this.location=J,this.restorationIdentifier=Q||p();let{action:Y,historyChanged:Z,referrer:U,snapshot:B,snapshotHTML:D,response:R,visitCachedSnapshot:b,willRender:y,updateHistory:I,shouldCacheSnapshot:j,acceptsStreamResponse:M,direction:L}={...wQ,...X};this.action=Y,this.historyChanged=Z,this.referrer=U,this.snapshot=B,this.snapshotHTML=D,this.response=R,this.isSamePage=this.delegate.locationWithActionIsSamePage(this.location,this.action),this.isPageRefresh=this.view.isPageRefresh(this),this.visitCachedSnapshot=b,this.willRender=y,this.updateHistory=I,this.scrolled=!y,this.shouldCacheSnapshot=j,this.acceptsStreamResponse=M,this.direction=L||EQ[Y]}get adapter(){return this.delegate.adapter}get view(){return this.delegate.view}get history(){return this.delegate.history}get restorationData(){return this.history.getRestorationDataForIdentifier(this.restorationIdentifier)}get silent(){return this.isSamePage}start(){if(this.state==k.initialized)this.recordTimingMetric(GH.visitStart),this.state=k.started,this.adapter.visitStarted(this),this.delegate.visitStarted(this)}cancel(){if(this.state==k.started){if(this.request)this.request.cancel();this.cancelRender(),this.state=k.canceled}}complete(){if(this.state==k.started){if(this.recordTimingMetric(GH.visitEnd),this.adapter.visitCompleted(this),this.state=k.completed,this.followRedirect(),!this.followedRedirect)this.delegate.visitCompleted(this)}}fail(){if(this.state==k.started)this.state=k.failed,this.adapter.visitFailed(this),this.delegate.visitCompleted(this)}changeHistory(){if(!this.historyChanged&&this.updateHistory){let H=this.location.href===this.referrer?.href?"replace":this.action,J=Y1(H);this.history.update(J,this.location,this.restorationIdentifier),this.historyChanged=!0}}issueRequest(){if(this.hasPreloadedResponse())this.simulateRequest();else if(this.shouldIssueRequest()&&!this.request)this.request=new e(this,O.get,this.location),this.request.perform()}simulateRequest(){if(this.response)this.startRequest(),this.recordResponse(),this.finishRequest()}startRequest(){this.recordTimingMetric(GH.requestStart),this.adapter.visitRequestStarted(this)}recordResponse(H=this.response){if(this.response=H,H){let{statusCode:J}=H;if(rH(J))this.adapter.visitRequestCompleted(this);else this.adapter.visitRequestFailedWithStatusCode(this,J)}}finishRequest(){this.recordTimingMetric(GH.requestEnd),this.adapter.visitRequestFinished(this)}loadResponse(){if(this.response){let{statusCode:H,responseHTML:J}=this.response;this.render(async()=>{if(this.shouldCacheSnapshot)this.cacheSnapshot();if(this.view.renderPromise)await this.view.renderPromise;if(rH(H)&&J!=null){let Q=h.fromHTMLString(J);await this.renderPageSnapshot(Q,!1),this.adapter.visitRendered(this),this.complete()}else await this.view.renderError(h.fromHTMLString(J),this),this.adapter.visitRendered(this),this.fail()})}}getCachedSnapshot(){let H=this.view.getCachedSnapshotForLocation(this.location)||this.getPreloadedSnapshot();if(H&&(!i(this.location)||H.hasAnchor(i(this.location)))){if(this.action=="restore"||H.isPreviewable)return H}}getPreloadedSnapshot(){if(this.snapshotHTML)return h.fromHTMLString(this.snapshotHTML)}hasCachedSnapshot(){return this.getCachedSnapshot()!=null}loadCachedSnapshot(){let H=this.getCachedSnapshot();if(H){let J=this.shouldIssueRequest();this.render(async()=>{if(this.cacheSnapshot(),this.isSamePage||this.isPageRefresh)this.adapter.visitRendered(this);else{if(this.view.renderPromise)await this.view.renderPromise;if(await this.renderPageSnapshot(H,J),this.adapter.visitRendered(this),!J)this.complete()}})}}followRedirect(){if(this.redirectedToLocation&&!this.followedRedirect&&this.response?.redirected)this.adapter.visitProposedToLocation(this.redirectedToLocation,{action:"replace",response:this.response,shouldCacheSnapshot:!1,willRender:!1}),this.followedRedirect=!0}goToSamePageAnchor(){if(this.isSamePage)this.render(async()=>{this.cacheSnapshot(),this.performScroll(),this.changeHistory(),this.adapter.visitRendered(this)})}prepareRequest(H){if(this.acceptsStreamResponse)H.acceptResponseType(m.contentType)}requestStarted(){this.startRequest()}requestPreventedHandlingResponse(H,J){}async requestSucceededWithResponse(H,J){let Q=await J.responseHTML,{redirected:X,statusCode:Y}=J;if(Q==null)this.recordResponse({statusCode:t.contentTypeMismatch,redirected:X});else this.redirectedToLocation=J.redirected?J.location:void 0,this.recordResponse({statusCode:Y,responseHTML:Q,redirected:X})}async requestFailedWithResponse(H,J){let Q=await J.responseHTML,{redirected:X,statusCode:Y}=J;if(Q==null)this.recordResponse({statusCode:t.contentTypeMismatch,redirected:X});else this.recordResponse({statusCode:Y,responseHTML:Q,redirected:X})}requestErrored(H,J){this.recordResponse({statusCode:t.networkFailure,redirected:!1})}requestFinished(){this.finishRequest()}performScroll(){if(!this.scrolled&&!this.view.forceReloaded&&!this.view.shouldPreserveScrollPosition(this)){if(this.action=="restore")this.scrollToRestoredPosition()||this.scrollToAnchor()||this.view.scrollToTop();else this.scrollToAnchor()||this.view.scrollToTop();if(this.isSamePage)this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation,this.location);this.scrolled=!0}}scrollToRestoredPosition(){let{scrollPosition:H}=this.restorationData;if(H)return this.view.scrollToPosition(H),!0}scrollToAnchor(){let H=i(this.location);if(H!=null)return this.view.scrollToAnchor(H),!0}recordTimingMetric(H){this.timingMetrics[H]=new Date().getTime()}getTimingMetrics(){return{...this.timingMetrics}}hasPreloadedResponse(){return typeof this.response=="object"}shouldIssueRequest(){if(this.isSamePage)return!1;else if(this.action=="restore")return!this.hasCachedSnapshot();else return this.willRender}cacheSnapshot(){if(!this.snapshotCached)this.view.cacheSnapshot(this.snapshot).then((H)=>H&&this.visitCachedSnapshot(H)),this.snapshotCached=!0}async render(H){this.cancelRender(),await new Promise((J)=>{this.frame=document.visibilityState==="hidden"?setTimeout(()=>J(),0):requestAnimationFrame(()=>J())}),await H(),delete this.frame}async renderPageSnapshot(H,J){await this.viewTransitioner.renderChange(this.view.shouldTransitionTo(H),async()=>{await this.view.renderPage(H,J,this.willRender,this),this.performScroll()})}cancelRender(){if(this.frame)cancelAnimationFrame(this.frame),delete this.frame}}function rH(H){return H>=200&&H<300}class R1{progressBar=new f;constructor(H){this.session=H}visitProposedToLocation(H,J){if(v(H,this.navigator.rootLocation))this.navigator.startVisit(H,J?.restorationIdentifier||p(),J);else window.location.href=H.toString()}visitStarted(H){this.location=H.location,H.loadCachedSnapshot(),H.issueRequest(),H.goToSamePageAnchor()}visitRequestStarted(H){if(this.progressBar.setValue(0),H.hasCachedSnapshot()||H.action!="restore")this.showVisitProgressBarAfterDelay();else this.showProgressBar()}visitRequestCompleted(H){H.loadResponse()}visitRequestFailedWithStatusCode(H,J){switch(J){case t.networkFailure:case t.timeoutFailure:case t.contentTypeMismatch:return this.reload({reason:"request_failed",context:{statusCode:J}});default:return H.loadResponse()}}visitRequestFinished(H){}visitCompleted(H){this.progressBar.setValue(1),this.hideVisitProgressBar()}pageInvalidated(H){this.reload(H)}visitFailed(H){this.progressBar.setValue(1),this.hideVisitProgressBar()}visitRendered(H){}linkPrefetchingIsEnabledForLocation(H){return!0}formSubmissionStarted(H){this.progressBar.setValue(0),this.showFormProgressBarAfterDelay()}formSubmissionFinished(H){this.progressBar.setValue(1),this.hideFormProgressBar()}showVisitProgressBarAfterDelay(){this.visitProgressBarTimeout=window.setTimeout(this.showProgressBar,this.session.progressBarDelay)}hideVisitProgressBar(){if(this.progressBar.hide(),this.visitProgressBarTimeout!=null)window.clearTimeout(this.visitProgressBarTimeout),delete this.visitProgressBarTimeout}showFormProgressBarAfterDelay(){if(this.formProgressBarTimeout==null)this.formProgressBarTimeout=window.setTimeout(this.showProgressBar,this.session.progressBarDelay)}hideFormProgressBar(){if(this.progressBar.hide(),this.formProgressBarTimeout!=null)window.clearTimeout(this.formProgressBarTimeout),delete this.formProgressBarTimeout}showProgressBar=()=>{this.progressBar.show()};reload(H){C("turbo:reload",{detail:H}),window.location.href=this.location?.toString()||window.location.href}get navigator(){return this.session.navigator}}class T1{selector="[data-turbo-temporary]";deprecatedSelector="[data-turbo-cache=false]";started=!1;start(){if(!this.started)this.started=!0,addEventListener("turbo:before-cache",this.removeTemporaryElements,!1)}stop(){if(this.started)this.started=!1,removeEventListener("turbo:before-cache",this.removeTemporaryElements,!1)}removeTemporaryElements=(H)=>{for(let J of this.temporaryElements)J.remove()};get temporaryElements(){return[...document.querySelectorAll(this.selector),...this.temporaryElementsWithDeprecation]}get temporaryElementsWithDeprecation(){let H=document.querySelectorAll(this.deprecatedSelector);if(H.length)console.warn(`The ${this.deprecatedSelector} selector is deprecated and will be removed in a future version. Use ${this.selector} instead.`);return[...H]}}class V1{constructor(H,J){this.session=H,this.element=J,this.linkInterceptor=new VH(this,J),this.formSubmitObserver=new BH(this,J)}start(){this.linkInterceptor.start(),this.formSubmitObserver.start()}stop(){this.linkInterceptor.stop(),this.formSubmitObserver.stop()}shouldInterceptLinkClick(H,J,Q){return this.#J(H)}linkClickIntercepted(H,J,Q){let X=this.#Q(H);if(X)X.delegate.linkClickIntercepted(H,J,Q)}willSubmitForm(H,J){return H.closest("turbo-frame")==null&&this.#H(H,J)&&this.#J(H,J)}formSubmitted(H,J){let Q=this.#Q(H,J);if(Q)Q.delegate.formSubmitted(H,J)}#H(H,J){let Q=wH(H,J),X=this.element.ownerDocument.querySelector('meta[name="turbo-root"]'),Y=V(X?.content??"/");return this.#J(H,J)&&v(Q,Y)}#J(H,J){if(H instanceof HTMLFormElement?this.session.submissionIsNavigatable(H,J):this.session.elementIsNavigatable(H)){let X=this.#Q(H,J);return X?X!=H.closest("turbo-frame"):!1}else return!1}#Q(H,J){let Q=J?.getAttribute("data-turbo-frame")||H.getAttribute("data-turbo-frame");if(Q&&Q!="_top"){let X=this.element.querySelector(`#${Q}:not([disabled])`);if(X instanceof g)return X}}}class D1{location;restorationIdentifier=p();restorationData={};started=!1;pageLoaded=!1;currentIndex=0;constructor(H){this.delegate=H}start(){if(!this.started)addEventListener("popstate",this.onPopState,!1),addEventListener("load",this.onPageLoad,!1),this.currentIndex=history.state?.turbo?.restorationIndex||0,this.started=!0,this.replace(new URL(window.location.href))}stop(){if(this.started)removeEventListener("popstate",this.onPopState,!1),removeEventListener("load",this.onPageLoad,!1),this.started=!1}push(H,J){this.update(history.pushState,H,J)}replace(H,J){this.update(history.replaceState,H,J)}update(H,J,Q=p()){if(H===history.pushState)++this.currentIndex;let X={turbo:{restorationIdentifier:Q,restorationIndex:this.currentIndex}};H.call(history,X,"",J.href),this.location=J,this.restorationIdentifier=Q}getRestorationDataForIdentifier(H){return this.restorationData[H]||{}}updateRestorationData(H){let{restorationIdentifier:J}=this,Q=this.restorationData[J];this.restorationData[J]={...Q,...H}}assumeControlOfScrollRestoration(){if(!this.previousScrollRestoration)this.previousScrollRestoration=history.scrollRestoration??"auto",history.scrollRestoration="manual"}relinquishControlOfScrollRestoration(){if(this.previousScrollRestoration)history.scrollRestoration=this.previousScrollRestoration,delete this.previousScrollRestoration}onPopState=(H)=>{if(this.shouldHandlePopState()){let{turbo:J}=H.state||{};if(J){this.location=new URL(window.location.href);let{restorationIdentifier:Q,restorationIndex:X}=J;this.restorationIdentifier=Q;let Y=X>this.currentIndex?"forward":"back";this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location,Q,Y),this.currentIndex=X}}};onPageLoad=async(H)=>{await yJ(),this.pageLoaded=!0};shouldHandlePopState(){return this.pageIsLoaded()}pageIsLoaded(){return this.pageLoaded||document.readyState=="complete"}}class O1{started=!1;#H=null;constructor(H,J){this.delegate=H,this.eventTarget=J}start(){if(this.started)return;if(this.eventTarget.readyState==="loading")this.eventTarget.addEventListener("DOMContentLoaded",this.#J,{once:!0});else this.#J()}stop(){if(!this.started)return;this.eventTarget.removeEventListener("mouseenter",this.#Q,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("mouseleave",this.#Z,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("turbo:before-fetch-request",this.#Y,!0),this.started=!1}#J=()=>{this.eventTarget.addEventListener("mouseenter",this.#Q,{capture:!0,passive:!0}),this.eventTarget.addEventListener("mouseleave",this.#Z,{capture:!0,passive:!0}),this.eventTarget.addEventListener("turbo:before-fetch-request",this.#Y,!0),this.started=!0};#Q=(H)=>{if(UH("turbo-prefetch")==="false")return;let J=H.target;if(J.matches&&J.matches("a[href]:not([target^=_]):not([download])")&&this.#W(J)){let X=J,Y=A1(X);if(this.delegate.canPrefetchRequestToLocation(X,Y)){this.#H=X;let Z=new e(this,O.get,Y,new URLSearchParams,J);l.setLater(Y.toString(),Z,this.#X)}}};#Z=(H)=>{if(H.target===this.#H)this.#$()};#$=()=>{l.clear(),this.#H=null};#Y=(H)=>{if(H.target.tagName!=="FORM"&&H.detail.fetchOptions.method==="GET"){let J=l.get(H.detail.url.toString());if(J)H.detail.fetchRequest=J;l.clear()}};prepareRequest(H){let J=H.target;H.headers["X-Sec-Purpose"]="prefetch";let Q=J.closest("turbo-frame"),X=J.getAttribute("data-turbo-frame")||Q?.getAttribute("target")||Q?.id;if(X&&X!=="_top")H.headers["Turbo-Frame"]=X}requestSucceededWithResponse(){}requestStarted(H){}requestErrored(H){}requestFinished(H){}requestPreventedHandlingResponse(H,J){}requestFailedWithResponse(H,J){}get#X(){return Number(UH("turbo-prefetch-cache-time"))||XQ}#W(H){if(!H.getAttribute("href"))return!1;if(RQ(H))return!1;if(TQ(H))return!1;if(VQ(H))return!1;if(DQ(H))return!1;if(xQ(H))return!1;return!0}}var RQ=(H)=>{return H.origin!==document.location.origin||!["http:","https:"].includes(H.protocol)||H.hasAttribute("target")},TQ=(H)=>{return H.pathname+H.search===document.location.pathname+document.location.search||H.href.startsWith("#")},VQ=(H)=>{if(H.getAttribute("data-turbo-prefetch")==="false")return!0;if(H.getAttribute("data-turbo")==="false")return!0;let J=n(H,"[data-turbo-prefetch]");if(J&&J.getAttribute("data-turbo-prefetch")==="false")return!0;return!1},DQ=(H)=>{let J=H.getAttribute("data-turbo-method");if(J&&J.toLowerCase()!=="get")return!0;if(OQ(H))return!0;if(H.hasAttribute("data-turbo-confirm"))return!0;if(H.hasAttribute("data-turbo-stream"))return!0;return!1},OQ=(H)=>{return H.hasAttribute("data-remote")||H.hasAttribute("data-behavior")||H.hasAttribute("data-confirm")||H.hasAttribute("data-method")},xQ=(H)=>{return C("turbo:before-prefetch",{target:H,cancelable:!0}).defaultPrevented};class x1{constructor(H){this.delegate=H}proposeVisit(H,J={}){if(this.delegate.allowsVisitingLocationWithAction(H,J.action))this.delegate.visitProposedToLocation(H,J)}startVisit(H,J,Q={}){this.stop(),this.currentVisit=new E1(this,V(H),J,{referrer:this.location,...Q}),this.currentVisit.start()}submitForm(H,J){this.stop(),this.formSubmission=new KH(this,H,J,!0),this.formSubmission.start()}stop(){if(this.formSubmission)this.formSubmission.stop(),delete this.formSubmission;if(this.currentVisit)this.currentVisit.cancel(),delete this.currentVisit}get adapter(){return this.delegate.adapter}get view(){return this.delegate.view}get rootLocation(){return this.view.snapshot.rootLocation}get history(){return this.delegate.history}formSubmissionStarted(H){if(typeof this.adapter.formSubmissionStarted==="function")this.adapter.formSubmissionStarted(H)}async formSubmissionSucceededWithResponse(H,J){if(H==this.formSubmission){let Q=await J.responseHTML;if(Q){let X=H.isSafe;if(!X)this.view.clearSnapshotCache();let{statusCode:Y,redirected:Z}=J,B={action:this.#H(H,J),shouldCacheSnapshot:X,response:{statusCode:Y,responseHTML:Q,redirected:Z}};this.proposeVisit(J.location,B)}}}async formSubmissionFailedWithResponse(H,J){let Q=await J.responseHTML;if(Q){let X=h.fromHTMLString(Q);if(J.serverError)await this.view.renderError(X,this.currentVisit);else await this.view.renderPage(X,!1,!0,this.currentVisit);if(!X.shouldPreserveScrollPosition)this.view.scrollToTop();this.view.clearSnapshotCache()}}formSubmissionErrored(H,J){console.error(J)}formSubmissionFinished(H){if(typeof this.adapter.formSubmissionFinished==="function")this.adapter.formSubmissionFinished(H)}linkPrefetchingIsEnabledForLocation(H){if(typeof this.adapter.linkPrefetchingIsEnabledForLocation==="function")return this.adapter.linkPrefetchingIsEnabledForLocation(H);return!0}visitStarted(H){this.delegate.visitStarted(H)}visitCompleted(H){this.delegate.visitCompleted(H),delete this.currentVisit}locationWithActionIsSamePage(H,J){let Q=i(H),X=i(this.view.lastRenderedLocation),Y=J==="restore"&&typeof Q==="undefined";return J!=="replace"&&jH(H)===jH(this.view.lastRenderedLocation)&&(Y||Q!=null&&Q!==X)}visitScrolledToSamePageLocation(H,J){this.delegate.visitScrolledToSamePageLocation(H,J)}get location(){return this.history.location}get restorationIdentifier(){return this.history.restorationIdentifier}#H(H,J){let{submitter:Q,formElement:X}=H;return s(Q,X)||this.#J(J)}#J(H){return H.redirected&&H.location.href===this.location?.href?"replace":"advance"}}var c={initial:0,loading:1,interactive:2,complete:3};class h1{stage=c.initial;started=!1;constructor(H){this.delegate=H}start(){if(!this.started){if(this.stage==c.initial)this.stage=c.loading;document.addEventListener("readystatechange",this.interpretReadyState,!1),addEventListener("pagehide",this.pageWillUnload,!1),this.started=!0}}stop(){if(this.started)document.removeEventListener("readystatechange",this.interpretReadyState,!1),removeEventListener("pagehide",this.pageWillUnload,!1),this.started=!1}interpretReadyState=()=>{let{readyState:H}=this;if(H=="interactive")this.pageIsInteractive();else if(H=="complete")this.pageIsComplete()};pageIsInteractive(){if(this.stage==c.loading)this.stage=c.interactive,this.delegate.pageBecameInteractive()}pageIsComplete(){if(this.pageIsInteractive(),this.stage==c.interactive)this.stage=c.complete,this.delegate.pageLoaded()}pageWillUnload=()=>{this.delegate.pageWillUnload()};get readyState(){return document.readyState}}class g1{started=!1;constructor(H){this.delegate=H}start(){if(!this.started)addEventListener("scroll",this.onScroll,!1),this.onScroll(),this.started=!0}stop(){if(this.started)removeEventListener("scroll",this.onScroll,!1),this.started=!1}onScroll=()=>{this.updatePosition({x:window.pageXOffset,y:window.pageYOffset})};updatePosition(H){this.delegate.scrollPositionChanged(H)}}class b1{render({fragment:H}){xH.preservingPermanentElements(this,hQ(H),()=>{gQ(H,()=>{bQ(()=>{document.documentElement.appendChild(H)})})})}enteringBardo(H,J){J.replaceWith(H.cloneNode(!0))}leavingBardo(){}}function hQ(H){let J=M1(document.documentElement),Q={};for(let X of J){let{id:Y}=X;for(let Z of H.querySelectorAll("turbo-stream")){let U=F1(Z.templateElement.content,Y);if(U)Q[Y]=[X,U]}}return Q}async function gQ(H,J){let Q=`turbo-stream-autofocus-${p()}`,X=H.querySelectorAll("turbo-stream"),Y=yQ(X),Z=null;if(Y){if(Y.id)Z=Y.id;else Z=Q;Y.id=Z}if(J(),await HH(),(document.activeElement==null||document.activeElement==document.body)&&Z){let B=document.getElementById(Z);if(SH(B))B.focus();if(B&&B.id==Q)B.removeAttribute("id")}}async function bQ(H){let[J,Q]=await dJ(H,()=>document.activeElement),X=J&&J.id;if(X){let Y=document.getElementById(X);if(SH(Y)&&Y!=Q)Y.focus()}}function yQ(H){for(let J of H){let Q=$1(J.templateElement.content);if(Q)return Q}return null}class y1{sources=new Set;#H=!1;constructor(H){this.delegate=H}start(){if(!this.#H)this.#H=!0,addEventListener("turbo:before-fetch-response",this.inspectFetchResponse,!1)}stop(){if(this.#H)this.#H=!1,removeEventListener("turbo:before-fetch-response",this.inspectFetchResponse,!1)}connectStreamSource(H){if(!this.streamSourceIsConnected(H))this.sources.add(H),H.addEventListener("message",this.receiveMessageEvent,!1)}disconnectStreamSource(H){if(this.streamSourceIsConnected(H))this.sources.delete(H),H.removeEventListener("message",this.receiveMessageEvent,!1)}streamSourceIsConnected(H){return this.sources.has(H)}inspectFetchResponse=(H)=>{let J=kQ(H);if(J&&NQ(J))H.preventDefault(),this.receiveMessageResponse(J)};receiveMessageEvent=(H)=>{if(this.#H&&typeof H.data=="string")this.receiveMessageHTML(H.data)};async receiveMessageResponse(H){let J=await H.responseHTML;if(J)this.receiveMessageHTML(J)}receiveMessageHTML(H){this.delegate.receivedMessageFromStream(m.wrap(H))}}function kQ(H){let J=H.detail?.fetchResponse;if(J instanceof zH)return J}function NQ(H){return(H.contentType??"").startsWith(m.contentType)}class k1 extends _H{static renderElement(H,J){let{documentElement:Q,body:X}=document;Q.replaceChild(J,X)}async render(){this.replaceHeadAndBody(),this.activateScriptElements()}replaceHeadAndBody(){let{documentElement:H,head:J}=document;H.replaceChild(this.newHead,J),this.renderElement(this.currentElement,this.newElement)}activateScriptElements(){for(let H of this.scriptElements){let J=H.parentNode;if(J){let Q=JH(H);J.replaceChild(Q,H)}}}get newHead(){return this.newSnapshot.headSnapshot.element}get scriptElements(){return document.documentElement.querySelectorAll("script")}}class FH extends _H{static renderElement(H,J){if(document.body&&J instanceof HTMLBodyElement)document.body.replaceWith(J);else document.documentElement.appendChild(J)}get shouldRender(){return this.newSnapshot.isVisitable&&this.trackedElementsAreIdentical}get reloadReason(){if(!this.newSnapshot.isVisitable)return{reason:"turbo_visit_control_is_reload"};if(!this.trackedElementsAreIdentical)return{reason:"tracked_element_mismatch"}}async prepareToRender(){this.#H(),await this.mergeHead()}async render(){if(this.willRender)await this.replaceBody()}finishRendering(){if(super.finishRendering(),!this.isPreview)this.focusFirstAutofocusableElement()}get currentHeadSnapshot(){return this.currentSnapshot.headSnapshot}get newHeadSnapshot(){return this.newSnapshot.headSnapshot}get newElement(){return this.newSnapshot.element}#H(){let{documentElement:H}=this.currentSnapshot,{lang:J}=this.newSnapshot;if(J)H.setAttribute("lang",J);else H.removeAttribute("lang")}async mergeHead(){let H=this.mergeProvisionalElements(),J=this.copyNewHeadStylesheetElements();if(this.copyNewHeadScriptElements(),await H,await J,this.willRender)this.removeUnusedDynamicStylesheetElements()}async replaceBody(){await this.preservingPermanentElements(async()=>{this.activateNewBody(),await this.assignNewBody()})}get trackedElementsAreIdentical(){return this.currentHeadSnapshot.trackedElementSignature==this.newHeadSnapshot.trackedElementSignature}async copyNewHeadStylesheetElements(){let H=[];for(let J of this.newHeadStylesheetElements)H.push(fJ(J)),document.head.appendChild(J);await Promise.all(H)}copyNewHeadScriptElements(){for(let H of this.newHeadScriptElements)document.head.appendChild(JH(H))}removeUnusedDynamicStylesheetElements(){for(let H of this.unusedDynamicStylesheetElements)document.head.removeChild(H)}async mergeProvisionalElements(){let H=[...this.newHeadProvisionalElements];for(let J of this.currentHeadProvisionalElements)if(!this.isCurrentElementInElementList(J,H))document.head.removeChild(J);for(let J of H)document.head.appendChild(J)}isCurrentElementInElementList(H,J){for(let[Q,X]of J.entries()){if(H.tagName=="TITLE"){if(X.tagName!="TITLE")continue;if(H.innerHTML==X.innerHTML)return J.splice(Q,1),!0}if(X.isEqualNode(H))return J.splice(Q,1),!0}return!1}removeCurrentHeadProvisionalElements(){for(let H of this.currentHeadProvisionalElements)document.head.removeChild(H)}copyNewHeadProvisionalElements(){for(let H of this.newHeadProvisionalElements)document.head.appendChild(H)}activateNewBody(){document.adoptNode(this.newElement),this.activateNewBodyScriptElements()}activateNewBodyScriptElements(){for(let H of this.newBodyScriptElements){let J=JH(H);H.replaceWith(J)}}async assignNewBody(){await this.renderElement(this.currentElement,this.newElement)}get unusedDynamicStylesheetElements(){return this.oldHeadStylesheetElements.filter((H)=>{return H.getAttribute("data-turbo-track")==="dynamic"})}get oldHeadStylesheetElements(){return this.currentHeadSnapshot.getStylesheetElementsNotInSnapshot(this.newHeadSnapshot)}get newHeadStylesheetElements(){return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot)}get newHeadScriptElements(){return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot)}get currentHeadProvisionalElements(){return this.currentHeadSnapshot.provisionalElements}get newHeadProvisionalElements(){return this.newHeadSnapshot.provisionalElements}get newBodyScriptElements(){return this.newElement.querySelectorAll("script")}}class N1 extends FH{static renderElement(H,J){hH(H,J,{callbacks:{beforeNodeMorphed:(Q)=>!aH(Q)}});for(let Q of H.querySelectorAll("turbo-frame"))if(aH(Q))Q.reload();C("turbo:morph",{detail:{currentElement:H,newElement:J}})}async preservingPermanentElements(H){return await H()}get renderMethod(){return"morph"}get shouldAutofocus(){return!1}}function aH(H){return H instanceof g&&H.src&&H.refresh==="morph"&&!H.closest("[data-turbo-permanent]")}class f1{keys=[];snapshots={};constructor(H){this.size=H}has(H){return $H(H)in this.snapshots}get(H){if(this.has(H)){let J=this.read(H);return this.touch(H),J}}put(H,J){return this.write(H,J),this.touch(H),J}clear(){this.snapshots={}}read(H){return this.snapshots[$H(H)]}write(H,J){this.snapshots[$H(H)]=J}touch(H){let J=$H(H),Q=this.keys.indexOf(J);if(Q>-1)this.keys.splice(Q,1);this.keys.unshift(J),this.trim()}trim(){for(let H of this.keys.splice(this.size))delete this.snapshots[H]}}class v1 extends TH{snapshotCache=new f1(10);lastRenderedLocation=new URL(location.href);forceReloaded=!1;shouldTransitionTo(H){return this.snapshot.prefersViewTransitions&&H.prefersViewTransitions}renderPage(H,J=!1,Q=!0,X){let U=new(this.isPageRefresh(X)&&this.snapshot.shouldMorphPage?N1:FH)(this.snapshot,H,J,Q);if(!U.shouldRender)this.forceReloaded=!0;else X?.changeHistory();return this.render(U)}renderError(H,J){J?.changeHistory();let Q=new k1(this.snapshot,H,!1);return this.render(Q)}clearSnapshotCache(){this.snapshotCache.clear()}async cacheSnapshot(H=this.snapshot){if(H.isCacheable){this.delegate.viewWillCacheSnapshot();let{lastRenderedLocation:J}=this;await J1();let Q=H.clone();return this.snapshotCache.put(J,Q),Q}}getCachedSnapshotForLocation(H){return this.snapshotCache.get(H)}isPageRefresh(H){return!H||this.lastRenderedLocation.pathname===H.location.pathname&&H.action==="replace"}shouldPreserveScrollPosition(H){return this.isPageRefresh(H)&&this.snapshot.shouldPreserveScrollPosition}get snapshot(){return h.fromElement(this.element)}}class p1{selector="a[data-turbo-preload]";constructor(H,J){this.delegate=H,this.snapshotCache=J}start(){if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",this.#H);else this.preloadOnLoadLinksForView(document.body)}stop(){document.removeEventListener("DOMContentLoaded",this.#H)}preloadOnLoadLinksForView(H){for(let J of H.querySelectorAll(this.selector))if(this.delegate.shouldPreloadLink(J))this.preloadURL(J)}async preloadURL(H){let J=new URL(H.href);if(this.snapshotCache.has(J))return;await new e(this,O.get,J,new URLSearchParams,H).perform()}prepareRequest(H){H.headers["X-Sec-Purpose"]="prefetch"}async requestSucceededWithResponse(H,J){try{let Q=await J.responseHTML,X=h.fromHTMLString(Q);this.snapshotCache.put(H.url,X)}catch(Q){}}requestStarted(H){}requestErrored(H){}requestFinished(H){}requestPreventedHandlingResponse(H,J){}requestFailedWithResponse(H,J){}#H=()=>{this.preloadOnLoadLinksForView(document.body)}}class d1{constructor(H){this.session=H}clear(){this.session.clearCache()}resetCacheControl(){this.#H("")}exemptPageFromCache(){this.#H("no-cache")}exemptPageFromPreview(){this.#H("no-preview")}#H(H){pJ("turbo-cache-control",H)}}class c1{navigator=new x1(this);history=new D1(this);view=new v1(this,document.documentElement);adapter=new R1(this);pageObserver=new h1(this);cacheObserver=new T1;linkPrefetchObserver=new O1(this,document);linkClickObserver=new DH(this,window);formSubmitObserver=new BH(this,document);scrollObserver=new g1(this);streamObserver=new y1(this);formLinkClickObserver=new OH(this,document.documentElement);frameRedirector=new V1(this,document.documentElement);streamMessageRenderer=new b1;cache=new d1(this);enabled=!0;started=!1;#H=150;constructor(H){this.recentRequests=H,this.preloader=new p1(this,this.view.snapshotCache),this.debouncedRefresh=this.refresh,this.pageRefreshDebouncePeriod=this.pageRefreshDebouncePeriod}start(){if(!this.started)this.pageObserver.start(),this.cacheObserver.start(),this.linkPrefetchObserver.start(),this.formLinkClickObserver.start(),this.linkClickObserver.start(),this.formSubmitObserver.start(),this.scrollObserver.start(),this.streamObserver.start(),this.frameRedirector.start(),this.history.start(),this.preloader.start(),this.started=!0,this.enabled=!0}disable(){this.enabled=!1}stop(){if(this.started)this.pageObserver.stop(),this.cacheObserver.stop(),this.linkPrefetchObserver.stop(),this.formLinkClickObserver.stop(),this.linkClickObserver.stop(),this.formSubmitObserver.stop(),this.scrollObserver.stop(),this.streamObserver.stop(),this.frameRedirector.stop(),this.history.stop(),this.preloader.stop(),this.started=!1}registerAdapter(H){this.adapter=H}visit(H,J={}){let Q=J.frame?document.getElementById(J.frame):null;if(Q instanceof g){let X=J.action||s(Q);Q.delegate.proposeVisitIfNavigatedWithAction(Q,X),Q.src=H.toString()}else this.navigator.proposeVisit(V(H),J)}refresh(H,J){let Q=J&&this.recentRequests.has(J),X=H===document.baseURI;if(!Q&&!this.navigator.currentVisit&&X)this.visit(H,{action:"replace",shouldCacheSnapshot:!1})}connectStreamSource(H){this.streamObserver.connectStreamSource(H)}disconnectStreamSource(H){this.streamObserver.disconnectStreamSource(H)}renderStreamMessage(H){this.streamMessageRenderer.render(m.wrap(H))}clearCache(){this.view.clearSnapshotCache()}setProgressBarDelay(H){console.warn("Please replace `session.setProgressBarDelay(delay)` with `session.progressBarDelay = delay`. The function is deprecated and will be removed in a future version of Turbo.`"),this.progressBarDelay=H}set progressBarDelay(H){T.drive.progressBarDelay=H}get progressBarDelay(){return T.drive.progressBarDelay}set drive(H){T.drive.enabled=H}get drive(){return T.drive.enabled}set formMode(H){T.forms.mode=H}get formMode(){return T.forms.mode}get location(){return this.history.location}get restorationIdentifier(){return this.history.restorationIdentifier}get pageRefreshDebouncePeriod(){return this.#H}set pageRefreshDebouncePeriod(H){this.refresh=cJ(this.debouncedRefresh.bind(this),H),this.#H=H}shouldPreloadLink(H){let J=H.hasAttribute("data-turbo-method"),Q=H.hasAttribute("data-turbo-stream"),X=H.getAttribute("data-turbo-frame"),Y=X=="_top"?null:document.getElementById(X)||n(H,"turbo-frame:not([disabled])");if(J||Q||Y instanceof g)return!1;else{let Z=new URL(H.href);return this.elementIsNavigatable(H)&&v(Z,this.snapshot.rootLocation)}}historyPoppedToLocationWithRestorationIdentifierAndDirection(H,J,Q){if(this.enabled)this.navigator.startVisit(H,J,{action:"restore",historyChanged:!0,direction:Q});else this.adapter.pageInvalidated({reason:"turbo_disabled"})}scrollPositionChanged(H){this.history.updateRestorationData({scrollPosition:H})}willSubmitFormLinkToLocation(H,J){return this.elementIsNavigatable(H)&&v(J,this.snapshot.rootLocation)}submittedFormLinkToLocation(){}canPrefetchRequestToLocation(H,J){return this.elementIsNavigatable(H)&&v(J,this.snapshot.rootLocation)&&this.navigator.linkPrefetchingIsEnabledForLocation(J)}willFollowLinkToLocation(H,J,Q){return this.elementIsNavigatable(H)&&v(J,this.snapshot.rootLocation)&&this.applicationAllowsFollowingLinkToLocation(H,J,Q)}followedLinkToLocation(H,J){let Q=this.getActionForLink(H),X=H.hasAttribute("data-turbo-stream");this.visit(J.href,{action:Q,acceptsStreamResponse:X})}allowsVisitingLocationWithAction(H,J){return this.locationWithActionIsSamePage(H,J)||this.applicationAllowsVisitingLocation(H)}visitProposedToLocation(H,J){lH(H),this.adapter.visitProposedToLocation(H,J)}visitStarted(H){if(!H.acceptsStreamResponse)AH(document.documentElement),this.view.markVisitDirection(H.direction);if(lH(H.location),!H.silent)this.notifyApplicationAfterVisitingLocation(H.location,H.action)}visitCompleted(H){this.view.unmarkVisitDirection(),qH(document.documentElement),this.notifyApplicationAfterPageLoad(H.getTimingMetrics())}locationWithActionIsSamePage(H,J){return this.navigator.locationWithActionIsSamePage(H,J)}visitScrolledToSamePageLocation(H,J){this.notifyApplicationAfterVisitingSamePageLocation(H,J)}willSubmitForm(H,J){let Q=wH(H,J);return this.submissionIsNavigatable(H,J)&&v(V(Q),this.snapshot.rootLocation)}formSubmitted(H,J){this.navigator.submitForm(H,J)}pageBecameInteractive(){this.view.lastRenderedLocation=this.location,this.notifyApplicationAfterPageLoad()}pageLoaded(){this.history.assumeControlOfScrollRestoration()}pageWillUnload(){this.history.relinquishControlOfScrollRestoration()}receivedMessageFromStream(H){this.renderStreamMessage(H)}viewWillCacheSnapshot(){if(!this.navigator.currentVisit?.silent)this.notifyApplicationBeforeCachingSnapshot()}allowsImmediateRender({element:H},J){let Q=this.notifyApplicationBeforeRender(H,J),{defaultPrevented:X,detail:{render:Y}}=Q;if(this.view.renderer&&Y)this.view.renderer.renderElement=Y;return!X}viewRenderedSnapshot(H,J,Q){this.view.lastRenderedLocation=this.history.location,this.notifyApplicationAfterRender(Q)}preloadOnLoadLinksForView(H){this.preloader.preloadOnLoadLinksForView(H)}viewInvalidated(H){this.adapter.pageInvalidated(H)}frameLoaded(H){this.notifyApplicationAfterFrameLoad(H)}frameRendered(H,J){this.notifyApplicationAfterFrameRender(H,J)}applicationAllowsFollowingLinkToLocation(H,J,Q){return!this.notifyApplicationAfterClickingLinkToLocation(H,J,Q).defaultPrevented}applicationAllowsVisitingLocation(H){return!this.notifyApplicationBeforeVisitingLocation(H).defaultPrevented}notifyApplicationAfterClickingLinkToLocation(H,J,Q){return C("turbo:click",{target:H,detail:{url:J.href,originalEvent:Q},cancelable:!0})}notifyApplicationBeforeVisitingLocation(H){return C("turbo:before-visit",{detail:{url:H.href},cancelable:!0})}notifyApplicationAfterVisitingLocation(H,J){return C("turbo:visit",{detail:{url:H.href,action:J}})}notifyApplicationBeforeCachingSnapshot(){return C("turbo:before-cache")}notifyApplicationBeforeRender(H,J){return C("turbo:before-render",{detail:{newBody:H,...J},cancelable:!0})}notifyApplicationAfterRender(H){return C("turbo:render",{detail:{renderMethod:H}})}notifyApplicationAfterPageLoad(H={}){return C("turbo:load",{detail:{url:this.location.href,timing:H}})}notifyApplicationAfterVisitingSamePageLocation(H,J){dispatchEvent(new HashChangeEvent("hashchange",{oldURL:H.toString(),newURL:J.toString()}))}notifyApplicationAfterFrameLoad(H){return C("turbo:frame-load",{target:H})}notifyApplicationAfterFrameRender(H,J){return C("turbo:frame-render",{detail:{fetchResponse:H},target:J,cancelable:!0})}submissionIsNavigatable(H,J){if(T.forms.mode=="off")return!1;else{let Q=J?this.elementIsNavigatable(J):!0;if(T.forms.mode=="optin")return Q&&H.closest('[data-turbo="true"]')!=null;else return Q&&this.elementIsNavigatable(H)}}elementIsNavigatable(H){let J=n(H,"[data-turbo]"),Q=n(H,"turbo-frame");if(T.drive.enabled||Q)if(J)return J.getAttribute("data-turbo")!="false";else return!0;else if(J)return J.getAttribute("data-turbo")=="true";else return!1}getActionForLink(H){return s(H)||"advance"}get snapshot(){return this.view.snapshot}}function lH(H){Object.defineProperties(H,fQ)}var fQ={absoluteURL:{get(){return this.toString()}}},E=new c1(z1),{cache:vQ,navigator:pQ}=E;function u1(){E.start()}function dQ(H){E.registerAdapter(H)}function cQ(H,J){E.visit(H,J)}function s1(H){E.connectStreamSource(H)}function i1(H){E.disconnectStreamSource(H)}function uQ(H){E.renderStreamMessage(H)}function sQ(){console.warn("Please replace `Turbo.clearCache()` with `Turbo.cache.clear()`. The top-level function is deprecated and will be removed in a future version of Turbo.`"),E.clearCache()}function iQ(H){console.warn("Please replace `Turbo.setProgressBarDelay(delay)` with `Turbo.config.drive.progressBarDelay = delay`. The top-level function is deprecated and will be removed in a future version of Turbo.`"),T.drive.progressBarDelay=H}function mQ(H){console.warn("Please replace `Turbo.setConfirmMethod(confirmMethod)` with `Turbo.config.forms.confirm = confirmMethod`. The top-level function is deprecated and will be removed in a future version of Turbo.`"),T.forms.confirm=H}function oQ(H){console.warn("Please replace `Turbo.setFormMode(mode)` with `Turbo.config.forms.mode = mode`. The top-level function is deprecated and will be removed in a future version of Turbo.`"),T.forms.mode=H}var rQ=Object.freeze({__proto__:null,navigator:pQ,session:E,cache:vQ,PageRenderer:FH,PageSnapshot:h,FrameRenderer:IH,fetch:K1,config:T,start:u1,registerAdapter:dQ,visit:cQ,connectStreamSource:s1,disconnectStreamSource:i1,renderStreamMessage:uQ,clearCache:sQ,setProgressBarDelay:iQ,setConfirmMethod:mQ,setFormMode:oQ});class m1 extends Error{}class o1{fetchResponseLoaded=(H)=>Promise.resolve();#H=null;#J=()=>{};#Q=!1;#Z=!1;#$=new Set;#Y=!1;action=null;constructor(H){this.element=H,this.view=new P1(this,this.element),this.appearanceObserver=new _1(this,this.element),this.formLinkClickObserver=new OH(this,this.element),this.linkInterceptor=new VH(this,this.element),this.restorationIdentifier=p(),this.formSubmitObserver=new BH(this,this.element)}connect(){if(!this.#Q){if(this.#Q=!0,this.loadingStyle==a.lazy)this.appearanceObserver.start();else this.#X();this.formLinkClickObserver.start(),this.linkInterceptor.start(),this.formSubmitObserver.start()}}disconnect(){if(this.#Q)this.#Q=!1,this.appearanceObserver.stop(),this.formLinkClickObserver.stop(),this.linkInterceptor.stop(),this.formSubmitObserver.stop()}disabledChanged(){if(this.loadingStyle==a.eager)this.#X()}sourceURLChanged(){if(this.#M("src"))return;if(this.element.isConnected)this.complete=!1;if(this.loadingStyle==a.eager||this.#Z)this.#X()}sourceURLReloaded(){let{refresh:H,src:J}=this.element;return this.#Y=J&&H==="morph",this.element.removeAttribute("complete"),this.element.src=null,this.element.src=J,this.element.loaded}loadingStyleChanged(){if(this.loadingStyle==a.lazy)this.appearanceObserver.start();else this.appearanceObserver.stop(),this.#X()}async#X(){if(this.enabled&&this.isActive&&!this.complete&&this.sourceURL)this.element.loaded=this.#U(V(this.sourceURL)),this.appearanceObserver.stop(),await this.element.loaded,this.#Z=!0}async loadResponse(H){if(H.redirected||H.succeeded&&H.isHTML)this.sourceURL=H.response.url;try{let J=await H.responseHTML;if(J){let Q=Q1(J);if(h.fromDocument(Q).isVisitable)await this.#W(H,Q);else await this.#K(H)}}finally{this.#Y=!1,this.fetchResponseLoaded=()=>Promise.resolve()}}elementAppearedInViewport(H){this.proposeVisitIfNavigatedWithAction(H,s(H)),this.#X()}willSubmitFormLinkToLocation(H){return this.#A(H)}submittedFormLinkToLocation(H,J,Q){let X=this.#G(H);if(X)Q.setAttribute("data-turbo-frame",X.id)}shouldInterceptLinkClick(H,J,Q){return this.#A(H)}linkClickIntercepted(H,J){this.#z(H,J)}willSubmitForm(H,J){return H.closest("turbo-frame")==this.element&&this.#A(H,J)}formSubmitted(H,J){if(this.formSubmission)this.formSubmission.stop();this.formSubmission=new KH(this,H,J);let{fetchRequest:Q}=this.formSubmission;this.prepareRequest(Q),this.formSubmission.start()}prepareRequest(H){if(H.headers["Turbo-Frame"]=this.id,this.currentNavigationElement?.hasAttribute("data-turbo-stream"))H.acceptResponseType(m.contentType)}requestStarted(H){AH(this.element)}requestPreventedHandlingResponse(H,J){this.#J()}async requestSucceededWithResponse(H,J){await this.loadResponse(J),this.#J()}async requestFailedWithResponse(H,J){await this.loadResponse(J),this.#J()}requestErrored(H,J){console.error(J),this.#J()}requestFinished(H){qH(this.element)}formSubmissionStarted({formElement:H}){AH(H,this.#G(H))}formSubmissionSucceededWithResponse(H,J){let Q=this.#G(H.formElement,H.submitter);if(Q.delegate.proposeVisitIfNavigatedWithAction(Q,s(H.submitter,H.formElement,Q)),Q.delegate.loadResponse(J),!H.isSafe)E.clearCache()}formSubmissionFailedWithResponse(H,J){this.element.delegate.loadResponse(J),E.clearCache()}formSubmissionErrored(H,J){console.error(J)}formSubmissionFinished({formElement:H}){qH(H,this.#G(H))}allowsImmediateRender({element:H},J){let Q=C("turbo:before-frame-render",{target:this.element,detail:{newFrame:H,...J},cancelable:!0}),{defaultPrevented:X,detail:{render:Y}}=Q;if(this.view.renderer&&Y)this.view.renderer.renderElement=Y;return!X}viewRenderedSnapshot(H,J,Q){}preloadOnLoadLinksForView(H){E.preloadOnLoadLinksForView(H)}viewInvalidated(){}willRenderFrame(H,J){this.previousFrameElement=H.cloneNode(!0)}visitCachedSnapshot=({element:H})=>{let J=H.querySelector("#"+this.element.id);if(J&&this.previousFrameElement)J.replaceChildren(...this.previousFrameElement.children);delete this.previousFrameElement};async#W(H,J){let Q=await this.extractForeignFrameElement(J.body),X=this.#Y?C1:IH;if(Q){let Y=new QH(Q),Z=new X(this,this.view.snapshot,Y,!1,!1);if(this.view.renderPromise)await this.view.renderPromise;this.changeHistory(),await this.view.render(Z),this.complete=!0,E.frameRendered(H,this.element),E.frameLoaded(this.element),await this.fetchResponseLoaded(H)}else if(this.#B(H))this.#_(H)}async#U(H){let J=new e(this,O.get,H,new URLSearchParams,this.element);return this.#H?.cancel(),this.#H=J,new Promise((Q)=>{this.#J=()=>{this.#J=()=>{},this.#H=null,Q()},J.perform()})}#z(H,J,Q){let X=this.#G(H,Q);X.delegate.proposeVisitIfNavigatedWithAction(X,s(Q,H,X)),this.#L(H,()=>{X.src=J})}proposeVisitIfNavigatedWithAction(H,J=null){if(this.action=J,this.action){let Q=h.fromElement(H).clone(),{visitCachedSnapshot:X}=H.delegate;H.delegate.fetchResponseLoaded=async(Y)=>{if(H.src){let{statusCode:Z,redirected:U}=Y,B=await Y.responseHTML,R={response:{statusCode:Z,redirected:U,responseHTML:B},visitCachedSnapshot:X,willRender:!1,updateHistory:!1,restorationIdentifier:this.restorationIdentifier,snapshot:Q};if(this.action)R.action=this.action;E.visit(H.src,R)}}}}changeHistory(){if(this.action){let H=Y1(this.action);E.history.update(H,V(this.element.src||""),this.restorationIdentifier)}}async#K(H){console.warn(`The response (${H.statusCode}) from <turbo-frame id="${this.element.id}"> is performing a full page visit due to turbo-visit-control.`),await this.#q(H.response)}#B(H){this.element.setAttribute("complete","");let J=H.response,Q=async(Y,Z)=>{if(Y instanceof Response)this.#q(Y);else E.visit(Y,Z)};return!C("turbo:frame-missing",{target:this.element,detail:{response:J,visit:Q},cancelable:!0}).defaultPrevented}#_(H){this.view.missing(),this.#I(H)}#I(H){let J=`The response (${H.statusCode}) did not contain the expected <turbo-frame id="${this.element.id}"> and will be ignored. To perform a full page visit instead, set turbo-visit-control to reload.`;throw new m1(J)}async#q(H){let J=new zH(H),Q=await J.responseHTML,{location:X,redirected:Y,statusCode:Z}=J;return E.visit(X,{response:{redirected:Y,statusCode:Z,responseHTML:Q}})}#G(H,J){let Q=WH("data-turbo-frame",J,H)||this.element.getAttribute("target");return nH(Q)??this.element}async extractForeignFrameElement(H){let J,Q=CSS.escape(this.id);try{if(J=tH(H.querySelector(`turbo-frame#${Q}`),this.sourceURL),J)return J;if(J=tH(H.querySelector(`turbo-frame[src][recurse~=${Q}]`),this.sourceURL),J)return await J.loaded,await this.extractForeignFrameElement(J)}catch(X){return console.error(X),new g}return null}#F(H,J){let Q=wH(H,J);return v(V(Q),this.rootLocation)}#A(H,J){let Q=WH("data-turbo-frame",J,H)||this.element.getAttribute("target");if(H instanceof HTMLFormElement&&!this.#F(H,J))return!1;if(!this.enabled||Q=="_top")return!1;if(Q){let X=nH(Q);if(X)return!X.disabled}if(!E.elementIsNavigatable(H))return!1;if(J&&!E.elementIsNavigatable(J))return!1;return!0}get id(){return this.element.id}get enabled(){return!this.element.disabled}get sourceURL(){if(this.element.src)return this.element.src}set sourceURL(H){this.#P("src",()=>{this.element.src=H??null})}get loadingStyle(){return this.element.loading}get isLoading(){return this.formSubmission!==void 0||this.#J()!==void 0}get complete(){return this.element.hasAttribute("complete")}set complete(H){if(H)this.element.setAttribute("complete","");else this.element.removeAttribute("complete")}get isActive(){return this.element.isActive&&this.#Q}get rootLocation(){let J=this.element.ownerDocument.querySelector('meta[name="turbo-root"]')?.content??"/";return V(J)}#M(H){return this.#$.has(H)}#P(H,J){this.#$.add(H),J(),this.#$.delete(H)}#L(H,J){this.currentNavigationElement=H,J(),delete this.currentNavigationElement}}function nH(H){if(H!=null){let J=document.getElementById(H);if(J instanceof g)return J}}function tH(H,J){if(H){let Q=H.getAttribute("src");if(Q!=null&&J!=null&&oJ(Q,J))throw new Error(`Matching <turbo-frame id="${H.id}"> element has a source URL which references itself`);if(H.ownerDocument!==document)H=document.importNode(H,!0);if(H instanceof g)return H.connectedCallback(),H.disconnectedCallback(),H}}var r1={after(){this.targetElements.forEach((H)=>H.parentElement?.insertBefore(this.templateContent,H.nextSibling))},append(){this.removeDuplicateTargetChildren(),this.targetElements.forEach((H)=>H.append(this.templateContent))},before(){this.targetElements.forEach((H)=>H.parentElement?.insertBefore(this.templateContent,H))},prepend(){this.removeDuplicateTargetChildren(),this.targetElements.forEach((H)=>H.prepend(this.templateContent))},remove(){this.targetElements.forEach((H)=>H.remove())},replace(){let H=this.getAttribute("method");this.targetElements.forEach((J)=>{if(H==="morph")hH(J,this.templateContent);else J.replaceWith(this.templateContent)})},update(){let H=this.getAttribute("method");this.targetElements.forEach((J)=>{if(H==="morph")L1(J,this.templateContent);else J.innerHTML="",J.append(this.templateContent)})},refresh(){E.refresh(this.baseURI,this.requestId)}};class gH extends HTMLElement{static async renderElement(H){await H.performAction()}async connectedCallback(){try{await this.render()}catch(H){console.error(H)}finally{this.disconnect()}}async render(){return this.renderPromise??=(async()=>{let H=this.beforeRenderEvent;if(this.dispatchEvent(H))await HH(),await H.detail.render(this)})()}disconnect(){try{this.remove()}catch{}}removeDuplicateTargetChildren(){this.duplicateChildren.forEach((H)=>H.remove())}get duplicateChildren(){let H=this.targetElements.flatMap((Q)=>[...Q.children]).filter((Q)=>!!Q.getAttribute("id")),J=[...this.templateContent?.children||[]].filter((Q)=>!!Q.getAttribute("id")).map((Q)=>Q.getAttribute("id"));return H.filter((Q)=>J.includes(Q.getAttribute("id")))}get performAction(){if(this.action){let H=r1[this.action];if(H)return H;this.#H("unknown action")}this.#H("action attribute is missing")}get targetElements(){if(this.target)return this.targetElementsById;else if(this.targets)return this.targetElementsByQuery;else this.#H("target or targets attribute is missing")}get templateContent(){return this.templateElement.content.cloneNode(!0)}get templateElement(){if(this.firstElementChild===null){let H=this.ownerDocument.createElement("template");return this.appendChild(H),H}else if(this.firstElementChild instanceof HTMLTemplateElement)return this.firstElementChild;this.#H("first child element must be a <template> element")}get action(){return this.getAttribute("action")}get target(){return this.getAttribute("target")}get targets(){return this.getAttribute("targets")}get requestId(){return this.getAttribute("request-id")}#H(H){throw new Error(`${this.description}: ${H}`)}get description(){return(this.outerHTML.match(/<[^>]+>/)??[])[0]??"<turbo-stream>"}get beforeRenderEvent(){return new CustomEvent("turbo:before-stream-render",{bubbles:!0,cancelable:!0,detail:{newStream:this,render:gH.renderElement}})}get targetElementsById(){let H=this.ownerDocument?.getElementById(this.target);if(H!==null)return[H];else return[]}get targetElementsByQuery(){let H=this.ownerDocument?.querySelectorAll(this.targets);if(H.length!==0)return Array.prototype.slice.call(H);else return[]}}class a1 extends HTMLElement{streamSource=null;connectedCallback(){this.streamSource=this.src.match(/^ws{1,2}:/)?new WebSocket(this.src):new EventSource(this.src),s1(this.streamSource)}disconnectedCallback(){if(this.streamSource)this.streamSource.close(),i1(this.streamSource)}get src(){return this.getAttribute("src")||""}}g.delegateConstructor=o1;if(customElements.get("turbo-frame")===void 0)customElements.define("turbo-frame",g);if(customElements.get("turbo-stream")===void 0)customElements.define("turbo-stream",gH);if(customElements.get("turbo-stream-source")===void 0)customElements.define("turbo-stream-source",a1);(()=>{let H=document.currentScript;if(!H)return;if(H.hasAttribute("data-turbo-suppress-warning"))return;H=H.parentElement;while(H){if(H==document.body)return console.warn(X1`
21
+ You are loading Turbo from a <script> element inside the <body> element. This is probably not what you meant to do!
22
+
23
+ Load your application’s JavaScript bundle inside the <head> element instead. <script> elements in <body> are evaluated with each page change.
24
+
25
+ For more information, see: https://turbo.hotwired.dev/handbook/building#working-with-script-elements
26
+
27
+ ——
28
+ Suppress this warning by adding a "data-turbo-suppress-warning" attribute to: %s
29
+ `,H.outerHTML);H=H.parentElement}})();window.Turbo={...rQ,StreamActions:r1};u1();class ZJ{constructor(H,J,Q){this.eventTarget=H,this.eventName=J,this.eventOptions=Q,this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(H){this.unorderedBindings.add(H)}bindingDisconnected(H){this.unorderedBindings.delete(H)}handleEvent(H){let J=aQ(H);for(let Q of this.bindings)if(J.immediatePropagationStopped)break;else Q.handleEvent(J)}hasBindings(){return this.unorderedBindings.size>0}get bindings(){return Array.from(this.unorderedBindings).sort((H,J)=>{let Q=H.index,X=J.index;return Q<X?-1:Q>X?1:0})}}function aQ(H){if("immediatePropagationStopped"in H)return H;else{let{stopImmediatePropagation:J}=H;return Object.assign(H,{immediatePropagationStopped:!1,stopImmediatePropagation(){this.immediatePropagationStopped=!0,J.call(this)}})}}class $J{constructor(H){this.application=H,this.eventListenerMaps=new Map,this.started=!1}start(){if(!this.started)this.started=!0,this.eventListeners.forEach((H)=>H.connect())}stop(){if(this.started)this.started=!1,this.eventListeners.forEach((H)=>H.disconnect())}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce((H,J)=>H.concat(Array.from(J.values())),[])}bindingConnected(H){this.fetchEventListenerForBinding(H).bindingConnected(H)}bindingDisconnected(H,J=!1){if(this.fetchEventListenerForBinding(H).bindingDisconnected(H),J)this.clearEventListenersForBinding(H)}handleError(H,J,Q={}){this.application.handleError(H,`Error ${J}`,Q)}clearEventListenersForBinding(H){let J=this.fetchEventListenerForBinding(H);if(!J.hasBindings())J.disconnect(),this.removeMappedEventListenerFor(H)}removeMappedEventListenerFor(H){let{eventTarget:J,eventName:Q,eventOptions:X}=H,Y=this.fetchEventListenerMapForEventTarget(J),Z=this.cacheKey(Q,X);if(Y.delete(Z),Y.size==0)this.eventListenerMaps.delete(J)}fetchEventListenerForBinding(H){let{eventTarget:J,eventName:Q,eventOptions:X}=H;return this.fetchEventListener(J,Q,X)}fetchEventListener(H,J,Q){let X=this.fetchEventListenerMapForEventTarget(H),Y=this.cacheKey(J,Q),Z=X.get(Y);if(!Z)Z=this.createEventListener(H,J,Q),X.set(Y,Z);return Z}createEventListener(H,J,Q){let X=new ZJ(H,J,Q);if(this.started)X.connect();return X}fetchEventListenerMapForEventTarget(H){let J=this.eventListenerMaps.get(H);if(!J)J=new Map,this.eventListenerMaps.set(H,J);return J}cacheKey(H,J){let Q=[H];return Object.keys(J).sort().forEach((X)=>{Q.push(`${J[X]?"":"!"}${X}`)}),Q.join(":")}}var lQ={stop({event:H,value:J}){if(J)H.stopPropagation();return!0},prevent({event:H,value:J}){if(J)H.preventDefault();return!0},self({event:H,value:J,element:Q}){if(J)return Q===H.target;else return!0}},nQ=/^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function tQ(H){let Q=H.trim().match(nQ)||[],X=Q[2],Y=Q[3];if(Y&&!["keydown","keyup","keypress"].includes(X))X+=`.${Y}`,Y="";return{eventTarget:eQ(Q[4]),eventName:X,eventOptions:Q[7]?HX(Q[7]):{},identifier:Q[5],methodName:Q[6],keyFilter:Q[1]||Y}}function eQ(H){if(H=="window")return window;else if(H=="document")return document}function HX(H){return H.split(":").reduce((J,Q)=>Object.assign(J,{[Q.replace(/^!/,"")]:!/^!/.test(Q)}),{})}function JX(H){if(H==window)return"window";else if(H==document)return"document"}function NH(H){return H.replace(/(?:[_-])([a-z0-9])/g,(J,Q)=>Q.toUpperCase())}function bH(H){return NH(H.replace(/--/g,"-").replace(/__/g,"_"))}function YH(H){return H.charAt(0).toUpperCase()+H.slice(1)}function GJ(H){return H.replace(/([A-Z])/g,(J,Q)=>`-${Q.toLowerCase()}`)}function QX(H){return H.match(/[^\s]+/g)||[]}function l1(H){return H!==null&&H!==void 0}function yH(H,J){return Object.prototype.hasOwnProperty.call(H,J)}var n1=["meta","ctrl","alt","shift"];class WJ{constructor(H,J,Q,X){this.element=H,this.index=J,this.eventTarget=Q.eventTarget||H,this.eventName=Q.eventName||XX(H)||MH("missing event name"),this.eventOptions=Q.eventOptions||{},this.identifier=Q.identifier||MH("missing identifier"),this.methodName=Q.methodName||MH("missing method name"),this.keyFilter=Q.keyFilter||"",this.schema=X}static forToken(H,J){return new this(H.element,H.index,tQ(H.content),J)}toString(){let H=this.keyFilter?`.${this.keyFilter}`:"",J=this.eventTargetName?`@${this.eventTargetName}`:"";return`${this.eventName}${H}${J}->${this.identifier}#${this.methodName}`}shouldIgnoreKeyboardEvent(H){if(!this.keyFilter)return!1;let J=this.keyFilter.split("+");if(this.keyFilterDissatisfied(H,J))return!0;let Q=J.filter((X)=>!n1.includes(X))[0];if(!Q)return!1;if(!yH(this.keyMappings,Q))MH(`contains unknown key filter: ${this.keyFilter}`);return this.keyMappings[Q].toLowerCase()!==H.key.toLowerCase()}shouldIgnoreMouseEvent(H){if(!this.keyFilter)return!1;let J=[this.keyFilter];if(this.keyFilterDissatisfied(H,J))return!0;return!1}get params(){let H={},J=new RegExp(`^data-${this.identifier}-(.+)-param$`,"i");for(let{name:Q,value:X}of Array.from(this.element.attributes)){let Y=Q.match(J),Z=Y&&Y[1];if(Z)H[NH(Z)]=YX(X)}return H}get eventTargetName(){return JX(this.eventTarget)}get keyMappings(){return this.schema.keyMappings}keyFilterDissatisfied(H,J){let[Q,X,Y,Z]=n1.map((U)=>J.includes(U));return H.metaKey!==Q||H.ctrlKey!==X||H.altKey!==Y||H.shiftKey!==Z}}var t1={a:()=>"click",button:()=>"click",form:()=>"submit",details:()=>"toggle",input:(H)=>H.getAttribute("type")=="submit"?"click":"input",select:()=>"change",textarea:()=>"input"};function XX(H){let J=H.tagName.toLowerCase();if(J in t1)return t1[J](H)}function MH(H){throw new Error(H)}function YX(H){try{return JSON.parse(H)}catch(J){return H}}class AJ{constructor(H,J){this.context=H,this.action=J}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(H){let J=this.prepareActionEvent(H);if(this.willBeInvokedByEvent(H)&&this.applyEventModifiers(J))this.invokeWithEvent(J)}get eventName(){return this.action.eventName}get method(){let H=this.controller[this.methodName];if(typeof H=="function")return H;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}applyEventModifiers(H){let{element:J}=this.action,{actionDescriptorFilters:Q}=this.context.application,{controller:X}=this.context,Y=!0;for(let[Z,U]of Object.entries(this.eventOptions))if(Z in Q){let B=Q[Z];Y=Y&&B({name:Z,value:U,event:H,element:J,controller:X})}else continue;return Y}prepareActionEvent(H){return Object.assign(H,{params:this.action.params})}invokeWithEvent(H){let{target:J,currentTarget:Q}=H;try{this.method.call(this.controller,H),this.context.logDebugActivity(this.methodName,{event:H,target:J,currentTarget:Q,action:this.methodName})}catch(X){let{identifier:Y,controller:Z,element:U,index:B}=this,D={identifier:Y,controller:Z,element:U,index:B,event:H};this.context.handleError(X,`invoking action "${this.action}"`,D)}}willBeInvokedByEvent(H){let J=H.target;if(H instanceof KeyboardEvent&&this.action.shouldIgnoreKeyboardEvent(H))return!1;if(H instanceof MouseEvent&&this.action.shouldIgnoreMouseEvent(H))return!1;if(this.element===J)return!0;else if(J instanceof Element&&this.element.contains(J))return this.scope.containsElement(J);else return this.scope.containsElement(this.action.element)}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class fH{constructor(H,J){this.mutationObserverInit={attributes:!0,childList:!0,subtree:!0},this.element=H,this.started=!1,this.delegate=J,this.elements=new Set,this.mutationObserver=new MutationObserver((Q)=>this.processMutations(Q))}start(){if(!this.started)this.started=!0,this.mutationObserver.observe(this.element,this.mutationObserverInit),this.refresh()}pause(H){if(this.started)this.mutationObserver.disconnect(),this.started=!1;if(H(),!this.started)this.mutationObserver.observe(this.element,this.mutationObserverInit),this.started=!0}stop(){if(this.started)this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1}refresh(){if(this.started){let H=new Set(this.matchElementsInTree());for(let J of Array.from(this.elements))if(!H.has(J))this.removeElement(J);for(let J of Array.from(H))this.addElement(J)}}processMutations(H){if(this.started)for(let J of H)this.processMutation(J)}processMutation(H){if(H.type=="attributes")this.processAttributeChange(H.target,H.attributeName);else if(H.type=="childList")this.processRemovedNodes(H.removedNodes),this.processAddedNodes(H.addedNodes)}processAttributeChange(H,J){if(this.elements.has(H))if(this.delegate.elementAttributeChanged&&this.matchElement(H))this.delegate.elementAttributeChanged(H,J);else this.removeElement(H);else if(this.matchElement(H))this.addElement(H)}processRemovedNodes(H){for(let J of Array.from(H)){let Q=this.elementFromNode(J);if(Q)this.processTree(Q,this.removeElement)}}processAddedNodes(H){for(let J of Array.from(H)){let Q=this.elementFromNode(J);if(Q&&this.elementIsActive(Q))this.processTree(Q,this.addElement)}}matchElement(H){return this.delegate.matchElement(H)}matchElementsInTree(H=this.element){return this.delegate.matchElementsInTree(H)}processTree(H,J){for(let Q of this.matchElementsInTree(H))J.call(this,Q)}elementFromNode(H){if(H.nodeType==Node.ELEMENT_NODE)return H}elementIsActive(H){if(H.isConnected!=this.element.isConnected)return!1;else return this.element.contains(H)}addElement(H){if(!this.elements.has(H)){if(this.elementIsActive(H)){if(this.elements.add(H),this.delegate.elementMatched)this.delegate.elementMatched(H)}}}removeElement(H){if(this.elements.has(H)){if(this.elements.delete(H),this.delegate.elementUnmatched)this.delegate.elementUnmatched(H)}}}class vH{constructor(H,J,Q){this.attributeName=J,this.delegate=Q,this.elementObserver=new fH(H,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}pause(H){this.elementObserver.pause(H)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(H){return H.hasAttribute(this.attributeName)}matchElementsInTree(H){let J=this.matchElement(H)?[H]:[],Q=Array.from(H.querySelectorAll(this.selector));return J.concat(Q)}elementMatched(H){if(this.delegate.elementMatchedAttribute)this.delegate.elementMatchedAttribute(H,this.attributeName)}elementUnmatched(H){if(this.delegate.elementUnmatchedAttribute)this.delegate.elementUnmatchedAttribute(H,this.attributeName)}elementAttributeChanged(H,J){if(this.delegate.elementAttributeValueChanged&&this.attributeName==J)this.delegate.elementAttributeValueChanged(H,J)}}function ZX(H,J,Q){qJ(H,J).add(Q)}function $X(H,J,Q){qJ(H,J).delete(Q),GX(H,J)}function qJ(H,J){let Q=H.get(J);if(!Q)Q=new Set,H.set(J,Q);return Q}function GX(H,J){let Q=H.get(J);if(Q!=null&&Q.size==0)H.delete(J)}class d{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){return Array.from(this.valuesByKey.values()).reduce((J,Q)=>J.concat(Array.from(Q)),[])}get size(){return Array.from(this.valuesByKey.values()).reduce((J,Q)=>J+Q.size,0)}add(H,J){ZX(this.valuesByKey,H,J)}delete(H,J){$X(this.valuesByKey,H,J)}has(H,J){let Q=this.valuesByKey.get(H);return Q!=null&&Q.has(J)}hasKey(H){return this.valuesByKey.has(H)}hasValue(H){return Array.from(this.valuesByKey.values()).some((Q)=>Q.has(H))}getValuesForKey(H){let J=this.valuesByKey.get(H);return J?Array.from(J):[]}getKeysForValue(H){return Array.from(this.valuesByKey).filter(([J,Q])=>Q.has(H)).map(([J,Q])=>J)}}class UJ{constructor(H,J,Q,X){this._selector=J,this.details=X,this.elementObserver=new fH(H,this),this.delegate=Q,this.matchesByElement=new d}get started(){return this.elementObserver.started}get selector(){return this._selector}set selector(H){this._selector=H,this.refresh()}start(){this.elementObserver.start()}pause(H){this.elementObserver.pause(H)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get element(){return this.elementObserver.element}matchElement(H){let{selector:J}=this;if(J){let Q=H.matches(J);if(this.delegate.selectorMatchElement)return Q&&this.delegate.selectorMatchElement(H,this.details);return Q}else return!1}matchElementsInTree(H){let{selector:J}=this;if(J){let Q=this.matchElement(H)?[H]:[],X=Array.from(H.querySelectorAll(J)).filter((Y)=>this.matchElement(Y));return Q.concat(X)}else return[]}elementMatched(H){let{selector:J}=this;if(J)this.selectorMatched(H,J)}elementUnmatched(H){let J=this.matchesByElement.getKeysForValue(H);for(let Q of J)this.selectorUnmatched(H,Q)}elementAttributeChanged(H,J){let{selector:Q}=this;if(Q){let X=this.matchElement(H),Y=this.matchesByElement.has(Q,H);if(X&&!Y)this.selectorMatched(H,Q);else if(!X&&Y)this.selectorUnmatched(H,Q)}}selectorMatched(H,J){this.delegate.selectorMatched(H,J,this.details),this.matchesByElement.add(J,H)}selectorUnmatched(H,J){this.delegate.selectorUnmatched(H,J,this.details),this.matchesByElement.delete(J,H)}}class zJ{constructor(H,J){this.element=H,this.delegate=J,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver((Q)=>this.processMutations(Q))}start(){if(!this.started)this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh()}stop(){if(this.started)this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1}refresh(){if(this.started)for(let H of this.knownAttributeNames)this.refreshAttribute(H,null)}processMutations(H){if(this.started)for(let J of H)this.processMutation(J)}processMutation(H){let J=H.attributeName;if(J)this.refreshAttribute(J,H.oldValue)}refreshAttribute(H,J){let Q=this.delegate.getStringMapKeyForAttribute(H);if(Q!=null){if(!this.stringMap.has(H))this.stringMapKeyAdded(Q,H);let X=this.element.getAttribute(H);if(this.stringMap.get(H)!=X)this.stringMapValueChanged(X,Q,J);if(X==null){let Y=this.stringMap.get(H);if(this.stringMap.delete(H),Y)this.stringMapKeyRemoved(Q,H,Y)}else this.stringMap.set(H,X)}}stringMapKeyAdded(H,J){if(this.delegate.stringMapKeyAdded)this.delegate.stringMapKeyAdded(H,J)}stringMapValueChanged(H,J,Q){if(this.delegate.stringMapValueChanged)this.delegate.stringMapValueChanged(H,J,Q)}stringMapKeyRemoved(H,J,Q){if(this.delegate.stringMapKeyRemoved)this.delegate.stringMapKeyRemoved(H,J,Q)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map((H)=>H.name)}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}class pH{constructor(H,J,Q){this.attributeObserver=new vH(H,J,this),this.delegate=Q,this.tokensByElement=new d}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}pause(H){this.attributeObserver.pause(H)}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(H){this.tokensMatched(this.readTokensForElement(H))}elementAttributeValueChanged(H){let[J,Q]=this.refreshTokensForElement(H);this.tokensUnmatched(J),this.tokensMatched(Q)}elementUnmatchedAttribute(H){this.tokensUnmatched(this.tokensByElement.getValuesForKey(H))}tokensMatched(H){H.forEach((J)=>this.tokenMatched(J))}tokensUnmatched(H){H.forEach((J)=>this.tokenUnmatched(J))}tokenMatched(H){this.delegate.tokenMatched(H),this.tokensByElement.add(H.element,H)}tokenUnmatched(H){this.delegate.tokenUnmatched(H),this.tokensByElement.delete(H.element,H)}refreshTokensForElement(H){let J=this.tokensByElement.getValuesForKey(H),Q=this.readTokensForElement(H),X=AX(J,Q).findIndex(([Y,Z])=>!qX(Y,Z));if(X==-1)return[[],[]];else return[J.slice(X),Q.slice(X)]}readTokensForElement(H){let J=this.attributeName,Q=H.getAttribute(J)||"";return WX(Q,H,J)}}function WX(H,J,Q){return H.trim().split(/\s+/).filter((X)=>X.length).map((X,Y)=>({element:J,attributeName:Q,content:X,index:Y}))}function AX(H,J){let Q=Math.max(H.length,J.length);return Array.from({length:Q},(X,Y)=>[H[Y],J[Y]])}function qX(H,J){return H&&J&&H.index==J.index&&H.content==J.content}class dH{constructor(H,J,Q){this.tokenListObserver=new pH(H,J,this),this.delegate=Q,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(H){let{element:J}=H,{value:Q}=this.fetchParseResultForToken(H);if(Q)this.fetchValuesByTokenForElement(J).set(H,Q),this.delegate.elementMatchedValue(J,Q)}tokenUnmatched(H){let{element:J}=H,{value:Q}=this.fetchParseResultForToken(H);if(Q)this.fetchValuesByTokenForElement(J).delete(H),this.delegate.elementUnmatchedValue(J,Q)}fetchParseResultForToken(H){let J=this.parseResultsByToken.get(H);if(!J)J=this.parseToken(H),this.parseResultsByToken.set(H,J);return J}fetchValuesByTokenForElement(H){let J=this.valuesByTokenByElement.get(H);if(!J)J=new Map,this.valuesByTokenByElement.set(H,J);return J}parseToken(H){try{return{value:this.delegate.parseValueForToken(H)}}catch(J){return{error:J}}}}class KJ{constructor(H,J){this.context=H,this.delegate=J,this.bindingsByAction=new Map}start(){if(!this.valueListObserver)this.valueListObserver=new dH(this.element,this.actionAttribute,this),this.valueListObserver.start()}stop(){if(this.valueListObserver)this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions()}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(H){let J=new AJ(this.context,H);this.bindingsByAction.set(H,J),this.delegate.bindingConnected(J)}disconnectAction(H){let J=this.bindingsByAction.get(H);if(J)this.bindingsByAction.delete(H),this.delegate.bindingDisconnected(J)}disconnectAllActions(){this.bindings.forEach((H)=>this.delegate.bindingDisconnected(H,!0)),this.bindingsByAction.clear()}parseValueForToken(H){let J=WJ.forToken(H,this.schema);if(J.identifier==this.identifier)return J}elementMatchedValue(H,J){this.connectAction(J)}elementUnmatchedValue(H,J){this.disconnectAction(J)}}class BJ{constructor(H,J){this.context=H,this.receiver=J,this.stringMapObserver=new zJ(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap}start(){this.stringMapObserver.start(),this.invokeChangedCallbacksForDefaultValues()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(H){if(H in this.valueDescriptorMap)return this.valueDescriptorMap[H].name}stringMapKeyAdded(H,J){let Q=this.valueDescriptorMap[J];if(!this.hasValue(H))this.invokeChangedCallback(H,Q.writer(this.receiver[H]),Q.writer(Q.defaultValue))}stringMapValueChanged(H,J,Q){let X=this.valueDescriptorNameMap[J];if(H===null)return;if(Q===null)Q=X.writer(X.defaultValue);this.invokeChangedCallback(J,H,Q)}stringMapKeyRemoved(H,J,Q){let X=this.valueDescriptorNameMap[H];if(this.hasValue(H))this.invokeChangedCallback(H,X.writer(this.receiver[H]),Q);else this.invokeChangedCallback(H,X.writer(X.defaultValue),Q)}invokeChangedCallbacksForDefaultValues(){for(let{key:H,name:J,defaultValue:Q,writer:X}of this.valueDescriptors)if(Q!=null&&!this.controller.data.has(H))this.invokeChangedCallback(J,X(Q),void 0)}invokeChangedCallback(H,J,Q){let X=`${H}Changed`,Y=this.receiver[X];if(typeof Y=="function"){let Z=this.valueDescriptorNameMap[H];try{let U=Z.reader(J),B=Q;if(Q)B=Z.reader(Q);Y.call(this.receiver,U,B)}catch(U){if(U instanceof TypeError)U.message=`Stimulus Value "${this.context.identifier}.${Z.name}" - ${U.message}`;throw U}}}get valueDescriptors(){let{valueDescriptorMap:H}=this;return Object.keys(H).map((J)=>H[J])}get valueDescriptorNameMap(){let H={};return Object.keys(this.valueDescriptorMap).forEach((J)=>{let Q=this.valueDescriptorMap[J];H[Q.name]=Q}),H}hasValue(H){let J=this.valueDescriptorNameMap[H],Q=`has${YH(J.name)}`;return this.receiver[Q]}}class _J{constructor(H,J){this.context=H,this.delegate=J,this.targetsByName=new d}start(){if(!this.tokenListObserver)this.tokenListObserver=new pH(this.element,this.attributeName,this),this.tokenListObserver.start()}stop(){if(this.tokenListObserver)this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver}tokenMatched({element:H,content:J}){if(this.scope.containsElement(H))this.connectTarget(H,J)}tokenUnmatched({element:H,content:J}){this.disconnectTarget(H,J)}connectTarget(H,J){var Q;if(!this.targetsByName.has(J,H))this.targetsByName.add(J,H),(Q=this.tokenListObserver)===null||Q===void 0||Q.pause(()=>this.delegate.targetConnected(H,J))}disconnectTarget(H,J){var Q;if(this.targetsByName.has(J,H))this.targetsByName.delete(J,H),(Q=this.tokenListObserver)===null||Q===void 0||Q.pause(()=>this.delegate.targetDisconnected(H,J))}disconnectAllTargets(){for(let H of this.targetsByName.keys)for(let J of this.targetsByName.getValuesForKey(H))this.disconnectTarget(J,H)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}function ZH(H,J){let Q=IJ(H);return Array.from(Q.reduce((X,Y)=>{return zX(Y,J).forEach((Z)=>X.add(Z)),X},new Set))}function UX(H,J){return IJ(H).reduce((X,Y)=>{return X.push(...KX(Y,J)),X},[])}function IJ(H){let J=[];while(H)J.push(H),H=Object.getPrototypeOf(H);return J.reverse()}function zX(H,J){let Q=H[J];return Array.isArray(Q)?Q:[]}function KX(H,J){let Q=H[J];return Q?Object.keys(Q).map((X)=>[X,Q[X]]):[]}class FJ{constructor(H,J){this.started=!1,this.context=H,this.delegate=J,this.outletsByName=new d,this.outletElementsByName=new d,this.selectorObserverMap=new Map,this.attributeObserverMap=new Map}start(){if(!this.started)this.outletDefinitions.forEach((H)=>{this.setupSelectorObserverForOutlet(H),this.setupAttributeObserverForOutlet(H)}),this.started=!0,this.dependentContexts.forEach((H)=>H.refresh())}refresh(){this.selectorObserverMap.forEach((H)=>H.refresh()),this.attributeObserverMap.forEach((H)=>H.refresh())}stop(){if(this.started)this.started=!1,this.disconnectAllOutlets(),this.stopSelectorObservers(),this.stopAttributeObservers()}stopSelectorObservers(){if(this.selectorObserverMap.size>0)this.selectorObserverMap.forEach((H)=>H.stop()),this.selectorObserverMap.clear()}stopAttributeObservers(){if(this.attributeObserverMap.size>0)this.attributeObserverMap.forEach((H)=>H.stop()),this.attributeObserverMap.clear()}selectorMatched(H,J,{outletName:Q}){let X=this.getOutlet(H,Q);if(X)this.connectOutlet(X,H,Q)}selectorUnmatched(H,J,{outletName:Q}){let X=this.getOutletFromMap(H,Q);if(X)this.disconnectOutlet(X,H,Q)}selectorMatchElement(H,{outletName:J}){let Q=this.selector(J),X=this.hasOutlet(H,J),Y=H.matches(`[${this.schema.controllerAttribute}~=${J}]`);if(Q)return X&&Y&&H.matches(Q);else return!1}elementMatchedAttribute(H,J){let Q=this.getOutletNameFromOutletAttributeName(J);if(Q)this.updateSelectorObserverForOutlet(Q)}elementAttributeValueChanged(H,J){let Q=this.getOutletNameFromOutletAttributeName(J);if(Q)this.updateSelectorObserverForOutlet(Q)}elementUnmatchedAttribute(H,J){let Q=this.getOutletNameFromOutletAttributeName(J);if(Q)this.updateSelectorObserverForOutlet(Q)}connectOutlet(H,J,Q){var X;if(!this.outletElementsByName.has(Q,J))this.outletsByName.add(Q,H),this.outletElementsByName.add(Q,J),(X=this.selectorObserverMap.get(Q))===null||X===void 0||X.pause(()=>this.delegate.outletConnected(H,J,Q))}disconnectOutlet(H,J,Q){var X;if(this.outletElementsByName.has(Q,J))this.outletsByName.delete(Q,H),this.outletElementsByName.delete(Q,J),(X=this.selectorObserverMap.get(Q))===null||X===void 0||X.pause(()=>this.delegate.outletDisconnected(H,J,Q))}disconnectAllOutlets(){for(let H of this.outletElementsByName.keys)for(let J of this.outletElementsByName.getValuesForKey(H))for(let Q of this.outletsByName.getValuesForKey(H))this.disconnectOutlet(Q,J,H)}updateSelectorObserverForOutlet(H){let J=this.selectorObserverMap.get(H);if(J)J.selector=this.selector(H)}setupSelectorObserverForOutlet(H){let J=this.selector(H),Q=new UJ(document.body,J,this,{outletName:H});this.selectorObserverMap.set(H,Q),Q.start()}setupAttributeObserverForOutlet(H){let J=this.attributeNameForOutletName(H),Q=new vH(this.scope.element,J,this);this.attributeObserverMap.set(H,Q),Q.start()}selector(H){return this.scope.outlets.getSelectorForOutletName(H)}attributeNameForOutletName(H){return this.scope.schema.outletAttributeForScope(this.identifier,H)}getOutletNameFromOutletAttributeName(H){return this.outletDefinitions.find((J)=>this.attributeNameForOutletName(J)===H)}get outletDependencies(){let H=new d;return this.router.modules.forEach((J)=>{let Q=J.definition.controllerConstructor;ZH(Q,"outlets").forEach((Y)=>H.add(Y,J.identifier))}),H}get outletDefinitions(){return this.outletDependencies.getKeysForValue(this.identifier)}get dependentControllerIdentifiers(){return this.outletDependencies.getValuesForKey(this.identifier)}get dependentContexts(){let H=this.dependentControllerIdentifiers;return this.router.contexts.filter((J)=>H.includes(J.identifier))}hasOutlet(H,J){return!!this.getOutlet(H,J)||!!this.getOutletFromMap(H,J)}getOutlet(H,J){return this.application.getControllerForElementAndIdentifier(H,J)}getOutletFromMap(H,J){return this.outletsByName.getValuesForKey(J).find((Q)=>Q.element===H)}get scope(){return this.context.scope}get schema(){return this.context.schema}get identifier(){return this.context.identifier}get application(){return this.context.application}get router(){return this.application.router}}class MJ{constructor(H,J){this.logDebugActivity=(Q,X={})=>{let{identifier:Y,controller:Z,element:U}=this;X=Object.assign({identifier:Y,controller:Z,element:U},X),this.application.logDebugActivity(this.identifier,Q,X)},this.module=H,this.scope=J,this.controller=new H.controllerConstructor(this),this.bindingObserver=new KJ(this,this.dispatcher),this.valueObserver=new BJ(this,this.controller),this.targetObserver=new _J(this,this),this.outletObserver=new FJ(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(Q){this.handleError(Q,"initializing controller")}}connect(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start(),this.outletObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(H){this.handleError(H,"connecting controller")}}refresh(){this.outletObserver.refresh()}disconnect(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(H){this.handleError(H,"disconnecting controller")}this.outletObserver.stop(),this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(H,J,Q={}){let{identifier:X,controller:Y,element:Z}=this;Q=Object.assign({identifier:X,controller:Y,element:Z},Q),this.application.handleError(H,`Error ${J}`,Q)}targetConnected(H,J){this.invokeControllerMethod(`${J}TargetConnected`,H)}targetDisconnected(H,J){this.invokeControllerMethod(`${J}TargetDisconnected`,H)}outletConnected(H,J,Q){this.invokeControllerMethod(`${bH(Q)}OutletConnected`,H,J)}outletDisconnected(H,J,Q){this.invokeControllerMethod(`${bH(Q)}OutletDisconnected`,H,J)}invokeControllerMethod(H,...J){let Q=this.controller;if(typeof Q[H]=="function")Q[H](...J)}}function BX(H){return _X(H,IX(H))}function _X(H,J){let Q=LX(H),X=FX(H.prototype,J);return Object.defineProperties(Q.prototype,X),Q}function IX(H){return ZH(H,"blessings").reduce((Q,X)=>{let Y=X(H);for(let Z in Y){let U=Q[Z]||{};Q[Z]=Object.assign(U,Y[Z])}return Q},{})}function FX(H,J){return PX(J).reduce((Q,X)=>{let Y=MX(H,J,X);if(Y)Object.assign(Q,{[X]:Y});return Q},{})}function MX(H,J,Q){let X=Object.getOwnPropertyDescriptor(H,Q);if(!(X&&("value"in X))){let Z=Object.getOwnPropertyDescriptor(J,Q).value;if(X)Z.get=X.get||Z.get,Z.set=X.set||Z.set;return Z}}var PX=(()=>{if(typeof Object.getOwnPropertySymbols=="function")return(H)=>[...Object.getOwnPropertyNames(H),...Object.getOwnPropertySymbols(H)];else return Object.getOwnPropertyNames})(),LX=(()=>{function H(Q){function X(){return Reflect.construct(Q,arguments,new.target)}return X.prototype=Object.create(Q.prototype,{constructor:{value:X}}),Reflect.setPrototypeOf(X,Q),X}function J(){let X=H(function(){this.a.call(this)});return X.prototype.a=function(){},new X}try{return J(),H}catch(Q){return(X)=>class Y extends X{}}})();function jX(H){return{identifier:H.identifier,controllerConstructor:BX(H.controllerConstructor)}}class PJ{constructor(H,J){this.application=H,this.definition=jX(J),this.contextsByScope=new WeakMap,this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(H){let J=this.fetchContextForScope(H);this.connectedContexts.add(J),J.connect()}disconnectContextForScope(H){let J=this.contextsByScope.get(H);if(J)this.connectedContexts.delete(J),J.disconnect()}fetchContextForScope(H){let J=this.contextsByScope.get(H);if(!J)J=new MJ(this,H),this.contextsByScope.set(H,J);return J}}class LJ{constructor(H){this.scope=H}has(H){return this.data.has(this.getDataKey(H))}get(H){return this.getAll(H)[0]}getAll(H){let J=this.data.get(this.getDataKey(H))||"";return QX(J)}getAttributeName(H){return this.data.getAttributeNameForKey(this.getDataKey(H))}getDataKey(H){return`${H}-class`}get data(){return this.scope.data}}class jJ{constructor(H){this.scope=H}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(H){let J=this.getAttributeNameForKey(H);return this.element.getAttribute(J)}set(H,J){let Q=this.getAttributeNameForKey(H);return this.element.setAttribute(Q,J),this.get(H)}has(H){let J=this.getAttributeNameForKey(H);return this.element.hasAttribute(J)}delete(H){if(this.has(H)){let J=this.getAttributeNameForKey(H);return this.element.removeAttribute(J),!0}else return!1}getAttributeNameForKey(H){return`data-${this.identifier}-${GJ(H)}`}}class CJ{constructor(H){this.warnedKeysByObject=new WeakMap,this.logger=H}warn(H,J,Q){let X=this.warnedKeysByObject.get(H);if(!X)X=new Set,this.warnedKeysByObject.set(H,X);if(!X.has(J))X.add(J),this.logger.warn(Q,H)}}function kH(H,J){return`[${H}~="${J}"]`}class SJ{constructor(H){this.scope=H}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(H){return this.find(H)!=null}find(...H){return H.reduce((J,Q)=>J||this.findTarget(Q)||this.findLegacyTarget(Q),void 0)}findAll(...H){return H.reduce((J,Q)=>[...J,...this.findAllTargets(Q),...this.findAllLegacyTargets(Q)],[])}findTarget(H){let J=this.getSelectorForTargetName(H);return this.scope.findElement(J)}findAllTargets(H){let J=this.getSelectorForTargetName(H);return this.scope.findAllElements(J)}getSelectorForTargetName(H){let J=this.schema.targetAttributeForScope(this.identifier);return kH(J,H)}findLegacyTarget(H){let J=this.getLegacySelectorForTargetName(H);return this.deprecate(this.scope.findElement(J),H)}findAllLegacyTargets(H){let J=this.getLegacySelectorForTargetName(H);return this.scope.findAllElements(J).map((Q)=>this.deprecate(Q,H))}getLegacySelectorForTargetName(H){let J=`${this.identifier}.${H}`;return kH(this.schema.targetAttribute,J)}deprecate(H,J){if(H){let{identifier:Q}=this,X=this.schema.targetAttribute,Y=this.schema.targetAttributeForScope(Q);this.guide.warn(H,`target:${J}`,`Please replace ${X}="${Q}.${J}" with ${Y}="${J}". The ${X} attribute is deprecated and will be removed in a future version of Stimulus.`)}return H}get guide(){return this.scope.guide}}class wJ{constructor(H,J){this.scope=H,this.controllerElement=J}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(H){return this.find(H)!=null}find(...H){return H.reduce((J,Q)=>J||this.findOutlet(Q),void 0)}findAll(...H){return H.reduce((J,Q)=>[...J,...this.findAllOutlets(Q)],[])}getSelectorForOutletName(H){let J=this.schema.outletAttributeForScope(this.identifier,H);return this.controllerElement.getAttribute(J)}findOutlet(H){let J=this.getSelectorForOutletName(H);if(J)return this.findElement(J,H)}findAllOutlets(H){let J=this.getSelectorForOutletName(H);return J?this.findAllElements(J,H):[]}findElement(H,J){return this.scope.queryElements(H).filter((X)=>this.matchesElement(X,H,J))[0]}findAllElements(H,J){return this.scope.queryElements(H).filter((X)=>this.matchesElement(X,H,J))}matchesElement(H,J,Q){let X=H.getAttribute(this.scope.schema.controllerAttribute)||"";return H.matches(J)&&X.split(" ").includes(Q)}}class cH{constructor(H,J,Q,X){this.targets=new SJ(this),this.classes=new LJ(this),this.data=new jJ(this),this.containsElement=(Y)=>{return Y.closest(this.controllerSelector)===this.element},this.schema=H,this.element=J,this.identifier=Q,this.guide=new CJ(X),this.outlets=new wJ(this.documentScope,J)}findElement(H){return this.element.matches(H)?this.element:this.queryElements(H).find(this.containsElement)}findAllElements(H){return[...this.element.matches(H)?[this.element]:[],...this.queryElements(H).filter(this.containsElement)]}queryElements(H){return Array.from(this.element.querySelectorAll(H))}get controllerSelector(){return kH(this.schema.controllerAttribute,this.identifier)}get isDocumentScope(){return this.element===document.documentElement}get documentScope(){return this.isDocumentScope?this:new cH(this.schema,document.documentElement,this.identifier,this.guide.logger)}}class EJ{constructor(H,J,Q){this.element=H,this.schema=J,this.delegate=Q,this.valueListObserver=new dH(this.element,this.controllerAttribute,this),this.scopesByIdentifierByElement=new WeakMap,this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(H){let{element:J,content:Q}=H;return this.parseValueForElementAndIdentifier(J,Q)}parseValueForElementAndIdentifier(H,J){let Q=this.fetchScopesByIdentifierForElement(H),X=Q.get(J);if(!X)X=this.delegate.createScopeForElementAndIdentifier(H,J),Q.set(J,X);return X}elementMatchedValue(H,J){let Q=(this.scopeReferenceCounts.get(J)||0)+1;if(this.scopeReferenceCounts.set(J,Q),Q==1)this.delegate.scopeConnected(J)}elementUnmatchedValue(H,J){let Q=this.scopeReferenceCounts.get(J);if(Q){if(this.scopeReferenceCounts.set(J,Q-1),Q==1)this.delegate.scopeDisconnected(J)}}fetchScopesByIdentifierForElement(H){let J=this.scopesByIdentifierByElement.get(H);if(!J)J=new Map,this.scopesByIdentifierByElement.set(H,J);return J}}class RJ{constructor(H){this.application=H,this.scopeObserver=new EJ(this.element,this.schema,this),this.scopesByIdentifier=new d,this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce((H,J)=>H.concat(J.contexts),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(H){this.unloadIdentifier(H.identifier);let J=new PJ(this.application,H);this.connectModule(J);let Q=H.controllerConstructor.afterLoad;if(Q)Q.call(H.controllerConstructor,H.identifier,this.application)}unloadIdentifier(H){let J=this.modulesByIdentifier.get(H);if(J)this.disconnectModule(J)}getContextForElementAndIdentifier(H,J){let Q=this.modulesByIdentifier.get(J);if(Q)return Q.contexts.find((X)=>X.element==H)}proposeToConnectScopeForElementAndIdentifier(H,J){let Q=this.scopeObserver.parseValueForElementAndIdentifier(H,J);if(Q)this.scopeObserver.elementMatchedValue(Q.element,Q);else console.error(`Couldn't find or create scope for identifier: "${J}" and element:`,H)}handleError(H,J,Q){this.application.handleError(H,J,Q)}createScopeForElementAndIdentifier(H,J){return new cH(this.schema,H,J,this.logger)}scopeConnected(H){this.scopesByIdentifier.add(H.identifier,H);let J=this.modulesByIdentifier.get(H.identifier);if(J)J.connectContextForScope(H)}scopeDisconnected(H){this.scopesByIdentifier.delete(H.identifier,H);let J=this.modulesByIdentifier.get(H.identifier);if(J)J.disconnectContextForScope(H)}connectModule(H){this.modulesByIdentifier.set(H.identifier,H),this.scopesByIdentifier.getValuesForKey(H.identifier).forEach((Q)=>H.connectContextForScope(Q))}disconnectModule(H){this.modulesByIdentifier.delete(H.identifier),this.scopesByIdentifier.getValuesForKey(H.identifier).forEach((Q)=>H.disconnectContextForScope(Q))}}var CX={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:(H)=>`data-${H}-target`,outletAttributeForScope:(H,J)=>`data-${H}-${J}-outlet`,keyMappings:Object.assign(Object.assign({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"},e1("abcdefghijklmnopqrstuvwxyz".split("").map((H)=>[H,H]))),e1("0123456789".split("").map((H)=>[H,H])))};function e1(H){return H.reduce((J,[Q,X])=>Object.assign(Object.assign({},J),{[Q]:X}),{})}class uH{constructor(H=document.documentElement,J=CX){this.logger=console,this.debug=!1,this.logDebugActivity=(Q,X,Y={})=>{if(this.debug)this.logFormattedMessage(Q,X,Y)},this.element=H,this.schema=J,this.dispatcher=new $J(this),this.router=new RJ(this),this.actionDescriptorFilters=Object.assign({},lQ)}static start(H,J){let Q=new this(H,J);return Q.start(),Q}async start(){await SX(),this.logDebugActivity("application","starting"),this.dispatcher.start(),this.router.start(),this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}register(H,J){this.load({identifier:H,controllerConstructor:J})}registerActionOption(H,J){this.actionDescriptorFilters[H]=J}load(H,...J){(Array.isArray(H)?H:[H,...J]).forEach((X)=>{if(X.controllerConstructor.shouldLoad)this.router.loadDefinition(X)})}unload(H,...J){(Array.isArray(H)?H:[H,...J]).forEach((X)=>this.router.unloadIdentifier(X))}get controllers(){return this.router.contexts.map((H)=>H.controller)}getControllerForElementAndIdentifier(H,J){let Q=this.router.getContextForElementAndIdentifier(H,J);return Q?Q.controller:null}handleError(H,J,Q){var X;this.logger.error(`%s
30
+
31
+ %o
32
+
33
+ %o`,J,H,Q),(X=window.onerror)===null||X===void 0||X.call(window,J,"",0,0,H)}logFormattedMessage(H,J,Q={}){Q=Object.assign({application:this},Q),this.logger.groupCollapsed(`${H} #${J}`),this.logger.log("details:",Object.assign({},Q)),this.logger.groupEnd()}}function SX(){return new Promise((H)=>{if(document.readyState=="loading")document.addEventListener("DOMContentLoaded",()=>H());else H()})}function wX(H){return ZH(H,"classes").reduce((Q,X)=>{return Object.assign(Q,EX(X))},{})}function EX(H){return{[`${H}Class`]:{get(){let{classes:J}=this;if(J.has(H))return J.get(H);else{let Q=J.getAttributeName(H);throw new Error(`Missing attribute "${Q}"`)}}},[`${H}Classes`]:{get(){return this.classes.getAll(H)}},[`has${YH(H)}Class`]:{get(){return this.classes.has(H)}}}}function RX(H){return ZH(H,"outlets").reduce((Q,X)=>{return Object.assign(Q,TX(X))},{})}function HJ(H,J,Q){return H.application.getControllerForElementAndIdentifier(J,Q)}function JJ(H,J,Q){let X=HJ(H,J,Q);if(X)return X;if(H.application.router.proposeToConnectScopeForElementAndIdentifier(J,Q),X=HJ(H,J,Q),X)return X}function TX(H){let J=bH(H);return{[`${J}Outlet`]:{get(){let Q=this.outlets.find(H),X=this.outlets.getSelectorForOutletName(H);if(Q){let Y=JJ(this,Q,H);if(Y)return Y;throw new Error(`The provided outlet element is missing an outlet controller "${H}" instance for host controller "${this.identifier}"`)}throw new Error(`Missing outlet element "${H}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${X}".`)}},[`${J}Outlets`]:{get(){let Q=this.outlets.findAll(H);if(Q.length>0)return Q.map((X)=>{let Y=JJ(this,X,H);if(Y)return Y;console.warn(`The provided outlet element is missing an outlet controller "${H}" instance for host controller "${this.identifier}"`,X)}).filter((X)=>X);return[]}},[`${J}OutletElement`]:{get(){let Q=this.outlets.find(H),X=this.outlets.getSelectorForOutletName(H);if(Q)return Q;else throw new Error(`Missing outlet element "${H}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${X}".`)}},[`${J}OutletElements`]:{get(){return this.outlets.findAll(H)}},[`has${YH(J)}Outlet`]:{get(){return this.outlets.has(H)}}}}function VX(H){return ZH(H,"targets").reduce((Q,X)=>{return Object.assign(Q,DX(X))},{})}function DX(H){return{[`${H}Target`]:{get(){let J=this.targets.find(H);if(J)return J;else throw new Error(`Missing target element "${H}" for "${this.identifier}" controller`)}},[`${H}Targets`]:{get(){return this.targets.findAll(H)}},[`has${YH(H)}Target`]:{get(){return this.targets.has(H)}}}}function OX(H){let J=UX(H,"values"),Q={valueDescriptorMap:{get(){return J.reduce((X,Y)=>{let Z=TJ(Y,this.identifier),U=this.data.getAttributeNameForKey(Z.key);return Object.assign(X,{[U]:Z})},{})}}};return J.reduce((X,Y)=>{return Object.assign(X,xX(Y))},Q)}function xX(H,J){let Q=TJ(H,J),{key:X,name:Y,reader:Z,writer:U}=Q;return{[Y]:{get(){let B=this.data.get(X);if(B!==null)return Z(B);else return Q.defaultValue},set(B){if(B===void 0)this.data.delete(X);else this.data.set(X,U(B))}},[`has${YH(Y)}`]:{get(){return this.data.has(X)||Q.hasCustomDefaultValue}}}}function TJ([H,J],Q){return yX({controller:Q,token:H,typeDefinition:J})}function PH(H){switch(H){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function XH(H){switch(typeof H){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}if(Array.isArray(H))return"array";if(Object.prototype.toString.call(H)==="[object Object]")return"object"}function hX(H){let{controller:J,token:Q,typeObject:X}=H,Y=l1(X.type),Z=l1(X.default),U=Y&&Z,B=Y&&!Z,D=!Y&&Z,R=PH(X.type),b=XH(H.typeObject.default);if(B)return R;if(D)return b;if(R!==b){let y=J?`${J}.${Q}`:Q;throw new Error(`The specified default value for the Stimulus Value "${y}" must match the defined type "${R}". The provided default value of "${X.default}" is of type "${b}".`)}if(U)return R}function gX(H){let{controller:J,token:Q,typeDefinition:X}=H,Z=hX({controller:J,token:Q,typeObject:X}),U=XH(X),B=PH(X),D=Z||U||B;if(D)return D;let R=J?`${J}.${X}`:Q;throw new Error(`Unknown value type "${R}" for "${Q}" value`)}function bX(H){let J=PH(H);if(J)return QJ[J];let Q=yH(H,"default"),X=yH(H,"type"),Y=H;if(Q)return Y.default;if(X){let{type:Z}=Y,U=PH(Z);if(U)return QJ[U]}return H}function yX(H){let{token:J,typeDefinition:Q}=H,X=`${GJ(J)}-value`,Y=gX(H);return{type:Y,key:X,name:NH(X),get defaultValue(){return bX(Q)},get hasCustomDefaultValue(){return XH(Q)!==void 0},reader:kX[Y],writer:XJ[Y]||XJ.default}}var QJ={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},kX={array(H){let J=JSON.parse(H);if(!Array.isArray(J))throw new TypeError(`expected value of type "array" but instead got value "${H}" of type "${XH(J)}"`);return J},boolean(H){return!(H=="0"||String(H).toLowerCase()=="false")},number(H){return Number(H.replace(/_/g,""))},object(H){let J=JSON.parse(H);if(J===null||typeof J!="object"||Array.isArray(J))throw new TypeError(`expected value of type "object" but instead got value "${H}" of type "${XH(J)}"`);return J},string(H){return H}},XJ={default:NX,array:YJ,object:YJ};function YJ(H){return JSON.stringify(H)}function NX(H){return`${H}`}class N{constructor(H){this.context=H}static get shouldLoad(){return!0}static afterLoad(H,J){return}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(H,{target:J=this.element,detail:Q={},prefix:X=this.identifier,bubbles:Y=!0,cancelable:Z=!0}={}){let U=X?`${X}:${H}`:H,B=new CustomEvent(U,{detail:Q,bubbles:Y,cancelable:Z});return J.dispatchEvent(B),B}}N.blessings=[wX,VX,OX,RX];N.targets=[];N.outlets=[];N.values={};class sH extends N{sheets=[];moveFocus=(H)=>{let{key:J}=H;if(J==="Tab")H.preventDefault(),document.querySelector(".table .cell[data-xy]")?.click();else if(J==="ArrowRight")this.sheets[Number(H.target.dataset.x)+1]?.focus();else if(J==="ArrowLeft")this.sheets[Number(H.target.dataset.x)-1]?.focus()};connect=()=>{this.sheets=[...this.element.querySelectorAll("[data-x]")],this.sheets.forEach((H)=>{if(H.classList.contains("active"))H.focus();H.addEventListener("keydown",this.moveFocus)})}}class LH extends N{static arrowKeys=["ArrowDown","ArrowLeft","ArrowRight","ArrowUp"];csrf=document.querySelector("meta[name=csrf-token]")?.content;flash=document.querySelector(".flash");input=document.createElement("input");cell=this.input;cells={};columnNames=[];ids=[];editMode=!1;prevValue="";update=()=>{let H=window.location.pathname,[J,Q]=this.getPosition(),{cell:X,prevValue:Y,input:{value:Z}}=this;if(Z===Y)return;fetch(`${H}/${this.ids[Q]}?column_name=${this.columnNames[J]}&value=${Z}`,{method:"PUT",headers:{"Content-Type":"application/json","X-CSRF-Token":this.csrf??""}}).then((U)=>U.json()).then((U)=>{if(U){let B=document.createElement("span");B.classList.add("alert"),B.innerHTML=U,X.innerHTML=Y,X.click(),this.flash.replaceChildren(B),setTimeout(()=>B.remove(),5000)}})};getPosition=()=>this.cell.dataset.xy.split(",").map(Number);setCell=(H)=>{if(!H)return;if(this.editMode)this.update(),this.editMode=!1,this.cell.innerHTML=this.input.value,this.cell.scrollLeft=0;this.cell=H,H.focus()};enableEditMode=()=>{if(!this.cell.classList.contains("readonly"))this.editMode=!0,this.prevValue=this.input.value=this.cell.innerHTML,this.cell.replaceChildren(this.input),this.input.select()};focus=(H)=>{let J=H.target;if(J!==this.cell&&J.classList.contains("cell"))this.setCell(H.target);else if(!this.editMode)this.enableEditMode()};moveFocus=(H)=>{let{key:J}=H;if(this.editMode){if(J==="Enter"){let[Q,X]=this.getPosition();this.setCell(this.cells[`${Q},${X+1}`])}}else if(J==="Enter")this.enableEditMode();else if(J==="Tab")H.preventDefault(),document.querySelector(".sheets .active").focus();else if(LH.arrowKeys.includes(J)){let Q=J==="ArrowDown"?[0,1]:J==="ArrowRight"?[1,0]:J==="ArrowUp"?[0,-1]:[-1,0],[X,Y]=this.getPosition().map((U,B)=>U+Q[B]),Z=this.cells[`${X},${Y}`];if(Q[0])for(let U=X;!Z&&U!==0&&U!==this.columnNames.length;U+=Q[0])Z=this.cells[`${U},${Y}`];this.setCell(Z)}};addCell=(H)=>{this.cells[H.dataset.xy]=H,H.addEventListener("click",this.focus),H.addEventListener("keydown",this.moveFocus)};connect=()=>{this.element.querySelectorAll(".cell[data-xy]").forEach((H)=>{this.addCell(H)}),this.columnNames=[...this.element.querySelectorAll(".header")].map((H)=>H.dataset.name),this.ids=[...this.element.querySelectorAll(".column:first-child .readonly")].map((H)=>H.innerHTML)}}var VJ=uH.start();VJ.register("nav",sH);VJ.register("sheets",LH);
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Hotsheet
4
- class ApplicationController < ActionController::Base
5
- include Pagy::Backend
6
- end
3
+ class Hotsheet::ApplicationController < ActionController::Base
4
+ protect_from_forgery with: :exception
7
5
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Hotsheet::SheetsController < Hotsheet::ApplicationController
4
+ before_action :set_sheet
5
+ before_action :set_column, only: :update
6
+ before_action :set_resource, only: :update
7
+
8
+ def index
9
+ @columns = @sheet.columns
10
+ @cells = @sheet.cells_for @columns
11
+ end
12
+
13
+ def update
14
+ if @resource.update params[:column_name] => params[:value]
15
+ respond
16
+ else
17
+ respond @resource.errors.full_messages.first
18
+ end
19
+ end
20
+
21
+ def error
22
+ render "error", status: :not_found
23
+ end
24
+
25
+ private
26
+
27
+ def set_sheet
28
+ @sheet = Hotsheet.sheets[params[:sheet_name]]
29
+ end
30
+
31
+ def set_column
32
+ @column = @sheet.columns[params[:column_name]]
33
+ return respond Hotsheet.t "errors.not_found" if @column.nil?
34
+
35
+ respond Hotsheet.t "errors.forbidden" unless @column.editable?
36
+ end
37
+
38
+ def set_resource
39
+ @resource = @sheet.model.find_by id: params[:id]
40
+
41
+ respond Hotsheet.t "errors.not_found" if @resource.nil?
42
+ end
43
+
44
+ def respond(message = "")
45
+ respond_to { |format| format.any { render json: message.to_json } }
46
+ end
47
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Hotsheet
4
- module ApplicationHelper
5
- include Pagy::Frontend
3
+ module Hotsheet::ApplicationHelper
4
+ def sheet_path_for(sheet_name, **args)
5
+ hotsheet.public_send :"#{sheet_name}_path", **args
6
6
  end
7
7
  end
@@ -0,0 +1,14 @@
1
+ <nav class="nav" data-controller="nav">
2
+ <ul>
3
+ <li><%= link_to Hotsheet.t("title"), root_path, class: "title" %></li>
4
+ </ul>
5
+ <ul class="sheets">
6
+ <% Hotsheet.sheets.each_with_index do |entry, index| %>
7
+ <li>
8
+ <% sheet_name, sheet = entry %>
9
+ <%= link_to sheet.model.model_name.human(count: 2), sheet_path_for(sheet_name),
10
+ class: ("active" if params[:sheet_name] == sheet_name), data: { x: index } %>
11
+ </li>
12
+ <% end %>
13
+ </ul>
14
+ </nav>
@@ -0,0 +1 @@
1
+ <h1><%= Hotsheet.t "errors.not_found" %></h1>
@@ -0,0 +1,20 @@
1
+ <div class="table" spellcheck="false" data-controller="sheets">
2
+ <% @columns.each_with_index do |entry, x_index| %>
3
+ <% column_name, column = entry %>
4
+ <% editable = column.editable? %>
5
+
6
+ <div class="column">
7
+ <span class="cell header" data-name="<%= column_name %>">
8
+ <%= @sheet.model.human_attribute_name column_name %>
9
+ </span>
10
+
11
+ <% @cells[x_index]&.each_with_index do |value, y_index| %>
12
+ <% if editable %>
13
+ <span class="cell" tabindex="0" data-xy="<%= "#{x_index},#{y_index}" %>"><%= value %></span>
14
+ <% else %>
15
+ <span class="cell readonly"><%= value %></span>
16
+ <% end %>
17
+ <% end %>
18
+ </div>
19
+ <% end %>
20
+ </div>