panda-core 0.2.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +185 -0
- data/app/assets/tailwind/application.css +279 -0
- data/app/assets/tailwind/tailwind.config.js +21 -0
- data/app/components/panda/core/UI/badge.rb +107 -0
- data/app/components/panda/core/UI/button.rb +89 -0
- data/app/components/panda/core/UI/card.rb +88 -0
- data/app/components/panda/core/admin/button_component.rb +46 -28
- data/app/components/panda/core/admin/container_component.rb +52 -4
- data/app/components/panda/core/admin/flash_message_component.rb +74 -9
- data/app/components/panda/core/admin/form_error_component.rb +48 -0
- data/app/components/panda/core/admin/form_input_component.rb +50 -0
- data/app/components/panda/core/admin/form_select_component.rb +68 -0
- data/app/components/panda/core/admin/heading_component.rb +52 -24
- data/app/components/panda/core/admin/panel_component.rb +33 -4
- data/app/components/panda/core/admin/slideover_component.rb +8 -4
- data/app/components/panda/core/admin/statistics_component.rb +19 -0
- data/app/components/panda/core/admin/tab_bar_component.rb +101 -0
- data/app/components/panda/core/admin/table_component.rb +90 -9
- data/app/components/panda/core/admin/tag_component.rb +21 -16
- data/app/components/panda/core/admin/user_activity_component.rb +43 -0
- data/app/components/panda/core/admin/user_display_component.rb +78 -0
- data/app/components/panda/core/base.rb +122 -0
- data/app/controllers/panda/core/admin/base_controller.rb +68 -0
- data/app/controllers/panda/core/admin/dashboard_controller.rb +7 -6
- data/app/controllers/panda/core/admin/my_profile_controller.rb +3 -3
- data/app/controllers/panda/core/admin/sessions_controller.rb +26 -5
- data/app/helpers/panda/core/sessions_helper.rb +21 -0
- data/app/javascript/panda/core/application.js +1 -0
- data/app/javascript/panda/core/vendor/@hotwired--stimulus.js +4 -0
- data/app/javascript/panda/core/vendor/@hotwired--turbo.js +160 -0
- data/app/javascript/panda/core/vendor/@rails--actioncable--src.js +4 -0
- data/app/models/panda/core/user.rb +17 -13
- data/app/views/layouts/panda/core/admin.html.erb +40 -57
- data/app/views/layouts/panda/core/admin_simple.html.erb +5 -0
- data/app/views/panda/core/admin/dashboard/_default_content.html.erb +73 -0
- data/app/views/panda/core/admin/dashboard/show.html.erb +4 -10
- data/app/views/panda/core/admin/my_profile/edit.html.erb +13 -27
- data/app/views/panda/core/admin/sessions/new.html.erb +13 -12
- data/app/views/panda/core/admin/shared/_breadcrumbs.html.erb +27 -34
- data/app/views/panda/core/admin/shared/_flash.html.erb +4 -30
- data/app/views/panda/core/admin/shared/_sidebar.html.erb +36 -20
- data/app/views/panda/core/shared/_footer.html.erb +2 -0
- data/app/views/panda/core/shared/_header.html.erb +19 -0
- data/config/importmap.rb +15 -0
- data/config/initializers/panda_core.rb +37 -1
- data/config/routes.rb +7 -7
- data/db/migrate/20250810120000_add_current_theme_to_panda_core_users.rb +7 -0
- data/lib/generators/panda/core/install_generator.rb +3 -9
- data/lib/generators/panda/core/templates/README +25 -0
- data/lib/generators/panda/core/templates/initializer.rb +28 -0
- data/lib/panda/core/asset_loader.rb +23 -8
- data/lib/panda/core/configuration.rb +41 -9
- data/lib/panda/core/debug.rb +47 -0
- data/lib/panda/core/engine.rb +82 -8
- data/lib/panda/core/version.rb +1 -1
- data/lib/panda/core.rb +1 -0
- data/lib/tasks/assets.rake +58 -392
- data/lib/tasks/panda_core_tasks.rake +16 -0
- metadata +102 -14
- data/app/components/panda/core/admin/container_component.html.erb +0 -12
- data/app/components/panda/core/admin/flash_message_component.html.erb +0 -31
- data/app/components/panda/core/admin/panel_component.html.erb +0 -7
- data/app/components/panda/core/admin/slideover_component.html.erb +0 -9
- data/app/components/panda/core/admin/table_component.html.erb +0 -29
- data/app/controllers/panda/core/admin_controller.rb +0 -28
|
@@ -3,19 +3,24 @@
|
|
|
3
3
|
module Panda
|
|
4
4
|
module Core
|
|
5
5
|
module Admin
|
|
6
|
-
class SessionsController <
|
|
6
|
+
class SessionsController < BaseController
|
|
7
|
+
layout "panda/core/admin_simple"
|
|
8
|
+
|
|
7
9
|
# Skip authentication for login/logout actions
|
|
8
10
|
skip_before_action :authenticate_admin_user!, only: [:new, :create, :destroy, :failure]
|
|
9
11
|
|
|
10
12
|
def new
|
|
11
|
-
@providers = Core.
|
|
13
|
+
@providers = Core.config.authentication_providers.keys
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
def create
|
|
15
17
|
auth = request.env["omniauth.auth"]
|
|
16
|
-
|
|
18
|
+
provider_path = params[:provider]&.to_sym
|
|
19
|
+
|
|
20
|
+
# Find the actual provider key (might be using path_name override)
|
|
21
|
+
provider = find_provider_by_path(provider_path)
|
|
17
22
|
|
|
18
|
-
unless Core.
|
|
23
|
+
unless provider && Core.config.authentication_providers.key?(provider)
|
|
19
24
|
redirect_to admin_login_path, flash: {error: "Authentication provider not enabled"}
|
|
20
25
|
return
|
|
21
26
|
end
|
|
@@ -37,7 +42,8 @@ module Panda
|
|
|
37
42
|
provider: provider)
|
|
38
43
|
|
|
39
44
|
# Use configured dashboard path or default to admin_root_path
|
|
40
|
-
redirect_path = Panda::Core.
|
|
45
|
+
redirect_path = Panda::Core.config.dashboard_redirect_path || admin_root_path
|
|
46
|
+
redirect_path = redirect_path.call if redirect_path.respond_to?(:call)
|
|
41
47
|
redirect_to redirect_path, flash: {success: "Successfully logged in as #{user.name}"}
|
|
42
48
|
else
|
|
43
49
|
redirect_to admin_login_path, flash: {error: "Unable to create account: #{user.errors.full_messages.join(", ")}"}
|
|
@@ -63,6 +69,21 @@ module Panda
|
|
|
63
69
|
|
|
64
70
|
redirect_to admin_login_path, flash: {success: "Successfully logged out"}
|
|
65
71
|
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
# Find the provider key by path name (handles path_name override)
|
|
76
|
+
def find_provider_by_path(provider_path)
|
|
77
|
+
# First check if it's a direct match
|
|
78
|
+
return provider_path if Core.config.authentication_providers.key?(provider_path)
|
|
79
|
+
|
|
80
|
+
# Then check if any provider has a matching path_name
|
|
81
|
+
Core.config.authentication_providers.each do |key, config|
|
|
82
|
+
return key if config[:path_name]&.to_sym == provider_path
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
nil
|
|
86
|
+
end
|
|
66
87
|
end
|
|
67
88
|
end
|
|
68
89
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Panda
|
|
4
|
+
module Core
|
|
5
|
+
module SessionsHelper
|
|
6
|
+
# Map OAuth provider names to their FontAwesome icon names
|
|
7
|
+
PROVIDER_ICON_MAP = {
|
|
8
|
+
google_oauth2: "google",
|
|
9
|
+
microsoft_graph: "microsoft",
|
|
10
|
+
github: "github"
|
|
11
|
+
}.freeze
|
|
12
|
+
|
|
13
|
+
# Returns the FontAwesome icon name for a given provider
|
|
14
|
+
# Checks provider config first, then falls back to the mapping, then uses the provider name as-is
|
|
15
|
+
def oauth_provider_icon(provider)
|
|
16
|
+
provider_config = Panda::Core.config.authentication_providers[provider]
|
|
17
|
+
provider_config&.dig(:icon) || PROVIDER_ICON_MAP[provider.to_sym] || provider.to_s
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @hotwired/stimulus@3.2.2 downloaded from https://ga.jspm.io/npm:@hotwired/stimulus@3.2.2/dist/stimulus.js
|
|
2
|
+
|
|
3
|
+
class EventListener{constructor(e,t,r){this.eventTarget=e;this.eventName=t;this.eventOptions=r;this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(e){this.unorderedBindings.add(e)}bindingDisconnected(e){this.unorderedBindings.delete(e)}handleEvent(e){const t=extendEvent(e);for(const e of this.bindings){if(t.immediatePropagationStopped)break;e.handleEvent(t)}}hasBindings(){return this.unorderedBindings.size>0}get bindings(){return Array.from(this.unorderedBindings).sort(((e,t)=>{const r=e.index,s=t.index;return r<s?-1:r>s?1:0}))}}function extendEvent(e){if("immediatePropagationStopped"in e)return e;{const{stopImmediatePropagation:t}=e;return Object.assign(e,{immediatePropagationStopped:false,stopImmediatePropagation(){this.immediatePropagationStopped=true;t.call(this)}})}}class Dispatcher{constructor(e){this.application=e;this.eventListenerMaps=new Map;this.started=false}start(){if(!this.started){this.started=true;this.eventListeners.forEach((e=>e.connect()))}}stop(){if(this.started){this.started=false;this.eventListeners.forEach((e=>e.disconnect()))}}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce(((e,t)=>e.concat(Array.from(t.values()))),[])}bindingConnected(e){this.fetchEventListenerForBinding(e).bindingConnected(e)}bindingDisconnected(e,t=false){this.fetchEventListenerForBinding(e).bindingDisconnected(e);t&&this.clearEventListenersForBinding(e)}handleError(e,t,r={}){this.application.handleError(e,`Error ${t}`,r)}clearEventListenersForBinding(e){const t=this.fetchEventListenerForBinding(e);if(!t.hasBindings()){t.disconnect();this.removeMappedEventListenerFor(e)}}removeMappedEventListenerFor(e){const{eventTarget:t,eventName:r,eventOptions:s}=e;const n=this.fetchEventListenerMapForEventTarget(t);const i=this.cacheKey(r,s);n.delete(i);0==n.size&&this.eventListenerMaps.delete(t)}fetchEventListenerForBinding(e){const{eventTarget:t,eventName:r,eventOptions:s}=e;return this.fetchEventListener(t,r,s)}fetchEventListener(e,t,r){const s=this.fetchEventListenerMapForEventTarget(e);const n=this.cacheKey(t,r);let i=s.get(n);if(!i){i=this.createEventListener(e,t,r);s.set(n,i)}return i}createEventListener(e,t,r){const s=new EventListener(e,t,r);this.started&&s.connect();return s}fetchEventListenerMapForEventTarget(e){let t=this.eventListenerMaps.get(e);if(!t){t=new Map;this.eventListenerMaps.set(e,t)}return t}cacheKey(e,t){const r=[e];Object.keys(t).sort().forEach((e=>{r.push(`${t[e]?"":"!"}${e}`)}));return r.join(":")}}const e={stop({event:e,value:t}){t&&e.stopPropagation();return true},prevent({event:e,value:t}){t&&e.preventDefault();return true},self({event:e,value:t,element:r}){return!t||r===e.target}};const t=/^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function parseActionDescriptorString(e){const r=e.trim();const s=r.match(t)||[];let n=s[2];let i=s[3];if(i&&!["keydown","keyup","keypress"].includes(n)){n+=`.${i}`;i=""}return{eventTarget:parseEventTarget(s[4]),eventName:n,eventOptions:s[7]?parseEventOptions(s[7]):{},identifier:s[5],methodName:s[6],keyFilter:s[1]||i}}function parseEventTarget(e){return"window"==e?window:"document"==e?document:void 0}function parseEventOptions(e){return e.split(":").reduce(((e,t)=>Object.assign(e,{[t.replace(/^!/,"")]:!/^!/.test(t)})),{})}function stringifyEventTarget(e){return e==window?"window":e==document?"document":void 0}function camelize(e){return e.replace(/(?:[_-])([a-z0-9])/g,((e,t)=>t.toUpperCase()))}function namespaceCamelize(e){return camelize(e.replace(/--/g,"-").replace(/__/g,"_"))}function capitalize(e){return e.charAt(0).toUpperCase()+e.slice(1)}function dasherize(e){return e.replace(/([A-Z])/g,((e,t)=>`-${t.toLowerCase()}`))}function tokenize(e){return e.match(/[^\s]+/g)||[]}function isSomething(e){return null!==e&&void 0!==e}function hasProperty(e,t){return Object.prototype.hasOwnProperty.call(e,t)}const r=["meta","ctrl","alt","shift"];class Action{constructor(e,t,r,s){this.element=e;this.index=t;this.eventTarget=r.eventTarget||e;this.eventName=r.eventName||getDefaultEventNameForElement(e)||error("missing event name");this.eventOptions=r.eventOptions||{};this.identifier=r.identifier||error("missing identifier");this.methodName=r.methodName||error("missing method name");this.keyFilter=r.keyFilter||"";this.schema=s}static forToken(e,t){return new this(e.element,e.index,parseActionDescriptorString(e.content),t)}toString(){const e=this.keyFilter?`.${this.keyFilter}`:"";const t=this.eventTargetName?`@${this.eventTargetName}`:"";return`${this.eventName}${e}${t}->${this.identifier}#${this.methodName}`}shouldIgnoreKeyboardEvent(e){if(!this.keyFilter)return false;const t=this.keyFilter.split("+");if(this.keyFilterDissatisfied(e,t))return true;const s=t.filter((e=>!r.includes(e)))[0];if(!s)return false;hasProperty(this.keyMappings,s)||error(`contains unknown key filter: ${this.keyFilter}`);return this.keyMappings[s].toLowerCase()!==e.key.toLowerCase()}shouldIgnoreMouseEvent(e){if(!this.keyFilter)return false;const t=[this.keyFilter];return!!this.keyFilterDissatisfied(e,t)}get params(){const e={};const t=new RegExp(`^data-${this.identifier}-(.+)-param$`,"i");for(const{name:r,value:s}of Array.from(this.element.attributes)){const n=r.match(t);const i=n&&n[1];i&&(e[camelize(i)]=typecast(s))}return e}get eventTargetName(){return stringifyEventTarget(this.eventTarget)}get keyMappings(){return this.schema.keyMappings}keyFilterDissatisfied(e,t){const[s,n,i,o]=r.map((e=>t.includes(e)));return e.metaKey!==s||e.ctrlKey!==n||e.altKey!==i||e.shiftKey!==o}}const s={a:()=>"click",button:()=>"click",form:()=>"submit",details:()=>"toggle",input:e=>"submit"==e.getAttribute("type")?"click":"input",select:()=>"change",textarea:()=>"input"};function getDefaultEventNameForElement(e){const t=e.tagName.toLowerCase();if(t in s)return s[t](e)}function error(e){throw new Error(e)}function typecast(e){try{return JSON.parse(e)}catch(t){return e}}class Binding{constructor(e,t){this.context=e;this.action=t}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(e){const t=this.prepareActionEvent(e);this.willBeInvokedByEvent(e)&&this.applyEventModifiers(t)&&this.invokeWithEvent(t)}get eventName(){return this.action.eventName}get method(){const e=this.controller[this.methodName];if("function"==typeof e)return e;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}applyEventModifiers(e){const{element:t}=this.action;const{actionDescriptorFilters:r}=this.context.application;const{controller:s}=this.context;let n=true;for(const[i,o]of Object.entries(this.eventOptions))if(i in r){const c=r[i];n=n&&c({name:i,value:o,event:e,element:t,controller:s})}return n}prepareActionEvent(e){return Object.assign(e,{params:this.action.params})}invokeWithEvent(e){const{target:t,currentTarget:r}=e;try{this.method.call(this.controller,e);this.context.logDebugActivity(this.methodName,{event:e,target:t,currentTarget:r,action:this.methodName})}catch(t){const{identifier:r,controller:s,element:n,index:i}=this;const o={identifier:r,controller:s,element:n,index:i,event:e};this.context.handleError(t,`invoking action "${this.action}"`,o)}}willBeInvokedByEvent(e){const t=e.target;return!(e instanceof KeyboardEvent&&this.action.shouldIgnoreKeyboardEvent(e))&&(!(e instanceof MouseEvent&&this.action.shouldIgnoreMouseEvent(e))&&(this.element===t||(t instanceof Element&&this.element.contains(t)?this.scope.containsElement(t):this.scope.containsElement(this.action.element))))}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class ElementObserver{constructor(e,t){this.mutationObserverInit={attributes:true,childList:true,subtree:true};this.element=e;this.started=false;this.delegate=t;this.elements=new Set;this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){if(!this.started){this.started=true;this.mutationObserver.observe(this.element,this.mutationObserverInit);this.refresh()}}pause(e){if(this.started){this.mutationObserver.disconnect();this.started=false}e();if(!this.started){this.mutationObserver.observe(this.element,this.mutationObserverInit);this.started=true}}stop(){if(this.started){this.mutationObserver.takeRecords();this.mutationObserver.disconnect();this.started=false}}refresh(){if(this.started){const e=new Set(this.matchElementsInTree());for(const t of Array.from(this.elements))e.has(t)||this.removeElement(t);for(const t of Array.from(e))this.addElement(t)}}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){if("attributes"==e.type)this.processAttributeChange(e.target,e.attributeName);else if("childList"==e.type){this.processRemovedNodes(e.removedNodes);this.processAddedNodes(e.addedNodes)}}processAttributeChange(e,t){this.elements.has(e)?this.delegate.elementAttributeChanged&&this.matchElement(e)?this.delegate.elementAttributeChanged(e,t):this.removeElement(e):this.matchElement(e)&&this.addElement(e)}processRemovedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.processTree(e,this.removeElement)}}processAddedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.elementIsActive(e)&&this.processTree(e,this.addElement)}}matchElement(e){return this.delegate.matchElement(e)}matchElementsInTree(e=this.element){return this.delegate.matchElementsInTree(e)}processTree(e,t){for(const r of this.matchElementsInTree(e))t.call(this,r)}elementFromNode(e){if(e.nodeType==Node.ELEMENT_NODE)return e}elementIsActive(e){return e.isConnected==this.element.isConnected&&this.element.contains(e)}addElement(e){if(!this.elements.has(e)&&this.elementIsActive(e)){this.elements.add(e);this.delegate.elementMatched&&this.delegate.elementMatched(e)}}removeElement(e){if(this.elements.has(e)){this.elements.delete(e);this.delegate.elementUnmatched&&this.delegate.elementUnmatched(e)}}}class AttributeObserver{constructor(e,t,r){this.attributeName=t;this.delegate=r;this.elementObserver=new ElementObserver(e,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(e){return e.hasAttribute(this.attributeName)}matchElementsInTree(e){const t=this.matchElement(e)?[e]:[];const r=Array.from(e.querySelectorAll(this.selector));return t.concat(r)}elementMatched(e){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(e,this.attributeName)}elementUnmatched(e){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(e,this.attributeName)}elementAttributeChanged(e,t){this.delegate.elementAttributeValueChanged&&this.attributeName==t&&this.delegate.elementAttributeValueChanged(e,t)}}function add(e,t,r){fetch(e,t).add(r)}function del(e,t,r){fetch(e,t).delete(r);prune(e,t)}function fetch(e,t){let r=e.get(t);if(!r){r=new Set;e.set(t,r)}return r}function prune(e,t){const r=e.get(t);null!=r&&0==r.size&&e.delete(t)}class Multimap{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){const e=Array.from(this.valuesByKey.values());return e.reduce(((e,t)=>e.concat(Array.from(t))),[])}get size(){const e=Array.from(this.valuesByKey.values());return e.reduce(((e,t)=>e+t.size),0)}add(e,t){add(this.valuesByKey,e,t)}delete(e,t){del(this.valuesByKey,e,t)}has(e,t){const r=this.valuesByKey.get(e);return null!=r&&r.has(t)}hasKey(e){return this.valuesByKey.has(e)}hasValue(e){const t=Array.from(this.valuesByKey.values());return t.some((t=>t.has(e)))}getValuesForKey(e){const t=this.valuesByKey.get(e);return t?Array.from(t):[]}getKeysForValue(e){return Array.from(this.valuesByKey).filter((([t,r])=>r.has(e))).map((([e,t])=>e))}}class IndexedMultimap extends Multimap{constructor(){super();this.keysByValue=new Map}get values(){return Array.from(this.keysByValue.keys())}add(e,t){super.add(e,t);add(this.keysByValue,t,e)}delete(e,t){super.delete(e,t);del(this.keysByValue,t,e)}hasValue(e){return this.keysByValue.has(e)}getKeysForValue(e){const t=this.keysByValue.get(e);return t?Array.from(t):[]}}class SelectorObserver{constructor(e,t,r,s){this._selector=t;this.details=s;this.elementObserver=new ElementObserver(e,this);this.delegate=r;this.matchesByElement=new Multimap}get started(){return this.elementObserver.started}get selector(){return this._selector}set selector(e){this._selector=e;this.refresh()}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get element(){return this.elementObserver.element}matchElement(e){const{selector:t}=this;if(t){const r=e.matches(t);return this.delegate.selectorMatchElement?r&&this.delegate.selectorMatchElement(e,this.details):r}return false}matchElementsInTree(e){const{selector:t}=this;if(t){const r=this.matchElement(e)?[e]:[];const s=Array.from(e.querySelectorAll(t)).filter((e=>this.matchElement(e)));return r.concat(s)}return[]}elementMatched(e){const{selector:t}=this;t&&this.selectorMatched(e,t)}elementUnmatched(e){const t=this.matchesByElement.getKeysForValue(e);for(const r of t)this.selectorUnmatched(e,r)}elementAttributeChanged(e,t){const{selector:r}=this;if(r){const t=this.matchElement(e);const s=this.matchesByElement.has(r,e);t&&!s?this.selectorMatched(e,r):!t&&s&&this.selectorUnmatched(e,r)}}selectorMatched(e,t){this.delegate.selectorMatched(e,t,this.details);this.matchesByElement.add(t,e)}selectorUnmatched(e,t){this.delegate.selectorUnmatched(e,t,this.details);this.matchesByElement.delete(t,e)}}class StringMapObserver{constructor(e,t){this.element=e;this.delegate=t;this.started=false;this.stringMap=new Map;this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){if(!this.started){this.started=true;this.mutationObserver.observe(this.element,{attributes:true,attributeOldValue:true});this.refresh()}}stop(){if(this.started){this.mutationObserver.takeRecords();this.mutationObserver.disconnect();this.started=false}}refresh(){if(this.started)for(const e of this.knownAttributeNames)this.refreshAttribute(e,null)}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){const t=e.attributeName;t&&this.refreshAttribute(t,e.oldValue)}refreshAttribute(e,t){const r=this.delegate.getStringMapKeyForAttribute(e);if(null!=r){this.stringMap.has(e)||this.stringMapKeyAdded(r,e);const s=this.element.getAttribute(e);this.stringMap.get(e)!=s&&this.stringMapValueChanged(s,r,t);if(null==s){const t=this.stringMap.get(e);this.stringMap.delete(e);t&&this.stringMapKeyRemoved(r,e,t)}else this.stringMap.set(e,s)}}stringMapKeyAdded(e,t){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(e,t)}stringMapValueChanged(e,t,r){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(e,t,r)}stringMapKeyRemoved(e,t,r){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(e,t,r)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map((e=>e.name))}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}class TokenListObserver{constructor(e,t,r){this.attributeObserver=new AttributeObserver(e,t,this);this.delegate=r;this.tokensByElement=new Multimap}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}pause(e){this.attributeObserver.pause(e)}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(e){this.tokensMatched(this.readTokensForElement(e))}elementAttributeValueChanged(e){const[t,r]=this.refreshTokensForElement(e);this.tokensUnmatched(t);this.tokensMatched(r)}elementUnmatchedAttribute(e){this.tokensUnmatched(this.tokensByElement.getValuesForKey(e))}tokensMatched(e){e.forEach((e=>this.tokenMatched(e)))}tokensUnmatched(e){e.forEach((e=>this.tokenUnmatched(e)))}tokenMatched(e){this.delegate.tokenMatched(e);this.tokensByElement.add(e.element,e)}tokenUnmatched(e){this.delegate.tokenUnmatched(e);this.tokensByElement.delete(e.element,e)}refreshTokensForElement(e){const t=this.tokensByElement.getValuesForKey(e);const r=this.readTokensForElement(e);const s=zip(t,r).findIndex((([e,t])=>!tokensAreEqual(e,t)));return-1==s?[[],[]]:[t.slice(s),r.slice(s)]}readTokensForElement(e){const t=this.attributeName;const r=e.getAttribute(t)||"";return parseTokenString(r,e,t)}}function parseTokenString(e,t,r){return e.trim().split(/\s+/).filter((e=>e.length)).map(((e,s)=>({element:t,attributeName:r,content:e,index:s})))}function zip(e,t){const r=Math.max(e.length,t.length);return Array.from({length:r},((r,s)=>[e[s],t[s]]))}function tokensAreEqual(e,t){return e&&t&&e.index==t.index&&e.content==t.content}class ValueListObserver{constructor(e,t,r){this.tokenListObserver=new TokenListObserver(e,t,this);this.delegate=r;this.parseResultsByToken=new WeakMap;this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(e){const{element:t}=e;const{value:r}=this.fetchParseResultForToken(e);if(r){this.fetchValuesByTokenForElement(t).set(e,r);this.delegate.elementMatchedValue(t,r)}}tokenUnmatched(e){const{element:t}=e;const{value:r}=this.fetchParseResultForToken(e);if(r){this.fetchValuesByTokenForElement(t).delete(e);this.delegate.elementUnmatchedValue(t,r)}}fetchParseResultForToken(e){let t=this.parseResultsByToken.get(e);if(!t){t=this.parseToken(e);this.parseResultsByToken.set(e,t)}return t}fetchValuesByTokenForElement(e){let t=this.valuesByTokenByElement.get(e);if(!t){t=new Map;this.valuesByTokenByElement.set(e,t)}return t}parseToken(e){try{const t=this.delegate.parseValueForToken(e);return{value:t}}catch(e){return{error:e}}}}class BindingObserver{constructor(e,t){this.context=e;this.delegate=t;this.bindingsByAction=new Map}start(){if(!this.valueListObserver){this.valueListObserver=new ValueListObserver(this.element,this.actionAttribute,this);this.valueListObserver.start()}}stop(){if(this.valueListObserver){this.valueListObserver.stop();delete this.valueListObserver;this.disconnectAllActions()}}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(e){const t=new Binding(this.context,e);this.bindingsByAction.set(e,t);this.delegate.bindingConnected(t)}disconnectAction(e){const t=this.bindingsByAction.get(e);if(t){this.bindingsByAction.delete(e);this.delegate.bindingDisconnected(t)}}disconnectAllActions(){this.bindings.forEach((e=>this.delegate.bindingDisconnected(e,true)));this.bindingsByAction.clear()}parseValueForToken(e){const t=Action.forToken(e,this.schema);if(t.identifier==this.identifier)return t}elementMatchedValue(e,t){this.connectAction(t)}elementUnmatchedValue(e,t){this.disconnectAction(t)}}class ValueObserver{constructor(e,t){this.context=e;this.receiver=t;this.stringMapObserver=new StringMapObserver(this.element,this);this.valueDescriptorMap=this.controller.valueDescriptorMap}start(){this.stringMapObserver.start();this.invokeChangedCallbacksForDefaultValues()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(e){if(e in this.valueDescriptorMap)return this.valueDescriptorMap[e].name}stringMapKeyAdded(e,t){const r=this.valueDescriptorMap[t];this.hasValue(e)||this.invokeChangedCallback(e,r.writer(this.receiver[e]),r.writer(r.defaultValue))}stringMapValueChanged(e,t,r){const s=this.valueDescriptorNameMap[t];if(null!==e){null===r&&(r=s.writer(s.defaultValue));this.invokeChangedCallback(t,e,r)}}stringMapKeyRemoved(e,t,r){const s=this.valueDescriptorNameMap[e];this.hasValue(e)?this.invokeChangedCallback(e,s.writer(this.receiver[e]),r):this.invokeChangedCallback(e,s.writer(s.defaultValue),r)}invokeChangedCallbacksForDefaultValues(){for(const{key:e,name:t,defaultValue:r,writer:s}of this.valueDescriptors)void 0==r||this.controller.data.has(e)||this.invokeChangedCallback(t,s(r),void 0)}invokeChangedCallback(e,t,r){const s=`${e}Changed`;const n=this.receiver[s];if("function"==typeof n){const s=this.valueDescriptorNameMap[e];try{const e=s.reader(t);let i=r;r&&(i=s.reader(r));n.call(this.receiver,e,i)}catch(e){e instanceof TypeError&&(e.message=`Stimulus Value "${this.context.identifier}.${s.name}" - ${e.message}`);throw e}}}get valueDescriptors(){const{valueDescriptorMap:e}=this;return Object.keys(e).map((t=>e[t]))}get valueDescriptorNameMap(){const e={};Object.keys(this.valueDescriptorMap).forEach((t=>{const r=this.valueDescriptorMap[t];e[r.name]=r}));return e}hasValue(e){const t=this.valueDescriptorNameMap[e];const r=`has${capitalize(t.name)}`;return this.receiver[r]}}class TargetObserver{constructor(e,t){this.context=e;this.delegate=t;this.targetsByName=new Multimap}start(){if(!this.tokenListObserver){this.tokenListObserver=new TokenListObserver(this.element,this.attributeName,this);this.tokenListObserver.start()}}stop(){if(this.tokenListObserver){this.disconnectAllTargets();this.tokenListObserver.stop();delete this.tokenListObserver}}tokenMatched({element:e,content:t}){this.scope.containsElement(e)&&this.connectTarget(e,t)}tokenUnmatched({element:e,content:t}){this.disconnectTarget(e,t)}connectTarget(e,t){var r;if(!this.targetsByName.has(t,e)){this.targetsByName.add(t,e);null===(r=this.tokenListObserver)||void 0===r?void 0:r.pause((()=>this.delegate.targetConnected(e,t)))}}disconnectTarget(e,t){var r;if(this.targetsByName.has(t,e)){this.targetsByName.delete(t,e);null===(r=this.tokenListObserver)||void 0===r?void 0:r.pause((()=>this.delegate.targetDisconnected(e,t)))}}disconnectAllTargets(){for(const e of this.targetsByName.keys)for(const t of this.targetsByName.getValuesForKey(e))this.disconnectTarget(t,e)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}function readInheritableStaticArrayValues(e,t){const r=getAncestorsForConstructor(e);return Array.from(r.reduce(((e,r)=>{getOwnStaticArrayValues(r,t).forEach((t=>e.add(t)));return e}),new Set))}function readInheritableStaticObjectPairs(e,t){const r=getAncestorsForConstructor(e);return r.reduce(((e,r)=>{e.push(...getOwnStaticObjectPairs(r,t));return e}),[])}function getAncestorsForConstructor(e){const t=[];while(e){t.push(e);e=Object.getPrototypeOf(e)}return t.reverse()}function getOwnStaticArrayValues(e,t){const r=e[t];return Array.isArray(r)?r:[]}function getOwnStaticObjectPairs(e,t){const r=e[t];return r?Object.keys(r).map((e=>[e,r[e]])):[]}class OutletObserver{constructor(e,t){this.started=false;this.context=e;this.delegate=t;this.outletsByName=new Multimap;this.outletElementsByName=new Multimap;this.selectorObserverMap=new Map;this.attributeObserverMap=new Map}start(){if(!this.started){this.outletDefinitions.forEach((e=>{this.setupSelectorObserverForOutlet(e);this.setupAttributeObserverForOutlet(e)}));this.started=true;this.dependentContexts.forEach((e=>e.refresh()))}}refresh(){this.selectorObserverMap.forEach((e=>e.refresh()));this.attributeObserverMap.forEach((e=>e.refresh()))}stop(){if(this.started){this.started=false;this.disconnectAllOutlets();this.stopSelectorObservers();this.stopAttributeObservers()}}stopSelectorObservers(){if(this.selectorObserverMap.size>0){this.selectorObserverMap.forEach((e=>e.stop()));this.selectorObserverMap.clear()}}stopAttributeObservers(){if(this.attributeObserverMap.size>0){this.attributeObserverMap.forEach((e=>e.stop()));this.attributeObserverMap.clear()}}selectorMatched(e,t,{outletName:r}){const s=this.getOutlet(e,r);s&&this.connectOutlet(s,e,r)}selectorUnmatched(e,t,{outletName:r}){const s=this.getOutletFromMap(e,r);s&&this.disconnectOutlet(s,e,r)}selectorMatchElement(e,{outletName:t}){const r=this.selector(t);const s=this.hasOutlet(e,t);const n=e.matches(`[${this.schema.controllerAttribute}~=${t}]`);return!!r&&(s&&n&&e.matches(r))}elementMatchedAttribute(e,t){const r=this.getOutletNameFromOutletAttributeName(t);r&&this.updateSelectorObserverForOutlet(r)}elementAttributeValueChanged(e,t){const r=this.getOutletNameFromOutletAttributeName(t);r&&this.updateSelectorObserverForOutlet(r)}elementUnmatchedAttribute(e,t){const r=this.getOutletNameFromOutletAttributeName(t);r&&this.updateSelectorObserverForOutlet(r)}connectOutlet(e,t,r){var s;if(!this.outletElementsByName.has(r,t)){this.outletsByName.add(r,e);this.outletElementsByName.add(r,t);null===(s=this.selectorObserverMap.get(r))||void 0===s?void 0:s.pause((()=>this.delegate.outletConnected(e,t,r)))}}disconnectOutlet(e,t,r){var s;if(this.outletElementsByName.has(r,t)){this.outletsByName.delete(r,e);this.outletElementsByName.delete(r,t);null===(s=this.selectorObserverMap.get(r))||void 0===s?void 0:s.pause((()=>this.delegate.outletDisconnected(e,t,r)))}}disconnectAllOutlets(){for(const e of this.outletElementsByName.keys)for(const t of this.outletElementsByName.getValuesForKey(e))for(const r of this.outletsByName.getValuesForKey(e))this.disconnectOutlet(r,t,e)}updateSelectorObserverForOutlet(e){const t=this.selectorObserverMap.get(e);t&&(t.selector=this.selector(e))}setupSelectorObserverForOutlet(e){const t=this.selector(e);const r=new SelectorObserver(document.body,t,this,{outletName:e});this.selectorObserverMap.set(e,r);r.start()}setupAttributeObserverForOutlet(e){const t=this.attributeNameForOutletName(e);const r=new AttributeObserver(this.scope.element,t,this);this.attributeObserverMap.set(e,r);r.start()}selector(e){return this.scope.outlets.getSelectorForOutletName(e)}attributeNameForOutletName(e){return this.scope.schema.outletAttributeForScope(this.identifier,e)}getOutletNameFromOutletAttributeName(e){return this.outletDefinitions.find((t=>this.attributeNameForOutletName(t)===e))}get outletDependencies(){const e=new Multimap;this.router.modules.forEach((t=>{const r=t.definition.controllerConstructor;const s=readInheritableStaticArrayValues(r,"outlets");s.forEach((r=>e.add(r,t.identifier)))}));return e}get outletDefinitions(){return this.outletDependencies.getKeysForValue(this.identifier)}get dependentControllerIdentifiers(){return this.outletDependencies.getValuesForKey(this.identifier)}get dependentContexts(){const e=this.dependentControllerIdentifiers;return this.router.contexts.filter((t=>e.includes(t.identifier)))}hasOutlet(e,t){return!!this.getOutlet(e,t)||!!this.getOutletFromMap(e,t)}getOutlet(e,t){return this.application.getControllerForElementAndIdentifier(e,t)}getOutletFromMap(e,t){return this.outletsByName.getValuesForKey(t).find((t=>t.element===e))}get scope(){return this.context.scope}get schema(){return this.context.schema}get identifier(){return this.context.identifier}get application(){return this.context.application}get router(){return this.application.router}}class Context{constructor(e,t){this.logDebugActivity=(e,t={})=>{const{identifier:r,controller:s,element:n}=this;t=Object.assign({identifier:r,controller:s,element:n},t);this.application.logDebugActivity(this.identifier,e,t)};this.module=e;this.scope=t;this.controller=new e.controllerConstructor(this);this.bindingObserver=new BindingObserver(this,this.dispatcher);this.valueObserver=new ValueObserver(this,this.controller);this.targetObserver=new TargetObserver(this,this);this.outletObserver=new OutletObserver(this,this);try{this.controller.initialize();this.logDebugActivity("initialize")}catch(e){this.handleError(e,"initializing controller")}}connect(){this.bindingObserver.start();this.valueObserver.start();this.targetObserver.start();this.outletObserver.start();try{this.controller.connect();this.logDebugActivity("connect")}catch(e){this.handleError(e,"connecting controller")}}refresh(){this.outletObserver.refresh()}disconnect(){try{this.controller.disconnect();this.logDebugActivity("disconnect")}catch(e){this.handleError(e,"disconnecting controller")}this.outletObserver.stop();this.targetObserver.stop();this.valueObserver.stop();this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(e,t,r={}){const{identifier:s,controller:n,element:i}=this;r=Object.assign({identifier:s,controller:n,element:i},r);this.application.handleError(e,`Error ${t}`,r)}targetConnected(e,t){this.invokeControllerMethod(`${t}TargetConnected`,e)}targetDisconnected(e,t){this.invokeControllerMethod(`${t}TargetDisconnected`,e)}outletConnected(e,t,r){this.invokeControllerMethod(`${namespaceCamelize(r)}OutletConnected`,e,t)}outletDisconnected(e,t,r){this.invokeControllerMethod(`${namespaceCamelize(r)}OutletDisconnected`,e,t)}invokeControllerMethod(e,...t){const r=this.controller;"function"==typeof r[e]&&r[e](...t)}}function bless(e){return shadow(e,getBlessedProperties(e))}function shadow(e,t){const r=i(e);const s=getShadowProperties(e.prototype,t);Object.defineProperties(r.prototype,s);return r}function getBlessedProperties(e){const t=readInheritableStaticArrayValues(e,"blessings");return t.reduce(((t,r)=>{const s=r(e);for(const e in s){const r=t[e]||{};t[e]=Object.assign(r,s[e])}return t}),{})}function getShadowProperties(e,t){return n(t).reduce(((r,s)=>{const n=getShadowedDescriptor(e,t,s);n&&Object.assign(r,{[s]:n});return r}),{})}function getShadowedDescriptor(e,t,r){const s=Object.getOwnPropertyDescriptor(e,r);const n=s&&"value"in s;if(!n){const e=Object.getOwnPropertyDescriptor(t,r).value;if(s){e.get=s.get||e.get;e.set=s.set||e.set}return e}}const n=(()=>"function"==typeof Object.getOwnPropertySymbols?e=>[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)]:Object.getOwnPropertyNames)();const i=(()=>{function extendWithReflect(e){function extended(){return Reflect.construct(e,arguments,new.target)}extended.prototype=Object.create(e.prototype,{constructor:{value:extended}});Reflect.setPrototypeOf(extended,e);return extended}function testReflectExtension(){const a=function(){this.a.call(this)};const e=extendWithReflect(a);e.prototype.a=function(){};return new e}try{testReflectExtension();return extendWithReflect}catch(e){return e=>class extended extends e{}}})();function blessDefinition(e){return{identifier:e.identifier,controllerConstructor:bless(e.controllerConstructor)}}class Module{constructor(e,t){this.application=e;this.definition=blessDefinition(t);this.contextsByScope=new WeakMap;this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(e){const t=this.fetchContextForScope(e);this.connectedContexts.add(t);t.connect()}disconnectContextForScope(e){const t=this.contextsByScope.get(e);if(t){this.connectedContexts.delete(t);t.disconnect()}}fetchContextForScope(e){let t=this.contextsByScope.get(e);if(!t){t=new Context(this,e);this.contextsByScope.set(e,t)}return t}}class ClassMap{constructor(e){this.scope=e}has(e){return this.data.has(this.getDataKey(e))}get(e){return this.getAll(e)[0]}getAll(e){const t=this.data.get(this.getDataKey(e))||"";return tokenize(t)}getAttributeName(e){return this.data.getAttributeNameForKey(this.getDataKey(e))}getDataKey(e){return`${e}-class`}get data(){return this.scope.data}}class DataMap{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(e){const t=this.getAttributeNameForKey(e);return this.element.getAttribute(t)}set(e,t){const r=this.getAttributeNameForKey(e);this.element.setAttribute(r,t);return this.get(e)}has(e){const t=this.getAttributeNameForKey(e);return this.element.hasAttribute(t)}delete(e){if(this.has(e)){const t=this.getAttributeNameForKey(e);this.element.removeAttribute(t);return true}return false}getAttributeNameForKey(e){return`data-${this.identifier}-${dasherize(e)}`}}class Guide{constructor(e){this.warnedKeysByObject=new WeakMap;this.logger=e}warn(e,t,r){let s=this.warnedKeysByObject.get(e);if(!s){s=new Set;this.warnedKeysByObject.set(e,s)}if(!s.has(t)){s.add(t);this.logger.warn(r,e)}}}function attributeValueContainsToken(e,t){return`[${e}~="${t}"]`}class TargetSet{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce(((e,t)=>e||this.findTarget(t)||this.findLegacyTarget(t)),void 0)}findAll(...e){return e.reduce(((e,t)=>[...e,...this.findAllTargets(t),...this.findAllLegacyTargets(t)]),[])}findTarget(e){const t=this.getSelectorForTargetName(e);return this.scope.findElement(t)}findAllTargets(e){const t=this.getSelectorForTargetName(e);return this.scope.findAllElements(t)}getSelectorForTargetName(e){const t=this.schema.targetAttributeForScope(this.identifier);return attributeValueContainsToken(t,e)}findLegacyTarget(e){const t=this.getLegacySelectorForTargetName(e);return this.deprecate(this.scope.findElement(t),e)}findAllLegacyTargets(e){const t=this.getLegacySelectorForTargetName(e);return this.scope.findAllElements(t).map((t=>this.deprecate(t,e)))}getLegacySelectorForTargetName(e){const t=`${this.identifier}.${e}`;return attributeValueContainsToken(this.schema.targetAttribute,t)}deprecate(e,t){if(e){const{identifier:r}=this;const s=this.schema.targetAttribute;const n=this.schema.targetAttributeForScope(r);this.guide.warn(e,`target:${t}`,`Please replace ${s}="${r}.${t}" with ${n}="${t}". The ${s} attribute is deprecated and will be removed in a future version of Stimulus.`)}return e}get guide(){return this.scope.guide}}class OutletSet{constructor(e,t){this.scope=e;this.controllerElement=t}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce(((e,t)=>e||this.findOutlet(t)),void 0)}findAll(...e){return e.reduce(((e,t)=>[...e,...this.findAllOutlets(t)]),[])}getSelectorForOutletName(e){const t=this.schema.outletAttributeForScope(this.identifier,e);return this.controllerElement.getAttribute(t)}findOutlet(e){const t=this.getSelectorForOutletName(e);if(t)return this.findElement(t,e)}findAllOutlets(e){const t=this.getSelectorForOutletName(e);return t?this.findAllElements(t,e):[]}findElement(e,t){const r=this.scope.queryElements(e);return r.filter((r=>this.matchesElement(r,e,t)))[0]}findAllElements(e,t){const r=this.scope.queryElements(e);return r.filter((r=>this.matchesElement(r,e,t)))}matchesElement(e,t,r){const s=e.getAttribute(this.scope.schema.controllerAttribute)||"";return e.matches(t)&&s.split(" ").includes(r)}}class Scope{constructor(e,t,r,s){this.targets=new TargetSet(this);this.classes=new ClassMap(this);this.data=new DataMap(this);this.containsElement=e=>e.closest(this.controllerSelector)===this.element;this.schema=e;this.element=t;this.identifier=r;this.guide=new Guide(s);this.outlets=new OutletSet(this.documentScope,t)}findElement(e){return this.element.matches(e)?this.element:this.queryElements(e).find(this.containsElement)}findAllElements(e){return[...this.element.matches(e)?[this.element]:[],...this.queryElements(e).filter(this.containsElement)]}queryElements(e){return Array.from(this.element.querySelectorAll(e))}get controllerSelector(){return attributeValueContainsToken(this.schema.controllerAttribute,this.identifier)}get isDocumentScope(){return this.element===document.documentElement}get documentScope(){return this.isDocumentScope?this:new Scope(this.schema,document.documentElement,this.identifier,this.guide.logger)}}class ScopeObserver{constructor(e,t,r){this.element=e;this.schema=t;this.delegate=r;this.valueListObserver=new ValueListObserver(this.element,this.controllerAttribute,this);this.scopesByIdentifierByElement=new WeakMap;this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(e){const{element:t,content:r}=e;return this.parseValueForElementAndIdentifier(t,r)}parseValueForElementAndIdentifier(e,t){const r=this.fetchScopesByIdentifierForElement(e);let s=r.get(t);if(!s){s=this.delegate.createScopeForElementAndIdentifier(e,t);r.set(t,s)}return s}elementMatchedValue(e,t){const r=(this.scopeReferenceCounts.get(t)||0)+1;this.scopeReferenceCounts.set(t,r);1==r&&this.delegate.scopeConnected(t)}elementUnmatchedValue(e,t){const r=this.scopeReferenceCounts.get(t);if(r){this.scopeReferenceCounts.set(t,r-1);1==r&&this.delegate.scopeDisconnected(t)}}fetchScopesByIdentifierForElement(e){let t=this.scopesByIdentifierByElement.get(e);if(!t){t=new Map;this.scopesByIdentifierByElement.set(e,t)}return t}}class Router{constructor(e){this.application=e;this.scopeObserver=new ScopeObserver(this.element,this.schema,this);this.scopesByIdentifier=new Multimap;this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce(((e,t)=>e.concat(t.contexts)),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(e){this.unloadIdentifier(e.identifier);const t=new Module(this.application,e);this.connectModule(t);const r=e.controllerConstructor.afterLoad;r&&r.call(e.controllerConstructor,e.identifier,this.application)}unloadIdentifier(e){const t=this.modulesByIdentifier.get(e);t&&this.disconnectModule(t)}getContextForElementAndIdentifier(e,t){const r=this.modulesByIdentifier.get(t);if(r)return r.contexts.find((t=>t.element==e))}proposeToConnectScopeForElementAndIdentifier(e,t){const r=this.scopeObserver.parseValueForElementAndIdentifier(e,t);r?this.scopeObserver.elementMatchedValue(r.element,r):console.error(`Couldn't find or create scope for identifier: "${t}" and element:`,e)}handleError(e,t,r){this.application.handleError(e,t,r)}createScopeForElementAndIdentifier(e,t){return new Scope(this.schema,e,t,this.logger)}scopeConnected(e){this.scopesByIdentifier.add(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.connectContextForScope(e)}scopeDisconnected(e){this.scopesByIdentifier.delete(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.disconnectContextForScope(e)}connectModule(e){this.modulesByIdentifier.set(e.identifier,e);const t=this.scopesByIdentifier.getValuesForKey(e.identifier);t.forEach((t=>e.connectContextForScope(t)))}disconnectModule(e){this.modulesByIdentifier.delete(e.identifier);const t=this.scopesByIdentifier.getValuesForKey(e.identifier);t.forEach((t=>e.disconnectContextForScope(t)))}}const o={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:e=>`data-${e}-target`,outletAttributeForScope:(e,t)=>`data-${e}-${t}-outlet`,keyMappings:Object.assign(Object.assign({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"},objectFromEntries("abcdefghijklmnopqrstuvwxyz".split("").map((e=>[e,e])))),objectFromEntries("0123456789".split("").map((e=>[e,e]))))};function objectFromEntries(e){return e.reduce(((e,[t,r])=>Object.assign(Object.assign({},e),{[t]:r})),{})}class Application{constructor(t=document.documentElement,r=o){this.logger=console;this.debug=false;this.logDebugActivity=(e,t,r={})=>{this.debug&&this.logFormattedMessage(e,t,r)};this.element=t;this.schema=r;this.dispatcher=new Dispatcher(this);this.router=new Router(this);this.actionDescriptorFilters=Object.assign({},e)}static start(e,t){const r=new this(e,t);r.start();return r}async start(){await domReady();this.logDebugActivity("application","starting");this.dispatcher.start();this.router.start();this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping");this.dispatcher.stop();this.router.stop();this.logDebugActivity("application","stop")}register(e,t){this.load({identifier:e,controllerConstructor:t})}registerActionOption(e,t){this.actionDescriptorFilters[e]=t}load(e,...t){const r=Array.isArray(e)?e:[e,...t];r.forEach((e=>{e.controllerConstructor.shouldLoad&&this.router.loadDefinition(e)}))}unload(e,...t){const r=Array.isArray(e)?e:[e,...t];r.forEach((e=>this.router.unloadIdentifier(e)))}get controllers(){return this.router.contexts.map((e=>e.controller))}getControllerForElementAndIdentifier(e,t){const r=this.router.getContextForElementAndIdentifier(e,t);return r?r.controller:null}handleError(e,t,r){var s;this.logger.error("%s\n\n%o\n\n%o",t,e,r);null===(s=window.onerror)||void 0===s?void 0:s.call(window,t,"",0,0,e)}logFormattedMessage(e,t,r={}){r=Object.assign({application:this},r);this.logger.groupCollapsed(`${e} #${t}`);this.logger.log("details:",Object.assign({},r));this.logger.groupEnd()}}function domReady(){return new Promise((e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",(()=>e())):e()}))}function ClassPropertiesBlessing(e){const t=readInheritableStaticArrayValues(e,"classes");return t.reduce(((e,t)=>Object.assign(e,propertiesForClassDefinition(t))),{})}function propertiesForClassDefinition(e){return{[`${e}Class`]:{get(){const{classes:t}=this;if(t.has(e))return t.get(e);{const r=t.getAttributeName(e);throw new Error(`Missing attribute "${r}"`)}}},[`${e}Classes`]:{get(){return this.classes.getAll(e)}},[`has${capitalize(e)}Class`]:{get(){return this.classes.has(e)}}}}function OutletPropertiesBlessing(e){const t=readInheritableStaticArrayValues(e,"outlets");return t.reduce(((e,t)=>Object.assign(e,propertiesForOutletDefinition(t))),{})}function getOutletController(e,t,r){return e.application.getControllerForElementAndIdentifier(t,r)}function getControllerAndEnsureConnectedScope(e,t,r){let s=getOutletController(e,t,r);if(s)return s;e.application.router.proposeToConnectScopeForElementAndIdentifier(t,r);s=getOutletController(e,t,r);return s||void 0}function propertiesForOutletDefinition(e){const t=namespaceCamelize(e);return{[`${t}Outlet`]:{get(){const t=this.outlets.find(e);const r=this.outlets.getSelectorForOutletName(e);if(t){const r=getControllerAndEnsureConnectedScope(this,t,e);if(r)return r;throw new Error(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`)}throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${r}".`)}},[`${t}Outlets`]:{get(){const t=this.outlets.findAll(e);return t.length>0?t.map((t=>{const r=getControllerAndEnsureConnectedScope(this,t,e);if(r)return r;console.warn(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`,t)})).filter((e=>e)):[]}},[`${t}OutletElement`]:{get(){const t=this.outlets.find(e);const r=this.outlets.getSelectorForOutletName(e);if(t)return t;throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${r}".`)}},[`${t}OutletElements`]:{get(){return this.outlets.findAll(e)}},[`has${capitalize(t)}Outlet`]:{get(){return this.outlets.has(e)}}}}function TargetPropertiesBlessing(e){const t=readInheritableStaticArrayValues(e,"targets");return t.reduce(((e,t)=>Object.assign(e,propertiesForTargetDefinition(t))),{})}function propertiesForTargetDefinition(e){return{[`${e}Target`]:{get(){const t=this.targets.find(e);if(t)return t;throw new Error(`Missing target element "${e}" for "${this.identifier}" controller`)}},[`${e}Targets`]:{get(){return this.targets.findAll(e)}},[`has${capitalize(e)}Target`]:{get(){return this.targets.has(e)}}}}function ValuePropertiesBlessing(e){const t=readInheritableStaticObjectPairs(e,"values");const r={valueDescriptorMap:{get(){return t.reduce(((e,t)=>{const r=parseValueDefinitionPair(t,this.identifier);const s=this.data.getAttributeNameForKey(r.key);return Object.assign(e,{[s]:r})}),{})}}};return t.reduce(((e,t)=>Object.assign(e,propertiesForValueDefinitionPair(t))),r)}function propertiesForValueDefinitionPair(e,t){const r=parseValueDefinitionPair(e,t);const{key:s,name:n,reader:i,writer:o}=r;return{[n]:{get(){const e=this.data.get(s);return null!==e?i(e):r.defaultValue},set(e){void 0===e?this.data.delete(s):this.data.set(s,o(e))}},[`has${capitalize(n)}`]:{get(){return this.data.has(s)||r.hasCustomDefaultValue}}}}function parseValueDefinitionPair([e,t],r){return valueDescriptorForTokenAndTypeDefinition({controller:r,token:e,typeDefinition:t})}function parseValueTypeConstant(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function parseValueTypeDefault(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}function parseValueTypeObject(e){const{controller:t,token:r,typeObject:s}=e;const n=isSomething(s.type);const i=isSomething(s.default);const o=n&&i;const c=n&&!i;const l=!n&&i;const h=parseValueTypeConstant(s.type);const u=parseValueTypeDefault(e.typeObject.default);if(c)return h;if(l)return u;if(h!==u){const e=t?`${t}.${r}`:r;throw new Error(`The specified default value for the Stimulus Value "${e}" must match the defined type "${h}". The provided default value of "${s.default}" is of type "${u}".`)}return o?h:void 0}function parseValueTypeDefinition(e){const{controller:t,token:r,typeDefinition:s}=e;const n={controller:t,token:r,typeObject:s};const i=parseValueTypeObject(n);const o=parseValueTypeDefault(s);const c=parseValueTypeConstant(s);const l=i||o||c;if(l)return l;const h=t?`${t}.${s}`:r;throw new Error(`Unknown value type "${h}" for "${r}" value`)}function defaultValueForDefinition(e){const t=parseValueTypeConstant(e);if(t)return c[t];const r=hasProperty(e,"default");const s=hasProperty(e,"type");const n=e;if(r)return n.default;if(s){const{type:e}=n;const t=parseValueTypeConstant(e);if(t)return c[t]}return e}function valueDescriptorForTokenAndTypeDefinition(e){const{token:t,typeDefinition:r}=e;const s=`${dasherize(t)}-value`;const n=parseValueTypeDefinition(e);return{type:n,key:s,name:camelize(s),get defaultValue(){return defaultValueForDefinition(r)},get hasCustomDefaultValue(){return void 0!==parseValueTypeDefault(r)},reader:l[n],writer:h[n]||h.default}}const c={get array(){return[]},boolean:false,number:0,get object(){return{}},string:""};const l={array(e){const t=JSON.parse(e);if(!Array.isArray(t))throw new TypeError(`expected value of type "array" but instead got value "${e}" of type "${parseValueTypeDefault(t)}"`);return t},boolean(e){return!("0"==e||"false"==String(e).toLowerCase())},number(e){return Number(e.replace(/_/g,""))},object(e){const t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError(`expected value of type "object" but instead got value "${e}" of type "${parseValueTypeDefault(t)}"`);return t},string(e){return e}};const h={default:writeString,array:writeJSON,object:writeJSON};function writeJSON(e){return JSON.stringify(e)}function writeString(e){return`${e}`}class Controller{constructor(e){this.context=e}static get shouldLoad(){return true}static afterLoad(e,t){}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:r={},prefix:s=this.identifier,bubbles:n=true,cancelable:i=true}={}){const o=s?`${s}:${e}`:e;const c=new CustomEvent(o,{detail:r,bubbles:n,cancelable:i});t.dispatchEvent(c);return c}}Controller.blessings=[ClassPropertiesBlessing,TargetPropertiesBlessing,ValuePropertiesBlessing,OutletPropertiesBlessing];Controller.targets=[];Controller.outlets=[];Controller.values={};export{Application,AttributeObserver,Context,Controller,ElementObserver,IndexedMultimap,Multimap,SelectorObserver,StringMapObserver,TokenListObserver,ValueListObserver,add,o as defaultSchema,del,fetch,prune};
|
|
4
|
+
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// @hotwired/turbo@8.0.12 downloaded from https://ga.jspm.io/npm:@hotwired/turbo@8.0.12/dist/turbo.es2017-esm.js
|
|
2
|
+
|
|
3
|
+
(function(e){typeof e.requestSubmit!="function"&&(e.requestSubmit=function(e){if(e){validateSubmitter(e,this);e.click()}else{e=document.createElement("input");e.type="submit";e.hidden=true;this.appendChild(e);e.click();this.removeChild(e)}});function validateSubmitter(e,t){e instanceof HTMLElement||raise(TypeError,"parameter 1 is not of type 'HTMLElement'");e.type=="submit"||raise(TypeError,"The specified element is not a submit button");e.form==t||raise(DOMException,"The specified element is not owned by this form element","NotFoundError")}function raise(e,t,r){throw new e("Failed to execute 'requestSubmit' on 'HTMLFormElement': "+t+".",r)}})(HTMLFormElement.prototype);const e=new WeakMap;function findSubmitterFromClickTarget(e){const t=e instanceof Element?e:e instanceof Node?e.parentElement:null;const r=t?t.closest("input, button"):null;return r?.type=="submit"?r:null}function clickCaptured(t){const r=findSubmitterFromClickTarget(t.target);r&&r.form&&e.set(r.form,r)}(function(){if("submitter"in Event.prototype)return;let t=window.Event.prototype;if("SubmitEvent"in window){const e=window.SubmitEvent.prototype;if(!/Apple Computer/.test(navigator.vendor)||"submitter"in e)return;t=e}addEventListener("click",clickCaptured,true);Object.defineProperty(t,"submitter",{get(){if(this.type=="submit"&&this.target instanceof HTMLFormElement)return e.get(this.target)}})})();const t={eager:"eager",lazy:"lazy"};class FrameElement extends HTMLElement{static delegateConstructor=void 0;loaded=Promise.resolve();static get observedAttributes(){return["disabled","loading","src"]}constructor(){super();this.delegate=new FrameElement.delegateConstructor(this)}connectedCallback(){this.delegate.connect()}disconnectedCallback(){this.delegate.disconnect()}reload(){return this.delegate.sourceURLReloaded()}attributeChangedCallback(e){e=="loading"?this.delegate.loadingStyleChanged():e=="src"?this.delegate.sourceURLChanged():e=="disabled"&&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&&this.refresh==="morph"}get loading(){return frameLoadingStyleFromString(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")}}function frameLoadingStyleFromString(e){switch(e.toLowerCase()){case"lazy":return t.lazy;default:return t.eager}}const r={enabled:true,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 activateScriptElement(e){if(e.getAttribute("data-turbo-eval")=="false")return e;{const t=document.createElement("script");const r=getCspNonce();r&&(t.nonce=r);t.textContent=e.textContent;t.async=false;copyElementAttributes(t,e);return t}}function copyElementAttributes(e,t){for(const{name:r,value:s}of t.attributes)e.setAttribute(r,s)}function createDocumentFragment(e){const t=document.createElement("template");t.innerHTML=e;return t.content}function dispatch(e,{target:t,cancelable:r,detail:s}={}){const i=new CustomEvent(e,{cancelable:r,bubbles:true,composed:true,detail:s});t&&t.isConnected?t.dispatchEvent(i):document.documentElement.dispatchEvent(i);return i}function cancelEvent(e){e.preventDefault();e.stopImmediatePropagation()}function nextRepaint(){return document.visibilityState==="hidden"?nextEventLoopTick():nextAnimationFrame()}function nextAnimationFrame(){return new Promise((e=>requestAnimationFrame((()=>e()))))}function nextEventLoopTick(){return new Promise((e=>setTimeout((()=>e()),0)))}function nextMicrotask(){return Promise.resolve()}function parseHTMLDocument(e=""){return(new DOMParser).parseFromString(e,"text/html")}function unindent(e,...t){const r=interpolate(e,t).replace(/^\n/,"").split("\n");const s=r[0].match(/^\s+/);const i=s?s[0].length:0;return r.map((e=>e.slice(i))).join("\n")}function interpolate(e,t){return e.reduce(((e,r,s)=>{const i=t[s]==void 0?"":t[s];return e+r+i}),"")}function uuid(){return Array.from({length:36}).map(((e,t)=>t==8||t==13||t==18||t==23?"-":t==14?"4":t==19?(Math.floor(Math.random()*4)+8).toString(16):Math.floor(Math.random()*15).toString(16))).join("")}function getAttribute(e,...t){for(const r of t.map((t=>t?.getAttribute(e))))if(typeof r=="string")return r;return null}function hasAttribute(e,...t){return t.some((t=>t&&t.hasAttribute(e)))}function markAsBusy(...e){for(const t of e){t.localName=="turbo-frame"&&t.setAttribute("busy","");t.setAttribute("aria-busy","true")}}function clearBusyState(...e){for(const t of e){t.localName=="turbo-frame"&&t.removeAttribute("busy");t.removeAttribute("aria-busy")}}function waitForLoad(e,t=2e3){return new Promise((r=>{const onComplete=()=>{e.removeEventListener("error",onComplete);e.removeEventListener("load",onComplete);r()};e.addEventListener("load",onComplete,{once:true});e.addEventListener("error",onComplete,{once:true});setTimeout(r,t)}))}function getHistoryMethodForAction(e){switch(e){case"replace":return history.replaceState;case"advance":case"restore":return history.pushState}}function isAction(e){return e=="advance"||e=="replace"||e=="restore"}function getVisitAction(...e){const t=getAttribute("data-turbo-action",...e);return isAction(t)?t:null}function getMetaElement(e){return document.querySelector(`meta[name="${e}"]`)}function getMetaContent(e){const t=getMetaElement(e);return t&&t.content}function getCspNonce(){const e=getMetaElement("csp-nonce");if(e){const{nonce:t,content:r}=e;return t==""?r:t}}function setMetaContent(e,t){let r=getMetaElement(e);if(!r){r=document.createElement("meta");r.setAttribute("name",e);document.head.appendChild(r)}r.setAttribute("content",t);return r}function findClosestRecursively(e,t){if(e instanceof Element)return e.closest(t)||findClosestRecursively(e.assignedSlot||e.getRootNode()?.host,t)}function elementIsFocusable(e){const t="[inert], :disabled, [hidden], details:not([open]), dialog:not([open])";return!!e&&e.closest(t)==null&&typeof e.focus=="function"}function queryAutofocusableElement(e){return Array.from(e.querySelectorAll("[autofocus]")).find(elementIsFocusable)}async function around(e,t){const r=t();e();await nextAnimationFrame();const s=t();return[r,s]}function doesNotTargetIFrame(e){if(e==="_blank")return false;if(e){for(const t of document.getElementsByName(e))if(t instanceof HTMLIFrameElement)return false;return true}return true}function findLinkFromClickTarget(e){return findClosestRecursively(e,"a[href]:not([target^=_]):not([download])")}function getLocationForLink(e){return expandURL(e.getAttribute("href")||"")}function debounce(e,t){let r=null;return(...s)=>{const callback=()=>e.apply(this,s);clearTimeout(r);r=setTimeout(callback,t)}}const s={"aria-disabled":{beforeSubmit:e=>{e.setAttribute("aria-disabled","true");e.addEventListener("click",cancelEvent)},afterSubmit:e=>{e.removeAttribute("aria-disabled");e.removeEventListener("click",cancelEvent)}},disabled:{beforeSubmit:e=>e.disabled=true,afterSubmit:e=>e.disabled=false}};class Config{#e=null;constructor(e){Object.assign(this,e)}get submitter(){return this.#e}set submitter(e){this.#e=s[e]||e}}const i=new Config({mode:"on",submitter:"disabled"});const n={drive:r,forms:i};function expandURL(e){return new URL(e.toString(),document.baseURI)}function getAnchor(e){let t;return e.hash?e.hash.slice(1):(t=e.href.match(/#(.*)$/))?t[1]:void 0}function getAction$1(e,t){const r=t?.getAttribute("formaction")||e.getAttribute("action")||e.action;return expandURL(r)}function getExtension(e){return(getLastPathComponent(e).match(/\.[^.]*$/)||[])[0]||""}function isPrefixedBy(e,t){const r=getPrefix(t);return e.href===expandURL(r).href||e.href.startsWith(r)}function locationIsVisitable(e,t){return isPrefixedBy(e,t)&&!n.drive.unvisitableExtensions.has(getExtension(e))}function getRequestURL(e){const t=getAnchor(e);return t!=null?e.href.slice(0,-(t.length+1)):e.href}function toCacheKey(e){return getRequestURL(e)}function urlsAreEqual(e,t){return expandURL(e).href==expandURL(t).href}function getPathComponents(e){return e.pathname.split("/").slice(1)}function getLastPathComponent(e){return getPathComponents(e).slice(-1)[0]}function getPrefix(e){return addTrailingSlash(e.origin+e.pathname)}function addTrailingSlash(e){return e.endsWith("/")?e:e+"/"}class FetchResponse{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 expandURL(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 LimitedSet extends Set{constructor(e){super();this.maxSize=e}add(e){if(this.size>=this.maxSize){const e=this.values();const t=e.next().value;this.delete(t)}super.add(e)}}const o=new LimitedSet(20);const a=window.fetch;function fetchWithTurboHeaders(e,t={}){const r=new Headers(t.headers||{});const s=uuid();o.add(s);r.append("X-Turbo-Request-Id",s);return a(e,{...t,headers:r})}function fetchMethodFromString(e){switch(e.toLowerCase()){case"get":return c.get;case"post":return c.post;case"put":return c.put;case"patch":return c.patch;case"delete":return c.delete}}const c={get:"get",post:"post",put:"put",patch:"patch",delete:"delete"};function fetchEnctypeFromString(e){switch(e.toLowerCase()){case l.multipart:return l.multipart;case l.plain:return l.plain;default:return l.urlEncoded}}const l={urlEncoded:"application/x-www-form-urlencoded",multipart:"multipart/form-data",plain:"text/plain"};class FetchRequest{abortController=new AbortController;#t=e=>{};constructor(e,t,r,s=new URLSearchParams,i=null,n=l.urlEncoded){const[o,a]=buildResourceAndBody(expandURL(r),t,s,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;const r=fetchMethodFromString(e)||c.get;this.url.search="";const[s,i]=buildResourceAndBody(this.url,r,t,this.enctype);this.url=s;this.fetchOptions.body=i;this.fetchOptions.method=r.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.#r(e);try{this.delegate.requestStarted(this);t.detail.fetchRequest?this.response=t.detail.fetchRequest.response:this.response=fetchWithTurboHeaders(this.url.href,e);const r=await this.response;return await this.receive(r)}catch(e){if(e.name!=="AbortError"){this.#s(e)&&this.delegate.requestErrored(this,e);throw e}}finally{this.delegate.requestFinished(this)}}async receive(e){const t=new FetchResponse(e);const r=dispatch("turbo:before-fetch-response",{cancelable:true,detail:{fetchResponse:t},target:this.target});r.defaultPrevented?this.delegate.requestPreventedHandlingResponse(this,t):t.succeeded?this.delegate.requestSucceededWithResponse(this,t):this.delegate.requestFailedWithResponse(this,t);return t}get defaultHeaders(){return{Accept:"text/html, application/xhtml+xml"}}get isSafe(){return isSafe(this.method)}get abortSignal(){return this.abortController.signal}acceptResponseType(e){this.headers.Accept=[e,this.headers.Accept].join(", ")}async#r(e){const t=new Promise((e=>this.#t=e));const r=dispatch("turbo:before-fetch-request",{cancelable:true,detail:{fetchOptions:e,url:this.url,resume:this.#t},target:this.target});this.url=r.detail.url;r.defaultPrevented&&await t;return r}#s(e){const t=dispatch("turbo:fetch-request-error",{target:this.target,cancelable:true,detail:{request:this,error:e}});return!t.defaultPrevented}}function isSafe(e){return fetchMethodFromString(e)==c.get}function buildResourceAndBody(e,t,r,s){const i=Array.from(r).length>0?new URLSearchParams(entriesExcludingFiles(r)):e.searchParams;return isSafe(t)?[mergeIntoURLSearchParams(e,i),null]:s==l.urlEncoded?[e,i]:[e,r]}function entriesExcludingFiles(e){const t=[];for(const[r,s]of e)s instanceof File||t.push([r,s]);return t}function mergeIntoURLSearchParams(e,t){const r=new URLSearchParams(entriesExcludingFiles(t));e.search=r.toString();return e}class AppearanceObserver{started=false;constructor(e,t){this.delegate=e;this.element=t;this.intersectionObserver=new IntersectionObserver(this.intersect)}start(){if(!this.started){this.started=true;this.intersectionObserver.observe(this.element)}}stop(){if(this.started){this.started=false;this.intersectionObserver.unobserve(this.element)}}intersect=e=>{const t=e.slice(-1)[0];t?.isIntersecting&&this.delegate.elementAppearedInViewport(this.element)}}class StreamMessage{static contentType="text/vnd.turbo-stream.html";static wrap(e){return typeof e=="string"?new this(createDocumentFragment(e)):e}constructor(e){this.fragment=importStreamElements(e)}}function importStreamElements(e){for(const t of e.querySelectorAll("turbo-stream")){const e=document.importNode(t,true);for(const t of e.templateElement.content.querySelectorAll("script"))t.replaceWith(activateScriptElement(t));t.replaceWith(e)}return e}const h=100;class PrefetchCache{#i=null;#n=null;get(e){if(this.#n&&this.#n.url===e&&this.#n.expire>Date.now())return this.#n.request}setLater(e,t,r){this.clear();this.#i=setTimeout((()=>{t.perform();this.set(e,t,r);this.#i=null}),h)}set(e,t,r){this.#n={url:e,request:t,expire:new Date((new Date).getTime()+r)}}clear(){this.#i&&clearTimeout(this.#i);this.#n=null}}const d=1e4;const u=new PrefetchCache;const m={initialized:"initialized",requesting:"requesting",waiting:"waiting",receiving:"receiving",stopping:"stopping",stopped:"stopped"};class FormSubmission{state=m.initialized;static confirmMethod(e){return Promise.resolve(confirm(e))}constructor(e,t,r,s=false){const i=getMethod(t,r);const n=getAction(getFormAction(t,r),i);const o=buildFormData(t,r);const a=getEnctype(t,r);this.delegate=e;this.formElement=t;this.submitter=r;this.fetchRequest=new FetchRequest(this,i,n,o,t,a);this.mustRedirect=s}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=expandURL(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}=m;const r=getAttribute("data-turbo-confirm",this.submitter,this.formElement);if(typeof r==="string"){const e=typeof n.forms.confirm==="function"?n.forms.confirm:FormSubmission.confirmMethod;const t=await e(r,this.formElement,this.submitter);if(!t)return}if(this.state==e){this.state=t;return this.fetchRequest.perform()}}stop(){const{stopping:e,stopped:t}=m;if(this.state!=e&&this.state!=t){this.state=e;this.fetchRequest.cancel();return true}}prepareRequest(e){if(!e.isSafe){const t=getCookieValue(getMetaContent("csrf-param"))||getMetaContent("csrf-token");t&&(e.headers["X-CSRF-Token"]=t)}this.requestAcceptsTurboStreamResponse(e)&&e.acceptResponseType(StreamMessage.contentType)}requestStarted(e){this.state=m.waiting;this.submitter&&n.forms.submitter.beforeSubmit(this.submitter);this.setSubmitsWith();markAsBusy(this.formElement);dispatch("turbo:submit-start",{target:this.formElement,detail:{formSubmission:this}});this.delegate.formSubmissionStarted(this)}requestPreventedHandlingResponse(e,t){u.clear();this.result={success:t.succeeded,fetchResponse:t}}requestSucceededWithResponse(e,t){if(t.clientError||t.serverError)this.delegate.formSubmissionFailedWithResponse(this,t);else{u.clear();if(this.requestMustRedirect(e)&&responseSucceededWithoutRedirect(t)){const e=new Error("Form responses must redirect to another location");this.delegate.formSubmissionErrored(this,e)}else{this.state=m.receiving;this.result={success:true,fetchResponse:t};this.delegate.formSubmissionSucceededWithResponse(this,t)}}}requestFailedWithResponse(e,t){this.result={success:false,fetchResponse:t};this.delegate.formSubmissionFailedWithResponse(this,t)}requestErrored(e,t){this.result={success:false,error:t};this.delegate.formSubmissionErrored(this,t)}requestFinished(e){this.state=m.stopped;this.submitter&&n.forms.submitter.afterSubmit(this.submitter);this.resetSubmitterText();clearBusyState(this.formElement);dispatch("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")){const e=this.submitter;e.value=this.originalSubmitText}}requestMustRedirect(e){return!e.isSafe&&this.mustRedirect}requestAcceptsTurboStreamResponse(e){return!e.isSafe||hasAttribute("data-turbo-stream",this.submitter,this.formElement)}get submitsWith(){return this.submitter?.getAttribute("data-turbo-submits-with")}}function buildFormData(e,t){const r=new FormData(e);const s=t?.getAttribute("name");const i=t?.getAttribute("value");s&&r.append(s,i||"");return r}function getCookieValue(e){if(e!=null){const t=document.cookie?document.cookie.split("; "):[];const r=t.find((t=>t.startsWith(e)));if(r){const e=r.split("=").slice(1).join("=");return e?decodeURIComponent(e):void 0}}}function responseSucceededWithoutRedirect(e){return e.statusCode==200&&!e.redirected}function getFormAction(e,t){const r=typeof e.action==="string"?e.action:null;return t?.hasAttribute("formaction")?t.getAttribute("formaction")||"":e.getAttribute("action")||r||""}function getAction(e,t){const r=expandURL(e);isSafe(t)&&(r.search="");return r}function getMethod(e,t){const r=t?.getAttribute("formmethod")||e.getAttribute("method")||"";return fetchMethodFromString(r.toLowerCase())||c.get}function getEnctype(e,t){return fetchEnctypeFromString(t?.getAttribute("formenctype")||e.enctype)}class Snapshot{constructor(e){this.element=e}get activeElement(){return this.element.ownerDocument.activeElement}get children(){return[...this.element.children]}hasAnchor(e){return this.getElementForAnchor(e)!=null}getElementForAnchor(e){return e?this.element.querySelector(`[id='${e}'], a[name='${e}']`):null}get isConnected(){return this.element.isConnected}get firstAutofocusableElement(){return queryAutofocusableElement(this.element)}get permanentElements(){return queryPermanentElementsAll(this.element)}getPermanentElementById(e){return getPermanentElementById(this.element,e)}getPermanentElementMapForSnapshot(e){const t={};for(const r of this.permanentElements){const{id:s}=r;const i=e.getPermanentElementById(s);i&&(t[s]=[r,i])}return t}}function getPermanentElementById(e,t){return e.querySelector(`#${t}[data-turbo-permanent]`)}function queryPermanentElementsAll(e){return e.querySelectorAll("[id][data-turbo-permanent]")}class FormSubmitObserver{started=false;constructor(e,t){this.delegate=e;this.eventTarget=t}start(){if(!this.started){this.eventTarget.addEventListener("submit",this.submitCaptured,true);this.started=true}}stop(){if(this.started){this.eventTarget.removeEventListener("submit",this.submitCaptured,true);this.started=false}}submitCaptured=()=>{this.eventTarget.removeEventListener("submit",this.submitBubbled,false);this.eventTarget.addEventListener("submit",this.submitBubbled,false)};submitBubbled=e=>{if(!e.defaultPrevented){const t=e.target instanceof HTMLFormElement?e.target:void 0;const r=e.submitter||void 0;if(t&&submissionDoesNotDismissDialog(t,r)&&submissionDoesNotTargetIFrame(t,r)&&this.delegate.willSubmitForm(t,r)){e.preventDefault();e.stopImmediatePropagation();this.delegate.formSubmitted(t,r)}}}}function submissionDoesNotDismissDialog(e,t){const r=t?.getAttribute("formmethod")||e.getAttribute("method");return r!="dialog"}function submissionDoesNotTargetIFrame(e,t){const r=t?.getAttribute("formtarget")||e.getAttribute("target");return doesNotTargetIFrame(r)}class View{#o=e=>{};#a=e=>{};constructor(e,t){this.delegate=e;this.element=t}scrollToAnchor(e){const t=this.snapshot.getElementForAnchor(e);if(t){this.scrollToElement(t);this.focusElement(t)}else this.scrollToPosition({x:0,y:0})}scrollToAnchorFromLocation(e){this.scrollToAnchor(getAnchor(e))}scrollToElement(e){e.scrollIntoView()}focusElement(e){if(e instanceof HTMLElement)if(e.hasAttribute("tabindex"))e.focus();else{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:r,willRender:s,newSnapshot:i}=e;const n=s;if(r)try{this.renderPromise=new Promise((e=>this.#o=e));this.renderer=e;await this.prepareToRenderSnapshot(e);const r=new Promise((e=>this.#a=e));const s={resume:this.#a,render:this.renderer.renderElement,renderMethod:this.renderer.renderMethod};const n=this.delegate.allowsImmediateRender(i,s);n||await r;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.#o(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 FrameView extends View{missing(){this.element.innerHTML='<strong class="turbo-frame-error">Content missing</strong>'}get snapshot(){return new Snapshot(this.element)}}class LinkInterceptor{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=>{if(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;const r=findLinkFromClickTarget(t)||t;return r instanceof Element&&r.closest("turbo-frame, html")==this.element}}class LinkClickObserver{started=false;constructor(e,t){this.delegate=e;this.eventTarget=t}start(){if(!this.started){this.eventTarget.addEventListener("click",this.clickCaptured,true);this.started=true}}stop(){if(this.started){this.eventTarget.removeEventListener("click",this.clickCaptured,true);this.started=false}}clickCaptured=()=>{this.eventTarget.removeEventListener("click",this.clickBubbled,false);this.eventTarget.addEventListener("click",this.clickBubbled,false)};clickBubbled=e=>{if(e instanceof MouseEvent&&this.clickEventIsSignificant(e)){const t=e.composedPath&&e.composedPath()[0]||e.target;const r=findLinkFromClickTarget(t);if(r&&doesNotTargetIFrame(r.target)){const t=getLocationForLink(r);if(this.delegate.willFollowLinkToLocation(r,t,e)){e.preventDefault();this.delegate.followedLinkToLocation(r,t)}}}};clickEventIsSignificant(e){return!(e.target&&e.target.isContentEditable||e.defaultPrevented||e.which>1||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey)}}class FormLinkClickObserver{constructor(e,t){this.delegate=e;this.linkInterceptor=new LinkClickObserver(this,t)}start(){this.linkInterceptor.start()}stop(){this.linkInterceptor.stop()}canPrefetchRequestToLocation(e,t){return false}prefetchAndCacheRequestToLocation(e,t){}willFollowLinkToLocation(e,t,r){return this.delegate.willSubmitFormLinkToLocation(e,t,r)&&(e.hasAttribute("data-turbo-method")||e.hasAttribute("data-turbo-stream"))}followedLinkToLocation(e,t){const r=document.createElement("form");const s="hidden";for(const[e,i]of t.searchParams)r.append(Object.assign(document.createElement("input"),{type:s,name:e,value:i}));const i=Object.assign(t,{search:""});r.setAttribute("data-turbo","true");r.setAttribute("action",i.href);r.setAttribute("hidden","");const n=e.getAttribute("data-turbo-method");n&&r.setAttribute("method",n);const o=e.getAttribute("data-turbo-frame");o&&r.setAttribute("data-turbo-frame",o);const a=getVisitAction(e);a&&r.setAttribute("data-turbo-action",a);const c=e.getAttribute("data-turbo-confirm");c&&r.setAttribute("data-turbo-confirm",c);const l=e.hasAttribute("data-turbo-stream");l&&r.setAttribute("data-turbo-stream","");this.delegate.submittedFormLinkToLocation(e,t,r);document.body.appendChild(r);r.addEventListener("turbo:submit-end",(()=>r.remove()),{once:true});requestAnimationFrame((()=>r.requestSubmit()))}}class Bardo{static async preservingPermanentElements(e,t,r){const s=new this(e,t);s.enter();await r();s.leave()}constructor(e,t){this.delegate=e;this.permanentElementMap=t}enter(){for(const e in this.permanentElementMap){const[t,r]=this.permanentElementMap[e];this.delegate.enteringBardo(t,r);this.replaceNewPermanentElementWithPlaceholder(r)}}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=createPlaceholderForPermanentElement(e);e.replaceWith(t)}replaceCurrentPermanentElementWithClone(e){const t=e.cloneNode(true);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]")]}}function createPlaceholderForPermanentElement(e){const t=document.createElement("meta");t.setAttribute("name","turbo-permanent-placeholder");t.setAttribute("content",e.id);return t}class Renderer{#c=null;static renderElement(e,t){}constructor(e,t,r,s=true){this.currentSnapshot=e;this.newSnapshot=t;this.isPreview=r;this.willRender=s;this.renderElement=this.constructor.renderElement;this.promise=new Promise(((e,t)=>this.resolvingFunctions={resolve:e,reject:t}))}get shouldRender(){return true}get shouldAutofocus(){return true}get reloadReason(){}prepareToRender(){}render(){}finishRendering(){if(this.resolvingFunctions){this.resolvingFunctions.resolve();delete this.resolvingFunctions}}async preservingPermanentElements(e){await Bardo.preservingPermanentElements(this,this.permanentElementMap,e)}focusFirstAutofocusableElement(){if(this.shouldAutofocus){const e=this.connectedSnapshot.firstAutofocusableElement;e&&e.focus()}}enteringBardo(e){this.#c||e.contains(this.currentSnapshot.activeElement)&&(this.#c=this.currentSnapshot.activeElement)}leavingBardo(e){if(e.contains(this.#c)&&this.#c instanceof HTMLElement){this.#c.focus();this.#c=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 FrameRenderer extends Renderer{static renderElement(e,t){const r=document.createRange();r.selectNodeContents(e);r.deleteContents();const s=t;const i=s.ownerDocument?.createRange();if(i){i.selectNodeContents(s);e.appendChild(i.extractContents())}}constructor(e,t,r,s,i,n=true){super(t,r,s,i,n);this.delegate=e}get shouldRender(){return true}async render(){await nextRepaint();this.preservingPermanentElements((()=>{this.loadFrameElement()}));this.scrollFrameIntoView();await nextRepaint();this.focusFirstAutofocusableElement();await nextRepaint();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 e=this.currentElement.firstElementChild;const t=readScrollLogicalPosition(this.currentElement.getAttribute("data-autoscroll-block"),"end");const r=readScrollBehavior(this.currentElement.getAttribute("data-autoscroll-behavior"),"auto");if(e){e.scrollIntoView({block:t,behavior:r});return true}}return false}activateScriptElements(){for(const e of this.newScriptElements){const t=activateScriptElement(e);e.replaceWith(t)}}get newScriptElements(){return this.currentElement.querySelectorAll("script")}}function readScrollLogicalPosition(e,t){return e=="end"||e=="start"||e=="center"||e=="nearest"?e:t}function readScrollBehavior(e,t){return e=="auto"||e=="smooth"?e:t}var p=function(){let e=new Set;let t={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:noOp,afterNodeAdded:noOp,beforeNodeMorphed:noOp,afterNodeMorphed:noOp,beforeNodeRemoved:noOp,afterNodeRemoved:noOp,beforeAttributeUpdated:noOp},head:{style:"merge",shouldPreserve:function(e){return e.getAttribute("im-preserve")==="true"},shouldReAppend:function(e){return e.getAttribute("im-re-append")==="true"},shouldRemove:noOp,afterHeadMorphed:noOp}};function morph(e,t,r={}){e instanceof Document&&(e=e.documentElement);typeof t==="string"&&(t=parseContent(t));let s=normalizeContent(t);let i=createMorphContext(e,s,r);return morphNormalizedContent(e,s,i)}function morphNormalizedContent(e,t,r){if(r.head.block){let s=e.querySelector("head");let i=t.querySelector("head");if(s&&i){let n=handleHeadElement(i,s,r);Promise.all(n).then((function(){morphNormalizedContent(e,t,Object.assign(r,{head:{block:false,ignore:true}}))}));return}}if(r.morphStyle==="innerHTML"){morphChildren(t,e,r);return e.children}if(r.morphStyle==="outerHTML"||r.morphStyle==null){let s=findBestNodeMatch(t,e,r);let i=s?.previousSibling;let n=s?.nextSibling;let o=morphOldNodeTo(e,s,r);return s?insertSiblings(i,o,n):[]}throw"Do not understand how to morph style "+r.morphStyle}
|
|
4
|
+
/**
|
|
5
|
+
* @param possibleActiveElement
|
|
6
|
+
* @param ctx
|
|
7
|
+
* @returns {boolean}
|
|
8
|
+
*/function ignoreValueOfActiveElement(e,t){return t.ignoreActiveValue&&e===document.activeElement&&e!==document.body}
|
|
9
|
+
/**
|
|
10
|
+
* @param oldNode root node to merge content into
|
|
11
|
+
* @param newContent new content to merge
|
|
12
|
+
* @param ctx the merge context
|
|
13
|
+
* @returns {Element} the element that ended up in the DOM
|
|
14
|
+
*/function morphOldNodeTo(e,t,r){if(!r.ignoreActive||e!==document.activeElement){if(t==null){if(r.callbacks.beforeNodeRemoved(e)===false)return e;e.remove();r.callbacks.afterNodeRemoved(e);return null}if(isSoftMatch(e,t)){if(r.callbacks.beforeNodeMorphed(e,t)===false)return e;if(e instanceof HTMLHeadElement&&r.head.ignore);else if(e instanceof HTMLHeadElement&&r.head.style!=="morph")handleHeadElement(t,e,r);else{syncNodeFrom(t,e,r);ignoreValueOfActiveElement(e,r)||morphChildren(t,e,r)}r.callbacks.afterNodeMorphed(e,t);return e}if(r.callbacks.beforeNodeRemoved(e)===false)return e;if(r.callbacks.beforeNodeAdded(t)===false)return e;e.parentElement.replaceChild(t,e);r.callbacks.afterNodeAdded(t);r.callbacks.afterNodeRemoved(e);return t}}
|
|
15
|
+
/**
|
|
16
|
+
* This is the core algorithm for matching up children. The idea is to use id sets to try to match up
|
|
17
|
+
* nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but
|
|
18
|
+
* by using id sets, we are able to better match up with content deeper in the DOM.
|
|
19
|
+
*
|
|
20
|
+
* Basic algorithm is, for each node in the new content:
|
|
21
|
+
*
|
|
22
|
+
* - if we have reached the end of the old parent, append the new content
|
|
23
|
+
* - if the new content has an id set match with the current insertion point, morph
|
|
24
|
+
* - search for an id set match
|
|
25
|
+
* - if id set match found, morph
|
|
26
|
+
* - otherwise search for a "soft" match
|
|
27
|
+
* - if a soft match is found, morph
|
|
28
|
+
* - otherwise, prepend the new node before the current insertion point
|
|
29
|
+
*
|
|
30
|
+
* The two search algorithms terminate if competing node matches appear to outweigh what can be achieved
|
|
31
|
+
* with the current node. See findIdSetMatch() and findSoftMatch() for details.
|
|
32
|
+
*
|
|
33
|
+
* @param {Element} newParent the parent element of the new content
|
|
34
|
+
* @param {Element } oldParent the old content that we are merging the new content into
|
|
35
|
+
* @param ctx the merge context
|
|
36
|
+
*/function morphChildren(e,t,r){let s=e.firstChild;let i=t.firstChild;let n;while(s){n=s;s=n.nextSibling;if(i==null){if(r.callbacks.beforeNodeAdded(n)===false)return;t.appendChild(n);r.callbacks.afterNodeAdded(n);removeIdsFromConsideration(r,n);continue}if(isIdSetMatch(n,i,r)){morphOldNodeTo(i,n,r);i=i.nextSibling;removeIdsFromConsideration(r,n);continue}let o=findIdSetMatch(e,t,n,i,r);if(o){i=removeNodesBetween(i,o,r);morphOldNodeTo(o,n,r);removeIdsFromConsideration(r,n);continue}let a=findSoftMatch(e,t,n,i,r);if(a){i=removeNodesBetween(i,a,r);morphOldNodeTo(a,n,r);removeIdsFromConsideration(r,n)}else{if(r.callbacks.beforeNodeAdded(n)===false)return;t.insertBefore(n,i);r.callbacks.afterNodeAdded(n);removeIdsFromConsideration(r,n)}}while(i!==null){let e=i;i=i.nextSibling;removeNode(e,r)}}
|
|
37
|
+
/**
|
|
38
|
+
* @param attr {String} the attribute to be mutated
|
|
39
|
+
* @param to {Element} the element that is going to be updated
|
|
40
|
+
* @param updateType {("update"|"remove")}
|
|
41
|
+
* @param ctx the merge context
|
|
42
|
+
* @returns {boolean} true if the attribute should be ignored, false otherwise
|
|
43
|
+
*/function ignoreAttribute(e,t,r,s){return!(e!=="value"||!s.ignoreActiveValue||t!==document.activeElement)||s.callbacks.beforeAttributeUpdated(e,t,r)===false}
|
|
44
|
+
/**
|
|
45
|
+
* syncs a given node with another node, copying over all attributes and
|
|
46
|
+
* inner element state from the 'from' node to the 'to' node
|
|
47
|
+
*
|
|
48
|
+
* @param {Element} from the element to copy attributes & state from
|
|
49
|
+
* @param {Element} to the element to copy attributes & state to
|
|
50
|
+
* @param ctx the merge context
|
|
51
|
+
*/function syncNodeFrom(e,t,r){let s=e.nodeType;if(s===1){const s=e.attributes;const i=t.attributes;for(const e of s)ignoreAttribute(e.name,t,"update",r)||t.getAttribute(e.name)!==e.value&&t.setAttribute(e.name,e.value);for(let s=i.length-1;0<=s;s--){const n=i[s];ignoreAttribute(n.name,t,"remove",r)||(e.hasAttribute(n.name)||t.removeAttribute(n.name))}}s!==8&&s!==3||t.nodeValue!==e.nodeValue&&(t.nodeValue=e.nodeValue);ignoreValueOfActiveElement(t,r)||syncInputValue(e,t,r)}
|
|
52
|
+
/**
|
|
53
|
+
* @param from {Element} element to sync the value from
|
|
54
|
+
* @param to {Element} element to sync the value to
|
|
55
|
+
* @param attributeName {String} the attribute name
|
|
56
|
+
* @param ctx the merge context
|
|
57
|
+
*/function syncBooleanAttribute(e,t,r,s){if(e[r]!==t[r]){let i=ignoreAttribute(r,t,"update",s);i||(t[r]=e[r]);e[r]?i||t.setAttribute(r,e[r]):ignoreAttribute(r,t,"remove",s)||t.removeAttribute(r)}}
|
|
58
|
+
/**
|
|
59
|
+
* NB: many bothans died to bring us information:
|
|
60
|
+
*
|
|
61
|
+
* https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js
|
|
62
|
+
* https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113
|
|
63
|
+
*
|
|
64
|
+
* @param from {Element} the element to sync the input value from
|
|
65
|
+
* @param to {Element} the element to sync the input value to
|
|
66
|
+
* @param ctx the merge context
|
|
67
|
+
*/function syncInputValue(e,t,r){if(e instanceof HTMLInputElement&&t instanceof HTMLInputElement&&e.type!=="file"){let s=e.value;let i=t.value;syncBooleanAttribute(e,t,"checked",r);syncBooleanAttribute(e,t,"disabled",r);if(e.hasAttribute("value")){if(s!==i&&!ignoreAttribute("value",t,"update",r)){t.setAttribute("value",s);t.value=s}}else if(!ignoreAttribute("value",t,"remove",r)){t.value="";t.removeAttribute("value")}}else if(e instanceof HTMLOptionElement)syncBooleanAttribute(e,t,"selected",r);else if(e instanceof HTMLTextAreaElement&&t instanceof HTMLTextAreaElement){let s=e.value;let i=t.value;if(ignoreAttribute("value",t,"update",r))return;s!==i&&(t.value=s);t.firstChild&&t.firstChild.nodeValue!==s&&(t.firstChild.nodeValue=s)}}function handleHeadElement(e,t,r){let s=[];let i=[];let n=[];let o=[];let a=r.head.style;let c=new Map;for(const t of e.children)c.set(t.outerHTML,t);for(const e of t.children){let t=c.has(e.outerHTML);let s=r.head.shouldReAppend(e);let l=r.head.shouldPreserve(e);if(t||l)if(s)i.push(e);else{c.delete(e.outerHTML);n.push(e)}else if(a==="append"){if(s){i.push(e);o.push(e)}}else r.head.shouldRemove(e)!==false&&i.push(e)}o.push(...c.values());let l=[];for(const e of o){let i=document.createRange().createContextualFragment(e.outerHTML).firstChild;if(r.callbacks.beforeNodeAdded(i)!==false){if(i.href||i.src){let e=null;let t=new Promise((function(t){e=t}));i.addEventListener("load",(function(){e()}));l.push(t)}t.appendChild(i);r.callbacks.afterNodeAdded(i);s.push(i)}}for(const e of i)if(r.callbacks.beforeNodeRemoved(e)!==false){t.removeChild(e);r.callbacks.afterNodeRemoved(e)}r.head.afterHeadMorphed(t,{added:s,kept:n,removed:i});return l}function noOp(){}function mergeDefaults(e){let r={};Object.assign(r,t);Object.assign(r,e);r.callbacks={};Object.assign(r.callbacks,t.callbacks);Object.assign(r.callbacks,e.callbacks);r.head={};Object.assign(r.head,t.head);Object.assign(r.head,e.head);return r}function createMorphContext(e,t,r){r=mergeDefaults(r);return{target:e,newContent:t,config:r,morphStyle:r.morphStyle,ignoreActive:r.ignoreActive,ignoreActiveValue:r.ignoreActiveValue,idMap:createIdMap(e,t),deadIds:new Set,callbacks:r.callbacks,head:r.head}}function isIdSetMatch(e,t,r){return e!=null&&t!=null&&(e.nodeType===t.nodeType&&e.tagName===t.tagName&&(e.id!==""&&e.id===t.id||getIdIntersectionCount(r,e,t)>0))}function isSoftMatch(e,t){return e!=null&&t!=null&&(e.nodeType===t.nodeType&&e.tagName===t.tagName)}function removeNodesBetween(e,t,r){while(e!==t){let t=e;e=e.nextSibling;removeNode(t,r)}removeIdsFromConsideration(r,t);return t.nextSibling}function findIdSetMatch(e,t,r,s,i){let n=getIdIntersectionCount(i,r,t);let o=null;if(n>0){let t=s;let o=0;while(t!=null){if(isIdSetMatch(r,t,i))return t;o+=getIdIntersectionCount(i,t,e);if(o>n)return null;t=t.nextSibling}}return o}function findSoftMatch(e,t,r,s,i){let n=s;let o=r.nextSibling;let a=0;while(n!=null){if(getIdIntersectionCount(i,n,e)>0)return null;if(isSoftMatch(r,n))return n;if(isSoftMatch(o,n)){a++;o=o.nextSibling;if(a>=2)return null}n=n.nextSibling}return n}function parseContent(e){let t=new DOMParser;let r=e.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(r.match(/<\/html>/)||r.match(/<\/head>/)||r.match(/<\/body>/)){let s=t.parseFromString(e,"text/html");if(r.match(/<\/html>/)){s.generatedByIdiomorph=true;return s}{let e=s.firstChild;if(e){e.generatedByIdiomorph=true;return e}return null}}{let r=t.parseFromString("<body><template>"+e+"</template></body>","text/html");let s=r.body.querySelector("template").content;s.generatedByIdiomorph=true;return s}}function normalizeContent(e){if(e==null){const e=document.createElement("div");return e}if(e.generatedByIdiomorph)return e;if(e instanceof Node){const t=document.createElement("div");t.append(e);return t}{const t=document.createElement("div");for(const r of[...e])t.append(r);return t}}function insertSiblings(e,t,r){let s=[];let i=[];while(e!=null){s.push(e);e=e.previousSibling}while(s.length>0){let e=s.pop();i.push(e);t.parentElement.insertBefore(e,t)}i.push(t);while(r!=null){s.push(r);i.push(r);r=r.nextSibling}while(s.length>0)t.parentElement.insertBefore(s.pop(),t.nextSibling);return i}function findBestNodeMatch(e,t,r){let s;s=e.firstChild;let i=s;let n=0;while(s){let e=scoreElement(s,t,r);if(e>n){i=s;n=e}s=s.nextSibling}return i}function scoreElement(e,t,r){return isSoftMatch(e,t)?.5+getIdIntersectionCount(r,e,t):0}function removeNode(e,t){removeIdsFromConsideration(t,e);if(t.callbacks.beforeNodeRemoved(e)!==false){e.remove();t.callbacks.afterNodeRemoved(e)}}function isIdInConsideration(e,t){return!e.deadIds.has(t)}function idIsWithinNode(t,r,s){let i=t.idMap.get(s)||e;return i.has(r)}function removeIdsFromConsideration(t,r){let s=t.idMap.get(r)||e;for(const e of s)t.deadIds.add(e)}function getIdIntersectionCount(t,r,s){let i=t.idMap.get(r)||e;let n=0;for(const e of i)isIdInConsideration(t,e)&&idIsWithinNode(t,e,s)&&++n;return n}
|
|
68
|
+
/**
|
|
69
|
+
* A bottom up algorithm that finds all elements with ids inside of the node
|
|
70
|
+
* argument and populates id sets for those nodes and all their parents, generating
|
|
71
|
+
* a set of ids contained within all nodes for the entire hierarchy in the DOM
|
|
72
|
+
*
|
|
73
|
+
* @param node {Element}
|
|
74
|
+
* @param {Map<Node, Set<String>>} idMap
|
|
75
|
+
*/function populateIdMapForNode(e,t){let r=e.parentElement;let s=e.querySelectorAll("[id]");for(const e of s){let s=e;while(s!==r&&s!=null){let r=t.get(s);if(r==null){r=new Set;t.set(s,r)}r.add(e.id);s=s.parentElement}}}
|
|
76
|
+
/**
|
|
77
|
+
* This function computes a map of nodes to all ids contained within that node (inclusive of the
|
|
78
|
+
* node). This map can be used to ask if two nodes have intersecting sets of ids, which allows
|
|
79
|
+
* for a looser definition of "matching" than tradition id matching, and allows child nodes
|
|
80
|
+
* to contribute to a parent nodes matching.
|
|
81
|
+
*
|
|
82
|
+
* @param {Element} oldContent the old content that will be morphed
|
|
83
|
+
* @param {Element} newContent the new content to morph to
|
|
84
|
+
* @returns {Map<Node, Set<String>>} a map of nodes to id sets for the
|
|
85
|
+
*/function createIdMap(e,t){let r=new Map;populateIdMapForNode(e,r);populateIdMapForNode(t,r);return r}return{morph:morph,defaults:t}}();function morphElements(e,t,{callbacks:r,...s}={}){p.morph(e,t,{...s,callbacks:new DefaultIdiomorphCallbacks(r)})}function morphChildren(e,t){morphElements(e,t.children,{morphStyle:"innerHTML"})}class DefaultIdiomorphCallbacks{#l;constructor({beforeNodeMorphed:e}={}){this.#l=e||(()=>true)}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.#l(e,t)){const r=dispatch("turbo:before-morph-element",{cancelable:true,target:e,detail:{currentElement:e,newElement:t}});return!r.defaultPrevented}return false}};beforeAttributeUpdated=(e,t,r)=>{const s=dispatch("turbo:before-morph-attribute",{cancelable:true,target:t,detail:{attributeName:e,mutationType:r}});return!s.defaultPrevented};beforeNodeRemoved=e=>this.beforeNodeMorphed(e);afterNodeMorphed=(e,t)=>{e instanceof Element&&dispatch("turbo:morph-element",{target:e,detail:{currentElement:e,newElement:t}})}}class MorphingFrameRenderer extends FrameRenderer{static renderElement(e,t){dispatch("turbo:before-frame-morph",{target:e,detail:{currentElement:e,newElement:t}});morphChildren(e,t)}async preservingPermanentElements(e){return await e()}}class ProgressBar{static animationDuration=300;static get defaultCSS(){return unindent`
|
|
86
|
+
.turbo-progress-bar {
|
|
87
|
+
position: fixed;
|
|
88
|
+
display: block;
|
|
89
|
+
top: 0;
|
|
90
|
+
left: 0;
|
|
91
|
+
height: 3px;
|
|
92
|
+
background: #0076ff;
|
|
93
|
+
z-index: 2147483647;
|
|
94
|
+
transition:
|
|
95
|
+
width ${ProgressBar.animationDuration}ms ease-out,
|
|
96
|
+
opacity ${ProgressBar.animationDuration/2}ms ${ProgressBar.animationDuration/2}ms ease-in;
|
|
97
|
+
transform: translate3d(0, 0, 0);
|
|
98
|
+
}
|
|
99
|
+
`}hiding=false;value=0;visible=false;constructor(){this.stylesheetElement=this.createStylesheetElement();this.progressElement=this.createProgressElement();this.installStylesheetElement();this.setValue(0)}show(){if(!this.visible){this.visible=true;this.installProgressElement();this.startTrickling()}}hide(){if(this.visible&&!this.hiding){this.hiding=true;this.fadeProgressElement((()=>{this.uninstallProgressElement();this.stopTrickling();this.visible=false;this.hiding=false}))}}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,ProgressBar.animationDuration*1.5)}uninstallProgressElement(){this.progressElement.parentNode&&document.documentElement.removeChild(this.progressElement)}startTrickling(){this.trickleInterval||(this.trickleInterval=window.setInterval(this.trickle,ProgressBar.animationDuration))}stopTrickling(){window.clearInterval(this.trickleInterval);delete this.trickleInterval}trickle=()=>{this.setValue(this.value+Math.random()/100)};refresh(){requestAnimationFrame((()=>{this.progressElement.style.width=10+this.value*90+"%"}))}createStylesheetElement(){const e=document.createElement("style");e.type="text/css";e.textContent=ProgressBar.defaultCSS;const t=getCspNonce();t&&(e.nonce=t);return e}createProgressElement(){const e=document.createElement("div");e.className="turbo-progress-bar";return e}}class HeadSnapshot extends Snapshot{detailsByOuterHTML=this.children.filter((e=>!elementIsNoscript(e))).map((e=>elementWithoutNonce(e))).reduce(((e,t)=>{const{outerHTML:r}=t;const s=r in e?e[r]:{type:elementType(t),tracked:elementIsTracked(t),elements:[]};return{...e,[r]:{...s,elements:[...s.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:r,tracked:s,elements:i}=this.detailsByOuterHTML[t];return r!=null||s?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,r)=>{const{elements:[s]}=this.detailsByOuterHTML[r];return elementIsMetaElementWithName(s,e)?s:t}),0)}}function elementType(e){return elementIsScript(e)?"script":elementIsStylesheet(e)?"stylesheet":void 0}function elementIsTracked(e){return e.getAttribute("data-turbo-track")=="reload"}function elementIsScript(e){const t=e.localName;return t=="script"}function elementIsNoscript(e){const t=e.localName;return t=="noscript"}function elementIsStylesheet(e){const t=e.localName;return t=="style"||t=="link"&&e.getAttribute("rel")=="stylesheet"}function elementIsMetaElementWithName(e,t){const r=e.localName;return r=="meta"&&e.getAttribute("name")==t}function elementWithoutNonce(e){e.hasAttribute("nonce")&&e.setAttribute("nonce","");return e}class PageSnapshot extends Snapshot{static fromHTMLString(e=""){return this.fromDocument(parseHTMLDocument(e))}static fromElement(e){return this.fromDocument(e.ownerDocument)}static fromDocument({documentElement:e,body:t,head:r}){return new this(e,t,new HeadSnapshot(r))}constructor(e,t,r){super(t);this.documentElement=e;this.headSnapshot=r}clone(){const e=this.element.cloneNode(true);const t=this.element.querySelectorAll("select");const r=e.querySelectorAll("select");for(const[e,s]of t.entries()){const t=r[e];for(const e of t.selectedOptions)e.selected=false;for(const e of s.selectedOptions)t.options[e.index].selected=true}for(const t of e.querySelectorAll('input[type="password"]'))t.value="";return new PageSnapshot(this.documentElement,e,this.headSnapshot)}get lang(){return this.documentElement.getAttribute("lang")}get headElement(){return this.headSnapshot.element}get rootLocation(){const e=this.getSetting("root")??"/";return expandURL(e)}get cacheControlValue(){return this.getSetting("cache-control")}get isPreviewable(){return this.cacheControlValue!="no-preview"}get isCacheable(){return this.cacheControlValue!="no-cache"}get isVisitable(){return this.getSetting("visit-control")!="reload"}get prefersViewTransitions(){return this.headSnapshot.getMetaValue("view-transition")==="same-origin"}get shouldMorphPage(){return this.getSetting("refresh-method")==="morph"}get shouldPreserveScrollPosition(){return this.getSetting("refresh-scroll")==="preserve"}getSetting(e){return this.headSnapshot.getMetaValue(`turbo-${e}`)}}class ViewTransitioner{#h=false;#d=Promise.resolve();renderChange(e,t){if(e&&this.viewTransitionsAvailable&&!this.#h){this.#h=true;this.#d=this.#d.then((async()=>{await document.startViewTransition(t).finished}))}else this.#d=this.#d.then(t);return this.#d}get viewTransitionsAvailable(){return document.startViewTransition}}const f={action:"advance",historyChanged:false,visitCachedSnapshot:()=>{},willRender:true,updateHistory:true,shouldCacheSnapshot:true,acceptsStreamResponse:false};const g={visitStart:"visitStart",requestStart:"requestStart",requestEnd:"requestEnd",visitEnd:"visitEnd"};const b={initialized:"initialized",started:"started",canceled:"canceled",failed:"failed",completed:"completed"};const v={networkFailure:0,timeoutFailure:-1,contentTypeMismatch:-2};const S={advance:"forward",restore:"back",replace:"none"};class Visit{identifier=uuid();timingMetrics={};followedRedirect=false;historyChanged=false;scrolled=false;shouldCacheSnapshot=true;acceptsStreamResponse=false;snapshotCached=false;state=b.initialized;viewTransitioner=new ViewTransitioner;constructor(e,t,r,s={}){this.delegate=e;this.location=t;this.restorationIdentifier=r||uuid();const{action:i,historyChanged:n,referrer:o,snapshot:a,snapshotHTML:c,response:l,visitCachedSnapshot:h,willRender:d,updateHistory:u,shouldCacheSnapshot:m,acceptsStreamResponse:p,direction:g}={...f,...s};this.action=i;this.historyChanged=n;this.referrer=o;this.snapshot=a;this.snapshotHTML=c;this.response=l;this.isSamePage=this.delegate.locationWithActionIsSamePage(this.location,this.action);this.isPageRefresh=this.view.isPageRefresh(this);this.visitCachedSnapshot=h;this.willRender=d;this.updateHistory=u;this.scrolled=!d;this.shouldCacheSnapshot=m;this.acceptsStreamResponse=p;this.direction=g||S[i]}get adapter(){return this.delegate.adapter}get view(){return this.delegate.view}get history(){return this.delegate.history}get restorationData(){return this.history.getRestorationDataForIdentifier(this.restorationIdentifier)}get silent(){return this.isSamePage}start(){if(this.state==b.initialized){this.recordTimingMetric(g.visitStart);this.state=b.started;this.adapter.visitStarted(this);this.delegate.visitStarted(this)}}cancel(){if(this.state==b.started){this.request&&this.request.cancel();this.cancelRender();this.state=b.canceled}}complete(){if(this.state==b.started){this.recordTimingMetric(g.visitEnd);this.adapter.visitCompleted(this);this.state=b.completed;this.followRedirect();this.followedRedirect||this.delegate.visitCompleted(this)}}fail(){if(this.state==b.started){this.state=b.failed;this.adapter.visitFailed(this);this.delegate.visitCompleted(this)}}changeHistory(){if(!this.historyChanged&&this.updateHistory){const e=this.location.href===this.referrer?.href?"replace":this.action;const t=getHistoryMethodForAction(e);this.history.update(t,this.location,this.restorationIdentifier);this.historyChanged=true}}issueRequest(){if(this.hasPreloadedResponse())this.simulateRequest();else if(this.shouldIssueRequest()&&!this.request){this.request=new FetchRequest(this,c.get,this.location);this.request.perform()}}simulateRequest(){if(this.response){this.startRequest();this.recordResponse();this.finishRequest()}}startRequest(){this.recordTimingMetric(g.requestStart);this.adapter.visitRequestStarted(this)}recordResponse(e=this.response){this.response=e;if(e){const{statusCode:t}=e;isSuccessful(t)?this.adapter.visitRequestCompleted(this):this.adapter.visitRequestFailedWithStatusCode(this,t)}}finishRequest(){this.recordTimingMetric(g.requestEnd);this.adapter.visitRequestFinished(this)}loadResponse(){if(this.response){const{statusCode:e,responseHTML:t}=this.response;this.render((async()=>{this.shouldCacheSnapshot&&this.cacheSnapshot();this.view.renderPromise&&await this.view.renderPromise;if(isSuccessful(e)&&t!=null){const e=PageSnapshot.fromHTMLString(t);await this.renderPageSnapshot(e,false);this.adapter.visitRendered(this);this.complete()}else{await this.view.renderError(PageSnapshot.fromHTMLString(t),this);this.adapter.visitRendered(this);this.fail()}}))}}getCachedSnapshot(){const e=this.view.getCachedSnapshotForLocation(this.location)||this.getPreloadedSnapshot();if(e&&(!getAnchor(this.location)||e.hasAnchor(getAnchor(this.location)))&&(this.action=="restore"||e.isPreviewable))return e}getPreloadedSnapshot(){if(this.snapshotHTML)return PageSnapshot.fromHTMLString(this.snapshotHTML)}hasCachedSnapshot(){return this.getCachedSnapshot()!=null}loadCachedSnapshot(){const e=this.getCachedSnapshot();if(e){const t=this.shouldIssueRequest();this.render((async()=>{this.cacheSnapshot();if(this.isSamePage||this.isPageRefresh)this.adapter.visitRendered(this);else{this.view.renderPromise&&await this.view.renderPromise;await this.renderPageSnapshot(e,t);this.adapter.visitRendered(this);t||this.complete()}}))}}followRedirect(){if(this.redirectedToLocation&&!this.followedRedirect&&this.response?.redirected){this.adapter.visitProposedToLocation(this.redirectedToLocation,{action:"replace",response:this.response,shouldCacheSnapshot:false,willRender:false});this.followedRedirect=true}}goToSamePageAnchor(){this.isSamePage&&this.render((async()=>{this.cacheSnapshot();this.performScroll();this.changeHistory();this.adapter.visitRendered(this)}))}prepareRequest(e){this.acceptsStreamResponse&&e.acceptResponseType(StreamMessage.contentType)}requestStarted(){this.startRequest()}requestPreventedHandlingResponse(e,t){}async requestSucceededWithResponse(e,t){const r=await t.responseHTML;const{redirected:s,statusCode:i}=t;if(r==void 0)this.recordResponse({statusCode:v.contentTypeMismatch,redirected:s});else{this.redirectedToLocation=t.redirected?t.location:void 0;this.recordResponse({statusCode:i,responseHTML:r,redirected:s})}}async requestFailedWithResponse(e,t){const r=await t.responseHTML;const{redirected:s,statusCode:i}=t;r==void 0?this.recordResponse({statusCode:v.contentTypeMismatch,redirected:s}):this.recordResponse({statusCode:i,responseHTML:r,redirected:s})}requestErrored(e,t){this.recordResponse({statusCode:v.networkFailure,redirected:false})}requestFinished(){this.finishRequest()}performScroll(){if(!this.scrolled&&!this.view.forceReloaded&&!this.view.shouldPreserveScrollPosition(this)){this.action=="restore"?this.scrollToRestoredPosition()||this.scrollToAnchor()||this.view.scrollToTop():this.scrollToAnchor()||this.view.scrollToTop();this.isSamePage&&this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation,this.location);this.scrolled=true}}scrollToRestoredPosition(){const{scrollPosition:e}=this.restorationData;if(e){this.view.scrollToPosition(e);return true}}scrollToAnchor(){const e=getAnchor(this.location);if(e!=null){this.view.scrollToAnchor(e);return true}}recordTimingMetric(e){this.timingMetrics[e]=(new Date).getTime()}getTimingMetrics(){return{...this.timingMetrics}}getHistoryMethodForAction(e){switch(e){case"replace":return history.replaceState;case"advance":case"restore":return history.pushState}}hasPreloadedResponse(){return typeof this.response=="object"}shouldIssueRequest(){return!this.isSamePage&&(this.action=="restore"?!this.hasCachedSnapshot():this.willRender)}cacheSnapshot(){if(!this.snapshotCached){this.view.cacheSnapshot(this.snapshot).then((e=>e&&this.visitCachedSnapshot(e)));this.snapshotCached=true}}async render(e){this.cancelRender();await new Promise((e=>{this.frame=document.visibilityState==="hidden"?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(){if(this.frame){cancelAnimationFrame(this.frame);delete this.frame}}}function isSuccessful(e){return e>=200&&e<300}class BrowserAdapter{progressBar=new ProgressBar;constructor(e){this.session=e}visitProposedToLocation(e,t){locationIsVisitable(e,this.navigator.rootLocation)?this.navigator.startVisit(e,t?.restorationIdentifier||uuid(),t):window.location.href=e.toString()}visitStarted(e){this.location=e.location;e.loadCachedSnapshot();e.issueRequest();e.goToSamePageAnchor()}visitRequestStarted(e){this.progressBar.setValue(0);e.hasCachedSnapshot()||e.action!="restore"?this.showVisitProgressBarAfterDelay():this.showProgressBar()}visitRequestCompleted(e){e.loadResponse()}visitRequestFailedWithStatusCode(e,t){switch(t){case v.networkFailure:case v.timeoutFailure:case v.contentTypeMismatch: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){}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();if(this.visitProgressBarTimeout!=null){window.clearTimeout(this.visitProgressBarTimeout);delete this.visitProgressBarTimeout}}showFormProgressBarAfterDelay(){this.formProgressBarTimeout==null&&(this.formProgressBarTimeout=window.setTimeout(this.showProgressBar,this.session.progressBarDelay))}hideFormProgressBar(){this.progressBar.hide();if(this.formProgressBarTimeout!=null){window.clearTimeout(this.formProgressBarTimeout);delete this.formProgressBarTimeout}}showProgressBar=()=>{this.progressBar.show()};reload(e){dispatch("turbo:reload",{detail:e});window.location.href=this.location?.toString()||window.location.href}get navigator(){return this.session.navigator}}class CacheObserver{selector="[data-turbo-temporary]";deprecatedSelector="[data-turbo-cache=false]";started=false;start(){if(!this.started){this.started=true;addEventListener("turbo:before-cache",this.removeTemporaryElements,false)}}stop(){if(this.started){this.started=false;removeEventListener("turbo:before-cache",this.removeTemporaryElements,false)}}removeTemporaryElements=e=>{for(const e of this.temporaryElements)e.remove()};get temporaryElements(){return[...document.querySelectorAll(this.selector),...this.temporaryElementsWithDeprecation]}get temporaryElementsWithDeprecation(){const e=document.querySelectorAll(this.deprecatedSelector);e.length&&console.warn(`The ${this.deprecatedSelector} selector is deprecated and will be removed in a future version. Use ${this.selector} instead.`);return[...e]}}class FrameRedirector{constructor(e,t){this.session=e;this.element=t;this.linkInterceptor=new LinkInterceptor(this,t);this.formSubmitObserver=new FormSubmitObserver(this,t)}start(){this.linkInterceptor.start();this.formSubmitObserver.start()}stop(){this.linkInterceptor.stop();this.formSubmitObserver.stop()}shouldInterceptLinkClick(e,t,r){return this.#u(e)}linkClickIntercepted(e,t,r){const s=this.#m(e);s&&s.delegate.linkClickIntercepted(e,t,r)}willSubmitForm(e,t){return e.closest("turbo-frame")==null&&this.#p(e,t)&&this.#u(e,t)}formSubmitted(e,t){const r=this.#m(e,t);r&&r.delegate.formSubmitted(e,t)}#p(e,t){const r=getAction$1(e,t);const s=this.element.ownerDocument.querySelector('meta[name="turbo-root"]');const i=expandURL(s?.content??"/");return this.#u(e,t)&&locationIsVisitable(r,i)}#u(e,t){const r=e instanceof HTMLFormElement?this.session.submissionIsNavigatable(e,t):this.session.elementIsNavigatable(e);if(r){const r=this.#m(e,t);return!!r&&r!=e.closest("turbo-frame")}return false}#m(e,t){const r=t?.getAttribute("data-turbo-frame")||e.getAttribute("data-turbo-frame");if(r&&r!="_top"){const e=this.element.querySelector(`#${r}:not([disabled])`);if(e instanceof FrameElement)return e}}}class History{location;restorationIdentifier=uuid();restorationData={};started=false;pageLoaded=false;currentIndex=0;constructor(e){this.delegate=e}start(){if(!this.started){addEventListener("popstate",this.onPopState,false);addEventListener("load",this.onPageLoad,false);this.currentIndex=history.state?.turbo?.restorationIndex||0;this.started=true;this.replace(new URL(window.location.href))}}stop(){if(this.started){removeEventListener("popstate",this.onPopState,false);removeEventListener("load",this.onPageLoad,false);this.started=false}}push(e,t){this.update(history.pushState,e,t)}replace(e,t){this.update(history.replaceState,e,t)}update(e,t,r=uuid()){e===history.pushState&&++this.currentIndex;const s={turbo:{restorationIdentifier:r,restorationIndex:this.currentIndex}};e.call(history,s,"",t.href);this.location=t;this.restorationIdentifier=r}getRestorationDataForIdentifier(e){return this.restorationData[e]||{}}updateRestorationData(e){const{restorationIdentifier:t}=this;const r=this.restorationData[t];this.restorationData[t]={...r,...e}}assumeControlOfScrollRestoration(){if(!this.previousScrollRestoration){this.previousScrollRestoration=history.scrollRestoration??"auto";history.scrollRestoration="manual"}}relinquishControlOfScrollRestoration(){if(this.previousScrollRestoration){history.scrollRestoration=this.previousScrollRestoration;delete this.previousScrollRestoration}}onPopState=e=>{if(this.shouldHandlePopState()){const{turbo:t}=e.state||{};if(t){this.location=new URL(window.location.href);const{restorationIdentifier:e,restorationIndex:r}=t;this.restorationIdentifier=e;const s=r>this.currentIndex?"forward":"back";this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location,e,s);this.currentIndex=r}}};onPageLoad=async e=>{await nextMicrotask();this.pageLoaded=true};shouldHandlePopState(){return this.pageIsLoaded()}pageIsLoaded(){return this.pageLoaded||document.readyState=="complete"}}class LinkPrefetchObserver{started=false;#f=null;constructor(e,t){this.delegate=e;this.eventTarget=t}start(){this.started||(this.eventTarget.readyState==="loading"?this.eventTarget.addEventListener("DOMContentLoaded",this.#g,{once:true}):this.#g())}stop(){if(this.started){this.eventTarget.removeEventListener("mouseenter",this.#b,{capture:true,passive:true});this.eventTarget.removeEventListener("mouseleave",this.#v,{capture:true,passive:true});this.eventTarget.removeEventListener("turbo:before-fetch-request",this.#S,true);this.started=false}}#g=()=>{this.eventTarget.addEventListener("mouseenter",this.#b,{capture:true,passive:true});this.eventTarget.addEventListener("mouseleave",this.#v,{capture:true,passive:true});this.eventTarget.addEventListener("turbo:before-fetch-request",this.#S,true);this.started=true};#b=e=>{if(getMetaContent("turbo-prefetch")==="false")return;const t=e.target;const r=t.matches&&t.matches("a[href]:not([target^=_]):not([download])");if(r&&this.#w(t)){const e=t;const r=getLocationForLink(e);if(this.delegate.canPrefetchRequestToLocation(e,r)){this.#f=e;const s=new FetchRequest(this,c.get,r,new URLSearchParams,t);u.setLater(r.toString(),s,this.#E)}}};#v=e=>{e.target===this.#f&&this.#y()};#y=()=>{u.clear();this.#f=null};#S=e=>{if(e.target.tagName!=="FORM"&&e.detail.fetchOptions.method==="GET"){const t=u.get(e.detail.url.toString());t&&(e.detail.fetchRequest=t);u.clear()}};prepareRequest(e){const t=e.target;e.headers["X-Sec-Purpose"]="prefetch";const r=t.closest("turbo-frame");const s=t.getAttribute("data-turbo-frame")||r?.getAttribute("target")||r?.id;s&&s!=="_top"&&(e.headers["Turbo-Frame"]=s)}requestSucceededWithResponse(){}requestStarted(e){}requestErrored(e){}requestFinished(e){}requestPreventedHandlingResponse(e,t){}requestFailedWithResponse(e,t){}get#E(){return Number(getMetaContent("turbo-prefetch-cache-time"))||d}#w(e){const t=e.getAttribute("href");return!!t&&(!unfetchableLink(e)&&(!linkToTheSamePage(e)&&(!linkOptsOut(e)&&(!nonSafeLink(e)&&!eventPrevented(e)))))}}const unfetchableLink=e=>e.origin!==document.location.origin||!["http:","https:"].includes(e.protocol)||e.hasAttribute("target");const linkToTheSamePage=e=>e.pathname+e.search===document.location.pathname+document.location.search||e.href.startsWith("#");const linkOptsOut=e=>{if(e.getAttribute("data-turbo-prefetch")==="false")return true;if(e.getAttribute("data-turbo")==="false")return true;const t=findClosestRecursively(e,"[data-turbo-prefetch]");return!(!t||t.getAttribute("data-turbo-prefetch")!=="false")};const nonSafeLink=e=>{const t=e.getAttribute("data-turbo-method");return!(!t||t.toLowerCase()==="get")||(!!isUJS(e)||(!!e.hasAttribute("data-turbo-confirm")||!!e.hasAttribute("data-turbo-stream")))};const isUJS=e=>e.hasAttribute("data-remote")||e.hasAttribute("data-behavior")||e.hasAttribute("data-confirm")||e.hasAttribute("data-method");const eventPrevented=e=>{const t=dispatch("turbo:before-prefetch",{target:e,cancelable:true});return t.defaultPrevented};class Navigator{constructor(e){this.delegate=e}proposeVisit(e,t={}){this.delegate.allowsVisitingLocationWithAction(e,t.action)&&this.delegate.visitProposedToLocation(e,t)}startVisit(e,t,r={}){this.stop();this.currentVisit=new Visit(this,expandURL(e),t,{referrer:this.location,...r});this.currentVisit.start()}submitForm(e,t){this.stop();this.formSubmission=new FormSubmission(this,e,t,true);this.formSubmission.start()}stop(){if(this.formSubmission){this.formSubmission.stop();delete this.formSubmission}if(this.currentVisit){this.currentVisit.cancel();delete this.currentVisit}}get adapter(){return this.delegate.adapter}get view(){return this.delegate.view}get rootLocation(){return this.view.snapshot.rootLocation}get history(){return this.delegate.history}formSubmissionStarted(e){typeof this.adapter.formSubmissionStarted==="function"&&this.adapter.formSubmissionStarted(e)}async formSubmissionSucceededWithResponse(e,t){if(e==this.formSubmission){const r=await t.responseHTML;if(r){const s=e.isSafe;s||this.view.clearSnapshotCache();const{statusCode:i,redirected:n}=t;const o=this.#R(e,t);const a={action:o,shouldCacheSnapshot:s,response:{statusCode:i,responseHTML:r,redirected:n}};this.proposeVisit(t.location,a)}}}async formSubmissionFailedWithResponse(e,t){const r=await t.responseHTML;if(r){const e=PageSnapshot.fromHTMLString(r);t.serverError?await this.view.renderError(e,this.currentVisit):await this.view.renderPage(e,false,true,this.currentVisit);e.shouldPreserveScrollPosition||this.view.scrollToTop();this.view.clearSnapshotCache()}}formSubmissionErrored(e,t){console.error(t)}formSubmissionFinished(e){typeof this.adapter.formSubmissionFinished==="function"&&this.adapter.formSubmissionFinished(e)}visitStarted(e){this.delegate.visitStarted(e)}visitCompleted(e){this.delegate.visitCompleted(e);delete this.currentVisit}locationWithActionIsSamePage(e,t){const r=getAnchor(e);const s=getAnchor(this.view.lastRenderedLocation);const i=t==="restore"&&typeof r==="undefined";return t!=="replace"&&getRequestURL(e)===getRequestURL(this.view.lastRenderedLocation)&&(i||r!=null&&r!==s)}visitScrolledToSamePageLocation(e,t){this.delegate.visitScrolledToSamePageLocation(e,t)}get location(){return this.history.location}get restorationIdentifier(){return this.history.restorationIdentifier}#R(e,t){const{submitter:r,formElement:s}=e;return getVisitAction(r,s)||this.#A(t)}#A(e){const t=e.redirected&&e.location.href===this.location?.href;return t?"replace":"advance"}}const w={initial:0,loading:1,interactive:2,complete:3};class PageObserver{stage=w.initial;started=false;constructor(e){this.delegate=e}start(){if(!this.started){this.stage==w.initial&&(this.stage=w.loading);document.addEventListener("readystatechange",this.interpretReadyState,false);addEventListener("pagehide",this.pageWillUnload,false);this.started=true}}stop(){if(this.started){document.removeEventListener("readystatechange",this.interpretReadyState,false);removeEventListener("pagehide",this.pageWillUnload,false);this.started=false}}interpretReadyState=()=>{const{readyState:e}=this;e=="interactive"?this.pageIsInteractive():e=="complete"&&this.pageIsComplete()};pageIsInteractive(){if(this.stage==w.loading){this.stage=w.interactive;this.delegate.pageBecameInteractive()}}pageIsComplete(){this.pageIsInteractive();if(this.stage==w.interactive){this.stage=w.complete;this.delegate.pageLoaded()}}pageWillUnload=()=>{this.delegate.pageWillUnload()};get readyState(){return document.readyState}}class ScrollObserver{started=false;constructor(e){this.delegate=e}start(){if(!this.started){addEventListener("scroll",this.onScroll,false);this.onScroll();this.started=true}}stop(){if(this.started){removeEventListener("scroll",this.onScroll,false);this.started=false}}onScroll=()=>{this.updatePosition({x:window.pageXOffset,y:window.pageYOffset})};updatePosition(e){this.delegate.scrollPositionChanged(e)}}class StreamMessageRenderer{render({fragment:e}){Bardo.preservingPermanentElements(this,getPermanentElementMapForFragment(e),(()=>{withAutofocusFromFragment(e,(()=>{withPreservedFocus((()=>{document.documentElement.appendChild(e)}))}))}))}enteringBardo(e,t){t.replaceWith(e.cloneNode(true))}leavingBardo(){}}function getPermanentElementMapForFragment(e){const t=queryPermanentElementsAll(document.documentElement);const r={};for(const s of t){const{id:t}=s;for(const i of e.querySelectorAll("turbo-stream")){const e=getPermanentElementById(i.templateElement.content,t);e&&(r[t]=[s,e])}}return r}async function withAutofocusFromFragment(e,t){const r=`turbo-stream-autofocus-${uuid()}`;const s=e.querySelectorAll("turbo-stream");const i=firstAutofocusableElementInStreams(s);let n=null;if(i){n=i.id?i.id:r;i.id=n}t();await nextRepaint();const o=document.activeElement==null||document.activeElement==document.body;if(o&&n){const e=document.getElementById(n);elementIsFocusable(e)&&e.focus();e&&e.id==r&&e.removeAttribute("id")}}async function withPreservedFocus(e){const[t,r]=await around(e,(()=>document.activeElement));const s=t&&t.id;if(s){const e=document.getElementById(s);elementIsFocusable(e)&&e!=r&&e.focus()}}function firstAutofocusableElementInStreams(e){for(const t of e){const e=queryAutofocusableElement(t.templateElement.content);if(e)return e}return null}class StreamObserver{sources=new Set;#L=false;constructor(e){this.delegate=e}start(){if(!this.#L){this.#L=true;addEventListener("turbo:before-fetch-response",this.inspectFetchResponse,false)}}stop(){if(this.#L){this.#L=false;removeEventListener("turbo:before-fetch-response",this.inspectFetchResponse,false)}}connectStreamSource(e){if(!this.streamSourceIsConnected(e)){this.sources.add(e);e.addEventListener("message",this.receiveMessageEvent,false)}}disconnectStreamSource(e){if(this.streamSourceIsConnected(e)){this.sources.delete(e);e.removeEventListener("message",this.receiveMessageEvent,false)}}streamSourceIsConnected(e){return this.sources.has(e)}inspectFetchResponse=e=>{const t=fetchResponseFromEvent(e);if(t&&fetchResponseIsStream(t)){e.preventDefault();this.receiveMessageResponse(t)}};receiveMessageEvent=e=>{this.#L&&typeof e.data=="string"&&this.receiveMessageHTML(e.data)};async receiveMessageResponse(e){const t=await e.responseHTML;t&&this.receiveMessageHTML(t)}receiveMessageHTML(e){this.delegate.receivedMessageFromStream(StreamMessage.wrap(e))}}function fetchResponseFromEvent(e){const t=e.detail?.fetchResponse;if(t instanceof FetchResponse)return t}function fetchResponseIsStream(e){const t=e.contentType??"";return t.startsWith(StreamMessage.contentType)}class ErrorRenderer extends Renderer{static renderElement(e,t){const{documentElement:r,body:s}=document;r.replaceChild(t,s)}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 r=activateScriptElement(e);t.replaceChild(r,e)}}}get newHead(){return this.newSnapshot.headSnapshot.element}get scriptElements(){return document.documentElement.querySelectorAll("script")}}class PageRenderer extends Renderer{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;const{lang:t}=this.newSnapshot;t?e.setAttribute("lang",t):e.removeAttribute("lang")}async mergeHead(){const e=this.mergeProvisionalElements();const 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(waitForLoad(t));document.head.appendChild(t)}await Promise.all(e)}copyNewHeadScriptElements(){for(const e of this.newHeadScriptElements)document.head.appendChild(activateScriptElement(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[r,s]of t.entries()){if(e.tagName=="TITLE"){if(s.tagName!="TITLE")continue;if(e.innerHTML==s.innerHTML){t.splice(r,1);return true}}if(s.isEqualNode(e)){t.splice(r,1);return true}}return false}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.activateNewBodyScriptElements()}activateNewBodyScriptElements(){for(const e of this.newBodyScriptElements){const t=activateScriptElement(e);e.replaceWith(t)}}async assignNewBody(){await this.renderElement(this.currentElement,this.newElement)}get unusedDynamicStylesheetElements(){return this.oldHeadStylesheetElements.filter((e=>e.getAttribute("data-turbo-track")==="dynamic"))}get oldHeadStylesheetElements(){return this.currentHeadSnapshot.getStylesheetElementsNotInSnapshot(this.newHeadSnapshot)}get newHeadStylesheetElements(){return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot)}get newHeadScriptElements(){return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot)}get currentHeadProvisionalElements(){return this.currentHeadSnapshot.provisionalElements}get newHeadProvisionalElements(){return this.newHeadSnapshot.provisionalElements}get newBodyScriptElements(){return this.newElement.querySelectorAll("script")}}class MorphingPageRenderer extends PageRenderer{static renderElement(e,t){morphElements(e,t,{callbacks:{beforeNodeMorphed:e=>!canRefreshFrame(e)}});for(const t of e.querySelectorAll("turbo-frame"))canRefreshFrame(t)&&t.reload();dispatch("turbo:morph",{detail:{currentElement:e,newElement:t}})}async preservingPermanentElements(e){return await e()}get renderMethod(){return"morph"}get shouldAutofocus(){return false}}function canRefreshFrame(e){return e instanceof FrameElement&&e.src&&e.refresh==="morph"&&!e.closest("[data-turbo-permanent]")}class SnapshotCache{keys=[];snapshots={};constructor(e){this.size=e}has(e){return toCacheKey(e)in this.snapshots}get(e){if(this.has(e)){const t=this.read(e);this.touch(e);return t}}put(e,t){this.write(e,t);this.touch(e);return t}clear(){this.snapshots={}}read(e){return this.snapshots[toCacheKey(e)]}write(e,t){this.snapshots[toCacheKey(e)]=t}touch(e){const t=toCacheKey(e);const r=this.keys.indexOf(t);r>-1&&this.keys.splice(r,1);this.keys.unshift(t);this.trim()}trim(){for(const e of this.keys.splice(this.size))delete this.snapshots[e]}}class PageView extends View{snapshotCache=new SnapshotCache(10);lastRenderedLocation=new URL(location.href);forceReloaded=false;shouldTransitionTo(e){return this.snapshot.prefersViewTransitions&&e.prefersViewTransitions}renderPage(e,t=false,r=true,s){const i=this.isPageRefresh(s)&&this.snapshot.shouldMorphPage;const n=i?MorphingPageRenderer:PageRenderer;const o=new n(this.snapshot,e,t,r);o.shouldRender?s?.changeHistory():this.forceReloaded=true;return this.render(o)}renderError(e,t){t?.changeHistory();const r=new ErrorRenderer(this.snapshot,e,false);return this.render(r)}clearSnapshotCache(){this.snapshotCache.clear()}async cacheSnapshot(e=this.snapshot){if(e.isCacheable){this.delegate.viewWillCacheSnapshot();const{lastRenderedLocation:t}=this;await nextEventLoopTick();const r=e.clone();this.snapshotCache.put(t,r);return r}}getCachedSnapshotForLocation(e){return this.snapshotCache.get(e)}isPageRefresh(e){return!e||this.lastRenderedLocation.pathname===e.location.pathname&&e.action==="replace"}shouldPreserveScrollPosition(e){return this.isPageRefresh(e)&&this.snapshot.shouldPreserveScrollPosition}get snapshot(){return PageSnapshot.fromElement(this.element)}}class Preloader{selector="a[data-turbo-preload]";constructor(e,t){this.delegate=e;this.snapshotCache=t}start(){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",this.#T):this.preloadOnLoadLinksForView(document.body)}stop(){document.removeEventListener("DOMContentLoaded",this.#T)}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 r=new FetchRequest(this,c.get,t,new URLSearchParams,e);await r.perform()}prepareRequest(e){e.headers["X-Sec-Purpose"]="prefetch"}async requestSucceededWithResponse(e,t){try{const r=await t.responseHTML;const s=PageSnapshot.fromHTMLString(r);this.snapshotCache.put(e.url,s)}catch(e){}}requestStarted(e){}requestErrored(e){}requestFinished(e){}requestPreventedHandlingResponse(e,t){}requestFailedWithResponse(e,t){}#T=()=>{this.preloadOnLoadLinksForView(document.body)}}class Cache{constructor(e){this.session=e}clear(){this.session.clearCache()}resetCacheControl(){this.#P("")}exemptPageFromCache(){this.#P("no-cache")}exemptPageFromPreview(){this.#P("no-preview")}#P(e){setMetaContent("turbo-cache-control",e)}}class Session{navigator=new Navigator(this);history=new History(this);view=new PageView(this,document.documentElement);adapter=new BrowserAdapter(this);pageObserver=new PageObserver(this);cacheObserver=new CacheObserver;linkPrefetchObserver=new LinkPrefetchObserver(this,document);linkClickObserver=new LinkClickObserver(this,window);formSubmitObserver=new FormSubmitObserver(this,document);scrollObserver=new ScrollObserver(this);streamObserver=new StreamObserver(this);formLinkClickObserver=new FormLinkClickObserver(this,document.documentElement);frameRedirector=new FrameRedirector(this,document.documentElement);streamMessageRenderer=new StreamMessageRenderer;cache=new Cache(this);enabled=true;started=false;#F=150;constructor(e){this.recentRequests=e;this.preloader=new Preloader(this,this.view.snapshotCache);this.debouncedRefresh=this.refresh;this.pageRefreshDebouncePeriod=this.pageRefreshDebouncePeriod}start(){if(!this.started){this.pageObserver.start();this.cacheObserver.start();this.linkPrefetchObserver.start();this.formLinkClickObserver.start();this.linkClickObserver.start();this.formSubmitObserver.start();this.scrollObserver.start();this.streamObserver.start();this.frameRedirector.start();this.history.start();this.preloader.start();this.started=true;this.enabled=true}}disable(){this.enabled=false}stop(){if(this.started){this.pageObserver.stop();this.cacheObserver.stop();this.linkPrefetchObserver.stop();this.formLinkClickObserver.stop();this.linkClickObserver.stop();this.formSubmitObserver.stop();this.scrollObserver.stop();this.streamObserver.stop();this.frameRedirector.stop();this.history.stop();this.preloader.stop();this.started=false}}registerAdapter(e){this.adapter=e}visit(e,t={}){const r=t.frame?document.getElementById(t.frame):null;if(r instanceof FrameElement){const s=t.action||getVisitAction(r);r.delegate.proposeVisitIfNavigatedWithAction(r,s);r.src=e.toString()}else this.navigator.proposeVisit(expandURL(e),t)}refresh(e,t){const r=t&&this.recentRequests.has(t);r||this.navigator.currentVisit||this.visit(e,{action:"replace",shouldCacheSnapshot:false})}connectStreamSource(e){this.streamObserver.connectStreamSource(e)}disconnectStreamSource(e){this.streamObserver.disconnectStreamSource(e)}renderStreamMessage(e){this.streamMessageRenderer.render(StreamMessage.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){n.drive.progressBarDelay=e}get progressBarDelay(){return n.drive.progressBarDelay}set drive(e){n.drive.enabled=e}get drive(){return n.drive.enabled}set formMode(e){n.forms.mode=e}get formMode(){return n.forms.mode}get location(){return this.history.location}get restorationIdentifier(){return this.history.restorationIdentifier}get pageRefreshDebouncePeriod(){return this.#F}set pageRefreshDebouncePeriod(e){this.refresh=debounce(this.debouncedRefresh.bind(this),e);this.#F=e}shouldPreloadLink(e){const t=e.hasAttribute("data-turbo-method");const r=e.hasAttribute("data-turbo-stream");const s=e.getAttribute("data-turbo-frame");const i=s=="_top"?null:document.getElementById(s)||findClosestRecursively(e,"turbo-frame:not([disabled])");if(t||r||i instanceof FrameElement)return false;{const t=new URL(e.href);return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)}}historyPoppedToLocationWithRestorationIdentifierAndDirection(e,t,r){this.enabled?this.navigator.startVisit(e,t,{action:"restore",historyChanged:true,direction:r}):this.adapter.pageInvalidated({reason:"turbo_disabled"})}scrollPositionChanged(e){this.history.updateRestorationData({scrollPosition:e})}willSubmitFormLinkToLocation(e,t){return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)}submittedFormLinkToLocation(){}canPrefetchRequestToLocation(e,t){return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)}willFollowLinkToLocation(e,t,r){return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)&&this.applicationAllowsFollowingLinkToLocation(e,t,r)}followedLinkToLocation(e,t){const r=this.getActionForLink(e);const s=e.hasAttribute("data-turbo-stream");this.visit(t.href,{action:r,acceptsStreamResponse:s})}allowsVisitingLocationWithAction(e,t){return this.locationWithActionIsSamePage(e,t)||this.applicationAllowsVisitingLocation(e)}visitProposedToLocation(e,t){extendURLWithDeprecatedProperties(e);this.adapter.visitProposedToLocation(e,t)}visitStarted(e){if(!e.acceptsStreamResponse){markAsBusy(document.documentElement);this.view.markVisitDirection(e.direction)}extendURLWithDeprecatedProperties(e.location);e.silent||this.notifyApplicationAfterVisitingLocation(e.location,e.action)}visitCompleted(e){this.view.unmarkVisitDirection();clearBusyState(document.documentElement);this.notifyApplicationAfterPageLoad(e.getTimingMetrics())}locationWithActionIsSamePage(e,t){return this.navigator.locationWithActionIsSamePage(e,t)}visitScrolledToSamePageLocation(e,t){this.notifyApplicationAfterVisitingSamePageLocation(e,t)}willSubmitForm(e,t){const r=getAction$1(e,t);return this.submissionIsNavigatable(e,t)&&locationIsVisitable(expandURL(r),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.navigator.currentVisit?.silent||this.notifyApplicationBeforeCachingSnapshot()}allowsImmediateRender({element:e},t){const r=this.notifyApplicationBeforeRender(e,t);const{defaultPrevented:s,detail:{render:i}}=r;this.view.renderer&&i&&(this.view.renderer.renderElement=i);return!s}viewRenderedSnapshot(e,t,r){this.view.lastRenderedLocation=this.history.location;this.notifyApplicationAfterRender(r)}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,r){const s=this.notifyApplicationAfterClickingLinkToLocation(e,t,r);return!s.defaultPrevented}applicationAllowsVisitingLocation(e){const t=this.notifyApplicationBeforeVisitingLocation(e);return!t.defaultPrevented}notifyApplicationAfterClickingLinkToLocation(e,t,r){return dispatch("turbo:click",{target:e,detail:{url:t.href,originalEvent:r},cancelable:true})}notifyApplicationBeforeVisitingLocation(e){return dispatch("turbo:before-visit",{detail:{url:e.href},cancelable:true})}notifyApplicationAfterVisitingLocation(e,t){return dispatch("turbo:visit",{detail:{url:e.href,action:t}})}notifyApplicationBeforeCachingSnapshot(){return dispatch("turbo:before-cache")}notifyApplicationBeforeRender(e,t){return dispatch("turbo:before-render",{detail:{newBody:e,...t},cancelable:true})}notifyApplicationAfterRender(e){return dispatch("turbo:render",{detail:{renderMethod:e}})}notifyApplicationAfterPageLoad(e={}){return dispatch("turbo:load",{detail:{url:this.location.href,timing:e}})}notifyApplicationAfterVisitingSamePageLocation(e,t){dispatchEvent(new HashChangeEvent("hashchange",{oldURL:e.toString(),newURL:t.toString()}))}notifyApplicationAfterFrameLoad(e){return dispatch("turbo:frame-load",{target:e})}notifyApplicationAfterFrameRender(e,t){return dispatch("turbo:frame-render",{detail:{fetchResponse:e},target:t,cancelable:true})}submissionIsNavigatable(e,t){if(n.forms.mode=="off")return false;{const r=!t||this.elementIsNavigatable(t);return n.forms.mode=="optin"?r&&e.closest('[data-turbo="true"]')!=null:r&&this.elementIsNavigatable(e)}}elementIsNavigatable(e){const t=findClosestRecursively(e,"[data-turbo]");const r=findClosestRecursively(e,"turbo-frame");return n.drive.enabled||r?!t||t.getAttribute("data-turbo")!="false":!!t&&t.getAttribute("data-turbo")=="true"}getActionForLink(e){return getVisitAction(e)||"advance"}get snapshot(){return this.view.snapshot}}function extendURLWithDeprecatedProperties(e){Object.defineProperties(e,E)}const E={absoluteURL:{get(){return this.toString()}}};const y=new Session(o);const{cache:R,navigator:A}=y;function start(){y.start()}
|
|
100
|
+
/**
|
|
101
|
+
* Registers an adapter for the main session.
|
|
102
|
+
*
|
|
103
|
+
* @param adapter Adapter to register
|
|
104
|
+
*/function registerAdapter(e){y.registerAdapter(e)}
|
|
105
|
+
/**
|
|
106
|
+
* Performs an application visit to the given location.
|
|
107
|
+
*
|
|
108
|
+
* @param location Location to visit (a URL or path)
|
|
109
|
+
* @param options Options to apply
|
|
110
|
+
* @param options.action Type of history navigation to apply ("restore",
|
|
111
|
+
* "replace" or "advance")
|
|
112
|
+
* @param options.historyChanged Specifies whether the browser history has
|
|
113
|
+
* already been changed for this visit or not
|
|
114
|
+
* @param options.referrer Specifies the referrer of this visit such that
|
|
115
|
+
* navigations to the same page will not result in a new history entry.
|
|
116
|
+
* @param options.snapshotHTML Cached snapshot to render
|
|
117
|
+
* @param options.response Response of the specified location
|
|
118
|
+
*/function visit(e,t){y.visit(e,t)}
|
|
119
|
+
/**
|
|
120
|
+
* Connects a stream source to the main session.
|
|
121
|
+
*
|
|
122
|
+
* @param source Stream source to connect
|
|
123
|
+
*/function connectStreamSource(e){y.connectStreamSource(e)}
|
|
124
|
+
/**
|
|
125
|
+
* Disconnects a stream source from the main session.
|
|
126
|
+
*
|
|
127
|
+
* @param source Stream source to disconnect
|
|
128
|
+
*/function disconnectStreamSource(e){y.disconnectStreamSource(e)}
|
|
129
|
+
/**
|
|
130
|
+
* Renders a stream message to the main session by appending it to the
|
|
131
|
+
* current document.
|
|
132
|
+
*
|
|
133
|
+
* @param message Message to render
|
|
134
|
+
*/function renderStreamMessage(e){y.renderStreamMessage(e)}
|
|
135
|
+
/**
|
|
136
|
+
* Removes all entries from the Turbo Drive page cache.
|
|
137
|
+
* Call this when state has changed on the server that may affect cached pages.
|
|
138
|
+
*
|
|
139
|
+
* @deprecated since version 7.2.0 in favor of `Turbo.cache.clear()`
|
|
140
|
+
*/function clearCache(){console.warn("Please replace `Turbo.clearCache()` with `Turbo.cache.clear()`. The top-level function is deprecated and will be removed in a future version of Turbo.`");y.clearCache()}
|
|
141
|
+
/**
|
|
142
|
+
* Sets the delay after which the progress bar will appear during navigation.
|
|
143
|
+
*
|
|
144
|
+
* The progress bar appears after 500ms by default.
|
|
145
|
+
*
|
|
146
|
+
* Note that this method has no effect when used with the iOS or Android
|
|
147
|
+
* adapters.
|
|
148
|
+
*
|
|
149
|
+
* @param delay Time to delay in milliseconds
|
|
150
|
+
*/function setProgressBarDelay(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.`");n.drive.progressBarDelay=e}function setConfirmMethod(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.`");n.forms.confirm=e}function setFormMode(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.`");n.forms.mode=e}var L=Object.freeze({__proto__:null,navigator:A,session:y,cache:R,PageRenderer:PageRenderer,PageSnapshot:PageSnapshot,FrameRenderer:FrameRenderer,fetch:fetchWithTurboHeaders,config:n,start:start,registerAdapter:registerAdapter,visit:visit,connectStreamSource:connectStreamSource,disconnectStreamSource:disconnectStreamSource,renderStreamMessage:renderStreamMessage,clearCache:clearCache,setProgressBarDelay:setProgressBarDelay,setConfirmMethod:setConfirmMethod,setFormMode:setFormMode});class TurboFrameMissingError extends Error{}class FrameController{fetchResponseLoaded=e=>Promise.resolve();#M=null;#k=()=>{};#I=false;#q=false;#B=new Set;#H=false;action=null;constructor(e){this.element=e;this.view=new FrameView(this,this.element);this.appearanceObserver=new AppearanceObserver(this,this.element);this.formLinkClickObserver=new FormLinkClickObserver(this,this.element);this.linkInterceptor=new LinkInterceptor(this,this.element);this.restorationIdentifier=uuid();this.formSubmitObserver=new FormSubmitObserver(this,this.element)}connect(){if(!this.#I){this.#I=true;this.loadingStyle==t.lazy?this.appearanceObserver.start():this.#N();this.formLinkClickObserver.start();this.linkInterceptor.start();this.formSubmitObserver.start()}}disconnect(){if(this.#I){this.#I=false;this.appearanceObserver.stop();this.formLinkClickObserver.stop();this.linkInterceptor.stop();this.formSubmitObserver.stop()}}disabledChanged(){this.loadingStyle==t.eager&&this.#N()}sourceURLChanged(){if(!this.#O("src")){this.element.isConnected&&(this.complete=false);(this.loadingStyle==t.eager||this.#q)&&this.#N()}}sourceURLReloaded(){const{refresh:e,src:t}=this.element;this.#H=t&&e==="morph";this.element.removeAttribute("complete");this.element.src=null;this.element.src=t;return this.element.loaded}loadingStyleChanged(){if(this.loadingStyle==t.lazy)this.appearanceObserver.start();else{this.appearanceObserver.stop();this.#N()}}async#N(){if(this.enabled&&this.isActive&&!this.complete&&this.sourceURL){this.element.loaded=this.#x(expandURL(this.sourceURL));this.appearanceObserver.stop();await this.element.loaded;this.#q=true}}async loadResponse(e){(e.redirected||e.succeeded&&e.isHTML)&&(this.sourceURL=e.response.url);try{const t=await e.responseHTML;if(t){const r=parseHTMLDocument(t);const s=PageSnapshot.fromDocument(r);s.isVisitable?await this.#V(e,r):await this.#D(e)}}finally{this.#H=false;this.fetchResponseLoaded=()=>Promise.resolve()}}elementAppearedInViewport(e){this.proposeVisitIfNavigatedWithAction(e,getVisitAction(e));this.#N()}willSubmitFormLinkToLocation(e){return this.#W(e)}submittedFormLinkToLocation(e,t,r){const s=this.#m(e);s&&r.setAttribute("data-turbo-frame",s.id)}shouldInterceptLinkClick(e,t,r){return this.#W(e)}linkClickIntercepted(e,t){this.#U(e,t)}willSubmitForm(e,t){return e.closest("turbo-frame")==this.element&&this.#W(e,t)}formSubmitted(e,t){this.formSubmission&&this.formSubmission.stop();this.formSubmission=new FormSubmission(this,e,t);const{fetchRequest:r}=this.formSubmission;this.prepareRequest(r);this.formSubmission.start()}prepareRequest(e){e.headers["Turbo-Frame"]=this.id;this.currentNavigationElement?.hasAttribute("data-turbo-stream")&&e.acceptResponseType(StreamMessage.contentType)}requestStarted(e){markAsBusy(this.element)}requestPreventedHandlingResponse(e,t){this.#k()}async requestSucceededWithResponse(e,t){await this.loadResponse(t);this.#k()}async requestFailedWithResponse(e,t){await this.loadResponse(t);this.#k()}requestErrored(e,t){console.error(t);this.#k()}requestFinished(e){clearBusyState(this.element)}formSubmissionStarted({formElement:e}){markAsBusy(e,this.#m(e))}formSubmissionSucceededWithResponse(e,t){const r=this.#m(e.formElement,e.submitter);r.delegate.proposeVisitIfNavigatedWithAction(r,getVisitAction(e.submitter,e.formElement,r));r.delegate.loadResponse(t);e.isSafe||y.clearCache()}formSubmissionFailedWithResponse(e,t){this.element.delegate.loadResponse(t);y.clearCache()}formSubmissionErrored(e,t){console.error(t)}formSubmissionFinished({formElement:e}){clearBusyState(e,this.#m(e))}allowsImmediateRender({element:e},t){const r=dispatch("turbo:before-frame-render",{target:this.element,detail:{newFrame:e,...t},cancelable:true});const{defaultPrevented:s,detail:{render:i}}=r;this.view.renderer&&i&&(this.view.renderer.renderElement=i);return!s}viewRenderedSnapshot(e,t,r){}preloadOnLoadLinksForView(e){y.preloadOnLoadLinksForView(e)}viewInvalidated(){}willRenderFrame(e,t){this.previousFrameElement=e.cloneNode(true)}visitCachedSnapshot=({element:e})=>{const t=e.querySelector("#"+this.element.id);t&&this.previousFrameElement&&t.replaceChildren(...this.previousFrameElement.children);delete this.previousFrameElement};async#V(e,t){const r=await this.extractForeignFrameElement(t.body);const s=this.#H?MorphingFrameRenderer:FrameRenderer;if(r){const t=new Snapshot(r);const i=new s(this,this.view.snapshot,t,false,false);this.view.renderPromise&&await this.view.renderPromise;this.changeHistory();await this.view.render(i);this.complete=true;y.frameRendered(e,this.element);y.frameLoaded(this.element);await this.fetchResponseLoaded(e)}else this.#z(e)&&this.#j(e)}async#x(e){const t=new FetchRequest(this,c.get,e,new URLSearchParams,this.element);this.#M?.cancel();this.#M=t;return new Promise((e=>{this.#k=()=>{this.#k=()=>{};this.#M=null;e()};t.perform()}))}#U(e,t,r){const s=this.#m(e,r);s.delegate.proposeVisitIfNavigatedWithAction(s,getVisitAction(r,e,s));this.#$(e,(()=>{s.src=t}))}proposeVisitIfNavigatedWithAction(e,t=null){this.action=t;if(this.action){const t=PageSnapshot.fromElement(e).clone();const{visitCachedSnapshot:r}=e.delegate;e.delegate.fetchResponseLoaded=async s=>{if(e.src){const{statusCode:i,redirected:n}=s;const o=await s.responseHTML;const a={statusCode:i,redirected:n,responseHTML:o};const c={response:a,visitCachedSnapshot:r,willRender:false,updateHistory:false,restorationIdentifier:this.restorationIdentifier,snapshot:t};this.action&&(c.action=this.action);y.visit(e.src,c)}}}}changeHistory(){if(this.action){const e=getHistoryMethodForAction(this.action);y.history.update(e,expandURL(this.element.src||""),this.restorationIdentifier)}}async#D(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.#_(e.response)}#z(e){this.element.setAttribute("complete","");const t=e.response;const visit=async(e,t)=>{e instanceof Response?this.#_(e):y.visit(e,t)};const r=dispatch("turbo:frame-missing",{target:this.element,detail:{response:t,visit:visit},cancelable:true});return!r.defaultPrevented}#j(e){this.view.missing();this.#K(e)}#K(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 TurboFrameMissingError(t)}async#_(e){const t=new FetchResponse(e);const r=await t.responseHTML;const{location:s,redirected:i,statusCode:n}=t;return y.visit(s,{response:{redirected:i,statusCode:n,responseHTML:r}})}#m(e,t){const r=getAttribute("data-turbo-frame",t,e)||this.element.getAttribute("target");return getFrameElementById(r)??this.element}async extractForeignFrameElement(e){let t;const r=CSS.escape(this.id);try{t=activateElement(e.querySelector(`turbo-frame#${r}`),this.sourceURL);if(t)return t;t=activateElement(e.querySelector(`turbo-frame[src][recurse~=${r}]`),this.sourceURL);if(t){await t.loaded;return await this.extractForeignFrameElement(t)}}catch(e){console.error(e);return new FrameElement}return null}#X(e,t){const r=getAction$1(e,t);return locationIsVisitable(expandURL(r),this.rootLocation)}#W(e,t){const r=getAttribute("data-turbo-frame",t,e)||this.element.getAttribute("target");if(e instanceof HTMLFormElement&&!this.#X(e,t))return false;if(!this.enabled||r=="_top")return false;if(r){const e=getFrameElementById(r);if(e)return!e.disabled}return!!y.elementIsNavigatable(e)&&!(t&&!y.elementIsNavigatable(t))}get id(){return this.element.id}get enabled(){return!this.element.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 this.formSubmission!==void 0||this.#k()!==void 0}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.#I}get rootLocation(){const e=this.element.ownerDocument.querySelector('meta[name="turbo-root"]');const t=e?.content??"/";return expandURL(t)}#O(e){return this.#B.has(e)}#Q(e,t){this.#B.add(e);t();this.#B.delete(e)}#$(e,t){this.currentNavigationElement=e;t();delete this.currentNavigationElement}}function getFrameElementById(e){if(e!=null){const t=document.getElementById(e);if(t instanceof FrameElement)return t}}function activateElement(e,t){if(e){const r=e.getAttribute("src");if(r!=null&&t!=null&&urlsAreEqual(r,t))throw new Error(`Matching <turbo-frame id="${e.id}"> element has a source URL which references itself`);e.ownerDocument!==document&&(e=document.importNode(e,true));if(e instanceof FrameElement){e.connectedCallback();e.disconnectedCallback();return e}}}const C={after(){this.targetElements.forEach((e=>e.parentElement?.insertBefore(this.templateContent,e.nextSibling)))},append(){this.removeDuplicateTargetChildren();this.targetElements.forEach((e=>e.append(this.templateContent)))},before(){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=>{e==="morph"?morphElements(t,this.templateContent):t.replaceWith(this.templateContent)}))},update(){const e=this.getAttribute("method");this.targetElements.forEach((t=>{if(e==="morph")morphChildren(t,this.templateContent);else{t.innerHTML="";t.append(this.templateContent)}}))},refresh(){y.refresh(this.baseURI,this.requestId)}};class StreamElement 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;if(this.dispatchEvent(e)){await nextRepaint();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.id));const 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=C[this.action];if(e)return e;this.#Y("unknown action")}this.#Y("action attribute is missing")}get targetElements(){if(this.target)return this.targetElementsById;if(this.targets)return this.targetElementsByQuery;this.#Y("target or targets attribute is missing")}get templateContent(){return this.templateElement.content.cloneNode(true)}get templateElement(){if(this.firstElementChild===null){const e=this.ownerDocument.createElement("template");this.appendChild(e);return e}if(this.firstElementChild instanceof HTMLTemplateElement)return this.firstElementChild;this.#Y("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")}#Y(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:true,cancelable:true,detail:{newStream:this,render:StreamElement.renderElement}})}get targetElementsById(){const e=this.ownerDocument?.getElementById(this.target);return e!==null?[e]:[]}get targetElementsByQuery(){const e=this.ownerDocument?.querySelectorAll(this.targets);return e.length!==0?Array.prototype.slice.call(e):[]}}class StreamSourceElement extends HTMLElement{streamSource=null;connectedCallback(){this.streamSource=this.src.match(/^ws{1,2}:/)?new WebSocket(this.src):new EventSource(this.src);connectStreamSource(this.streamSource)}disconnectedCallback(){if(this.streamSource){this.streamSource.close();disconnectStreamSource(this.streamSource)}}get src(){return this.getAttribute("src")||""}}FrameElement.delegateConstructor=FrameController;customElements.get("turbo-frame")===void 0&&customElements.define("turbo-frame",FrameElement);customElements.get("turbo-stream")===void 0&&customElements.define("turbo-stream",StreamElement);customElements.get("turbo-stream-source")===void 0&&customElements.define("turbo-stream-source",StreamSourceElement);(()=>{let e=document.currentScript;if(e&&!e.hasAttribute("data-turbo-suppress-warning")){e=e.parentElement;while(e){if(e==document.body)return console.warn(unindent`
|
|
151
|
+
You are loading Turbo from a <script> element inside the <body> element. This is probably not what you meant to do!
|
|
152
|
+
|
|
153
|
+
Load your application’s JavaScript bundle inside the <head> element instead. <script> elements in <body> are evaluated with each page change.
|
|
154
|
+
|
|
155
|
+
For more information, see: https://turbo.hotwired.dev/handbook/building#working-with-script-elements
|
|
156
|
+
|
|
157
|
+
——
|
|
158
|
+
Suppress this warning by adding a "data-turbo-suppress-warning" attribute to: %s
|
|
159
|
+
`,e.outerHTML);e=e.parentElement}}})();window.Turbo={...L,StreamActions:C};start();export{l as FetchEnctype,c as FetchMethod,FetchRequest,FetchResponse,FrameElement,t as FrameLoadingStyle,FrameRenderer,PageRenderer,PageSnapshot,C as StreamActions,StreamElement,StreamSourceElement,R as cache,clearCache,n as config,connectStreamSource,disconnectStreamSource,fetchWithTurboHeaders as fetch,fetchEnctypeFromString,fetchMethodFromString,isSafe,A as navigator,registerAdapter,renderStreamMessage,y as session,setConfirmMethod,setFormMode,setProgressBarDelay,start,visit};
|
|
160
|
+
|