hr_lite 0.51.0 → 0.53.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29f3f6694be039bef5c21d9548eaf1aaf8ff7c60191b0e92e2903c9fac7769fe
4
- data.tar.gz: 361260627747e8ca8280401e985ef777cc8b267864fc6ccc0229ddf84670e939
3
+ metadata.gz: 21dc6e39c0cac6008a3b99d4fe74a6d1b81a335e5fc58fe615f1cb4a98dfd32f
4
+ data.tar.gz: 715135ae1cda08faafe28049aa51c0cac73ae4e0a6c45aeefc1889417bc5224c
5
5
  SHA512:
6
- metadata.gz: fbe31ca225879b95e882ee76b5cca183ef535c124c75616ebde7cd350bc03bff252febf09d6e7375f0dcf395ab19593548140667e6aa358b707be8f405c0f6f3
7
- data.tar.gz: 39472b4fffa414eaafcbb2a7fb366354608d79f91f1cabe3e41d1e5a32380a2f7b42460fe3539e726850e163cea5680b5531aa4edf5ab7e79449d16e425e4091
6
+ metadata.gz: bfb1bf34635704206cc890a4acee68684c7033b3d5dbbda67fa1b4c44b3c377e05f2f74271a30ad7174cc221d0d7bbed4d6afb244133082d64945f3066c8018f
7
+ data.tar.gz: 1f8e31b31cad07625f8540f4ed3f8e6dd3ada6e4415c91c96d34eb86d899a056d3ee9668b2cc78f71ee4d6367dc22d42de8641112b5e50f422a054ad302a6d81
data/CHANGELOG.md CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.53.0] - 2026-10-16
11
+
12
+ - HR runs inside the host's iOS and Android staff apps: pages opened by a Hotwire Native shell load Turbo (vendored 8.0.23) with `turbo-visit-control: reload`, so every visit is a full page load and the engine's plain scripts run exactly as in a browser. Browsers still get no Turbo. `config.native_app = ->(request) { … }` lets the host say which requests are its app; the default matches the Hotwire Native user agent.
13
+
14
+ ## [0.52.0] - 2026-10-16
15
+
16
+ - HR uploads documents for an employee: the person's Documents page (HR → People → a person → Documents) now has "Upload a document", the same form as My documents. Only company-wide profile managers (HR, admin) see it, and never on their own record. The document belongs to the employee, records who uploaded it, and its visibility still follows its category (an Aadhaar, PAN, passport or bank document stays with the money tier).
17
+ - Download links now expire after 5 minutes. Before, the file link behind "Open" never expired, so anyone holding a copied link could fetch the scan without signing in. Every download is still permission-checked and audited first.
18
+
19
+ ## [0.51.1] - 2026-10-16
20
+
21
+ - No "Check in again" once the day is worked in full: after checking out with the person's day done (HR's 8h 30m, less any shorter day), the button is gone and the card reads "Your day is done: 8h 45m worked." The server refuses a check-in again too. A short day still offers it as before.
22
+
10
23
  ## [0.51.0] - 2026-10-16
11
24
 
12
25
  - Shorter day on a repeat: HR or admin give a person 30, 60 or 90 minutes off the working day (so 7h at the least) on a pattern set like a calendar's custom repeat: every N days, every N weeks on chosen weekdays, or every N months on the start's date, from a start date, ending never, on a date, or after N times. No repeat means every day, as before.
@@ -0,0 +1,28 @@
1
+ /*!
2
+ Turbo 8.0.23
3
+ Copyright © 2026 37signals LLC
4
+ */
5
+ const e={eager:"eager",lazy:"lazy"};class t extends HTMLElement{static delegateConstructor=void 0;loaded=Promise.resolve();static get observedAttributes(){return["disabled","loading","src"]}constructor(){super(),this.delegate=new t.delegateConstructor(this)}connectedCallback(){this.delegate.connect()}disconnectedCallback(){this.delegate.disconnect()}reload(){return this.delegate.sourceURLReloaded()}attributeChangedCallback(e){"loading"==e?this.delegate.loadingStyleChanged():"src"==e?this.delegate.sourceURLChanged():"disabled"==e&&this.delegate.disabledChanged()}get src(){return this.getAttribute("src")}set src(e){e?this.setAttribute("src",e):this.removeAttribute("src")}get refresh(){return this.getAttribute("refresh")}set refresh(e){e?this.setAttribute("refresh",e):this.removeAttribute("refresh")}get shouldReloadWithMorph(){return this.src&&"morph"===this.refresh}get loading(){return function(t){if("lazy"===t.toLowerCase())return e.lazy;return e.eager}(this.getAttribute("loading")||"")}set loading(e){e?this.setAttribute("loading",e):this.removeAttribute("loading")}get disabled(){return this.hasAttribute("disabled")}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled")}get autoscroll(){return this.hasAttribute("autoscroll")}set autoscroll(e){e?this.setAttribute("autoscroll",""):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")}}const s={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 r(e){if("false"==e.getAttribute("data-turbo-eval"))return e;{const t=document.createElement("script"),s=w();return s&&(t.nonce=s),t.textContent=e.textContent,t.async=!1,function(e,t){for(const{name:s,value:r}of t.attributes)e.setAttribute(s,r)}(t,e),t}}function i(e,{target:t,cancelable:s,detail:r}={}){const i=new CustomEvent(e,{cancelable:s,bubbles:!0,composed:!0,detail:r});return t&&t.isConnected?t.dispatchEvent(i):document.documentElement.dispatchEvent(i),i}function n(e){e.preventDefault(),e.stopImmediatePropagation()}function o(){return"hidden"===document.visibilityState?c():a()}function a(){return new Promise((e=>requestAnimationFrame((()=>e()))))}function c(){return new Promise((e=>setTimeout((()=>e()),0)))}function l(e=""){return(new DOMParser).parseFromString(e,"text/html")}function h(e,...t){const s=function(e,t){return e.reduce(((e,s,r)=>e+s+(null==t[r]?"":t[r])),"")}(e,t).replace(/^\n/,"").split("\n"),r=s[0].match(/^\s+/),i=r?r[0].length:0;return s.map((e=>e.slice(i))).join("\n")}function d(){return Array.from({length:36}).map(((e,t)=>8==t||13==t||18==t||23==t?"-":14==t?"4":19==t?(Math.floor(4*Math.random())+8).toString(16):Math.floor(16*Math.random()).toString(16))).join("")}function u(e,...t){for(const s of t.map((t=>t?.getAttribute(e))))if("string"==typeof s)return s;return null}function m(...e){for(const t of e)"turbo-frame"==t.localName&&t.setAttribute("busy",""),t.setAttribute("aria-busy","true")}function p(...e){for(const t of e)"turbo-frame"==t.localName&&t.removeAttribute("busy"),t.removeAttribute("aria-busy")}function f(e,t=2e3){return new Promise((s=>{const r=()=>{e.removeEventListener("error",r),e.removeEventListener("load",r),s()};e.addEventListener("load",r,{once:!0}),e.addEventListener("error",r,{once:!0}),setTimeout(s,t)}))}function g(e){switch(e){case"replace":return history.replaceState;case"advance":case"restore":return history.pushState}}function b(...e){const t=u("data-turbo-action",...e);return function(e){return"advance"==e||"replace"==e||"restore"==e}(t)?t:null}function v(e){return document.querySelector(`meta[name="${e}"]`)}function S(e){const t=v(e);return t&&t.content}function w(){const e=v("csp-nonce");if(e){const{nonce:t,content:s}=e;return""==t?s:t}}function y(e,t){if(e instanceof Element)return e.closest(t)||y(e.assignedSlot||e.getRootNode()?.host,t)}function E(e){return!!e&&null==e.closest("[inert], :disabled, [hidden], details:not([open]), dialog:not([open])")&&"function"==typeof e.focus}function A(e){return Array.from(e.querySelectorAll("[autofocus]")).find(E)}function R(e){if("_blank"===e)return!1;if(e){for(const t of document.getElementsByName(e))if(t instanceof HTMLIFrameElement)return!1;return!0}return!0}function T(e){const t=y(e,"a[href], a[xlink\\:href]");if(!t)return null;if(t.href.startsWith("#"))return null;if(t.hasAttribute("download"))return null;const s=t.getAttribute("target");return s&&"_self"!==s?null:t}const L={"aria-disabled":{beforeSubmit:e=>{e.setAttribute("aria-disabled","true"),e.addEventListener("click",n)},afterSubmit:e=>{e.removeAttribute("aria-disabled"),e.removeEventListener("click",n)}},disabled:{beforeSubmit:e=>e.disabled=!0,afterSubmit:e=>e.disabled=!1}};const C=new class{#e=null;constructor(e){Object.assign(this,e)}get submitter(){return this.#e}set submitter(e){this.#e=L[e]||e}}({mode:"on",submitter:"disabled"}),P={drive:s,forms:C};function k(e){return new URL(e.toString(),document.baseURI)}function M(e){let t;return e.hash?e.hash.slice(1):(t=e.href.match(/#(.*)$/))?t[1]:void 0}function F(e,t){return k(t?.getAttribute("formaction")||e.getAttribute("action")||e.action)}function I(e){return(function(e){return function(e){return e.pathname.split("/").slice(1)}(e).slice(-1)[0]}(e).match(/\.[^.]*$/)||[])[0]||""}function q(e,t){return function(e,t){const s=O(t.origin+t.pathname);return O(e.href)===s||e.href.startsWith(s)}(e,t)&&!P.drive.unvisitableExtensions.has(I(e))}function H(e){return k(e.getAttribute("href")||"")}function B(e){return function(e){const t=M(e);return null!=t?e.href.slice(0,-(t.length+1)):e.href}(e)}function N(e,t){return k(e).href==k(t).href}function O(e){return e.endsWith("/")?e:e+"/"}class D{constructor(e){this.response=e}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 k(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(){return this.isHTML?this.response.clone().text():Promise.resolve(void 0)}header(e){return this.response.headers.get(e)}}class x extends Set{constructor(e){super(),this.maxSize=e}add(e){if(this.size>=this.maxSize){const e=this.values().next().value;this.delete(e)}super.add(e)}}const V=new x(20);function W(e,t={}){const s=new Headers(t.headers||{}),r=d();return V.add(r),s.append("X-Turbo-Request-Id",r),window.fetch(e,{...t,headers:s})}function U(e){switch(e.toLowerCase()){case"get":return _.get;case"post":return _.post;case"put":return _.put;case"patch":return _.patch;case"delete":return _.delete}}const _={get:"get",post:"post",put:"put",patch:"patch",delete:"delete"};function $(e){switch(e.toLowerCase()){case j.multipart:return j.multipart;case j.plain:return j.plain;default:return j.urlEncoded}}const j={urlEncoded:"application/x-www-form-urlencoded",multipart:"multipart/form-data",plain:"text/plain"};class z{abortController=new AbortController;#t=e=>{};constructor(e,t,s,r=new URLSearchParams,i=null,n=j.urlEncoded){const[o,a]=K(k(s),t,r,n);this.delegate=e,this.url=o,this.target=i,this.fetchOptions={credentials:"same-origin",redirect:"follow",method:t.toUpperCase(),headers:{...this.defaultHeaders},body:a,signal:this.abortSignal,referrer:this.delegate.referrer?.href},this.enctype=n}get method(){return this.fetchOptions.method}set method(e){const t=this.isSafe?this.url.searchParams:this.fetchOptions.body||new FormData,s=U(e)||_.get;this.url.search="";const[r,i]=K(this.url,s,t,this.enctype);this.url=r,this.fetchOptions.body=i,this.fetchOptions.method=s.toUpperCase()}get headers(){return this.fetchOptions.headers}set headers(e){this.fetchOptions.headers=e}get body(){return this.isSafe?this.url.searchParams:this.fetchOptions.body}set body(e){this.fetchOptions.body=e}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(){const{fetchOptions:e}=this;this.delegate.prepareRequest(this);const t=await this.#s(e);try{this.delegate.requestStarted(this),t.detail.fetchRequest?this.response=t.detail.fetchRequest.response:this.response=W(this.url.href,e);const s=await this.response;return await this.receive(s)}catch(e){if("AbortError"!==e.name)throw this.#r(e)&&this.delegate.requestErrored(this,e),e}finally{this.delegate.requestFinished(this)}}async receive(e){const t=new D(e);return i("turbo:before-fetch-response",{cancelable:!0,detail:{fetchResponse:t},target:this.target}).defaultPrevented?this.delegate.requestPreventedHandlingResponse(this,t):t.succeeded?this.delegate.requestSucceededWithResponse(this,t):this.delegate.requestFailedWithResponse(this,t),t}get defaultHeaders(){return{Accept:"text/html, application/xhtml+xml"}}get isSafe(){return G(this.method)}get abortSignal(){return this.abortController.signal}acceptResponseType(e){this.headers.Accept=[e,this.headers.Accept].join(", ")}async#s(e){const t=new Promise((e=>this.#t=e)),s=i("turbo:before-fetch-request",{cancelable:!0,detail:{fetchOptions:e,url:this.url,resume:this.#t},target:this.target});return this.url=s.detail.url,s.defaultPrevented&&await t,s}#r(e){return!i("turbo:fetch-request-error",{target:this.target,cancelable:!0,detail:{request:this,error:e}}).defaultPrevented}}function G(e){return U(e)==_.get}function K(e,t,s,r){const i=Array.from(s).length>0?new URLSearchParams(J(s)):e.searchParams;return G(t)?[X(e,i),null]:r==j.urlEncoded?[e,i]:[e,s]}function J(e){const t=[];for(const[s,r]of e)r instanceof File||t.push([s,r]);return t}function X(e,t){const s=new URLSearchParams(J(t));return e.search=s.toString(),e}class Y{started=!1;constructor(e,t){this.delegate=e,this.element=t,this.intersectionObserver=new IntersectionObserver(this.intersect)}start(){this.started||(this.started=!0,this.intersectionObserver.observe(this.element))}stop(){this.started&&(this.started=!1,this.intersectionObserver.unobserve(this.element))}intersect=e=>{const t=e.slice(-1)[0];t?.isIntersecting&&this.delegate.elementAppearedInViewport(this.element)}}class Q{static contentType="text/vnd.turbo-stream.html";static wrap(e){return"string"==typeof e?new this(function(e){const t=document.createElement("template");return t.innerHTML=e,t.content}(e)):e}constructor(e){this.fragment=function(e){for(const t of e.querySelectorAll("turbo-stream")){const e=document.importNode(t,!0);for(const t of e.templateElement.content.querySelectorAll("script"))t.replaceWith(r(t));t.replaceWith(e)}return e}(e)}}const Z=e=>e;class ee{keys=[];entries={};#i;constructor(e,t=Z){this.size=e,this.#i=t}has(e){return this.#i(e)in this.entries}get(e){if(this.has(e)){const t=this.read(e);return this.touch(e),t}}put(e,t){return this.write(e,t),this.touch(e),t}clear(){for(const e of Object.keys(this.entries))this.evict(e)}read(e){return this.entries[this.#i(e)]}write(e,t){this.entries[this.#i(e)]=t}touch(e){e=this.#i(e);const t=this.keys.indexOf(e);t>-1&&this.keys.splice(t,1),this.keys.unshift(e),this.trim()}trim(){for(const e of this.keys.splice(this.size))this.evict(e)}evict(e){delete this.entries[e]}}const te=1e4,se=new class extends ee{#n=null;#o={};constructor(e=1,t=100){super(e,B),this.prefetchDelay=t}putLater(e,t,s){this.#n=setTimeout((()=>{t.perform(),this.put(e,t,s),this.#n=null}),this.prefetchDelay)}put(e,t,s=te){super.put(e,t),this.#o[B(e)]=new Date((new Date).getTime()+s)}clear(){super.clear(),this.#n&&clearTimeout(this.#n)}evict(e){super.evict(e),delete this.#o[e]}has(e){if(super.has(e)){const t=this.#o[B(e)];return t&&t>Date.now()}return!1}},re={initialized:"initialized",requesting:"requesting",waiting:"waiting",receiving:"receiving",stopping:"stopping",stopped:"stopped"};class ie{state=re.initialized;static confirmMethod(e){return Promise.resolve(confirm(e))}constructor(e,t,s,r=!1){const i=function(e,t){const s=t?.getAttribute("formmethod")||e.getAttribute("method")||"";return U(s.toLowerCase())||_.get}(t,s),n=function(e,t){const s=k(e);G(t)&&(s.search="");return s}(function(e,t){const s="string"==typeof e.action?e.action:null;return t?.hasAttribute("formaction")?t.getAttribute("formaction")||"":e.getAttribute("action")||s||""}(t,s),i),o=function(e,t){const s=new FormData(e),r=t?.getAttribute("name"),i=t?.getAttribute("value");r&&s.append(r,i||"");return s}(t,s),a=function(e,t){return $(t?.getAttribute("formenctype")||e.enctype)}(t,s);this.delegate=e,this.formElement=t,this.submitter=s,this.fetchRequest=new z(this,i,n,o,t,a),this.mustRedirect=r}get method(){return this.fetchRequest.method}set method(e){this.fetchRequest.method=e}get action(){return this.fetchRequest.url.toString()}set action(e){this.fetchRequest.url=k(e)}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(){const{initialized:e,requesting:t}=re,s=u("data-turbo-confirm",this.submitter,this.formElement);if("string"==typeof s){const e="function"==typeof P.forms.confirm?P.forms.confirm:ie.confirmMethod;if(!await e(s,this.formElement,this.submitter))return}if(this.state==e)return this.state=t,this.fetchRequest.perform()}stop(){const{stopping:e,stopped:t}=re;if(this.state!=e&&this.state!=t)return this.state=e,this.fetchRequest.cancel(),!0}prepareRequest(e){if(!e.isSafe){const t=function(e){if(null!=e){const t=(document.cookie?document.cookie.split("; "):[]).find((t=>t.startsWith(e)));if(t){const e=t.split("=").slice(1).join("=");return e?decodeURIComponent(e):void 0}}}(S("csrf-param"))||S("csrf-token");t&&(e.headers["X-CSRF-Token"]=t)}this.requestAcceptsTurboStreamResponse(e)&&e.acceptResponseType(Q.contentType)}requestStarted(e){this.state=re.waiting,this.submitter&&P.forms.submitter.beforeSubmit(this.submitter),this.setSubmitsWith(),m(this.formElement),i("turbo:submit-start",{target:this.formElement,detail:{formSubmission:this}}),this.delegate.formSubmissionStarted(this)}requestPreventedHandlingResponse(e,t){se.clear(),this.result={success:t.succeeded,fetchResponse:t}}requestSucceededWithResponse(e,t){if(t.clientError||t.serverError)this.delegate.formSubmissionFailedWithResponse(this,t);else if(se.clear(),this.requestMustRedirect(e)&&function(e){return 200==e.statusCode&&!e.redirected}(t)){const e=new Error("Form responses must redirect to another location");this.delegate.formSubmissionErrored(this,e)}else this.state=re.receiving,this.result={success:!0,fetchResponse:t},this.delegate.formSubmissionSucceededWithResponse(this,t)}requestFailedWithResponse(e,t){this.result={success:!1,fetchResponse:t},this.delegate.formSubmissionFailedWithResponse(this,t)}requestErrored(e,t){this.result={success:!1,error:t},this.delegate.formSubmissionErrored(this,t)}requestFinished(e){this.state=re.stopped,this.submitter&&P.forms.submitter.afterSubmit(this.submitter),this.resetSubmitterText(),p(this.formElement),i("turbo:submit-end",{target:this.formElement,detail:{formSubmission:this,...this.result}}),this.delegate.formSubmissionFinished(this)}setSubmitsWith(){if(this.submitter&&this.submitsWith)if(this.submitter.matches("button"))this.originalSubmitText=this.submitter.innerHTML,this.submitter.innerHTML=this.submitsWith;else if(this.submitter.matches("input")){const e=this.submitter;this.originalSubmitText=e.value,e.value=this.submitsWith}}resetSubmitterText(){if(this.submitter&&this.originalSubmitText)if(this.submitter.matches("button"))this.submitter.innerHTML=this.originalSubmitText;else if(this.submitter.matches("input")){this.submitter.value=this.originalSubmitText}}requestMustRedirect(e){return!e.isSafe&&this.mustRedirect}requestAcceptsTurboStreamResponse(e){return!e.isSafe||function(e,...t){return t.some((t=>t&&t.hasAttribute(e)))}("data-turbo-stream",this.submitter,this.formElement)}get submitsWith(){return this.submitter?.getAttribute("data-turbo-submits-with")}}class ne{constructor(e){this.element=e}get activeElement(){return this.element.ownerDocument.activeElement}get children(){return[...this.element.children]}hasAnchor(e){return null!=this.getElementForAnchor(e)}getElementForAnchor(e){return e?this.element.querySelector(`[id='${e}'], a[name='${e}']`):null}get isConnected(){return this.element.isConnected}get firstAutofocusableElement(){return A(this.element)}get permanentElements(){return ae(this.element)}getPermanentElementById(e){return oe(this.element,e)}getPermanentElementMapForSnapshot(e){const t={};for(const s of this.permanentElements){const{id:r}=s,i=e.getPermanentElementById(r);i&&(t[r]=[s,i])}return t}}function oe(e,t){return e.querySelector(`#${t}[data-turbo-permanent]`)}function ae(e){return e.querySelectorAll("[id][data-turbo-permanent]")}class ce{started=!1;constructor(e,t){this.delegate=e,this.eventTarget=t}start(){this.started||(this.eventTarget.addEventListener("submit",this.submitCaptured,!0),this.started=!0)}stop(){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=e=>{if(!e.defaultPrevented){const t=e.target instanceof HTMLFormElement?e.target:void 0,s=e.submitter||void 0;t&&function(e,t){const s=t?.getAttribute("formmethod")||e.getAttribute("method");return"dialog"!=s}(t,s)&&function(e,t){const s=t?.getAttribute("formtarget")||e.getAttribute("target");return R(s)}(t,s)&&this.delegate.willSubmitForm(t,s)&&(e.preventDefault(),e.stopImmediatePropagation(),this.delegate.formSubmitted(t,s))}}}class le{#a=e=>{};#c=e=>{};constructor(e,t){this.delegate=e,this.element=t}scrollToAnchor(e){const t=this.snapshot.getElementForAnchor(e);t?(this.focusElement(t),this.scrollToElement(t)):this.scrollToPosition({x:0,y:0})}scrollToAnchorFromLocation(e){this.scrollToAnchor(M(e))}scrollToElement(e){e.scrollIntoView()}focusElement(e){e instanceof HTMLElement&&(e.hasAttribute("tabindex")?e.focus():(e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")))}scrollToPosition({x:e,y:t}){this.scrollRoot.scrollTo(e,t)}scrollToTop(){this.scrollToPosition({x:0,y:0})}get scrollRoot(){return window}async render(e){const{isPreview:t,shouldRender:s,willRender:r,newSnapshot:i}=e,n=r;if(s)try{this.renderPromise=new Promise((e=>this.#a=e)),this.renderer=e,await this.prepareToRenderSnapshot(e);const s=new Promise((e=>this.#c=e)),r={resume:this.#c,render:this.renderer.renderElement,renderMethod:this.renderer.renderMethod};this.delegate.allowsImmediateRender(i,r)||await s,await this.renderSnapshot(e),this.delegate.viewRenderedSnapshot(i,t,this.renderer.renderMethod),this.delegate.preloadOnLoadLinksForView(this.element),this.finishRenderingSnapshot(e)}finally{delete this.renderer,this.#a(void 0),delete this.renderPromise}else n&&this.invalidate(e.reloadReason)}invalidate(e){this.delegate.viewInvalidated(e)}async prepareToRenderSnapshot(e){this.markAsPreview(e.isPreview),await e.prepareToRender()}markAsPreview(e){e?this.element.setAttribute("data-turbo-preview",""):this.element.removeAttribute("data-turbo-preview")}markVisitDirection(e){this.element.setAttribute("data-turbo-visit-direction",e)}unmarkVisitDirection(){this.element.removeAttribute("data-turbo-visit-direction")}async renderSnapshot(e){await e.render()}finishRenderingSnapshot(e){e.finishRendering()}}class he extends le{missing(){this.element.innerHTML='<strong class="turbo-frame-error">Content missing</strong>'}get snapshot(){return new ne(this.element)}}class de{constructor(e,t){this.delegate=e,this.element=t}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=e=>{this.clickEventIsSignificant(e)?this.clickEvent=e:delete this.clickEvent};linkClicked=e=>{this.clickEvent&&this.clickEventIsSignificant(e)&&this.delegate.shouldInterceptLinkClick(e.target,e.detail.url,e.detail.originalEvent)&&(this.clickEvent.preventDefault(),e.preventDefault(),this.delegate.linkClickIntercepted(e.target,e.detail.url,e.detail.originalEvent)),delete this.clickEvent};willVisit=e=>{delete this.clickEvent};clickEventIsSignificant(e){const t=e.composed?e.target?.parentElement:e.target,s=T(t)||t;return s instanceof Element&&s.closest("turbo-frame, html")==this.element}}class ue{started=!1;constructor(e,t){this.delegate=e,this.eventTarget=t}start(){this.started||(this.eventTarget.addEventListener("click",this.clickCaptured,!0),this.started=!0)}stop(){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=e=>{if(e instanceof MouseEvent&&this.clickEventIsSignificant(e)){const t=T(e.composedPath&&e.composedPath()[0]||e.target);if(t&&R(t.target)){const s=H(t);this.delegate.willFollowLinkToLocation(t,s,e)&&(e.preventDefault(),this.delegate.followedLinkToLocation(t,s))}}};clickEventIsSignificant(e){return!(e.target&&e.target.isContentEditable||e.defaultPrevented||e.which>1||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey)}}class me{constructor(e,t){this.delegate=e,this.linkInterceptor=new ue(this,t)}start(){this.linkInterceptor.start()}stop(){this.linkInterceptor.stop()}canPrefetchRequestToLocation(e,t){return!1}prefetchAndCacheRequestToLocation(e,t){}willFollowLinkToLocation(e,t,s){return this.delegate.willSubmitFormLinkToLocation(e,t,s)&&(e.hasAttribute("data-turbo-method")||e.hasAttribute("data-turbo-stream"))}followedLinkToLocation(e,t){const s=document.createElement("form");for(const[e,r]of t.searchParams)s.append(Object.assign(document.createElement("input"),{type:"hidden",name:e,value:r}));const r=Object.assign(t,{search:""});s.setAttribute("data-turbo","true"),s.setAttribute("action",r.href),s.setAttribute("hidden","");const i=e.getAttribute("data-turbo-method");i&&s.setAttribute("method",i);const n=e.getAttribute("data-turbo-frame");n&&s.setAttribute("data-turbo-frame",n);const o=b(e);o&&s.setAttribute("data-turbo-action",o);const a=e.getAttribute("data-turbo-confirm");a&&s.setAttribute("data-turbo-confirm",a);e.hasAttribute("data-turbo-stream")&&s.setAttribute("data-turbo-stream",""),this.delegate.submittedFormLinkToLocation(e,t,s),document.body.appendChild(s),s.addEventListener("turbo:submit-end",(()=>s.remove()),{once:!0}),requestAnimationFrame((()=>s.requestSubmit()))}}class pe{static async preservingPermanentElements(e,t,s){const r=new this(e,t);r.enter(),await s(),r.leave()}constructor(e,t){this.delegate=e,this.permanentElementMap=t}enter(){for(const e in this.permanentElementMap){const[t,s]=this.permanentElementMap[e];this.delegate.enteringBardo(t,s),this.replaceNewPermanentElementWithPlaceholder(s)}}leave(){for(const e in this.permanentElementMap){const[t]=this.permanentElementMap[e];this.replaceCurrentPermanentElementWithClone(t),this.replacePlaceholderWithPermanentElement(t),this.delegate.leavingBardo(t)}}replaceNewPermanentElementWithPlaceholder(e){const t=function(e){const t=document.createElement("meta");return t.setAttribute("name","turbo-permanent-placeholder"),t.setAttribute("content",e.id),t}(e);e.replaceWith(t)}replaceCurrentPermanentElementWithClone(e){const t=e.cloneNode(!0);e.replaceWith(t)}replacePlaceholderWithPermanentElement(e){const t=this.getPlaceholderById(e.id);t?.replaceWith(e)}getPlaceholderById(e){return this.placeholders.find((t=>t.content==e))}get placeholders(){return[...document.querySelectorAll("meta[name=turbo-permanent-placeholder][content]")]}}class fe{#l=null;static renderElement(e,t){}constructor(e,t,s,r=!0){this.currentSnapshot=e,this.newSnapshot=t,this.isPreview=s,this.willRender=r,this.renderElement=this.constructor.renderElement,this.promise=new Promise(((e,t)=>this.resolvingFunctions={resolve:e,reject:t}))}get shouldRender(){return!0}get shouldAutofocus(){return!0}get reloadReason(){}prepareToRender(){}render(){}finishRendering(){this.resolvingFunctions&&(this.resolvingFunctions.resolve(),delete this.resolvingFunctions)}async preservingPermanentElements(e){await pe.preservingPermanentElements(this,this.permanentElementMap,e)}focusFirstAutofocusableElement(){if(this.shouldAutofocus){const e=this.connectedSnapshot.firstAutofocusableElement;e&&e.focus()}}enteringBardo(e){this.#l||e.contains(this.currentSnapshot.activeElement)&&(this.#l=this.currentSnapshot.activeElement)}leavingBardo(e){e.contains(this.#l)&&this.#l instanceof HTMLElement&&(this.#l.focus(),this.#l=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 ge extends fe{static renderElement(e,t){const s=document.createRange();s.selectNodeContents(e),s.deleteContents();const r=t,i=r.ownerDocument?.createRange();i&&(i.selectNodeContents(r),e.appendChild(i.extractContents()))}constructor(e,t,s,r,i,n=!0){super(t,s,r,i,n),this.delegate=e}get shouldRender(){return!0}async render(){await o(),this.preservingPermanentElements((()=>{this.loadFrameElement()})),this.scrollFrameIntoView(),await o(),this.focusFirstAutofocusableElement(),await o(),this.activateScriptElements()}loadFrameElement(){this.delegate.willRenderFrame(this.currentElement,this.newElement),this.renderElement(this.currentElement,this.newElement)}scrollFrameIntoView(){if(this.currentElement.autoscroll||this.newElement.autoscroll){const s=this.currentElement.firstElementChild,r=(e=this.currentElement.getAttribute("data-autoscroll-block"),t="end","end"==e||"start"==e||"center"==e||"nearest"==e?e:t),i=function(e,t){return"auto"==e||"smooth"==e?e:t}(this.currentElement.getAttribute("data-autoscroll-behavior"),"auto");if(s)return s.scrollIntoView({block:r,behavior:i}),!0}var e,t;return!1}activateScriptElements(){for(const e of this.newScriptElements){const t=r(e);e.replaceWith(t)}}get newScriptElements(){return this.currentElement.querySelectorAll("script")}}var be=function(){const e=()=>{},t={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:e,afterNodeAdded:e,beforeNodeMorphed:e,afterNodeMorphed:e,beforeNodeRemoved:e,afterNodeRemoved:e,beforeAttributeUpdated:e},head:{style:"merge",shouldPreserve:e=>"true"===e.getAttribute("im-preserve"),shouldReAppend:e=>"true"===e.getAttribute("im-re-append"),shouldRemove:e,afterHeadMorphed:e},restoreFocus:!0};const s=function(){function e(e,t,s,i){if(!1===i.callbacks.beforeNodeAdded(t))return null;if(i.idMap.has(t)){const n=document.createElement(t.tagName);return e.insertBefore(n,s),r(n,t,i),i.callbacks.afterNodeAdded(n),n}{const r=document.importNode(t,!0);return e.insertBefore(r,s),i.callbacks.afterNodeAdded(r),r}}const t=function(){function e(e,t,s){let r=e.idMap.get(t),i=e.idMap.get(s);if(!i||!r)return!1;for(const e of r)if(i.has(e))return!0;return!1}function t(e,t){const s=e,r=t;return s.nodeType===r.nodeType&&s.tagName===r.tagName&&(!s.getAttribute?.("id")||s.getAttribute?.("id")===r.getAttribute?.("id"))}return function(s,r,i,n){let o=null,a=r.nextSibling,c=0,l=i;for(;l&&l!=n;){if(t(l,r)){if(e(s,l,r))return l;null===o&&(s.idMap.has(l)||(o=l))}if(null===o&&a&&t(l,a)&&(c++,a=a.nextSibling,c>=2&&(o=void 0)),s.activeElementAndParents.includes(l))break;l=l.nextSibling}return o||null}}();function s(e,t){if(e.idMap.has(t))o(e.pantry,t,null);else{if(!1===e.callbacks.beforeNodeRemoved(t))return;t.parentNode?.removeChild(t),e.callbacks.afterNodeRemoved(t)}}function i(e,t,r){let i=t;for(;i&&i!==r;){let t=i;i=i.nextSibling,s(e,t)}return i}function n(e,t,s,r){const i=r.target.getAttribute?.("id")===t&&r.target||r.target.querySelector(`[id="${t}"]`)||r.pantry.querySelector(`[id="${t}"]`);return function(e,t){const s=e.getAttribute("id");for(;e=e.parentNode;){let r=t.idMap.get(e);r&&(r.delete(s),r.size||t.idMap.delete(e))}}(i,r),o(e,i,s),i}function o(e,t,s){if(e.moveBefore)try{e.moveBefore(t,s)}catch(r){e.insertBefore(t,s)}else e.insertBefore(t,s)}return function(o,a,c,l=null,h=null){a instanceof HTMLTemplateElement&&c instanceof HTMLTemplateElement&&(a=a.content,c=c.content),l||=a.firstChild;for(const s of c.childNodes){if(l&&l!=h){const e=t(o,s,l,h);if(e){e!==l&&i(o,l,e),r(e,s,o),l=e.nextSibling;continue}}if(s instanceof Element){const e=s.getAttribute("id");if(o.persistentIds.has(e)){const t=n(a,e,l,o);r(t,s,o),l=t.nextSibling;continue}}const c=e(a,s,l,o);c&&(l=c.nextSibling)}for(;l&&l!=h;){const e=l;l=l.nextSibling,s(o,e)}}}(),r=function(){function e(e,s,r,i){const n=s[r];if(n!==e[r]){const o=t(r,e,"update",i);o||(e[r]=s[r]),n?o||e.setAttribute(r,""):t(r,e,"remove",i)||e.removeAttribute(r)}}function t(e,t,s,r){return!("value"!==e||!r.ignoreActiveValue||t!==document.activeElement)||!1===r.callbacks.beforeAttributeUpdated(e,t,s)}function r(e,t){return!!t.ignoreActiveValue&&e===document.activeElement&&e!==document.body}return function(n,o,a){return a.ignoreActive&&n===document.activeElement?null:(!1===a.callbacks.beforeNodeMorphed(n,o)||(n instanceof HTMLHeadElement&&a.head.ignore||(n instanceof HTMLHeadElement&&"morph"!==a.head.style?i(n,o,a):(!function(s,i,n){let o=i.nodeType;if(1===o){const o=s,a=i,c=o.attributes,l=a.attributes;for(const e of l)t(e.name,o,"update",n)||o.getAttribute(e.name)!==e.value&&o.setAttribute(e.name,e.value);for(let e=c.length-1;0<=e;e--){const s=c[e];if(s&&!a.hasAttribute(s.name)){if(t(s.name,o,"remove",n))continue;o.removeAttribute(s.name)}}r(o,n)||function(s,r,i){if(s instanceof HTMLInputElement&&r instanceof HTMLInputElement&&"file"!==r.type){let n=r.value,o=s.value;e(s,r,"checked",i),e(s,r,"disabled",i),r.hasAttribute("value")?o!==n&&(t("value",s,"update",i)||(s.setAttribute("value",n),s.value=n)):t("value",s,"remove",i)||(s.value="",s.removeAttribute("value"))}else if(s instanceof HTMLOptionElement&&r instanceof HTMLOptionElement)e(s,r,"selected",i);else if(s instanceof HTMLTextAreaElement&&r instanceof HTMLTextAreaElement){let e=r.value,n=s.value;if(t("value",s,"update",i))return;e!==n&&(s.value=e),s.firstChild&&s.firstChild.nodeValue!==e&&(s.firstChild.nodeValue=e)}}(o,a,n)}8!==o&&3!==o||s.nodeValue!==i.nodeValue&&(s.nodeValue=i.nodeValue)}(n,o,a),r(n,a)||s(a,n,o))),a.callbacks.afterNodeMorphed(n,o)),n)}}();function i(e,t,s){let r=[],i=[],n=[],o=[],a=new Map;for(const e of t.children)a.set(e.outerHTML,e);for(const t of e.children){let e=a.has(t.outerHTML),r=s.head.shouldReAppend(t),c=s.head.shouldPreserve(t);e||c?r?i.push(t):(a.delete(t.outerHTML),n.push(t)):"append"===s.head.style?r&&(i.push(t),o.push(t)):!1!==s.head.shouldRemove(t)&&i.push(t)}o.push(...a.values());let c=[];for(const t of o){let i=document.createRange().createContextualFragment(t.outerHTML).firstChild;if(!1!==s.callbacks.beforeNodeAdded(i)){if("href"in i&&i.href||"src"in i&&i.src){let e,t=new Promise((function(t){e=t}));i.addEventListener("load",(function(){e()})),c.push(t)}e.appendChild(i),s.callbacks.afterNodeAdded(i),r.push(i)}}for(const t of i)!1!==s.callbacks.beforeNodeRemoved(t)&&(e.removeChild(t),s.callbacks.afterNodeRemoved(t));return s.head.afterHeadMorphed(e,{added:r,kept:n,removed:i}),c}const n=function(){function e(){const e=document.createElement("div");return e.hidden=!0,document.body.insertAdjacentElement("afterend",e),e}function s(e){let t=[],s=document.activeElement;if("BODY"!==s?.tagName&&e.contains(s))for(;s&&(t.push(s),s!==e);)s=s.parentElement;return t}function r(e){let t=Array.from(e.querySelectorAll("[id]"));return e.getAttribute?.("id")&&t.push(e),t}function i(e,t,s,r){for(const i of r){const r=i.getAttribute("id");if(t.has(r)){let t=i;for(;t;){let i=e.get(t);if(null==i&&(i=new Set,e.set(t,i)),i.add(r),t===s)break;t=t.parentElement}}}}return function(n,o,a){const{persistentIds:c,idMap:l}=function(e,t){const s=r(e),n=r(t),o=function(e,t){let s=new Set,r=new Map;for(const{id:t,tagName:i}of e)r.has(t)?s.add(t):r.set(t,i);let i=new Set;for(const{id:e,tagName:n}of t)i.has(e)?s.add(e):r.get(e)===n&&i.add(e);for(const e of s)i.delete(e);return i}(s,n);let a=new Map;i(a,o,e,s);const c=t.__idiomorphRoot||t;return i(a,o,c,n),{persistentIds:o,idMap:a}}(n,o),h=function(e){let s=Object.assign({},t);return Object.assign(s,e),s.callbacks=Object.assign({},t.callbacks,e.callbacks),s.head=Object.assign({},t.head,e.head),s}(a),d=h.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(d))throw`Do not understand how to morph style ${d}`;return{target:n,newContent:o,config:h,morphStyle:d,ignoreActive:h.ignoreActive,ignoreActiveValue:h.ignoreActiveValue,restoreFocus:h.restoreFocus,idMap:l,persistentIds:c,pantry:e(),activeElementAndParents:s(n),callbacks:h.callbacks,head:h.head}}}(),{normalizeElement:o,normalizeParent:a}=function(){const e=new WeakSet;class t{constructor(e){this.originalNode=e,this.realParentNode=e.parentNode,this.previousSibling=e.previousSibling,this.nextSibling=e.nextSibling}get childNodes(){const e=[];let t=this.previousSibling?this.previousSibling.nextSibling:this.realParentNode.firstChild;for(;t&&t!=this.nextSibling;)e.push(t),t=t.nextSibling;return e}querySelectorAll(e){return this.childNodes.reduce(((t,s)=>{if(s instanceof Element){s.matches(e)&&t.push(s);const r=s.querySelectorAll(e);for(let e=0;e<r.length;e++)t.push(r[e])}return t}),[])}insertBefore(e,t){return this.realParentNode.insertBefore(e,t)}moveBefore(e,t){return this.realParentNode.moveBefore(e,t)}get __idiomorphRoot(){return this.originalNode}}return{normalizeElement:function(e){return e instanceof Document?e.documentElement:e},normalizeParent:function s(r){if(null==r)return document.createElement("div");if("string"==typeof r)return s(function(t){let s=new DOMParser,r=t.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(r.match(/<\/html>/)||r.match(/<\/head>/)||r.match(/<\/body>/)){let i=s.parseFromString(t,"text/html");if(r.match(/<\/html>/))return e.add(i),i;{let t=i.firstChild;return t&&e.add(t),t}}{let r=s.parseFromString("<body><template>"+t+"</template></body>","text/html").body.querySelector("template").content;return e.add(r),r}}(r));if(e.has(r))return r;if(r instanceof Node){if(r.parentNode)return new t(r);{const e=document.createElement("div");return e.append(r),e}}{const e=document.createElement("div");for(const t of[...r])e.append(t);return e}}}}();return{morph:function(e,t,r={}){e=o(e);const c=a(t),l=n(e,c,r),h=function(e,t){if(!e.config.restoreFocus)return t();let s=document.activeElement;if(!(s instanceof HTMLInputElement||s instanceof HTMLTextAreaElement))return t();const{id:r,selectionStart:i,selectionEnd:n}=s,o=t();r&&r!==document.activeElement?.getAttribute("id")&&(s=e.target.querySelector(`[id="${r}"]`),s?.focus());s&&!s.selectionEnd&&n&&s.setSelectionRange(i,n);return o}(l,(()=>function(e,t,s,r){if(e.head.block){const n=t.querySelector("head"),o=s.querySelector("head");if(n&&o){const t=i(n,o,e);return Promise.all(t).then((()=>{const t=Object.assign(e,{head:{block:!1,ignore:!0}});return r(t)}))}}return r(e)}(l,e,c,(t=>"innerHTML"===t.morphStyle?(s(t,e,c),Array.from(e.childNodes)):function(e,t,r){const i=a(t);return s(e,i,r,t,t.nextSibling),Array.from(i.childNodes)}(t,e,c)))));return l.pantry.remove(),h},defaults:t}}();function ve(e,t,{callbacks:s,...r}={}){be.morph(e,t,{...r,callbacks:new Ee(s)})}function Se(e,t,s={}){ve(e,t.childNodes,{...s,morphStyle:"innerHTML"})}function we(e,s){return e instanceof t&&e.shouldReloadWithMorph&&(!s||function(e,t){return t instanceof Element&&"TURBO-FRAME"===t.nodeName&&e.id===t.id&&(!t.getAttribute("src")||N(e.src,t.getAttribute("src")))}(e,s))&&!e.closest("[data-turbo-permanent]")}function ye(e){return e.parentElement.closest("turbo-frame[src][refresh=morph]")}class Ee{#h;constructor({beforeNodeMorphed:e}={}){this.#h=e||(()=>!0)}beforeNodeAdded=e=>!(e.id&&e.hasAttribute("data-turbo-permanent")&&document.getElementById(e.id));beforeNodeMorphed=(e,t)=>{if(e instanceof Element){if(!e.hasAttribute("data-turbo-permanent")&&this.#h(e,t)){return!i("turbo:before-morph-element",{cancelable:!0,target:e,detail:{currentElement:e,newElement:t}}).defaultPrevented}return!1}};beforeAttributeUpdated=(e,t,s)=>!i("turbo:before-morph-attribute",{cancelable:!0,target:t,detail:{attributeName:e,mutationType:s}}).defaultPrevented;beforeNodeRemoved=e=>this.beforeNodeMorphed(e);afterNodeMorphed=(e,t)=>{e instanceof Element&&i("turbo:morph-element",{target:e,detail:{currentElement:e,newElement:t}})}}class Ae extends ge{static renderElement(e,t){i("turbo:before-frame-morph",{target:e,detail:{currentElement:e,newElement:t}}),Se(e,t,{callbacks:{beforeNodeMorphed:(t,s)=>!we(t,s)||ye(t)!==e||(t.reload(),!1)}})}async preservingPermanentElements(e){return await e()}}class Re{static animationDuration=300;static get defaultCSS(){return h`
6
+ .turbo-progress-bar {
7
+ position: fixed;
8
+ display: block;
9
+ top: 0;
10
+ left: 0;
11
+ height: 3px;
12
+ background: #0076ff;
13
+ z-index: 2147483647;
14
+ transition:
15
+ width ${Re.animationDuration}ms ease-out,
16
+ opacity ${Re.animationDuration/2}ms ${Re.animationDuration/2}ms ease-in;
17
+ transform: translate3d(0, 0, 0);
18
+ }
19
+ `}hiding=!1;value=0;visible=!1;constructor(){this.stylesheetElement=this.createStylesheetElement(),this.progressElement=this.createProgressElement(),this.installStylesheetElement(),this.setValue(0)}show(){this.visible||(this.visible=!0,this.installProgressElement(),this.startTrickling())}hide(){this.visible&&!this.hiding&&(this.hiding=!0,this.fadeProgressElement((()=>{this.uninstallProgressElement(),this.stopTrickling(),this.visible=!1,this.hiding=!1})))}setValue(e){this.value=e,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(e){this.progressElement.style.opacity="0",setTimeout(e,1.5*Re.animationDuration)}uninstallProgressElement(){this.progressElement.parentNode&&document.documentElement.removeChild(this.progressElement)}startTrickling(){this.trickleInterval||(this.trickleInterval=window.setInterval(this.trickle,Re.animationDuration))}stopTrickling(){window.clearInterval(this.trickleInterval),delete this.trickleInterval}trickle=()=>{this.setValue(this.value+Math.random()/100)};refresh(){requestAnimationFrame((()=>{this.progressElement.style.width=10+90*this.value+"%"}))}createStylesheetElement(){const e=document.createElement("style");e.type="text/css",e.textContent=Re.defaultCSS;const t=w();return t&&(e.nonce=t),e}createProgressElement(){const e=document.createElement("div");return e.className="turbo-progress-bar",e}}class Te extends ne{detailsByOuterHTML=this.children.filter((e=>!function(e){const t=e.localName;return"noscript"==t}(e))).map((e=>function(e){e.hasAttribute("nonce")&&e.setAttribute("nonce","");return e}(e))).reduce(((e,t)=>{const{outerHTML:s}=t,r=s in e?e[s]:{type:Le(t),tracked:Ce(t),elements:[]};return{...e,[s]:{...r,elements:[...r.elements,t]}}}),{});get trackedElementSignature(){return Object.keys(this.detailsByOuterHTML).filter((e=>this.detailsByOuterHTML[e].tracked)).join("")}getScriptElementsNotInSnapshot(e){return this.getElementsMatchingTypeNotInSnapshot("script",e)}getStylesheetElementsNotInSnapshot(e){return this.getElementsMatchingTypeNotInSnapshot("stylesheet",e)}getElementsMatchingTypeNotInSnapshot(e,t){return Object.keys(this.detailsByOuterHTML).filter((e=>!(e in t.detailsByOuterHTML))).map((e=>this.detailsByOuterHTML[e])).filter((({type:t})=>t==e)).map((({elements:[e]})=>e))}get provisionalElements(){return Object.keys(this.detailsByOuterHTML).reduce(((e,t)=>{const{type:s,tracked:r,elements:i}=this.detailsByOuterHTML[t];return null!=s||r?i.length>1?[...e,...i.slice(1)]:e:[...e,...i]}),[])}getMetaValue(e){const t=this.findMetaElementByName(e);return t?t.getAttribute("content"):null}findMetaElementByName(e){return Object.keys(this.detailsByOuterHTML).reduce(((t,s)=>{const{elements:[r]}=this.detailsByOuterHTML[s];return function(e,t){const s=e.localName;return"meta"==s&&e.getAttribute("name")==t}(r,e)?r:t}),0)}}function Le(e){return function(e){const t=e.localName;return"script"==t}(e)?"script":function(e){const t=e.localName;return"style"==t||"link"==t&&"stylesheet"==e.getAttribute("rel")}(e)?"stylesheet":void 0}function Ce(e){return"reload"==e.getAttribute("data-turbo-track")}class Pe extends ne{static fromHTMLString(e=""){return this.fromDocument(l(e))}static fromElement(e){return this.fromDocument(e.ownerDocument)}static fromDocument({documentElement:e,body:t,head:s}){return new this(e,t,new Te(s))}constructor(e,t,s){super(t),this.documentElement=e,this.headSnapshot=s}clone(){const e=this.element.cloneNode(!0),t=this.element.querySelectorAll("select"),s=e.querySelectorAll("select");for(const[e,r]of t.entries()){const t=s[e];for(const e of t.selectedOptions)e.selected=!1;for(const e of r.selectedOptions)t.options[e.index].selected=!0}for(const t of e.querySelectorAll('input[type="password"]'))t.value="";for(const t of e.querySelectorAll("noscript"))t.remove();return new Pe(this.documentElement,e,this.headSnapshot)}get lang(){return this.documentElement.getAttribute("lang")}get dir(){return this.documentElement.getAttribute("dir")}get headElement(){return this.headSnapshot.element}get rootLocation(){return k(this.getSetting("root")??"/")}get cacheControlValue(){return this.getSetting("cache-control")}get isPreviewable(){return"no-preview"!=this.cacheControlValue}get isCacheable(){return"no-cache"!=this.cacheControlValue}get isVisitable(){return"reload"!=this.getSetting("visit-control")}get prefersViewTransitions(){return("true"===this.getSetting("view-transition")||"same-origin"===this.headSnapshot.getMetaValue("view-transition"))&&!window.matchMedia("(prefers-reduced-motion: reduce)").matches}get refreshMethod(){return this.getSetting("refresh-method")}get refreshScroll(){return this.getSetting("refresh-scroll")}getSetting(e){return this.headSnapshot.getMetaValue(`turbo-${e}`)}}class ke{#d=!1;#u=Promise.resolve();renderChange(e,t){return e&&this.viewTransitionsAvailable&&!this.#d?(this.#d=!0,this.#u=this.#u.then((async()=>{await document.startViewTransition(t).finished}))):this.#u=this.#u.then(t),this.#u}get viewTransitionsAvailable(){return document.startViewTransition}}const Me={action:"advance",historyChanged:!1,visitCachedSnapshot:()=>{},willRender:!0,updateHistory:!0,shouldCacheSnapshot:!0,acceptsStreamResponse:!1,refresh:{}},Fe="visitStart",Ie="requestStart",qe="requestEnd",He="visitEnd",Be="initialized",Ne="started",Oe="canceled",De="failed",xe="completed",Ve=0,We=-1,Ue=-2,_e={advance:"forward",restore:"back",replace:"none"};class $e{identifier=d();timingMetrics={};followedRedirect=!1;historyChanged=!1;scrolled=!1;shouldCacheSnapshot=!0;acceptsStreamResponse=!1;snapshotCached=!1;state=Be;viewTransitioner=new ke;constructor(e,t,s,r={}){this.delegate=e,this.location=t,this.restorationIdentifier=s||d();const{action:i,historyChanged:n,referrer:o,snapshot:a,snapshotHTML:c,response:l,visitCachedSnapshot:h,willRender:u,updateHistory:m,shouldCacheSnapshot:p,acceptsStreamResponse:f,direction:g,refresh:b}={...Me,...r};this.action=i,this.historyChanged=n,this.referrer=o,this.snapshot=a,this.snapshotHTML=c,this.response=l,this.isPageRefresh=this.view.isPageRefresh(this),this.visitCachedSnapshot=h,this.willRender=u,this.updateHistory=m,this.scrolled=!u,this.shouldCacheSnapshot=p,this.acceptsStreamResponse=f,this.direction=g||_e[i],this.refresh=b}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)}start(){this.state==Be&&(this.recordTimingMetric(Fe),this.state=Ne,this.adapter.visitStarted(this),this.delegate.visitStarted(this))}cancel(){this.state==Ne&&(this.request&&this.request.cancel(),this.cancelRender(),this.state=Oe)}complete(){this.state==Ne&&(this.recordTimingMetric(He),this.adapter.visitCompleted(this),this.state=xe,this.followRedirect(),this.followedRedirect||this.delegate.visitCompleted(this))}fail(){this.state==Ne&&(this.state=De,this.adapter.visitFailed(this),this.delegate.visitCompleted(this))}changeHistory(){if(!this.historyChanged&&this.updateHistory){const e=g(this.location.href===this.referrer?.href?"replace":this.action);this.history.update(e,this.location,this.restorationIdentifier),this.historyChanged=!0}}issueRequest(){this.hasPreloadedResponse()?this.simulateRequest():this.shouldIssueRequest()&&!this.request&&(this.request=new z(this,_.get,this.location),this.request.perform())}simulateRequest(){this.response&&(this.startRequest(),this.recordResponse(),this.finishRequest())}startRequest(){this.recordTimingMetric(Ie),this.adapter.visitRequestStarted(this)}recordResponse(e=this.response){if(this.response=e,e){const{statusCode:t}=e;je(t)?this.adapter.visitRequestCompleted(this):this.adapter.visitRequestFailedWithStatusCode(this,t)}}finishRequest(){this.recordTimingMetric(qe),this.adapter.visitRequestFinished(this)}loadResponse(){if(this.response){const{statusCode:e,responseHTML:t}=this.response;this.render((async()=>{if(this.shouldCacheSnapshot&&this.cacheSnapshot(),this.view.renderPromise&&await this.view.renderPromise,je(e)&&null!=t){const e=Pe.fromHTMLString(t);await this.renderPageSnapshot(e,!1),this.adapter.visitRendered(this),this.complete()}else await this.view.renderError(Pe.fromHTMLString(t),this),this.adapter.visitRendered(this),this.fail()}))}}getCachedSnapshot(){const e=this.view.getCachedSnapshotForLocation(this.location)||this.getPreloadedSnapshot();if(e&&(!M(this.location)||e.hasAnchor(M(this.location)))&&("restore"==this.action||e.isPreviewable))return e}getPreloadedSnapshot(){if(this.snapshotHTML)return Pe.fromHTMLString(this.snapshotHTML)}hasCachedSnapshot(){return null!=this.getCachedSnapshot()}loadCachedSnapshot(){const e=this.getCachedSnapshot();if(e){const t=this.shouldIssueRequest();this.render((async()=>{this.cacheSnapshot(),this.isPageRefresh?this.adapter.visitRendered(this):(this.view.renderPromise&&await this.view.renderPromise,await this.renderPageSnapshot(e,t),this.adapter.visitRendered(this),t||this.complete())}))}}followRedirect(){this.redirectedToLocation&&!this.followedRedirect&&this.response?.redirected&&(this.adapter.visitProposedToLocation(this.redirectedToLocation,{action:"replace",response:this.response,shouldCacheSnapshot:!1,willRender:!1}),this.followedRedirect=!0)}prepareRequest(e){this.acceptsStreamResponse&&e.acceptResponseType(Q.contentType)}requestStarted(){this.startRequest()}requestPreventedHandlingResponse(e,t){}async requestSucceededWithResponse(e,t){const s=await t.responseHTML,{redirected:r,statusCode:i}=t;null==s?this.recordResponse({statusCode:Ue,redirected:r}):(this.redirectedToLocation=t.redirected?t.location:void 0,this.recordResponse({statusCode:i,responseHTML:s,redirected:r}))}async requestFailedWithResponse(e,t){const s=await t.responseHTML,{redirected:r,statusCode:i}=t;null==s?this.recordResponse({statusCode:Ue,redirected:r}):this.recordResponse({statusCode:i,responseHTML:s,redirected:r})}requestErrored(e,t){this.recordResponse({statusCode:Ve,redirected:!1})}requestFinished(){this.finishRequest()}performScroll(){this.scrolled||this.view.forceReloaded||this.view.shouldPreserveScrollPosition(this)||("restore"==this.action?this.scrollToRestoredPosition()||this.scrollToAnchor()||this.view.scrollToTop():this.scrollToAnchor()||this.view.scrollToTop(),this.scrolled=!0)}scrollToRestoredPosition(){const{scrollPosition:e}=this.restorationData;if(e)return this.view.scrollToPosition(e),!0}scrollToAnchor(){const e=M(this.location);if(null!=e)return this.view.scrollToAnchor(e),!0}recordTimingMetric(e){this.timingMetrics[e]=(new Date).getTime()}getTimingMetrics(){return{...this.timingMetrics}}hasPreloadedResponse(){return"object"==typeof this.response}shouldIssueRequest(){return"restore"==this.action?!this.hasCachedSnapshot():this.willRender}cacheSnapshot(){this.snapshotCached||(this.view.cacheSnapshot(this.snapshot).then((e=>e&&this.visitCachedSnapshot(e))),this.snapshotCached=!0)}async render(e){this.cancelRender(),await new Promise((e=>{this.frame="hidden"===document.visibilityState?setTimeout((()=>e()),0):requestAnimationFrame((()=>e()))})),await e(),delete this.frame}async renderPageSnapshot(e,t){await this.viewTransitioner.renderChange(this.view.shouldTransitionTo(e),(async()=>{await this.view.renderPage(e,t,this.willRender,this),this.performScroll()}))}cancelRender(){this.frame&&(cancelAnimationFrame(this.frame),delete this.frame)}}function je(e){return e>=200&&e<300}class ze{progressBar=new Re;constructor(e){this.session=e}visitProposedToLocation(e,t){q(e,this.navigator.rootLocation)?this.navigator.startVisit(e,t?.restorationIdentifier||d(),t):window.location.href=e.toString()}visitStarted(e){this.location=e.location,this.redirectedToLocation=null,e.loadCachedSnapshot(),e.issueRequest()}visitRequestStarted(e){this.progressBar.setValue(0),e.hasCachedSnapshot()||"restore"!=e.action?this.showVisitProgressBarAfterDelay():this.showProgressBar()}visitRequestCompleted(e){e.loadResponse(),e.response.redirected&&(this.redirectedToLocation=e.redirectedToLocation)}visitRequestFailedWithStatusCode(e,t){switch(t){case Ve:case We:case Ue:return this.reload({reason:"request_failed",context:{statusCode:t}});default:return e.loadResponse()}}visitRequestFinished(e){}visitCompleted(e){this.progressBar.setValue(1),this.hideVisitProgressBar()}pageInvalidated(e){this.reload(e)}visitFailed(e){this.progressBar.setValue(1),this.hideVisitProgressBar()}visitRendered(e){}linkPrefetchingIsEnabledForLocation(e){return!0}formSubmissionStarted(e){this.progressBar.setValue(0),this.showFormProgressBarAfterDelay()}formSubmissionFinished(e){this.progressBar.setValue(1),this.hideFormProgressBar()}showVisitProgressBarAfterDelay(){this.visitProgressBarTimeout=window.setTimeout(this.showProgressBar,this.session.progressBarDelay)}hideVisitProgressBar(){this.progressBar.hide(),null!=this.visitProgressBarTimeout&&(window.clearTimeout(this.visitProgressBarTimeout),delete this.visitProgressBarTimeout)}showFormProgressBarAfterDelay(){null==this.formProgressBarTimeout&&(this.formProgressBarTimeout=window.setTimeout(this.showProgressBar,this.session.progressBarDelay))}hideFormProgressBar(){this.progressBar.hide(),null!=this.formProgressBarTimeout&&(window.clearTimeout(this.formProgressBarTimeout),delete this.formProgressBarTimeout)}showProgressBar=()=>{this.progressBar.show()};reload(e){i("turbo:reload",{detail:e}),window.location.href=(this.redirectedToLocation||this.location)?.toString()||window.location.href}get navigator(){return this.session.navigator}}class Ge{selector="[data-turbo-temporary]";started=!1;start(){this.started||(this.started=!0,addEventListener("turbo:before-cache",this.removeTemporaryElements,!1))}stop(){this.started&&(this.started=!1,removeEventListener("turbo:before-cache",this.removeTemporaryElements,!1))}removeTemporaryElements=e=>{for(const e of this.temporaryElements)e.remove()};get temporaryElements(){return[...document.querySelectorAll(this.selector)]}}class Ke{constructor(e,t){this.session=e,this.element=t,this.linkInterceptor=new de(this,t),this.formSubmitObserver=new ce(this,t)}start(){this.linkInterceptor.start(),this.formSubmitObserver.start()}stop(){this.linkInterceptor.stop(),this.formSubmitObserver.stop()}shouldInterceptLinkClick(e,t,s){return this.#m(e)}linkClickIntercepted(e,t,s){const r=this.#p(e);r&&r.delegate.linkClickIntercepted(e,t,s)}willSubmitForm(e,t){return null==e.closest("turbo-frame")&&this.#f(e,t)&&this.#m(e,t)}formSubmitted(e,t){const s=this.#p(e,t);s&&s.delegate.formSubmitted(e,t)}#f(e,t){const s=F(e,t),r=this.element.ownerDocument.querySelector('meta[name="turbo-root"]'),i=k(r?.content??"/");return this.#m(e,t)&&q(s,i)}#m(e,t){if(e instanceof HTMLFormElement?this.session.submissionIsNavigatable(e,t):this.session.elementIsNavigatable(e)){const s=this.#p(e,t);return!!s&&s!=e.closest("turbo-frame")}return!1}#p(e,s){const r=s?.getAttribute("data-turbo-frame")||e.getAttribute("data-turbo-frame");if(r&&"_top"!=r){const e=this.element.querySelector(`#${r}:not([disabled])`);if(e instanceof t)return e}}}class Je{location;restorationIdentifier=d();restorationData={};started=!1;currentIndex=0;constructor(e){this.delegate=e}start(){this.started||(addEventListener("popstate",this.onPopState,!1),this.currentIndex=history.state?.turbo?.restorationIndex||0,this.started=!0,this.replace(new URL(window.location.href)))}stop(){this.started&&(removeEventListener("popstate",this.onPopState,!1),this.started=!1)}push(e,t){this.update(history.pushState,e,t)}replace(e,t){this.update(history.replaceState,e,t)}update(e,t,s=d()){e===history.pushState&&++this.currentIndex;const r={turbo:{restorationIdentifier:s,restorationIndex:this.currentIndex}};e.call(history,r,"",t.href),this.location=t,this.restorationIdentifier=s}getRestorationDataForIdentifier(e){return this.restorationData[e]||{}}updateRestorationData(e){const{restorationIdentifier:t}=this,s=this.restorationData[t];this.restorationData[t]={...s,...e}}assumeControlOfScrollRestoration(){this.previousScrollRestoration||(this.previousScrollRestoration=history.scrollRestoration??"auto",history.scrollRestoration="manual")}relinquishControlOfScrollRestoration(){this.previousScrollRestoration&&(history.scrollRestoration=this.previousScrollRestoration,delete this.previousScrollRestoration)}onPopState=e=>{const{turbo:t}=e.state||{};if(this.location=new URL(window.location.href),t){const{restorationIdentifier:e,restorationIndex:s}=t;this.restorationIdentifier=e;const r=s>this.currentIndex?"forward":"back";this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location,e,r),this.currentIndex=s}else this.currentIndex++,this.delegate.historyPoppedWithEmptyState(this.location)}}class Xe{started=!1;#g=null;constructor(e,t){this.delegate=e,this.eventTarget=t}start(){this.started||("loading"===this.eventTarget.readyState?this.eventTarget.addEventListener("DOMContentLoaded",this.#b,{once:!0}):this.#b())}stop(){this.started&&(this.eventTarget.removeEventListener("mouseenter",this.#v,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("mouseleave",this.#S,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("turbo:before-fetch-request",this.#w,!0),this.started=!1)}#b=()=>{this.eventTarget.addEventListener("mouseenter",this.#v,{capture:!0,passive:!0}),this.eventTarget.addEventListener("mouseleave",this.#S,{capture:!0,passive:!0}),this.eventTarget.addEventListener("turbo:before-fetch-request",this.#w,!0),this.started=!0};#v=e=>{if("false"===S("turbo-prefetch"))return;const t=e.target;if(t.matches&&t.matches("a[href]:not([target^=_]):not([download])")&&this.#y(t)){const e=t,s=H(e);if(this.delegate.canPrefetchRequestToLocation(e,s)){this.#g=e;const r=new z(this,_.get,s,new URLSearchParams,t);r.fetchOptions.priority="low",se.putLater(s,r,this.#E)}}};#S=e=>{e.target===this.#g&&this.#A()};#A=()=>{se.clear(),this.#g=null};#w=e=>{if("FORM"!==e.target.tagName&&"GET"===e.detail.fetchOptions.method){const t=se.get(e.detail.url);t&&(e.detail.fetchRequest=t),se.clear()}};prepareRequest(e){const t=e.target;e.headers["X-Sec-Purpose"]="prefetch";const s=t.closest("turbo-frame"),r=t.getAttribute("data-turbo-frame")||s?.getAttribute("target")||s?.id;r&&"_top"!==r&&(e.headers["Turbo-Frame"]=r)}requestSucceededWithResponse(){}requestStarted(e){}requestErrored(e){}requestFinished(e){}requestPreventedHandlingResponse(e,t){}requestFailedWithResponse(e,t){}get#E(){return Number(S("turbo-prefetch-cache-time"))||te}#y(e){return!!e.getAttribute("href")&&(!Ye(e)&&(!Qe(e)&&(!Ze(e)&&(!et(e)&&!st(e)))))}}const Ye=e=>e.origin!==document.location.origin||!["http:","https:"].includes(e.protocol)||e.hasAttribute("target"),Qe=e=>e.pathname+e.search===document.location.pathname+document.location.search||e.href.startsWith("#"),Ze=e=>{if("false"===e.getAttribute("data-turbo-prefetch"))return!0;if("false"===e.getAttribute("data-turbo"))return!0;const t=y(e,"[data-turbo-prefetch]");return!(!t||"false"!==t.getAttribute("data-turbo-prefetch"))},et=e=>{const t=e.getAttribute("data-turbo-method");return!(!t||"get"===t.toLowerCase())||(!!tt(e)||(!!e.hasAttribute("data-turbo-confirm")||!!e.hasAttribute("data-turbo-stream")))},tt=e=>e.hasAttribute("data-remote")||e.hasAttribute("data-behavior")||e.hasAttribute("data-confirm")||e.hasAttribute("data-method"),st=e=>i("turbo:before-prefetch",{target:e,cancelable:!0}).defaultPrevented;class rt{constructor(e){this.delegate=e}proposeVisit(e,t={}){this.delegate.allowsVisitingLocationWithAction(e,t.action)&&this.delegate.visitProposedToLocation(e,t)}startVisit(e,t,s={}){this.stop(),this.currentVisit=new $e(this,k(e),t,{referrer:this.location,...s}),this.currentVisit.start()}submitForm(e,t){this.stop(),this.formSubmission=new ie(this,e,t,!0),this.formSubmission.start()}stop(){this.formSubmission&&(this.formSubmission.stop(),delete this.formSubmission),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(e){"function"==typeof this.adapter.formSubmissionStarted&&this.adapter.formSubmissionStarted(e)}async formSubmissionSucceededWithResponse(e,t){if(e==this.formSubmission){const s=await t.responseHTML;if(s){const r=e.isSafe;r||this.view.clearSnapshotCache();const{statusCode:i,redirected:n}=t,o={action:this.#R(e,t),shouldCacheSnapshot:r,response:{statusCode:i,responseHTML:s,redirected:n}};this.proposeVisit(t.location,o)}}}async formSubmissionFailedWithResponse(e,t){const s=await t.responseHTML;if(s){const e=Pe.fromHTMLString(s);t.serverError?await this.view.renderError(e,this.currentVisit):await this.view.renderPage(e,!1,!0,this.currentVisit),"preserve"!==e.refreshScroll&&this.view.scrollToTop(),this.view.clearSnapshotCache()}}formSubmissionErrored(e,t){console.error(t)}formSubmissionFinished(e){"function"==typeof this.adapter.formSubmissionFinished&&this.adapter.formSubmissionFinished(e)}linkPrefetchingIsEnabledForLocation(e){return"function"!=typeof this.adapter.linkPrefetchingIsEnabledForLocation||this.adapter.linkPrefetchingIsEnabledForLocation(e)}visitStarted(e){this.delegate.visitStarted(e)}visitCompleted(e){this.delegate.visitCompleted(e),delete this.currentVisit}locationWithActionIsSamePage(e,t){return!1}get location(){return this.history.location}get restorationIdentifier(){return this.history.restorationIdentifier}#R(e,t){const{submitter:s,formElement:r}=e;return b(s,r)||this.#T(t)}#T(e){return e.redirected&&e.location.href===this.location?.href?"replace":"advance"}}const it=0,nt=1,ot=2,at=3;class ct{stage=it;started=!1;constructor(e){this.delegate=e}start(){this.started||(this.stage==it&&(this.stage=nt),document.addEventListener("readystatechange",this.interpretReadyState,!1),addEventListener("pagehide",this.pageWillUnload,!1),this.started=!0)}stop(){this.started&&(document.removeEventListener("readystatechange",this.interpretReadyState,!1),removeEventListener("pagehide",this.pageWillUnload,!1),this.started=!1)}interpretReadyState=()=>{const{readyState:e}=this;"interactive"==e?this.pageIsInteractive():"complete"==e&&this.pageIsComplete()};pageIsInteractive(){this.stage==nt&&(this.stage=ot,this.delegate.pageBecameInteractive())}pageIsComplete(){this.pageIsInteractive(),this.stage==ot&&(this.stage=at,this.delegate.pageLoaded())}pageWillUnload=()=>{this.delegate.pageWillUnload()};get readyState(){return document.readyState}}class lt{started=!1;constructor(e){this.delegate=e}start(){this.started||(addEventListener("scroll",this.onScroll,!1),this.onScroll(),this.started=!0)}stop(){this.started&&(removeEventListener("scroll",this.onScroll,!1),this.started=!1)}onScroll=()=>{this.updatePosition({x:window.pageXOffset,y:window.pageYOffset})};updatePosition(e){this.delegate.scrollPositionChanged(e)}}class ht{render({fragment:e}){pe.preservingPermanentElements(this,function(e){const t=ae(document.documentElement),s={};for(const r of t){const{id:t}=r;for(const i of e.querySelectorAll("turbo-stream")){const e=oe(i.templateElement.content,t);e&&(s[t]=[r,e])}}return s}(e),(()=>{!async function(e,t){const s=`turbo-stream-autofocus-${d()}`,r=e.querySelectorAll("turbo-stream"),i=function(e){for(const t of e){const e=A(t.templateElement.content);if(e)return e}return null}(r);let n=null;i&&(n=i.id?i.id:s,i.id=n);t(),await o();if((null==document.activeElement||document.activeElement==document.body)&&n){const e=document.getElementById(n);E(e)&&e.focus(),e&&e.id==s&&e.removeAttribute("id")}}(e,(()=>{!async function(e){const[t,s]=await async function(e,t){const s=t();return e(),await a(),[s,t()]}(e,(()=>document.activeElement)),r=t&&t.id;if(r){const e=document.getElementById(r);E(e)&&e!=s&&e.focus()}}((()=>{document.documentElement.appendChild(e)}))}))}))}enteringBardo(e,t){t.replaceWith(e.cloneNode(!0))}leavingBardo(){}}class dt{sources=new Set;#L=!1;constructor(e){this.delegate=e}start(){this.#L||(this.#L=!0,addEventListener("turbo:before-fetch-response",this.inspectFetchResponse,!1))}stop(){this.#L&&(this.#L=!1,removeEventListener("turbo:before-fetch-response",this.inspectFetchResponse,!1))}connectStreamSource(e){this.streamSourceIsConnected(e)||(this.sources.add(e),e.addEventListener("message",this.receiveMessageEvent,!1))}disconnectStreamSource(e){this.streamSourceIsConnected(e)&&(this.sources.delete(e),e.removeEventListener("message",this.receiveMessageEvent,!1))}streamSourceIsConnected(e){return this.sources.has(e)}inspectFetchResponse=e=>{const t=function(e){const t=e.detail?.fetchResponse;if(t instanceof D)return t}(e);t&&function(e){const t=e.contentType??"";return t.startsWith(Q.contentType)}(t)&&(e.preventDefault(),this.receiveMessageResponse(t))};receiveMessageEvent=e=>{this.#L&&"string"==typeof e.data&&this.receiveMessageHTML(e.data)};async receiveMessageResponse(e){const t=await e.responseHTML;t&&this.receiveMessageHTML(t)}receiveMessageHTML(e){this.delegate.receivedMessageFromStream(Q.wrap(e))}}class ut extends fe{static renderElement(e,t){const{documentElement:s,body:r}=document;s.replaceChild(t,r)}async render(){this.replaceHeadAndBody(),this.activateScriptElements()}replaceHeadAndBody(){const{documentElement:e,head:t}=document;e.replaceChild(this.newHead,t),this.renderElement(this.currentElement,this.newElement)}activateScriptElements(){for(const e of this.scriptElements){const t=e.parentNode;if(t){const s=r(e);t.replaceChild(s,e)}}}get newHead(){return this.newSnapshot.headSnapshot.element}get scriptElements(){return document.documentElement.querySelectorAll("script")}}class mt extends fe{static renderElement(e,t){document.body&&t instanceof HTMLBodyElement?document.body.replaceWith(t):document.documentElement.appendChild(t)}get shouldRender(){return this.newSnapshot.isVisitable&&this.trackedElementsAreIdentical}get reloadReason(){return this.newSnapshot.isVisitable?this.trackedElementsAreIdentical?void 0:{reason:"tracked_element_mismatch"}:{reason:"turbo_visit_control_is_reload"}}async prepareToRender(){this.#C(),await this.mergeHead()}async render(){this.willRender&&await this.replaceBody()}finishRendering(){super.finishRendering(),this.isPreview||this.focusFirstAutofocusableElement()}get currentHeadSnapshot(){return this.currentSnapshot.headSnapshot}get newHeadSnapshot(){return this.newSnapshot.headSnapshot}get newElement(){return this.newSnapshot.element}#C(){const{documentElement:e}=this.currentSnapshot,{dir:t,lang:s}=this.newSnapshot;s?e.setAttribute("lang",s):e.removeAttribute("lang"),t?e.setAttribute("dir",t):e.removeAttribute("dir")}async mergeHead(){const e=this.mergeProvisionalElements(),t=this.copyNewHeadStylesheetElements();this.copyNewHeadScriptElements(),await e,await t,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(){const e=[];for(const t of this.newHeadStylesheetElements)e.push(f(t)),document.head.appendChild(t);await Promise.all(e)}copyNewHeadScriptElements(){for(const e of this.newHeadScriptElements)document.head.appendChild(r(e))}removeUnusedDynamicStylesheetElements(){for(const e of this.unusedDynamicStylesheetElements)document.head.removeChild(e)}async mergeProvisionalElements(){const e=[...this.newHeadProvisionalElements];for(const t of this.currentHeadProvisionalElements)this.isCurrentElementInElementList(t,e)||document.head.removeChild(t);for(const t of e)document.head.appendChild(t)}isCurrentElementInElementList(e,t){for(const[s,r]of t.entries()){if("TITLE"==e.tagName){if("TITLE"!=r.tagName)continue;if(e.innerHTML==r.innerHTML)return t.splice(s,1),!0}if(r.isEqualNode(e))return t.splice(s,1),!0}return!1}removeCurrentHeadProvisionalElements(){for(const e of this.currentHeadProvisionalElements)document.head.removeChild(e)}copyNewHeadProvisionalElements(){for(const e of this.newHeadProvisionalElements)document.head.appendChild(e)}activateNewBody(){document.adoptNode(this.newElement),this.removeNoscriptElements(),this.activateNewBodyScriptElements()}removeNoscriptElements(){for(const e of this.newElement.querySelectorAll("noscript"))e.remove()}activateNewBodyScriptElements(){for(const e of this.newBodyScriptElements){const t=r(e);e.replaceWith(t)}}async assignNewBody(){await this.renderElement(this.currentElement,this.newElement)}get unusedDynamicStylesheetElements(){return this.oldHeadStylesheetElements.filter((e=>"dynamic"===e.getAttribute("data-turbo-track")))}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 pt extends mt{static renderElement(e,t){ve(e,t,{callbacks:{beforeNodeMorphed:(e,t)=>!(we(e,t)&&!ye(e))||(e.reload(),!1)}}),i("turbo:morph",{detail:{currentElement:e,newElement:t}})}async preservingPermanentElements(e){return await e()}get renderMethod(){return"morph"}get shouldAutofocus(){return!1}}class ft extends ee{constructor(e){super(e,B)}get snapshots(){return this.entries}}class gt extends le{snapshotCache=new ft(10);lastRenderedLocation=new URL(location.href);forceReloaded=!1;shouldTransitionTo(e){return this.snapshot.prefersViewTransitions&&e.prefersViewTransitions}renderPage(e,t=!1,s=!0,r){const i=new(this.isPageRefresh(r)&&"morph"===(r?.refresh?.method||this.snapshot.refreshMethod)?pt:mt)(this.snapshot,e,t,s);return i.shouldRender?r?.changeHistory():this.forceReloaded=!0,this.render(i)}renderError(e,t){t?.changeHistory();const s=new ut(this.snapshot,e,!1);return this.render(s)}clearSnapshotCache(){this.snapshotCache.clear()}async cacheSnapshot(e=this.snapshot){if(e.isCacheable){this.delegate.viewWillCacheSnapshot();const{lastRenderedLocation:t}=this;await c();const s=e.clone();return this.snapshotCache.put(t,s),s}}getCachedSnapshotForLocation(e){return this.snapshotCache.get(e)}isPageRefresh(e){return!e||this.lastRenderedLocation.pathname===e.location.pathname&&"replace"===e.action}shouldPreserveScrollPosition(e){return this.isPageRefresh(e)&&"preserve"===(e?.refresh?.scroll||this.snapshot.refreshScroll)}get snapshot(){return Pe.fromElement(this.element)}}class bt{selector="a[data-turbo-preload]";constructor(e,t){this.delegate=e,this.snapshotCache=t}start(){"loading"===document.readyState?document.addEventListener("DOMContentLoaded",this.#P):this.preloadOnLoadLinksForView(document.body)}stop(){document.removeEventListener("DOMContentLoaded",this.#P)}preloadOnLoadLinksForView(e){for(const t of e.querySelectorAll(this.selector))this.delegate.shouldPreloadLink(t)&&this.preloadURL(t)}async preloadURL(e){const t=new URL(e.href);if(this.snapshotCache.has(t))return;const s=new z(this,_.get,t,new URLSearchParams,e);await s.perform()}prepareRequest(e){e.headers["X-Sec-Purpose"]="prefetch"}async requestSucceededWithResponse(e,t){try{const s=await t.responseHTML,r=Pe.fromHTMLString(s);this.snapshotCache.put(e.url,r)}catch(e){}}requestStarted(e){}requestErrored(e){}requestFinished(e){}requestPreventedHandlingResponse(e,t){}requestFailedWithResponse(e,t){}#P=()=>{this.preloadOnLoadLinksForView(document.body)}}class vt{constructor(e){this.session=e}clear(){this.session.clearCache()}resetCacheControl(){this.#k("")}exemptPageFromCache(){this.#k("no-cache")}exemptPageFromPreview(){this.#k("no-preview")}#k(e){!function(e,t){let s=v(e);s||(s=document.createElement("meta"),s.setAttribute("name",e),document.head.appendChild(s)),s.setAttribute("content",t)}("turbo-cache-control",e)}}function St(e){Object.defineProperties(e,wt)}const wt={absoluteURL:{get(){return this.toString()}}},yt=new class{navigator=new rt(this);history=new Je(this);view=new gt(this,document.documentElement);adapter=new ze(this);pageObserver=new ct(this);cacheObserver=new Ge;linkPrefetchObserver=new Xe(this,document);linkClickObserver=new ue(this,window);formSubmitObserver=new ce(this,document);scrollObserver=new lt(this);streamObserver=new dt(this);formLinkClickObserver=new me(this,document.documentElement);frameRedirector=new Ke(this,document.documentElement);streamMessageRenderer=new ht;cache=new vt(this);enabled=!0;started=!1;#M=150;constructor(e){this.recentRequests=e,this.preloader=new bt(this,this.view.snapshotCache),this.debouncedRefresh=this.refresh,this.pageRefreshDebouncePeriod=this.pageRefreshDebouncePeriod}start(){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(){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(e){this.adapter=e}visit(e,s={}){const r=s.frame?document.getElementById(s.frame):null;if(r instanceof t){const t=s.action||b(r);r.delegate.proposeVisitIfNavigatedWithAction(r,t),r.src=e.toString()}else this.navigator.proposeVisit(k(e),s)}refresh(e,t={}){t="string"==typeof t?{requestId:t}:t;const{method:s,requestId:r,scroll:i}=t,n=r&&this.recentRequests.has(r),o=e===document.baseURI;n||this.navigator.currentVisit||!o||this.visit(e,{action:"replace",shouldCacheSnapshot:!1,refresh:{method:s,scroll:i}})}connectStreamSource(e){this.streamObserver.connectStreamSource(e)}disconnectStreamSource(e){this.streamObserver.disconnectStreamSource(e)}renderStreamMessage(e){this.streamMessageRenderer.render(Q.wrap(e))}clearCache(){this.view.clearSnapshotCache()}setProgressBarDelay(e){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=e}set progressBarDelay(e){P.drive.progressBarDelay=e}get progressBarDelay(){return P.drive.progressBarDelay}set drive(e){P.drive.enabled=e}get drive(){return P.drive.enabled}set formMode(e){P.forms.mode=e}get formMode(){return P.forms.mode}get location(){return this.history.location}get restorationIdentifier(){return this.history.restorationIdentifier}get pageRefreshDebouncePeriod(){return this.#M}set pageRefreshDebouncePeriod(e){this.refresh=function(e,t){let s=null;return(...r)=>{clearTimeout(s),s=setTimeout((()=>e.apply(this,r)),t)}}(this.debouncedRefresh.bind(this),e),this.#M=e}shouldPreloadLink(e){const s=e.hasAttribute("data-turbo-method"),r=e.hasAttribute("data-turbo-stream"),i=e.getAttribute("data-turbo-frame"),n="_top"==i?null:document.getElementById(i)||y(e,"turbo-frame:not([disabled])");if(s||r||n instanceof t)return!1;{const t=new URL(e.href);return this.elementIsNavigatable(e)&&q(t,this.snapshot.rootLocation)}}historyPoppedToLocationWithRestorationIdentifierAndDirection(e,t,s){this.enabled?this.navigator.startVisit(e,t,{action:"restore",historyChanged:!0,direction:s}):this.adapter.pageInvalidated({reason:"turbo_disabled"})}historyPoppedWithEmptyState(e){this.history.replace(e),this.view.lastRenderedLocation=e,this.view.cacheSnapshot()}scrollPositionChanged(e){this.history.updateRestorationData({scrollPosition:e})}willSubmitFormLinkToLocation(e,t){return this.elementIsNavigatable(e)&&q(t,this.snapshot.rootLocation)}submittedFormLinkToLocation(){}canPrefetchRequestToLocation(e,t){return this.elementIsNavigatable(e)&&q(t,this.snapshot.rootLocation)&&this.navigator.linkPrefetchingIsEnabledForLocation(t)}willFollowLinkToLocation(e,t,s){return this.elementIsNavigatable(e)&&q(t,this.snapshot.rootLocation)&&this.applicationAllowsFollowingLinkToLocation(e,t,s)}followedLinkToLocation(e,t){const s=this.getActionForLink(e),r=e.hasAttribute("data-turbo-stream");this.visit(t.href,{action:s,acceptsStreamResponse:r})}allowsVisitingLocationWithAction(e,t){return this.applicationAllowsVisitingLocation(e)}visitProposedToLocation(e,t){St(e),this.adapter.visitProposedToLocation(e,t)}visitStarted(e){e.acceptsStreamResponse||(m(document.documentElement),this.view.markVisitDirection(e.direction)),St(e.location),this.notifyApplicationAfterVisitingLocation(e.location,e.action)}visitCompleted(e){this.view.unmarkVisitDirection(),p(document.documentElement),this.notifyApplicationAfterPageLoad(e.getTimingMetrics())}willSubmitForm(e,t){const s=F(e,t);return this.submissionIsNavigatable(e,t)&&q(k(s),this.snapshot.rootLocation)}formSubmitted(e,t){this.navigator.submitForm(e,t)}pageBecameInteractive(){this.view.lastRenderedLocation=this.location,this.notifyApplicationAfterPageLoad()}pageLoaded(){this.history.assumeControlOfScrollRestoration()}pageWillUnload(){this.history.relinquishControlOfScrollRestoration()}receivedMessageFromStream(e){this.renderStreamMessage(e)}viewWillCacheSnapshot(){this.notifyApplicationBeforeCachingSnapshot()}allowsImmediateRender({element:e},t){const s=this.notifyApplicationBeforeRender(e,t),{defaultPrevented:r,detail:{render:i}}=s;return this.view.renderer&&i&&(this.view.renderer.renderElement=i),!r}viewRenderedSnapshot(e,t,s){this.view.lastRenderedLocation=this.history.location,this.notifyApplicationAfterRender(s)}preloadOnLoadLinksForView(e){this.preloader.preloadOnLoadLinksForView(e)}viewInvalidated(e){this.adapter.pageInvalidated(e)}frameLoaded(e){this.notifyApplicationAfterFrameLoad(e)}frameRendered(e,t){this.notifyApplicationAfterFrameRender(e,t)}applicationAllowsFollowingLinkToLocation(e,t,s){return!this.notifyApplicationAfterClickingLinkToLocation(e,t,s).defaultPrevented}applicationAllowsVisitingLocation(e){return!this.notifyApplicationBeforeVisitingLocation(e).defaultPrevented}notifyApplicationAfterClickingLinkToLocation(e,t,s){return i("turbo:click",{target:e,detail:{url:t.href,originalEvent:s},cancelable:!0})}notifyApplicationBeforeVisitingLocation(e){return i("turbo:before-visit",{detail:{url:e.href},cancelable:!0})}notifyApplicationAfterVisitingLocation(e,t){return i("turbo:visit",{detail:{url:e.href,action:t}})}notifyApplicationBeforeCachingSnapshot(){return i("turbo:before-cache")}notifyApplicationBeforeRender(e,t){return i("turbo:before-render",{detail:{newBody:e,...t},cancelable:!0})}notifyApplicationAfterRender(e){return i("turbo:render",{detail:{renderMethod:e}})}notifyApplicationAfterPageLoad(e={}){return i("turbo:load",{detail:{url:this.location.href,timing:e}})}notifyApplicationAfterFrameLoad(e){return i("turbo:frame-load",{target:e})}notifyApplicationAfterFrameRender(e,t){return i("turbo:frame-render",{detail:{fetchResponse:e},target:t,cancelable:!0})}submissionIsNavigatable(e,t){if("off"==P.forms.mode)return!1;{const s=!t||this.elementIsNavigatable(t);return"optin"==P.forms.mode?s&&null!=e.closest('[data-turbo="true"]'):s&&this.elementIsNavigatable(e)}}elementIsNavigatable(e){const t=y(e,"[data-turbo]"),s=y(e,"turbo-frame");return P.drive.enabled||s?!t||"false"!=t.getAttribute("data-turbo"):!!t&&"true"==t.getAttribute("data-turbo")}getActionForLink(e){return b(e)||"advance"}get snapshot(){return this.view.snapshot}}(V),{cache:Et,navigator:At}=yt;function Rt(){yt.start()}function Tt(e){yt.registerAdapter(e)}function Lt(e,t){yt.visit(e,t)}function Ct(e){yt.connectStreamSource(e)}function Pt(e){yt.disconnectStreamSource(e)}function kt(e){yt.renderStreamMessage(e)}function Mt(e){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.`"),P.drive.progressBarDelay=e}function Ft(e){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.`"),P.forms.confirm=e}function It(e){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.`"),P.forms.mode=e}function qt(e,t){pt.renderElement(e,t)}function Ht(e,t){Ae.renderElement(e,t)}var Bt=Object.freeze({__proto__:null,PageRenderer:mt,PageSnapshot:Pe,FrameRenderer:ge,fetch:W,config:P,session:yt,cache:Et,navigator:At,start:Rt,registerAdapter:Tt,visit:Lt,connectStreamSource:Ct,disconnectStreamSource:Pt,renderStreamMessage:kt,setProgressBarDelay:Mt,setConfirmMethod:Ft,setFormMode:It,morphBodyElements:qt,morphTurboFrameElements:Ht,morphChildren:Se,morphElements:ve});class Nt extends Error{}function Ot(e,s){if(e){const r=e.getAttribute("src");if(null!=r&&null!=s&&N(r,s))throw new Error(`Matching <turbo-frame id="${e.id}"> element has a source URL which references itself`);if(e.ownerDocument!==document&&(e=document.importNode(e,!0)),e instanceof t)return e.connectedCallback(),e.disconnectedCallback(),e}}const Dt={after(){this.removeDuplicateTargetSiblings(),this.targetElements.forEach((e=>e.parentElement?.insertBefore(this.templateContent,e.nextSibling)))},append(){this.removeDuplicateTargetChildren(),this.targetElements.forEach((e=>e.append(this.templateContent)))},before(){this.removeDuplicateTargetSiblings(),this.targetElements.forEach((e=>e.parentElement?.insertBefore(this.templateContent,e)))},prepend(){this.removeDuplicateTargetChildren(),this.targetElements.forEach((e=>e.prepend(this.templateContent)))},remove(){this.targetElements.forEach((e=>e.remove()))},replace(){const e=this.getAttribute("method");this.targetElements.forEach((t=>{"morph"===e?ve(t,this.templateContent):t.replaceWith(this.templateContent)}))},update(){const e=this.getAttribute("method");this.targetElements.forEach((t=>{"morph"===e?Se(t,this.templateContent):(t.innerHTML="",t.append(this.templateContent))}))},refresh(){const e=this.getAttribute("method"),t=this.requestId,s=this.getAttribute("scroll");yt.refresh(this.baseURI,{method:e,requestId:t,scroll:s})}};class xt extends HTMLElement{static async renderElement(e){await e.performAction()}async connectedCallback(){try{await this.render()}catch(e){console.error(e)}finally{this.disconnect()}}async render(){return this.renderPromise??=(async()=>{const e=this.beforeRenderEvent;this.dispatchEvent(e)&&(await o(),await e.detail.render(this))})()}disconnect(){try{this.remove()}catch{}}removeDuplicateTargetChildren(){this.duplicateChildren.forEach((e=>e.remove()))}get duplicateChildren(){const e=this.targetElements.flatMap((e=>[...e.children])).filter((e=>!!e.getAttribute("id"))),t=[...this.templateContent?.children||[]].filter((e=>!!e.getAttribute("id"))).map((e=>e.getAttribute("id")));return e.filter((e=>t.includes(e.getAttribute("id"))))}removeDuplicateTargetSiblings(){this.duplicateSiblings.forEach((e=>e.remove()))}get duplicateSiblings(){const e=this.targetElements.flatMap((e=>[...e.parentElement.children])).filter((e=>!!e.id)),t=[...this.templateContent?.children||[]].filter((e=>!!e.id)).map((e=>e.id));return e.filter((e=>t.includes(e.id)))}get performAction(){if(this.action){const e=Dt[this.action];if(e)return e;this.#F("unknown action")}this.#F("action attribute is missing")}get targetElements(){return this.target?this.targetElementsById:this.targets?this.targetElementsByQuery:void this.#F("target or targets attribute is missing")}get templateContent(){return this.templateElement.content.cloneNode(!0)}get templateElement(){if(null===this.firstElementChild){const e=this.ownerDocument.createElement("template");return this.appendChild(e),e}if(this.firstElementChild instanceof HTMLTemplateElement)return this.firstElementChild;this.#F("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")}#F(e){throw new Error(`${this.description}: ${e}`)}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:xt.renderElement}})}get targetElementsById(){const e=this.ownerDocument?.getElementById(this.target);return null!==e?[e]:[]}get targetElementsByQuery(){const e=this.ownerDocument?.querySelectorAll(this.targets);return 0!==e.length?Array.prototype.slice.call(e):[]}}class Vt extends HTMLElement{streamSource=null;connectedCallback(){this.streamSource=this.src.match(/^ws{1,2}:/)?new WebSocket(this.src):new EventSource(this.src),Ct(this.streamSource)}disconnectedCallback(){this.streamSource&&(this.streamSource.close(),Pt(this.streamSource))}get src(){return this.getAttribute("src")||""}}t.delegateConstructor=class{fetchResponseLoaded=e=>Promise.resolve();#I=null;#q=()=>{};#H=!1;#B=!1;#N=new Set;#O=!1;action=null;constructor(e){this.element=e,this.view=new he(this,this.element),this.appearanceObserver=new Y(this,this.element),this.formLinkClickObserver=new me(this,this.element),this.linkInterceptor=new de(this,this.element),this.restorationIdentifier=d(),this.formSubmitObserver=new ce(this,this.element)}connect(){this.#H||(this.#H=!0,this.loadingStyle==e.lazy?this.appearanceObserver.start():this.#D(),this.formLinkClickObserver.start(),this.linkInterceptor.start(),this.formSubmitObserver.start())}disconnect(){this.#H&&(this.#H=!1,this.appearanceObserver.stop(),this.formLinkClickObserver.stop(),this.linkInterceptor.stop(),this.formSubmitObserver.stop(),this.element.hasAttribute("recurse")||this.#I?.cancel())}disabledChanged(){this.disabled?this.#I?.cancel():this.loadingStyle==e.eager&&this.#D()}sourceURLChanged(){this.#x("src")||(this.sourceURL||this.#I?.cancel(),this.element.isConnected&&(this.complete=!1),(this.loadingStyle==e.eager||this.#B)&&this.#D())}sourceURLReloaded(){const{refresh:e,src:t}=this.element;return this.#O=t&&"morph"===e,this.element.removeAttribute("complete"),this.element.src=null,this.element.src=t,this.element.loaded}loadingStyleChanged(){this.loadingStyle==e.lazy?this.appearanceObserver.start():(this.appearanceObserver.stop(),this.#D())}async#D(){this.enabled&&this.isActive&&!this.complete&&this.sourceURL&&(this.element.loaded=this.#V(k(this.sourceURL)),this.appearanceObserver.stop(),await this.element.loaded,this.#B=!0)}async loadResponse(e){(e.redirected||e.succeeded&&e.isHTML)&&(this.sourceURL=e.response.url);try{const t=await e.responseHTML;if(t){const s=l(t);Pe.fromDocument(s).isVisitable?await this.#W(e,s):await this.#U(e)}}finally{this.#O=!1,this.fetchResponseLoaded=()=>Promise.resolve()}}elementAppearedInViewport(e){this.proposeVisitIfNavigatedWithAction(e,b(e)),this.#D()}willSubmitFormLinkToLocation(e){return this.#_(e)}submittedFormLinkToLocation(e,t,s){const r=this.#p(e);r&&s.setAttribute("data-turbo-frame",r.id)}shouldInterceptLinkClick(e,t,s){return this.#_(e)}linkClickIntercepted(e,t){this.#$(e,t)}willSubmitForm(e,t){return e.closest("turbo-frame")==this.element&&this.#_(e,t)}formSubmitted(e,t){this.formSubmission&&this.formSubmission.stop(),this.formSubmission=new ie(this,e,t);const{fetchRequest:s}=this.formSubmission,r=this.#p(e,t);this.prepareRequest(s,r),this.formSubmission.start()}prepareRequest(e,t=this){e.headers["Turbo-Frame"]=t.id,this.currentNavigationElement?.hasAttribute("data-turbo-stream")&&e.acceptResponseType(Q.contentType)}requestStarted(e){m(this.element)}requestPreventedHandlingResponse(e,t){this.#q()}async requestSucceededWithResponse(e,t){await this.loadResponse(t),this.#q()}async requestFailedWithResponse(e,t){await this.loadResponse(t),this.#q()}requestErrored(e,t){console.error(t),this.#q()}requestFinished(e){p(this.element)}formSubmissionStarted({formElement:e}){m(e,this.#p(e))}formSubmissionSucceededWithResponse(e,t){const s=this.#p(e.formElement,e.submitter);s.delegate.proposeVisitIfNavigatedWithAction(s,b(e.submitter,e.formElement,s)),s.delegate.loadResponse(t),e.isSafe||yt.clearCache()}formSubmissionFailedWithResponse(e,t){this.element.delegate.loadResponse(t),yt.clearCache()}formSubmissionErrored(e,t){console.error(t)}formSubmissionFinished({formElement:e}){p(e,this.#p(e))}allowsImmediateRender({element:e},t){const s=i("turbo:before-frame-render",{target:this.element,detail:{newFrame:e,...t},cancelable:!0}),{defaultPrevented:r,detail:{render:n}}=s;return this.view.renderer&&n&&(this.view.renderer.renderElement=n),!r}viewRenderedSnapshot(e,t,s){}preloadOnLoadLinksForView(e){yt.preloadOnLoadLinksForView(e)}viewInvalidated(){}willRenderFrame(e,t){this.previousFrameElement=e.cloneNode(!0)}visitCachedSnapshot=({element:e})=>{const t=e.querySelector("#"+this.element.id);t&&this.previousFrameElement&&t.replaceChildren(...this.previousFrameElement.children),delete this.previousFrameElement};async#W(e,t){const s=await this.extractForeignFrameElement(t.body),r=this.#O?Ae:ge;if(s){const t=new ne(s),i=new r(this,this.view.snapshot,t,!1,!1);this.view.renderPromise&&await this.view.renderPromise,this.changeHistory(),await this.view.render(i),this.complete=!0,yt.frameRendered(e,this.element),yt.frameLoaded(this.element),await this.fetchResponseLoaded(e)}else this.#j(e)&&this.#z(e)}async#V(e){const t=new z(this,_.get,e,new URLSearchParams,this.element);return this.#I?.cancel(),this.#I=t,new Promise((e=>{this.#q=()=>{this.#q=()=>{},this.#I=null,e()},t.perform()}))}#$(e,t,s){const r=this.#p(e,s);r.delegate.proposeVisitIfNavigatedWithAction(r,b(s,e,r)),this.#G(e,(()=>{r.src=t}))}proposeVisitIfNavigatedWithAction(e,t=null){if(this.action=t,this.action){const t=Pe.fromElement(e).clone(),{visitCachedSnapshot:s}=e.delegate;e.delegate.fetchResponseLoaded=async r=>{if(e.src){const{statusCode:i,redirected:n}=r,o={response:{statusCode:i,redirected:n,responseHTML:await r.responseHTML},visitCachedSnapshot:s,willRender:!1,updateHistory:!1,restorationIdentifier:this.restorationIdentifier,snapshot:t};this.action&&(o.action=this.action),yt.visit(e.src,o)}}}}changeHistory(){if(this.action){const e=g(this.action);yt.history.update(e,k(this.element.src||""),this.restorationIdentifier)}}async#U(e){console.warn(`The response (${e.statusCode}) from <turbo-frame id="${this.element.id}"> is performing a full page visit due to turbo-visit-control.`),await this.#K(e.response)}#j(e){this.element.setAttribute("complete","");const t=e.response;return!i("turbo:frame-missing",{target:this.element,detail:{response:t,visit:async(e,t)=>{e instanceof Response?this.#K(e):yt.visit(e,t)}},cancelable:!0}).defaultPrevented}#z(e){this.view.missing(),this.#J(e)}#J(e){const t=`The response (${e.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 Nt(t)}async#K(e){const t=new D(e),s=await t.responseHTML,{location:r,redirected:i,statusCode:n}=t;return yt.visit(r,{response:{redirected:i,statusCode:n,responseHTML:s}})}#p(e,s){const r=u("data-turbo-frame",s,e)||this.element.getAttribute("target"),i=this.#X(r);return i instanceof t?i:this.element}async extractForeignFrameElement(e){let s;const r=CSS.escape(this.id);try{if(s=Ot(e.querySelector(`turbo-frame#${r}`),this.sourceURL),s)return s;if(s=Ot(e.querySelector(`turbo-frame[src][recurse~=${r}]`),this.sourceURL),s)return await s.loaded,await this.extractForeignFrameElement(s)}catch(e){return console.error(e),new t}return null}#Y(e,t){return q(k(F(e,t)),this.rootLocation)}#_(e,t){const s=u("data-turbo-frame",t,e)||this.element.getAttribute("target");if(e instanceof HTMLFormElement&&!this.#Y(e,t))return!1;if(!this.enabled||"_top"==s)return!1;if(s){const e=this.#X(s);if(e)return!e.disabled;if("_parent"==s)return!1}return!!yt.elementIsNavigatable(e)&&!(t&&!yt.elementIsNavigatable(t))}get id(){return this.element.id}get disabled(){return this.element.disabled}get enabled(){return!this.disabled}get sourceURL(){if(this.element.src)return this.element.src}set sourceURL(e){this.#Q("src",(()=>{this.element.src=e??null}))}get loadingStyle(){return this.element.loading}get isLoading(){return void 0!==this.formSubmission||void 0!==this.#q()}get complete(){return this.element.hasAttribute("complete")}set complete(e){e?this.element.setAttribute("complete",""):this.element.removeAttribute("complete")}get isActive(){return this.element.isActive&&this.#H}get rootLocation(){const e=this.element.ownerDocument.querySelector('meta[name="turbo-root"]');return k(e?.content??"/")}#x(e){return this.#N.has(e)}#Q(e,t){this.#N.add(e),t(),this.#N.delete(e)}#G(e,t){this.currentNavigationElement=e,t(),delete this.currentNavigationElement}#X(e){if(null!=e){const s="_parent"===e?this.element.parentElement.closest("turbo-frame"):document.getElementById(e);if(s instanceof t)return s}}},void 0===customElements.get("turbo-frame")&&customElements.define("turbo-frame",t),void 0===customElements.get("turbo-stream")&&customElements.define("turbo-stream",xt),void 0===customElements.get("turbo-stream-source")&&customElements.define("turbo-stream-source",Vt),(()=>{const e=document.currentScript;if(!e)return;if(e.hasAttribute("data-turbo-suppress-warning"))return;let t=e.parentElement;for(;t;){if(t==document.body)return console.warn(h`
20
+ You are loading Turbo from a <script> element inside the <body> element. This is probably not what you meant to do!
21
+
22
+ Load your application’s JavaScript bundle inside the <head> element instead. <script> elements in <body> are evaluated with each page change.
23
+
24
+ For more information, see: https://turbo.hotwired.dev/handbook/building#working-with-script-elements
25
+
26
+ ——
27
+ Suppress this warning by adding a "data-turbo-suppress-warning" attribute to: %s
28
+ `,e.outerHTML);t=t.parentElement}})(),window.Turbo={...Bt,StreamActions:Dt},Rt();var Wt=Object.freeze({__proto__:null,FetchEnctype:j,FetchMethod:_,FetchRequest:z,FetchResponse:D,FrameElement:t,FrameLoadingStyle:e,FrameRenderer:ge,PageRenderer:mt,PageSnapshot:Pe,StreamActions:Dt,StreamElement:xt,StreamSourceElement:Vt,cache:Et,config:P,connectStreamSource:Ct,disconnectStreamSource:Pt,fetch:W,fetchEnctypeFromString:$,fetchMethodFromString:U,isSafe:G,morphBodyElements:qt,morphChildren:Se,morphElements:ve,morphTurboFrameElements:Ht,navigator:At,registerAdapter:Tt,renderStreamMessage:kt,session:yt,setConfirmMethod:Ft,setFormMode:It,setProgressBarDelay:Mt,start:Rt,visit:Lt});let Ut;async function _t(){return Ut||$t(jt().then($t))}function $t(e){return Ut=e}async function jt(){const{createConsumer:e}=await Promise.resolve().then((function(){return fs}));return e()}async function zt(e,t){const{subscriptions:s}=await _t();return s.create(e,t)}var Gt=Object.freeze({__proto__:null,getConsumer:_t,setConsumer:$t,createConsumer:jt,subscribeTo:zt});function Kt(e){return e&&"object"==typeof e?e instanceof Date||e instanceof RegExp?e:Array.isArray(e)?e.map(Kt):Object.keys(e).reduce((function(t,s){return t[s[0].toLowerCase()+s.slice(1).replace(/([A-Z]+)/g,(function(e,t){return"_"+t.toLowerCase()}))]=Kt(e[s]),t}),{}):e}class Jt extends HTMLElement{static observedAttributes=["channel","signed-stream-name"];async connectedCallback(){Ct(this),this.subscription=await zt(this.channel,{received:this.dispatchMessageEvent.bind(this),connected:this.subscriptionConnected.bind(this),disconnected:this.subscriptionDisconnected.bind(this)})}disconnectedCallback(){Pt(this),this.subscription&&this.subscription.unsubscribe(),this.subscriptionDisconnected()}attributeChangedCallback(){this.subscription&&(this.disconnectedCallback(),this.connectedCallback())}dispatchMessageEvent(e){const t=new MessageEvent("message",{data:e});return this.dispatchEvent(t)}subscriptionConnected(){this.setAttribute("connected","")}subscriptionDisconnected(){this.removeAttribute("connected")}get channel(){return{channel:this.getAttribute("channel"),signed_stream_name:this.getAttribute("signed-stream-name"),...Kt({...this.dataset})}}}void 0===customElements.get("turbo-cable-stream-source")&&customElements.define("turbo-cable-stream-source",Jt),window.Turbo=Wt,addEventListener("turbo:before-fetch-request",(function(e){if(e.target instanceof HTMLFormElement){const{target:t,detail:{fetchOptions:s}}=e;t.addEventListener("turbo:submit-start",(({detail:{formSubmission:{submitter:e}}})=>{const r=function(e){return e instanceof FormData||e instanceof URLSearchParams}(s.body)?s.body:new URLSearchParams,i=function(e,t,s){const r=function(e){return e instanceof HTMLButtonElement||e instanceof HTMLInputElement?"_method"===e.name?e.value:e.hasAttribute("formmethod")?e.formMethod:null:null}(e),i=t.get("_method"),n=s.getAttribute("method")||"get";return"string"==typeof r?r:"string"==typeof i?i:n}(e,r,t);/get/i.test(i)||(/post/i.test(i)?r.delete("_method"):r.set("_method",i),s.method="post")}),{once:!0})}}));var Xt={logger:"undefined"!=typeof console?console:void 0,WebSocket:"undefined"!=typeof WebSocket?WebSocket:void 0},Yt={log(...e){this.enabled&&(e.push(Date.now()),Xt.logger.log("[ActionCable]",...e))}};const Qt=()=>(new Date).getTime(),Zt=e=>(Qt()-e)/1e3;class es{constructor(e){this.visibilityDidChange=this.visibilityDidChange.bind(this),this.connection=e,this.reconnectAttempts=0}start(){this.isRunning()||(this.startedAt=Qt(),delete this.stoppedAt,this.startPolling(),addEventListener("visibilitychange",this.visibilityDidChange),Yt.log(`ConnectionMonitor started. stale threshold = ${this.constructor.staleThreshold} s`))}stop(){this.isRunning()&&(this.stoppedAt=Qt(),this.stopPolling(),removeEventListener("visibilitychange",this.visibilityDidChange),Yt.log("ConnectionMonitor stopped"))}isRunning(){return this.startedAt&&!this.stoppedAt}recordMessage(){this.pingedAt=Qt()}recordConnect(){this.reconnectAttempts=0,delete this.disconnectedAt,Yt.log("ConnectionMonitor recorded connect")}recordDisconnect(){this.disconnectedAt=Qt(),Yt.log("ConnectionMonitor recorded disconnect")}startPolling(){this.stopPolling(),this.poll()}stopPolling(){clearTimeout(this.pollTimeout)}poll(){this.pollTimeout=setTimeout((()=>{this.reconnectIfStale(),this.poll()}),this.getPollInterval())}getPollInterval(){const{staleThreshold:e,reconnectionBackoffRate:t}=this.constructor;return 1e3*e*Math.pow(1+t,Math.min(this.reconnectAttempts,10))*(1+(0===this.reconnectAttempts?1:t)*Math.random())}reconnectIfStale(){this.connectionIsStale()&&(Yt.log(`ConnectionMonitor detected stale connection. reconnectAttempts = ${this.reconnectAttempts}, time stale = ${Zt(this.refreshedAt)} s, stale threshold = ${this.constructor.staleThreshold} s`),this.reconnectAttempts++,this.disconnectedRecently()?Yt.log(`ConnectionMonitor skipping reopening recent disconnect. time disconnected = ${Zt(this.disconnectedAt)} s`):(Yt.log("ConnectionMonitor reopening"),this.connection.reopen()))}get refreshedAt(){return this.pingedAt?this.pingedAt:this.startedAt}connectionIsStale(){return Zt(this.refreshedAt)>this.constructor.staleThreshold}disconnectedRecently(){return this.disconnectedAt&&Zt(this.disconnectedAt)<this.constructor.staleThreshold}visibilityDidChange(){"visible"===document.visibilityState&&setTimeout((()=>{!this.connectionIsStale()&&this.connection.isOpen()||(Yt.log(`ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = ${document.visibilityState}`),this.connection.reopen())}),200)}}es.staleThreshold=6,es.reconnectionBackoffRate=.15;var ts=es,ss={message_types:{welcome:"welcome",disconnect:"disconnect",ping:"ping",confirmation:"confirm_subscription",rejection:"reject_subscription"},disconnect_reasons:{unauthorized:"unauthorized",invalid_request:"invalid_request",server_restart:"server_restart",remote:"remote"},default_mount_path:"/cable",protocols:["actioncable-v1-json","actioncable-unsupported"]};const{message_types:rs,protocols:is}=ss,ns=is.slice(0,is.length-1),os=[].indexOf;class as{constructor(e){this.open=this.open.bind(this),this.consumer=e,this.subscriptions=this.consumer.subscriptions,this.monitor=new ts(this),this.disconnected=!0}send(e){return!!this.isOpen()&&(this.webSocket.send(JSON.stringify(e)),!0)}open(){if(this.isActive())return Yt.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`),!1;{const e=[...is,...this.consumer.subprotocols||[]];return Yt.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${e}`),this.webSocket&&this.uninstallEventHandlers(),this.webSocket=new Xt.WebSocket(this.consumer.url,e),this.installEventHandlers(),this.monitor.start(),!0}}close({allowReconnect:e}={allowReconnect:!0}){if(e||this.monitor.stop(),this.isOpen())return this.webSocket.close()}reopen(){if(Yt.log(`Reopening WebSocket, current state is ${this.getState()}`),!this.isActive())return this.open();try{return this.close()}catch(e){Yt.log("Failed to reopen WebSocket",e)}finally{Yt.log(`Reopening WebSocket in ${this.constructor.reopenDelay}ms`),setTimeout(this.open,this.constructor.reopenDelay)}}getProtocol(){if(this.webSocket)return this.webSocket.protocol}isOpen(){return this.isState("open")}isActive(){return this.isState("open","connecting")}triedToReconnect(){return this.monitor.reconnectAttempts>0}isProtocolSupported(){return os.call(ns,this.getProtocol())>=0}isState(...e){return os.call(e,this.getState())>=0}getState(){if(this.webSocket)for(let e in Xt.WebSocket)if(Xt.WebSocket[e]===this.webSocket.readyState)return e.toLowerCase();return null}installEventHandlers(){for(let e in this.events){const t=this.events[e].bind(this);this.webSocket[`on${e}`]=t}}uninstallEventHandlers(){for(let e in this.events)this.webSocket[`on${e}`]=function(){}}}as.reopenDelay=500,as.prototype.events={message(e){if(!this.isProtocolSupported())return;const{identifier:t,message:s,reason:r,reconnect:i,type:n}=JSON.parse(e.data);switch(this.monitor.recordMessage(),n){case rs.welcome:return this.triedToReconnect()&&(this.reconnectAttempted=!0),this.monitor.recordConnect(),this.subscriptions.reload();case rs.disconnect:return Yt.log(`Disconnecting. Reason: ${r}`),this.close({allowReconnect:i});case rs.ping:return null;case rs.confirmation:return this.subscriptions.confirmSubscription(t),this.reconnectAttempted?(this.reconnectAttempted=!1,this.subscriptions.notify(t,"connected",{reconnected:!0})):this.subscriptions.notify(t,"connected",{reconnected:!1});case rs.rejection:return this.subscriptions.reject(t);default:return this.subscriptions.notify(t,"received",s)}},open(){if(Yt.log(`WebSocket onopen event, using '${this.getProtocol()}' subprotocol`),this.disconnected=!1,!this.isProtocolSupported())return Yt.log("Protocol is unsupported. Stopping monitor and disconnecting."),this.close({allowReconnect:!1})},close(e){if(Yt.log("WebSocket onclose event"),!this.disconnected)return this.disconnected=!0,this.monitor.recordDisconnect(),this.subscriptions.notifyAll("disconnected",{willAttemptReconnect:this.monitor.isRunning()})},error(){Yt.log("WebSocket onerror event")}};var cs=as;class ls{constructor(e,t={},s){this.consumer=e,this.identifier=JSON.stringify(t),function(e,t){if(null!=t)for(let s in t){const r=t[s];e[s]=r}}(this,s)}perform(e,t={}){return t.action=e,this.send(t)}send(e){return this.consumer.send({command:"message",identifier:this.identifier,data:JSON.stringify(e)})}unsubscribe(){return this.consumer.subscriptions.remove(this)}}var hs=class{constructor(e){this.subscriptions=e,this.pendingSubscriptions=[]}guarantee(e){-1==this.pendingSubscriptions.indexOf(e)?(Yt.log(`SubscriptionGuarantor guaranteeing ${e.identifier}`),this.pendingSubscriptions.push(e)):Yt.log(`SubscriptionGuarantor already guaranteeing ${e.identifier}`),this.startGuaranteeing()}forget(e){Yt.log(`SubscriptionGuarantor forgetting ${e.identifier}`),this.pendingSubscriptions=this.pendingSubscriptions.filter((t=>t!==e))}startGuaranteeing(){this.stopGuaranteeing(),this.retrySubscribing()}stopGuaranteeing(){clearTimeout(this.retryTimeout)}retrySubscribing(){this.retryTimeout=setTimeout((()=>{this.subscriptions&&"function"==typeof this.subscriptions.subscribe&&this.pendingSubscriptions.map((e=>{Yt.log(`SubscriptionGuarantor resubscribing ${e.identifier}`),this.subscriptions.subscribe(e)}))}),500)}};class ds{constructor(e){this.consumer=e,this.guarantor=new hs(this),this.subscriptions=[]}create(e,t){const s="object"==typeof e?e:{channel:e},r=new ls(this.consumer,s,t);return this.add(r)}add(e){return this.subscriptions.push(e),this.consumer.ensureActiveConnection(),this.notify(e,"initialized"),this.subscribe(e),e}remove(e){return this.forget(e),this.findAll(e.identifier).length||this.sendCommand(e,"unsubscribe"),e}reject(e){return this.findAll(e).map((e=>(this.forget(e),this.notify(e,"rejected"),e)))}forget(e){return this.guarantor.forget(e),this.subscriptions=this.subscriptions.filter((t=>t!==e)),e}findAll(e){return this.subscriptions.filter((t=>t.identifier===e))}reload(){return this.subscriptions.map((e=>this.subscribe(e)))}notifyAll(e,...t){return this.subscriptions.map((s=>this.notify(s,e,...t)))}notify(e,t,...s){let r;return r="string"==typeof e?this.findAll(e):[e],r.map((e=>"function"==typeof e[t]?e[t](...s):void 0))}subscribe(e){this.sendCommand(e,"subscribe")&&this.guarantor.guarantee(e)}confirmSubscription(e){Yt.log(`Subscription confirmed ${e}`),this.findAll(e).map((e=>this.guarantor.forget(e)))}sendCommand(e,t){const{identifier:s}=e;return this.consumer.send({command:t,identifier:s})}}class us{constructor(e){this._url=e,this.subscriptions=new ds(this),this.connection=new cs(this),this.subprotocols=[]}get url(){return ms(this._url)}send(e){return this.connection.send(e)}connect(){return this.connection.open()}disconnect(){return this.connection.close({allowReconnect:!1})}ensureActiveConnection(){if(!this.connection.isActive())return this.connection.open()}addSubProtocol(e){this.subprotocols=[...this.subprotocols,e]}}function ms(e){if("function"==typeof e&&(e=e()),e&&!/^wss?:/i.test(e)){const t=document.createElement("a");return t.href=e,t.href=t.href,t.protocol=t.protocol.replace("http","ws"),t.href}return e}function ps(e){const t=document.head.querySelector(`meta[name='action-cable-${e}']`);if(t)return t.getAttribute("content")}var fs=Object.freeze({__proto__:null,Connection:cs,ConnectionMonitor:ts,Consumer:us,INTERNAL:ss,Subscription:ls,Subscriptions:ds,SubscriptionGuarantor:hs,adapters:Xt,createWebSocketURL:ms,logger:Yt,createConsumer:function(e=ps("url")||ss.default_mount_path){return new us(e)},getConfig:ps});export{Wt as Turbo,Gt as cable};
@@ -17,10 +17,24 @@ module HrLite
17
17
  end
18
18
 
19
19
  def show
20
- @employee = HrLite.user_klass.find(params[:user_id])
21
- hr_require_reach!("document.view", @employee)
22
- @documents = Document.for_user(@employee).recent_first
23
- @missing = Document::SENSITIVE_CATEGORIES - @documents.map(&:category)
20
+ load_person
21
+ @document = Document.new
22
+ end
23
+
24
+ # HR files a document for someone, e.g. a scan handed over on paper:
25
+ # company-wide profile managers only, and never their own (My documents).
26
+ def create
27
+ load_person
28
+ raise ActiveRecord::RecordNotFound if @employee.id == hr_current_user.id
29
+ return hr_access_denied unless hr_can?("profile.manage", scope: :all)
30
+
31
+ @document = Document.new(params.require(:document).permit(:category, :title, :reference_number, :issued_on, :expires_on, :file)
32
+ .merge(user_id: @employee.id, uploaded_by_id: hr_current_user.id))
33
+ if @document.save
34
+ redirect_to admin_employee_documents_path(@employee.id), notice: "#{@document.title} uploaded."
35
+ else
36
+ render :show, status: :unprocessable_entity
37
+ end
24
38
  end
25
39
 
26
40
  def verify
@@ -44,6 +58,13 @@ module HrLite
44
58
 
45
59
  private
46
60
 
61
+ def load_person
62
+ @employee = HrLite.user_klass.find(params[:user_id])
63
+ hr_require_reach!("document.view", @employee)
64
+ @documents = Document.for_user(@employee).recent_first
65
+ @missing = Document::SENSITIVE_CATEGORIES - @documents.map(&:category)
66
+ end
67
+
47
68
  def require_document_access!
48
69
  hr_require_permission!("document.view", scope: :team)
49
70
  end
@@ -56,7 +56,7 @@ module HrLite
56
56
  # rails_blob_path, not url_for: an engine controller has no default
57
57
  # host and url_for(attachment) raises without one.
58
58
  redirect_to Rails.application.routes.url_helpers.rails_blob_path(
59
- document.file, disposition: "attachment", only_path: true
59
+ document.file, disposition: "attachment", only_path: true, expires_in: 5.minutes # the link dies with the visit
60
60
  ), allow_other_host: false
61
61
  end
62
62
 
@@ -76,8 +76,11 @@ module HrLite
76
76
 
77
77
  def worked_under?(minutes) = !!(minutes && worked_duration && worked_duration < minutes.minutes)
78
78
 
79
- # Check in again after checking out: once a day, inside the hours HR sets in Settings.
79
+ # Check in again after checking out: once a day, inside the hours HR sets in
80
+ # Settings, and only while the day is short (a full day has nothing to add).
80
81
  def recheck_in_open?(at = Time.current)
82
+ return false if required_minutes && !short?
83
+
81
84
  s = Setting.instance
82
85
  now = at.in_time_zone(HrLite.config.time_zone).strftime("%H:%M")
83
86
  check_out_at.present? && rechecked_in_at.nil? && now >= s.recheck_in_from && now < s.recheck_in_until
@@ -41,3 +41,7 @@
41
41
  </div>
42
42
  <% end %>
43
43
  </section>
44
+
45
+ <% if @employee.id != hr_current_user.id && hr_can?("profile.manage", scope: :all) %>
46
+ <%= render "hr_lite/documents/upload_form", document: @document, url: hr_lite.admin_employee_documents_path(@employee.id), open: @document.errors.any? %>
47
+ <% end %>
@@ -108,6 +108,8 @@
108
108
  </button>
109
109
  <p class="hrl-small hrl-muted" data-hrl-geo-status role="status" aria-live="polite"></p>
110
110
  <% end %>
111
+ <% elsif record.required_minutes && !record.short? %>
112
+ <p class="hrl-small hrl-muted">Your day is done: <%= hrl_duration(record.worked_duration) %> worked.</p>
111
113
  <% else %>
112
114
  <p class="hrl-small hrl-muted">Check in again is open once a day, <%= HrLite::Setting.instance.recheck_in_from %>–<%= HrLite::Setting.instance.recheck_in_until %>.</p>
113
115
  <% end %>
@@ -0,0 +1,30 @@
1
+ <%# locals: document, url (where it posts), open (start expanded) — one upload form for My documents and HR's view of a person. %>
2
+ <details class="hrl-card" <%= "open" if open || document.errors.any? %>>
3
+ <summary class="hrl-btn hrl-btn--primary">Upload a document</summary>
4
+ <%= form_with model: document, url: url, method: :post, local: true, class: "hrl-mt" do |f| %>
5
+ <%= render "hr_lite/shared/form_errors", record: document %>
6
+ <div class="hrl-field">
7
+ <%= f.label :category, id: "hrl-doc-category", for: nil %>
8
+ <div class="hrl-chiprow" role="radiogroup" aria-labelledby="hrl-doc-category">
9
+ <% (HrLite::Document::SENSITIVE_CATEGORIES.map { |c| [ c.humanize.sub(/\APan\z/, "PAN"), c ] } +
10
+ [ [ "Offer letter", "offer_letter" ], [ "Certificate", "certificate" ], [ "Other", "other" ] ]).each do |label, value| %>
11
+ <label><%= f.radio_button :category, value, required: true %><span><%= label %></span></label>
12
+ <% end %>
13
+ </div>
14
+ </div>
15
+ <div class="hrl-field"><%= f.label :title %><%= f.text_field :title, required: true %></div>
16
+ <div class="hrl-field">
17
+ <%= f.label :reference_number, "Document number (optional)" %>
18
+ <%= f.text_field :reference_number %>
19
+ </div>
20
+ <div class="hrl-field">
21
+ <%= f.label :expires_on, "Expires on (optional — we will remind you)" %>
22
+ <%= f.date_field :expires_on %>
23
+ </div>
24
+ <div class="hrl-field">
25
+ <%= f.label :file, "File (PDF or image, up to 10 MB)" %>
26
+ <%= f.file_field :file, required: true, accept: "application/pdf,image/*" %>
27
+ </div>
28
+ <div class="hrl-form-actions"><%= f.submit "Upload", class: "hrl-btn hrl-btn--primary" %></div>
29
+ <% end %>
30
+ </details>
@@ -55,32 +55,4 @@
55
55
  <% end %>
56
56
  </section>
57
57
 
58
- <details class="hrl-card" <%= "open" if @documents.empty? || @document.errors.any? %>>
59
- <summary class="hrl-btn hrl-btn--primary">Upload a document</summary>
60
- <%= form_with model: @document, url: hr_lite.documents_path, method: :post, local: true, class: "hrl-mt" do |f| %>
61
- <%= render "hr_lite/shared/form_errors", record: @document %>
62
- <div class="hrl-field">
63
- <%= f.label :category, id: "hrl-doc-category", for: nil %>
64
- <div class="hrl-chiprow" role="radiogroup" aria-labelledby="hrl-doc-category">
65
- <% (HrLite::Document::SENSITIVE_CATEGORIES.map { |c| [ c.humanize.sub(/\APan\z/, "PAN"), c ] } +
66
- [ [ "Offer letter", "offer_letter" ], [ "Certificate", "certificate" ], [ "Other", "other" ] ]).each do |label, value| %>
67
- <label><%= f.radio_button :category, value, required: true %><span><%= label %></span></label>
68
- <% end %>
69
- </div>
70
- </div>
71
- <div class="hrl-field"><%= f.label :title %><%= f.text_field :title, required: true %></div>
72
- <div class="hrl-field">
73
- <%= f.label :reference_number, "Document number (optional)" %>
74
- <%= f.text_field :reference_number %>
75
- </div>
76
- <div class="hrl-field">
77
- <%= f.label :expires_on, "Expires on (optional — we will remind you)" %>
78
- <%= f.date_field :expires_on %>
79
- </div>
80
- <div class="hrl-field">
81
- <%= f.label :file, "File (PDF or image, up to 10 MB)" %>
82
- <%= f.file_field :file, required: true, accept: "application/pdf,image/*" %>
83
- </div>
84
- <div class="hrl-form-actions"><%= f.submit "Upload", class: "hrl-btn hrl-btn--primary" %></div>
85
- <% end %>
86
- </details>
58
+ <%= render "hr_lite/documents/upload_form", document: @document, url: hr_lite.documents_path, open: @documents.empty? %>
@@ -7,6 +7,13 @@
7
7
  <%= csrf_meta_tags %>
8
8
  <%= csp_meta_tag %>
9
9
  <%= yield :head %>
10
+ <% if HrLite.config.native_app.call(request) %>
11
+ <%# The host's iOS/Android shells drive pages through Turbo. "reload" makes
12
+ every visit a full page load, so the plain scripts below run exactly
13
+ as they do in a browser. Browsers never load Turbo here. %>
14
+ <meta name="turbo-visit-control" content="reload">
15
+ <%= javascript_include_tag "hr_lite/vendor/turbo.min", type: "module" %>
16
+ <% end %>
10
17
  <%= stylesheet_link_tag "hr_lite/hr_lite", media: "all" %>
11
18
  <% HrLite.config.extra_stylesheets.each do |sheet| %>
12
19
  <%= stylesheet_link_tag sheet, media: "all" %>
data/config/routes.rb CHANGED
@@ -105,6 +105,7 @@ HrLite::Engine.routes.draw do
105
105
  member { post :verify; post :reject }
106
106
  end
107
107
  get "documents/for/:user_id", to: "documents#show", as: :employee_documents
108
+ post "documents/for/:user_id", to: "documents#create"
108
109
  resources :tax_declarations, only: %i[index show update] do
109
110
  member { post :verify; post :reject; post :accept_all; get "proofs/:proof_id", action: :proof, as: :proof }
110
111
  collection { get :overview; get "people/:user_id", action: :person, as: :person }
@@ -13,6 +13,9 @@ module HrLite
13
13
  # ->(user) { { url:, unread: } } — shows a notifications link in
14
14
  # the HR shell; nil (default) shows nothing.
15
15
  :notifications,
16
+ # ->(request) { bool } — is this request from the host's native app?
17
+ # Native pages load Turbo (see the layout); browsers never do.
18
+ :native_app,
16
19
  # e.g. 6 — default probation for new hires (admin edits per employee)
17
20
  :probation_months,
18
21
  # true = a punch without GPS is refused (default: recorded and flagged)
@@ -114,6 +117,7 @@ module HrLite
114
117
  @public_url_base = nil # e.g. "https://hr.example.com" — enables email links + HrLite.public_url
115
118
  @notification_matrix = nil # resolved lazily to Notifications::DEFAULT_MATRIX
116
119
  @back_link = nil # optional {label:, url:} for the shell nav
120
+ @native_app = ->(request) { request.user_agent.to_s.match?(/Hotwire Native|Turbo Native/) }
117
121
  @leave_year_start_month = 1 # 1 = calendar year; 7 = July–June leave year
118
122
  @slip_release_day = nil # e.g. 10 = slips open on the 10th of the next month
119
123
  @self_regularization = nil # e.g. { within_days: 2, per_week: 2 } — employees fix their own missed punch
@@ -1,3 +1,3 @@
1
1
  module HrLite
2
- VERSION = "0.51.0"
2
+ VERSION = "0.53.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hr_lite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.51.0
4
+ version: 0.53.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - kshitiz sinha
@@ -79,6 +79,7 @@ files:
79
79
  - app/assets/javascripts/hr_lite/share.js
80
80
  - app/assets/javascripts/hr_lite/tax_preview.js
81
81
  - app/assets/javascripts/hr_lite/vendor/html_to_image.js
82
+ - app/assets/javascripts/hr_lite/vendor/turbo.min.js
82
83
  - app/assets/stylesheets/hr_lite/application.css
83
84
  - app/assets/stylesheets/hr_lite/hr_lite.css
84
85
  - app/controllers/hr_lite/admin/appraisals_controller.rb
@@ -369,6 +370,7 @@ files:
369
370
  - app/views/hr_lite/career/show.html.erb
370
371
  - app/views/hr_lite/comp_off_requests/index.html.erb
371
372
  - app/views/hr_lite/comp_off_requests/new.html.erb
373
+ - app/views/hr_lite/documents/_upload_form.html.erb
372
374
  - app/views/hr_lite/documents/index.html.erb
373
375
  - app/views/hr_lite/employee_profiles/show.html.erb
374
376
  - app/views/hr_lite/event_mailer/event.html.erb